aws-cdk 2.178.2 → 2.179.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.
Files changed (53) hide show
  1. package/THIRD_PARTY_LICENSES +256 -234
  2. package/build-info.json +2 -2
  3. package/lib/api/cxapp/cloud-assembly.d.ts +18 -1
  4. package/lib/api/cxapp/cloud-assembly.js +38 -5
  5. package/lib/api/deployments/asset-publishing.d.ts +4 -27
  6. package/lib/api/deployments/asset-publishing.js +8 -34
  7. package/lib/api/deployments/cloudformation.d.ts +1 -0
  8. package/lib/api/deployments/cloudformation.js +9 -1
  9. package/lib/api/deployments/deployments.d.ts +0 -22
  10. package/lib/api/deployments/deployments.js +1 -29
  11. package/lib/api/garbage-collection/garbage-collector.js +3 -3
  12. package/lib/api/garbage-collection/progress-printer.js +8 -1
  13. package/lib/{import.d.ts → api/resource-import/importer.d.ts} +55 -12
  14. package/lib/api/resource-import/importer.js +332 -0
  15. package/lib/api/resource-import/index.d.ts +2 -0
  16. package/lib/api/resource-import/index.js +19 -0
  17. package/lib/{migrator.d.ts → api/resource-import/migrator.d.ts} +9 -6
  18. package/lib/api/resource-import/migrator.js +74 -0
  19. package/lib/cli/cdk-toolkit.d.ts +7 -0
  20. package/lib/cli/cdk-toolkit.js +20 -9
  21. package/lib/cli/cli.js +4 -3
  22. package/lib/cli/convert-to-user-input.js +1 -1
  23. package/lib/cli/messages.d.ts +30 -0
  24. package/lib/cli/messages.js +112 -0
  25. package/lib/cli/parse-command-line-arguments.js +1 -1
  26. package/lib/cli/user-configuration.js +2 -1
  27. package/lib/cli/user-input.js +1 -1
  28. package/lib/cli/util/yargs-helpers.js +2 -2
  29. package/lib/cli/version.d.ts +1 -1
  30. package/lib/cli/version.js +6 -3
  31. package/lib/commands/doctor.js +2 -2
  32. package/lib/index.js +126 -197
  33. package/lib/init-templates/.init-version.json +1 -1
  34. package/lib/init-templates/app/javascript/package.json +1 -1
  35. package/lib/init-templates/app/typescript/package.json +1 -1
  36. package/lib/init-templates/sample-app/javascript/package.json +1 -1
  37. package/lib/init-templates/sample-app/typescript/package.json +1 -1
  38. package/lib/init.d.ts +13 -1
  39. package/lib/init.js +37 -32
  40. package/lib/list-stacks.d.ts +1 -17
  41. package/lib/list-stacks.js +2 -37
  42. package/package.json +10 -10
  43. package/test/api/deployments/cloudformation-deployments.test.js +27 -3
  44. package/test/api/garbage-collection.test.js +23 -1
  45. package/test/api/resource-import/import.test.js +373 -0
  46. package/test/init.test.js +14 -1
  47. package/test/toolkit/cli-io-host.test.js +18 -10
  48. package/lib/import.js +0 -329
  49. package/lib/migrator.js +0 -67
  50. package/test/_helpers/prompts.d.ts +0 -11
  51. package/test/_helpers/prompts.js +0 -22
  52. package/test/import.test.js +0 -364
  53. /package/test/{import.test.d.ts → api/resource-import/import.test.d.ts} +0 -0
package/lib/migrator.js DELETED
@@ -1,67 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ResourceMigrator = void 0;
4
- const chalk = require("chalk");
5
- const fs = require("fs-extra");
6
- const string_manipulation_1 = require("./api/util/string-manipulation");
7
- const import_1 = require("./import");
8
- const logging_1 = require("./logging");
9
- class ResourceMigrator {
10
- constructor(props) {
11
- this.props = props;
12
- }
13
- /**
14
- * Checks to see if a migrate.json file exists. If it does and the source is either `filepath` or
15
- * is in the same environment as the stack deployment, a new stack is created and the resources are
16
- * migrated to the stack using an IMPORT changeset. The normal deployment will resume after this is complete
17
- * to add back in any outputs and the CDKMetadata.
18
- */
19
- async tryMigrateResources(stacks, options) {
20
- const stack = stacks.stackArtifacts[0];
21
- const migrateDeployment = new import_1.ResourceImporter(stack, this.props.deployments);
22
- const resourcesToImport = await this.tryGetResources(await migrateDeployment.resolveEnvironment());
23
- if (resourcesToImport) {
24
- (0, logging_1.info)('%s: creating stack for resource migration...', chalk.bold(stack.displayName));
25
- (0, logging_1.info)('%s: importing resources into stack...', chalk.bold(stack.displayName));
26
- await this.performResourceMigration(migrateDeployment, resourcesToImport, options);
27
- fs.rmSync('migrate.json');
28
- (0, logging_1.info)('%s: applying CDKMetadata and Outputs to stack (if applicable)...', chalk.bold(stack.displayName));
29
- }
30
- }
31
- /**
32
- * Creates a new stack with just the resources to be migrated
33
- */
34
- async performResourceMigration(migrateDeployment, resourcesToImport, options) {
35
- const startDeployTime = new Date().getTime();
36
- let elapsedDeployTime = 0;
37
- // Initial Deployment
38
- await migrateDeployment.importResourcesFromMigrate(resourcesToImport, {
39
- roleArn: options.roleArn,
40
- toolkitStackName: options.toolkitStackName,
41
- deploymentMethod: options.deploymentMethod,
42
- usePreviousParameters: true,
43
- progress: options.progress,
44
- rollback: options.rollback,
45
- });
46
- elapsedDeployTime = new Date().getTime() - startDeployTime;
47
- (0, logging_1.info)('\n✨ Resource migration time: %ss\n', (0, string_manipulation_1.formatTime)(elapsedDeployTime));
48
- }
49
- async tryGetResources(environment) {
50
- try {
51
- const migrateFile = fs.readJsonSync('migrate.json', {
52
- encoding: 'utf-8',
53
- });
54
- const sourceEnv = migrateFile.Source.split(':');
55
- if (sourceEnv[0] === 'localfile' ||
56
- (sourceEnv[4] === environment.account && sourceEnv[3] === environment.region)) {
57
- return migrateFile.Resources;
58
- }
59
- }
60
- catch (e) {
61
- // Nothing to do
62
- }
63
- return undefined;
64
- }
65
- }
66
- exports.ResourceMigrator = ResourceMigrator;
67
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtaWdyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSwrQkFBK0I7QUFDL0IsK0JBQStCO0FBRy9CLHdFQUE0RDtBQUU1RCxxQ0FBNEM7QUFDNUMsdUNBQWlDO0FBUWpDLE1BQWEsZ0JBQWdCO0lBQzNCLFlBQW9DLEtBQTRCO1FBQTVCLFVBQUssR0FBTCxLQUFLLENBQXVCO0lBQUcsQ0FBQztJQUVwRTs7Ozs7T0FLRztJQUNJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxNQUF1QixFQUFFLE9BQWdDO1FBQ3hGLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLHlCQUFnQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzlFLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0saUJBQWlCLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO1FBRW5HLElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUN0QixJQUFBLGNBQUksRUFBQyw4Q0FBOEMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ3BGLElBQUEsY0FBSSxFQUFDLHVDQUF1QyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFFN0UsTUFBTSxJQUFJLENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFFbkYsRUFBRSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUMxQixJQUFBLGNBQUksRUFBQyxrRUFBa0UsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzFHLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsd0JBQXdCLENBQ3BDLGlCQUFtQyxFQUNuQyxpQkFBb0MsRUFDcEMsT0FBZ0M7UUFFaEMsTUFBTSxlQUFlLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM3QyxJQUFJLGlCQUFpQixHQUFHLENBQUMsQ0FBQztRQUUxQixxQkFBcUI7UUFDckIsTUFBTSxpQkFBaUIsQ0FBQywwQkFBMEIsQ0FBQyxpQkFBaUIsRUFBRTtZQUNwRSxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87WUFDeEIsZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLGdCQUFnQjtZQUMxQyxnQkFBZ0IsRUFBRSxPQUFPLENBQUMsZ0JBQWdCO1lBQzFDLHFCQUFxQixFQUFFLElBQUk7WUFDM0IsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1lBQzFCLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtTQUMzQixDQUFDLENBQUM7UUFFSCxpQkFBaUIsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLGVBQWUsQ0FBQztRQUMzRCxJQUFBLGNBQUksRUFBQyxxQ0FBcUMsRUFBRSxJQUFBLGdDQUFVLEVBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFTSxLQUFLLENBQUMsZUFBZSxDQUFDLFdBQThCO1FBQ3pELElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFO2dCQUNsRCxRQUFRLEVBQUUsT0FBTzthQUNsQixDQUFDLENBQUM7WUFDSCxNQUFNLFNBQVMsR0FBSSxXQUFXLENBQUMsTUFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDNUQsSUFDRSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssV0FBVztnQkFDNUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssV0FBVyxDQUFDLE9BQU8sSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUM3RSxDQUFDO2dCQUNELE9BQU8sV0FBVyxDQUFDLFNBQVMsQ0FBQztZQUMvQixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxnQkFBZ0I7UUFDbEIsQ0FBQztRQUVELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7Q0FDRjtBQXBFRCw0Q0FvRUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyBTdGFja0NvbGxlY3Rpb24gfSBmcm9tICcuL2FwaS9jeGFwcC9jbG91ZC1hc3NlbWJseSc7XG5pbXBvcnQgeyBEZXBsb3ltZW50cywgUmVzb3VyY2VzVG9JbXBvcnQgfSBmcm9tICcuL2FwaS9kZXBsb3ltZW50cyc7XG5pbXBvcnQgeyBmb3JtYXRUaW1lIH0gZnJvbSAnLi9hcGkvdXRpbC9zdHJpbmctbWFuaXB1bGF0aW9uJztcbmltcG9ydCB7IERlcGxveU9wdGlvbnMgfSBmcm9tICcuL2NsaS9jZGstdG9vbGtpdCc7XG5pbXBvcnQgeyBSZXNvdXJjZUltcG9ydGVyIH0gZnJvbSAnLi9pbXBvcnQnO1xuaW1wb3J0IHsgaW5mbyB9IGZyb20gJy4vbG9nZ2luZyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb3VyY2VNaWdyYXRvclByb3BzIHtcbiAgZGVwbG95bWVudHM6IERlcGxveW1lbnRzO1xufVxuXG50eXBlIFJlc291cmNlTWlncmF0b3JPcHRpb25zID0gUGljazxEZXBsb3lPcHRpb25zLCAncm9sZUFybicgfCAndG9vbGtpdFN0YWNrTmFtZScgfCAnZGVwbG95bWVudE1ldGhvZCcgfCAncHJvZ3Jlc3MnIHwgJ3JvbGxiYWNrJz5cblxuZXhwb3J0IGNsYXNzIFJlc291cmNlTWlncmF0b3Ige1xuICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBwcm9wczogUmVzb3VyY2VNaWdyYXRvclByb3BzKSB7fVxuXG4gIC8qKlxuICAgKiBDaGVja3MgdG8gc2VlIGlmIGEgbWlncmF0ZS5qc29uIGZpbGUgZXhpc3RzLiBJZiBpdCBkb2VzIGFuZCB0aGUgc291cmNlIGlzIGVpdGhlciBgZmlsZXBhdGhgIG9yXG4gICAqIGlzIGluIHRoZSBzYW1lIGVudmlyb25tZW50IGFzIHRoZSBzdGFjayBkZXBsb3ltZW50LCBhIG5ldyBzdGFjayBpcyBjcmVhdGVkIGFuZCB0aGUgcmVzb3VyY2VzIGFyZVxuICAgKiBtaWdyYXRlZCB0byB0aGUgc3RhY2sgdXNpbmcgYW4gSU1QT1JUIGNoYW5nZXNldC4gVGhlIG5vcm1hbCBkZXBsb3ltZW50IHdpbGwgcmVzdW1lIGFmdGVyIHRoaXMgaXMgY29tcGxldGVcbiAgICogdG8gYWRkIGJhY2sgaW4gYW55IG91dHB1dHMgYW5kIHRoZSBDREtNZXRhZGF0YS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB0cnlNaWdyYXRlUmVzb3VyY2VzKHN0YWNrczogU3RhY2tDb2xsZWN0aW9uLCBvcHRpb25zOiBSZXNvdXJjZU1pZ3JhdG9yT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tzLnN0YWNrQXJ0aWZhY3RzWzBdO1xuICAgIGNvbnN0IG1pZ3JhdGVEZXBsb3ltZW50ID0gbmV3IFJlc291cmNlSW1wb3J0ZXIoc3RhY2ssIHRoaXMucHJvcHMuZGVwbG95bWVudHMpO1xuICAgIGNvbnN0IHJlc291cmNlc1RvSW1wb3J0ID0gYXdhaXQgdGhpcy50cnlHZXRSZXNvdXJjZXMoYXdhaXQgbWlncmF0ZURlcGxveW1lbnQucmVzb2x2ZUVudmlyb25tZW50KCkpO1xuXG4gICAgaWYgKHJlc291cmNlc1RvSW1wb3J0KSB7XG4gICAgICBpbmZvKCclczogY3JlYXRpbmcgc3RhY2sgZm9yIHJlc291cmNlIG1pZ3JhdGlvbi4uLicsIGNoYWxrLmJvbGQoc3RhY2suZGlzcGxheU5hbWUpKTtcbiAgICAgIGluZm8oJyVzOiBpbXBvcnRpbmcgcmVzb3VyY2VzIGludG8gc3RhY2suLi4nLCBjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKSk7XG5cbiAgICAgIGF3YWl0IHRoaXMucGVyZm9ybVJlc291cmNlTWlncmF0aW9uKG1pZ3JhdGVEZXBsb3ltZW50LCByZXNvdXJjZXNUb0ltcG9ydCwgb3B0aW9ucyk7XG5cbiAgICAgIGZzLnJtU3luYygnbWlncmF0ZS5qc29uJyk7XG4gICAgICBpbmZvKCclczogYXBwbHlpbmcgQ0RLTWV0YWRhdGEgYW5kIE91dHB1dHMgdG8gc3RhY2sgKGlmIGFwcGxpY2FibGUpLi4uJywgY2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHN0YWNrIHdpdGgganVzdCB0aGUgcmVzb3VyY2VzIHRvIGJlIG1pZ3JhdGVkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHBlcmZvcm1SZXNvdXJjZU1pZ3JhdGlvbihcbiAgICBtaWdyYXRlRGVwbG95bWVudDogUmVzb3VyY2VJbXBvcnRlcixcbiAgICByZXNvdXJjZXNUb0ltcG9ydDogUmVzb3VyY2VzVG9JbXBvcnQsXG4gICAgb3B0aW9uczogUmVzb3VyY2VNaWdyYXRvck9wdGlvbnMsXG4gICkge1xuICAgIGNvbnN0IHN0YXJ0RGVwbG95VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGxldCBlbGFwc2VkRGVwbG95VGltZSA9IDA7XG5cbiAgICAvLyBJbml0aWFsIERlcGxveW1lbnRcbiAgICBhd2FpdCBtaWdyYXRlRGVwbG95bWVudC5pbXBvcnRSZXNvdXJjZXNGcm9tTWlncmF0ZShyZXNvdXJjZXNUb0ltcG9ydCwge1xuICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgdG9vbGtpdFN0YWNrTmFtZTogb3B0aW9ucy50b29sa2l0U3RhY2tOYW1lLFxuICAgICAgZGVwbG95bWVudE1ldGhvZDogb3B0aW9ucy5kZXBsb3ltZW50TWV0aG9kLFxuICAgICAgdXNlUHJldmlvdXNQYXJhbWV0ZXJzOiB0cnVlLFxuICAgICAgcHJvZ3Jlc3M6IG9wdGlvbnMucHJvZ3Jlc3MsXG4gICAgICByb2xsYmFjazogb3B0aW9ucy5yb2xsYmFjayxcbiAgICB9KTtcblxuICAgIGVsYXBzZWREZXBsb3lUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydERlcGxveVRpbWU7XG4gICAgaW5mbygnXFxu4pyoICBSZXNvdXJjZSBtaWdyYXRpb24gdGltZTogJXNzXFxuJywgZm9ybWF0VGltZShlbGFwc2VkRGVwbG95VGltZSkpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHRyeUdldFJlc291cmNlcyhlbnZpcm9ubWVudDogY3hhcGkuRW52aXJvbm1lbnQpOiBQcm9taXNlPFJlc291cmNlc1RvSW1wb3J0IHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG1pZ3JhdGVGaWxlID0gZnMucmVhZEpzb25TeW5jKCdtaWdyYXRlLmpzb24nLCB7XG4gICAgICAgIGVuY29kaW5nOiAndXRmLTgnLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBzb3VyY2VFbnYgPSAobWlncmF0ZUZpbGUuU291cmNlIGFzIHN0cmluZykuc3BsaXQoJzonKTtcbiAgICAgIGlmIChcbiAgICAgICAgc291cmNlRW52WzBdID09PSAnbG9jYWxmaWxlJyB8fFxuICAgICAgICAoc291cmNlRW52WzRdID09PSBlbnZpcm9ubWVudC5hY2NvdW50ICYmIHNvdXJjZUVudlszXSA9PT0gZW52aXJvbm1lbnQucmVnaW9uKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBtaWdyYXRlRmlsZS5SZXNvdXJjZXM7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gTm90aGluZyB0byBkb1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuIl19
@@ -1,11 +0,0 @@
1
- /**
2
- * Sends a response to a prompt to stdin
3
- * When using this in tests, call just before the prompt runs.
4
- *
5
- * @example
6
- * ```ts
7
- * sendResponse('y');
8
- * await prompt('Confirm (y/n)?');
9
- * ```
10
- */
11
- export declare function sendResponse(res: string, delay?: number): void;
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sendResponse = sendResponse;
4
- /**
5
- * Sends a response to a prompt to stdin
6
- * When using this in tests, call just before the prompt runs.
7
- *
8
- * @example
9
- * ```ts
10
- * sendResponse('y');
11
- * await prompt('Confirm (y/n)?');
12
- * ```
13
- */
14
- function sendResponse(res, delay = 0) {
15
- if (!delay) {
16
- setImmediate(() => process.stdin.emit('data', `${res}\n`));
17
- }
18
- else {
19
- setTimeout(() => process.stdin.emit('data', `${res}\n`), delay);
20
- }
21
- }
22
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbXB0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByb21wdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFVQSxvQ0FNQztBQWhCRDs7Ozs7Ozs7O0dBU0c7QUFDSCxTQUFnQixZQUFZLENBQUMsR0FBVyxFQUFFLEtBQUssR0FBRyxDQUFDO0lBQ2pELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNYLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztTQUFNLENBQUM7UUFDTixVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNsRSxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2VuZHMgYSByZXNwb25zZSB0byBhIHByb21wdCB0byBzdGRpblxuICogV2hlbiB1c2luZyB0aGlzIGluIHRlc3RzLCBjYWxsIGp1c3QgYmVmb3JlIHRoZSBwcm9tcHQgcnVucy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIHNlbmRSZXNwb25zZSgneScpO1xuICogYXdhaXQgcHJvbXB0KCdDb25maXJtICh5L24pPycpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZW5kUmVzcG9uc2UocmVzOiBzdHJpbmcsIGRlbGF5ID0gMCkge1xuICBpZiAoIWRlbGF5KSB7XG4gICAgc2V0SW1tZWRpYXRlKCgpID0+IHByb2Nlc3Muc3RkaW4uZW1pdCgnZGF0YScsIGAke3Jlc31cXG5gKSk7XG4gIH0gZWxzZSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiBwcm9jZXNzLnN0ZGluLmVtaXQoJ2RhdGEnLCBgJHtyZXN9XFxuYCksIGRlbGF5KTtcbiAgfVxufVxuIl19
@@ -1,364 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- jest.mock('promptly', () => {
4
- return {
5
- ...jest.requireActual('promptly'),
6
- confirm: jest.fn(),
7
- prompt: jest.fn(),
8
- };
9
- });
10
- const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
11
- const promptly = require("promptly");
12
- const util_1 = require("./util");
13
- const mock_sdk_1 = require("./util/mock-sdk");
14
- const deployments_1 = require("../lib/api/deployments");
15
- const import_1 = require("../lib/import");
16
- const promptlyConfirm = promptly.confirm;
17
- const promptlyPrompt = promptly.prompt;
18
- function stackWithQueue(props) {
19
- return (0, util_1.testStack)({
20
- stackName: 'StackWithQueue',
21
- template: {
22
- Resources: {
23
- MyQueue: {
24
- Type: 'AWS::SQS::Queue',
25
- Properties: props,
26
- },
27
- },
28
- },
29
- });
30
- }
31
- const STACK_WITH_QUEUE = stackWithQueue({});
32
- const STACK_WITH_NAMED_QUEUE = stackWithQueue({
33
- QueueName: 'TheQueueName',
34
- });
35
- function stackWithGlobalTable(props) {
36
- return (0, util_1.testStack)({
37
- stackName: 'StackWithTable',
38
- template: {
39
- Resources: {
40
- MyTable: {
41
- Type: 'AWS::DynamoDB::GlobalTable',
42
- Properties: props,
43
- },
44
- },
45
- },
46
- });
47
- }
48
- function stackWithKeySigningKey(props) {
49
- return (0, util_1.testStack)({
50
- stackName: 'StackWithKSK',
51
- template: {
52
- Resources: {
53
- MyKSK: {
54
- Type: 'AWS::Route53::KeySigningKey',
55
- Properties: props,
56
- },
57
- },
58
- },
59
- });
60
- }
61
- let sdkProvider;
62
- let deployments;
63
- beforeEach(() => {
64
- (0, mock_sdk_1.restoreSdkMocksToDefault)();
65
- jest.resetAllMocks();
66
- sdkProvider = new mock_sdk_1.MockSdkProvider();
67
- deployments = new deployments_1.Deployments({ sdkProvider });
68
- });
69
- test('discovers importable resources', async () => {
70
- givenCurrentStack(STACK_WITH_QUEUE.stackName, {
71
- Resources: {},
72
- });
73
- const importer = new import_1.ResourceImporter(STACK_WITH_QUEUE, deployments);
74
- const { additions } = await importer.discoverImportableResources();
75
- expect(additions).toEqual([
76
- expect.objectContaining({
77
- logicalId: 'MyQueue',
78
- }),
79
- ]);
80
- });
81
- test('by default, its an error if there are non-addition changes in the template', async () => {
82
- givenCurrentStack(STACK_WITH_QUEUE.stackName, {
83
- Resources: {
84
- SomethingThatDisappeared: {
85
- Type: 'AWS::S3::Bucket',
86
- },
87
- },
88
- });
89
- const importer = new import_1.ResourceImporter(STACK_WITH_QUEUE, deployments);
90
- await expect(importer.discoverImportableResources()).rejects.toThrow(/No resource updates or deletes/);
91
- // But the error can be silenced
92
- await expect(importer.discoverImportableResources(true)).resolves.toBeTruthy();
93
- });
94
- test('asks human for resource identifiers', async () => {
95
- // GIVEN
96
- givenCurrentStack(STACK_WITH_QUEUE.stackName, { Resources: {} });
97
- const importer = new import_1.ResourceImporter(STACK_WITH_QUEUE, deployments);
98
- const { additions } = await importer.discoverImportableResources();
99
- // WHEN
100
- promptlyPrompt.mockResolvedValue('TheQueueName');
101
- const importable = await importer.askForResourceIdentifiers(additions);
102
- // THEN
103
- expect(importable.resourceMap).toEqual({
104
- MyQueue: {
105
- QueueName: 'TheQueueName',
106
- },
107
- });
108
- expect(importable.importResources).toEqual([
109
- expect.objectContaining({
110
- logicalId: 'MyQueue',
111
- }),
112
- ]);
113
- });
114
- test('asks human to confirm automic import if identifier is in template', async () => {
115
- // GIVEN
116
- givenCurrentStack(STACK_WITH_NAMED_QUEUE.stackName, { Resources: {} });
117
- const importer = new import_1.ResourceImporter(STACK_WITH_NAMED_QUEUE, deployments);
118
- const { additions } = await importer.discoverImportableResources();
119
- // WHEN
120
- promptlyConfirm.mockResolvedValue(true);
121
- const importable = await importer.askForResourceIdentifiers(additions);
122
- // THEN
123
- expect(importable.resourceMap).toEqual({
124
- MyQueue: {
125
- QueueName: 'TheQueueName',
126
- },
127
- });
128
- expect(importable.importResources).toEqual([
129
- expect.objectContaining({
130
- logicalId: 'MyQueue',
131
- }),
132
- ]);
133
- });
134
- test('asks human to confirm automic import if identifier is in template', async () => {
135
- // GIVEN
136
- givenCurrentStack(STACK_WITH_QUEUE.stackName, { Resources: {} });
137
- const importer = new import_1.ResourceImporter(STACK_WITH_QUEUE, deployments);
138
- const { additions } = await importer.discoverImportableResources();
139
- const importMap = {
140
- importResources: additions,
141
- resourceMap: {
142
- MyQueue: { QueueName: 'TheQueueName' },
143
- },
144
- };
145
- // WHEN
146
- await importer.importResourcesFromMap(importMap, {});
147
- expect(mock_sdk_1.mockCloudFormationClient).toHaveReceivedCommandWith(client_cloudformation_1.CreateChangeSetCommand, {
148
- ChangeSetName: expect.any(String),
149
- StackName: STACK_WITH_QUEUE.stackName,
150
- TemplateBody: expect.any(String),
151
- ChangeSetType: 'IMPORT',
152
- ResourcesToImport: [
153
- {
154
- LogicalResourceId: 'MyQueue',
155
- ResourceIdentifier: { QueueName: 'TheQueueName' },
156
- ResourceType: 'AWS::SQS::Queue',
157
- },
158
- ],
159
- });
160
- });
161
- test('importing resources from migrate strips cdk metadata and outputs', async () => {
162
- // GIVEN
163
- const MyQueue = {
164
- Type: 'AWS::SQS::Queue',
165
- Properties: {},
166
- };
167
- const stack = {
168
- stackName: 'StackWithQueue',
169
- template: {
170
- Resources: {
171
- MyQueue,
172
- CDKMetadata: {
173
- Type: 'AWS::CDK::Metadata',
174
- Properties: {
175
- Analytics: 'exists',
176
- },
177
- },
178
- },
179
- Outputs: {
180
- Output: {
181
- Description: 'There is an output',
182
- Value: 'OutputValue',
183
- },
184
- },
185
- },
186
- };
187
- givenCurrentStack(stack.stackName, stack);
188
- const importer = new import_1.ResourceImporter((0, util_1.testStack)(stack), deployments);
189
- const migrateMap = [
190
- {
191
- LogicalResourceId: 'MyQueue',
192
- ResourceIdentifier: { QueueName: 'TheQueueName' },
193
- ResourceType: 'AWS::SQS::Queue',
194
- },
195
- ];
196
- // WHEN
197
- await importer.importResourcesFromMigrate(migrateMap, STACK_WITH_QUEUE.template);
198
- // THEN
199
- expect(mock_sdk_1.mockCloudFormationClient).toHaveReceivedCommandWith(client_cloudformation_1.CreateChangeSetCommand, {
200
- ChangeSetName: expect.any(String),
201
- StackName: STACK_WITH_QUEUE.stackName,
202
- TemplateBody: expect.any(String),
203
- ChangeSetType: 'IMPORT',
204
- ResourcesToImport: [
205
- {
206
- LogicalResourceId: 'MyQueue',
207
- ResourceIdentifier: { QueueName: 'TheQueueName' },
208
- ResourceType: 'AWS::SQS::Queue',
209
- },
210
- ],
211
- });
212
- });
213
- test('only use one identifier if multiple are in template', async () => {
214
- // GIVEN
215
- const stack = stackWithGlobalTable({
216
- TableName: 'TheTableName',
217
- TableArn: 'ThisFieldDoesntExistInReality',
218
- TableStreamArn: 'NorDoesThisOne',
219
- });
220
- // WHEN
221
- promptlyConfirm.mockResolvedValue(true); // Confirm yes/no
222
- await importTemplateFromClean(stack);
223
- // THEN
224
- expect(mock_sdk_1.mockCloudFormationClient).toHaveReceivedCommandWith(client_cloudformation_1.CreateChangeSetCommand, {
225
- ChangeSetName: expect.any(String),
226
- StackName: stack.stackName,
227
- TemplateBody: expect.any(String),
228
- ChangeSetType: 'IMPORT',
229
- ResourcesToImport: [
230
- {
231
- LogicalResourceId: 'MyTable',
232
- ResourceIdentifier: { TableName: 'TheTableName' },
233
- ResourceType: 'AWS::DynamoDB::GlobalTable',
234
- },
235
- ],
236
- });
237
- });
238
- test('only ask user for one identifier if multiple possible ones are possible', async () => {
239
- // GIVEN -- no identifiers in template, so ask user
240
- const stack = stackWithGlobalTable({});
241
- // WHEN
242
- promptlyPrompt.mockResolvedValue('Banana');
243
- const importable = await importTemplateFromClean(stack);
244
- // THEN -- only asked once
245
- expect(promptlyPrompt).toHaveBeenCalledTimes(1);
246
- expect(importable.resourceMap).toEqual({
247
- MyTable: { TableName: 'Banana' },
248
- });
249
- });
250
- test('ask identifier if the value in the template is a CFN intrinsic', async () => {
251
- // GIVEN -- identifier in template is a CFN intrinsic so it doesn't count
252
- const stack = stackWithQueue({
253
- QueueName: { Ref: 'SomeParam' },
254
- });
255
- // WHEN
256
- promptlyPrompt.mockResolvedValue('Banana');
257
- const importable = await importTemplateFromClean(stack);
258
- // THEN
259
- expect(importable.resourceMap).toEqual({
260
- MyQueue: { QueueName: 'Banana' },
261
- });
262
- });
263
- test('take compound identifiers from the template if found', async () => {
264
- // GIVEN
265
- const stack = stackWithKeySigningKey({
266
- HostedZoneId: 'z-123',
267
- Name: 'KeyName',
268
- });
269
- // WHEN
270
- promptlyConfirm.mockResolvedValue(true);
271
- await importTemplateFromClean(stack);
272
- // THEN
273
- expect(mock_sdk_1.mockCloudFormationClient).toHaveReceivedCommandWith(client_cloudformation_1.CreateChangeSetCommand, {
274
- ChangeSetName: expect.any(String),
275
- StackName: stack.stackName,
276
- TemplateBody: expect.any(String),
277
- ChangeSetType: 'IMPORT',
278
- ResourcesToImport: [
279
- {
280
- LogicalResourceId: 'MyKSK',
281
- ResourceIdentifier: { HostedZoneId: 'z-123', Name: 'KeyName' },
282
- ResourceType: 'AWS::Route53::KeySigningKey',
283
- },
284
- ],
285
- });
286
- });
287
- test('ask user for compound identifiers if not found', async () => {
288
- // GIVEN
289
- const stack = stackWithKeySigningKey({});
290
- // WHEN
291
- promptlyPrompt.mockReturnValue('Banana');
292
- await importTemplateFromClean(stack);
293
- // THEN
294
- expect(mock_sdk_1.mockCloudFormationClient).toHaveReceivedCommandWith(client_cloudformation_1.CreateChangeSetCommand, {
295
- ChangeSetName: expect.any(String),
296
- StackName: stack.stackName,
297
- TemplateBody: expect.any(String),
298
- ChangeSetType: 'IMPORT',
299
- ResourcesToImport: [
300
- {
301
- LogicalResourceId: 'MyKSK',
302
- ResourceIdentifier: { HostedZoneId: 'Banana', Name: 'Banana' },
303
- ResourceType: 'AWS::Route53::KeySigningKey',
304
- },
305
- ],
306
- });
307
- });
308
- test('do not ask for second part of compound identifier if the user skips the first', async () => {
309
- // GIVEN
310
- const stack = stackWithKeySigningKey({});
311
- // WHEN
312
- promptlyPrompt.mockReturnValue('');
313
- const importMap = await importTemplateFromClean(stack);
314
- // THEN
315
- expect(importMap.resourceMap).toEqual({});
316
- });
317
- /**
318
- * Do a full import cycle with the given stack template
319
- */
320
- async function importTemplateFromClean(stack) {
321
- givenCurrentStack(stack.stackName, { Resources: {} });
322
- const importer = new import_1.ResourceImporter(stack, deployments);
323
- const { additions } = await importer.discoverImportableResources();
324
- const importable = await importer.askForResourceIdentifiers(additions);
325
- await importer.importResourcesFromMap(importable, {});
326
- return importable;
327
- }
328
- function givenCurrentStack(stackName, template) {
329
- mock_sdk_1.mockCloudFormationClient.on(client_cloudformation_1.DescribeStacksCommand).resolves({
330
- Stacks: [
331
- {
332
- StackName: stackName,
333
- CreationTime: new Date(),
334
- StackStatus: client_cloudformation_1.StackStatus.UPDATE_COMPLETE,
335
- StackStatusReason: 'It is magic',
336
- Outputs: [],
337
- },
338
- ],
339
- });
340
- mock_sdk_1.mockCloudFormationClient.on(client_cloudformation_1.GetTemplateCommand).resolves({
341
- TemplateBody: JSON.stringify(template),
342
- });
343
- mock_sdk_1.mockCloudFormationClient.on(client_cloudformation_1.GetTemplateSummaryCommand).resolves({
344
- ResourceIdentifierSummaries: [
345
- {
346
- ResourceType: 'AWS::SQS::Queue',
347
- ResourceIdentifiers: ['QueueName'],
348
- },
349
- {
350
- ResourceType: 'AWS::DynamoDB::GlobalTable',
351
- ResourceIdentifiers: ['TableName', 'TableArn', 'TableStreamArn'],
352
- },
353
- {
354
- ResourceType: 'AWS::Route53::KeySigningKey',
355
- ResourceIdentifiers: ['HostedZoneId,Name'],
356
- },
357
- ],
358
- });
359
- mock_sdk_1.mockCloudFormationClient.on(client_cloudformation_1.DescribeChangeSetCommand).resolves({
360
- Status: client_cloudformation_1.StackStatus.CREATE_COMPLETE,
361
- Changes: [],
362
- });
363
- }
364
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbXBvcnQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRTtJQUN6QixPQUFPO1FBQ0wsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQztRQUNqQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNsQixNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtLQUNsQixDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCwwRUFPd0M7QUFDeEMscUNBQXFDO0FBQ3JDLGlDQUFtQztBQUNuQyw4Q0FBc0c7QUFDdEcsd0RBQXFEO0FBQ3JELDBDQUE0RDtBQUU1RCxNQUFNLGVBQWUsR0FBRyxRQUFRLENBQUMsT0FBb0IsQ0FBQztBQUN0RCxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsTUFBbUIsQ0FBQztBQUVwRCxTQUFTLGNBQWMsQ0FBQyxLQUE4QjtJQUNwRCxPQUFPLElBQUEsZ0JBQVMsRUFBQztRQUNmLFNBQVMsRUFBRSxnQkFBZ0I7UUFDM0IsUUFBUSxFQUFFO1lBQ1IsU0FBUyxFQUFFO2dCQUNULE9BQU8sRUFBRTtvQkFDUCxJQUFJLEVBQUUsaUJBQWlCO29CQUN2QixVQUFVLEVBQUUsS0FBSztpQkFDbEI7YUFDRjtTQUNGO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELE1BQU0sZ0JBQWdCLEdBQUcsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBRTVDLE1BQU0sc0JBQXNCLEdBQUcsY0FBYyxDQUFDO0lBQzVDLFNBQVMsRUFBRSxjQUFjO0NBQzFCLENBQUMsQ0FBQztBQUVILFNBQVMsb0JBQW9CLENBQUMsS0FBOEI7SUFDMUQsT0FBTyxJQUFBLGdCQUFTLEVBQUM7UUFDZixTQUFTLEVBQUUsZ0JBQWdCO1FBQzNCLFFBQVEsRUFBRTtZQUNSLFNBQVMsRUFB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QVcsQ0FBQyxlQUFlO2dCQUN4QyxpQkFBaUIsRUFBRSxhQUFhO2dCQUNoQyxPQUFPLEVBQUUsRUFBRTthQUNaO1NBQ0Y7S0FDRixDQUFDLENBQUM7SUFDSCxtQ0FBd0IsQ0FBQyxFQUFFLENBQUMsMENBQWtCLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDdkQsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDO0tBQ3ZDLENBQUMsQ0FBQztJQUNILG1DQUF3QixDQUFDLEVBQUUsQ0FBQyxpREFBeUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUM5RCwyQkFBMkIsRUFBRTtZQUMzQjtnQkFDRSxZQUFZLEVBQUUsaUJBQWlCO2dCQUMvQixtQkFBbUIsRUFBRSxDQUFDLFdBQVcsQ0FBQzthQUNuQztZQUNEO2dCQUNFLFlBQVksRUFBRSw0QkFBNEI7Z0JBQzFDLG1CQUFtQixFQUFFLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQzthQUNqRTtZQUNEO2dCQUNFLFlBQVksRUFBRSw2QkFBNkI7Z0JBQzNDLG1CQUFtQixFQUFFLENBQUMsbUJBQW1CLENBQUM7YUFDM0M7U0FDRjtLQUNGLENBQUMsQ0FBQztJQUVILG1DQUF3QixDQUFDLEVBQUUsQ0FBQyxnREFBd0IsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUM3RCxNQUFNLEVBQUUsbUNBQVcsQ0FBQyxlQUFlO1FBQ25DLE9BQU8sRUFBRSxFQUFFO0tBQ1osQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImplc3QubW9jaygncHJvbXB0bHknLCAoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgLi4uamVzdC5yZXF1aXJlQWN0dWFsKCdwcm9tcHRseScpLFxuICAgIGNvbmZpcm06IGplc3QuZm4oKSxcbiAgICBwcm9tcHQ6IGplc3QuZm4oKSxcbiAgfTtcbn0pO1xuXG5pbXBvcnQge1xuICBDcmVhdGVDaGFuZ2VTZXRDb21tYW5kLFxuICBEZXNjcmliZUNoYW5nZVNldENvbW1hbmQsXG4gIERlc2NyaWJlU3RhY2tzQ29tbWFuZCxcbiAgR2V0VGVtcGxhdGVDb21tYW5kLFxuICBHZXRUZW1wbGF0ZVN1bW1hcnlDb21tYW5kLFxuICBTdGFja1N0YXR1cyxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJztcbmltcG9ydCAqIGFzIHByb21wdGx5IGZyb20gJ3Byb21wdGx5JztcbmltcG9ydCB7IHRlc3RTdGFjayB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyBNb2NrU2RrUHJvdmlkZXIsIG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudCwgcmVzdG9yZVNka01vY2tzVG9EZWZhdWx0IH0gZnJvbSAnLi91dGlsL21vY2stc2RrJztcbmltcG9ydCB7IERlcGxveW1lbnRzIH0gZnJvbSAnLi4vbGliL2FwaS9kZXBsb3ltZW50cyc7XG5pbXBvcnQgeyBSZXNvdXJjZUltcG9ydGVyLCBJbXBvcnRNYXAgfSBmcm9tICcuLi9saWIvaW1wb3J0JztcblxuY29uc3QgcHJvbXB0bHlDb25maXJtID0gcHJvbXB0bHkuY29uZmlybSBhcyBqZXN0Lk1vY2s7XG5jb25zdCBwcm9tcHRseVByb21wdCA9IHByb21wdGx5LnByb21wdCBhcyBqZXN0Lk1vY2s7XG5cbmZ1bmN0aW9uIHN0YWNrV2l0aFF1ZXVlKHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICByZXR1cm4gdGVzdFN0YWNrKHtcbiAgICBzdGFja05hbWU6ICdTdGFja1dpdGhRdWV1ZScsXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgIFJlc291cmNlczoge1xuICAgICAgICBNeVF1ZXVlOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6U1FTOjpRdWV1ZScsXG4gICAgICAgICAgUHJvcGVydGllczogcHJvcHMsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xufVxuXG5jb25zdCBTVEFDS19XSVRIX1FVRVVFID0gc3RhY2tXaXRoUXVldWUoe30pO1xuXG5jb25zdCBTVEFDS19XSVRIX05BTUVEX1FVRVVFID0gc3RhY2tXaXRoUXVldWUoe1xuICBRdWV1ZU5hbWU6ICdUaGVRdWV1ZU5hbWUnLFxufSk7XG5cbmZ1bmN0aW9uIHN0YWNrV2l0aEdsb2JhbFRhYmxlKHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICByZXR1cm4gdGVzdFN0YWNrKHtcbiAgICBzdGFja05hbWU6ICdTdGFja1dpdGhUYWJsZScsXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgIFJlc291cmNlczoge1xuICAgICAgICBNeVRhYmxlOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiBwcm9wcyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHN0YWNrV2l0aEtleVNpZ25pbmdLZXkocHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gIHJldHVybiB0ZXN0U3RhY2soe1xuICAgIHN0YWNrTmFtZTogJ1N0YWNrV2l0aEtTSycsXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgIFJlc291cmNlczoge1xuICAgICAgICBNeUtTSzoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXknLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHByb3BzLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cblxubGV0IHNka1Byb3ZpZGVyOiBNb2NrU2RrUHJvdmlkZXI7XG5sZXQgZGVwbG95bWVudHM6IERlcGxveW1lbnRzO1xuYmVmb3JlRWFjaCgoKSA9PiB7XG4gIHJlc3RvcmVTZGtNb2Nrc1RvRGVmYXVsdCgpO1xuICBqZXN0LnJlc2V0QWxsTW9ja3MoKTtcbiAgc2RrUHJvdmlkZXIgPSBuZXcgTW9ja1Nka1Byb3ZpZGVyKCk7XG4gIGRlcGxveW1lbnRzID0gbmV3IERlcGxveW1lbnRzKHsgc2RrUHJvdmlkZXIgfSk7XG59KTtcblxudGVzdCgnZGlzY292ZXJzIGltcG9ydGFibGUgcmVzb3VyY2VzJywgYXN5bmMgKCkgPT4ge1xuICBnaXZlbkN1cnJlbnRTdGFjayhTVEFDS19XSVRIX1FVRVVFLnN0YWNrTmFtZSwge1xuICAgIFJlc291cmNlczoge30sXG4gIH0pO1xuXG4gIGNvbnN0IGltcG9ydGVyID0gbmV3IFJlc291cmNlSW1wb3J0ZXIoU1RBQ0tfV0lUSF9RVUVVRSwgZGVwbG95bWVudHMpO1xuICBjb25zdCB7IGFkZGl0aW9ucyB9ID0gYXdhaXQgaW1wb3J0ZXIuZGlzY292ZXJJbXBvcnRhYmxlUmVzb3VyY2VzKCk7XG4gIGV4cGVjdChhZGRpdGlvbnMpLnRvRXF1YWwoW1xuICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgIGxvZ2ljYWxJZDogJ015UXVldWUnLFxuICAgIH0pLFxuICBdKTtcbn0pO1xuXG50ZXN0KCdieSBkZWZhdWx0LCBpdHMgYW4gZXJyb3IgaWYgdGhlcmUgYXJlIG5vbi1hZGRpdGlvbiBjaGFuZ2VzIGluIHRoZSB0ZW1wbGF0ZScsIGFzeW5jICgpID0+IHtcbiAgZ2l2ZW5DdXJyZW50U3RhY2soU1RBQ0tfV0lUSF9RVUVVRS5zdGFja05hbWUsIHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIFNvbWV0aGluZ1RoYXREaXNhcHBlYXJlZDoge1xuICAgICAgICBUeXBlOiAnQVdTOjpTMzo6QnVja2V0JyxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgY29uc3QgaW1wb3J0ZXIgPSBuZXcgUmVzb3VyY2VJbXBvcnRlcihTVEFDS19XSVRIX1FVRVVFLCBkZXBsb3ltZW50cyk7XG4gIGF3YWl0IGV4cGVjdChpbXBvcnRlci5kaXNjb3ZlckltcG9ydGFibGVSZXNvdXJjZXMoKSkucmVqZWN0cy50b1Rocm93KC9ObyByZXNvdXJjZSB1cGRhdGVzIG9yIGRlbGV0ZXMvKTtcblxuICAvLyBCdXQgdGhlIGVycm9yIGNhbiBiZSBzaWxlbmNlZFxuICBhd2FpdCBleHBlY3QoaW1wb3J0ZXIuZGlzY292ZXJJbXBvcnRhYmxlUmVzb3VyY2VzKHRydWUpKS5yZXNvbHZlcy50b0JlVHJ1dGh5KCk7XG59KTtcblxudGVzdCgnYXNrcyBodW1hbiBmb3IgcmVzb3VyY2UgaWRlbnRpZmllcnMnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGdpdmVuQ3VycmVudFN0YWNrKFNUQUNLX1dJVEhfUVVFVUUuc3RhY2tOYW1lLCB7IFJlc291cmNlczoge30gfSk7XG4gIGNvbnN0IGltcG9ydGVyID0gbmV3IFJlc291cmNlSW1wb3J0ZXIoU1RBQ0tfV0lUSF9RVUVVRSwgZGVwbG95bWVudHMpO1xuICBjb25zdCB7IGFkZGl0aW9ucyB9ID0gYXdhaXQgaW1wb3J0ZXIuZGlzY292ZXJJbXBvcnRhYmxlUmVzb3VyY2VzKCk7XG5cbiAgLy8gV0hFTlxuICBwcm9tcHRseVByb21wdC5tb2NrUmVzb2x2ZWRWYWx1ZSgnVGhlUXVldWVOYW1lJyk7XG4gIGNvbnN0IGltcG9ydGFibGUgPSBhd2FpdCBpbXBvcnRlci5hc2tGb3JSZXNvdXJjZUlkZW50aWZpZXJzKGFkZGl0aW9ucyk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoaW1wb3J0YWJsZS5yZXNvdXJjZU1hcCkudG9FcXVhbCh7XG4gICAgTXlRdWV1ZToge1xuICAgICAgUXVldWVOYW1lOiAnVGhlUXVldWVOYW1lJyxcbiAgICB9LFxuICB9KTtcbiAgZXhwZWN0KGltcG9ydGFibGUuaW1wb3J0UmVzb3VyY2VzKS50b0VxdWFsKFtcbiAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICBsb2dpY2FsSWQ6ICdNeVF1ZXVlJyxcbiAgICB9KSxcbiAgXSk7XG59KTtcblxudGVzdCgnYXNrcyBodW1hbiB0byBjb25maXJtIGF1dG9taWMgaW1wb3J0IGlmIGlkZW50aWZpZXIgaXMgaW4gdGVtcGxhdGUnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGdpdmVuQ3VycmVudFN0YWNrKFNUQUNLX1dJVEhfTkFNRURfUVVFVUUuc3RhY2tOYW1lLCB7IFJlc291cmNlczoge30gfSk7XG4gIGNvbnN0IGltcG9ydGVyID0gbmV3IFJlc291cmNlSW1wb3J0ZXIoU1RBQ0tfV0lUSF9OQU1FRF9RVUVVRSwgZGVwbG95bWVudHMpO1xuICBjb25zdCB7IGFkZGl0aW9ucyB9ID0gYXdhaXQgaW1wb3J0ZXIuZGlzY292ZXJJbXBvcnRhYmxlUmVzb3VyY2VzKCk7XG5cbiAgLy8gV0hFTlxuICBwcm9tcHRseUNvbmZpcm0ubW9ja1Jlc29sdmVkVmFsdWUodHJ1ZSk7XG4gIGNvbnN0IGltcG9ydGFibGUgPSBhd2FpdCBpbXBvcnRlci5hc2tGb3JSZXNvdXJjZUlkZW50aWZpZXJzKGFkZGl0aW9ucyk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoaW1wb3J0YWJsZS5yZXNvdXJjZU1hcCkudG9FcXVhbCh7XG4gICAgTXlRdWV1ZToge1xuICAgICAgUXVldWVOYW1lOiAnVGhlUXVldWVOYW1lJyxcbiAgICB9LFxuICB9KTtcbiAgZXhwZWN0KGltcG9ydGFibGUuaW1wb3J0UmVzb3VyY2VzKS50b0VxdWFsKFtcbiAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICBsb2dpY2FsSWQ6ICdNeVF1ZXVlJyxcbiAgICB9KSxcbiAgXSk7XG59KTtcblxudGVzdCgnYXNrcyBodW1hbiB0byBjb25maXJtIGF1dG9taWMgaW1wb3J0IGlmIGlkZW50aWZpZXIgaXMgaW4gdGVtcGxhdGUnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGdpdmVuQ3VycmVudFN0YWNrKFNUQUNLX1dJVEhfUVVFVUUuc3RhY2tOYW1lLCB7IFJlc291cmNlczoge30gfSk7XG4gIGNvbnN0IGltcG9ydGVyID0gbmV3IFJlc291cmNlSW1wb3J0ZXIoU1RBQ0tfV0lUSF9RVUVVRSwgZGVwbG95bWVudHMpO1xuICBjb25zdCB7IGFkZGl0aW9ucyB9ID0gYXdhaXQgaW1wb3J0ZXIuZGlzY292ZXJJbXBvcnRhYmxlUmVzb3VyY2VzKCk7XG4gIGNvbnN0IGltcG9ydE1hcDogSW1wb3J0TWFwID0ge1xuICAgIGltcG9ydFJlc291cmNlczogYWRkaXRpb25zLFxuICAgIHJlc291cmNlTWFwOiB7XG4gICAgICBNeVF1ZXVlOiB7IFF1ZXVlTmFtZTogJ1RoZVF1ZXVlTmFtZScgfSxcbiAgICB9LFxuICB9O1xuXG4gIC8vIFdIRU5cbiAgYXdhaXQgaW1wb3J0ZXIuaW1wb3J0UmVzb3VyY2VzRnJvbU1hcChpbXBvcnRNYXAsIHt9KTtcblxuICBleHBlY3QobW9ja0Nsb3VkRm9ybWF0aW9uQ2xpZW50KS50b0hhdmVSZWNlaXZlZENvbW1hbmRXaXRoKENyZWF0ZUNoYW5nZVNldENvbW1hbmQsIHtcbiAgICBDaGFuZ2VTZXROYW1lOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgU3RhY2tOYW1lOiBTVEFDS19XSVRIX1FVRVVFLnN0YWNrTmFtZSxcbiAgICBUZW1wbGF0ZUJvZHk6IGV4cGVjdC5hbnkoU3RyaW5nKSxcbiAgICBDaGFuZ2VTZXRUeXBlOiAnSU1QT1JUJyxcbiAgICBSZXNvdXJjZXNUb0ltcG9ydDogW1xuICAgICAge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ015UXVldWUnLFxuICAgICAgICBSZXNvdXJjZUlkZW50aWZpZXI6IHsgUXVldWVOYW1lOiAnVGhlUXVldWVOYW1lJyB9LFxuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OlNRUzo6UXVldWUnLFxuICAgICAgfSxcbiAgICBdLFxuICB9KTtcbn0pO1xuXG50ZXN0KCdpbXBvcnRpbmcgcmVzb3VyY2VzIGZyb20gbWlncmF0ZSBzdHJpcHMgY2RrIG1ldGFkYXRhIGFuZCBvdXRwdXRzJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuXG4gIGNvbnN0IE15UXVldWUgPSB7XG4gICAgVHlwZTogJ0FXUzo6U1FTOjpRdWV1ZScsXG4gICAgUHJvcGVydGllczoge30sXG4gIH07XG4gIGNvbnN0IHN0YWNrID0ge1xuICAgIHN0YWNrTmFtZTogJ1N0YWNrV2l0aFF1ZXVlJyxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIE15UXVldWUsXG4gICAgICAgIENES01ldGFkYXRhOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6Q0RLOjpNZXRhZGF0YScsXG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgQW5hbHl0aWNzOiAnZXhpc3RzJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIE91dHB1dHM6IHtcbiAgICAgICAgT3V0cHV0OiB7XG4gICAgICAgICAgRGVzY3JpcHRpb246ICdUaGVyZSBpcyBhbiBvdXRwdXQnLFxuICAgICAgICAgIFZhbHVlOiAnT3V0cHV0VmFsdWUnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xuXG4gIGdpdmVuQ3VycmVudFN0YWNrKHN0YWNrLnN0YWNrTmFtZSwgc3RhY2spO1xuICBjb25zdCBpbXBvcnRlciA9IG5ldyBSZXNvdXJjZUltcG9ydGVyKHRlc3RTdGFjayhzdGFjayksIGRlcGxveW1lbnRzKTtcbiAgY29uc3QgbWlncmF0ZU1hcCA9IFtcbiAgICB7XG4gICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ015UXVldWUnLFxuICAgICAgUmVzb3VyY2VJZGVudGlmaWVyOiB7IFF1ZXVlTmFtZTogJ1RoZVF1ZXVlTmFtZScgfSxcbiAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6U1FTOjpRdWV1ZScsXG4gICAgfSxcbiAgXTtcblxuICAvLyBXSEVOXG4gIGF3YWl0IGltcG9ydGVyLmltcG9ydFJlc291cmNlc0Zyb21NaWdyYXRlKG1pZ3JhdGVNYXAsIFNUQUNLX1dJVEhfUVVFVUUudGVtcGxhdGUpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudCkudG9IYXZlUmVjZWl2ZWRDb21tYW5kV2l0aChDcmVhdGVDaGFuZ2VTZXRDb21tYW5kLCB7XG4gICAgQ2hhbmdlU2V0TmFtZTogZXhwZWN0LmFueShTdHJpbmcpLFxuICAgIFN0YWNrTmFtZTogU1RBQ0tfV0lUSF9RVUVVRS5zdGFja05hbWUsXG4gICAgVGVtcGxhdGVCb2R5OiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgQ2hhbmdlU2V0VHlwZTogJ0lNUE9SVCcsXG4gICAgUmVzb3VyY2VzVG9JbXBvcnQ6IFtcbiAgICAgIHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdNeVF1ZXVlJyxcbiAgICAgICAgUmVzb3VyY2VJZGVudGlmaWVyOiB7IFF1ZXVlTmFtZTogJ1RoZVF1ZXVlTmFtZScgfSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpTUVM6OlF1ZXVlJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG59KTtcblxudGVzdCgnb25seSB1c2Ugb25lIGlkZW50aWZpZXIgaWYgbXVsdGlwbGUgYXJlIGluIHRlbXBsYXRlJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aEdsb2JhbFRhYmxlKHtcbiAgICBUYWJsZU5hbWU6ICdUaGVUYWJsZU5hbWUnLFxuICAgIFRhYmxlQXJuOiAnVGhpc0ZpZWxkRG9lc250RXhpc3RJblJlYWxpdHknLFxuICAgIFRhYmxlU3RyZWFtQXJuOiAnTm9yRG9lc1RoaXNPbmUnLFxuICB9KTtcblxuICAvLyBXSEVOXG4gIHByb21wdGx5Q29uZmlybS5tb2NrUmVzb2x2ZWRWYWx1ZSh0cnVlKTsgLy8gQ29uZmlybSB5ZXMvbm9cbiAgYXdhaXQgaW1wb3J0VGVtcGxhdGVGcm9tQ2xlYW4oc3RhY2spO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudCkudG9IYXZlUmVjZWl2ZWRDb21tYW5kV2l0aChDcmVhdGVDaGFuZ2VTZXRDb21tYW5kLCB7XG4gICAgQ2hhbmdlU2V0TmFtZTogZXhwZWN0LmFueShTdHJpbmcpLFxuICAgIFN0YWNrTmFtZTogc3RhY2suc3RhY2tOYW1lLFxuICAgIFRlbXBsYXRlQm9keTogZXhwZWN0LmFueShTdHJpbmcpLFxuICAgIENoYW5nZVNldFR5cGU6ICdJTVBPUlQnLFxuICAgIFJlc291cmNlc1RvSW1wb3J0OiBbXG4gICAgICB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnTXlUYWJsZScsXG4gICAgICAgIFJlc291cmNlSWRlbnRpZmllcjogeyBUYWJsZU5hbWU6ICdUaGVUYWJsZU5hbWUnIH0sXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG59KTtcblxudGVzdCgnb25seSBhc2sgdXNlciBmb3Igb25lIGlkZW50aWZpZXIgaWYgbXVsdGlwbGUgcG9zc2libGUgb25lcyBhcmUgcG9zc2libGUnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOIC0tIG5vIGlkZW50aWZpZXJzIGluIHRlbXBsYXRlLCBzbyBhc2sgdXNlclxuICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aEdsb2JhbFRhYmxlKHt9KTtcblxuICAvLyBXSEVOXG4gIHByb21wdGx5UHJvbXB0Lm1vY2tSZXNvbHZlZFZhbHVlKCdCYW5hbmEnKTtcbiAgY29uc3QgaW1wb3J0YWJsZSA9IGF3YWl0IGltcG9ydFRlbXBsYXRlRnJvbUNsZWFuKHN0YWNrKTtcblxuICAvLyBUSEVOIC0tIG9ubHkgYXNrZWQgb25jZVxuICBleHBlY3QocHJvbXB0bHlQcm9tcHQpLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygxKTtcbiAgZXhwZWN0KGltcG9ydGFibGUucmVzb3VyY2VNYXApLnRvRXF1YWwoe1xuICAgIE15VGFibGU6IHsgVGFibGVOYW1lOiAnQmFuYW5hJyB9LFxuICB9KTtcbn0pO1xuXG50ZXN0KCdhc2sgaWRlbnRpZmllciBpZiB0aGUgdmFsdWUgaW4gdGhlIHRlbXBsYXRlIGlzIGEgQ0ZOIGludHJpbnNpYycsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU4gLS0gaWRlbnRpZmllciBpbiB0ZW1wbGF0ZSBpcyBhIENGTiBpbnRyaW5zaWMgc28gaXQgZG9lc24ndCBjb3VudFxuICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aFF1ZXVlKHtcbiAgICBRdWV1ZU5hbWU6IHsgUmVmOiAnU29tZVBhcmFtJyB9LFxuICB9KTtcblxuICAvLyBXSEVOXG4gIHByb21wdGx5UHJvbXB0Lm1vY2tSZXNvbHZlZFZhbHVlKCdCYW5hbmEnKTtcbiAgY29uc3QgaW1wb3J0YWJsZSA9IGF3YWl0IGltcG9ydFRlbXBsYXRlRnJvbUNsZWFuKHN0YWNrKTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChpbXBvcnRhYmxlLnJlc291cmNlTWFwKS50b0VxdWFsKHtcbiAgICBNeVF1ZXVlOiB7IFF1ZXVlTmFtZTogJ0JhbmFuYScgfSxcbiAgfSk7XG59KTtcblxudGVzdCgndGFrZSBjb21wb3VuZCBpZGVudGlmaWVycyBmcm9tIHRoZSB0ZW1wbGF0ZSBpZiBmb3VuZCcsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3Qgc3RhY2sgPSBzdGFja1dpdGhLZXlTaWduaW5nS2V5KHtcbiAgICBIb3N0ZWRab25lSWQ6ICd6LTEyMycsXG4gICAgTmFtZTogJ0tleU5hbWUnLFxuICB9KTtcblxuICAvLyBXSEVOXG4gIHByb21wdGx5Q29uZmlybS5tb2NrUmVzb2x2ZWRWYWx1ZSh0cnVlKTtcbiAgYXdhaXQgaW1wb3J0VGVtcGxhdGVGcm9tQ2xlYW4oc3RhY2spO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudCkudG9IYXZlUmVjZWl2ZWRDb21tYW5kV2l0aChDcmVhdGVDaGFuZ2VTZXRDb21tYW5kLCB7XG4gICAgQ2hhbmdlU2V0TmFtZTogZXhwZWN0LmFueShTdHJpbmcpLFxuICAgIFN0YWNrTmFtZTogc3RhY2suc3RhY2tOYW1lLFxuICAgIFRlbXBsYXRlQm9keTogZXhwZWN0LmFueShTdHJpbmcpLFxuICAgIENoYW5nZVNldFR5cGU6ICdJTVBPUlQnLFxuICAgIFJlc291cmNlc1RvSW1wb3J0OiBbXG4gICAgICB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnTXlLU0snLFxuICAgICAgICBSZXNvdXJjZUlkZW50aWZpZXI6IHsgSG9zdGVkWm9uZUlkOiAnei0xMjMnLCBOYW1lOiAnS2V5TmFtZScgfSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpSb3V0ZTUzOjpLZXlTaWduaW5nS2V5JyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG59KTtcblxudGVzdCgnYXNrIHVzZXIgZm9yIGNvbXBvdW5kIGlkZW50aWZpZXJzIGlmIG5vdCBmb3VuZCcsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3Qgc3RhY2sgPSBzdGFja1dpdGhLZXlTaWduaW5nS2V5KHt9KTtcblxuICAvLyBXSEVOXG4gIHByb21wdGx5UHJvbXB0Lm1vY2tSZXR1cm5WYWx1ZSgnQmFuYW5hJyk7XG4gIGF3YWl0IGltcG9ydFRlbXBsYXRlRnJvbUNsZWFuKHN0YWNrKTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChtb2NrQ2xvdWRGb3JtYXRpb25DbGllbnQpLnRvSGF2ZVJlY2VpdmVkQ29tbWFuZFdpdGgoQ3JlYXRlQ2hhbmdlU2V0Q29tbWFuZCwge1xuICAgIENoYW5nZVNldE5hbWU6IGV4cGVjdC5hbnkoU3RyaW5nKSxcbiAgICBTdGFja05hbWU6IHN0YWNrLnN0YWNrTmFtZSxcbiAgICBUZW1wbGF0ZUJvZHk6IGV4cGVjdC5hbnkoU3RyaW5nKSxcbiAgICBDaGFuZ2VTZXRUeXBlOiAnSU1QT1JUJyxcbiAgICBSZXNvdXJjZXNUb0ltcG9ydDogW1xuICAgICAge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ015S1NLJyxcbiAgICAgICAgUmVzb3VyY2VJZGVudGlmaWVyOiB7IEhvc3RlZFpvbmVJZDogJ0JhbmFuYScsIE5hbWU6ICdCYW5hbmEnIH0sXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Um91dGU1Mzo6S2V5U2lnbmluZ0tleScsXG4gICAgICB9LFxuICAgIF0sXG4gIH0pO1xufSk7XG5cbnRlc3QoJ2RvIG5vdCBhc2sgZm9yIHNlY29uZCBwYXJ0IG9mIGNvbXBvdW5kIGlkZW50aWZpZXIgaWYgdGhlIHVzZXIgc2tpcHMgdGhlIGZpcnN0JywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aEtleVNpZ25pbmdLZXkoe30pO1xuXG4gIC8vIFdIRU5cbiAgcHJvbXB0bHlQcm9tcHQubW9ja1JldHVyblZhbHVlKCcnKTtcbiAgY29uc3QgaW1wb3J0TWFwID0gYXdhaXQgaW1wb3J0VGVtcGxhdGVGcm9tQ2xlYW4oc3RhY2spO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGltcG9ydE1hcC5yZXNvdXJjZU1hcCkudG9FcXVhbCh7fSk7XG59KTtcblxuLyoqXG4gKiBEbyBhIGZ1bGwgaW1wb3J0IGN5Y2xlIHdpdGggdGhlIGdpdmVuIHN0YWNrIHRlbXBsYXRlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGltcG9ydFRlbXBsYXRlRnJvbUNsZWFuKHN0YWNrOiBSZXR1cm5UeXBlPHR5cGVvZiB0ZXN0U3RhY2s+KSB7XG4gIGdpdmVuQ3VycmVudFN0YWNrKHN0YWNrLnN0YWNrTmFtZSwgeyBSZXNvdXJjZXM6IHt9IH0pO1xuICBjb25zdCBpbXBvcnRlciA9IG5ldyBSZXNvdXJjZUltcG9ydGVyKHN0YWNrLCBkZXBsb3ltZW50cyk7XG4gIGNvbnN0IHsgYWRkaXRpb25zIH0gPSBhd2FpdCBpbXBvcnRlci5kaXNjb3ZlckltcG9ydGFibGVSZXNvdXJjZXMoKTtcbiAgY29uc3QgaW1wb3J0YWJsZSA9IGF3YWl0IGltcG9ydGVyLmFza0ZvclJlc291cmNlSWRlbnRpZmllcnMoYWRkaXRpb25zKTtcbiAgYXdhaXQgaW1wb3J0ZXIuaW1wb3J0UmVzb3VyY2VzRnJvbU1hcChpbXBvcnRhYmxlLCB7fSk7XG4gIHJldHVybiBpbXBvcnRhYmxlO1xufVxuXG5mdW5jdGlvbiBnaXZlbkN1cnJlbnRTdGFjayhzdGFja05hbWU6IHN0cmluZywgdGVtcGxhdGU6IGFueSkge1xuICBtb2NrQ2xvdWRGb3JtYXRpb25DbGllbnQub24oRGVzY3JpYmVTdGFja3NDb21tYW5kKS5yZXNvbHZlcyh7XG4gICAgU3RhY2tzOiBbXG4gICAgICB7XG4gICAgICAgIFN0YWNrTmFtZTogc3RhY2tOYW1lLFxuICAgICAgICBDcmVhdGlvblRpbWU6IG5ldyBEYXRlKCksXG4gICAgICAgIFN0YWNrU3RhdHVzOiBTdGFja1N0YXR1cy5VUERBVEVfQ09NUExFVEUsXG4gICAgICAgIFN0YWNrU3RhdHVzUmVhc29uOiAnSXQgaXMgbWFnaWMnLFxuICAgICAgICBPdXRwdXRzOiBbXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG4gIG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudC5vbihHZXRUZW1wbGF0ZUNvbW1hbmQpLnJlc29sdmVzKHtcbiAgICBUZW1wbGF0ZUJvZHk6IEpTT04uc3RyaW5naWZ5KHRlbXBsYXRlKSxcbiAgfSk7XG4gIG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudC5vbihHZXRUZW1wbGF0ZVN1bW1hcnlDb21tYW5kKS5yZXNvbHZlcyh7XG4gICAgUmVzb3VyY2VJZGVudGlmaWVyU3VtbWFyaWVzOiBbXG4gICAgICB7XG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6U1FTOjpRdWV1ZScsXG4gICAgICAgIFJlc291cmNlSWRlbnRpZmllcnM6IFsnUXVldWVOYW1lJ10sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OkR5bmFtb0RCOjpHbG9iYWxUYWJsZScsXG4gICAgICAgIFJlc291cmNlSWRlbnRpZmllcnM6IFsnVGFibGVOYW1lJywgJ1RhYmxlQXJuJywgJ1RhYmxlU3RyZWFtQXJuJ10sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXknLFxuICAgICAgICBSZXNvdXJjZUlkZW50aWZpZXJzOiBbJ0hvc3RlZFpvbmVJZCxOYW1lJ10sXG4gICAgICB9LFxuICAgIF0sXG4gIH0pO1xuXG4gIG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudC5vbihEZXNjcmliZUNoYW5nZVNldENvbW1hbmQpLnJlc29sdmVzKHtcbiAgICBTdGF0dXM6IFN0YWNrU3RhdHVzLkNSRUFURV9DT01QTEVURSxcbiAgICBDaGFuZ2VzOiBbXSxcbiAgfSk7XG59XG4iXX0=