@aws-cdk-testing/cli-integ 3.8.0 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -39,7 +39,7 @@
39
39
  "organization": true
40
40
  },
41
41
  "devDependencies": {
42
- "@aws-cdk/toolkit-lib": "0.3.5",
42
+ "@aws-cdk/toolkit-lib": "0.3.7",
43
43
  "@aws-cdk/yarn-cling": "0.0.0",
44
44
  "@cdklabs/eslint-plugin": "^1.3.2",
45
45
  "@stylistic/eslint-plugin": "^3",
@@ -58,7 +58,7 @@
58
58
  "eslint-import-resolver-typescript": "^3.10.1",
59
59
  "eslint-plugin-import": "^2.31.0",
60
60
  "eslint-plugin-jest": "^28.11.0",
61
- "eslint-plugin-jsdoc": "^50.6.14",
61
+ "eslint-plugin-jsdoc": "^50.6.17",
62
62
  "eslint-plugin-prettier": "^5.4.0",
63
63
  "jest": "^29.7.0",
64
64
  "jest-junit": "^16",
@@ -80,7 +80,7 @@
80
80
  "@aws-sdk/client-sso": "^3",
81
81
  "@aws-sdk/client-sts": "^3",
82
82
  "@aws-sdk/credential-providers": "^3",
83
- "@cdklabs/cdk-atmosphere-client": "^0.0.43",
83
+ "@cdklabs/cdk-atmosphere-client": "^0.0.47",
84
84
  "@octokit/rest": "^18.12.0",
85
85
  "@smithy/types": "^4.2.0",
86
86
  "@smithy/util-retry": "^4.0.3",
@@ -115,7 +115,7 @@
115
115
  "publishConfig": {
116
116
  "access": "public"
117
117
  },
118
- "version": "3.8.0",
118
+ "version": "3.10.0",
119
119
  "types": "lib/index.d.ts",
120
120
  "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
121
121
  }
@@ -0,0 +1,38 @@
1
+ const cdk = require('aws-cdk-lib/core');
2
+ const dynamodb = require('aws-cdk-lib/aws-dynamodb');
3
+
4
+ const stackPrefix = process.env.STACK_NAME_PREFIX;
5
+ if (!stackPrefix) {
6
+ throw new Error(`the STACK_NAME_PREFIX environment variable is required`);
7
+ }
8
+
9
+ class BaseStack extends cdk.Stack {
10
+ constructor(scope, id, props) {
11
+ super(scope, id, props);
12
+
13
+ // Create a random table name with prefix
14
+ if (process.env.VERSION == 'v2') {
15
+ new dynamodb.TableV2(this, 'MyGlobalTable', {
16
+ partitionKey: {
17
+ name: 'PK',
18
+ type: dynamodb.AttributeType.STRING,
19
+ },
20
+ tableName: 'integ-test-import-app-base-table-1',
21
+ });
22
+ } else {
23
+ new dynamodb.Table(this, 'MyTable', {
24
+ partitionKey: {
25
+ name: 'PK',
26
+ type: dynamodb.AttributeType.STRING,
27
+ },
28
+ tableName: 'integ-test-import-app-base-table-1',
29
+ removalPolicy: process.env.VERSION == 'v1' ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
30
+ });
31
+ }
32
+ }
33
+ }
34
+
35
+ const app = new cdk.App();
36
+ new BaseStack(app, `${stackPrefix}-base-1`);
37
+
38
+ app.synth();
@@ -0,0 +1,7 @@
1
+ {
2
+ "app": "node app.js",
3
+ "versionReporting": false,
4
+ "context": {
5
+ "aws-cdk:enableDiffNoFail": "true"
6
+ }
7
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lib_1 = require("../../lib");
4
+ jest.setTimeout(2 * 60 * 60_000); // Includes the time to acquire locks, worst-case single-threaded runtime
5
+ (0, lib_1.integTest)('cdk diff --import-existing-resources show resource being imported', (0, lib_1.withSpecificFixture)('import-app', async (fixture) => {
6
+ // GIVEN
7
+ await fixture.cdkDeploy('base-1', {
8
+ modEnv: {
9
+ VERSION: 'v1',
10
+ },
11
+ });
12
+ // THEN
13
+ let diff = await fixture.cdk(['diff', '--import-existing-resources', fixture.fullStackName('base-1')], {
14
+ modEnv: {
15
+ VERSION: 'v2',
16
+ },
17
+ });
18
+ // Assert there are no changes and diff shows import
19
+ expect(diff).not.toContain('There were no differences');
20
+ expect(diff).toContain('[←]');
21
+ expect(diff).toContain('import');
22
+ // THEN
23
+ diff = await fixture.cdk(['diff', fixture.fullStackName('base-1')], {
24
+ modEnv: {
25
+ VERSION: 'v2',
26
+ },
27
+ });
28
+ // Assert there are no changes and diff shows add
29
+ expect(diff).not.toContain('There were no differences');
30
+ expect(diff).toContain('[+]');
31
+ // Deploy the stack with v3 to set table removal policy as destroy
32
+ await fixture.cdkDeploy('base-1', {
33
+ modEnv: {
34
+ VERSION: 'v3',
35
+ },
36
+ });
37
+ }));
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLWNkay1kaWZmLS1pbXBvcnQtZXhpc3RpbmctcmVzb3VyY2VzLXNob3dzLWltcG9ydC5pbnRlZ3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjZGstY2RrLWRpZmYtLWltcG9ydC1leGlzdGluZy1yZXNvdXJjZXMtc2hvd3MtaW1wb3J0LmludGVndGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG1DQUEyRDtBQUUzRCxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyx5RUFBeUU7QUFFM0csSUFBQSxlQUFTLEVBQ1AsbUVBQW1FLEVBQ25FLElBQUEseUJBQW1CLEVBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNsRCxRQUFRO0lBQ1IsTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRTtRQUNoQyxNQUFNLEVBQUU7WUFDTixPQUFPLEVBQUUsSUFBSTtTQUNkO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsT0FBTztJQUNQLElBQUksSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSw2QkFBNkIsRUFBRSxPQUFPLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUU7UUFDckcsTUFBTSxFQUFFO1lBQ04sT0FBTyxFQUFFLElBQUk7U0FDZDtLQUNGLENBQUMsQ0FBQztJQUVILG9EQUFvRDtJQUNwRCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVqQyxPQUFPO0lBQ1AsSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUU7UUFDbEUsTUFBTSxFQUFFO1lBQ04sT0FBTyxFQUFFLElBQUk7U0FDZDtLQUNGLENBQUMsQ0FBQztJQUVILGlEQUFpRDtJQUNqRCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFOUIsa0VBQWtFO0lBQ2xFLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUU7UUFDaEMsTUFBTSxFQUFFO1lBQ04sT0FBTyxFQUFFLElBQUk7U0FDZDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbnRlZ1Rlc3QsIHdpdGhTcGVjaWZpY0ZpeHR1cmUgfSBmcm9tICcuLi8uLi9saWInO1xuXG5qZXN0LnNldFRpbWVvdXQoMiAqIDYwICogNjBfMDAwKTsgLy8gSW5jbHVkZXMgdGhlIHRpbWUgdG8gYWNxdWlyZSBsb2Nrcywgd29yc3QtY2FzZSBzaW5nbGUtdGhyZWFkZWQgcnVudGltZVxuXG5pbnRlZ1Rlc3QoXG4gICdjZGsgZGlmZiAtLWltcG9ydC1leGlzdGluZy1yZXNvdXJjZXMgc2hvdyByZXNvdXJjZSBiZWluZyBpbXBvcnRlZCcsXG4gIHdpdGhTcGVjaWZpY0ZpeHR1cmUoJ2ltcG9ydC1hcHAnLCBhc3luYyAoZml4dHVyZSkgPT4ge1xuICAgIC8vIEdJVkVOXG4gICAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2Jhc2UtMScsIHtcbiAgICAgIG1vZEVudjoge1xuICAgICAgICBWRVJTSU9OOiAndjEnLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIFRIRU5cbiAgICBsZXQgZGlmZiA9IGF3YWl0IGZpeHR1cmUuY2RrKFsnZGlmZicsICctLWltcG9ydC1leGlzdGluZy1yZXNvdXJjZXMnLCBmaXh0dXJlLmZ1bGxTdGFja05hbWUoJ2Jhc2UtMScpXSwge1xuICAgICAgbW9kRW52OiB7XG4gICAgICAgIFZFUlNJT046ICd2MicsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gQXNzZXJ0IHRoZXJlIGFyZSBubyBjaGFuZ2VzIGFuZCBkaWZmIHNob3dzIGltcG9ydFxuICAgIGV4cGVjdChkaWZmKS5ub3QudG9Db250YWluKCdUaGVyZSB3ZXJlIG5vIGRpZmZlcmVuY2VzJyk7XG4gICAgZXhwZWN0KGRpZmYpLnRvQ29udGFpbignW+KGkF0nKTtcbiAgICBleHBlY3QoZGlmZikudG9Db250YWluKCdpbXBvcnQnKTtcblxuICAgIC8vIFRIRU5cbiAgICBkaWZmID0gYXdhaXQgZml4dHVyZS5jZGsoWydkaWZmJywgZml4dHVyZS5mdWxsU3RhY2tOYW1lKCdiYXNlLTEnKV0sIHtcbiAgICAgIG1vZEVudjoge1xuICAgICAgICBWRVJTSU9OOiAndjInLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIEFzc2VydCB0aGVyZSBhcmUgbm8gY2hhbmdlcyBhbmQgZGlmZiBzaG93cyBhZGRcbiAgICBleHBlY3QoZGlmZikubm90LnRvQ29udGFpbignVGhlcmUgd2VyZSBubyBkaWZmZXJlbmNlcycpO1xuICAgIGV4cGVjdChkaWZmKS50b0NvbnRhaW4oJ1srXScpO1xuXG4gICAgLy8gRGVwbG95IHRoZSBzdGFjayB3aXRoIHYzIHRvIHNldCB0YWJsZSByZW1vdmFsIHBvbGljeSBhcyBkZXN0cm95XG4gICAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2Jhc2UtMScsIHtcbiAgICAgIG1vZEVudjoge1xuICAgICAgICBWRVJTSU9OOiAndjMnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSksXG4pO1xuIl19
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const client_s3_1 = require("@aws-sdk/client-s3");
4
+ const lib_1 = require("../../lib");
5
+ jest.setTimeout(2 * 60 * 60_000); // Includes the time to acquire locks, worst-case single-threaded runtime
6
+ const DAY = 24 * 60 * 60 * 1000;
7
+ const S3_ISOLATED_TAG = 'aws-cdk:isolated';
8
+ (0, lib_1.integTest)('Garbage Collection deletes unused s3 objects with rollback-buffer-days', (0, lib_1.withoutBootstrap)(async (fixture) => {
9
+ const toolkitStackName = fixture.bootstrapStackName;
10
+ const bootstrapBucketName = `aws-cdk-garbage-collect-integ-test-bckt-${(0, lib_1.randomString)()}`;
11
+ fixture.rememberToDeleteBucket(bootstrapBucketName); // just in case
12
+ await fixture.cdkBootstrapModern({
13
+ toolkitStackName,
14
+ bootstrapBucketName,
15
+ });
16
+ await fixture.cdkDeploy('lambda', {
17
+ options: [
18
+ '--context', `bootstrapBucket=${bootstrapBucketName}`,
19
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
20
+ '--toolkit-stack-name', toolkitStackName,
21
+ '--force',
22
+ ],
23
+ });
24
+ fixture.log('Setup complete!');
25
+ await fixture.cdkDestroy('lambda', {
26
+ options: [
27
+ '--context', `bootstrapBucket=${bootstrapBucketName}`,
28
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
29
+ '--toolkit-stack-name', toolkitStackName,
30
+ '--force',
31
+ ],
32
+ });
33
+ // Pretend the assets were tagged with an old date > 1 day ago so that garbage collection
34
+ // should pick up and delete asset even with rollbackBufferDays=1
35
+ const res = await fixture.aws.s3.send(new client_s3_1.ListObjectsV2Command({ Bucket: bootstrapBucketName }));
36
+ for (const contents of res.Contents ?? []) {
37
+ await fixture.aws.s3.send(new client_s3_1.PutObjectTaggingCommand({
38
+ Bucket: bootstrapBucketName,
39
+ Key: contents.Key,
40
+ Tagging: {
41
+ TagSet: [{
42
+ Key: S3_ISOLATED_TAG,
43
+ Value: String(Date.now() - (30 * DAY)),
44
+ }],
45
+ },
46
+ }));
47
+ }
48
+ await fixture.cdkGarbageCollect({
49
+ rollbackBufferDays: 1,
50
+ type: 's3',
51
+ bootstrapStackName: toolkitStackName,
52
+ });
53
+ fixture.log('Garbage collection complete!');
54
+ // assert that the bootstrap bucket is empty
55
+ await fixture.aws.s3.send(new client_s3_1.ListObjectsV2Command({ Bucket: bootstrapBucketName }))
56
+ .then((result) => {
57
+ expect(result.Contents).toBeUndefined();
58
+ });
59
+ }));
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLWdjLWRlbGV0ZXMtdW51c2VkLXMzLW9iamVjdHMtcm9sbGJhY2suaW50ZWd0ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2RrLWdjLWRlbGV0ZXMtdW51c2VkLXMzLW9iamVjdHMtcm9sbGJhY2suaW50ZWd0ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsa0RBQW1GO0FBQ25GLG1DQUFzRTtBQUV0RSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyx5RUFBeUU7QUFFM0csTUFBTSxHQUFHLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sZUFBZSxHQUFHLGtCQUFrQixDQUFDO0FBRTNDLElBQUEsZUFBUyxFQUNQLHdFQUF3RSxFQUN4RSxJQUFBLHNCQUFnQixFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNqQyxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUNwRCxNQUFNLG1CQUFtQixHQUFHLDJDQUEyQyxJQUFBLGtCQUFZLEdBQUUsRUFBRSxDQUFDO0lBQ3hGLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsZUFBZTtJQUVwRSxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0I7UUFDaEIsbUJBQW1CO0tBQ3BCLENBQUMsQ0FBQztJQUVILE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUU7UUFDaEMsT0FBTyxFQUFFO1lBQ1AsV0FBVyxFQUFFLG1CQUFtQixtQkFBbUIsRUFBRTtZQUNyRCxXQUFXLEVBQUUsb0NBQW9DLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDcEUsc0JBQXNCLEVBQUUsZ0JBQWdCO1lBQ3hDLFNBQVM7U0FDVjtLQUNGLENBQUMsQ0FBQztJQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUUvQixNQUFNLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFO1FBQ2pDLE9BQU8sRUFBRTtZQUNQLFdBQVcsRUFBRSxtQkFBbUIsbUJBQW1CLEVBQUU7WUFDckQsV0FBVyxFQUFFLG9DQUFvQyxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQ3BFLHNCQUFzQixFQUFFLGdCQUFnQjtZQUN4QyxTQUFTO1NBQ1Y7S0FDRixDQUFDLENBQUM7SUFFSCx5RkFBeUY7SUFDekYsaUVBQWlFO0lBQ2pFLE1BQU0sR0FBRyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksZ0NBQW9CLENBQUMsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDakcsS0FBSyxNQUFNLFFBQVEsSUFBSSxHQUFHLENBQUMsUUFBUSxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQzFDLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksbUNBQXVCLENBQUM7WUFDcEQsTUFBTSxFQUFFLG1CQUFtQjtZQUMzQixHQUFHLEVBQUUsUUFBUSxDQUFDLEdBQUc7WUFDakIsT0FBTyxFQUFFO2dCQUNQLE1BQU0sRUFBRSxDQUFDO3dCQUNQLEdBQUcsRUFBRSxlQUFlO3dCQUNwQixLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQztxQkFDdkMsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsTUFBTSxPQUFPLENBQUMsaUJBQWlCLENBQUM7UUFDOUIsa0JBQWtCLEVBQUUsQ0FBQztRQUNyQixJQUFJLEVBQUUsSUFBSTtRQUNWLGtCQUFrQixFQUFFLGdCQUFnQjtLQUNyQyxDQUFDLENBQUM7SUFDSCxPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFFNUMsNENBQTRDO0lBQzVDLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksZ0NBQW9CLENBQUMsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1NBQ2pGLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQ2YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMxQyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQyxDQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMaXN0T2JqZWN0c1YyQ29tbWFuZCwgUHV0T2JqZWN0VGFnZ2luZ0NvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtczMnO1xuaW1wb3J0IHsgaW50ZWdUZXN0LCB3aXRob3V0Qm9vdHN0cmFwLCByYW5kb21TdHJpbmcgfSBmcm9tICcuLi8uLi9saWInO1xuXG5qZXN0LnNldFRpbWVvdXQoMiAqIDYwICogNjBfMDAwKTsgLy8gSW5jbHVkZXMgdGhlIHRpbWUgdG8gYWNxdWlyZSBsb2Nrcywgd29yc3QtY2FzZSBzaW5nbGUtdGhyZWFkZWQgcnVudGltZVxuXG5jb25zdCBEQVkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuY29uc3QgUzNfSVNPTEFURURfVEFHID0gJ2F3cy1jZGs6aXNvbGF0ZWQnO1xuXG5pbnRlZ1Rlc3QoXG4gICdHYXJiYWdlIENvbGxlY3Rpb24gZGVsZXRlcyB1bnVzZWQgczMgb2JqZWN0cyB3aXRoIHJvbGxiYWNrLWJ1ZmZlci1kYXlzJyxcbiAgd2l0aG91dEJvb3RzdHJhcChhc3luYyAoZml4dHVyZSkgPT4ge1xuICAgIGNvbnN0IHRvb2xraXRTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcbiAgICBjb25zdCBib290c3RyYXBCdWNrZXROYW1lID0gYGF3cy1jZGstZ2FyYmFnZS1jb2xsZWN0LWludGVnLXRlc3QtYmNrdC0ke3JhbmRvbVN0cmluZygpfWA7XG4gICAgZml4dHVyZS5yZW1lbWJlclRvRGVsZXRlQnVja2V0KGJvb3RzdHJhcEJ1Y2tldE5hbWUpOyAvLyBqdXN0IGluIGNhc2VcblxuICAgIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICAgIHRvb2xraXRTdGFja05hbWUsXG4gICAgICBib290c3RyYXBCdWNrZXROYW1lLFxuICAgIH0pO1xuXG4gICAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYScsIHtcbiAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgJy0tY29udGV4dCcsIGBib290c3RyYXBCdWNrZXQ9JHtib290c3RyYXBCdWNrZXROYW1lfWAsXG4gICAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgICAnLS10b29sa2l0LXN0YWNrLW5hbWUnLCB0b29sa2l0U3RhY2tOYW1lLFxuICAgICAgICAnLS1mb3JjZScsXG4gICAgICBdLFxuICAgIH0pO1xuICAgIGZpeHR1cmUubG9nKCdTZXR1cCBjb21wbGV0ZSEnKTtcblxuICAgIGF3YWl0IGZpeHR1cmUuY2RrRGVzdHJveSgnbGFtYmRhJywge1xuICAgICAgb3B0aW9uczogW1xuICAgICAgICAnLS1jb250ZXh0JywgYGJvb3RzdHJhcEJ1Y2tldD0ke2Jvb3RzdHJhcEJ1Y2tldE5hbWV9YCxcbiAgICAgICAgJy0tY29udGV4dCcsIGBAYXdzLWNkay9jb3JlOmJvb3RzdHJhcFF1YWxpZmllcj0ke2ZpeHR1cmUucXVhbGlmaWVyfWAsXG4gICAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIHRvb2xraXRTdGFja05hbWUsXG4gICAgICAgICctLWZvcmNlJyxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICAvLyBQcmV0ZW5kIHRoZSBhc3NldHMgd2VyZSB0YWdnZWQgd2l0aCBhbiBvbGQgZGF0ZSA+IDEgZGF5IGFnbyBzbyB0aGF0IGdhcmJhZ2UgY29sbGVjdGlvblxuICAgIC8vIHNob3VsZCBwaWNrIHVwIGFuZCBkZWxldGUgYXNzZXQgZXZlbiB3aXRoIHJvbGxiYWNrQnVmZmVyRGF5cz0xXG4gICAgY29uc3QgcmVzID0gYXdhaXQgZml4dHVyZS5hd3MuczMuc2VuZChuZXcgTGlzdE9iamVjdHNWMkNvbW1hbmQoeyBCdWNrZXQ6IGJvb3RzdHJhcEJ1Y2tldE5hbWUgfSkpO1xuICAgIGZvciAoY29uc3QgY29udGVudHMgb2YgcmVzLkNvbnRlbnRzID8/IFtdKSB7XG4gICAgICBhd2FpdCBmaXh0dXJlLmF3cy5zMy5zZW5kKG5ldyBQdXRPYmplY3RUYWdnaW5nQ29tbWFuZCh7XG4gICAgICAgIEJ1Y2tldDogYm9vdHN0cmFwQnVja2V0TmFtZSxcbiAgICAgICAgS2V5OiBjb250ZW50cy5LZXksXG4gICAgICAgIFRhZ2dpbmc6IHtcbiAgICAgICAgICBUYWdTZXQ6IFt7XG4gICAgICAgICAgICBLZXk6IFMzX0lTT0xBVEVEX1RBRyxcbiAgICAgICAgICAgIFZhbHVlOiBTdHJpbmcoRGF0ZS5ub3coKSAtICgzMCAqIERBWSkpLFxuICAgICAgICAgIH1dLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIGF3YWl0IGZpeHR1cmUuY2RrR2FyYmFnZUNvbGxlY3Qoe1xuICAgICAgcm9sbGJhY2tCdWZmZXJEYXlzOiAxLFxuICAgICAgdHlwZTogJ3MzJyxcbiAgICAgIGJvb3RzdHJhcFN0YWNrTmFtZTogdG9vbGtpdFN0YWNrTmFtZSxcbiAgICB9KTtcbiAgICBmaXh0dXJlLmxvZygnR2FyYmFnZSBjb2xsZWN0aW9uIGNvbXBsZXRlIScpO1xuXG4gICAgLy8gYXNzZXJ0IHRoYXQgdGhlIGJvb3RzdHJhcCBidWNrZXQgaXMgZW1wdHlcbiAgICBhd2FpdCBmaXh0dXJlLmF3cy5zMy5zZW5kKG5ldyBMaXN0T2JqZWN0c1YyQ29tbWFuZCh7IEJ1Y2tldDogYm9vdHN0cmFwQnVja2V0TmFtZSB9KSlcbiAgICAgIC50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5Db250ZW50cykudG9CZVVuZGVmaW5lZCgpO1xuICAgICAgfSk7XG4gIH0pLFxuKTtcbiJdfQ==