UNPKG

mysql-user-and-database-cdk

Version:

[![docs](https://img.shields.io/badge/docs-!-brightgreen)](https://isotoma.github.io/mysql-user-and-database-cdk/) [![npm](https://img.shields.io/npm/v/mysql-user-and-database-cdk)](https://www.npmjs.com/package/mysql-user-and-database-cdk) [![NPM](https:

107 lines 20.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MysqlUserAndDatabase = exports.DEFAULT_PASSWORD_EXCLUDE_CHARS = void 0; const constructs_1 = require("constructs"); const pathlib = require("path"); const cdk = require("aws-cdk-lib"); const iam = require("aws-cdk-lib/aws-iam"); const secretsmanager = require("aws-cdk-lib/aws-secretsmanager"); const cr = require("aws-cdk-lib/custom-resources"); const lambda = require("aws-cdk-lib/aws-lambda"); exports.DEFAULT_PASSWORD_EXCLUDE_CHARS = ' %+~`#$&*()|[]{}:;<>?!\'/@"\\'; class MysqlUserAndDatabase extends constructs_1.Construct { constructor(scope, id, props) { var _a, _b, _c, _d, _e, _f, _g, _h; super(scope, id); // Using a custom resource, create a user and database in the RDS cluster // https://docs.aws.amazon.com/cdk/api/latest/docs/custom-resources-readme.html const handler = new lambda.Function(this, 'OnEvent', { code: lambda.Code.fromAsset(pathlib.join(__dirname, 'handler')), runtime: new lambda.Runtime('nodejs22.x', lambda.RuntimeFamily.NODEJS, { supportsInlineCode: true }), handler: 'main.handler', vpc: props.vpc, timeout: cdk.Duration.seconds(30), }); if (props.userSecret) { this.userSecret = props.userSecret; } else if (props.username) { this.userSecret = (_a = props.userSecret) !== null && _a !== void 0 ? _a : new secretsmanager.Secret(this, 'UserSecret', { generateSecretString: { passwordLength: 30, secretStringTemplate: JSON.stringify({ username: props.username, dbname: props.databaseName, host: props.dbCluster.clusterEndpoint.hostname, port: props.dbCluster.clusterEndpoint.port, }), generateStringKey: 'password', excludeCharacters: exports.DEFAULT_PASSWORD_EXCLUDE_CHARS, }, }); } else { throw new Error('Must provide either userSecret or username'); } props.dbSecret.grantRead(handler); this.userSecret.grantRead(handler); let secretLatestVersion = undefined; if (props.onUpdateCheckSecretVersion) { const secretLatestVersionHandler = new lambda.Function(this, 'OnEventSecretLatestVersion', { code: lambda.Code.fromAsset(pathlib.join(__dirname, 'latest_secret_version_handler')), runtime: new lambda.Runtime('nodejs22.x', lambda.RuntimeFamily.NODEJS, { supportsInlineCode: true }), handler: 'main.handler', timeout: cdk.Duration.seconds(30), }); // Grant the function secretmanager:ListSecretVersionIds if (!secretLatestVersionHandler.role) { throw new Error('Lambda for SecretLatestVersion has no role'); } const policyResult = secretLatestVersionHandler.role.addToPrincipalPolicy(new iam.PolicyStatement({ actions: ['secretsmanager:ListSecretVersionIds'], resources: [this.userSecret.secretArn], })); const secretLatestVersionProvider = new cr.Provider(this, 'SecretLatestVersionProvider', { onEventHandler: secretLatestVersionHandler, }); const secretLatestVersionCustomResource = new cdk.CustomResource(this, 'SecretLatestVersionResource', { serviceToken: secretLatestVersionProvider.serviceToken, properties: { secretArn: this.userSecret.secretArn, datetime: `onUpdateCheckSecretVersion: ${new Date().toISOString()}`, }, }); if (policyResult.policyDependable) { secretLatestVersionCustomResource.node.addDependency(policyResult.policyDependable); } secretLatestVersion = secretLatestVersionCustomResource.getAttString('LatestVersionId'); } handler.connections.allowToDefaultPort(props.dbCluster); const provider = new cr.Provider(this, 'Provider', { onEventHandler: handler, }); const customResource = new cdk.CustomResource(this, 'Resource', { serviceToken: provider.serviceToken, properties: { dbClusterHostname: props.dbCluster.clusterEndpoint.hostname, dbClusterPort: props.dbCluster.clusterEndpoint.port, dbSecretArn: props.dbSecret.secretArn, userSecretArn: this.userSecret.secretArn, databaseName: props.databaseName, onDelete: (_b = props.onDelete) !== null && _b !== void 0 ? _b : 'Delete', onCreateIfExists: (_c = props.onCreateIfExists) !== null && _c !== void 0 ? _c : 'Fail', onUpdateIfUserDoesNotExist: (_d = props.onUpdateIfUserDoesNotExist) !== null && _d !== void 0 ? _d : 'Ignore', onUpdateIfDatabaseDoesNotExist: (_e = props.onUpdateIfDatabaseDoesNotExist) !== null && _e !== void 0 ? _e : 'Ignore', onUpdateSetUserPassword: (_f = props.onUpdateSetUserPassword) !== null && _f !== void 0 ? _f : 'Never', onUpdateSetUserPermissions: (_g = props.onUpdateSetUserPermissions) !== null && _g !== void 0 ? _g : 'Never', onUpdateSetDatabaseOwnership: (_h = props.onUpdateSetDatabaseOwnership) !== null && _h !== void 0 ? _h : 'Never', ...(secretLatestVersion ? { secretLatestVersion } : {}), }, }); customResource.node.addDependency(...handler.connections.securityGroups); customResource.node.addDependency(this.userSecret); } } exports.MysqlUserAndDatabase = MysqlUserAndDatabase; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFDdkMsZ0NBQWdDO0FBQ2hDLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFFM0MsaUVBQWlFO0FBRWpFLG1EQUFtRDtBQUNuRCxpREFBaUQ7QUFrQ3BDLFFBQUEsOEJBQThCLEdBQUcsK0JBQStCLENBQUM7QUFFOUUsTUFBYSxvQkFBcUIsU0FBUSxzQkFBUztJQUcvQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQWdDOztRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLHlFQUF5RTtRQUN6RSwrRUFBK0U7UUFFL0UsTUFBTSxPQUFPLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDakQsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQy9ELE9BQU8sRUFBRSxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLEVBQUUsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDcEcsT0FBTyxFQUFFLGNBQWM7WUFDdkIsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO1lBQ2QsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztTQUNwQyxDQUFDLENBQUM7UUFFSCxJQUFJLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDdkMsQ0FBQzthQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxVQUFV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QkFBNEIsbUNBQUksT0FBTztnQkFDM0UsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUMxRDtTQUNKLENBQUMsQ0FBQztRQUVILGNBQWMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN6RSxjQUFjLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdkQsQ0FBQztDQUNKO0FBOUdELG9EQThHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0ICogYXMgcGF0aGxpYiBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgdHlwZSAqIGFzIHJkcyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtcmRzJztcbmltcG9ydCAqIGFzIHNlY3JldHNtYW5hZ2VyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zZWNyZXRzbWFuYWdlcic7XG5pbXBvcnQgdHlwZSAqIGFzIGVjMiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGNyIGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE15c3FsVXNlckFuZERhdGFiYXNlUHJvcHMge1xuICAgIGRiQ2x1c3RlcjogcmRzLklEYXRhYmFzZUNsdXN0ZXI7XG4gICAgZGJTZWNyZXQ6IHNlY3JldHNtYW5hZ2VyLklTZWNyZXQ7XG4gICAgLy8gTXVzdCBoYXZlIGEgc2VjcmV0U3RyaW5nIHdpdGggdGhlIGZvbGxvd2luZyBrZXlzOlxuICAgIC8vIC0gdXNlcm5hbWVcbiAgICAvLyAtIHBhc3N3b3JkXG4gICAgdXNlclNlY3JldD86IHNlY3JldHNtYW5hZ2VyLklTZWNyZXQ7XG4gICAgLy8gTXVzdCBzZXQgdGhpcyBpZiB1c2VyU2VjcmV0IGlzIG5vdCBwcm92aWRlZCwgYW5kIGEgcGFzc3dvcmRcbiAgICAvLyB3aWxsIGJlIGdlbmVyYXRlZCB3aXRoIGtleXMgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIChhcyB3ZWxsIGFzXG4gICAgLy8gZGJuYW1lLCBob3N0LCBhbmQgcG9ydClcbiAgICB1c2VybmFtZT86IHN0cmluZztcbiAgICBkYXRhYmFzZU5hbWU6IHN0cmluZztcbiAgICB2cGM6IGVjMi5JVnBjO1xuICAgIC8vIERlZmF1bHRzIHRvIEZhaWxcbiAgICBvbkNyZWF0ZUlmRXhpc3RzPzogJ0ZhaWwnIHwgJ0Fkb3B0JyB8ICdEZWxldGVBbmRSZWNyZWF0ZSc7XG4gICAgLy8gRGVmYXVsdHMgdG8gRGVsZXRlXG4gICAgb25EZWxldGU/OiAnRGVsZXRlJyB8ICdSZXRhaW4nO1xuICAgIC8vIERlZmF1bHRzIHRvIElnbm9yZVxuICAgIG9uVXBkYXRlSWZVc2VyRG9lc05vdEV4aXN0PzogJ0lnbm9yZScgfCAnQ3JlYXRlJztcbiAgICAvLyBEZWZhdWx0cyB0byBJZ25vcmVcbiAgICBvblVwZGF0ZUlmRGF0YWJhc2VEb2VzTm90RXhpc3Q/OiAnSWdub3JlJyB8ICdDcmVhdGUnO1xuICAgIC8vIERlZmF1bHRzIHRvIE5ldmVyXG4gICAgb25VcGRhdGVTZXRVc2VyUGFzc3dvcmQ/OiAnQWx3YXlzJyB8ICdOZXZlcic7XG4gICAgLy8gRGVmYXVsdHMgdG8gTmV2ZXJcbiAgICBvblVwZGF0ZVNldFVzZXJQZXJtaXNzaW9ucz86ICdBbHdheXMnIHwgJ05ldmVyJztcbiAgICAvLyBEZWZhdWx0cyB0byBOZXZlclxuICAgIG9uVXBkYXRlU2V0RGF0YWJhc2VPd25lcnNoaXA/OiAnQWx3YXlzJyB8ICdOZXZlcic7XG4gICAgLy8gQ2hlY2sgZm9yIGEgbmV3IHNlY3JldCB2ZXJzaW9uIGV2ZXJ5IHRpbWUgdGhlIGN1c3RvbSByZXNvdXJjZSBpcyB1cGRhdGVkXG4gICAgLy8gRGVmYXVsdHMgdG8gZmFsc2VcbiAgICBvblVwZGF0ZUNoZWNrU2VjcmV0VmVyc2lvbj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1BBU1NXT1JEX0VYQ0xVREVfQ0hBUlMgPSAnICUrfmAjJCYqKCl8W117fTo7PD4/IVxcJy9AXCJcXFxcJztcblxuZXhwb3J0IGNsYXNzIE15c3FsVXNlckFuZERhdGFiYXNlIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgICByZWFkb25seSB1c2VyU2VjcmV0OiBzZWNyZXRzbWFuYWdlci5JU2VjcmV0O1xuXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE15c3FsVXNlckFuZERhdGFiYXNlUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgICAgICAvLyBVc2luZyBhIGN1c3RvbSByZXNvdXJjZSwgY3JlYXRlIGEgdXNlciBhbmQgZGF0YWJhc2UgaW4gdGhlIFJEUyBjbHVzdGVyXG4gICAgICAgIC8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jZGsvYXBpL2xhdGVzdC9kb2NzL2N1c3RvbS1yZXNvdXJjZXMtcmVhZG1lLmh0bWxcblxuICAgICAgICBjb25zdCBoYW5kbGVyID0gbmV3IGxhbWJkYS5GdW5jdGlvbih0aGlzLCAnT25FdmVudCcsIHtcbiAgICAgICAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRobGliLmpvaW4oX19kaXJuYW1lLCAnaGFuZGxlcicpKSxcbiAgICAgICAgICAgIHJ1bnRpbWU6IG5ldyBsYW1iZGEuUnVudGltZSgnbm9kZWpzMjIueCcsIGxhbWJkYS5SdW50aW1lRmFtaWx5Lk5PREVKUywgeyBzdXBwb3J0c0lubGluZUNvZGU6IHRydWUgfSksXG4gICAgICAgICAgICBoYW5kbGVyOiAnbWFpbi5oYW5kbGVyJyxcbiAgICAgICAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgICAgICAgdGltZW91dDogY2RrLkR1cmF0aW9uLnNlY29uZHMoMzApLFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocHJvcHMudXNlclNlY3JldCkge1xuICAgICAgICAgICAgdGhpcy51c2VyU2VjcmV0ID0gcHJvcHMudXNlclNlY3JldDtcbiAgICAgICAgfSBlbHNlIGlmIChwcm9wcy51c2VybmFtZSkge1xuICAgICAgICAgICAgdGhpcy51c2VyU2VjcmV0ID1cbiAgICAgICAgICAgICAgICBwcm9wcy51c2VyU2VjcmV0ID8/XG4gICAgICAgICAgICAgICAgbmV3IHNlY3JldHNtYW5hZ2VyLlNlY3JldCh0aGlzLCAnVXNlclNlY3JldCcsIHtcbiAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVTZWNyZXRTdHJpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3N3b3JkTGVuZ3RoOiAzMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlY3JldFN0cmluZ1RlbXBsYXRlOiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlcm5hbWU6IHByb3BzLnVzZXJuYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRibmFtZTogcHJvcHMuZGF0YWJhc2VOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3Q6IHByb3BzLmRiQ2x1c3Rlci5jbHVzdGVyRW5kcG9pbnQuaG9zdG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9ydDogcHJvcHMuZGJDbHVzdGVyLmNsdXN0ZXJFbmRwb2ludC5wb3J0LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZVN0cmluZ0tleTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGVDaGFyYWN0ZXJzOiBERUZBVUxUX1BBU1NXT1JEX0VYQ0xVREVfQ0hBUlMsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ011c3QgcHJvdmlkZSBlaXRoZXIgdXNlclNlY3JldCBvciB1c2VybmFtZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJvcHMuZGJTZWNyZXQuZ3JhbnRSZWFkKGhhbmRsZXIpO1xuICAgICAgICB0aGlzLnVzZXJTZWNyZXQuZ3JhbnRSZWFkKGhhbmRsZXIpO1xuXG4gICAgICAgIGxldCBzZWNyZXRMYXRlc3RWZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChwcm9wcy5vblVwZGF0ZUNoZWNrU2VjcmV0VmVyc2lvbikge1xuICAgICAgICAgICAgY29uc3Qgc2VjcmV0TGF0ZXN0VmVyc2lvbkhhbmRsZXIgPSBuZXcgbGFtYmRhLkZ1bmN0aW9uKHRoaXMsICdPbkV2ZW50U2VjcmV0TGF0ZXN0VmVyc2lvbicsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aGxpYi5qb2luKF9fZGlybmFtZSwgJ2xhdGVzdF9zZWNyZXRfdmVyc2lvbl9oYW5kbGVyJykpLFxuICAgICAgICAgICAgICAgIHJ1bnRpbWU6IG5ldyBsYW1iZGEuUnVudGltZSgnbm9kZWpzMjIueCcsIGxhbWJkYS5SdW50aW1lRmFtaWx5Lk5PREVKUywgeyBzdXBwb3J0c0lubGluZUNvZGU6IHRydWUgfSksXG4gICAgICAgICAgICAgICAgaGFuZGxlcjogJ21haW4uaGFuZGxlcicsXG4gICAgICAgICAgICAgICAgdGltZW91dDogY2RrLkR1cmF0aW9uLnNlY29uZHMoMzApLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEdyYW50IHRoZSBmdW5jdGlvbiBzZWNyZXRtYW5hZ2VyOkxpc3RTZWNyZXRWZXJzaW9uSWRzXG4gICAgICAgICAgICBpZiAoIXNlY3JldExhdGVzdFZlcnNpb25IYW5kbGVyLnJvbGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xhbWJkYSBmb3IgU2VjcmV0TGF0ZXN0VmVyc2lvbiBoYXMgbm8gcm9sZScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBwb2xpY3lSZXN1bHQgPSBzZWNyZXRMYXRlc3RWZXJzaW9uSGFuZGxlci5yb2xlLmFkZFRvUHJpbmNpcGFsUG9saWN5KFxuICAgICAgICAgICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uczogWydzZWNyZXRzbWFuYWdlcjpMaXN0U2VjcmV0VmVyc2lvbklkcyddLFxuICAgICAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFt0aGlzLnVzZXJTZWNyZXQuc2VjcmV0QXJuXSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlY3JldExhdGVzdFZlcnNpb25Qcm92aWRlciA9IG5ldyBjci5Qcm92aWRlcih0aGlzLCAnU2VjcmV0TGF0ZXN0VmVyc2lvblByb3ZpZGVyJywge1xuICAgICAgICAgICAgICAgIG9uRXZlbnRIYW5kbGVyOiBzZWNyZXRMYXRlc3RWZXJzaW9uSGFuZGxlcixcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBzZWNyZXRMYXRlc3RWZXJzaW9uQ3VzdG9tUmVzb3VyY2UgPSBuZXcgY2RrLkN1c3RvbVJlc291cmNlKHRoaXMsICdTZWNyZXRMYXRlc3RWZXJzaW9uUmVzb3VyY2UnLCB7XG4gICAgICAgICAgICAgICAgc2VydmljZVRva2VuOiBzZWNyZXRMYXRlc3RWZXJzaW9uUHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VjcmV0QXJuOiB0aGlzLnVzZXJTZWNyZXQuc2VjcmV0QXJuLFxuICAgICAgICAgICAgICAgICAgICBkYXRldGltZTogYG9uVXBkYXRlQ2hlY2tTZWNyZXRWZXJzaW9uOiAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1gLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKHBvbGljeVJlc3VsdC5wb2xpY3lEZXBlbmRhYmxlKSB7XG4gICAgICAgICAgICAgICAgc2VjcmV0TGF0ZXN0VmVyc2lvbkN1c3RvbVJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeShwb2xpY3lSZXN1bHQucG9saWN5RGVwZW5kYWJsZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNlY3JldExhdGVzdFZlcnNpb24gPSBzZWNyZXRMYXRlc3RWZXJzaW9uQ3VzdG9tUmVzb3VyY2UuZ2V0QXR0U3RyaW5nKCdMYXRlc3RWZXJzaW9uSWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhhbmRsZXIuY29ubmVjdGlvbnMuYWxsb3dUb0RlZmF1bHRQb3J0KHByb3BzLmRiQ2x1c3Rlcik7XG5cbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgY3IuUHJvdmlkZXIodGhpcywgJ1Byb3ZpZGVyJywge1xuICAgICAgICAgICAgb25FdmVudEhhbmRsZXI6IGhhbmRsZXIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGN1c3RvbVJlc291cmNlID0gbmV3IGNkay5DdXN0b21SZXNvdXJjZSh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICAgICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBkYkNsdXN0ZXJIb3N0bmFtZTogcHJvcHMuZGJDbHVzdGVyLmNsdXN0ZXJFbmRwb2ludC5ob3N0bmFtZSxcbiAgICAgICAgICAgICAgICBkYkNsdXN0ZXJQb3J0OiBwcm9wcy5kYkNsdXN0ZXIuY2x1c3RlckVuZHBvaW50LnBvcnQsXG4gICAgICAgICAgICAgICAgZGJTZWNyZXRBcm46IHByb3BzLmRiU2VjcmV0LnNlY3JldEFybixcbiAgICAgICAgICAgICAgICB1c2VyU2VjcmV0QXJuOiB0aGlzLnVzZXJTZWNyZXQuc2VjcmV0QXJuLFxuICAgICAgICAgICAgICAgIGRhdGFiYXNlTmFtZTogcHJvcHMuZGF0YWJhc2VOYW1lLFxuICAgICAgICAgICAgICAgIG9uRGVsZXRlOiBwcm9wcy5vbkRlbGV0ZSA/PyAnRGVsZXRlJyxcbiAgICAgICAgICAgICAgICBvbkNyZWF0ZUlmRXhpc3RzOiBwcm9wcy5vbkNyZWF0ZUlmRXhpc3RzID8/ICdGYWlsJyxcbiAgICAgICAgICAgICAgICBvblVwZGF0ZUlmVXNlckRvZXNOb3RFeGlzdDogcHJvcHMub25VcGRhdGVJZlVzZXJEb2VzTm90RXhpc3QgPz8gJ0lnbm9yZScsXG4gICAgICAgICAgICAgICAgb25VcGRhdGVJZkRhdGFiYXNlRG9lc05vdEV4aXN0OiBwcm9wcy5vblVwZGF0ZUlmRGF0YWJhc2VEb2VzTm90RXhpc3QgPz8gJ0lnbm9yZScsXG4gICAgICAgICAgICAgICAgb25VcGRhdGVTZXRVc2VyUGFzc3dvcmQ6IHByb3BzLm9uVXBkYXRlU2V0VXNlclBhc3N3b3JkID8/ICdOZXZlcicsXG4gICAgICAgICAgICAgICAgb25VcGRhdGVTZXRVc2VyUGVybWlzc2lvbnM6IHByb3BzLm9uVXBkYXRlU2V0VXNlclBlcm1pc3Npb25zID8/ICdOZXZlcicsXG4gICAgICAgICAgICAgICAgb25VcGRhdGVTZXREYXRhYmFzZU93bmVyc2hpcDogcHJvcHMub25VcGRhdGVTZXREYXRhYmFzZU93bmVyc2hpcCA/PyAnTmV2ZXInLFxuICAgICAgICAgICAgICAgIC4uLihzZWNyZXRMYXRlc3RWZXJzaW9uID8geyBzZWNyZXRMYXRlc3RWZXJzaW9uIH0gOiB7fSksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjdXN0b21SZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koLi4uaGFuZGxlci5jb25uZWN0aW9ucy5zZWN1cml0eUdyb3Vwcyk7XG4gICAgICAgIGN1c3RvbVJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLnVzZXJTZWNyZXQpO1xuICAgIH1cbn1cbiJdfQ==