UNPKG

cdk-rds-sql

Version:

A CDK construct that allows creating roles or users and databases an on Aurora Serverless Postgresql or Mysql/MariaDB cluster.

139 lines 21 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 { const securityGroup = props.cluster.connections.securityGroups[0]; this.handler.node.defaultChild?.node.addDependency(securityGroup); } 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_22_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.1.4" }; function slugify(x) { return x.replace(/[^a-zA-Z0-9]/g, ""); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwyQkFBK0I7QUFDL0IsNkJBQTRCO0FBQzVCLDZDQUE2QztBQUM3QyxpREFBdUU7QUFDdkUsMkNBQTBDO0FBQzFDLHVEQUEyRDtBQUMzRCx3REFBdUQ7QUFJdkQsZ0VBQStEO0FBQy9ELDJDQUFzQztBQWdFdEMsTUFBYSxRQUFTLFNBQVEsc0JBQVM7SUFhckMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFrQjtRQUMxRCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBQ2hCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQTtRQUMxQixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUE7UUFFNUIsK0RBQStEO1FBQy9ELElBQUksbUJBQW1CLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3pDLHlCQUF5QjtZQUN6QixNQUFNLGFBQWEsR0FBSSxLQUFLLENBQUMsT0FBNEIsQ0FBQyxNQUFNLENBQUE7WUFDaEUsSUFBSSxDQUFDLE1BQU07Z0JBQ1QsYUFBYSxJQUFJLGFBQWEsQ0FBQyxZQUFZLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQTtRQUNsRixDQUFDO2FBQU0sSUFBSSxvQkFBb0IsSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakQsMEJBQTBCO1lBQzFCLE1BQU0sY0FBYyxHQUFJLEtBQUssQ0FBQyxPQUE2QixDQUFDLE1BQU0sQ0FBQTtZQUNsRSxJQUFJLENBQUMsTUFBTTtnQkFDVCxjQUFjLElBQUksY0FBYyxDQUFDLFlBQVksS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFBO1FBQ3BGLENBQUM7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QUM7b0JBQ0QsYUFBYTt3QkFDWCxPQUFPLEVBQUUsQ0FBQTtvQkFDWCxDQUFDO2lCQUNGO2FBQ0Y7WUFDRCxXQUFXLEVBQUU7Z0JBQ1gsTUFBTSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUU7Z0JBQ3pCLEdBQUcsV0FBVzthQUNmO1lBQ0QsYUFBYSxFQUFFO2dCQUNiLHFCQUFxQjtnQkFDckIsR0FBRyxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsYUFBYSxJQUFJLEVBQUUsQ0FBQzthQUM5QztTQUNGLENBQUMsQ0FBQTtRQUVGLElBQ0UsQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGNBQWM7WUFDcEMsS0FBSyxDQUFDLGFBQWEsRUFBRSxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUMsRUFDaEQsQ0FBQztZQUNELEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUM1QyxFQUFFLEVBQ0YsNENBQTRDLENBQzdDLENBQUE7UUFDSCxDQUFDO1FBRUQsT0FBTyxFQUFFLENBQUE7SUFDWCxDQUFDOztBQW5KSCw0QkFvSkM7OztBQUVELFNBQVMsT0FBTyxDQUFDLENBQVM7SUFDeEIsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQTtBQUN2QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gXCJmc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCB7IER1cmF0aW9uLCBTdGFjayB9IGZyb20gXCJhd3MtY2RrLWxpYlwiXG5pbXBvcnQgeyBJVnBjLCBTdWJuZXRUeXBlLCBTdWJuZXRTZWxlY3Rpb24gfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIlxuaW1wb3J0IHsgSUZ1bmN0aW9uLCBSdW50aW1lIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqc1wiXG5pbXBvcnQgeyBOb2RlanNGdW5jdGlvblByb3BzIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGEtbm9kZWpzXCJcbmltcG9ydCB7IElEYXRhYmFzZUNsdXN0ZXIsIElEYXRhYmFzZUluc3RhbmNlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1yZHNcIlxuaW1wb3J0IHsgSVNlY3JldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXJcIlxuaW1wb3J0ICogYXMgY3VzdG9tUmVzb3VyY2VzIGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCJcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCJcblxuZXhwb3J0IGludGVyZmFjZSBSZHNTcWxQcm9wcyB7XG4gIC8qKlxuICAgKiBWUEMgbmV0d29yayB0byBwbGFjZSB0aGUgcHJvdmlkZXIgbGFtYmRhLlxuICAgKlxuICAgKiBOb3JtYWxseSB0aGlzIGlzIHRoZSBWUEMgb2YgeW91ciBkYXRhYmFzZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBGdW5jdGlvbiBpcyBub3QgcGxhY2VkIHdpdGhpbiBhIFZQQy5cbiAgICovXG4gIHJlYWRvbmx5IHZwYzogSVZwY1xuXG4gIC8qKlxuICAgKiBXaGVyZSB0byBwbGFjZSB0aGUgbmV0d29yayBwcm92aWRlciBsYW1iZGEgd2l0aGluIHRoZSBWUEMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGlzb2xhdGVkIHN1Ym5ldCBpZiBub3Qgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSB2cGNTdWJuZXRzPzogU3VibmV0U2VsZWN0aW9uXG5cbiAgLyoqXG4gICAqIFlvdXIgZGF0YWJhc2UuXG4gICAqL1xuICByZWFkb25seSBjbHVzdGVyOiBJRGF0YWJhc2VDbHVzdGVyIHwgSURhdGFiYXNlSW5zdGFuY2VcblxuICAvKipcbiAgICogU2VjcmV0IHRoYXQgZ3JhbnRzIGFjY2VzcyB0byB5b3VyIGRhdGFiYXNlLlxuICAgKlxuICAgKiBVc3VhbGx5IHRoaXMgaXMgeW91ciBjbHVzdGVyJ3MgbWFzdGVyIHNlY3JldC5cbiAgICovXG4gIHJlYWRvbmx5IHNlY3JldDogSVNlY3JldFxuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGZvciBsYW1iZGEgdG8gZG8gaXRzIHdvcmsuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gNSBtaW51dGVzXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0PzogRHVyYXRpb25cblxuICAvKipcbiAgICogTG9nIFNRTCBzdGF0ZW1lbnRzLiBUaGlzIGluY2x1ZGVzIHBhc3N3b3Jkcy4gVXNlIG9ubHkgZm9yIGRlYnVnZ2luZy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgbG9nZ2VyPzogYm9vbGVhblxuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGZ1bmN0aW9uIGN1c3RvbWl6YXRpb24uXG4gICAqXG4gICAqIFRoaXMgZW5hYmxlcyBhZGRpdGlvbmFsIGZ1bmN0aW9uIGN1c3RvbWl6YXRpb24gc3VjaCBhcyB0aGUgbG9nIGdyb3VwLiBIb3dldmVyLFxuICAgKiBsYW1iZGEgZnVuY3Rpb24gcHJvcGVydGllcyBjb250cm9sbGVkIGJ5IG90aGVyIHtSZHNTcWxQcm9wc30gcGFyYW1ldGVycyB3aWxsIHRydW1wXG4gICAqIG9waW9ucyBzZXQgdmlhIHRoaXMgcGFyYW1ldGVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGVtcHR5XG4gICAqL1xuICByZWFkb25seSBmdW5jdGlvblByb3BzPzogTm9kZWpzRnVuY3Rpb25Qcm9wc1xuXG4gIC8qKlxuICAgKiBVc2UgU1NMP1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIGZhbHNlXG4gICAqL1xuICByZWFkb25seSBzc2w/OiBib29sZWFuXG59XG5cbmV4cG9ydCBjbGFzcyBQcm92aWRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlVG9rZW46IHN0cmluZ1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0OiBJU2VjcmV0XG4gIHB1YmxpYyByZWFkb25seSBoYW5kbGVyOiBJRnVuY3Rpb25cbiAgcHVibGljIHJlYWRvbmx5IGNsdXN0ZXI6IElEYXRhYmFzZUNsdXN0ZXIgfCBJRGF0YWJhc2VJbnN0YW5jZVxuXG4gIC8qKlxuICAgKiBUaGUgZW5naW5lIGxpa2UgXCJwb3N0Z3Jlc1wiIG9yIFwibXlzcWxcIlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGlmIHdlIGNhbm5vdCBkZXRlcm1pbmUgdGhpcyBcInBvc3RncmVzXCJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBlbmdpbmU6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBSZHNTcWxQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcbiAgICB0aGlzLnNlY3JldCA9IHByb3BzLnNlY3JldFxuICAgIHRoaXMuY2x1c3RlciA9IHByb3BzLmNsdXN0ZXJcblxuICAgIC8vIERldGVybWluZSBlbmdpbmUgZnJvbSBjbHVzdGVyL2luc3RhbmNlIGluc3RlYWQgb2YgaGFyZGNvZGluZ1xuICAgIGlmIChcImNsdXN0ZXJJZGVudGlmaWVyXCIgaW4gcHJvcHMuY2x1c3Rlcikge1xuICAgICAgLy8gSXQncyBhIERhdGFiYXNlQ2x1c3RlclxuICAgICAgY29uc3QgY2x1c3RlckVuZ2luZSA9IChwcm9wcy5jbHVzdGVyIGFzIElEYXRhYmFzZUNsdXN0ZXIpLmVuZ2luZVxuICAgICAgdGhpcy5lbmdpbmUgPVxuICAgICAgICBjbHVzdGVyRW5naW5lICYmIGNsdXN0ZXJFbmdpbmUuZW5naW5lRmFtaWx5ID09PSBcIk1ZU1FMXCIgPyBcIm15c3FsXCIgOiBcInBvc3RncmVzXCJcbiAgICB9IGVsc2UgaWYgKFwiaW5zdGFuY2VJZGVudGlmaWVyXCIgaW4gcHJvcHMuY2x1c3Rlcikge1xuICAgICAgLy8gSXQncyBhIERhdGFiYXNlSW5zdGFuY2VcbiAgICAgIGNvbnN0IGluc3RhbmNlRW5naW5lID0gKHByb3BzLmNsdXN0ZXIgYXMgSURhdGFiYXNlSW5zdGFuY2UpLmVuZ2luZVxuICAgICAgdGhpcy5lbmdpbmUgPVxuICAgICAgICBpbnN0YW5jZUVuZ2luZSAmJiBpbnN0YW5jZUVuZ2luZS5lbmdpbmVGYW1pbHkgPT09IFwiTVlTUUxcIiA/IFwibXlzcWxcIiA6IFwicG9zdGdyZXNcIlxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGYWxsYmFjayB0byBwb3N0Z3JlcyBpZiBlbmdpbmUgaGFzbid0IGJlZW4gcHJvdmlkZWRcbiAgICAgIHRoaXMuZW5naW5lID0gXCJwb3N0Z3Jlc1wiXG4gICAgfVxuXG4gICAgY29uc3QgZnVuY3Rpb25OYW1lID0gXCJSZHNTcWxcIiArIHNsdWdpZnkoXCIyOGI5ZTc5MS1hZjYwLTRhMzMtYmNhOC1mZmI2ZjMwZWY4YzVcIilcbiAgICB0aGlzLmhhbmRsZXIgPVxuICAgICAgKFN0YWNrLm9mKHRoaXMpLm5vZGUudHJ5RmluZENoaWxkKGZ1bmN0aW9uTmFtZSkgYXMgSUZ1bmN0aW9uKSA/P1xuICAgICAgdGhpcy5uZXdDdXN0b21SZXNvdXJjZUhhbmRsZXIoc2NvcGUsIGZ1bmN0aW9uTmFtZSwgcHJvcHMpXG5cbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBjdXN0b21SZXNvdXJjZXMuUHJvdmlkZXIodGhpcywgXCJSZHNTcWxcIiwge1xuICAgICAgb25FdmVudEhhbmRsZXI6IHRoaXMuaGFuZGxlcixcbiAgICB9KVxuICAgIHRoaXMuc2VydmljZVRva2VuID0gcHJvdmlkZXIuc2VydmljZVRva2VuXG4gICAgdGhpcy5zZWNyZXQuZ3JhbnRSZWFkKHRoaXMuaGFuZGxlcilcbiAgICBpZiAodGhpcy5zZWNyZXQuZW5jcnlwdGlvbktleSkge1xuICAgICAgLy8gSXQgc2VlbXMgd2UgbmVlZCB0byBncmFudCBleHBsaWNpdCBwZXJtaXNzaW9uXG4gICAgICB0aGlzLnNlY3JldC5lbmNyeXB0aW9uS2V5LmdyYW50RGVjcnlwdCh0aGlzLmhhbmRsZXIpXG4gICAgfVxuICAgIGlmIChwcm9wcy5jbHVzdGVyLmNvbm5lY3Rpb25zLnNlY3VyaXR5R3JvdXBzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2x1c3RlciBkb2VzIG5vdCBoYXZlIGEgc2VjdXJpdHkgZ3JvdXAuXCIpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHNlY3VyaXR5R3JvdXAgPSBwcm9wcy5jbHVzdGVyLmNvbm5lY3Rpb25zLnNlY3VyaXR5R3JvdXBzWzBdIVxuICAgICAgdGhpcy5oYW5kbGVyLm5vZGUuZGVmYXVsdENoaWxkPy5ub2RlLmFkZERlcGVuZGVuY3koc2VjdXJpdHlHcm91cClcbiAgICB9XG4gICAgdGhpcy5ub2RlLmFkZERlcGVuZGVuY3kocHJvcHMuY2x1c3RlcilcbiAgfVxuXG4gIHByb3RlY3RlZCBuZXdDdXN0b21SZXNvdXJjZUhhbmRsZXIoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIHByb3BzOiBSZHNTcWxQcm9wc1xuICApOiBsYW1iZGEuTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGhhbmRsZXJEaXIgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCBcImhhbmRsZXJcIilcbiAgICBjb25zdCBpbmRleF90cyA9IHBhdGguam9pbihoYW5kbGVyRGlyLCBcImluZGV4LnRzXCIpXG4gICAgY29uc3QgaW5kZXhfanMgPSBwYXRoLmpvaW4oaGFuZGxlckRpciwgXCJpbmRleC5qc1wiKVxuICAgIGxldCBlbnRyeTogc3RyaW5nXG5cbiAgICBpZiAoZXhpc3RzU3luYyhpbmRleF90cykpIHtcbiAgICAgIGVudHJ5ID0gaW5kZXhfdHNcbiAgICB9IGVsc2UgaWYgKGV4aXN0c1N5bmMoaW5kZXhfanMpKSB7XG4gICAgICBlbnRyeSA9IGluZGV4X2pzXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVnbHkgaGFjayB0byBzdXBwb3J0IFNTVCAocG9zc2libHkgY2F1c2VkIGJ5IG15IGhhY2sgdG8gbWFrZSBTU1Qgd29yayB3aXRoIENvbW1vbkpTIGxpYnJhcmllcylcbiAgICAgIGVudHJ5ID0gcGF0aC5qb2luKFxuICAgICAgICBwYXRoLmRpcm5hbWUocHJvY2Vzcy5lbnYubnBtX3BhY2thZ2VfanNvbiB8fCBwcm9jZXNzLmN3ZCgpKSxcbiAgICAgICAgXCJub2RlX21vZHVsZXMvY2RrLXJkcy1zcWwvbGliL2hhbmRsZXIvaW5kZXguanNcIlxuICAgICAgKVxuICAgIH1cbiAgICBsZXQgc3NsX29wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICBpZiAocHJvcHMuc3NsICE9PSB1bmRlZmluZWQgJiYgIXByb3BzLnNzbCkge1xuICAgICAgc3NsX29wdGlvbnMgPSB7XG4gICAgICAgIFNTTDogSlNPTi5zdHJpbmdpZnkocHJvcHMuc3NsKSxcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgbG9nZ2VyID0gcHJvcHMubG9nZ2VyID8/IGZhbHNlXG5cbiAgICBjb25zdCBkZWxldGVQYXJhbWV0ZXJQb2xpY3kgPSBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbXCJzc206RGVsZXRlUGFyYW1ldGVyXCJdLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIGBhcm46YXdzOnNzbToke1N0YWNrLm9mKHNjb3BlKS5yZWdpb259OiR7U3RhY2sub2Yoc2NvcGUpLmFjY291bnR9OnBhcmFtZXRlci8qYCxcbiAgICAgIF0sXG4gICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgIFwic3NtOlJlc291cmNlVGFnL2NyZWF0ZWQtYnlcIjogXCJjZGstcmRzLXNxbFwiLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgY29uc3QgZm4gPSBuZXcgbGFtYmRhLk5vZGVqc0Z1bmN0aW9uKHNjb3BlLCBpZCwge1xuICAgICAgLi4ucHJvcHMuZnVuY3Rpb25Qcm9wcyxcbiAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgdnBjU3VibmV0czogcHJvcHMudnBjU3VibmV0cyA/PyB7XG4gICAgICAgIHN1Ym5ldFR5cGU6IFN1Ym5ldFR5cGUuUFJJVkFURV9JU09MQVRFRCxcbiAgICAgIH0sXG4gICAgICBlbnRyeTogZW50cnksXG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgdGltZW91dDogcHJvcHMudGltZW91dCA/PyBwcm9wcy5mdW5jdGlvblByb3BzPy50aW1lb3V0ID8/IER1cmF0aW9uLnNlY29uZHMoMzAwKSxcbiAgICAgIGJ1bmRsaW5nOiB7XG4gICAgICAgIC8vIEluY2x1ZGUgdGhlIG1pZ3JhdGlvbnMgZGlyZWN0b3J5IGluIHRoZSBidW5kbGVcbiAgICAgICAgY29tbWFuZEhvb2tzOiB7XG4gICAgICAgICAgYmVmb3JlQnVuZGxpbmcoXzogc3RyaW5nLCBvdXRwdXREaXI6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgIGBjdXJsIC0tc2lsZW50IC1mTCBodHRwczovL3RydXN0c3RvcmUucGtpLnJkcy5hbWF6b25hd3MuY29tL2dsb2JhbC9nbG9iYWwtYnVuZGxlLnBlbSAtbyAke3BhdGguam9pbihcbiAgICAgICAgICAgICAgICBvdXRwdXREaXIsXG4gICAgICAgICAgICAgICAgXCJnbG9iYWwtYnVuZGxlLnBlbVwiXG4gICAgICAgICAgICAgICl9YCxcbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGFmdGVyQnVuZGxpbmcoKTogc3RyaW5nW10ge1xuICAgICAgICAgICAgcmV0dXJuIFtdXG4gICAgICAgICAgfSxcbiAgICAgICAgICBiZWZvcmVJbnN0YWxsKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgICAgIHJldHVybiBbXVxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgTE9HR0VSOiBsb2dnZXIudG9TdHJpbmcoKSxcbiAgICAgICAgLi4uc3NsX29wdGlvbnMsXG4gICAgICB9LFxuICAgICAgaW5pdGlhbFBvbGljeTogW1xuICAgICAgICBkZWxldGVQYXJhbWV0ZXJQb2xpY3ksXG4gICAgICAgIC4uLihwcm9wcy5mdW5jdGlvblByb3BzPy5pbml0aWFsUG9saWN5ID8/IFtdKSxcbiAgICAgIF0sXG4gICAgfSlcblxuICAgIGlmIChcbiAgICAgICFwcm9wcy5mdW5jdGlvblByb3BzPy5zZWN1cml0eUdyb3VwcyB8fFxuICAgICAgcHJvcHMuZnVuY3Rpb25Qcm9wcz8uc2VjdXJpdHlHcm91cHMubGVuZ3RoID09PSAwXG4gICAgKSB7XG4gICAgICBwcm9wcy5jbHVzdGVyLmNvbm5lY3Rpb25zLmFsbG93RGVmYXVsdFBvcnRGcm9tKFxuICAgICAgICBmbixcbiAgICAgICAgXCJBbGxvdyB0aGUgcmRzIHNxbCBoYW5kbGVyIHRvIGNvbm5lY3QgdG8gZGJcIlxuICAgICAgKVxuICAgIH1cblxuICAgIHJldHVybiBmblxuICB9XG59XG5cbmZ1bmN0aW9uIHNsdWdpZnkoeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHgucmVwbGFjZSgvW15hLXpBLVowLTldL2csIFwiXCIpXG59XG4iXX0=