cdk8s-cli
Version:
This is the command line tool for Cloud Development Kit (CDK) for Kubernetes (cdk8s).
239 lines • 32 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) {
this.manifests = manifests;
this.pkg = pkg;
this.version = version;
this.metadata = metadata;
this.stdout = stdout;
this.report = new ValidationReport(this.pkg, this.version, this.metadata ?? {}, 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) {
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 = this.metadata[resource.resourceName]?.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() {
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(json.summary.metadata ?? {}),
]));
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: ${construct.constructPath ?? '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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wbHVnaW5zL3ZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsdUNBQXlCO0FBQ3pCLGlDQUE4QjtBQUM5QiwyQ0FBNkI7QUFLN0I7O0dBRUc7QUFDSCxNQUFhLGlCQUFpQjtJQWdCNUI7SUFFRTs7T0FFRztJQUNhLFNBQTRCO0lBRTVDOztPQUVHO0lBQ2EsR0FBVztJQUUzQjs7T0FFRztJQUNhLE9BQWU7SUFFL0I7O09BRUc7SUFDYSxXQUFrRSxFQUFFO0lBRXBGOztPQUVHO0lBQ2EsTUFBZ0I7UUFwQmhCLGNBQVMsR0FBVCxTQUFTLENBQW1CO1FBSzVCLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFLWCxZQUFPLEdBQVAsT0FBTyxDQUFRO1FBS2YsYUFBUSxHQUFSLFFBQVEsQ0FBNEQ7UUFLcEUsV0FBTSxHQUFOLE1BQU0sQ0FBVTtRQUVoQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxFQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQztRQUNqRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0lBRU0sYUFBYSxDQUFDLFlBQW9CO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUYsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxD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UUFDaEUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHFCQUFxQixFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzRixNQUFNLFNBQVMsR0FBaUQsRUFBRSxDQUFDO1FBQ25FLElBQUksUUFBUSxDQUFDLE9BQU8sS0FBSyxPQUFPLEVBQUU7WUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MscUJBQXFCLEtBQUssUUFBUSxDQUFDLE9BQU8sbUNBQW1DLENBQUMsQ0FBQztTQUMvSTtRQUNELEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUNqRSxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUcsUUFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNwRDtRQUNELE9BQU8sU0FBUyxDQUFDO0lBRW5CLENBQUM7Q0FFRjtBQTFDRCw0Q0EwQ0M7QUFjRCxTQUFTLEtBQUssQ0FBQyxDQUFTO0lBQ3RCLE9BQU8sR0FBRyxDQUFDLFNBQVMsQ0FBQztBQUN2QixDQUFDO0FBRUQsU0FBUyxHQUFHLENBQUMsQ0FBUztJQUNwQixPQUFPLFdBQVcsQ0FBQyxFQUFFLENBQUM7QUFDeEIsQ0FBQztBQUVELFNBQVMsTUFBTSxDQUFDLENBQVM7SUFDdkIsT0FBTyxVQUFVLENBQUMsRUFBRSxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgeyB0YWJsZSB9IGZyb20gJ3RhYmxlJztcbmltcG9ydCAqIGFzIHlhbWwgZnJvbSAneWFtbCc7XG5pbXBvcnQgeyBQbHVnaW5NYW5hZ2VyIH0gZnJvbSAnLi9fbWFuYWdlcic7XG5pbXBvcnQgeyBWYWxpZGF0aW9uQ29uZmlnIH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7IFN5bnRoZXNpemVkQXBwIH0gZnJvbSAnLi4vdXRpbCc7XG5cbi8qKlxuICogQ29udGV4dCBhdmFpbGFibGUgdG8gcGx1Z2lucyBkdXJpbmcgdmFsaWRhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25Db250ZXh0IHtcblxuICAvKipcbiAgICogUmVwb3J0IGVtaXR0ZWQgYnkgdGhlIHZhbGlkYXRpb24uXG4gICAqXG4gICAqIFBsdWdpbnMgc2hvdWxkIGludGVyYWN0IHdpdGggdGhpcyBvYmplY3QgdG8gZ2VuZXJhdGUgdGhlIHJlcG9ydC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSByZXBvcnQ6IFZhbGlkYXRpb25SZXBvcnQ7XG5cbiAgLyoqXG4gICAqIExvZ2dlciBmb3IgdGhlIHZhbGlkYXRpb24uXG4gICAqXG4gICAqIFBsdWdpbnMgc2hvdWxkIGludGVyYWN0IHdpdGggdGhpcyBvYmplY3QgdG8gbG9nIG1lc3NhZ2VzIGR1cmluZyB2YWxpZGF0aW9uLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGxvZ2dlcjogVmFsaWRhdGlvbkxvZ2dlcjtcblxuICBjb25zdHJ1Y3RvcihcblxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIG1hbmlmZXN0cyB0byB2YWxpZGF0ZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgbWFuaWZlc3RzOiByZWFkb25seSBzdHJpbmdbXSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBOb2RlSlMgcGFja2FnZSBuYW1lIG9mIHRoZSBwbHVnaW4gcnVubmluZyB0aGUgdmFsaWRhdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgcGtnOiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgTm9kZUpTIHBhY2thZ2UgdGhhdCBydW5zIHRoZSB2YWxpZGF0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3QgbWV0YWRhdGEgb2YgcmVzb3VyY2VzIGluIHRoZSBhcHBsaWNhdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgbWV0YWRhdGE6IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogUmVzb3VyY2VDb25zdHJ1Y3RNZXRhZGF0YSB9ID0ge30sXG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgc3ludGggY29tbWFuZCB3YXMgZXhlY3V0ZWQgd2l0aCAtLXN0ZG91dC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgc3Rkb3V0PzogYm9vbGVhbikge1xuXG4gICAgdGhpcy5yZXBvcnQgPSBuZXcgVmFsaWRhdGlvblJlcG9ydCh0aGlzLnBrZywgdGhpcy52ZXJzaW9uLCB0aGlzLm1ldGFkYXRhID8/IHt9LCBzdGRvdXQgPz8gZmFsc2UpO1xuICAgIHRoaXMubG9nZ2VyID0gbmV3IFZhbGlkYXRpb25Mb2dnZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZU1hbmlmZXN0KG1hbmlmZXN0UGF0aDogc3RyaW5nKTogYW55W10ge1xuICAgIGNvbnN0IHBhcnNlZCA9IHlhbWwucGFyc2VBbGxEb2N1bWVudHMoZnMucmVhZEZpbGVTeW5jKG1hbmlmZXN0UGF0aCwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KSk7XG4gICAgY29uc3QgcmVzb3VyY2VzID0gQXJyYXkuaXNBcnJheShwYXJzZWQpID8gcGFyc2VkIDogW3BhcnNlZF07XG4gICAgcmV0dXJuIHJlc291cmNlcy5tYXAociA9PiByLnRvSlMoKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBMb2dnZXIgYXZhaWxhYmxlIHRvIHBsdWdpbnMgZHVyaW5nIHZhbGlkYXRpb24uIFVzZSB0aGlzIGluc3RlYWQgb2YgYGNvbnNvbGUubG9nYC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25Mb2dnZXIge1xuXG4gIC8qKlxuICAgKiBMb2cgYSBtZXNzYWdlLlxuICAgKi9cbiAgcHVibGljIGxvZyhtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZyhtZXNzYWdlKTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnRyYWN0IGJldHdlZW4gY2RrOHMgYW5kIHRoaXJkLXBhcnRpZXMgbG9va2luZyB0byBpbXBsZW1lbnQgdmFsaWRhdGlvbiBwbHVnaW5zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb24ge1xuXG4gIC8qKlxuICAgKiBSdW4gdGhlIHZhbGlkYXRpb24gbG9naWMuXG4gICAqXG4gICAqIC0gVXNlIGBjb250ZXh0Lm1hbmlmZXN0c2AgdG8gcmV0cmlldmUgdGhlIGxpc3Qgb2YgbWFuaWZlc3RzIHRvIHZhbGlkYXRlLlxuICAgKiAtIFVzZSBgY29udGV4dC5yZXBvcnRgIHRvIGFjY2VzcyBhbmQgYnVpbGQgdGhlIHJlc3VsdGluZyByZXBvcnQuXG4gICAqXG4gICAqIE1ha2Ugc3VyZSB0byBjYWxsIGBjb250ZXh0LnJlcG9ydC5wYXNzKClgIG9yIGBjb250ZXh0LnJlcG9ydC5mYWlsKClgIGJlZm9yZSByZXR1cm5pbmcsIG90aGVyd2lzZSB0aGUgdmFsaWRhdGlvbiBpcyBjb25zaWRlcmVkIGluY29tcGxldGUuXG4gICAqL1xuICB2YWxpZGF0ZShjb250ZXh0OiBWYWxpZGF0aW9uQ29udGV4dCk6IFByb21pc2U8dm9pZD47XG5cbn1cblxuLyoqXG4gKiBSZXNvdXJjZSB2aW9sYXRpbmcgYSBzcGVjaWZpYyBydWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25WaW9sYXRpbmdSZXNvdXJjZSB7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZSBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBsb2NhdGlvbnMgaW4gaXRzIGNvbmZpZyB0aGF0IHBvc2UgdGhlIHZpb2xhdGlvbnMuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbnM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgbWFuaWZlc3QgdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgbWFuaWZlc3RQYXRoOiBzdHJpbmc7XG5cbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3QgdmlvbGF0aW5nIGEgc3BlY2lmaWMgcnVsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uVmlvbGF0aW5nQ29uc3RydWN0IGV4dGVuZHMgVmFsaWRhdGlvblZpb2xhdGluZ1Jlc291cmNlIHtcblxuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdCBwYXRoIGFzIGRlZmluZWQgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uc3RydWN0UGF0aD86IHN0cmluZztcblxufVxuXG4vKipcbiAqIFZpb2xhdGlvbiBwcm9kdWNlZCBieSB0aGUgdmFsaWRhdGlvbiBwbHVnaW4uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdGlvblZpb2xhdGlvbiB7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBydWxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcnVsZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlY29tbWVuZGF0aW9uIHRvIHJlc29sdmUgdGhlIHZpb2xhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlY29tbWVuZGF0aW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyB0byBmaXggdGhlIHJlY29tbWVuZGF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZml4OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZXMgdmlvbGF0aW5nIHRoaXMgcnVsZS5cbiAgICovXG4gIHJlYWRvbmx5IHZpb2xhdGluZ1Jlc291cmNlczogcmVhZG9ubHkgVmFsaWRhdGlvblZpb2xhdGluZ1Jlc291cmNlW107XG5cbn1cblxuLyoqXG4gKiBWYWxpZGF0aW9uIHByb2R1Y2VkIGJ5IHRoZSB2YWxpZGF0aW9uIHBsdWdpbiwgaW4gY29uc3RydWN0IHRlcm1zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25WaW9sYXRpb25Db25zdHJ1Y3RBd2FyZSBleHRlbmRzIE9taXQ8VmFsaWRhdGlvblZpb2xhdGlvbiwgJ3Zpb2xhdGluZ1Jlc291cmNlcyc+IHtcblxuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdHMgdmlvbGF0aW5nIHRoaXMgcnVsZS5cbiAgICovXG4gIHJlYWRvbmx5IHZpb2xhdGluZ0NvbnN0cnVjdHM6IHJlYWRvbmx5IFZhbGlkYXRpb25WaW9sYXRpbmdDb25zdHJ1Y3RbXTtcbn1cblxuLy8gd2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYW4gZW51bSBzbyB0aGF0XG4vLyBwbHVnaW5zIGRvbid0IGhhdmUgdG8gaW1wb3J0IHRoZSBjbGkgYXQgcnVudGltZS5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25SZXBvcnRTdGF0dXMgPSAnc3VjY2VzcycgfCAnZmFpbHVyZSc7XG5cbi8qKlxuICogU3VtbWFyeSBvZiB0aGUgcmVwb3J0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25SZXBvcnRTdW1tYXJ5IHtcblxuICByZWFkb25seSBzdGF0dXM6IFZhbGlkYXRpb25SZXBvcnRTdGF0dXM7XG5cbiAgcmVhZG9ubHkgcGx1Z2luOiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IG1ldGFkYXRhPzogeyByZWFkb25seSBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcblxufVxuXG4vKipcbiAqIEpTT04gcmVwcmVzZW50YXRpb24gb2YgdGhlIHJlcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uUmVwb3J0SnNvbiB7XG5cbiAgLyoqXG4gICAqIFJlcG9ydCB0aXRsZS5cbiAgICovXG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIExpc3Qgb2YgdmlvbGF0aW9ucyBpbiB0aGUgcmVycG90LlxuICAgKi9cbiAgcmVhZG9ubHkgdmlvbGF0aW9uczogcmVhZG9ubHkgVmFsaWRhdGlvblZpb2xhdGlvbkNvbnN0cnVjdEF3YXJlW107XG5cbiAgLyoqXG4gICAqIFJlcG9ydCBzdW1tYXJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgc3VtbWFyeTogVmFsaWRhdGlvblJlcG9ydFN1bW1hcnk7XG5cbn1cblxuLyoqXG4gKiBUaGUgcmVwb3J0IGVtaXR0ZWQgYnkgdGhlIHBsdWdpbiBhZnRlciBldmFsdWF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvblJlcG9ydCB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2aW9sYXRpb25zOiBWYWxpZGF0aW9uVmlvbGF0aW9uQ29uc3RydWN0QXdhcmVbXSA9IFtdO1xuXG4gIHByaXZhdGUgX3N1bW1hcnk/OiBWYWxpZGF0aW9uUmVwb3J0U3VtbWFyeTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBrZzogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWV0YWRhdGE6IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogUmVzb3VyY2VDb25zdHJ1Y3RNZXRhZGF0YSB9LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgc3Rkb3V0OiBib29sZWFuKSB7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgdmlvbGF0aW9uIHRvIHRoZSByZXBvcnQuXG4gICAqL1xuICBwdWJsaWMgYWRkVmlvbGF0aW9uKHZpb2xhdGlvbjogVmFsaWRhdGlvblZpb2xhdGlvbikge1xuICAgIGlmICh0aGlzLl9zdW1tYXJ5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Zpb2xhdGlvbnMgY2Fubm90IGJlIGFkZGVkIHRvIHJlcG9ydCBhZnRlciBpdHMgc3VibWl0dGVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdmlvbGF0aW5nQ29uc3RydWN0czogVmFsaWRhdGlvblZpb2xhdGluZ0NvbnN0cnVjdFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHJlc291cmNlIG9mIHZpb2xhdGlvbi52aW9sYXRpbmdSZXNvdXJjZXMpIHtcbiAgICAgIGNvbnN0IGNvbnN0cnVjdFBhdGggPSB0aGlzLm1ldGFkYXRhW3Jlc291cmNlLnJlc291cmNlTmFtZV0/LnBhdGg7XG4gICAgICB2aW9sYXRpbmdDb25zdHJ1Y3RzLnB1c2goe1xuICAgICAgICAuLi5yZXNvdXJjZSxcblxuICAgICAgICAvLyBhdWdtZW50IHdpdGggY29uc3RydWN0IG1ldGFkYXRhXG4gICAgICAgIGNvbnN0cnVjdFBhdGg6IGNvbnN0cnVjdFBhdGgsXG5cbiAgICAgICAgLy8gaWYgc3ludGggaXMgZXhlY3V0ZWQgd2l0aCAtLXN0ZG91dCwgdGhlIG1hbmlmZXN0IHBhdGhcbiAgICAgICAgLy8gaGVyZSBpcyB0ZW1wb3JhcnkgYW5kIHdpbGwgYmUgZGVsZXRlZCBvbmNlIHRoZSBjb21tYW5kIGZpbmlzaGVzLlxuICAgICAgICBtYW5pZmVzdFBhdGg6IHRoaXMuc3Rkb3V0ID8gJ1NURE9VVCcgOiByZXNvdXJjZS5tYW5pZmVzdFBhdGgsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnZpb2xhdGlvbnMucHVzaCh7XG4gICAgICBydWxlTmFtZTogdmlvbGF0aW9uLnJ1bGVOYW1lLFxuICAgICAgcmVjb21tZW5kYXRpb246IHZpb2xhdGlvbi5yZWNvbW1lbmRhdGlvbixcbiAgICAgIHZpb2xhdGluZ0NvbnN0cnVjdHM6IHZpb2xhdGluZ0NvbnN0cnVjdHMsXG4gICAgICBmaXg6IHZpb2xhdGlvbi5maXgsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3VibWl0IHRoZSByZXBvcnQgd2l0aCBhIHN0YXR1cyBhbmQgYWRkaXRpb25hbCBtZXRhZGF0YS5cbiAgICovXG4gIHB1YmxpYyBzdWJtaXQoc3RhdHVzOiBWYWxpZGF0aW9uUmVwb3J0U3RhdHVzLCBtZXRhZGF0YT86IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pIHtcbiAgICB0aGlzLl9zdW1tYXJ5ID0geyBzdGF0dXMsIHBsdWdpbjogdGhpcy5wa2csIHZlcnNpb246IHRoaXMudmVyc2lvbiwgbWV0YWRhdGEgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgcmVwb3J0IHdhcyBzdWNjZXNzZnVsbC5cbiAgICovXG4gIHB1YmxpYyBnZXQgc3VjY2VzcygpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuX3N1bW1hcnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVybWluZSByZXBvcnQgc3RhdHVzOiBSZXBvcnQgaXMgaW5jb21wbGV0ZS4gQ2FsbCBcXCdyZXBvcnQuc3VibWl0XFwnJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zdW1tYXJ5LnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybSB0aGUgcmVwb3J0IHRvIGEgd2VsbCBmb3JtYXR0ZWQgdGFibGUgc3RyaW5nLlxuICAgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG5cbiAgICBjb25zdCBqc29uID0gdGhpcy50b0pzb24oKTtcbiAgICBjb25zdCBvdXRwdXQgPSBbanNvbi50aXRsZV07XG5cbiAgICBvdXRwdXQucHVzaCgnLScucmVwZWF0KGpzb24udGl0bGUubGVuZ3RoKSk7XG4gICAgb3V0cHV0LnB1c2goJycpO1xuICAgIG91dHB1dC5wdXNoKCcoU3VtbWFyeSknKTtcbiAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgb3V0cHV0LnB1c2godGFibGUoW1xuICAgICAgWydTdGF0dXMnLCBqc29uLnN1bW1hcnkuc3RhdHVzXSxcbiAgICAgIFsnUGx1Z2luJywganNvbi5zdW1tYXJ5LnBsdWdpbl0sXG4gICAgICBbJ1ZlcnNpb24nLCBqc29uLnN1bW1hcnkudmVyc2lvbl0sXG4gICAgICAuLi5PYmplY3QuZW50cmllcyhqc29uLnN1bW1hcnkubWV0YWRhdGEgPz8ge30pLFxuICAgIF0pKTtcblxuICAgIGlmIChqc29uLnZpb2xhdGlvbnMpIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICAgIG91dHB1dC5wdXNoKCcoVmlvbGF0aW9ucyknKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCB2aW9sYXRpb24gb2YganNvbi52aW9sYXRpb25zKSB7XG4gICAgICBjb25zdCBvY2N1cnJlbmNlcyA9IHZpb2xhdGlvbi52aW9sYXRpbmdDb25zdHJ1Y3RzLmZsYXRNYXAoYyA9PiBjLmxvY2F0aW9ucykubGVuZ3RoO1xuICAgICAgY29uc3QgdGl0bGUgPSByZXNldChyZWQoYnJpZ2h0KGAke3Zpb2xhdGlvbi5ydWxlTmFtZX0gKCR7b2NjdXJyZW5jZXN9IG9jY3VycmVuY2VzKWApKSk7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgICBvdXRwdXQucHVzaCh0aXRsZSk7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgICBvdXRwdXQucHVzaCgnICBPY2N1cnJlbmNlczonKTtcbiAgICAgIGZvciAoY29uc3QgY29uc3RydWN0IG9mIHZpb2xhdGlvbi52aW9sYXRpbmdDb25zdHJ1Y3RzKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICAgICAgb3V0cHV0LnB1c2goYCAgICAtIENvbnN0cnVjdCBQYXRoOiAke2NvbnN0cnVjdC5jb25zdHJ1Y3RQYXRoID8/ICdOL0EnfWApO1xuICAgICAgICBvdXRwdXQucHVzaChgICAgIC0gTWFuaWZlc3QgUGF0aDogJHtjb25zdHJ1Y3QubWFuaWZlc3RQYXRofWApO1xuICAgICAgICBvdXRwdXQucHVzaChgICAgIC0gUmVzb3VyY2UgTmFtZTogJHtjb25zdHJ1Y3QucmVzb3VyY2VOYW1lfWApO1xuICAgICAgICBpZiAoY29uc3RydWN0LmxvY2F0aW9ucykge1xuICAgICAgICAgIG91dHB1dC5wdXNoKCcgICAgLSBMb2NhdGlvbnM6Jyk7XG4gICAgICAgICAgZm9yIChjb25zdCBsb2NhdGlvbiBvZiBjb25zdHJ1Y3QubG9jYXRpb25zKSB7XG4gICAgICAgICAgICBvdXRwdXQucHVzaChgICAgICAgPiAke2xvY2F0aW9ufWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgICAgb3V0cHV0LnB1c2goYCAgUmVjb21tZW5kYXRpb246ICR7dmlvbGF0aW9uLnJlY29tbWVuZGF0aW9ufWApO1xuICAgICAgb3V0cHV0LnB1c2goYCAgSG93IHRvIGZpeDogJHt2aW9sYXRpb24uZml4fWApO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXQuam9pbihvcy5FT0wpO1xuXG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtIHRoZSByZXBvcnQgaW50byBhIEpTT04gb2JqZWN0LlxuICAgKi9cbiAgcHVibGljIHRvSnNvbigpOiBWYWxpZGF0aW9uUmVwb3J0SnNvbiB7XG4gICAgaWYgKCF0aGlzLl9zdW1tYXJ5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZXRlcm1pbmUgcmVwb3J0IHJlc3VsdDogUmVwb3J0IGlzIGluY29tcGxldGUuIENhbGwgXFwncmVwb3J0LnN1Ym1pdFxcJycpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdGl0bGU6IGBWYWxpZGF0aW9uIFJlcG9ydCAoJHt0aGlzLnBrZ31AJHt0aGlzLnZlcnNpb259KWAsXG4gICAgICB2aW9sYXRpb25zOiB0aGlzLnZpb2xhdGlvbnMsXG4gICAgICBzdW1tYXJ5OiB0aGlzLl9zdW1tYXJ5LFxuICAgIH07XG4gIH1cblxufVxuXG4vKipcbiAqIFV0aWxpeSBjbGFzcyBmb3IgbG9hZGluZyB2YWxpZGF0aW9uIHBsdWdpbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBWYWxpZGF0aW9uUGx1Z2luIHtcblxuICAvKipcbiAgICogTG9hZCB0aGUgdmFsaWRhdGlvbiBwbHVnaW4gYW5kIGNyZWF0ZSB0aGUgbmVjZXNzYXJ5IGNvbnRleHQgZm9yIGl0cyBleGVjdXRpb24uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGxvYWQoXG4gICAgdmFsaWRhdGlvbjogVmFsaWRhdGlvbkNvbmZpZyxcbiAgICBhcHA6IFN5bnRoZXNpemVkQXBwLFxuICAgIHN0ZG91dDogYm9vbGVhbixcbiAgICBwbHVnaW5NYW5hZ2VyOiBQbHVnaW5NYW5hZ2VyKTogeyBwbHVnaW46IFZhbGlkYXRpb247IGNvbnRleHQ6IFZhbGlkYXRpb25Db250ZXh0IH0ge1xuXG4gICAgY29uc3QgcGx1Z2luID0gcGx1Z2luTWFuYWdlci5sb2FkKHtcbiAgICAgIHBrZzogdmFsaWRhdGlvbi5wYWNrYWdlLFxuICAgICAgdmVyc2lvbjogdmFsaWRhdGlvbi52ZXJzaW9uLFxuICAgICAgY2xhc3M6IHZhbGlkYXRpb24uY2xhc3MsXG4gICAgICBwcm9wZXJ0aWVzOiB2YWxpZGF0aW9uLnByb3BlcnRpZXMsXG4gICAgICBpbnN0YWxsRW52OiB2YWxpZGF0aW9uLmluc3RhbGxFbnYsXG4gICAgfSk7XG5cbiAgICBpZiAodHlwZW9mKChwbHVnaW4uaW5zdGFuY2UgYXMgYW55KS52YWxpZGF0ZSkgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5zdGFuY2Ugb2YgY2xhc3MgJyR7dmFsaWRhdGlvbi5jbGFzc30nIGZyb20gcGFja2FnZSAnJHt2YWxpZGF0aW9uLnBhY2thZ2V9QCR7dmFsaWRhdGlvbi52ZXJzaW9ufScgaXMgbm90IGEgdmFsaWRhdGlvbiBwbHVnaW4uIEFyZSB5b3Ugc3VyZSB5b3Ugc3BlY2lmaWVkIHRoZSBjb3JyZWN0IGNsYXNzP2ApO1xuICAgIH1cblxuICAgIGNvbnN0IG1ldGFkYXRhID0gYXBwLmNvbnN0cnVjdE1ldGFkYXRhID8gdGhpcy5sb2FkQ29uc3RydWN0TWV0YWRhdGEoYXBwLmNvbnN0cnVjdE1ldGFkYXRhKSA6IHt9O1xuICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgVmFsaWRhdGlvbkNvbnRleHQoYXBwLm1hbmlmZXN0cywgcGx1Z2luLnBhY2thZ2UucGtnLCBwbHVnaW4ucGFja2FnZS52ZXJzaW9uLCBtZXRhZGF0YSwgc3Rkb3V0KTtcbiAgICByZXR1cm4geyBwbHVnaW46IHBsdWdpbi5pbnN0YW5jZSBhcyBWYWxpZGF0aW9uLCBjb250ZXh0IH07XG5cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxvYWRDb25zdHJ1Y3RNZXRhZGF0YShjb25zdHJ1Y3RNZXRhZGF0YVBhdGg6IHN0cmluZyk6IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogUmVzb3VyY2VDb25zdHJ1Y3RNZXRhZGF0YSB9IHtcbiAgICBjb25zdCBjb250ZW50cyA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGNvbnN0cnVjdE1ldGFkYXRhUGF0aCwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KSk7XG4gICAgY29uc3QgcmVzb3VyY2VzOiB7IFtrZXk6IHN0cmluZ106IFJlc291cmNlQ29uc3RydWN0TWV0YWRhdGEgfSA9IHt9O1xuICAgIGlmIChjb250ZW50cy52ZXJzaW9uICE9PSAnMS4wLjAnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgdmVyc2lvbiBvZiBjb25zdHJ1Y3QgbWV0YWRhdGEgYXQgJHtjb25zdHJ1Y3RNZXRhZGF0YVBhdGh9OiAke2NvbnRlbnRzLnZlcnNpb259LiBTdXBwb3J0ZWQgdmVyc2lvbnMgYXJlOiBbMS4wLjBdYCk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgW25hbWUsIG1ldGFkYXRhXSBvZiBPYmplY3QuZW50cmllcyhjb250ZW50cy5yZXNvdXJjZXMpKSB7XG4gICAgICByZXNvdXJjZXNbbmFtZV0gPSB7IHBhdGg6IChtZXRhZGF0YSBhcyBhbnkpLnBhdGggfTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc291cmNlcztcblxuICB9XG5cbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3QgcmVsYXRlZCBtZXRhZGF0YSBvbiByZXNvdXJjZXMuXG4gKi9cbmludGVyZmFjZSBSZXNvdXJjZUNvbnN0cnVjdE1ldGFkYXRhIHtcblxuICAvKipcbiAgICogVGhlIHBhdGggb2YgdGhlIGNvbnN0cnVjdCBpbiB0aGUgYXBwbGljYXRpb24uXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbn1cblxuZnVuY3Rpb24gcmVzZXQoczogc3RyaW5nKSB7XG4gIHJldHVybiBgJHtzfVxceDFiWzBtYDtcbn1cblxuZnVuY3Rpb24gcmVkKHM6IHN0cmluZykge1xuICByZXR1cm4gYFxceDFiWzMxbSR7c31gO1xufVxuXG5mdW5jdGlvbiBicmlnaHQoczogc3RyaW5nKSB7XG4gIHJldHVybiBgXFx4MWJbMW0ke3N9YDtcbn0iXX0=
;