aws-delivlib
Version:
A fabulous library for defining continuous pipelines for building, testing and releasing code libraries.
98 lines • 14 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.ChangeController = void 0;
const path = __importStar(require("path"));
const aws_cdk_lib_1 = require("aws-cdk-lib");
const constructs_1 = require("constructs");
/**
* Controls enabling and disabling a CodePipeline promotion into a particular stage based on "blocking" windows that are
* configured in an iCal document stored in an S3 bucket. If the document is not present or the bucket does not exist,
* the transition will be disabled.
*/
class ChangeController extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
let changeControlBucket = props.changeControlBucket;
let ownBucket;
if (!changeControlBucket) {
changeControlBucket = ownBucket = new aws_cdk_lib_1.aws_s3.Bucket(this, 'Calendar', {
removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
versioned: true,
});
}
// const changeControlBucket = props.changeControlBucket || new s3.Bucket(this, 'Bucket', { versioned: true });
const changeControlObjectKey = props.changeControlObjectKey || 'change-control.ics';
const fn = new aws_cdk_lib_1.aws_lambda_nodejs.NodejsFunction(this, 'Function', {
description: `Enforces a Change Control Policy into CodePipeline's ${props.pipelineStage.stageName} stage`,
entry: path.join(__dirname, 'change-control-lambda', 'index.ts'),
runtime: aws_cdk_lib_1.aws_lambda.Runtime.NODEJS_20_X,
environment: {
// CAPITAL punishment 👌🏻
CHANGE_CONTROL_BUCKET_NAME: changeControlBucket.bucketName,
CHANGE_CONTROL_OBJECT_KEY: changeControlObjectKey,
PIPELINE_NAME: props.pipelineStage.pipeline.pipelineName,
STAGE_NAME: props.pipelineStage.stageName,
},
timeout: aws_cdk_lib_1.Duration.seconds(300),
});
fn.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
resources: [`${props.pipelineStage.pipeline.pipelineArn}/${props.pipelineStage.stageName}`],
actions: ['codepipeline:EnableStageTransition', 'codepipeline:DisableStageTransition'],
}));
changeControlBucket.grantRead(fn, props.changeControlObjectKey);
if (ownBucket) {
ownBucket.addObjectCreatedNotification(new aws_cdk_lib_1.aws_s3_notifications.LambdaDestination(fn), {
prefix: changeControlObjectKey,
});
}
this.failureAlarm = new aws_cdk_lib_1.aws_cloudwatch.Alarm(this, 'Failed', {
metric: fn.metricErrors({
period: aws_cdk_lib_1.Duration.seconds(300),
}),
threshold: 1,
datapointsToAlarm: 1,
evaluationPeriods: 1,
});
const schedule = props.schedule || aws_cdk_lib_1.aws_events.Schedule.expression('rate(15 minutes)');
// Run this on a schedule
new aws_cdk_lib_1.aws_events.Rule(this, 'Rule', {
// tslint:disable-next-line:max-line-length
description: `Run the change controller for promotions into ${props.pipelineStage.pipeline.pipelineName}'s ${props.pipelineStage.stageName} on a ${schedule} schedule`,
schedule,
targets: [new aws_cdk_lib_1.aws_events_targets.LambdaFunction(fn)],
});
if (props.createOutputs !== false) {
new aws_cdk_lib_1.CfnOutput(this, 'ChangeControlBucketKey', {
value: changeControlObjectKey,
});
new aws_cdk_lib_1.CfnOutput(this, 'ChangeControlBucket', {
value: changeControlBucket.bucketName,
});
}
}
}
exports.ChangeController = ChangeController;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbmdlLWNvbnRyb2xsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjaGFuZ2UtY29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUE2QjtBQUM3Qiw2Q0FXcUI7QUFDckIsMkNBQXVDO0FBc0N2Qzs7OztHQUlHO0FBQ0gsTUFBYSxnQkFBaUIsU0FBUSxzQkFBUztJQU03QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTRCO1FBQ3BFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSxtQkFBbUIsR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUM7UUFDcEQsSUFBSSxTQUFnQyxDQUFDO1FBRXJDLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtZQUN4QixtQkFBbUIsR0FBRyxTQUFTLEdBQUcsSUFBSSxvQkFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUNoRSxhQUFhLEVBQUUsMkJBQWEsQ0FBQyxPQUFPO2dCQUNwQyxTQUFTLEVBQUUsSUFBSTthQUNoQixDQUFDLENBQUM7U0FDSjtRQUVELCtHQUErRztRQUMvRyxNQUFNLHNCQUFzQixHQUFHLEtBQUssQ0FBQyxzQkFBc0IsSUFBSSxvQkFBb0IsQ0FBQztRQUVwRixNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDckQsV0FBVyxFQUFFLHdEQUF3RCxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQVMsUUFBUTtZQUMxRyxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsdUJBQXVCLEVBQUUsVUFBVSxDQUFDO1lBQ2hFLE9BQU8sRUFBRSx3QkFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXO1lBQ25DLFdBQVcsRUFBRTtnQkFDWCwwQkFBMEI7Z0JBQzFCLDBCQUEwQixFQUFFLG1CQUFtQixDQUFDLFVBQVU7Z0JBQzFELHlCQUF5QixFQUFFLHNCQUFzQjtnQkFDakQsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLFlBQVk7Z0JBQ3hELFVBQVUsRUFBRSxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQVM7YUFDMUM7WUFDRCxPQUFPLEVBQUUsc0JBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO1NBQy9CLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxxQkFBRyxDQUFDLGVBQWUsQ0FBQztZQUN6QyxTQUFTLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLFdBQVcsSUFBSSxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzNGLE9BQU8sRUFBRSxDQUFDLG9DQUFvQyxFQUFFLHFDQUFxQyxDQUFDO1NBQ3ZGLENBQUMsQ0FBQyxDQUFDO1FBRUosbUJBQW1CLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUVoRSxJQUFJLFNBQVMsRUFBRTtZQUNiLFNBQVMsQ0FBQyw0QkFBNEIsQ0FBQyxJQUFJLGtDQUFnQixDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUNqRixNQUFNLEVBQUUsc0JBQXNCO2FBQy9CLENBQUMsQ0FBQztTQUNKO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLDRCQUFVLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7WUFDdkQsTUFBTSxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUM7Z0JBQ3RCLE1BQU0sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7YUFDOUIsQ0FBQztZQUNGLFNBQVMsRUFBRSxDQUFDO1lBQ1osaUJBQWlCLEVBQUUsQ0FBQztZQUNwQixpQkFBaUIsRUFBRSxDQUFDO1NBQ3JCLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLElBQUksd0JBQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFFbEYseUJBQXlCO1FBQ3pCLElBQUksd0JBQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRTtZQUM1QiwyQ0FBMkM7WUFDM0MsV0FBVyxFQUFFLGlEQUFpRCxLQUFLLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxZQUFZLE1BQU0sS0FBSyxDQUFDLGFBQWEsQ0FBQyxTQUFTLFNBQVMsUUFBUSxXQUFXO1lBQ3RLLFFBQVE7WUFDUixPQUFPLEVBQUUsQ0FBQyxJQUFJLGdDQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ2pELENBQUMsQ0FBQztRQUVILElBQUksS0FBSyxDQUFDLGFBQWEsS0FBSyxLQUFLLEVBQUU7WUFDakMsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSx3QkFBd0IsRUFBRTtnQkFDNUMsS0FBSyxFQUFFLHNCQUFzQjthQUM5QixDQUFDLENBQUM7WUFFSCxJQUFJLHVCQUFTLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFO2dCQUN6QyxLQUFLLEVBQUUsbUJBQW1CLENBQUMsVUFBVTthQUN0QyxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7Q0FDRjtBQTlFRCw0Q0E4RUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtcbiAgQ2ZuT3V0cHV0LCBEdXJhdGlvbiwgUmVtb3ZhbFBvbGljeSxcbiAgYXdzX2Nsb3Vkd2F0Y2ggYXMgY2xvdWR3YXRjaCxcbiAgYXdzX2NvZGVwaXBlbGluZSBhcyBjcCxcbiAgYXdzX2V2ZW50cyBhcyBldmVudHMsXG4gIGF3c19ldmVudHNfdGFyZ2V0cyBhcyBldmVudHNfdGFyZ2V0cyxcbiAgYXdzX2lhbSBhcyBpYW0sXG4gIGF3c19sYW1iZGEgYXMgbGFtYmRhLFxuICBhd3NfczMgYXMgczMsXG4gIGF3c19zM19ub3RpZmljYXRpb25zIGFzIHMzX25vdGlmaWNhdGlvbnMsXG4gIGF3c19sYW1iZGFfbm9kZWpzIGFzIG5vZGVqcyxcbn0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbmdlQ29udHJvbGxlclByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBidWNrZXQgaW4gd2hpY2ggdGhlIENoYW5nZUNvbnRyb2wgaUNhbCBkb2N1bWVudCB3aWxsIGJlIHN0b3JlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYSBuZXcgdmVyc2lvbmVkIGJ1Y2tldCB3aWxsIGJlIHByb3Zpc2lvbmVkLlxuICAgKi9cbiAgY2hhbmdlQ29udHJvbEJ1Y2tldD86IHMzLklCdWNrZXQ7XG5cbiAgLyoqXG4gICAqIFRoZSBrZXkgaW4gd2hpY2ggdGhlIGlDYWwgZmlsbGUgd2lsbCBiZSBzdG9yZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdjaGFuZ2UtY29udHJvbC5pY2FsJ1xuICAgKi9cbiAgY2hhbmdlQ29udHJvbE9iamVjdEtleT86IHN0cmluZztcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgc3RhZ2VcbiAgICovXG4gIHBpcGVsaW5lU3RhZ2U6IGNwLklTdGFnZTtcblxuICAvKipcbiAgICogU2NoZWR1bGUgdG8gcnVuIHRoZSBjaGFuZ2UgY29udHJvbGxlciBvblxuICAgKlxuICAgKiBAZGVmYXVsdCBvbmNlIGV2ZXJ5IDE1IG1pbnV0ZXNcbiAgICovXG4gIHNjaGVkdWxlPzogZXZlbnRzLlNjaGVkdWxlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBvdXRwdXRzIHRvIGluZm9ybSBvZiB0aGUgUzMgYnVja2V0IG5hbWUgYW5kIGtleXMgd2hlcmUgdGhlIGNoYW5nZSBjb250cm9sIGNhbGVuZGFyIHNob3VsZCBiZVxuICAgKiBzdG9yZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0cyB0cnVlXG4gICAqL1xuICBjcmVhdGVPdXRwdXRzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBDb250cm9scyBlbmFibGluZyBhbmQgZGlzYWJsaW5nIGEgQ29kZVBpcGVsaW5lIHByb21vdGlvbiBpbnRvIGEgcGFydGljdWxhciBzdGFnZSBiYXNlZCBvbiBcImJsb2NraW5nXCIgd2luZG93cyB0aGF0IGFyZVxuICogY29uZmlndXJlZCBpbiBhbiBpQ2FsIGRvY3VtZW50IHN0b3JlZCBpbiBhbiBTMyBidWNrZXQuIElmIHRoZSBkb2N1bWVudCBpcyBub3QgcHJlc2VudCBvciB0aGUgYnVja2V0IGRvZXMgbm90IGV4aXN0LFxuICogdGhlIHRyYW5zaXRpb24gd2lsbCBiZSBkaXNhYmxlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIENoYW5nZUNvbnRyb2xsZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIGFsYXJtIHRoYXQgd2lsbCBmaXJlIGluIGNhc2UgdGhlIGNoYW5nZSBjb250cm9sbGVyIGhhcyBmYWlsZWQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZmFpbHVyZUFsYXJtOiBjbG91ZHdhdGNoLkFsYXJtO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDaGFuZ2VDb250cm9sbGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgbGV0IGNoYW5nZUNvbnRyb2xCdWNrZXQgPSBwcm9wcy5jaGFuZ2VDb250cm9sQnVja2V0O1xuICAgIGxldCBvd25CdWNrZXQ6IHMzLkJ1Y2tldCB8IHVuZGVmaW5lZDtcblxuICAgIGlmICghY2hhbmdlQ29udHJvbEJ1Y2tldCkge1xuICAgICAgY2hhbmdlQ29udHJvbEJ1Y2tldCA9IG93bkJ1Y2tldCA9IG5ldyBzMy5CdWNrZXQodGhpcywgJ0NhbGVuZGFyJywge1xuICAgICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICAgIHZlcnNpb25lZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGNvbnN0IGNoYW5nZUNvbnRyb2xCdWNrZXQgPSBwcm9wcy5jaGFuZ2VDb250cm9sQnVja2V0IHx8IG5ldyBzMy5CdWNrZXQodGhpcywgJ0J1Y2tldCcsIHsgdmVyc2lvbmVkOiB0cnVlIH0pO1xuICAgIGNvbnN0IGNoYW5nZUNvbnRyb2xPYmplY3RLZXkgPSBwcm9wcy5jaGFuZ2VDb250cm9sT2JqZWN0S2V5IHx8ICdjaGFuZ2UtY29udHJvbC5pY3MnO1xuXG4gICAgY29uc3QgZm4gPSBuZXcgbm9kZWpzLk5vZGVqc0Z1bmN0aW9uKHRoaXMsICdGdW5jdGlvbicsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBgRW5mb3JjZXMgYSBDaGFuZ2UgQ29udHJvbCBQb2xpY3kgaW50byBDb2RlUGlwZWxpbmUncyAke3Byb3BzLnBpcGVsaW5lU3RhZ2Uuc3RhZ2VOYW1lfSBzdGFnZWAsXG4gICAgICBlbnRyeTogcGF0aC5qb2luKF9fZGlybmFtZSwgJ2NoYW5nZS1jb250cm9sLWxhbWJkYScsICdpbmRleC50cycpLFxuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICAvLyBDQVBJVEFMIHB1bmlzaG1lbnQg8J+RjPCfj7tcbiAgICAgICAgQ0hBTkdFX0NPTlRST0xfQlVDS0VUX05BTUU6IGNoYW5nZUNvbnRyb2xCdWNrZXQuYnVja2V0TmFtZSxcbiAgICAgICAgQ0hBTkdFX0NPTlRST0xfT0JKRUNUX0tFWTogY2hhbmdlQ29udHJvbE9iamVjdEtleSxcbiAgICAgICAgUElQRUxJTkVfTkFNRTogcHJvcHMucGlwZWxpbmVTdGFnZS5waXBlbGluZS5waXBlbGluZU5hbWUsXG4gICAgICAgIFNUQUdFX05BTUU6IHByb3BzLnBpcGVsaW5lU3RhZ2Uuc3RhZ2VOYW1lLFxuICAgICAgfSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMzAwKSxcbiAgICB9KTtcblxuICAgIGZuLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICByZXNvdXJjZXM6IFtgJHtwcm9wcy5waXBlbGluZVN0YWdlLnBpcGVsaW5lLnBpcGVsaW5lQXJufS8ke3Byb3BzLnBpcGVsaW5lU3RhZ2Uuc3RhZ2VOYW1lfWBdLFxuICAgICAgYWN0aW9uczogWydjb2RlcGlwZWxpbmU6RW5hYmxlU3RhZ2VUcmFuc2l0aW9uJywgJ2NvZGVwaXBlbGluZTpEaXNhYmxlU3RhZ2VUcmFuc2l0aW9uJ10sXG4gICAgfSkpO1xuXG4gICAgY2hhbmdlQ29udHJvbEJ1Y2tldC5ncmFudFJlYWQoZm4sIHByb3BzLmNoYW5nZUNvbnRyb2xPYmplY3RLZXkpO1xuXG4gICAgaWYgKG93bkJ1Y2tldCkge1xuICAgICAgb3duQnVja2V0LmFkZE9iamVjdENyZWF0ZWROb3RpZmljYXRpb24obmV3IHMzX25vdGlmaWNhdGlvbnMuTGFtYmRhRGVzdGluYXRpb24oZm4pLCB7XG4gICAgICAgIHByZWZpeDogY2hhbmdlQ29udHJvbE9iamVjdEtleSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZmFpbHVyZUFsYXJtID0gbmV3IGNsb3Vkd2F0Y2guQWxhcm0odGhpcywgJ0ZhaWxlZCcsIHtcbiAgICAgIG1ldHJpYzogZm4ubWV0cmljRXJyb3JzKHtcbiAgICAgICAgcGVyaW9kOiBEdXJhdGlvbi5zZWNvbmRzKDMwMCksXG4gICAgICB9KSxcbiAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiAxLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzY2hlZHVsZSA9IHByb3BzLnNjaGVkdWxlIHx8IGV2ZW50cy5TY2hlZHVsZS5leHByZXNzaW9uKCdyYXRlKDE1IG1pbnV0ZXMpJyk7XG5cbiAgICAvLyBSdW4gdGhpcyBvbiBhIHNjaGVkdWxlXG4gICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsICdSdWxlJywge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgZGVzY3JpcHRpb246IGBSdW4gdGhlIGNoYW5nZSBjb250cm9sbGVyIGZvciBwcm9tb3Rpb25zIGludG8gJHtwcm9wcy5waXBlbGluZVN0YWdlLnBpcGVsaW5lLnBpcGVsaW5lTmFtZX0ncyAke3Byb3BzLnBpcGVsaW5lU3RhZ2Uuc3RhZ2VOYW1lfSBvbiBhICR7c2NoZWR1bGV9IHNjaGVkdWxlYCxcbiAgICAgIHNjaGVkdWxlLFxuICAgICAgdGFyZ2V0czogW25ldyBldmVudHNfdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihmbildLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLmNyZWF0ZU91dHB1dHMgIT09IGZhbHNlKSB7XG4gICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdDaGFuZ2VDb250cm9sQnVja2V0S2V5Jywge1xuICAgICAgICB2YWx1ZTogY2hhbmdlQ29udHJvbE9iamVjdEtleSxcbiAgICAgIH0pO1xuXG4gICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdDaGFuZ2VDb250cm9sQnVja2V0Jywge1xuICAgICAgICB2YWx1ZTogY2hhbmdlQ29udHJvbEJ1Y2tldC5idWNrZXROYW1lLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iXX0=