projen
Version:
CDK for software projects
135 lines • 21.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderDockerComposeFile = renderDockerComposeFile;
const util_1 = require("../util");
function renderDockerComposeFile(serviceDescriptions, version) {
// Record volume configuration
const volumeConfig = {};
const volumeInfo = {
addVolumeConfiguration(volumeName, configuration) {
if (!volumeConfig[volumeName]) {
// First volume configuration takes precedence.
volumeConfig[volumeName] = configuration;
}
},
};
// Record network configuration
const networkConfig = {};
const networkInfo = {
addNetworkConfiguration(networkName, configuration) {
if (!networkConfig[networkName]) {
// First network configuration takes precedence.
networkConfig[networkName] = configuration;
}
},
};
// Render service configuration
const services = {};
for (const [serviceName, serviceDescription] of Object.entries(serviceDescriptions ?? {})) {
// Resolve the names of each dependency and check that they exist.
// Note: They may not exist if the user made a mistake when referencing a
// service by name via `DockerCompose.serviceName()`.
// @see DockerCompose.serviceName
const dependsOn = Array();
for (const dependsOnServiceName of serviceDescription.dependsOn ?? []) {
const resolvedServiceName = dependsOnServiceName.serviceName;
if (resolvedServiceName === serviceName) {
throw new Error(`Service ${serviceName} cannot depend on itself`);
}
if (!serviceDescriptions[resolvedServiceName]) {
throw new Error(`Unable to resolve service named ${resolvedServiceName} for ${serviceName}`);
}
dependsOn.push(resolvedServiceName);
}
// Give each volume binding a chance to bind any necessary volume
// configuration and provide volume mount information for the service.
const volumes = [];
for (const volumeBinding of serviceDescription.volumes ?? []) {
volumes.push(volumeBinding.bind(volumeInfo));
}
// Give each network binding a chance to bind any necessary network
// configuration and provide network mount information for the service.
const networks = [];
for (const networkBinding of serviceDescription.networks ?? []) {
networks.push(networkBinding.bind(networkInfo));
}
// Create and store the service configuration, taking care not to create
// object members with undefined values.
services[serviceName] = {
...getObjectWithKeyAndValueIfValueIsDefined("image", serviceDescription.image),
...getObjectWithKeyAndValueIfValueIsDefined("build", serviceDescription.imageBuild),
...getObjectWithKeyAndValueIfValueIsDefined("entrypoint", serviceDescription.entrypoint),
...getObjectWithKeyAndValueIfValueIsDefined("command", serviceDescription.command),
...getObjectWithKeyAndValueIfValueIsDefined("platform", serviceDescription.platform),
...getObjectWithKeyAndValueIfValueIsDefined("privileged", serviceDescription.privileged),
...(Object.keys(serviceDescription.environment).length > 0
? { environment: serviceDescription.environment }
: {}),
...(serviceDescription.ports.length > 0
? { ports: serviceDescription.ports }
: {}),
...(Object.keys(serviceDescription.labels).length > 0
? { labels: serviceDescription.labels }
: {}),
...(dependsOn.length > 0 ? { dependsOn } : {}),
...(volumes.length > 0 ? { volumes } : {}),
...(networks.length > 0 ? { networks } : {}),
};
}
// Explicit with the type here because the decamelize step after this wipes
// out types.
const input = {
...(version ? { version } : {}),
services,
...(Object.keys(volumeConfig).length > 0 ? { volumes: volumeConfig } : {}),
...(Object.keys(networkConfig).length > 0
? { networks: networkConfig }
: {}),
};
// Change most keys to snake case.
return (0, util_1.decamelizeKeysRecursively)(input, {
shouldDecamelize: shouldDecamelizeDockerComposeKey,
separator: "_",
});
}
/**
* Returns `{ [key]: value }` if `value` is defined, otherwise returns `{}` so
* that object spreading can be used to generate a peculiar interface.
* @param key
* @param value
*/
function getObjectWithKeyAndValueIfValueIsDefined(key, value) {
return value !== undefined ? { [key]: value } : {};
}
/**
* Determines whether the key at the given path should be decamelized.
* Largely, all keys should be snake cased. But, there are some
* exceptions for user-provided names for services, volumes, and
* environment variables.
*
* @param path
*/
function shouldDecamelizeDockerComposeKey(path) {
const poundPath = path.join("#");
// Does not decamelize user's names.
// services.namehere:
// volumes.namehere:
// networks.namehere:
if (/^(services|volumes|networks)#[^#]+$/.test(poundPath)) {
return false;
}
// Does not decamelize environment variables and labels
// services.namehere.environment.*
// services.namehere.labels.*
if (/^services#[^#]+#(environment|labels)#/.test(poundPath)) {
return false;
}
// Does not decamelize build arguments
// services.namehere.build.args.*
if (/^services#[^#]+#build#args#/.test(poundPath)) {
return false;
}
// Otherwise, let it all decamelize.
return true;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9ja2VyLWNvbXBvc2UtcmVuZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RvY2tlci1jb21wb3NlL2RvY2tlci1jb21wb3NlLXJlbmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTBDQSwwREErSEM7QUE3SkQsa0NBQW9EO0FBOEJwRCxTQUFnQix1QkFBdUIsQ0FDckMsbUJBQXlELEVBQ3pELE9BQWdCO0lBRWhCLDhCQUE4QjtJQUM5QixNQUFNLFlBQVksR0FBOEMsRUFBRSxDQUFDO0lBQ25FLE1BQU0sVUFBVSxHQUErQjtRQUM3QyxzQkFBc0IsQ0FDcEIsVUFBa0IsRUFDbEIsYUFBd0M7WUFFeEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUM5QiwrQ0FBK0M7Z0JBQy9DLFlBQVksQ0FBQyxVQUFVLENBQUMsR0FBRyxhQUFhLENBQUM7WUFDM0MsQ0FBQztRQUNILENBQUM7S0FDRixDQUFDO0lBQ0YsK0JBQStCO0lBQy9CLE1BQU0sYUFBYSxHQUErQyxFQUFFLENBQUM7SUFDckUsTUFBTSxXQUFXLEdBQWdDO1FBQy9DLHVCQUF1QixDQUNyQixXQUFtQixFQUNuQixhQUF5QztZQUV6QyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hDLGdEQUFnRDtnQkFDaEQsYUFBYSxDQUFDLFdBQVcsQ0FBQyxHQUFHLGFBQWEsQ0FBQztZQUM3QyxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUM7SUFFRiwrQkFBK0I7SUFDL0IsTUFBTSxRQUFRLEdBQW1ELEVBQUUsQ0FBQztJQUNwRSxLQUFLLE1BQU0sQ0FBQyxXQUFXLEVBQUUsa0JBQWtCLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUM1RCxtQkFBbUIsSUFBSSxFQUFFLENBQzFCLEVBQUUsQ0FBQztRQUNGLGtFQUFrRTtRQUNsRSx5RUFBeUU7UUFDekUscURBQXFEO1FBQ3JELGlDQUFpQztRQUNqQyxN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LE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFakMsb0NBQW9DO0lBQ3BDLHFCQUFxQjtJQUNyQixvQkFBb0I7SUFDcEIscUJBQXFCO0lBQ3JCLElBQUkscUNBQXFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDMUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsdURBQXVEO0lBQ3ZELGtDQUFrQztJQUNsQyw2QkFBNkI7SUFDN0IsSUFBSSx1Q0FBdUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUM1RCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxzQ0FBc0M7SUFDdEMsaUNBQWlDO0lBQ2pDLElBQUksNkJBQTZCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDbEQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsb0NBQW9DO0lBQ3BDLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERvY2tlckNvbXBvc2VCdWlsZCB9IGZyb20gXCIuL2RvY2tlci1jb21wb3NlXCI7XG5pbXBvcnQge1xuICBEb2NrZXJDb21wb3NlTmV0d29ya0NvbmZpZyxcbiAgSURvY2tlckNvbXBvc2VOZXR3b3JrQ29uZmlnLFxufSBmcm9tIFwiLi9kb2NrZXItY29tcG9zZS1uZXR3b3JrXCI7XG5pbXBvcnQgeyBEb2NrZXJDb21wb3NlU2VydmljZVBvcnQgfSBmcm9tIFwiLi9kb2NrZXItY29tcG9zZS1wb3J0XCI7XG5pbXBvcnQgeyBEb2NrZXJDb21wb3NlU2VydmljZSB9IGZyb20gXCIuL2RvY2tlci1jb21wb3NlLXNlcnZpY2VcIjtcbmltcG9ydCB7XG4gIERvY2tlckNvbXBvc2VWb2x1bWVDb25maWcsXG4gIERvY2tlckNvbXBvc2VWb2x1bWVNb3VudCxcbiAgSURvY2tlckNvbXBvc2VWb2x1bWVDb25maWcsXG59IGZyb20gXCIuL2RvY2tlci1jb21wb3NlLXZvbHVtZVwiO1xuaW1wb3J0IHsgZGVjYW1lbGl6ZUtleXNSZWN1cnNpdmVseSB9IGZyb20gXCIuLi91dGlsXCI7XG5cbi8qKlxuICogU3RydWN0dXJlIG9mIGEgZG9ja2VyIGNvbXBvc2UgZmlsZSdzIHNlcnZpY2UgYmVmb3JlIHdlIGRlY2FtZWxpemUuXG4gKiBAaW50ZXJuYWxcbiAqL1xuaW50ZXJmYWNlIERvY2tlckNvbXBvc2VGaWxlU2VydmljZVNjaGVtYSB7XG4gIHJlYWRvbmx5IGRlcGVuZHNPbj86IHN0cmluZ1tdO1xuICByZWFkb25seSBidWlsZD86IERvY2tlckNvbXBvc2VCdWlsZDtcbiAgcmVhZG9ubHkgaW1hZ2U/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbW1hbmQ/OiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgdm9sdW1lcz86IERvY2tlckNvbXBvc2VWb2x1bWVNb3VudFtdO1xuICByZWFkb25seSBuZXR3b3Jrcz86IHN0cmluZ1tdO1xuICByZWFkb25seSBwb3J0cz86IERvY2tlckNvbXBvc2VTZXJ2aWNlUG9ydFtdO1xuICByZWFkb25seSBlbnZpcm9ubWVudD86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIHJlYWRvbmx5IGxhYmVscz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIHJlYWRvbmx5IGVudHJ5cG9pbnQ/OiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgcHJpdmlsZWdlZD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogU3RydWN0dXJlIG9mIGEgZG9ja2VyIGNvbXBvc2UgZmlsZSBiZWZvcmUgd2UgZGVjYW1lbGl6ZS5cbiAqIEBpbnRlcm5hbFxuICovXG5pbnRlcmZhY2UgRG9ja2VyQ29tcG9zZUZpbGVTY2hlbWEge1xuICB2ZXJzaW9uPzogc3RyaW5nO1xuICBzZXJ2aWNlczogUmVjb3JkPHN0cmluZywgRG9ja2VyQ29tcG9zZUZpbGVTZXJ2aWNlU2NoZW1hPjtcbiAgdm9sdW1lcz86IFJlY29yZDxzdHJpbmcsIERvY2tlckNvbXBvc2VWb2x1bWVDb25maWc+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyRG9ja2VyQ29tcG9zZUZpbGUoXG4gIHNlcnZpY2VEZXNjcmlwdGlvbnM6IFJlY29yZDxzdHJpbmcsIERvY2tlckNvbXBvc2VTZXJ2aWNlPixcbiAgdmVyc2lvbj86IHN0cmluZyxcbik6IG9iamVjdCB7XG4gIC8vIFJlY29yZCB2b2x1bWUgY29uZmlndXJhdGlvblxuICBjb25zdCB2b2x1bWVDb25maWc6IFJlY29yZDxzdHJpbmcsIERvY2tlckNvbXBvc2VWb2x1bWVDb25maWc+ID0ge307XG4gIGNvbnN0IHZvbHVtZUluZm86IElEb2NrZXJDb21wb3NlVm9sdW1lQ29uZmlnID0ge1xuICAgIGFkZFZvbHVtZUNvbmZpZ3VyYXRpb24oXG4gICAgICB2b2x1bWVOYW1lOiBzdHJpbmcsXG4gICAgICBjb25maWd1cmF0aW9uOiBEb2NrZXJDb21wb3NlVm9sdW1lQ29uZmlnLFxuICAgICkge1xuICAgICAgaWYgKCF2b2x1bWVDb25maWdbdm9sdW1lTmFtZV0pIHtcbiAgICAgICAgLy8gRmlyc3Qgdm9sdW1lIGNvbmZpZ3VyYXRpb24gdGFrZXMgcHJlY2VkZW5jZS5cbiAgICAgICAgdm9sdW1lQ29uZmlnW3ZvbHVtZU5hbWVdID0gY29uZmlndXJhdGlvbjtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xuICAvLyBSZWNvcmQgbmV0d29yayBjb25maWd1cmF0aW9uXG4gIGNvbnN0IG5ldHdvcmtDb25maWc6IFJlY29yZDxzdHJpbmcsIERvY2tlckNvbXBvc2VOZXR3b3JrQ29uZmlnPiA9IHt9O1xuICBjb25zdCBuZXR3b3JrSW5mbzogSURvY2tlckNvbXBvc2VOZXR3b3JrQ29uZmlnID0ge1xuICAgIGFkZE5ldHdvcmtDb25maWd1cmF0aW9uKFxuICAgICAgbmV0d29ya05hbWU6IHN0cmluZyxcbiAgICAgIGNvbmZpZ3VyYXRpb246IERvY2tlckNvbXBvc2VOZXR3b3JrQ29uZmlnLFxuICAgICkge1xuICAgICAgaWYgKCFuZXR3b3JrQ29uZmlnW25ldHdvcmtOYW1lXSkge1xuICAgICAgICAvLyBGaXJzdCBuZXR3b3JrIGNvbmZpZ3VyYXRpb24gdGFrZXMgcHJlY2VkZW5jZS5cbiAgICAgICAgbmV0d29ya0NvbmZpZ1tuZXR3b3JrTmFtZV0gPSBjb25maWd1cmF0aW9uO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG5cbiAgLy8gUmVuZGVyIHNlcnZpY2UgY29uZmlndXJhdGlvblxuICBjb25zdCBzZXJ2aWNlczogUmVjb3JkPHN0cmluZywgRG9ja2VyQ29tcG9zZUZpbGVTZXJ2aWNlU2NoZW1hPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtzZXJ2aWNlTmFtZSwgc2VydmljZURlc2NyaXB0aW9uXSBvZiBPYmplY3QuZW50cmllcyhcbiAgICBzZXJ2aWNlRGVzY3JpcHRpb25zID8/IHt9LFxuICApKSB7XG4gICAgLy8gUmVzb2x2ZSB0aGUgbmFtZXMgb2YgZWFjaCBkZXBlbmRlbmN5IGFuZCBjaGVjayB0aGF0IHRoZXkgZXhpc3QuXG4gICAgLy8gTm90ZTogVGhleSBtYXkgbm90IGV4aXN0IGlmIHRoZSB1c2VyIG1hZGUgYSBtaXN0YWtlIHdoZW4gcmVmZXJlbmNpbmcgYVxuICAgIC8vIHNlcnZpY2UgYnkgbmFtZSB2aWEgYERvY2tlckNvbXBvc2Uuc2VydmljZU5hbWUoKWAuXG4gICAgLy8gQHNlZSBEb2NrZXJDb21wb3NlLnNlcnZpY2VOYW1lXG4gICAgY29uc3QgZGVwZW5kc09uID0gQXJyYXk8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgZGVwZW5kc09uU2VydmljZU5hbWUgb2Ygc2VydmljZURlc2NyaXB0aW9uLmRlcGVuZHNPbiA/PyBbXSkge1xuICAgICAgY29uc3QgcmVzb2x2ZWRTZXJ2aWNlTmFtZSA9IGRlcGVuZHNPblNlcnZpY2VOYW1lLnNlcnZpY2VOYW1lO1xuICAgICAgaWYgKHJlc29sdmVkU2VydmljZU5hbWUgPT09IHNlcnZpY2VOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2VydmljZSAke3NlcnZpY2VOYW1lfSBjYW5ub3QgZGVwZW5kIG9uIGl0c2VsZmApO1xuICAgICAgfVxuICAgICAgaWYgKCFzZXJ2aWNlRGVzY3JpcHRpb25zW3Jlc29sdmVkU2VydmljZU5hbWVdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgVW5hYmxlIHRvIHJlc29sdmUgc2VydmljZSBuYW1lZCAke3Jlc29sdmVkU2VydmljZU5hbWV9IGZvciAke3NlcnZpY2VOYW1lfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGRlcGVuZHNPbi5wdXNoKHJlc29sdmVkU2VydmljZU5hbWUpO1xuICAgIH1cblxuICAgIC8vIEdpdmUgZWFjaCB2b2x1bWUgYmluZGluZyBhIGNoYW5jZSB0byBiaW5kIGFueSBuZWNlc3Nhcnkgdm9sdW1lXG4gICAgLy8gY29uZmlndXJhdGlvbiBhbmQgcHJvdmlkZSB2b2x1bWUgbW91bnQgaW5mb3JtYXRpb24gZm9yIHRoZSBzZXJ2aWNlLlxuICAgIGNvbnN0IHZvbHVtZXM6IERvY2tlckNvbXBvc2VWb2x1bWVNb3VudFtdID0gW107XG4gICAgZm9yIChjb25zdCB2b2x1bWVCaW5kaW5nIG9mIHNlcnZpY2VEZXNjcmlwdGlvbi52b2x1bWVzID8/IFtdKSB7XG4gICAgICB2b2x1bWVzLnB1c2godm9sdW1lQmluZGluZy5iaW5kKHZvbHVtZUluZm8pKTtcbiAgICB9XG5cbiAgICAvLyBHaXZlIGVhY2ggbmV0d29yayBiaW5kaW5nIGEgY2hhbmNlIHRvIGJpbmQgYW55IG5lY2Vzc2FyeSBuZXR3b3JrXG4gICAgLy8gY29uZmlndXJhdGlvbiBhbmQgcHJvdmlkZSBuZXR3b3JrIG1vdW50IGluZm9ybWF0aW9uIGZvciB0aGUgc2VydmljZS5cbiAgICBjb25zdCBuZXR3b3Jrczogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IG5ldHdvcmtCaW5kaW5nIG9mIHNlcnZpY2VEZXNjcmlwdGlvbi5uZXR3b3JrcyA/PyBbXSkge1xuICAgICAgbmV0d29ya3MucHVzaChuZXR3b3JrQmluZGluZy5iaW5kKG5ldHdvcmtJbmZvKSk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIGFuZCBzdG9yZSB0aGUgc2VydmljZSBjb25maWd1cmF0aW9uLCB0YWtpbmcgY2FyZSBub3QgdG8gY3JlYXRlXG4gICAgLy8gb2JqZWN0IG1lbWJlcnMgd2l0aCB1bmRlZmluZWQgdmFsdWVzLlxuICAgIHNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IHtcbiAgICAgIC4uLmdldE9iamVjdFdpdGhLZXlBbmRWYWx1ZUlmVmFsdWVJc0RlZmluZWQoXG4gICAgICAgIFwiaW1hZ2VcIixcbiAgICAgICAgc2VydmljZURlc2NyaXB0aW9uLmltYWdlLFxuICAgICAgKSxcbiAgICAgIC4uLmdldE9iamVjdFdpdGhLZXlBbmRWYWx1ZUlmVmFsdWVJc0RlZmluZWQoXG4gICAgICAgIFwiYnVpbGRcIixcbiAgICAgICAgc2VydmljZURlc2NyaXB0aW9uLmltYWdlQnVpbGQsXG4gICAgICApLFxuICAgICAgLi4uZ2V0T2JqZWN0V2l0aEtleUFuZFZhbHVlSWZWYWx1ZUlzRGVmaW5lZChcbiAgICAgICAgXCJlbnRyeXBvaW50XCIsXG4gICAgICAgIHNlcnZpY2VEZXNjcmlwdGlvbi5lbnRyeXBvaW50LFxuICAgICAgKSxcbiAgICAgIC4uLmdldE9iamVjdFdpdGhLZXlBbmRWYWx1ZUlmVmFsdWVJc0RlZmluZWQoXG4gICAgICAgIFwiY29tbWFuZFwiLFxuICAgICAgICBzZXJ2aWNlRGVzY3JpcHRpb24uY29tbWFuZCxcbiAgICAgICksXG4gICAgICAuLi5nZXRPYmplY3RXaXRoS2V5QW5kVmFsdWVJZlZhbHVlSXNEZWZpbmVkKFxuICAgICAgICBcInBsYXRmb3JtXCIsXG4gICAgICAgIHNlcnZpY2VEZXNjcmlwdGlvbi5wbGF0Zm9ybSxcbiAgICAgICksXG4gICAgICAuLi5nZXRPYmplY3RXaXRoS2V5QW5kVmFsdWVJZlZhbHVlSXNEZWZpbmVkKFxuICAgICAgICBcInByaXZpbGVnZWRcIixcbiAgICAgICAgc2VydmljZURlc2NyaXB0aW9uLnByaXZpbGVnZWQsXG4gICAgICApLFxuICAgICAgLi4uKE9iamVjdC5rZXlzKHNlcnZpY2VEZXNjcmlwdGlvbi5lbnZpcm9ubWVudCkubGVuZ3RoID4gMFxuICAgICAgICA/IHsgZW52aXJvbm1lbnQ6IHNlcnZpY2VEZXNjcmlwdGlvbi5lbnZpcm9ubWVudCB9XG4gICAgICAgIDoge30pLFxuICAgICAgLi4uKHNlcnZpY2VEZXNjcmlwdGlvbi5wb3J0cy5sZW5ndGggPiAwXG4gICAgICAgID8geyBwb3J0czogc2VydmljZURlc2NyaXB0aW9uLnBvcnRzIH1cbiAgICAgICAgOiB7fSksXG4gICAgICAuLi4oT2JqZWN0LmtleXMoc2VydmljZURlc2NyaXB0aW9uLmxhYmVscykubGVuZ3RoID4gMFxuICAgICAgICA/IHsgbGFiZWxzOiBzZXJ2aWNlRGVzY3JpcHRpb24ubGFiZWxzIH1cbiAgICAgICAgOiB7fSksXG4gICAgICAuLi4oZGVwZW5kc09uLmxlbmd0aCA+IDAgPyB7IGRlcGVuZHNPbiB9IDoge30pLFxuICAgICAgLi4uKHZvbHVtZXMubGVuZ3RoID4gMCA/IHsgdm9sdW1lcyB9IDoge30pLFxuICAgICAgLi4uKG5ldHdvcmtzLmxlbmd0aCA+IDAgPyB7IG5ldHdvcmtzIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8vIEV4cGxpY2l0IHdpdGggdGhlIHR5cGUgaGVyZSBiZWNhdXNlIHRoZSBkZWNhbWVsaXplIHN0ZXAgYWZ0ZXIgdGhpcyB3aXBlc1xuICAvLyBvdXQgdHlwZXMuXG4gIGNvbnN0IGlucHV0OiBEb2NrZXJDb21wb3NlRmlsZVNjaGVtYSA9IHtcbiAgICAuLi4odmVyc2lvbiA/IHsgdmVyc2lvbiB9IDoge30pLFxuICAgIHNlcnZpY2VzLFxuICAgIC4uLihPYmplY3Qua2V5cyh2b2x1bWVDb25maWcpLmxlbmd0aCA+IDAgPyB7IHZvbHVtZXM6IHZvbHVtZUNvbmZpZyB9IDoge30pLFxuICAgIC4uLihPYmplY3Qua2V5cyhuZXR3b3JrQ29uZmlnKS5sZW5ndGggPiAwXG4gICAgICA/IHsgbmV0d29ya3M6IG5ldHdvcmtDb25maWcgfVxuICAgICAgOiB7fSksXG4gIH07XG5cbiAgLy8gQ2hhbmdlIG1vc3Qga2V5cyB0byBzbmFrZSBjYXNlLlxuICByZXR1cm4gZGVjYW1lbGl6ZUtleXNSZWN1cnNpdmVseShpbnB1dCwge1xuICAgIHNob3VsZERlY2FtZWxpemU6IHNob3VsZERlY2FtZWxpemVEb2NrZXJDb21wb3NlS2V5LFxuICAgIHNlcGFyYXRvcjogXCJfXCIsXG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYHsgW2tleV06IHZhbHVlIH1gIGlmIGB2YWx1ZWAgaXMgZGVmaW5lZCwgb3RoZXJ3aXNlIHJldHVybnMgYHt9YCBzb1xuICogdGhhdCBvYmplY3Qgc3ByZWFkaW5nIGNhbiBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgcGVjdWxpYXIgaW50ZXJmYWNlLlxuICogQHBhcmFtIGtleVxuICogQHBhcmFtIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGdldE9iamVjdFdpdGhLZXlBbmRWYWx1ZUlmVmFsdWVJc0RlZmluZWQ8SyBleHRlbmRzIHN0cmluZywgVD4oXG4gIGtleTogSyxcbiAgdmFsdWU6IFQsXG4pOiB7IEs6IFQgfSB8IHt9IHtcbiAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgPyB7IFtrZXldOiB2YWx1ZSB9IDoge307XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBrZXkgYXQgdGhlIGdpdmVuIHBhdGggc2hvdWxkIGJlIGRlY2FtZWxpemVkLlxuICogTGFyZ2VseSwgYWxsIGtleXMgc2hvdWxkIGJlIHNuYWtlIGNhc2VkLiBCdXQsIHRoZXJlIGFyZSBzb21lXG4gKiBleGNlcHRpb25zIGZvciB1c2VyLXByb3ZpZGVkIG5hbWVzIGZvciBzZXJ2aWNlcywgdm9sdW1lcywgYW5kXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gKlxuICogQHBhcmFtIHBhdGhcbiAqL1xuZnVuY3Rpb24gc2hvdWxkRGVjYW1lbGl6ZURvY2tlckNvbXBvc2VLZXkocGF0aDogc3RyaW5nW10pIHtcbiAgY29uc3QgcG91bmRQYXRoID0gcGF0aC5qb2luKFwiI1wiKTtcblxuICAvLyBEb2VzIG5vdCBkZWNhbWVsaXplIHVzZXIncyBuYW1lcy5cbiAgLy8gc2VydmljZXMubmFtZWhlcmU6XG4gIC8vIHZvbHVtZXMubmFtZWhlcmU6XG4gIC8vIG5ldHdvcmtzLm5hbWVoZXJlOlxuICBpZiAoL14oc2VydmljZXN8dm9sdW1lc3xuZXR3b3JrcykjW14jXSskLy50ZXN0KHBvdW5kUGF0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBEb2VzIG5vdCBkZWNhbWVsaXplIGVudmlyb25tZW50IHZhcmlhYmxlcyBhbmQgbGFiZWxzXG4gIC8vIHNlcnZpY2VzLm5hbWVoZXJlLmVudmlyb25tZW50LipcbiAgLy8gc2VydmljZXMubmFtZWhlcmUubGFiZWxzLipcbiAgaWYgKC9ec2VydmljZXMjW14jXSsjKGVudmlyb25tZW50fGxhYmVscykjLy50ZXN0KHBvdW5kUGF0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBEb2VzIG5vdCBkZWNhbWVsaXplIGJ1aWxkIGFyZ3VtZW50c1xuICAvLyBzZXJ2aWNlcy5uYW1laGVyZS5idWlsZC5hcmdzLipcbiAgaWYgKC9ec2VydmljZXMjW14jXSsjYnVpbGQjYXJncyMvLnRlc3QocG91bmRQYXRoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIE90aGVyd2lzZSwgbGV0IGl0IGFsbCBkZWNhbWVsaXplLlxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==