UNPKG

@aws-cdk/aws-ecs

Version:

The CDK Construct Library for AWS::ECS

89 lines 13.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InstanceDrainHook = void 0; const fs = require("fs"); const path = require("path"); const autoscaling = require("@aws-cdk/aws-autoscaling"); const hooks = require("@aws-cdk/aws-autoscaling-hooktargets"); const iam = require("@aws-cdk/aws-iam"); const lambda = require("@aws-cdk/aws-lambda"); const cdk = require("@aws-cdk/core"); // keep this import separate from other imports to reduce chance for merge conflicts with v2-main // eslint-disable-next-line no-duplicate-imports, import/order const core_1 = require("@aws-cdk/core"); /** * A hook to drain instances from ECS traffic before they're terminated */ class InstanceDrainHook extends core_1.Construct { /** * Constructs a new instance of the InstanceDrainHook class. */ constructor(scope, id, props) { super(scope, id); const drainTime = props.drainTime || cdk.Duration.minutes(5); // Invoke Lambda via SNS Topic const fn = new lambda.Function(this, 'Function', { code: lambda.Code.fromInline(fs.readFileSync(path.join(__dirname, 'lambda-source', 'index.py'), { encoding: 'utf-8' })), handler: 'index.lambda_handler', runtime: lambda.Runtime.PYTHON_3_9, // Timeout: some extra margin for additional API calls made by the Lambda, // up to a maximum of 15 minutes. timeout: cdk.Duration.seconds(Math.min(drainTime.toSeconds() + 10, 900)), environment: { CLUSTER: props.cluster.clusterName, }, }); // Hook everything up: ASG -> Topic, Topic -> Lambda props.autoScalingGroup.addLifecycleHook('DrainHook', { lifecycleTransition: autoscaling.LifecycleTransition.INSTANCE_TERMINATING, defaultResult: autoscaling.DefaultResult.CONTINUE, notificationTarget: new hooks.FunctionHook(fn, props.topicEncryptionKey), heartbeatTimeout: drainTime, }); // Describe actions cannot be restricted and restrict the CompleteLifecycleAction to the ASG arn // https://docs.aws.amazon.com/autoscaling/ec2/userguide/control-access-using-iam.html fn.addToRolePolicy(new iam.PolicyStatement({ actions: [ 'ec2:DescribeInstances', 'ec2:DescribeInstanceAttribute', 'ec2:DescribeInstanceStatus', 'ec2:DescribeHosts', ], resources: ['*'], })); // Restrict to the ASG fn.addToRolePolicy(new iam.PolicyStatement({ actions: ['autoscaling:CompleteLifecycleAction'], resources: [props.autoScalingGroup.autoScalingGroupArn], })); fn.addToRolePolicy(new iam.PolicyStatement({ actions: ['ecs:DescribeContainerInstances', 'ecs:DescribeTasks'], resources: ['*'], conditions: { ArnEquals: { 'ecs:cluster': props.cluster.clusterArn }, }, })); // Restrict to the ECS Cluster fn.addToRolePolicy(new iam.PolicyStatement({ actions: [ 'ecs:ListContainerInstances', 'ecs:SubmitContainerStateChange', 'ecs:SubmitTaskStateChange', ], resources: [props.cluster.clusterArn], })); // Restrict the container-instance operations to the ECS Cluster fn.addToRolePolicy(new iam.PolicyStatement({ actions: [ 'ecs:UpdateContainerInstancesState', 'ecs:ListTasks', ], conditions: { ArnEquals: { 'ecs:cluster': props.cluster.clusterArn }, }, resources: ['*'], })); } } exports.InstanceDrainHook = InstanceDrainHook; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFuY2UtZHJhaW4taG9vay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImluc3RhbmNlLWRyYWluLWhvb2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix3REFBd0Q7QUFDeEQsOERBQThEO0FBQzlELHdDQUF3QztBQUV4Qyw4Q0FBOEM7QUFDOUMscUNBQXFDO0FBSXJDLGlHQUFpRztBQUNqRyw4REFBOEQ7QUFDOUQsd0NBQTJEO0FBdUMzRDs7R0FFRztBQUNILE1BQWEsaUJBQWtCLFNBQVEsZ0JBQWE7SUFFbEQ7O09BRUc7SUFDSCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTZCO1FBQ3JFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3RCw4QkFBOEI7UUFDOUIsTUFBTSxFQUFFLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDL0MsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsZUFBZSxFQUFFLFVBQVUsQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDdkgsT0FBTyxFQUFFLHNCQUFzQjtZQUMvQixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVO1lBQ2xDLDBFQUEwRTtZQUMxRSxpQ0FBaUM7WUFDakMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN4RSxXQUFXLEVBQUU7Z0JBQ1gsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVzthQUNuQztTQUNGLENBQUMsQ0FBQztRQUVILG9EQUFvRDtRQUNwRCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFO1lBQ25ELG1CQUFtQixFQUFFLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxvQkFBb0I7WUFDekUsYUFBYSxFQUFFLFdBQVcsQ0FBQyxhQUFhLENBQUMsUUFBUTtZQUNqRCxrQkFBa0IsRUFBRSxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUN4RSxnQkFBZ0IsRUFBRSxTQUFTO1NBQzVCLENBQUMsQ0FBQztRQUVILGdHQUFnRztRQUNoRyxzRkFBc0Y7UUFDdEYsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7WUFDekMsT0FBTyxFQUFFO2dCQUNQLHVCQUF1QjtnQkFDdkIsK0JBQStCO2dCQUMvQiw0QkFBNEI7Z0JBQzVCLG1CQUFtQjthQUNwQjtZQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztTQUNqQixDQUFDLENBQUMsQ0FBQztRQUVKLHNCQUFzQjtRQUN0QixFQUFFLENBQUMsZUFBZSxDQUFDLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQztZQUN6QyxPQUFPLEVBQUUsQ0FBQyxxQ0FBcUMsQ0FBQztZQUNoRCxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUM7U0FDeEQsQ0FBQyxDQUFDLENBQUM7UUFFSixFQUFFLENBQUMsZUFBZSxDQUFDLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQztZQUN6QyxPQUFPLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxtQkFBbUIsQ0FBQztZQUNoRSxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDaEIsVUFBVSxFQUFFO2dCQUNWLFNBQVMsRUFBRSxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRTthQUN2RDtTQUNGLENBQUMsQ0FBQyxDQUFDO1FBRUosOEJBQThCO1FBQzlCLEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDO1lBQ3pDLE9BQU8sRUFBRTtnQkFDUCw0QkFBNEI7Z0JBQzVCLGdDQUFnQztnQkFDaEMsMkJBQTJCO2FBQzVCO1lBQ0QsU0FBUyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7U0FDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSixnRUFBZ0U7UUFDaEUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7WUFDekMsT0FBTyxFQUFFO2dCQUNQLG1DQUFtQztnQkFDbkMsZUFBZTthQUNoQjtZQUNELFVBQVUsRUFBRTtnQkFDVixTQUFTLEVBQUUsRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUU7YUFDdkQ7WUFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7U0FDakIsQ0FBQyxDQUFDLENBQUM7S0FDTDtDQUNGO0FBL0VELDhDQStFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBhdXRvc2NhbGluZyBmcm9tICdAYXdzLWNkay9hd3MtYXV0b3NjYWxpbmcnO1xuaW1wb3J0ICogYXMgaG9va3MgZnJvbSAnQGF3cy1jZGsvYXdzLWF1dG9zY2FsaW5nLWhvb2t0YXJnZXRzJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGttcyBmcm9tICdAYXdzLWNkay9hd3Mta21zJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdAYXdzLWNkay9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgSUNsdXN0ZXIgfSBmcm9tICcuLi9jbHVzdGVyJztcblxuLy8ga2VlcCB0aGlzIGltcG9ydCBzZXBhcmF0ZSBmcm9tIG90aGVyIGltcG9ydHMgdG8gcmVkdWNlIGNoYW5jZSBmb3IgbWVyZ2UgY29uZmxpY3RzIHdpdGggdjItbWFpblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWR1cGxpY2F0ZS1pbXBvcnRzLCBpbXBvcnQvb3JkZXJcbmltcG9ydCB7IENvbnN0cnVjdCBhcyBDb3JlQ29uc3RydWN0IH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5cbi8vIFJlZmVyZW5jZSBmb3IgdGhlIHNvdXJjZSBpbiB0aGlzIHBhY2thZ2U6XG4vL1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2F3cy1zYW1wbGVzL2Vjcy1yZWZhcmNoLWNsb3VkZm9ybWF0aW9uL2Jsb2IvbWFzdGVyL2luZnJhc3RydWN0dXJlL2xpZmVjeWNsZWhvb2sueWFtbFxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGluc3RhbmNlIGRyYWluaW5nIGhvb2tcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnN0YW5jZURyYWluSG9va1Byb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBBdXRvU2NhbGluZ0dyb3VwIHRvIGluc3RhbGwgdGhlIGluc3RhbmNlIGRyYWluaW5nIGhvb2sgZm9yXG4gICAqL1xuICBhdXRvU2NhbGluZ0dyb3VwOiBhdXRvc2NhbGluZy5JQXV0b1NjYWxpbmdHcm91cDtcblxuICAvKipcbiAgICogVGhlIGNsdXN0ZXIgb24gd2hpY2ggdGFza3MgaGF2ZSBiZWVuIHNjaGVkdWxlZFxuICAgKi9cbiAgY2x1c3RlcjogSUNsdXN0ZXI7XG5cbiAgLyoqXG4gICAqIEhvdyBtYW55IHNlY29uZHMgdG8gZ2l2ZSB0YXNrcyB0byBkcmFpbiBiZWZvcmUgdGhlIGluc3RhbmNlIGlzIHRlcm1pbmF0ZWQgYW55d2F5XG4gICAqXG4gICAqIE11c3QgYmUgYmV0d2VlbiAwIGFuZCAxNSBtaW51dGVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBEdXJhdGlvbi5taW51dGVzKDE1KVxuICAgKi9cbiAgZHJhaW5UaW1lPzogY2RrLkR1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgSW5zdGFuY2VEcmFpbkhvb2sgY3JlYXRlcyBhbiBTTlMgdG9waWMgZm9yIHRoZSBsaWZlY3ljbGUgaG9vayBvZiB0aGUgQVNHLiBJZiBwcm92aWRlZCwgdGhlbiB0aGlzXG4gICAqIGtleSB3aWxsIGJlIHVzZWQgdG8gZW5jcnlwdCB0aGUgY29udGVudHMgb2YgdGhhdCBTTlMgVG9waWMuXG4gICAqIFNlZSBbU05TIERhdGEgRW5jcnlwdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3Nucy9sYXRlc3QvZGcvc25zLWRhdGEtZW5jcnlwdGlvbi5odG1sKSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgVGhlIFNOUyBUb3BpYyB3aWxsIG5vdCBiZSBlbmNyeXB0ZWQuXG4gICAqL1xuICB0b3BpY0VuY3J5cHRpb25LZXk/OiBrbXMuSUtleTtcbn1cblxuLyoqXG4gKiBBIGhvb2sgdG8gZHJhaW4gaW5zdGFuY2VzIGZyb20gRUNTIHRyYWZmaWMgYmVmb3JlIHRoZXkncmUgdGVybWluYXRlZFxuICovXG5leHBvcnQgY2xhc3MgSW5zdGFuY2VEcmFpbkhvb2sgZXh0ZW5kcyBDb3JlQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgSW5zdGFuY2VEcmFpbkhvb2sgY2xhc3MuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogSW5zdGFuY2VEcmFpbkhvb2tQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBkcmFpblRpbWUgPSBwcm9wcy5kcmFpblRpbWUgfHwgY2RrLkR1cmF0aW9uLm1pbnV0ZXMoNSk7XG5cbiAgICAvLyBJbnZva2UgTGFtYmRhIHZpYSBTTlMgVG9waWNcbiAgICBjb25zdCBmbiA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgJ0Z1bmN0aW9uJywge1xuICAgICAgY29kZTogbGFtYmRhLkNvZGUuZnJvbUlubGluZShmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKF9fZGlybmFtZSwgJ2xhbWJkYS1zb3VyY2UnLCAnaW5kZXgucHknKSwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KSksXG4gICAgICBoYW5kbGVyOiAnaW5kZXgubGFtYmRhX2hhbmRsZXInLFxuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfOSxcbiAgICAgIC8vIFRpbWVvdXQ6IHNvbWUgZXh0cmEgbWFyZ2luIGZvciBhZGRpdGlvbmFsIEFQSSBjYWxscyBtYWRlIGJ5IHRoZSBMYW1iZGEsXG4gICAgICAvLyB1cCB0byBhIG1heGltdW0gb2YgMTUgbWludXRlcy5cbiAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKE1hdGgubWluKGRyYWluVGltZS50b1NlY29uZHMoKSArIDEwLCA5MDApKSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIENMVVNURVI6IHByb3BzLmNsdXN0ZXIuY2x1c3Rlck5hbWUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gSG9vayBldmVyeXRoaW5nIHVwOiBBU0cgLT4gVG9waWMsIFRvcGljIC0+IExhbWJkYVxuICAgIHByb3BzLmF1dG9TY2FsaW5nR3JvdXAuYWRkTGlmZWN5Y2xlSG9vaygnRHJhaW5Ib29rJywge1xuICAgICAgbGlmZWN5Y2xlVHJhbnNpdGlvbjogYXV0b3NjYWxpbmcuTGlmZWN5Y2xlVHJhbnNpdGlvbi5JTlNUQU5DRV9URVJNSU5BVElORyxcbiAgICAgIGRlZmF1bHRSZXN1bHQ6IGF1dG9zY2FsaW5nLkRlZmF1bHRSZXN1bHQuQ09OVElOVUUsXG4gICAgICBub3RpZmljYXRpb25UYXJnZXQ6IG5ldyBob29rcy5GdW5jdGlvbkhvb2soZm4sIHByb3BzLnRvcGljRW5jcnlwdGlvbktleSksXG4gICAgICBoZWFydGJlYXRUaW1lb3V0OiBkcmFpblRpbWUsXG4gICAgfSk7XG5cbiAgICAvLyBEZXNjcmliZSBhY3Rpb25zIGNhbm5vdCBiZSByZXN0cmljdGVkIGFuZCByZXN0cmljdCB0aGUgQ29tcGxldGVMaWZlY3ljbGVBY3Rpb24gdG8gdGhlIEFTRyBhcm5cbiAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXV0b3NjYWxpbmcvZWMyL3VzZXJndWlkZS9jb250cm9sLWFjY2Vzcy11c2luZy1pYW0uaHRtbFxuICAgIGZuLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbXG4gICAgICAgICdlYzI6RGVzY3JpYmVJbnN0YW5jZXMnLFxuICAgICAgICAnZWMyOkRlc2NyaWJlSW5zdGFuY2VBdHRyaWJ1dGUnLFxuICAgICAgICAnZWMyOkRlc2NyaWJlSW5zdGFuY2VTdGF0dXMnLFxuICAgICAgICAnZWMyOkRlc2NyaWJlSG9zdHMnLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgfSkpO1xuXG4gICAgLy8gUmVzdHJpY3QgdG8gdGhlIEFTR1xuICAgIGZuLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbJ2F1dG9zY2FsaW5nOkNvbXBsZXRlTGlmZWN5Y2xlQWN0aW9uJ10sXG4gICAgICByZXNvdXJjZXM6IFtwcm9wcy5hdXRvU2NhbGluZ0dyb3VwLmF1dG9TY2FsaW5nR3JvdXBBcm5dLFxuICAgIH0pKTtcblxuICAgIGZuLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbJ2VjczpEZXNjcmliZUNvbnRhaW5lckluc3RhbmNlcycsICdlY3M6RGVzY3JpYmVUYXNrcyddLFxuICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgQXJuRXF1YWxzOiB7ICdlY3M6Y2x1c3Rlcic6IHByb3BzLmNsdXN0ZXIuY2x1c3RlckFybiB9LFxuICAgICAgfSxcbiAgICB9KSk7XG5cbiAgICAvLyBSZXN0cmljdCB0byB0aGUgRUNTIENsdXN0ZXJcbiAgICBmbi5hZGRUb1JvbGVQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICAnZWNzOkxpc3RDb250YWluZXJJbnN0YW5jZXMnLFxuICAgICAgICAnZWNzOlN1Ym1pdENvbnRhaW5lclN0YXRlQ2hhbmdlJyxcbiAgICAgICAgJ2VjczpTdWJtaXRUYXNrU3RhdGVDaGFuZ2UnLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogW3Byb3BzLmNsdXN0ZXIuY2x1c3RlckFybl0sXG4gICAgfSkpO1xuXG4gICAgLy8gUmVzdHJpY3QgdGhlIGNvbnRhaW5lci1pbnN0YW5jZSBvcGVyYXRpb25zIHRvIHRoZSBFQ1MgQ2x1c3RlclxuICAgIGZuLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbXG4gICAgICAgICdlY3M6VXBkYXRlQ29udGFpbmVySW5zdGFuY2VzU3RhdGUnLFxuICAgICAgICAnZWNzOkxpc3RUYXNrcycsXG4gICAgICBdLFxuICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICBBcm5FcXVhbHM6IHsgJ2VjczpjbHVzdGVyJzogcHJvcHMuY2x1c3Rlci5jbHVzdGVyQXJuIH0sXG4gICAgICB9LFxuICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICB9KSk7XG4gIH1cbn1cbiJdfQ==