mysql-user-and-database-cdk
Version:
[](https://isotoma.github.io/mysql-user-and-database-cdk/) [](https://www.npmjs.com/package/mysql-user-and-database-cdk) [;
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==