cdk8s-cli
Version:
This is the command line tool for Cloud Development Kit (CDK) for Kubernetes (cdk8s).
242 lines • 32.3 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidationPlugin = exports.ValidationReport = exports.ValidationLogger = exports.ValidationContext = void 0;
const fs = __importStar(require("fs"));
const os = __importStar(require("os"));
const table_1 = require("table");
const yaml = __importStar(require("yaml"));
/**
* Context available to plugins during validation.
*/
class ValidationContext {
constructor(
/**
* The list of manifests to validate.
*/
manifests,
/**
* The NodeJS package name of the plugin running the validation.
*/
pkg,
/**
* The version of the NodeJS package that runs the validation.
*/
version,
/**
* Construct metadata of resources in the application.
*/
metadata = {},
/**
* Whether or not the synth command was executed with --stdout.
*/
stdout) {
var _a;
this.manifests = manifests;
this.pkg = pkg;
this.version = version;
this.metadata = metadata;
this.stdout = stdout;
this.report = new ValidationReport(this.pkg, this.version, (_a = this.metadata) !== null && _a !== void 0 ? _a : {}, stdout !== null && stdout !== void 0 ? stdout : false);
this.logger = new ValidationLogger();
}
parseManifest(manifestPath) {
const parsed = yaml.parseAllDocuments(fs.readFileSync(manifestPath, { encoding: 'utf-8' }));
const resources = Array.isArray(parsed) ? parsed : [parsed];
return resources.map(r => r.toJS());
}
}
exports.ValidationContext = ValidationContext;
/**
* Logger available to plugins during validation. Use this instead of `console.log`.
*/
class ValidationLogger {
/**
* Log a message.
*/
log(message) {
console.log(message);
}
}
exports.ValidationLogger = ValidationLogger;
/**
* The report emitted by the plugin after evaluation.
*/
class ValidationReport {
constructor(pkg, version, metadata, stdout) {
this.pkg = pkg;
this.version = version;
this.metadata = metadata;
this.stdout = stdout;
this.violations = [];
}
/**
* Add a violation to the report.
*/
addViolation(violation) {
var _a;
if (this._summary) {
throw new Error('Violations cannot be added to report after its submitted');
}
const violatingConstructs = [];
for (const resource of violation.violatingResources) {
const constructPath = (_a = this.metadata[resource.resourceName]) === null || _a === void 0 ? void 0 : _a.path;
violatingConstructs.push({
...resource,
// augment with construct metadata
constructPath: constructPath,
// if synth is executed with --stdout, the manifest path
// here is temporary and will be deleted once the command finishes.
manifestPath: this.stdout ? 'STDOUT' : resource.manifestPath,
});
}
this.violations.push({
ruleName: violation.ruleName,
recommendation: violation.recommendation,
violatingConstructs: violatingConstructs,
fix: violation.fix,
});
}
/**
* Submit the report with a status and additional metadata.
*/
submit(status, metadata) {
this._summary = { status, plugin: this.pkg, version: this.version, metadata };
}
/**
* Whether or not the report was successfull.
*/
get success() {
if (!this._summary) {
throw new Error('Unable to determine report status: Report is incomplete. Call \'report.submit\'');
}
return this._summary.status === 'success';
}
/**
* Transform the report to a well formatted table string.
*/
toString() {
var _a, _b;
const json = this.toJson();
const output = [json.title];
output.push('-'.repeat(json.title.length));
output.push('');
output.push('(Summary)');
output.push('');
output.push((0, table_1.table)([
['Status', json.summary.status],
['Plugin', json.summary.plugin],
['Version', json.summary.version],
...Object.entries((_a = json.summary.metadata) !== null && _a !== void 0 ? _a : {}),
]));
if (json.violations) {
output.push('');
output.push('(Violations)');
}
for (const violation of json.violations) {
const occurrences = violation.violatingConstructs.flatMap(c => c.locations).length;
const title = reset(red(bright(`${violation.ruleName} (${occurrences} occurrences)`)));
output.push('');
output.push(title);
output.push('');
output.push(' Occurrences:');
for (const construct of violation.violatingConstructs) {
output.push('');
output.push(` - Construct Path: ${(_b = construct.constructPath) !== null && _b !== void 0 ? _b : 'N/A'}`);
output.push(` - Manifest Path: ${construct.manifestPath}`);
output.push(` - Resource Name: ${construct.resourceName}`);
if (construct.locations) {
output.push(' - Locations:');
for (const location of construct.locations) {
output.push(` > ${location}`);
}
}
}
output.push('');
output.push(` Recommendation: ${violation.recommendation}`);
output.push(` How to fix: ${violation.fix}`);
}
return output.join(os.EOL);
}
/**
* Transform the report into a JSON object.
*/
toJson() {
if (!this._summary) {
throw new Error('Unable to determine report result: Report is incomplete. Call \'report.submit\'');
}
return {
title: `Validation Report (${this.pkg}@${this.version})`,
violations: this.violations,
summary: this._summary,
};
}
}
exports.ValidationReport = ValidationReport;
/**
* Utiliy class for loading validation plugins.
*/
class ValidationPlugin {
/**
* Load the validation plugin and create the necessary context for its execution.
*/
static load(validation, app, stdout, pluginManager) {
const plugin = pluginManager.load({
pkg: validation.package,
version: validation.version,
class: validation.class,
properties: validation.properties,
installEnv: validation.installEnv,
});
if (typeof (plugin.instance.validate) !== 'function') {
throw new Error(`Instance of class '${validation.class}' from package '${validation.package}@${validation.version}' is not a validation plugin. Are you sure you specified the correct class?`);
}
const metadata = app.constructMetadata ? this.loadConstructMetadata(app.constructMetadata) : {};
const context = new ValidationContext(app.manifests, plugin.package.pkg, plugin.package.version, metadata, stdout);
return { plugin: plugin.instance, context };
}
static loadConstructMetadata(constructMetadataPath) {
const contents = JSON.parse(fs.readFileSync(constructMetadataPath, { encoding: 'utf-8' }));
const resources = {};
if (contents.version !== '1.0.0') {
throw new Error(`Unexpected version of construct metadata at ${constructMetadataPath}: ${contents.version}. Supported versions are: [1.0.0]`);
}
for (const [name, metadata] of Object.entries(contents.resources)) {
resources[name] = { path: metadata.path };
}
return resources;
}
}
exports.ValidationPlugin = ValidationPlugin;
function reset(s) {
return `${s}\x1b[0m`;
}
function red(s) {
return `\x1b[31m${s}`;
}
function bright(s) {
return `\x1b[1m${s}`;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wbHVnaW5zL3ZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsdUNBQXlCO0FBQ3pCLGlDQUE4QjtBQUM5QiwyQ0FBNkI7QUFLN0I7O0dBRUc7QUFDSCxNQUFhLGlCQUFpQjtJQWdCNUI7SUFFRTs7T0FFRztJQUNhLFNBQTRCO0lBRTVDOztPQUVHO0lBQ2EsR0FBVztJQUUzQjs7T0FFRztJQUNhLE9BQWU7SUFFL0I7O09BRUc7SUFDYSxXQUFnRSxFQUFFO0lBRWxGOztPQUVHO0lBQ2EsTUFBZ0I7O1FBcEJoQixjQUFTLEdBQVQsU0FBUyxDQUFtQjtRQUs1QixRQUFHLEdBQUgsR0FBRyxDQUFRO1FBS1gsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQUtmLGFBQVEsR0FBUixRQUFRLENBQTBEO1FBS2xFLFdBQU0sR0FBTixNQUFNLENBQVU7UUFFaEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFBLElBQUksQ0FBQyxRQUFRLG1DQUFJLEVBQUUsRUFBRSxNQUFNLGFBQU4sTUFBTSxjQUFOLE1BQU0sR0FBSSxLQUFLLENBQUMsQ0FBQztRQUNqRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0lBRU0sYUFBYSxDQUFDLFlBQW9CO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUYsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFD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QztJQUU1RCxDQUFDO0lBRU8sTUFBTSxDQUFDLHFCQUFxQixDQUFDLHFCQUE2QjtRQUNoRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMscUJBQXFCLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzNGLE1BQU0sU0FBUyxHQUFpRCxFQUFFLENBQUM7UUFDbkUsSUFBSSxRQUFRLENBQUMsT0FBTyxLQUFLLE9BQU8sRUFBRTtZQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxxQkFBcUIsS0FBSyxRQUFRLENBQUMsT0FBTyxtQ0FBbUMsQ0FBQyxDQUFDO1NBQy9JO1FBQ0QsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ2pFLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRyxRQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO1NBQ3BEO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFFbkIsQ0FBQztDQUVGO0FBMUNELDRDQTBDQztBQWNELFNBQVMsS0FBSyxDQUFDLENBQVM7SUFDdEIsT0FBTyxHQUFHLENBQUMsU0FBUyxDQUFDO0FBQ3ZCLENBQUM7QUFFRCxTQUFTLEdBQUcsQ0FBQyxDQUFTO0lBQ3BCLE9BQU8sV0FBVyxDQUFDLEVBQUUsQ0FBQztBQUN4QixDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsQ0FBUztJQUN2QixPQUFPLFVBQVUsQ0FBQyxFQUFFLENBQUM7QUFDdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIG9zIGZyb20gJ29zJztcbmltcG9ydCB7IHRhYmxlIH0gZnJvbSAndGFibGUnO1xuaW1wb3J0ICogYXMgeWFtbCBmcm9tICd5YW1sJztcbmltcG9ydCB7IFBsdWdpbk1hbmFnZXIgfSBmcm9tICcuL19tYW5hZ2VyJztcbmltcG9ydCB7IFZhbGlkYXRpb25Db25maWcgfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHsgU3ludGhlc2l6ZWRBcHAgfSBmcm9tICcuLi91dGlsJztcblxuLyoqXG4gKiBDb250ZXh0IGF2YWlsYWJsZSB0byBwbHVnaW5zIGR1cmluZyB2YWxpZGF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkNvbnRleHQge1xuXG4gIC8qKlxuICAgKiBSZXBvcnQgZW1pdHRlZCBieSB0aGUgdmFsaWRhdGlvbi5cbiAgICpcbiAgICogUGx1Z2lucyBzaG91bGQgaW50ZXJhY3Qgd2l0aCB0aGlzIG9iamVjdCB0byBnZW5lcmF0ZSB0aGUgcmVwb3J0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJlcG9ydDogVmFsaWRhdGlvblJlcG9ydDtcblxuICAvKipcbiAgICogTG9nZ2VyIGZvciB0aGUgdmFsaWRhdGlvbi5cbiAgICpcbiAgICogUGx1Z2lucyBzaG91bGQgaW50ZXJhY3Qgd2l0aCB0aGlzIG9iamVjdCB0byBsb2cgbWVzc2FnZXMgZHVyaW5nIHZhbGlkYXRpb24uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbG9nZ2VyOiBWYWxpZGF0aW9uTG9nZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKFxuXG4gICAgLyoqXG4gICAgICogVGhlIGxpc3Qgb2YgbWFuaWZlc3RzIHRvIHZhbGlkYXRlLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBtYW5pZmVzdHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuXG4gICAgLyoqXG4gICAgICogVGhlIE5vZGVKUyBwYWNrYWdlIG5hbWUgb2YgdGhlIHBsdWdpbiBydW5uaW5nIHRoZSB2YWxpZGF0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBwa2c6IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB2ZXJzaW9uIG9mIHRoZSBOb2RlSlMgcGFja2FnZSB0aGF0IHJ1bnMgdGhlIHZhbGlkYXRpb24uXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBtZXRhZGF0YSBvZiByZXNvdXJjZXMgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBtZXRhZGF0YToge3JlYWRvbmx5IFtrZXk6IHN0cmluZ106IFJlc291cmNlQ29uc3RydWN0TWV0YWRhdGF9ID0ge30sXG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgc3ludGggY29tbWFuZCB3YXMgZXhlY3V0ZWQgd2l0aCAtLXN0ZG91dC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgc3Rkb3V0PzogYm9vbGVhbikge1xuXG4gICAgdGhpcy5yZXBvcnQgPSBuZXcgVmFsaWRhdGlvblJlcG9ydCh0aGlzLnBrZywgdGhpcy52ZXJzaW9uLCB0aGlzLm1ldGFkYXRhID8/IHt9LCBzdGRvdXQgPz8gZmFsc2UpO1xuICAgIHRoaXMubG9nZ2VyID0gbmV3IFZhbGlkYXRpb25Mb2dnZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZU1hbmlmZXN0KG1hbmlmZXN0UGF0aDogc3RyaW5nKTogYW55W10ge1xuICAgIGNvbnN0IHBhcnNlZCA9IHlhbWwucGFyc2VBbGxEb2N1bWVudHMoZnMucmVhZEZpbGVTeW5jKG1hbmlmZXN0UGF0aCwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KSk7XG4gICAgY29uc3QgcmVzb3VyY2VzID0gQXJyYXkuaXNBcnJheShwYXJzZWQpID8gcGFyc2VkIDogW3BhcnNlZF07XG4gICAgcmV0dXJuIHJlc291cmNlcy5tYXAociA9PiByLnRvSlMoKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBMb2dnZXIgYXZhaWxhYmxlIHRvIHBsdWdpbnMgZHVyaW5nIHZhbGlkYXRpb24uIFVzZSB0aGlzIGluc3RlYWQgb2YgYGNvbnNvbGUubG9nYC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25Mb2dnZXIge1xuXG4gIC8qKlxuICAgKiBMb2cgYSBtZXNzYWdlLlxuICAgKi9cbiAgcHVibGljIGxvZyhtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZyhtZXNzYWdlKTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnRyYWN0IGJldHdlZW4gY2RrOHMgYW5kIHRoaXJkLXBhcnRpZXMgbG9va2luZyB0byBpbXBsZW1lbnQgdmFsaWRhdGlvbiBwbHVnaW5zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb24ge1xuXG4gIC8qKlxuICAgKiBSdW4gdGhlIHZhbGlkYXRpb24gbG9naWMuXG4gICAqXG4gICAqIC0gVXNlIGBjb250ZXh0Lm1hbmlmZXN0c2AgdG8gcmV0cmlldmUgdGhlIGxpc3Qgb2YgbWFuaWZlc3RzIHRvIHZhbGlkYXRlLlxuICAgKiAtIFVzZSBgY29udGV4dC5yZXBvcnRgIHRvIGFjY2VzcyBhbmQgYnVpbGQgdGhlIHJlc3VsdGluZyByZXBvcnQuXG4gICAqXG4gICAqIE1ha2Ugc3VyZSB0byBjYWxsIGBjb250ZXh0LnJlcG9ydC5wYXNzKClgIG9yIGBjb250ZXh0LnJlcG9ydC5mYWlsKClgIGJlZm9yZSByZXR1cm5pbmcsIG90aGVyd2lzZSB0aGUgdmFsaWRhdGlvbiBpcyBjb25zaWRlcmVkIGluY29tcGxldGUuXG4gICAqL1xuICB2YWxpZGF0ZShjb250ZXh0OiBWYWxpZGF0aW9uQ29udGV4dCk6IFByb21pc2U8dm9pZD47XG5cbn1cblxuLyoqXG4gKiBSZXNvdXJjZSB2aW9sYXRpbmcgYSBzcGVjaWZpYyBydWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25WaW9sYXRpbmdSZXNvdXJjZSB7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZSBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBsb2NhdGlvbnMgaW4gaXRzIGNvbmZpZyB0aGF0IHBvc2UgdGhlIHZpb2xhdGlvbnMuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbnM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgbWFuaWZlc3QgdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgbWFuaWZlc3RQYXRoOiBzdHJpbmc7XG5cbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3QgdmlvbGF0aW5nIGEgc3BlY2lmaWMgcnVsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uVmlvbGF0aW5nQ29uc3RydWN0IGV4dGVuZHMgVmFsaWRhdGlvblZpb2xhdGluZ1Jlc291cmNlIHtcblxuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdCBwYXRoIGFzIGRlZmluZWQgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uc3RydWN0UGF0aD86IHN0cmluZztcblxufVxuXG4vKipcbiAqIFZpb2xhdGlvbiBwcm9kdWNlZCBieSB0aGUgdmFsaWRhdGlvbiBwbHVnaW4uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdGlvblZpb2xhdGlvbiB7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBydWxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcnVsZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlY29tbWVuZGF0aW9uIHRvIHJlc29sdmUgdGhlIHZpb2xhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlY29tbWVuZGF0aW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyB0byBmaXggdGhlIHJlY29tbWVuZGF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZml4OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZXMgdmlvbGF0aW5nIHRoaXMgcnVsZS5cbiAgICovXG4gIHJlYWRvbmx5IHZpb2xhdGluZ1Jlc291cmNlczogcmVhZG9ubHkgVmFsaWRhdGlvblZpb2xhdGluZ1Jlc291cmNlW107XG5cbn1cblxuLyoqXG4gKiBWYWxpZGF0aW9uIHByb2R1Y2VkIGJ5IHRoZSB2YWxpZGF0aW9uIHBsdWdpbiwgaW4gY29uc3RydWN0IHRlcm1zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25WaW9sYXRpb25Db25zdHJ1Y3RBd2FyZSBleHRlbmRzIE9taXQ8VmFsaWRhdGlvblZpb2xhdGlvbiwgJ3Zpb2xhdGluZ1Jlc291cmNlcyc+IHtcblxuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdHMgdmlvbGF0aW5nIHRoaXMgcnVsZS5cbiAgICovXG4gIHJlYWRvbmx5IHZpb2xhdGluZ0NvbnN0cnVjdHM6IHJlYWRvbmx5IFZhbGlkYXRpb25WaW9sYXRpbmdDb25zdHJ1Y3RbXTtcbn1cblxuLy8gd2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYW4gZW51bSBzbyB0aGF0XG4vLyBwbHVnaW5zIGRvbid0IGhhdmUgdG8gaW1wb3J0IHRoZSBjbGkgYXQgcnVudGltZS5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25SZXBvcnRTdGF0dXMgPSAnc3VjY2VzcycgfCAnZmFpbHVyZSc7XG5cbi8qKlxuICogU3VtbWFyeSBvZiB0aGUgcmVwb3J0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25SZXBvcnRTdW1tYXJ5IHtcblxuICByZWFkb25seSBzdGF0dXM6IFZhbGlkYXRpb25SZXBvcnRTdGF0dXM7XG5cbiAgcmVhZG9ubHkgcGx1Z2luOiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IG1ldGFkYXRhPzogeyByZWFkb25seSBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcblxufVxuXG4vKipcbiAqIEpTT04gcmVwcmVzZW50YXRpb24gb2YgdGhlIHJlcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uUmVwb3J0SnNvbiB7XG5cbiAgLyoqXG4gICAqIFJlcG9ydCB0aXRsZS5cbiAgICovXG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIExpc3Qgb2YgdmlvbGF0aW9ucyBpbiB0aGUgcmVycG90LlxuICAgKi9cbiAgcmVhZG9ubHkgdmlvbGF0aW9uczogcmVhZG9ubHkgVmFsaWRhdGlvblZpb2xhdGlvbkNvbnN0cnVjdEF3YXJlW107XG5cbiAgLyoqXG4gICAqIFJlcG9ydCBzdW1tYXJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgc3VtbWFyeTogVmFsaWRhdGlvblJlcG9ydFN1bW1hcnk7XG5cbn1cblxuLyoqXG4gKiBUaGUgcmVwb3J0IGVtaXR0ZWQgYnkgdGhlIHBsdWdpbiBhZnRlciBldmFsdWF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvblJlcG9ydCB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2aW9sYXRpb25zOiBWYWxpZGF0aW9uVmlvbGF0aW9uQ29uc3RydWN0QXdhcmVbXSA9IFtdO1xuXG4gIHByaXZhdGUgX3N1bW1hcnk/OiBWYWxpZGF0aW9uUmVwb3J0U3VtbWFyeTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBrZzogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWV0YWRhdGE6IHtyZWFkb25seSBba2V5OiBzdHJpbmddOiBSZXNvdXJjZUNvbnN0cnVjdE1ldGFkYXRhfSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0ZG91dDogYm9vbGVhbikge1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIHZpb2xhdGlvbiB0byB0aGUgcmVwb3J0LlxuICAgKi9cbiAgcHVibGljIGFkZFZpb2xhdGlvbih2aW9sYXRpb246IFZhbGlkYXRpb25WaW9sYXRpb24pIHtcbiAgICBpZiAodGhpcy5fc3VtbWFyeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWaW9sYXRpb25zIGNhbm5vdCBiZSBhZGRlZCB0byByZXBvcnQgYWZ0ZXIgaXRzIHN1Ym1pdHRlZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHZpb2xhdGluZ0NvbnN0cnVjdHM6IFZhbGlkYXRpb25WaW9sYXRpbmdDb25zdHJ1Y3RbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByZXNvdXJjZSBvZiB2aW9sYXRpb24udmlvbGF0aW5nUmVzb3VyY2VzKSB7XG4gICAgICBjb25zdCBjb25zdHJ1Y3RQYXRoID0gdGhpcy5tZXRhZGF0YVtyZXNvdXJjZS5yZXNvdXJjZU5hbWVdPy5wYXRoO1xuICAgICAgdmlvbGF0aW5nQ29uc3RydWN0cy5wdXNoKHtcbiAgICAgICAgLi4ucmVzb3VyY2UsXG5cbiAgICAgICAgLy8gYXVnbWVudCB3aXRoIGNvbnN0cnVjdCBtZXRhZGF0YVxuICAgICAgICBjb25zdHJ1Y3RQYXRoOiBjb25zdHJ1Y3RQYXRoLFxuXG4gICAgICAgIC8vIGlmIHN5bnRoIGlzIGV4ZWN1dGVkIHdpdGggLS1zdGRvdXQsIHRoZSBtYW5pZmVzdCBwYXRoXG4gICAgICAgIC8vIGhlcmUgaXMgdGVtcG9yYXJ5IGFuZCB3aWxsIGJlIGRlbGV0ZWQgb25jZSB0aGUgY29tbWFuZCBmaW5pc2hlcy5cbiAgICAgICAgbWFuaWZlc3RQYXRoOiB0aGlzLnN0ZG91dCA/ICdTVERPVVQnIDogcmVzb3VyY2UubWFuaWZlc3RQYXRoLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy52aW9sYXRpb25zLnB1c2goe1xuICAgICAgcnVsZU5hbWU6IHZpb2xhdGlvbi5ydWxlTmFtZSxcbiAgICAgIHJlY29tbWVuZGF0aW9uOiB2aW9sYXRpb24ucmVjb21tZW5kYXRpb24sXG4gICAgICB2aW9sYXRpbmdDb25zdHJ1Y3RzOiB2aW9sYXRpbmdDb25zdHJ1Y3RzLFxuICAgICAgZml4OiB2aW9sYXRpb24uZml4LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1Ym1pdCB0aGUgcmVwb3J0IHdpdGggYSBzdGF0dXMgYW5kIGFkZGl0aW9uYWwgbWV0YWRhdGEuXG4gICAqL1xuICBwdWJsaWMgc3VibWl0KHN0YXR1czogVmFsaWRhdGlvblJlcG9ydFN0YXR1cywgbWV0YWRhdGE/OiB7IHJlYWRvbmx5IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KSB7XG4gICAgdGhpcy5fc3VtbWFyeSA9IHsgc3RhdHVzLCBwbHVnaW46IHRoaXMucGtnLCB2ZXJzaW9uOiB0aGlzLnZlcnNpb24sIG1ldGFkYXRhIH07XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciBvciBub3QgdGhlIHJlcG9ydCB3YXMgc3VjY2Vzc2Z1bGwuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHN1Y2Nlc3MoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLl9zdW1tYXJ5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZXRlcm1pbmUgcmVwb3J0IHN0YXR1czogUmVwb3J0IGlzIGluY29tcGxldGUuIENhbGwgXFwncmVwb3J0LnN1Ym1pdFxcJycpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3VtbWFyeS5zdGF0dXMgPT09ICdzdWNjZXNzJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gdGhlIHJlcG9ydCB0byBhIHdlbGwgZm9ybWF0dGVkIHRhYmxlIHN0cmluZy5cbiAgICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuXG4gICAgY29uc3QganNvbiA9IHRoaXMudG9Kc29uKCk7XG4gICAgY29uc3Qgb3V0cHV0ID0gW2pzb24udGl0bGVdO1xuXG4gICAgb3V0cHV0LnB1c2goJy0nLnJlcGVhdChqc29uLnRpdGxlLmxlbmd0aCkpO1xuICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICBvdXRwdXQucHVzaCgnKFN1bW1hcnkpJyk7XG4gICAgb3V0cHV0LnB1c2goJycpO1xuICAgIG91dHB1dC5wdXNoKHRhYmxlKFtcbiAgICAgIFsnU3RhdHVzJywganNvbi5zdW1tYXJ5LnN0YXR1c10sXG4gICAgICBbJ1BsdWdpbicsIGpzb24uc3VtbWFyeS5wbHVnaW5dLFxuICAgICAgWydWZXJzaW9uJywganNvbi5zdW1tYXJ5LnZlcnNpb25dLFxuICAgICAgLi4uT2JqZWN0LmVudHJpZXMoanNvbi5zdW1tYXJ5Lm1ldGFkYXRhID8/IHt9KSxcbiAgICBdKSk7XG5cbiAgICBpZiAoanNvbi52aW9sYXRpb25zKSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgICBvdXRwdXQucHVzaCgnKFZpb2xhdGlvbnMpJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgdmlvbGF0aW9uIG9mIGpzb24udmlvbGF0aW9ucykge1xuICAgICAgY29uc3Qgb2NjdXJyZW5jZXMgPSB2aW9sYXRpb24udmlvbGF0aW5nQ29uc3RydWN0cy5mbGF0TWFwKGMgPT4gYy5sb2NhdGlvbnMpLmxlbmd0aDtcbiAgICAgIGNvbnN0IHRpdGxlID0gcmVzZXQocmVkKGJyaWdodChgJHt2aW9sYXRpb24ucnVsZU5hbWV9ICgke29jY3VycmVuY2VzfSBvY2N1cnJlbmNlcylgKSkpO1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgICAgb3V0cHV0LnB1c2godGl0bGUpO1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgICAgb3V0cHV0LnB1c2goJyAgT2NjdXJyZW5jZXM6Jyk7XG4gICAgICBmb3IgKGNvbnN0IGNvbnN0cnVjdCBvZiB2aW9sYXRpb24udmlvbGF0aW5nQ29uc3RydWN0cykge1xuICAgICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgICAgIG91dHB1dC5wdXNoKGAgICAgLSBDb25zdHJ1Y3QgUGF0aDogJHtjb25zdHJ1Y3QuY29uc3RydWN0UGF0aCA/PyAnTi9BJ31gKTtcbiAgICAgICAgb3V0cHV0LnB1c2goYCAgICAtIE1hbmlmZXN0IFBhdGg6ICR7Y29uc3RydWN0Lm1hbmlmZXN0UGF0aH1gKTtcbiAgICAgICAgb3V0cHV0LnB1c2goYCAgICAtIFJlc291cmNlIE5hbWU6ICR7Y29uc3RydWN0LnJlc291cmNlTmFtZX1gKTtcbiAgICAgICAgaWYgKGNvbnN0cnVjdC5sb2NhdGlvbnMpIHtcbiAgICAgICAgICBvdXRwdXQucHVzaCgnICAgIC0gTG9jYXRpb25zOicpO1xuICAgICAgICAgIGZvciAoY29uc3QgbG9jYXRpb24gb2YgY29uc3RydWN0LmxvY2F0aW9ucykge1xuICAgICAgICAgICAgb3V0cHV0LnB1c2goYCAgICAgID4gJHtsb2NhdGlvbn1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICAgIG91dHB1dC5wdXNoKGAgIFJlY29tbWVuZGF0aW9uOiAke3Zpb2xhdGlvbi5yZWNvbW1lbmRhdGlvbn1gKTtcbiAgICAgIG91dHB1dC5wdXNoKGAgIEhvdyB0byBmaXg6ICR7dmlvbGF0aW9uLmZpeH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0LmpvaW4ob3MuRU9MKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybSB0aGUgcmVwb3J0IGludG8gYSBKU09OIG9iamVjdC5cbiAgICovXG4gIHB1YmxpYyB0b0pzb24oKTogVmFsaWRhdGlvblJlcG9ydEpzb24ge1xuICAgIGlmICghdGhpcy5fc3VtbWFyeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGV0ZXJtaW5lIHJlcG9ydCByZXN1bHQ6IFJlcG9ydCBpcyBpbmNvbXBsZXRlLiBDYWxsIFxcJ3JlcG9ydC5zdWJtaXRcXCcnKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRpdGxlOiBgVmFsaWRhdGlvbiBSZXBvcnQgKCR7dGhpcy5wa2d9QCR7dGhpcy52ZXJzaW9ufSlgLFxuICAgICAgdmlvbGF0aW9uczogdGhpcy52aW9sYXRpb25zLFxuICAgICAgc3VtbWFyeTogdGhpcy5fc3VtbWFyeSxcbiAgICB9O1xuICB9XG5cbn1cblxuLyoqXG4gKiBVdGlsaXkgY2xhc3MgZm9yIGxvYWRpbmcgdmFsaWRhdGlvbiBwbHVnaW5zLlxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvblBsdWdpbiB7XG5cbiAgLyoqXG4gICAqIExvYWQgdGhlIHZhbGlkYXRpb24gcGx1Z2luIGFuZCBjcmVhdGUgdGhlIG5lY2Vzc2FyeSBjb250ZXh0IGZvciBpdHMgZXhlY3V0aW9uLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBsb2FkKFxuICAgIHZhbGlkYXRpb246IFZhbGlkYXRpb25Db25maWcsXG4gICAgYXBwOiBTeW50aGVzaXplZEFwcCxcbiAgICBzdGRvdXQ6IGJvb2xlYW4sXG4gICAgcGx1Z2luTWFuYWdlcjogUGx1Z2luTWFuYWdlcik6IHsgcGx1Z2luOiBWYWxpZGF0aW9uOyBjb250ZXh0OiBWYWxpZGF0aW9uQ29udGV4dCB9IHtcblxuICAgIGNvbnN0IHBsdWdpbiA9IHBsdWdpbk1hbmFnZXIubG9hZCh7XG4gICAgICBwa2c6IHZhbGlkYXRpb24ucGFja2FnZSxcbiAgICAgIHZlcnNpb246IHZhbGlkYXRpb24udmVyc2lvbixcbiAgICAgIGNsYXNzOiB2YWxpZGF0aW9uLmNsYXNzLFxuICAgICAgcHJvcGVydGllczogdmFsaWRhdGlvbi5wcm9wZXJ0aWVzLFxuICAgICAgaW5zdGFsbEVudjogdmFsaWRhdGlvbi5pbnN0YWxsRW52LFxuICAgIH0pO1xuXG4gICAgaWYgKHR5cGVvZigocGx1Z2luLmluc3RhbmNlIGFzIGFueSkudmFsaWRhdGUpICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEluc3RhbmNlIG9mIGNsYXNzICcke3ZhbGlkYXRpb24uY2xhc3N9JyBmcm9tIHBhY2thZ2UgJyR7dmFsaWRhdGlvbi5wYWNrYWdlfUAke3ZhbGlkYXRpb24udmVyc2lvbn0nIGlzIG5vdCBhIHZhbGlkYXRpb24gcGx1Z2luLiBBcmUgeW91IHN1cmUgeW91IHNwZWNpZmllZCB0aGUgY29ycmVjdCBjbGFzcz9gKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IGFwcC5jb25zdHJ1Y3RNZXRhZGF0YSA/IHRoaXMubG9hZENvbnN0cnVjdE1ldGFkYXRhKGFwcC5jb25zdHJ1Y3RNZXRhZGF0YSkgOiB7fTtcbiAgICBjb25zdCBjb250ZXh0ID0gbmV3IFZhbGlkYXRpb25Db250ZXh0KGFwcC5tYW5pZmVzdHMsIHBsdWdpbi5wYWNrYWdlLnBrZywgcGx1Z2luLnBhY2thZ2UudmVyc2lvbiwgbWV0YWRhdGEsIHN0ZG91dCk7XG4gICAgcmV0dXJuIHsgcGx1Z2luOiBwbHVnaW4uaW5zdGFuY2UgYXMgVmFsaWRhdGlvbiwgY29udGV4dCB9O1xuXG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBsb2FkQ29uc3RydWN0TWV0YWRhdGEoY29uc3RydWN0TWV0YWRhdGFQYXRoOiBzdHJpbmcpOiB7IHJlYWRvbmx5IFtrZXk6IHN0cmluZ106IFJlc291cmNlQ29uc3RydWN0TWV0YWRhdGEgfSB7XG4gICAgY29uc3QgY29udGVudHMgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhjb25zdHJ1Y3RNZXRhZGF0YVBhdGgsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSkpO1xuICAgIGNvbnN0IHJlc291cmNlczogeyBba2V5OiBzdHJpbmddOiBSZXNvdXJjZUNvbnN0cnVjdE1ldGFkYXRhIH0gPSB7fTtcbiAgICBpZiAoY29udGVudHMudmVyc2lvbiAhPT0gJzEuMC4wJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIHZlcnNpb24gb2YgY29uc3RydWN0IG1ldGFkYXRhIGF0ICR7Y29uc3RydWN0TWV0YWRhdGFQYXRofTogJHtjb250ZW50cy52ZXJzaW9ufS4gU3VwcG9ydGVkIHZlcnNpb25zIGFyZTogWzEuMC4wXWApO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBtZXRhZGF0YV0gb2YgT2JqZWN0LmVudHJpZXMoY29udGVudHMucmVzb3VyY2VzKSkge1xuICAgICAgcmVzb3VyY2VzW25hbWVdID0geyBwYXRoOiAobWV0YWRhdGEgYXMgYW55KS5wYXRoIH07XG4gICAgfVxuICAgIHJldHVybiByZXNvdXJjZXM7XG5cbiAgfVxuXG59XG5cbi8qKlxuICogQ29uc3RydWN0IHJlbGF0ZWQgbWV0YWRhdGEgb24gcmVzb3VyY2VzLlxuICovXG5pbnRlcmZhY2UgUmVzb3VyY2VDb25zdHJ1Y3RNZXRhZGF0YSB7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXRoIG9mIHRoZSBjb25zdHJ1Y3QgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuXG59XG5cbmZ1bmN0aW9uIHJlc2V0KHM6IHN0cmluZykge1xuICByZXR1cm4gYCR7c31cXHgxYlswbWA7XG59XG5cbmZ1bmN0aW9uIHJlZChzOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGBcXHgxYlszMW0ke3N9YDtcbn1cblxuZnVuY3Rpb24gYnJpZ2h0KHM6IHN0cmluZykge1xuICByZXR1cm4gYFxceDFiWzFtJHtzfWA7XG59Il19
;