UNPKG

cdk-rds-sql

Version:

A CDK construct that allows creating roles and databases an on Aurora Serverless Postgresql cluster.

138 lines 20.9 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.Provider = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const fs_1 = require("fs"); const path = require("path"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_ec2_1 = require("aws-cdk-lib/aws-ec2"); const iam = require("aws-cdk-lib/aws-iam"); const aws_lambda_1 = require("aws-cdk-lib/aws-lambda"); const lambda = require("aws-cdk-lib/aws-lambda-nodejs"); const customResources = require("aws-cdk-lib/custom-resources"); const constructs_1 = require("constructs"); class Provider extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); this.secret = props.secret; this.cluster = props.cluster; // Determine engine from cluster/instance instead of hardcoding if ("clusterIdentifier" in props.cluster) { // It's a DatabaseCluster const clusterEngine = props.cluster.engine; this.engine = clusterEngine && clusterEngine.engineFamily === "MYSQL" ? "mysql" : "postgres"; } else if ("instanceIdentifier" in props.cluster) { // It's a DatabaseInstance const instanceEngine = props.cluster.engine; this.engine = instanceEngine && instanceEngine.engineFamily === "MYSQL" ? "mysql" : "postgres"; } else { // Fallback to postgres if engine hasn't been provided this.engine = "postgres"; } const functionName = "RdsSql" + slugify("28b9e791-af60-4a33-bca8-ffb6f30ef8c5"); this.handler = aws_cdk_lib_1.Stack.of(this).node.tryFindChild(functionName) ?? this.newCustomResourceHandler(scope, functionName, props); const provider = new customResources.Provider(this, "RdsSql", { onEventHandler: this.handler, }); this.serviceToken = provider.serviceToken; this.secret.grantRead(this.handler); if (this.secret.encryptionKey) { // It seems we need to grant explicit permission this.secret.encryptionKey.grantDecrypt(this.handler); } if (props.cluster.connections.securityGroups.length === 0) { throw new Error("Cluster does not have a security group."); } else { this.handler.node.defaultChild?.node.addDependency(props.cluster.connections.securityGroups[0]); } this.node.addDependency(props.cluster); } newCustomResourceHandler(scope, id, props) { const handlerDir = path.join(__dirname, "handler"); const index_ts = path.join(handlerDir, "index.ts"); const index_js = path.join(handlerDir, "index.js"); let entry; if ((0, fs_1.existsSync)(index_ts)) { entry = index_ts; } else if ((0, fs_1.existsSync)(index_js)) { entry = index_js; } else { // Ugly hack to support SST (possibly caused by my hack to make SST work with CommonJS libraries) entry = path.join(path.dirname(process.env.npm_package_json || process.cwd()), "node_modules/cdk-rds-sql/lib/handler/index.js"); } let ssl_options; if (props.ssl !== undefined && !props.ssl) { ssl_options = { SSL: JSON.stringify(props.ssl), }; } const logger = props.logger ?? false; const deleteParameterPolicy = new iam.PolicyStatement({ actions: ["ssm:DeleteParameter"], resources: [ `arn:aws:ssm:${aws_cdk_lib_1.Stack.of(scope).region}:${aws_cdk_lib_1.Stack.of(scope).account}:parameter/*`, ], conditions: { StringEquals: { "ssm:ResourceTag/created-by": "cdk-rds-sql", }, }, }); const fn = new lambda.NodejsFunction(scope, id, { ...props.functionProps, vpc: props.vpc, vpcSubnets: props.vpcSubnets ?? { subnetType: aws_ec2_1.SubnetType.PRIVATE_ISOLATED, }, entry: entry, runtime: aws_lambda_1.Runtime.NODEJS_20_X, timeout: props.timeout ?? props.functionProps?.timeout ?? aws_cdk_lib_1.Duration.seconds(300), bundling: { // Include the migrations directory in the bundle commandHooks: { beforeBundling(_, outputDir) { return [ `curl --silent -fL https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem -o ${path.join(outputDir, "global-bundle.pem")}`, ]; }, afterBundling() { return []; }, beforeInstall() { return []; }, }, }, environment: { LOGGER: logger.toString(), ...ssl_options, }, initialPolicy: [ deleteParameterPolicy, ...(props.functionProps?.initialPolicy ?? []), ], }); if (!props.functionProps?.securityGroups || props.functionProps?.securityGroups.length === 0) { props.cluster.connections.allowDefaultPortFrom(fn, "Allow the rds sql handler to connect to db"); } return fn; } } exports.Provider = Provider; _a = JSII_RTTI_SYMBOL_1; Provider[_a] = { fqn: "cdk-rds-sql.Provider", version: "6.0.2" }; function slugify(x) { return x.replace(/[^a-zA-Z0-9]/g, ""); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwyQkFBK0I7QUFDL0IsNkJBQTRCO0FBQzVCLDZDQUE2QztBQUM3QyxpREFBdUU7QUFDdkUsMkNBQTBDO0FBQzFDLHVEQUEyRDtBQUMzRCx3REFBdUQ7QUFJdkQsZ0VBQStEO0FBQy9ELDJDQUFzQztBQWdFdEMsTUFBYSxRQUFTLFNBQVEsc0JBQVM7SUFhckMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFrQjtRQUMxRCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBQ2hCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQTtRQUMxQixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUE7UUFFNUIsK0RBQStEO1FBQy9ELElBQUksbUJBQW1CLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3pDLHlCQUF5QjtZQUN6QixNQUFNLGFBQWEsR0FBSSxLQUFLLENBQUMsT0FBNEIsQ0FBQyxNQUFNLENBQUE7WUFDaEUsSUFBSSxDQUFDLE1BQU07Z0JBQ1QsYUFBYSxJQUFJLGFBQWEsQ0FBQyxZQUFZLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQTtRQUNsRixDQUFDO2FBQU0sSUFBSSxvQkFBb0IsSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakQsMEJBQTBCO1lBQzFCLE1BQU0sY0FBYyxHQUFJLEtBQUssQ0FBQyxPQUE2QixDQUFDLE1BQU0sQ0FBQTtZQUNsRSxJQUFJLENBQUMsTUFBTTtnQkFDVCxjQUFjLElBQUksY0FBYyxDQUFDLFlBQVksS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFBO1FBQ3BGLENBQUM7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Q0FBQTtvQkFDWCxDQUFDO2lCQUNGO2FBQ0Y7WUFDRCxXQUFXLEVBQUU7Z0JBQ1gsTUFBTSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUU7Z0JBQ3pCLEdBQUcsV0FBVzthQUNmO1lBQ0QsYUFBYSxFQUFFO2dCQUNiLHFCQUFxQjtnQkFDckIsR0FBRyxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsYUFBYSxJQUFJLEVBQUUsQ0FBQzthQUM5QztTQUNGLENBQUMsQ0FBQTtRQUVGLElBQ0UsQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGNBQWM7WUFDcEMsS0FBSyxDQUFDLGFBQWEsRUFBRSxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUMsRUFDaEQsQ0FBQztZQUNELEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUM1QyxFQUFFLEVBQ0YsNENBQTRDLENBQzdDLENBQUE7UUFDSCxDQUFDO1FBRUQsT0FBTyxFQUFFLENBQUE7SUFDWCxDQUFDOztBQXBKSCw0QkFxSkM7OztBQUVELFNBQVMsT0FBTyxDQUFDLENBQVM7SUFDeEIsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQTtBQUN2QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gXCJmc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCB7IER1cmF0aW9uLCBTdGFjayB9IGZyb20gXCJhd3MtY2RrLWxpYlwiXG5pbXBvcnQgeyBJVnBjLCBTdWJuZXRUeXBlLCBTdWJuZXRTZWxlY3Rpb24gfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIlxuaW1wb3J0IHsgSUZ1bmN0aW9uLCBSdW50aW1lIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqc1wiXG5pbXBvcnQgeyBOb2RlanNGdW5jdGlvblByb3BzIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGEtbm9kZWpzXCJcbmltcG9ydCB7IElEYXRhYmFzZUNsdXN0ZXIsIElEYXRhYmFzZUluc3RhbmNlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1yZHNcIlxuaW1wb3J0IHsgSVNlY3JldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXJcIlxuaW1wb3J0ICogYXMgY3VzdG9tUmVzb3VyY2VzIGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCJcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCJcblxuZXhwb3J0IGludGVyZmFjZSBSZHNTcWxQcm9wcyB7XG4gIC8qKlxuICAgKiBWUEMgbmV0d29yayB0byBwbGFjZSB0aGUgcHJvdmlkZXIgbGFtYmRhLlxuICAgKlxuICAgKiBOb3JtYWxseSB0aGlzIGlzIHRoZSBWUEMgb2YgeW91ciBkYXRhYmFzZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBGdW5jdGlvbiBpcyBub3QgcGxhY2VkIHdpdGhpbiBhIFZQQy5cbiAgICovXG4gIHJlYWRvbmx5IHZwYzogSVZwY1xuXG4gIC8qKlxuICAgKiBXaGVyZSB0byBwbGFjZSB0aGUgbmV0d29yayBwcm92aWRlciBsYW1iZGEgd2l0aGluIHRoZSBWUEMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGlzb2xhdGVkIHN1Ym5ldCBpZiBub3Qgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSB2cGNTdWJuZXRzPzogU3VibmV0U2VsZWN0aW9uXG5cbiAgLyoqXG4gICAqIFlvdXIgZGF0YWJhc2UuXG4gICAqL1xuICByZWFkb25seSBjbHVzdGVyOiBJRGF0YWJhc2VDbHVzdGVyIHwgSURhdGFiYXNlSW5zdGFuY2VcblxuICAvKipcbiAgICogU2VjcmV0IHRoYXQgZ3JhbnRzIGFjY2VzcyB0byB5b3VyIGRhdGFiYXNlLlxuICAgKlxuICAgKiBVc3VhbGx5IHRoaXMgaXMgeW91ciBjbHVzdGVyJ3MgbWFzdGVyIHNlY3JldC5cbiAgICovXG4gIHJlYWRvbmx5IHNlY3JldDogSVNlY3JldFxuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGZvciBsYW1iZGEgdG8gZG8gaXRzIHdvcmsuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gNSBtaW51dGVzXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0PzogRHVyYXRpb25cblxuICAvKipcbiAgICogTG9nIFNRTCBzdGF0ZW1lbnRzLiBUaGlzIGluY2x1ZGVzIHBhc3N3b3Jkcy4gVXNlIG9ubHkgZm9yIGRlYnVnZ2luZy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgbG9nZ2VyPzogYm9vbGVhblxuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGZ1bmN0aW9uIGN1c3RvbWl6YXRpb24uXG4gICAqXG4gICAqIFRoaXMgZW5hYmxlcyBhZGRpdGlvbmFsIGZ1bmN0aW9uIGN1c3RvbWl6YXRpb24gc3VjaCBhcyB0aGUgbG9nIGdyb3VwLiBIb3dldmVyLFxuICAgKiBsYW1iZGEgZnVuY3Rpb24gcHJvcGVydGllcyBjb250cm9sbGVkIGJ5IG90aGVyIHtSZHNTcWxQcm9wc30gcGFyYW1ldGVycyB3aWxsIHRydW1wXG4gICAqIG9waW9ucyBzZXQgdmlhIHRoaXMgcGFyYW1ldGVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGVtcHR5XG4gICAqL1xuICByZWFkb25seSBmdW5jdGlvblByb3BzPzogTm9kZWpzRnVuY3Rpb25Qcm9wc1xuXG4gIC8qKlxuICAgKiBVc2UgU1NMP1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIGZhbHNlXG4gICAqL1xuICByZWFkb25seSBzc2w/OiBib29sZWFuXG59XG5cbmV4cG9ydCBjbGFzcyBQcm92aWRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlVG9rZW46IHN0cmluZ1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0OiBJU2VjcmV0XG4gIHB1YmxpYyByZWFkb25seSBoYW5kbGVyOiBJRnVuY3Rpb25cbiAgcHVibGljIHJlYWRvbmx5IGNsdXN0ZXI6IElEYXRhYmFzZUNsdXN0ZXIgfCBJRGF0YWJhc2VJbnN0YW5jZVxuXG4gIC8qKlxuICAgKiBUaGUgZW5naW5lIGxpa2UgXCJwb3N0Z3Jlc1wiIG9yIFwibXlzcWxcIlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGlmIHdlIGNhbm5vdCBkZXRlcm1pbmUgdGhpcyBcInBvc3RncmVzXCJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBlbmdpbmU6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBSZHNTcWxQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcbiAgICB0aGlzLnNlY3JldCA9IHByb3BzLnNlY3JldFxuICAgIHRoaXMuY2x1c3RlciA9IHByb3BzLmNsdXN0ZXJcblxuICAgIC8vIERldGVybWluZSBlbmdpbmUgZnJvbSBjbHVzdGVyL2luc3RhbmNlIGluc3RlYWQgb2YgaGFyZGNvZGluZ1xuICAgIGlmIChcImNsdXN0ZXJJZGVudGlmaWVyXCIgaW4gcHJvcHMuY2x1c3Rlcikge1xuICAgICAgLy8gSXQncyBhIERhdGFiYXNlQ2x1c3RlclxuICAgICAgY29uc3QgY2x1c3RlckVuZ2luZSA9IChwcm9wcy5jbHVzdGVyIGFzIElEYXRhYmFzZUNsdXN0ZXIpLmVuZ2luZVxuICAgICAgdGhpcy5lbmdpbmUgPVxuICAgICAgICBjbHVzdGVyRW5naW5lICYmIGNsdXN0ZXJFbmdpbmUuZW5naW5lRmFtaWx5ID09PSBcIk1ZU1FMXCIgPyBcIm15c3FsXCIgOiBcInBvc3RncmVzXCJcbiAgICB9IGVsc2UgaWYgKFwiaW5zdGFuY2VJZGVudGlmaWVyXCIgaW4gcHJvcHMuY2x1c3Rlcikge1xuICAgICAgLy8gSXQncyBhIERhdGFiYXNlSW5zdGFuY2VcbiAgICAgIGNvbnN0IGluc3RhbmNlRW5naW5lID0gKHByb3BzLmNsdXN0ZXIgYXMgSURhdGFiYXNlSW5zdGFuY2UpLmVuZ2luZVxuICAgICAgdGhpcy5lbmdpbmUgPVxuICAgICAgICBpbnN0YW5jZUVuZ2luZSAmJiBpbnN0YW5jZUVuZ2luZS5lbmdpbmVGYW1pbHkgPT09IFwiTVlTUUxcIiA/IFwibXlzcWxcIiA6IFwicG9zdGdyZXNcIlxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGYWxsYmFjayB0byBwb3N0Z3JlcyBpZiBlbmdpbmUgaGFzbid0IGJlZW4gcHJvdmlkZWRcbiAgICAgIHRoaXMuZW5naW5lID0gXCJwb3N0Z3Jlc1wiXG4gICAgfVxuXG4gICAgY29uc3QgZnVuY3Rpb25OYW1lID0gXCJSZHNTcWxcIiArIHNsdWdpZnkoXCIyOGI5ZTc5MS1hZjYwLTRhMzMtYmNhOC1mZmI2ZjMwZWY4YzVcIilcbiAgICB0aGlzLmhhbmRsZXIgPVxuICAgICAgKFN0YWNrLm9mKHRoaXMpLm5vZGUudHJ5RmluZENoaWxkKGZ1bmN0aW9uTmFtZSkgYXMgSUZ1bmN0aW9uKSA/P1xuICAgICAgdGhpcy5uZXdDdXN0b21SZXNvdXJjZUhhbmRsZXIoc2NvcGUsIGZ1bmN0aW9uTmFtZSwgcHJvcHMpXG5cbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBjdXN0b21SZXNvdXJjZXMuUHJvdmlkZXIodGhpcywgXCJSZHNTcWxcIiwge1xuICAgICAgb25FdmVudEhhbmRsZXI6IHRoaXMuaGFuZGxlcixcbiAgICB9KVxuICAgIHRoaXMuc2VydmljZVRva2VuID0gcHJvdmlkZXIuc2VydmljZVRva2VuXG4gICAgdGhpcy5zZWNyZXQuZ3JhbnRSZWFkKHRoaXMuaGFuZGxlcilcbiAgICBpZiAodGhpcy5zZWNyZXQuZW5jcnlwdGlvbktleSkge1xuICAgICAgLy8gSXQgc2VlbXMgd2UgbmVlZCB0byBncmFudCBleHBsaWNpdCBwZXJtaXNzaW9uXG4gICAgICB0aGlzLnNlY3JldC5lbmNyeXB0aW9uS2V5LmdyYW50RGVjcnlwdCh0aGlzLmhhbmRsZXIpXG4gICAgfVxuICAgIGlmIChwcm9wcy5jbHVzdGVyLmNvbm5lY3Rpb25zLnNlY3VyaXR5R3JvdXBzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2x1c3RlciBkb2VzIG5vdCBoYXZlIGEgc2VjdXJpdHkgZ3JvdXAuXCIpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGFuZGxlci5ub2RlLmRlZmF1bHRDaGlsZD8ubm9kZS5hZGREZXBlbmRlbmN5KFxuICAgICAgICBwcm9wcy5jbHVzdGVyLmNvbm5lY3Rpb25zLnNlY3VyaXR5R3JvdXBzWzBdXG4gICAgICApXG4gICAgfVxuICAgIHRoaXMubm9kZS5hZGREZXBlbmRlbmN5KHByb3BzLmNsdXN0ZXIpXG4gIH1cblxuICBwcm90ZWN0ZWQgbmV3Q3VzdG9tUmVzb3VyY2VIYW5kbGVyKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogUmRzU3FsUHJvcHNcbiAgKTogbGFtYmRhLk5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBoYW5kbGVyRGlyID0gcGF0aC5qb2luKF9fZGlybmFtZSwgXCJoYW5kbGVyXCIpXG4gICAgY29uc3QgaW5kZXhfdHMgPSBwYXRoLmpvaW4oaGFuZGxlckRpciwgXCJpbmRleC50c1wiKVxuICAgIGNvbnN0IGluZGV4X2pzID0gcGF0aC5qb2luKGhhbmRsZXJEaXIsIFwiaW5kZXguanNcIilcbiAgICBsZXQgZW50cnk6IHN0cmluZ1xuXG4gICAgaWYgKGV4aXN0c1N5bmMoaW5kZXhfdHMpKSB7XG4gICAgICBlbnRyeSA9IGluZGV4X3RzXG4gICAgfSBlbHNlIGlmIChleGlzdHNTeW5jKGluZGV4X2pzKSkge1xuICAgICAgZW50cnkgPSBpbmRleF9qc1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVZ2x5IGhhY2sgdG8gc3VwcG9ydCBTU1QgKHBvc3NpYmx5IGNhdXNlZCBieSBteSBoYWNrIHRvIG1ha2UgU1NUIHdvcmsgd2l0aCBDb21tb25KUyBsaWJyYXJpZXMpXG4gICAgICBlbnRyeSA9IHBhdGguam9pbihcbiAgICAgICAgcGF0aC5kaXJuYW1lKHByb2Nlc3MuZW52Lm5wbV9wYWNrYWdlX2pzb24gfHwgcHJvY2Vzcy5jd2QoKSksXG4gICAgICAgIFwibm9kZV9tb2R1bGVzL2Nkay1yZHMtc3FsL2xpYi9oYW5kbGVyL2luZGV4LmpzXCJcbiAgICAgIClcbiAgICB9XG4gICAgbGV0IHNzbF9vcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgaWYgKHByb3BzLnNzbCAhPT0gdW5kZWZpbmVkICYmICFwcm9wcy5zc2wpIHtcbiAgICAgIHNzbF9vcHRpb25zID0ge1xuICAgICAgICBTU0w6IEpTT04uc3RyaW5naWZ5KHByb3BzLnNzbCksXG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGxvZ2dlciA9IHByb3BzLmxvZ2dlciA/PyBmYWxzZVxuXG4gICAgY29uc3QgZGVsZXRlUGFyYW1ldGVyUG9saWN5ID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1wic3NtOkRlbGV0ZVBhcmFtZXRlclwiXSxcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICBgYXJuOmF3czpzc206JHtTdGFjay5vZihzY29wZSkucmVnaW9ufToke1N0YWNrLm9mKHNjb3BlKS5hY2NvdW50fTpwYXJhbWV0ZXIvKmAsXG4gICAgICBdLFxuICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICBTdHJpbmdFcXVhbHM6IHtcbiAgICAgICAgICBcInNzbTpSZXNvdXJjZVRhZy9jcmVhdGVkLWJ5XCI6IFwiY2RrLXJkcy1zcWxcIixcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIGNvbnN0IGZuID0gbmV3IGxhbWJkYS5Ob2RlanNGdW5jdGlvbihzY29wZSwgaWQsIHtcbiAgICAgIC4uLnByb3BzLmZ1bmN0aW9uUHJvcHMsXG4gICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgIHZwY1N1Ym5ldHM6IHByb3BzLnZwY1N1Ym5ldHMgPz8ge1xuICAgICAgICBzdWJuZXRUeXBlOiBTdWJuZXRUeXBlLlBSSVZBVEVfSVNPTEFURUQsXG4gICAgICB9LFxuICAgICAgZW50cnk6IGVudHJ5LFxuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIHRpbWVvdXQ6IHByb3BzLnRpbWVvdXQgPz8gcHJvcHMuZnVuY3Rpb25Qcm9wcz8udGltZW91dCA/PyBEdXJhdGlvbi5zZWNvbmRzKDMwMCksXG4gICAgICBidW5kbGluZzoge1xuICAgICAgICAvLyBJbmNsdWRlIHRoZSBtaWdyYXRpb25zIGRpcmVjdG9yeSBpbiB0aGUgYnVuZGxlXG4gICAgICAgIGNvbW1hbmRIb29rczoge1xuICAgICAgICAgIGJlZm9yZUJ1bmRsaW5nKF86IHN0cmluZywgb3V0cHV0RGlyOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICBgY3VybCAtLXNpbGVudCAtZkwgaHR0cHM6Ly90cnVzdHN0b3JlLnBraS5yZHMuYW1hem9uYXdzLmNvbS9nbG9iYWwvZ2xvYmFsLWJ1bmRsZS5wZW0gLW8gJHtwYXRoLmpvaW4oXG4gICAgICAgICAgICAgICAgb3V0cHV0RGlyLFxuICAgICAgICAgICAgICAgIFwiZ2xvYmFsLWJ1bmRsZS5wZW1cIlxuICAgICAgICAgICAgICApfWAsXG4gICAgICAgICAgICBdXG4gICAgICAgICAgfSxcbiAgICAgICAgICBhZnRlckJ1bmRsaW5nKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgICAgIHJldHVybiBbXVxuICAgICAgICAgIH0sXG4gICAgICAgICAgYmVmb3JlSW5zdGFsbCgpOiBzdHJpbmdbXSB7XG4gICAgICAgICAgICByZXR1cm4gW11cbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIExPR0dFUjogbG9nZ2VyLnRvU3RyaW5nKCksXG4gICAgICAgIC4uLnNzbF9vcHRpb25zLFxuICAgICAgfSxcbiAgICAgIGluaXRpYWxQb2xpY3k6IFtcbiAgICAgICAgZGVsZXRlUGFyYW1ldGVyUG9saWN5LFxuICAgICAgICAuLi4ocHJvcHMuZnVuY3Rpb25Qcm9wcz8uaW5pdGlhbFBvbGljeSA/PyBbXSksXG4gICAgICBdLFxuICAgIH0pXG5cbiAgICBpZiAoXG4gICAgICAhcHJvcHMuZnVuY3Rpb25Qcm9wcz8uc2VjdXJpdHlHcm91cHMgfHxcbiAgICAgIHByb3BzLmZ1bmN0aW9uUHJvcHM/LnNlY3VyaXR5R3JvdXBzLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgcHJvcHMuY2x1c3Rlci5jb25uZWN0aW9ucy5hbGxvd0RlZmF1bHRQb3J0RnJvbShcbiAgICAgICAgZm4sXG4gICAgICAgIFwiQWxsb3cgdGhlIHJkcyBzcWwgaGFuZGxlciB0byBjb25uZWN0IHRvIGRiXCJcbiAgICAgIClcbiAgICB9XG5cbiAgICByZXR1cm4gZm5cbiAgfVxufVxuXG5mdW5jdGlvbiBzbHVnaWZ5KHg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB4LnJlcGxhY2UoL1teYS16QS1aMC05XS9nLCBcIlwiKVxufVxuIl19