UNPKG

@alma-cdk/cross-region-parameter

Version:

Store AWS SSM Parameter Store Parameters into another AWS Region with AWS CDK

120 lines 15.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrossRegionParameter = exports.OnEvent = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const iam = require("aws-cdk-lib/aws-iam"); const ssm = require("aws-cdk-lib/aws-ssm"); const cr = require("aws-cdk-lib/custom-resources"); const change_case_1 = require("change-case"); const constructs_1 = require("constructs"); const add_1 = require("./errors/add"); var OnEvent; (function (OnEvent) { OnEvent["ON_CREATE"] = "onCreate"; OnEvent["ON_UPDATE"] = "onUpdate"; OnEvent["ON_DELETE"] = "onDelete"; })(OnEvent || (exports.OnEvent = OnEvent = {})); /** Cross-Region SSM Parameter. */ class CrossRegionParameter extends constructs_1.Construct { /** * Define a new Cross-Region SSM Parameter. * * @example * new CrossRegionParameter(this, 'SayHiToSweden', { * region: 'eu-north-1', * name: '/parameter/path/message', * description: 'Some message for the Swedes', * value: 'Hej då!', * }); */ constructor(scope, name, props) { super(scope, name); this.validateRegion(props.region); const st = this.definePolicy(props); const policy = new iam.Policy(this, `${(0, change_case_1.pascalCase)(name)}CrPolicy`, { statements: [st], }); const role = new iam.Role(this, "ParameterCrRole", { assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"), }); role.attachInlinePolicy(policy); const customResource = new cr.AwsCustomResource(this, "AwsCustomResource", { onCreate: this.defineCreateUpdateSdkCall(OnEvent.ON_CREATE, props), onUpdate: this.defineCreateUpdateSdkCall(OnEvent.ON_UPDATE, props), onDelete: this.defineDeleteSdkCall(props), policy: cr.AwsCustomResourcePolicy.fromStatements([st]), role, }); customResource.node.addDependency(role); } definePhysicalResourceId(props) { const { region, name } = props; return cr.PhysicalResourceId.of(`CrossRegionParameter${(0, change_case_1.pascalCase)(region)}${(0, change_case_1.pascalCase)(name)}`); } defineCreateUpdateSdkCall(eventType, props) { const { region, name, description, value, allowedPattern, keyId, parameterTier: tier = ssm.ParameterTier.STANDARD, parameterType: type = ssm.ParameterType.STRING, tags, policies, } = props; const parameters = { Name: name /* required */, Value: value /* required */, AllowedPattern: allowedPattern, Description: description, KeyId: keyId, Overwrite: eventType !== OnEvent.ON_CREATE, Policies: policies, Tags: this.tagPropsToTagParams(tags), Tier: tier, Type: type, }; return { physicalResourceId: this.definePhysicalResourceId(props), region, service: "SSM", action: "putParameter", parameters, }; } /** Ensure Parameter target region is not the same as the current "source" region. */ validateRegion(region) { const currentRegion = aws_cdk_lib_1.Stack.of(this).region; if (currentRegion === region) { (0, add_1.addError)(this, `Parameter target region ${region} can not be the same as source region ${currentRegion}`); } } /** Convert CDK/JSII compatible TagPropList to SDK compatible TagList. */ tagPropsToTagParams(tags) { return tags?.map((t) => ({ Key: t.key, Value: t.value, })); } defineDeleteSdkCall(props) { const { region, name } = props; return { physicalResourceId: this.definePhysicalResourceId(props), region, service: "SSM", action: "deleteParameter", parameters: { Name: name, }, }; } definePolicy(props) { const { region, name } = props; // Depending if path parameter or simple parameter we may or may not need to set a slash separator to resource ARN const separator = name.indexOf("/") === 0 ? "" : "/"; return new iam.PolicyStatement({ actions: ["ssm:PutParameter", "ssm:DeleteParameter"], resources: [ `arn:aws:ssm:${region}:${aws_cdk_lib_1.Stack.of(this).account}:parameter${separator}${name}`, ], effect: iam.Effect.ALLOW, }); } } exports.CrossRegionParameter = CrossRegionParameter; _a = JSII_RTTI_SYMBOL_1; CrossRegionParameter[_a] = { fqn: "@alma-cdk/cross-region-parameter.CrossRegionParameter", version: "1.0.1" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BhcmFtZXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUFvQztBQUNwQywyQ0FBMkM7QUFDM0MsMkNBQTJDO0FBQzNDLG1EQUFtRDtBQUVuRCw2Q0FBeUM7QUFDekMsMkNBQXVDO0FBQ3ZDLHNDQUF3QztBQUd4QyxJQUFZLE9BSVg7QUFKRCxXQUFZLE9BQU87SUFDakIsaUNBQXNCLENBQUE7SUFDdEIsaUNBQXNCLENBQUE7SUFDdEIsaUNBQXNCLENBQUE7QUFDeEIsQ0FBQyxFQUpXLE9BQU8sdUJBQVAsT0FBTyxRQUlsQjtBQUVELGtDQUFrQztBQUNsQyxNQUFhLG9CQUFxQixTQUFRLHNCQUFTO0lBQ2pEOzs7Ozs7Ozs7O09BVUc7SUFDSCxZQUNFLEtBQWdCLEVBQ2hCLElBQVksRUFDWixLQUFnQztRQUVoQyxLQUFLLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRW5CLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWxDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFcEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxHQUFHLElBQUEsd0JBQVUsRUFBQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2pFLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQztTQUNqQixDQUFDLENBQUM7UUFFSCxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGlCQUFpQixFQUFFO1lBQ2pELFNBQVMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsQ0FBQztTQUM1RCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFaEMsTUFBTSxjQUFjLEdBQUcsSUFBSSxFQUFFLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ3pFLFFBQVEsRUFBRSxJQUFJLENBQUMseUJBQXlCLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUM7WUFDbEUsUUFBUSxFQUFFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQztZQUNsRSxRQUFRLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQztZQUN6QyxNQUFNLEVBQUUsRUFBRSxDQUFDLHVCQUF1QixDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZELElBQUk7U0FDTCxDQUFDLENBQUM7UUFFSCxjQUFjLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRU8sd0JBQXdCLENBQzlCLEtBQWdDO1FBRWhDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFDO1FBQy9CLE9BQU8sRUFBRSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FDN0IsdUJBQXVCLElBQUEsd0JBQVUsRUFBQyxNQUFNLENBQUMsR0FBRyxJQUFBLHdCQUFVLEVBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDL0QsQ0FBQztJQUNKLENBQUM7SUFFTyx5QkFBeUIsQ0FDL0IsU0FBa0IsRUFDbEIsS0FBZ0M7UUFFaEMsTUFBTSxFQUNKLE1BQU0sRUFDTixJQUFJLEVBQ0osV0FBVyxFQUNYLEtBQUssRUFDTCxjQUFjLEVBQ2QsS0FBSyxFQUNMLGFBQWEsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQ2hELGFBQWEsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQzlDLElBQUksRUFDSixRQUFRLEdBQ1QsR0FBRyxLQUFLLENBQUM7UUFFVixNQUFNLFVBQVUsR0FBd0I7WUFDdEMsSUFBSSxFQUFFLElBQUksQ0FBQyxjQUFjO1lBQ3pCLEtBQUssRUFBRSxLQUFLLENBQUMsY0FBYztZQUMzQixjQUFjLEVBQUUsY0FBYztZQUM5QixXQUFXLEVBQUUsV0FBVztZQUN4QixLQUFLLEVBQUUsS0FBSztZQUNaLFNBQVMsRUFBRSxTQUFTLEtBQUssT0FBTyxDQUFDLFNBQVM7WUFDMUMsUUFBUSxFQUFFLFFBQVE7WUFDbEIsSUFBSSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUM7WUFDcEMsSUFBSSxFQUFFLElBQUk7WUFDVixJQUFJLEVBQUUsSUFBSTtTQUNYLENBQUM7UUFFRixPQUFPO1lBQ0wsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQztZQUN4RCxNQUFNO1lBQ04sT0FBTyxFQUFFLEtBQUs7WUFDZCxNQUFNLEVBQUUsY0FBYztZQUN0QixVQUFVO1NBQ1gsQ0FBQztJQUNKLENBQUM7SUFFRCxxRkFBcUY7SUFDN0UsY0FBYyxDQUFDLE1BQWM7UUFDbkMsTUFBTSxhQUFhLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQzVDLElBQUksYUFBYSxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQzdCLElBQUEsY0FBUSxFQUNOLElBQUksRUFDSiwyQkFBMkIsTUFBTSx5Q0FBeUMsYUFBYSxFQUFFLENBQzFGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELHlFQUF5RTtJQUNqRSxtQkFBbUIsQ0FBQyxJQUFrQjtRQUM1QyxPQUFPLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdkIsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHO1lBQ1YsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLO1NBQ2YsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRU8sbUJBQW1CLENBQUMsS0FBZ0M7UUFDMUQsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFFL0IsT0FBTztZQUNMLGtCQUFrQixFQUFFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUM7WUFDeEQsTUFBTTtZQUNOLE9BQU8sRUFBRSxLQUFLO1lBQ2QsTUFBTSxFQUFFLGlCQUFpQjtZQUN6QixVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFLElBQUk7YUFDWDtTQUNGLENBQUM7SUFDSixDQUFDO0lBRU8sWUFBWSxDQUFDLEtBQWdDO1FBQ25ELE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFDO1FBRS9CLGtIQUFrSDtRQUNsSCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFFckQsT0FBTyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7WUFDN0IsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUscUJBQXFCLENBQUM7WUFDcEQsU0FBUyxFQUFFO2dCQUNULGVBQWUsTUFBTSxJQUFJLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sYUFBYSxTQUFTLEdBQUcsSUFBSSxFQUFFO2FBQy9FO1lBQ0QsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSztTQUN6QixDQUFDLENBQUM7SUFDTCxDQUFDOztBQTFJSCxvREEySUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdGFjayB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgKiBhcyBzc20gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zc21cIjtcbmltcG9ydCAqIGFzIGNyIGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCI7XG5pbXBvcnQgeyBQdXRQYXJhbWV0ZXJSZXF1ZXN0LCBUYWdMaXN0IH0gZnJvbSBcImF3cy1zZGsvY2xpZW50cy9zc21cIjtcbmltcG9ydCB7IHBhc2NhbENhc2UgfSBmcm9tIFwiY2hhbmdlLWNhc2VcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBhZGRFcnJvciB9IGZyb20gXCIuL2Vycm9ycy9hZGRcIjtcbmltcG9ydCB7IENyb3NzUmVnaW9uUGFyYW1ldGVyUHJvcHMsIFRhZ1Byb3BMaXN0IH0gZnJvbSBcIi4vcHJvcHNcIjtcblxuZXhwb3J0IGVudW0gT25FdmVudCB7XG4gIE9OX0NSRUFURSA9IFwib25DcmVhdGVcIixcbiAgT05fVVBEQVRFID0gXCJvblVwZGF0ZVwiLFxuICBPTl9ERUxFVEUgPSBcIm9uRGVsZXRlXCIsXG59XG5cbi8qKiBDcm9zcy1SZWdpb24gU1NNIFBhcmFtZXRlci4gKi9cbmV4cG9ydCBjbGFzcyBDcm9zc1JlZ2lvblBhcmFtZXRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBEZWZpbmUgYSBuZXcgQ3Jvc3MtUmVnaW9uIFNTTSBQYXJhbWV0ZXIuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIG5ldyBDcm9zc1JlZ2lvblBhcmFtZXRlcih0aGlzLCAnU2F5SGlUb1N3ZWRlbicsIHtcbiAgICogICByZWdpb246ICdldS1ub3J0aC0xJyxcbiAgICogICBuYW1lOiAnL3BhcmFtZXRlci9wYXRoL21lc3NhZ2UnLFxuICAgKiAgIGRlc2NyaXB0aW9uOiAnU29tZSBtZXNzYWdlIGZvciB0aGUgU3dlZGVzJyxcbiAgICogICB2YWx1ZTogJ0hlaiBkw6UhJyxcbiAgICogfSk7XG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBwcm9wczogQ3Jvc3NSZWdpb25QYXJhbWV0ZXJQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIG5hbWUpO1xuXG4gICAgdGhpcy52YWxpZGF0ZVJlZ2lvbihwcm9wcy5yZWdpb24pO1xuXG4gICAgY29uc3Qgc3QgPSB0aGlzLmRlZmluZVBvbGljeShwcm9wcyk7XG5cbiAgICBjb25zdCBwb2xpY3kgPSBuZXcgaWFtLlBvbGljeSh0aGlzLCBgJHtwYXNjYWxDYXNlKG5hbWUpfUNyUG9saWN5YCwge1xuICAgICAgc3RhdGVtZW50czogW3N0XSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgXCJQYXJhbWV0ZXJDclJvbGVcIiwge1xuICAgICAgYXNzdW1lZEJ5OiBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoXCJsYW1iZGEuYW1hem9uYXdzLmNvbVwiKSxcbiAgICB9KTtcblxuICAgIHJvbGUuYXR0YWNoSW5saW5lUG9saWN5KHBvbGljeSk7XG5cbiAgICBjb25zdCBjdXN0b21SZXNvdXJjZSA9IG5ldyBjci5Bd3NDdXN0b21SZXNvdXJjZSh0aGlzLCBcIkF3c0N1c3RvbVJlc291cmNlXCIsIHtcbiAgICAgIG9uQ3JlYXRlOiB0aGlzLmRlZmluZUNyZWF0ZVVwZGF0ZVNka0NhbGwoT25FdmVudC5PTl9DUkVBVEUsIHByb3BzKSxcbiAgICAgIG9uVXBkYXRlOiB0aGlzLmRlZmluZUNyZWF0ZVVwZGF0ZVNka0NhbGwoT25FdmVudC5PTl9VUERBVEUsIHByb3BzKSxcbiAgICAgIG9uRGVsZXRlOiB0aGlzLmRlZmluZURlbGV0ZVNka0NhbGwocHJvcHMpLFxuICAgICAgcG9saWN5OiBjci5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeS5mcm9tU3RhdGVtZW50cyhbc3RdKSxcbiAgICAgIHJvbGUsXG4gICAgfSk7XG5cbiAgICBjdXN0b21SZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3kocm9sZSk7XG4gIH1cblxuICBwcml2YXRlIGRlZmluZVBoeXNpY2FsUmVzb3VyY2VJZChcbiAgICBwcm9wczogQ3Jvc3NSZWdpb25QYXJhbWV0ZXJQcm9wcyxcbiAgKTogY3IuUGh5c2ljYWxSZXNvdXJjZUlkIHtcbiAgICBjb25zdCB7IHJlZ2lvbiwgbmFtZSB9ID0gcHJvcHM7XG4gICAgcmV0dXJuIGNyLlBoeXNpY2FsUmVzb3VyY2VJZC5vZihcbiAgICAgIGBDcm9zc1JlZ2lvblBhcmFtZXRlciR7cGFzY2FsQ2FzZShyZWdpb24pfSR7cGFzY2FsQ2FzZShuYW1lKX1gLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGRlZmluZUNyZWF0ZVVwZGF0ZVNka0NhbGwoXG4gICAgZXZlbnRUeXBlOiBPbkV2ZW50LFxuICAgIHByb3BzOiBDcm9zc1JlZ2lvblBhcmFtZXRlclByb3BzLFxuICApOiBjci5Bd3NTZGtDYWxsIHtcbiAgICBjb25zdCB7XG4gICAgICByZWdpb24sXG4gICAgICBuYW1lLFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICB2YWx1ZSxcbiAgICAgIGFsbG93ZWRQYXR0ZXJuLFxuICAgICAga2V5SWQsXG4gICAgICBwYXJhbWV0ZXJUaWVyOiB0aWVyID0gc3NtLlBhcmFtZXRlclRpZXIuU1RBTkRBUkQsXG4gICAgICBwYXJhbWV0ZXJUeXBlOiB0eXBlID0gc3NtLlBhcmFtZXRlclR5cGUuU1RSSU5HLFxuICAgICAgdGFncyxcbiAgICAgIHBvbGljaWVzLFxuICAgIH0gPSBwcm9wcztcblxuICAgIGNvbnN0IHBhcmFtZXRlcnM6IFB1dFBhcmFtZXRlclJlcXVlc3QgPSB7XG4gICAgICBOYW1lOiBuYW1lIC8qIHJlcXVpcmVkICovLFxuICAgICAgVmFsdWU6IHZhbHVlIC8qIHJlcXVpcmVkICovLFxuICAgICAgQWxsb3dlZFBhdHRlcm46IGFsbG93ZWRQYXR0ZXJuLFxuICAgICAgRGVzY3JpcHRpb246IGRlc2NyaXB0aW9uLFxuICAgICAgS2V5SWQ6IGtleUlkLFxuICAgICAgT3ZlcndyaXRlOiBldmVudFR5cGUgIT09IE9uRXZlbnQuT05fQ1JFQVRFLFxuICAgICAgUG9saWNpZXM6IHBvbGljaWVzLFxuICAgICAgVGFnczogdGhpcy50YWdQcm9wc1RvVGFnUGFyYW1zKHRhZ3MpLFxuICAgICAgVGllcjogdGllcixcbiAgICAgIFR5cGU6IHR5cGUsXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IHRoaXMuZGVmaW5lUGh5c2ljYWxSZXNvdXJjZUlkKHByb3BzKSxcbiAgICAgIHJlZ2lvbixcbiAgICAgIHNlcnZpY2U6IFwiU1NNXCIsXG4gICAgICBhY3Rpb246IFwicHV0UGFyYW1ldGVyXCIsXG4gICAgICBwYXJhbWV0ZXJzLFxuICAgIH07XG4gIH1cblxuICAvKiogRW5zdXJlIFBhcmFtZXRlciB0YXJnZXQgcmVnaW9uIGlzIG5vdCB0aGUgc2FtZSBhcyB0aGUgY3VycmVudCBcInNvdXJjZVwiIHJlZ2lvbi4gKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVJlZ2lvbihyZWdpb246IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRSZWdpb24gPSBTdGFjay5vZih0aGlzKS5yZWdpb247XG4gICAgaWYgKGN1cnJlbnRSZWdpb24gPT09IHJlZ2lvbikge1xuICAgICAgYWRkRXJyb3IoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIGBQYXJhbWV0ZXIgdGFyZ2V0IHJlZ2lvbiAke3JlZ2lvbn0gY2FuIG5vdCBiZSB0aGUgc2FtZSBhcyBzb3VyY2UgcmVnaW9uICR7Y3VycmVudFJlZ2lvbn1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ29udmVydCBDREsvSlNJSSBjb21wYXRpYmxlIFRhZ1Byb3BMaXN0IHRvIFNESyBjb21wYXRpYmxlIFRhZ0xpc3QuICovXG4gIHByaXZhdGUgdGFnUHJvcHNUb1RhZ1BhcmFtcyh0YWdzPzogVGFnUHJvcExpc3QpOiBUYWdMaXN0IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGFncz8ubWFwKCh0KSA9PiAoe1xuICAgICAgS2V5OiB0LmtleSxcbiAgICAgIFZhbHVlOiB0LnZhbHVlLFxuICAgIH0pKTtcbiAgfVxuXG4gIHByaXZhdGUgZGVmaW5lRGVsZXRlU2RrQ2FsbChwcm9wczogQ3Jvc3NSZWdpb25QYXJhbWV0ZXJQcm9wcyk6IGNyLkF3c1Nka0NhbGwge1xuICAgIGNvbnN0IHsgcmVnaW9uLCBuYW1lIH0gPSBwcm9wcztcblxuICAgIHJldHVybiB7XG4gICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IHRoaXMuZGVmaW5lUGh5c2ljYWxSZXNvdXJjZUlkKHByb3BzKSxcbiAgICAgIHJlZ2lvbixcbiAgICAgIHNlcnZpY2U6IFwiU1NNXCIsXG4gICAgICBhY3Rpb246IFwiZGVsZXRlUGFyYW1ldGVyXCIsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIE5hbWU6IG5hbWUsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGRlZmluZVBvbGljeShwcm9wczogQ3Jvc3NSZWdpb25QYXJhbWV0ZXJQcm9wcyk6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQge1xuICAgIGNvbnN0IHsgcmVnaW9uLCBuYW1lIH0gPSBwcm9wcztcblxuICAgIC8vIERlcGVuZGluZyBpZiBwYXRoIHBhcmFtZXRlciBvciBzaW1wbGUgcGFyYW1ldGVyIHdlIG1heSBvciBtYXkgbm90IG5lZWQgdG8gc2V0IGEgc2xhc2ggc2VwYXJhdG9yIHRvIHJlc291cmNlIEFSTlxuICAgIGNvbnN0IHNlcGFyYXRvciA9IG5hbWUuaW5kZXhPZihcIi9cIikgPT09IDAgPyBcIlwiIDogXCIvXCI7XG5cbiAgICByZXR1cm4gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1wic3NtOlB1dFBhcmFtZXRlclwiLCBcInNzbTpEZWxldGVQYXJhbWV0ZXJcIl0sXG4gICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgYGFybjphd3M6c3NtOiR7cmVnaW9ufToke1N0YWNrLm9mKHRoaXMpLmFjY291bnR9OnBhcmFtZXRlciR7c2VwYXJhdG9yfSR7bmFtZX1gLFxuICAgICAgXSxcbiAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICB9KTtcbiAgfVxufVxuIl19