aws-cdk 2.10.0 → 2.11.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/CONTRIBUTING.md +1 -1
- package/build-info.json +2 -2
- package/lib/api/cloudformation-deployments.d.ts +8 -1
- package/lib/api/cloudformation-deployments.js +86 -16
- package/lib/api/hotswap-deployments.js +1 -1
- package/lib/assets.js +2 -1
- package/lib/cdk-toolkit.js +3 -3
- package/lib/context-providers/index.d.ts +6 -0
- package/lib/context-providers/index.js +16 -3
- package/lib/context-providers/vpcs.js +4 -1
- package/lib/plugin.d.ts +15 -1
- package/lib/plugin.js +17 -3
- package/npm-shrinkwrap.json +20 -20
- package/package.json +11 -11
- package/test/api/cloudformation-deployments.test.js +643 -1
- package/test/context-providers/generic.test.js +7 -6
- package/test/context-providers/vpcs.test.js +132 -1
- package/test/diff-nested-stacks-templates/one-output-one-param-stack.nested.template.json +20 -0
- package/test/diff-nested-stacks-templates/one-resource-one-stack-stack.nested.template.json +19 -0
- package/test/diff-nested-stacks-templates/one-resource-stack.nested.template.json +10 -0
- package/test/diff-nested-stacks-templates/one-resource-two-stacks-stack.nested.template.json +28 -0
- package/test/diff.test.js +215 -96
- package/test/util.js +18 -1
|
@@ -4,15 +4,33 @@ jest.mock('../../lib/api/deploy-stack');
|
|
|
4
4
|
const cloudformation_deployments_1 = require("../../lib/api/cloudformation-deployments");
|
|
5
5
|
const deploy_stack_1 = require("../../lib/api/deploy-stack");
|
|
6
6
|
const toolkit_info_1 = require("../../lib/api/toolkit-info");
|
|
7
|
+
const cloudformation_1 = require("../../lib/api/util/cloudformation");
|
|
7
8
|
const util_1 = require("../util");
|
|
8
9
|
const mock_sdk_1 = require("../util/mock-sdk");
|
|
10
|
+
const fake_cloudformation_stack_1 = require("./fake-cloudformation-stack");
|
|
9
11
|
let sdkProvider;
|
|
10
12
|
let deployments;
|
|
11
13
|
let mockToolkitInfoLookup;
|
|
14
|
+
let currentCfnStackResources;
|
|
15
|
+
let numberOfTimesListStackResourcesWasCalled;
|
|
12
16
|
beforeEach(() => {
|
|
13
17
|
jest.resetAllMocks();
|
|
14
18
|
sdkProvider = new mock_sdk_1.MockSdkProvider();
|
|
15
19
|
deployments = new cloudformation_deployments_1.CloudFormationDeployments({ sdkProvider });
|
|
20
|
+
numberOfTimesListStackResourcesWasCalled = 0;
|
|
21
|
+
currentCfnStackResources = {};
|
|
22
|
+
sdkProvider.stubCloudFormation({
|
|
23
|
+
listStackResources: ({ StackName: stackName }) => {
|
|
24
|
+
numberOfTimesListStackResourcesWasCalled++;
|
|
25
|
+
const stackResources = currentCfnStackResources[stackName];
|
|
26
|
+
if (!stackResources) {
|
|
27
|
+
throw new Error(`Stack with id ${stackName} does not exist`);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
StackResourceSummaries: stackResources,
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
});
|
|
16
34
|
toolkit_info_1.ToolkitInfo.lookup = mockToolkitInfoLookup = jest.fn().mockResolvedValue(toolkit_info_1.ToolkitInfo.bootstrapStackNotFoundInfo(sdkProvider.sdk));
|
|
17
35
|
});
|
|
18
36
|
function mockSuccessfulBootstrapStackLookup(props) {
|
|
@@ -125,4 +143,628 @@ test('if toolkit stack cannot be found but SSM parameter name is present deploym
|
|
|
125
143
|
});
|
|
126
144
|
expect(requestedParameterName).toEqual('/some/parameter');
|
|
127
145
|
});
|
|
128
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRmb3JtYXRpb24tZGVwbG95bWVudHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsb3VkZm9ybWF0aW9uLWRlcGxveW1lbnRzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUM7QUFFeEMseUZBQXFGO0FBQ3JGLDZEQUF5RDtBQUN6RCw2REFBeUQ7QUFDekQsa0NBQW9DO0FBQ3BDLCtDQUF1RTtBQUV2RSxJQUFJLFdBQTRCLENBQUM7QUFDakMsSUFBSSxXQUFzQyxDQUFDO0FBQzNDLElBQUkscUJBQWdDLENBQUM7QUFDckMsVUFBVSxDQUFDLEdBQUcsRUFBRTtJQUNkLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUNyQixXQUFXLEdBQUcsSUFBSSwwQkFBZSxFQUFFLENBQUM7SUFDcEMsV0FBVyxHQUFHLElBQUksc0RBQXlCLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzdELDBCQUFXLENBQUMsTUFBTSxHQUFHLHFCQUFxQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQywwQkFBVyxDQUFDLDBCQUEwQixDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3BJLENBQUMsQ0FBQyxDQUFDO0FBRUgsU0FBUyxrQ0FBa0MsQ0FBQyxLQUEyQjtJQUNyRSxNQUFNLE9BQU8sR0FBRztRQUNkLFVBQVUsRUFBRSxhQUFhO1FBQ3pCLGdCQUFnQixFQUFFLGlCQUFpQjtRQUNuQyxnQkFBZ0IsRUFBRSxHQUFHO1FBQ3JCLEdBQUcsS0FBSztLQUNULENBQUM7SUFFRixNQUFNLFNBQVMsR0FBRyw2QkFBa0IsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFO1FBQ3BELE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENB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QVcsQ0FBQyxXQUFXLENBQUM7UUFDbkMsS0FBSyxFQUFFLGdCQUFTLENBQUM7WUFDZixTQUFTLEVBQUUsTUFBTTtZQUNqQixVQUFVLEVBQUU7Z0JBQ1YsYUFBYSxFQUFFLHdDQUF3QztnQkFDdkQsNkJBQTZCLEVBQUUsRUFBRTthQUNsQztTQUNGLENBQUM7S0FDSCxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7QUFDMUUsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsd0ZBQXdGLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDeEcsbUZBQW1GO0lBQ25GLDREQUE0RDtJQUM1RCxrQ0FBa0MsQ0FBQztRQUNqQyxnQkFBZ0IsRUFBRSxDQUFDO0tBQ3BCLENBQUMsQ0FBQztJQUVILElBQUksc0JBQThCLENBQUM7SUFDbkMsV0FBVyxDQUFDLE9BQU8sQ0FBQztRQUNsQixZQUFZLENBQUMsT0FBTztZQUNsQixzQkFBc0IsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQ3RDLE9BQU87Z0JBQ0wsU0FBUyxFQUFFO29CQUNULEtBQUssRUFBRSxJQUFJO2lCQUNaO2FBQ0YsQ0FBQztRQUNKLENBQUM7S0FDRixDQUFDLENBQUM7SUFFSCxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUM7UUFDNUIsS0FBSyxFQUFFLGdCQUFTLENBQUM7WUFDZixTQUFTLEVBQUUsTUFBTTtZQUNqQixVQUFVLEVBQUU7Z0JBQ1YsYUFBYSxFQUFFLHdDQUF3QztnQkFDdkQsNkJBQTZCLEVBQUUsRUFBRTtnQkFDakMsaUNBQWlDLEVBQUUsaUJBQWlCO2FBQ3JEO1NBQ0YsQ0FBQztLQUNILENBQUMsQ0FBQztJQUVILE1BQU0sQ0FBQyxzQkFBdUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBQzdELENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiamVzdC5tb2NrKCcuLi8uLi9saWIvYXBpL2RlcGxveS1zdGFjaycpO1xuXG5pbXBvcnQgeyBDbG91ZEZvcm1hdGlvbkRlcGxveW1lbnRzIH0gZnJvbSAnLi4vLi4vbGliL2FwaS9jbG91ZGZvcm1hdGlvbi1kZXBsb3ltZW50cyc7XG5pbXBvcnQgeyBkZXBsb3lTdGFjayB9IGZyb20gJy4uLy4uL2xpYi9hcGkvZGVwbG95LXN0YWNrJztcbmltcG9ydCB7IFRvb2xraXRJbmZvIH0gZnJvbSAnLi4vLi4vbGliL2FwaS90b29sa2l0LWluZm8nO1xuaW1wb3J0IHsgdGVzdFN0YWNrIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgeyBtb2NrQm9vdHN0cmFwU3RhY2ssIE1vY2tTZGtQcm92aWRlciB9IGZyb20gJy4uL3V0aWwvbW9jay1zZGsnO1xuXG5sZXQgc2RrUHJvdmlkZXI6IE1vY2tTZGtQcm92aWRlcjtcbmxldCBkZXBsb3ltZW50czogQ2xvdWRGb3JtYXRpb25EZXBsb3ltZW50cztcbmxldCBtb2NrVG9vbGtpdEluZm9Mb29rdXA6IGplc3QuTW9jaztcbmJlZm9yZUVhY2goKCkgPT4ge1xuICBqZXN0LnJlc2V0QWxsTW9ja3MoKTtcbiAgc2RrUHJvdmlkZXIgPSBuZXcgTW9ja1Nka1Byb3ZpZGVyKCk7XG4gIGRlcGxveW1lbnRzID0gbmV3IENsb3VkRm9ybWF0aW9uRGVwbG95bWVudHMoeyBzZGtQcm92aWRlciB9KTtcbiAgVG9vbGtpdEluZm8ubG9va3VwID0gbW9ja1Rvb2xraXRJbmZvTG9va3VwID0gamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFRvb2xraXRJbmZvLmJvb3RzdHJhcFN0YWNrTm90Rm91bmRJbmZvKHNka1Byb3ZpZGVyLnNkaykpO1xufSk7XG5cbmZ1bmN0aW9uIG1vY2tTdWNjZXNzZnVsQm9vdHN0cmFwU3RhY2tMb29rdXAocHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gIGNvbnN0IG91dHB1dHMgPSB7XG4gICAgQnVja2V0TmFtZTogJ0JVQ0tFVF9OQU1FJyxcbiAgICBCdWNrZXREb21haW5OYW1lOiAnQlVDS0VUX0VORFBPSU5UJyxcbiAgICBCb290c3RyYXBWZXJzaW9uOiAnMScsXG4gICAgLi4ucHJvcHMsXG4gIH07XG5cbiAgY29uc3QgZmFrZVN0YWNrID0gbW9ja0Jvb3RzdHJhcFN0YWNrKHNka1Byb3ZpZGVyLnNkaywge1xuICAgIE91dHB1dHM6IE9iamVjdC5lbnRyaWVzKG91dHB1dHMpLm1hcCgoW2ssIHZdKSA9PiAoe1xuICAgICAgT3V0cHV0S2V5OiBrLFxuICAgICAgT3V0cHV0VmFsdWU6IGAke3Z9YCxcbiAgICB9KSksXG4gIH0pO1xuXG4gIG1vY2tUb29sa2l0SW5mb0xvb2t1cC5tb2NrUmVzb2x2ZWRWYWx1ZShUb29sa2l0SW5mby5mcm9tU3RhY2soZmFrZVN0YWNrLCBzZGtQcm92aWRlci5zZGspKTtcbn1cblxudGVzdCgncGFzc2VzIHRocm91Z2ggaG90c3dhcD10cnVlIHRvIGRlcGxveVN0YWNrKCknLCBhc3luYyAoKSA9PiB7XG4gIC8vIFdIRU5cbiAgYXdhaXQgZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgIHN0YWNrOiB0ZXN0U3RhY2soe1xuICAgICAgc3RhY2tOYW1lOiAnYm9vcCcsXG4gICAgfSksXG4gICAgaG90c3dhcDogdHJ1ZSxcbiAgfSk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoZGVwbG95U3RhY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICBob3Rzd2FwOiB0cnVlLFxuICB9KSk7XG59KTtcblxudGVzdCgncGxhY2Vob2xkZXJzIGFyZSBzdWJzdGl0dXRlZCBpbiBDbG91ZEZvcm1hdGlvbiBleGVjdXRpb24gcm9sZScsIGFzeW5jICgpID0+IHtcbiAgYXdhaXQgZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgIHN0YWNrOiB0ZXN0U3RhY2soe1xuICAgICAgc3RhY2tOYW1lOiAnYm9vcCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGNsb3VkRm9ybWF0aW9uRXhlY3V0aW9uUm9sZUFybjogJ2Jsb29wOiR7QVdTOjpSZWdpb259OiR7QVdTOjpBY2NvdW50SWR9JyxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuXG4gIGV4cGVjdChkZXBsb3lTdGFjaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgIHJvbGVBcm46ICdibG9vcDpoZXJlOjEyMzQ1Njc4OTAxMicsXG4gIH0pKTtcbn0pO1xuXG50ZXN0KCdyb2xlIHdpdGggcGxhY2Vob2xkZXJzIGlzIGFzc3VtZWQgaWYgYXNzdW1lcm9sZSBpcyBnaXZlbicsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgbW9ja0ZvckVudmlyb25tZW50ID0gamVzdC5mbigpLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiB7IHJldHVybiB7IHNkazogc2RrUHJvdmlkZXIuc2RrIH07IH0pO1xuICBzZGtQcm92aWRlci5mb3JFbnZpcm9ubWVudCA9IG1vY2tGb3JFbnZpcm9ubWVudDtcblxuICBhd2FpdCBkZXBsb3ltZW50cy5kZXBsb3lTdGFjayh7XG4gICAgc3RhY2s6IHRlc3RTdGFjayh7XG4gICAgICBzdGFja05hbWU6ICdib29wJyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYXNzdW1lUm9sZUFybjogJ2Jsb29wOiR7QVdTOjpSZWdpb259OiR7QVdTOjpBY2NvdW50SWR9JyxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuXG4gIGV4cGVjdChtb2NrRm9yRW52aXJvbm1lbnQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5hbnl0aGluZygpLCBleHBlY3QuYW55dGhpbmcoKSwgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgIGFzc3VtZVJvbGVBcm46ICdibG9vcDpoZXJlOjEyMzQ1Njc4OTAxMicsXG4gIH0pKTtcbn0pO1xuXG50ZXN0KCdkZXBsb3ltZW50IGZhaWxzIGlmIGJvb3RzdHJhcCBzdGFjayBpcyBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICBhd2FpdCBleHBlY3QoZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgIHN0YWNrOiB0ZXN0U3RhY2soe1xuICAgICAgc3RhY2tOYW1lOiAnYm9vcCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFzc3VtZVJvbGVBcm46ICdibG9vcDoke0FXUzo6UmVnaW9ufToke0FXUzo6QWNjb3VudElkfScsXG4gICAgICAgIHJlcXVpcmVzQm9vdHN0cmFwU3RhY2tWZXJzaW9uOiA5OSxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pKS5yZWplY3RzLnRvVGhyb3coL3JlcXVpcmVzIGEgYm9vdHN0cmFwIHN0YWNrLyk7XG59KTtcblxudGVzdCgnZGVwbG95bWVudCBmYWlscyBpZiBib290c3RyYXAgc3RhY2sgaXMgdG9vIG9sZCcsIGFzeW5jICgpID0+IHtcbiAgbW9ja1N1Y2Nlc3NmdWxCb290c3RyYXBTdGFja0xvb2t1cCh7XG4gICAgQm9vdHN0cmFwVmVyc2lvbjogNSxcbiAgfSk7XG5cbiAgYXdhaXQgZXhwZWN0KGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICBzdGFjazogdGVzdFN0YWNrKHtcbiAgICAgIHN0YWNrTmFtZTogJ2Jvb3AnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhc3N1bWVSb2xlQXJuOiAnYmxvb3A6JHtBV1M6OlJlZ2lvbn06JHtBV1M6OkFjY291bnRJZH0nLFxuICAgICAgICByZXF1aXJlc0Jvb3RzdHJhcFN0YWNrVmVyc2lvbjogOTksXG4gICAgICB9LFxuICAgIH0pLFxuICB9KSkucmVqZWN0cy50b1Rocm93KC9yZXF1aXJlcyBib290c3RyYXAgc3RhY2sgdmVyc2lvbiAnOTknLCBmb3VuZCAnNScvKTtcbn0pO1xuXG50ZXN0KCdpZiB0b29sa2l0IHN0YWNrIGNhbm5vdCBiZSBmb3VuZCBidXQgU1NNIHBhcmFtZXRlciBuYW1lIGlzIHByZXNlbnQgZGVwbG95bWVudCBzdWNjZWVkcycsIGFzeW5jICgpID0+IHtcbiAgLy8gRklYTUU6IE1vY2tpbmcgYSBzdWNjZXNzZnVsIGJvb3RzdHJhcCBzdGFjayBsb29rdXAgaGVyZSBzaG91bGQgbm90IGJlIG5lY2Vzc2FyeS5cbiAgLy8gVGhpcyBzaG91bGQgZmFpbCBhbmQgcmV0dXJuIGEgcGxhY2Vob2xkZXIgZmFpbHVyZSBvYmplY3QuXG4gIG1vY2tTdWNjZXNzZnVsQm9vdHN0cmFwU3RhY2tMb29rdXAoe1xuICAgIEJvb3RzdHJhcFZlcnNpb246IDIsXG4gIH0pO1xuXG4gIGxldCByZXF1ZXN0ZWRQYXJhbWV0ZXJOYW1lOiBzdHJpbmc7XG4gIHNka1Byb3ZpZGVyLnN0dWJTU00oe1xuICAgIGdldFBhcmFtZXRlcihyZXF1ZXN0KSB7XG4gICAgICByZXF1ZXN0ZWRQYXJhbWV0ZXJOYW1lID0gcmVxdWVzdC5OYW1lO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgUGFyYW1ldGVyOiB7XG4gICAgICAgICAgVmFsdWU6ICc5OScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xuXG4gIGF3YWl0IGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICBzdGFjazogdGVzdFN0YWNrKHtcbiAgICAgIHN0YWNrTmFtZTogJ2Jvb3AnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhc3N1bWVSb2xlQXJuOiAnYmxvb3A6JHtBV1M6OlJlZ2lvbn06JHtBV1M6OkFjY291bnRJZH0nLFxuICAgICAgICByZXF1aXJlc0Jvb3RzdHJhcFN0YWNrVmVyc2lvbjogOTksXG4gICAgICAgIGJvb3RzdHJhcFN0YWNrVmVyc2lvblNzbVBhcmFtZXRlcjogJy9zb21lL3BhcmFtZXRlcicsXG4gICAgICB9LFxuICAgIH0pLFxuICB9KTtcblxuICBleHBlY3QocmVxdWVzdGVkUGFyYW1ldGVyTmFtZSEpLnRvRXF1YWwoJy9zb21lL3BhcmFtZXRlcicpO1xufSk7XG4iXX0=
|
|
146
|
+
test('readCurrentTemplateWithNestedStacks() can handle non-Resources in the template', async () => {
|
|
147
|
+
const cfnStack = new fake_cloudformation_stack_1.FakeCloudformationStack({
|
|
148
|
+
stackName: 'ParentOfStackWithOutputAndParameter',
|
|
149
|
+
stackId: 'StackId',
|
|
150
|
+
});
|
|
151
|
+
cloudformation_1.CloudFormationStack.lookup = (async (_, stackName) => {
|
|
152
|
+
switch (stackName) {
|
|
153
|
+
case 'ParentOfStackWithOutputAndParameter':
|
|
154
|
+
cfnStack.template = async () => ({
|
|
155
|
+
Resources: {
|
|
156
|
+
NestedStack: {
|
|
157
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
158
|
+
Properties: {
|
|
159
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
160
|
+
},
|
|
161
|
+
Metadata: {
|
|
162
|
+
'aws:asset:path': 'one-output-one-param-stack.nested.template.json',
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
break;
|
|
168
|
+
case 'NestedStack':
|
|
169
|
+
cfnStack.template = async () => ({
|
|
170
|
+
Resources: {
|
|
171
|
+
NestedResource: {
|
|
172
|
+
Type: 'AWS::Something',
|
|
173
|
+
Properties: {
|
|
174
|
+
Property: 'old-value',
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
Parameters: {
|
|
179
|
+
NestedParam: {
|
|
180
|
+
Type: 'String',
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
Outputs: {
|
|
184
|
+
NestedOutput: {
|
|
185
|
+
Value: {
|
|
186
|
+
Ref: 'NestedResource',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
break;
|
|
192
|
+
default:
|
|
193
|
+
throw new Error('unknown stack name ' + stackName + ' found');
|
|
194
|
+
}
|
|
195
|
+
return cfnStack;
|
|
196
|
+
});
|
|
197
|
+
const rootStack = util_1.testStack({
|
|
198
|
+
stackName: 'ParentOfStackWithOutputAndParameter',
|
|
199
|
+
template: {
|
|
200
|
+
Resources: {
|
|
201
|
+
NestedStack: {
|
|
202
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
203
|
+
Properties: {
|
|
204
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
205
|
+
},
|
|
206
|
+
Metadata: {
|
|
207
|
+
'aws:asset:path': 'one-output-one-param-stack.nested.template.json',
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
pushStackResourceSummaries('ParentOfStackWithOutputAndParameter', stackSummaryOf('NestedStack', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/NestedStack/abcd'));
|
|
214
|
+
// WHEN
|
|
215
|
+
const deployedTemplate = await deployments.readCurrentTemplateWithNestedStacks(rootStack);
|
|
216
|
+
// THEN
|
|
217
|
+
expect(deployedTemplate).toEqual({
|
|
218
|
+
Resources: {
|
|
219
|
+
NestedStack: {
|
|
220
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
221
|
+
Properties: {
|
|
222
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
223
|
+
NestedTemplate: {
|
|
224
|
+
Resources: {
|
|
225
|
+
NestedResource: {
|
|
226
|
+
Type: 'AWS::Something',
|
|
227
|
+
Properties: {
|
|
228
|
+
Property: 'old-value',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
Outputs: {
|
|
233
|
+
NestedOutput: {
|
|
234
|
+
Value: {
|
|
235
|
+
Ref: 'NestedResource',
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
Parameters: {
|
|
240
|
+
NestedParam: {
|
|
241
|
+
Type: 'String',
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
Metadata: {
|
|
247
|
+
'aws:asset:path': 'one-output-one-param-stack.nested.template.json',
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
expect(rootStack.template).toEqual({
|
|
253
|
+
Resources: {
|
|
254
|
+
NestedStack: {
|
|
255
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
256
|
+
Properties: {
|
|
257
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
258
|
+
NestedTemplate: {
|
|
259
|
+
Resources: {
|
|
260
|
+
NestedResource: {
|
|
261
|
+
Type: 'AWS::Something',
|
|
262
|
+
Properties: {
|
|
263
|
+
Property: 'new-value',
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
Outputs: {
|
|
268
|
+
NestedOutput: {
|
|
269
|
+
Value: {
|
|
270
|
+
Ref: 'NestedResource',
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
Parameters: {
|
|
275
|
+
NestedParam: {
|
|
276
|
+
Type: 'Number',
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
Metadata: {
|
|
282
|
+
'aws:asset:path': 'one-output-one-param-stack.nested.template.json',
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
test('readCurrentTemplateWithNestedStacks() with a 3-level nested + sibling structure works', async () => {
|
|
289
|
+
const cfnStack = new fake_cloudformation_stack_1.FakeCloudformationStack({
|
|
290
|
+
stackName: 'MultiLevelRoot',
|
|
291
|
+
stackId: 'StackId',
|
|
292
|
+
});
|
|
293
|
+
cloudformation_1.CloudFormationStack.lookup = (async (_, stackName) => {
|
|
294
|
+
switch (stackName) {
|
|
295
|
+
case 'MultiLevelRoot':
|
|
296
|
+
cfnStack.template = async () => ({
|
|
297
|
+
Resources: {
|
|
298
|
+
NestedStack: {
|
|
299
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
300
|
+
Properties: {
|
|
301
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
302
|
+
},
|
|
303
|
+
Metadata: {
|
|
304
|
+
'aws:asset:path': 'one-resource-two-stacks-stack.nested.template.json',
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
break;
|
|
310
|
+
case 'NestedStack':
|
|
311
|
+
cfnStack.template = async () => ({
|
|
312
|
+
Resources: {
|
|
313
|
+
SomeResource: {
|
|
314
|
+
Type: 'AWS::Something',
|
|
315
|
+
Properties: {
|
|
316
|
+
Property: 'old-value',
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
GrandChildStackA: {
|
|
320
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
321
|
+
Properties: {
|
|
322
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
323
|
+
},
|
|
324
|
+
Metadata: {
|
|
325
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
GrandChildStackB: {
|
|
329
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
330
|
+
Properties: {
|
|
331
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
332
|
+
},
|
|
333
|
+
Metadata: {
|
|
334
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
break;
|
|
340
|
+
case 'GrandChildStackA':
|
|
341
|
+
cfnStack.template = async () => ({
|
|
342
|
+
Resources: {
|
|
343
|
+
SomeResource: {
|
|
344
|
+
Type: 'AWS::Something',
|
|
345
|
+
Properties: {
|
|
346
|
+
Property: 'old-value',
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
break;
|
|
352
|
+
case 'GrandChildStackB':
|
|
353
|
+
cfnStack.template = async () => ({
|
|
354
|
+
Resources: {
|
|
355
|
+
SomeResource: {
|
|
356
|
+
Type: 'AWS::Something',
|
|
357
|
+
Properties: {
|
|
358
|
+
Property: 'old-value',
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
break;
|
|
364
|
+
default:
|
|
365
|
+
throw new Error('unknown stack name ' + stackName + ' found in cloudformation-deployments.test.ts');
|
|
366
|
+
}
|
|
367
|
+
return cfnStack;
|
|
368
|
+
});
|
|
369
|
+
const rootStack = util_1.testStack({
|
|
370
|
+
stackName: 'MultiLevelRoot',
|
|
371
|
+
template: {
|
|
372
|
+
Resources: {
|
|
373
|
+
NestedStack: {
|
|
374
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
375
|
+
Properties: {
|
|
376
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
377
|
+
},
|
|
378
|
+
Metadata: {
|
|
379
|
+
'aws:asset:path': 'one-resource-two-stacks-stack.nested.template.json',
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
pushStackResourceSummaries('MultiLevelRoot', stackSummaryOf('NestedStack', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/NestedStack/abcd'));
|
|
386
|
+
pushStackResourceSummaries('NestedStack', stackSummaryOf('GrandChildStackA', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/GrandChildStackA/abcd'), stackSummaryOf('GrandChildStackB', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/GrandChildStackB/abcd'));
|
|
387
|
+
pushStackResourceSummaries('GrandChildStackA', stackSummaryOf('NestedStack', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/GrandChildA/abcd'));
|
|
388
|
+
pushStackResourceSummaries('GrandChildStackB', stackSummaryOf('NestedStack', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/GrandChildB/abcd'));
|
|
389
|
+
// WHEN
|
|
390
|
+
const deployedTemplate = await deployments.readCurrentTemplateWithNestedStacks(rootStack);
|
|
391
|
+
// THEN
|
|
392
|
+
expect(deployedTemplate).toEqual({
|
|
393
|
+
Resources: {
|
|
394
|
+
NestedStack: {
|
|
395
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
396
|
+
Properties: {
|
|
397
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
398
|
+
NestedTemplate: {
|
|
399
|
+
Resources: {
|
|
400
|
+
GrandChildStackA: {
|
|
401
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
402
|
+
Properties: {
|
|
403
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
404
|
+
NestedTemplate: {
|
|
405
|
+
Resources: {
|
|
406
|
+
SomeResource: {
|
|
407
|
+
Type: 'AWS::Something',
|
|
408
|
+
Properties: {
|
|
409
|
+
Property: 'old-value',
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
Metadata: {
|
|
416
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
GrandChildStackB: {
|
|
420
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
421
|
+
Properties: {
|
|
422
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
423
|
+
NestedTemplate: {
|
|
424
|
+
Resources: {
|
|
425
|
+
SomeResource: {
|
|
426
|
+
Type: 'AWS::Something',
|
|
427
|
+
Properties: {
|
|
428
|
+
Property: 'old-value',
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
Metadata: {
|
|
435
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
SomeResource: {
|
|
439
|
+
Type: 'AWS::Something',
|
|
440
|
+
Properties: {
|
|
441
|
+
Property: 'old-value',
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
Metadata: {
|
|
448
|
+
'aws:asset:path': 'one-resource-two-stacks-stack.nested.template.json',
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
});
|
|
453
|
+
expect(rootStack.template).toEqual({
|
|
454
|
+
Resources: {
|
|
455
|
+
NestedStack: {
|
|
456
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
457
|
+
Properties: {
|
|
458
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
459
|
+
NestedTemplate: {
|
|
460
|
+
Resources: {
|
|
461
|
+
GrandChildStackA: {
|
|
462
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
463
|
+
Properties: {
|
|
464
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
465
|
+
NestedTemplate: {
|
|
466
|
+
Resources: {
|
|
467
|
+
SomeResource: {
|
|
468
|
+
Type: 'AWS::Something',
|
|
469
|
+
Properties: {
|
|
470
|
+
Property: 'new-value',
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
Metadata: {
|
|
477
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
GrandChildStackB: {
|
|
481
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
482
|
+
Properties: {
|
|
483
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
484
|
+
NestedTemplate: {
|
|
485
|
+
Resources: {
|
|
486
|
+
SomeResource: {
|
|
487
|
+
Type: 'AWS::Something',
|
|
488
|
+
Properties: {
|
|
489
|
+
Property: 'new-value',
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
Metadata: {
|
|
496
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
SomeResource: {
|
|
500
|
+
Type: 'AWS::Something',
|
|
501
|
+
Properties: {
|
|
502
|
+
Property: 'new-value',
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
Metadata: {
|
|
509
|
+
'aws:asset:path': 'one-resource-two-stacks-stack.nested.template.json',
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
test('readCurrentTemplateWithNestedStacks() on an undeployed parent stack with an (also undeployed) nested stack works', async () => {
|
|
516
|
+
// GIVEN
|
|
517
|
+
const cfnStack = new fake_cloudformation_stack_1.FakeCloudformationStack({
|
|
518
|
+
stackName: 'UndeployedParent',
|
|
519
|
+
stackId: 'StackId',
|
|
520
|
+
});
|
|
521
|
+
cloudformation_1.CloudFormationStack.lookup = (async (_cfn, _stackName) => {
|
|
522
|
+
cfnStack.template = async () => ({});
|
|
523
|
+
return cfnStack;
|
|
524
|
+
});
|
|
525
|
+
const rootStack = util_1.testStack({
|
|
526
|
+
stackName: 'UndeployedParent',
|
|
527
|
+
template: {
|
|
528
|
+
Resources: {
|
|
529
|
+
NestedStack: {
|
|
530
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
531
|
+
Properties: {
|
|
532
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
533
|
+
},
|
|
534
|
+
Metadata: {
|
|
535
|
+
'aws:asset:path': 'one-resource-one-stack-stack.nested.template.json',
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
});
|
|
541
|
+
// WHEN
|
|
542
|
+
const deployedTemplate = await deployments.readCurrentTemplateWithNestedStacks(rootStack);
|
|
543
|
+
// THEN
|
|
544
|
+
expect(deployedTemplate).toEqual({
|
|
545
|
+
Resources: {
|
|
546
|
+
NestedStack: {
|
|
547
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
548
|
+
Properties: {
|
|
549
|
+
NestedTemplate: {
|
|
550
|
+
Resources: {
|
|
551
|
+
NestedStack: {
|
|
552
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
553
|
+
Properties: {
|
|
554
|
+
NestedTemplate: {},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
});
|
|
564
|
+
test('readCurrentTemplateWithNestedStacks() caches calls to listStackResources()', async () => {
|
|
565
|
+
// GIVEN
|
|
566
|
+
const cfnStack = new fake_cloudformation_stack_1.FakeCloudformationStack({
|
|
567
|
+
stackName: 'CachingRoot',
|
|
568
|
+
stackId: 'StackId',
|
|
569
|
+
});
|
|
570
|
+
cloudformation_1.CloudFormationStack.lookup = (async (_cfn, _stackName) => {
|
|
571
|
+
cfnStack.template = async () => ({
|
|
572
|
+
Resources: {
|
|
573
|
+
NestedStackA: {
|
|
574
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
575
|
+
Properties: {
|
|
576
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
577
|
+
},
|
|
578
|
+
Metadata: {
|
|
579
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
580
|
+
},
|
|
581
|
+
},
|
|
582
|
+
NestedStackB: {
|
|
583
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
584
|
+
Properties: {
|
|
585
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
586
|
+
},
|
|
587
|
+
Metadata: {
|
|
588
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
});
|
|
593
|
+
return cfnStack;
|
|
594
|
+
});
|
|
595
|
+
const rootStack = util_1.testStack({
|
|
596
|
+
stackName: 'CachingRoot',
|
|
597
|
+
template: {
|
|
598
|
+
Resources: {
|
|
599
|
+
NestedStackA: {
|
|
600
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
601
|
+
Properties: {
|
|
602
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
603
|
+
},
|
|
604
|
+
Metadata: {
|
|
605
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
NestedStackB: {
|
|
609
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
610
|
+
Properties: {
|
|
611
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
612
|
+
},
|
|
613
|
+
Metadata: {
|
|
614
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
615
|
+
},
|
|
616
|
+
},
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
});
|
|
620
|
+
pushStackResourceSummaries('CachingRoot', stackSummaryOf('NestedStackA', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/one-resource-stack/abcd'), stackSummaryOf('NestedStackB', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/one-resource-stack/abcd'));
|
|
621
|
+
// WHEN
|
|
622
|
+
await deployments.readCurrentTemplateWithNestedStacks(rootStack);
|
|
623
|
+
// THEN
|
|
624
|
+
expect(numberOfTimesListStackResourcesWasCalled).toEqual(1);
|
|
625
|
+
});
|
|
626
|
+
test('readCurrentTemplateWithNestedStacks() succesfully ignores stacks without metadata', async () => {
|
|
627
|
+
// GIVEN
|
|
628
|
+
const cfnStack = new fake_cloudformation_stack_1.FakeCloudformationStack({
|
|
629
|
+
stackName: 'MetadataRoot',
|
|
630
|
+
stackId: 'StackId',
|
|
631
|
+
});
|
|
632
|
+
cloudformation_1.CloudFormationStack.lookup = (async (_, stackName) => {
|
|
633
|
+
if (stackName === 'MetadataRoot') {
|
|
634
|
+
cfnStack.template = async () => ({
|
|
635
|
+
Resources: {
|
|
636
|
+
WithMetadata: {
|
|
637
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
638
|
+
Properties: {
|
|
639
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
640
|
+
},
|
|
641
|
+
Metadata: {
|
|
642
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
643
|
+
},
|
|
644
|
+
},
|
|
645
|
+
},
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
cfnStack.template = async () => ({
|
|
650
|
+
Resources: {
|
|
651
|
+
SomeResource: {
|
|
652
|
+
Type: 'AWS::Something',
|
|
653
|
+
Properties: {
|
|
654
|
+
Property: 'old-value',
|
|
655
|
+
},
|
|
656
|
+
},
|
|
657
|
+
},
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
return cfnStack;
|
|
661
|
+
});
|
|
662
|
+
const rootStack = util_1.testStack({
|
|
663
|
+
stackName: 'MetadataRoot',
|
|
664
|
+
template: {
|
|
665
|
+
Resources: {
|
|
666
|
+
WithoutMetadata: {
|
|
667
|
+
Properties: {
|
|
668
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
669
|
+
},
|
|
670
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
671
|
+
},
|
|
672
|
+
WithEmptyMetadata: {
|
|
673
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
674
|
+
Properties: {
|
|
675
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
676
|
+
},
|
|
677
|
+
Metadata: {},
|
|
678
|
+
},
|
|
679
|
+
WithMetadata: {
|
|
680
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
681
|
+
Properties: {
|
|
682
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
683
|
+
},
|
|
684
|
+
Metadata: {
|
|
685
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
|
+
pushStackResourceSummaries('MetadataRoot', stackSummaryOf('WithMetadata', 'AWS::CloudFormation::Stack', 'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/one-resource-stack/abcd'));
|
|
692
|
+
// WHEN
|
|
693
|
+
const deployedTemplate = await deployments.readCurrentTemplateWithNestedStacks(rootStack);
|
|
694
|
+
// THEN
|
|
695
|
+
expect(deployedTemplate).toEqual({
|
|
696
|
+
Resources: {
|
|
697
|
+
WithMetadata: {
|
|
698
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
699
|
+
Properties: {
|
|
700
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
701
|
+
NestedTemplate: {
|
|
702
|
+
Resources: {
|
|
703
|
+
SomeResource: {
|
|
704
|
+
Type: 'AWS::Something',
|
|
705
|
+
Properties: {
|
|
706
|
+
Property: 'old-value',
|
|
707
|
+
},
|
|
708
|
+
},
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
Metadata: {
|
|
713
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
714
|
+
},
|
|
715
|
+
},
|
|
716
|
+
},
|
|
717
|
+
});
|
|
718
|
+
expect(rootStack.template).toEqual({
|
|
719
|
+
Resources: {
|
|
720
|
+
WithoutMetadata: {
|
|
721
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
722
|
+
Properties: {
|
|
723
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
WithEmptyMetadata: {
|
|
727
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
728
|
+
Properties: {
|
|
729
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
730
|
+
},
|
|
731
|
+
Metadata: {},
|
|
732
|
+
},
|
|
733
|
+
WithMetadata: {
|
|
734
|
+
Type: 'AWS::CloudFormation::Stack',
|
|
735
|
+
Properties: {
|
|
736
|
+
TemplateURL: 'https://www.magic-url.com',
|
|
737
|
+
NestedTemplate: {
|
|
738
|
+
Resources: {
|
|
739
|
+
SomeResource: {
|
|
740
|
+
Type: 'AWS::Something',
|
|
741
|
+
Properties: {
|
|
742
|
+
Property: 'new-value',
|
|
743
|
+
},
|
|
744
|
+
},
|
|
745
|
+
},
|
|
746
|
+
},
|
|
747
|
+
},
|
|
748
|
+
Metadata: {
|
|
749
|
+
'aws:asset:path': 'one-resource-stack.nested.template.json',
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
},
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
function pushStackResourceSummaries(stackName, ...items) {
|
|
756
|
+
if (!currentCfnStackResources[stackName]) {
|
|
757
|
+
currentCfnStackResources[stackName] = [];
|
|
758
|
+
}
|
|
759
|
+
currentCfnStackResources[stackName].push(...items);
|
|
760
|
+
}
|
|
761
|
+
function stackSummaryOf(logicalId, resourceType, physicalResourceId) {
|
|
762
|
+
return {
|
|
763
|
+
LogicalResourceId: logicalId,
|
|
764
|
+
PhysicalResourceId: physicalResourceId,
|
|
765
|
+
ResourceType: resourceType,
|
|
766
|
+
ResourceStatus: 'CREATE_COMPLETE',
|
|
767
|
+
LastUpdatedTimestamp: new Date(),
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRmb3JtYXRpb24tZGVwbG95bWVudHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsb3VkZm9ybWF0aW9uLWRlcGxveW1lbnRzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUM7QUFHeEMseUZBQXFGO0FBQ3JGLDZEQUF5RDtBQUN6RCw2REFBeUQ7QUFDekQsc0VBQXdFO0FBQ3hFLGtDQUFvQztBQUNwQywrQ0FBdUU7QUFDdkUsMkVBQXNFO0FBRXRFLElBQUksV0FBNEIsQ0FBQztBQUNqQyxJQUFJLFdBQXNDLENBQUM7QUFDM0MsSUFBSSxxQkFBZ0MsQ0FBQztBQUNyQyxJQUFJLHdCQUFrRixDQUFDO0FBQ3ZGLElBQUksd0NBQWdELENBQUM7QUFDckQsVUFBVSxDQUFDLEdBQUcsRUFBRTtJQUNkLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUNyQixXQUFXLEdBQUcsSUFBSSwwQkFBZSxFQUFFLENBQUM7SUFDcEMsV0FBVyxHQUFHLElBQUksc0RBQXlCLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBRTdELHdDQUF3QyxHQUFHLENBQUMsQ0FBQztJQUM3Qyx3QkFBd0IsR0FBRyxFQUFFLENBQUM7SUFDOUIsV0FBVyxDQUFDLGtCQUFrQixDQUFDO1FBQzdCLGtCQUFrQixFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtZQUMvQyx3Q0FBd0MsRUFBRSxDQUFDO1lBQzNDLE1BQU0sY0FBYyxHQUFHLHdCQUF3QixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzNELElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLFNBQVMsaUJBQWlCLENBQUMsQ0FBQzthQUM5RDtZQUNELE9BQU87Z0JBQ0wsc0JBQXNCLEVBQUUsY0FBYzthQUN2QyxDQUFDO1FBQ0osQ0FBQztL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QUFrQjtRQUN0QyxZQUFZLEVBQUUsWUFBWTtRQUMxQixjQUFjLEVBQUUsaUJBQWlCO1FBQ2pDLG9CQUFvQixFQUFFLElBQUksSUFBSSxFQUFFO0tBQ2pDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiamVzdC5tb2NrKCcuLi8uLi9saWIvYXBpL2RlcGxveS1zdGFjaycpO1xuXG5pbXBvcnQgeyBDbG91ZEZvcm1hdGlvbiB9IGZyb20gJ2F3cy1zZGsnO1xuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb25EZXBsb3ltZW50cyB9IGZyb20gJy4uLy4uL2xpYi9hcGkvY2xvdWRmb3JtYXRpb24tZGVwbG95bWVudHMnO1xuaW1wb3J0IHsgZGVwbG95U3RhY2sgfSBmcm9tICcuLi8uLi9saWIvYXBpL2RlcGxveS1zdGFjayc7XG5pbXBvcnQgeyBUb29sa2l0SW5mbyB9IGZyb20gJy4uLy4uL2xpYi9hcGkvdG9vbGtpdC1pbmZvJztcbmltcG9ydCB7IENsb3VkRm9ybWF0aW9uU3RhY2sgfSBmcm9tICcuLi8uLi9saWIvYXBpL3V0aWwvY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgdGVzdFN0YWNrIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgeyBtb2NrQm9vdHN0cmFwU3RhY2ssIE1vY2tTZGtQcm92aWRlciB9IGZyb20gJy4uL3V0aWwvbW9jay1zZGsnO1xuaW1wb3J0IHsgRmFrZUNsb3VkZm9ybWF0aW9uU3RhY2sgfSBmcm9tICcuL2Zha2UtY2xvdWRmb3JtYXRpb24tc3RhY2snO1xuXG5sZXQgc2RrUHJvdmlkZXI6IE1vY2tTZGtQcm92aWRlcjtcbmxldCBkZXBsb3ltZW50czogQ2xvdWRGb3JtYXRpb25EZXBsb3ltZW50cztcbmxldCBtb2NrVG9vbGtpdEluZm9Mb29rdXA6IGplc3QuTW9jaztcbmxldCBjdXJyZW50Q2ZuU3RhY2tSZXNvdXJjZXM6IHsgW2tleTogc3RyaW5nXTogQ2xvdWRGb3JtYXRpb24uU3RhY2tSZXNvdXJjZVN1bW1hcnlbXSB9O1xubGV0IG51bWJlck9mVGltZXNMaXN0U3RhY2tSZXNvdXJjZXNXYXNDYWxsZWQ6IG51bWJlcjtcbmJlZm9yZUVhY2goKCkgPT4ge1xuICBqZXN0LnJlc2V0QWxsTW9ja3MoKTtcbiAgc2RrUHJvdmlkZXIgPSBuZXcgTW9ja1Nka1Byb3ZpZGVyKCk7XG4gIGRlcGxveW1lbnRzID0gbmV3IENsb3VkRm9ybWF0aW9uRGVwbG95bWVudHMoeyBzZGtQcm92aWRlciB9KTtcblxuICBudW1iZXJPZlRpbWVzTGlzdFN0YWNrUmVzb3VyY2VzV2FzQ2FsbGVkID0gMDtcbiAgY3VycmVudENmblN0YWNrUmVzb3VyY2VzID0ge307XG4gIHNka1Byb3ZpZGVyLnN0dWJDbG91ZEZvcm1hdGlvbih7XG4gICAgbGlzdFN0YWNrUmVzb3VyY2VzOiAoeyBTdGFja05hbWU6IHN0YWNrTmFtZSB9KSA9PiB7XG4gICAgICBudW1iZXJPZlRpbWVzTGlzdFN0YWNrUmVzb3VyY2VzV2FzQ2FsbGVkKys7XG4gICAgICBjb25zdCBzdGFja1Jlc291cmNlcyA9IGN1cnJlbnRDZm5TdGFja1Jlc291cmNlc1tzdGFja05hbWVdO1xuICAgICAgaWYgKCFzdGFja1Jlc291cmNlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFN0YWNrIHdpdGggaWQgJHtzdGFja05hbWV9IGRvZXMgbm90IGV4aXN0YCk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBTdGFja1Jlc291cmNlU3VtbWFyaWVzOiBzdGFja1Jlc291cmNlcyxcbiAgICAgIH07XG4gICAgfSxcbiAgfSk7XG5cbiAgVG9vbGtpdEluZm8ubG9va3VwID0gbW9ja1Rvb2xraXRJbmZvTG9va3VwID0gamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFRvb2xraXRJbmZvLmJvb3RzdHJhcFN0YWNrTm90Rm91bmRJbmZvKHNka1Byb3ZpZGVyLnNkaykpO1xufSk7XG5cbmZ1bmN0aW9uIG1vY2tTdWNjZXNzZnVsQm9vdHN0cmFwU3RhY2tMb29rdXAocHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gIGNvbnN0IG91dHB1dHMgPSB7XG4gICAgQnVja2V0TmFtZTogJ0JVQ0tFVF9OQU1FJyxcbiAgICBCdWNrZXREb21haW5OYW1lOiAnQlVDS0VUX0VORFBPSU5UJyxcbiAgICBCb290c3RyYXBWZXJzaW9uOiAnMScsXG4gICAgLi4ucHJvcHMsXG4gIH07XG5cbiAgY29uc3QgZmFrZVN0YWNrID0gbW9ja0Jvb3RzdHJhcFN0YWNrKHNka1Byb3ZpZGVyLnNkaywge1xuICAgIE91dHB1dHM6IE9iamVjdC5lbnRyaWVzKG91dHB1dHMpLm1hcCgoW2ssIHZdKSA9PiAoe1xuICAgICAgT3V0cHV0S2V5OiBrLFxuICAgICAgT3V0cHV0VmFsdWU6IGAke3Z9YCxcbiAgICB9KSksXG4gIH0pO1xuXG4gIG1vY2tUb29sa2l0SW5mb0xvb2t1cC5tb2NrUmVzb2x2ZWRWYWx1ZShUb29sa2l0SW5mby5mcm9tU3RhY2soZmFrZVN0YWNrLCBzZGtQcm92aWRlci5zZGspKTtcbn1cblxudGVzdCgncGFzc2VzIHRocm91Z2ggaG90c3dhcD10cnVlIHRvIGRlcGxveVN0YWNrKCknLCBhc3luYyAoKSA9PiB7XG4gIC8vIFdIRU5cbiAgYXdhaXQgZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgIHN0YWNrOiB0ZXN0U3RhY2soe1xuICAgICAgc3RhY2tOYW1lOiAnYm9vcCcsXG4gICAgfSksXG4gICAgaG90c3dhcDogdHJ1ZSxcbiAgfSk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoZGVwbG95U3RhY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICBob3Rzd2FwOiB0cnVlLFxuICB9KSk7XG59KTtcblxudGVzdCgncGxhY2Vob2xkZXJzIGFyZSBzdWJzdGl0dXRlZCBpbiBDbG91ZEZvcm1hdGlvbiBleGVjdXRpb24gcm9sZScsIGFzeW5jICgpID0+IHtcbiAgYXdhaXQgZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgIHN0YWNrOiB0ZXN0U3RhY2soe1xuICAgICAgc3RhY2tOYW1lOiAnYm9vcCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGNsb3VkRm9ybWF0aW9uRXhlY3V0aW9uUm9sZUFybjogJ2Jsb29wOiR7QVdTOjpSZWdpb259OiR7QVdTOjpBY2NvdW50SWR9JyxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuXG4gIGV4cGVjdChkZXBsb3lTdGFjaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgIHJvbGVBcm46ICdibG9vcDpoZXJlOjEyMzQ1Njc4OTAxMicsXG4gIH0pKTtcbn0pO1xuXG50ZXN0KCdyb2xlIHdpdGggcGxhY2Vob2xkZXJzIGlzIGFzc3VtZWQgaWYgYXNzdW1lcm9sZSBpcyBnaXZlbicsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgbW9ja0ZvckVudmlyb25tZW50ID0gamVzdC5mbigpLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiB7IHJldHVybiB7IHNkazogc2RrUHJvdmlkZXIuc2RrIH07IH0pO1xuICBzZGtQcm92aWRlci5mb3JFbnZpcm9ubWVudCA9IG1vY2tGb3JFbnZpcm9ubWVudDtcblxuICBhd2FpdCBkZXBsb3ltZW50cy5kZXBsb3lTdGFjayh7XG4gICAgc3RhY2s6IHRlc3RTdGFjayh7XG4gICAgICBzdGFja05hbWU6ICdib29wJyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYXNzdW1lUm9sZUFybjogJ2Jsb29wOiR7QVdTOjpSZWdpb259OiR7QVdTOjpBY2NvdW50SWR9JyxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuXG4gIGV4cGVjdChtb2NrRm9yRW52aXJvbm1lbnQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5hbnl0aGluZygpLCBleHBlY3QuYW55dGhpbmcoKSwgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgIGFzc3VtZVJvbGVBcm46ICdibG9vcDpoZXJlOjEyMzQ1Njc4OTAxMicsXG4gIH0pKTtcbn0pO1xuXG50ZXN0KCdkZXBsb3ltZW50IGZhaWxzIGlmIGJvb3RzdHJhcCBzdGFjayBpcyBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICBhd2FpdCBleHBlY3QoZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgIHN0YWNrOiB0ZXN0U3RhY2soe1xuICAgICAgc3RhY2tOYW1lOiAnYm9vcCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFzc3VtZVJvbGVBcm46ICdibG9vcDoke0FXUzo6UmVnaW9ufToke0FXUzo6QWNjb3VudElkfScsXG4gICAgICAgIHJlcXVpcmVzQm9vdHN0cmFwU3RhY2tWZXJzaW9uOiA5OSxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pKS5yZWplY3RzLnRvVGhyb3coL3JlcXVpcmVzIGEgYm9vdHN0cmFwIHN0YWNrLyk7XG59KTtcblxudGVzdCgnZGVwbG95bWVudCBmYWlscyBpZiBib290c3RyYXAgc3RhY2sgaXMgdG9vIG9sZCcsIGFzeW5jICgpID0+IHtcbiAgbW9ja1N1Y2Nlc3NmdWxCb290c3RyYXBTdGFja0xvb2t1cCh7XG4gICAgQm9vdHN0cmFwVmVyc2lvbjogNSxcbiAgfSk7XG5cbiAgYXdhaXQgZXhwZWN0KGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICBzdGFjazogdGVzdFN0YWNrKHtcbiAgICAgIHN0YWNrTmFtZTogJ2Jvb3AnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhc3N1bWVSb2xlQXJuOiAnYmxvb3A6JHtBV1M6OlJlZ2lvbn06JHtBV1M6OkFjY291bnRJZH0nLFxuICAgICAgICByZXF1aXJlc0Jvb3RzdHJhcFN0YWNrVmVyc2lvbjogOTksXG4gICAgICB9LFxuICAgIH0pLFxuICB9KSkucmVqZWN0cy50b1Rocm93KC9yZXF1aXJlcyBib290c3RyYXAgc3RhY2sgdmVyc2lvbiAnOTknLCBmb3VuZCAnNScvKTtcbn0pO1xuXG50ZXN0KCdpZiB0b29sa2l0IHN0YWNrIGNhbm5vdCBiZSBmb3VuZCBidXQgU1NNIHBhcmFtZXRlciBuYW1lIGlzIHByZXNlbnQgZGVwbG95bWVudCBzdWNjZWVkcycsIGFzeW5jICgpID0+IHtcbiAgLy8gRklYTUU6IE1vY2tpbmcgYSBzdWNjZXNzZnVsIGJvb3RzdHJhcCBzdGFjayBsb29rdXAgaGVyZSBzaG91bGQgbm90IGJlIG5lY2Vzc2FyeS5cbiAgLy8gVGhpcyBzaG91bGQgZmFpbCBhbmQgcmV0dXJuIGEgcGxhY2Vob2xkZXIgZmFpbHVyZSBvYmplY3QuXG4gIG1vY2tTdWNjZXNzZnVsQm9vdHN0cmFwU3RhY2tMb29rdXAoe1xuICAgIEJvb3RzdHJhcFZlcnNpb246IDIsXG4gIH0pO1xuXG4gIGxldCByZXF1ZXN0ZWRQYXJhbWV0ZXJOYW1lOiBzdHJpbmc7XG4gIHNka1Byb3ZpZGVyLnN0dWJTU00oe1xuICAgIGdldFBhcmFtZXRlcihyZXF1ZXN0KSB7XG4gICAgICByZXF1ZXN0ZWRQYXJhbWV0ZXJOYW1lID0gcmVxdWVzdC5OYW1lO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgUGFyYW1ldGVyOiB7XG4gICAgICAgICAgVmFsdWU6ICc5OScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xuXG4gIGF3YWl0IGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICBzdGFjazogdGVzdFN0YWNrKHtcbiAgICAgIHN0YWNrTmFtZTogJ2Jvb3AnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhc3N1bWVSb2xlQXJuOiAnYmxvb3A6JHtBV1M6OlJlZ2lvbn06JHtBV1M6OkFjY291bnRJZH0nLFxuICAgICAgICByZXF1aXJlc0Jvb3RzdHJhcFN0YWNrVmVyc2lvbjogOTksXG4gICAgICAgIGJvb3RzdHJhcFN0YWNrVmVyc2lvblNzbVBhcmFtZXRlcjogJy9zb21lL3BhcmFtZXRlcicsXG4gICAgICB9LFxuICAgIH0pLFxuICB9KTtcblxuICBleHBlY3QocmVxdWVzdGVkUGFyYW1ldGVyTmFtZSEpLnRvRXF1YWwoJy9zb21lL3BhcmFtZXRlcicpO1xufSk7XG5cbnRlc3QoJ3JlYWRDdXJyZW50VGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tzKCkgY2FuIGhhbmRsZSBub24tUmVzb3VyY2VzIGluIHRoZSB0ZW1wbGF0ZScsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgY2ZuU3RhY2sgPSBuZXcgRmFrZUNsb3VkZm9ybWF0aW9uU3RhY2soe1xuICAgIHN0YWNrTmFtZTogJ1BhcmVudE9mU3RhY2tXaXRoT3V0cHV0QW5kUGFyYW1ldGVyJyxcbiAgICBzdGFja0lkOiAnU3RhY2tJZCcsXG4gIH0pO1xuICBDbG91ZEZvcm1hdGlvblN0YWNrLmxvb2t1cCA9IChhc3luYyAoXywgc3RhY2tOYW1lOiBzdHJpbmcpID0+IHtcbiAgICBzd2l0Y2ggKHN0YWNrTmFtZSkge1xuICAgICAgY2FzZSAnUGFyZW50T2ZTdGFja1dpdGhPdXRwdXRBbmRQYXJhbWV0ZXInOlxuICAgICAgICBjZm5TdGFjay50ZW1wbGF0ZSA9IGFzeW5jICgpID0+ICh7XG4gICAgICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgICAgICBOZXN0ZWRTdGFjazoge1xuICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgVGVtcGxhdGVVUkw6ICdodHRwczovL3d3dy5tYWdpYy11cmwuY29tJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLW91dHB1dC1vbmUtcGFyYW0tc3RhY2submVzdGVkLnRlbXBsYXRlLmpzb24nLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ05lc3RlZFN0YWNrJzpcbiAgICAgICAgY2ZuU3RhY2sudGVtcGxhdGUgPSBhc3luYyAoKSA9PiAoe1xuICAgICAgICAgIFJlc291cmNlczoge1xuICAgICAgICAgICAgTmVzdGVkUmVzb3VyY2U6IHtcbiAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nJyxcbiAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIFByb3BlcnR5OiAnb2xkLXZhbHVlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBOZXN0ZWRQYXJhbToge1xuICAgICAgICAgICAgICBUeXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBPdXRwdXRzOiB7XG4gICAgICAgICAgICBOZXN0ZWRPdXRwdXQ6IHtcbiAgICAgICAgICAgICAgVmFsdWU6IHtcbiAgICAgICAgICAgICAgICBSZWY6ICdOZXN0ZWRSZXNvdXJjZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHN0YWNrIG5hbWUgJyArIHN0YWNrTmFtZSArICcgZm91bmQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2ZuU3RhY2s7XG4gIH0pO1xuXG4gIGNvbnN0IHJvb3RTdGFjayA9IHRlc3RTdGFjayh7XG4gICAgc3RhY2tOYW1lOiAnUGFyZW50T2ZTdGFja1dpdGhPdXRwdXRBbmRQYXJhbWV0ZXInLFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgTmVzdGVkU3RhY2s6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFRlbXBsYXRlVVJMOiAnaHR0cHM6Ly93d3cubWFnaWMtdXJsLmNvbScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29uZS1vdXRwdXQtb25lLXBhcmFtLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICBwdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcygnUGFyZW50T2ZTdGFja1dpdGhPdXRwdXRBbmRQYXJhbWV0ZXInLFxuICAgIHN0YWNrU3VtbWFyeU9mKCdOZXN0ZWRTdGFjaycsICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAnYXJuOmF3czpjbG91ZGZvcm1hdGlvbjpiZXJtdWRhLXRyaWFuZ2xlLTEzMzc6MTIzNDU2Nzg5MDEyOnN0YWNrL05lc3RlZFN0YWNrL2FiY2QnLFxuICAgICksXG4gICk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCBkZXBsb3llZFRlbXBsYXRlID0gYXdhaXQgZGVwbG95bWVudHMucmVhZEN1cnJlbnRUZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja3Mocm9vdFN0YWNrKTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChkZXBsb3llZFRlbXBsYXRlKS50b0VxdWFsKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIE5lc3RlZFN0YWNrOiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgTmVzdGVkUmVzb3VyY2U6IHtcbiAgICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpTb21ldGhpbmcnLFxuICAgICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgIFByb3BlcnR5OiAnb2xkLXZhbHVlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE91dHB1dHM6IHtcbiAgICAgICAgICAgICAgTmVzdGVkT3V0cHV0OiB7XG4gICAgICAgICAgICAgICAgVmFsdWU6IHtcbiAgICAgICAgICAgICAgICAgIFJlZjogJ05lc3RlZFJlc291cmNlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgTmVzdGVkUGFyYW06IHtcbiAgICAgICAgICAgICAgICBUeXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLW91dHB1dC1vbmUtcGFyYW0tc3RhY2submVzdGVkLnRlbXBsYXRlLmpzb24nLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICBleHBlY3Qocm9vdFN0YWNrLnRlbXBsYXRlKS50b0VxdWFsKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIE5lc3RlZFN0YWNrOiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgTmVzdGVkUmVzb3VyY2U6IHtcbiAgICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpTb21ldGhpbmcnLFxuICAgICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgIFByb3BlcnR5OiAnbmV3LXZhbHVlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE91dHB1dHM6IHtcbiAgICAgICAgICAgICAgTmVzdGVkT3V0cHV0OiB7XG4gICAgICAgICAgICAgICAgVmFsdWU6IHtcbiAgICAgICAgICAgICAgICAgIFJlZjogJ05lc3RlZFJlc291cmNlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgTmVzdGVkUGFyYW06IHtcbiAgICAgICAgICAgICAgICBUeXBlOiAnTnVtYmVyJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLW91dHB1dC1vbmUtcGFyYW0tc3RhY2submVzdGVkLnRlbXBsYXRlLmpzb24nLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn0pO1xuXG50ZXN0KCdyZWFkQ3VycmVudFRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcygpIHdpdGggYSAzLWxldmVsIG5lc3RlZCArIHNpYmxpbmcgc3RydWN0dXJlIHdvcmtzJywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCBjZm5TdGFjayA9IG5ldyBGYWtlQ2xvdWRmb3JtYXRpb25TdGFjayh7XG4gICAgc3RhY2tOYW1lOiAnTXVsdGlMZXZlbFJvb3QnLFxuICAgIHN0YWNrSWQ6ICdTdGFja0lkJyxcbiAgfSk7XG4gIENsb3VkRm9ybWF0aW9uU3RhY2subG9va3VwID0gKGFzeW5jIChfLCBzdGFja05hbWU6IHN0cmluZykgPT4ge1xuICAgIHN3aXRjaCAoc3RhY2tOYW1lKSB7XG4gICAgICBjYXNlICdNdWx0aUxldmVsUm9vdCc6XG4gICAgICAgIGNmblN0YWNrLnRlbXBsYXRlID0gYXN5bmMgKCkgPT4gKHtcbiAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgIE5lc3RlZFN0YWNrOiB7XG4gICAgICAgICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2UtdHdvLXN0YWNrcy1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnTmVzdGVkU3RhY2snOlxuICAgICAgICBjZm5TdGFjay50ZW1wbGF0ZSA9IGFzeW5jICgpID0+ICh7XG4gICAgICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgICAgICBTb21lUmVzb3VyY2U6IHtcbiAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nJyxcbiAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIFByb3BlcnR5OiAnb2xkLXZhbHVlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBHcmFuZENoaWxkU3RhY2tBOiB7XG4gICAgICAgICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2Utc3RhY2submVzdGVkLnRlbXBsYXRlLmpzb24nLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIEdyYW5kQ2hpbGRTdGFja0I6IHtcbiAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIFRlbXBsYXRlVVJMOiAnaHR0cHM6Ly93d3cubWFnaWMtdXJsLmNvbScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29uZS1yZXNvdXJjZS1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnR3JhbmRDaGlsZFN0YWNrQSc6XG4gICAgICAgIGNmblN0YWNrLnRlbXBsYXRlID0gYXN5bmMgKCkgPT4gKHtcbiAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgIFNvbWVSZXNvdXJjZToge1xuICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpTb21ldGhpbmcnLFxuICAgICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgUHJvcGVydHk6ICdvbGQtdmFsdWUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0dyYW5kQ2hpbGRTdGFja0InOlxuICAgICAgICBjZm5TdGFjay50ZW1wbGF0ZSA9IGFzeW5jICgpID0+ICh7XG4gICAgICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgICAgICBTb21lUmVzb3VyY2U6IHtcbiAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nJyxcbiAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIFByb3BlcnR5OiAnb2xkLXZhbHVlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gc3RhY2sgbmFtZSAnICsgc3RhY2tOYW1lICsgJyBmb3VuZCBpbiBjbG91ZGZvcm1hdGlvbi1kZXBsb3ltZW50cy50ZXN0LnRzJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNmblN0YWNrO1xuICB9KTtcblxuICBjb25zdCByb290U3RhY2sgPSB0ZXN0U3RhY2soe1xuICAgIHN0YWNrTmFtZTogJ011bHRpTGV2ZWxSb290JyxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIE5lc3RlZFN0YWNrOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2UtdHdvLXN0YWNrcy1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoJ011bHRpTGV2ZWxSb290JyxcbiAgICBzdGFja1N1bW1hcnlPZignTmVzdGVkU3RhY2snLCAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgJ2Fybjphd3M6Y2xvdWRmb3JtYXRpb246YmVybXVkYS10cmlhbmdsZS0xMzM3OjEyMzQ1Njc4OTAxMjpzdGFjay9OZXN0ZWRTdGFjay9hYmNkJyxcbiAgICApLFxuICApO1xuICBwdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcygnTmVzdGVkU3RhY2snLFxuICAgIHN0YWNrU3VtbWFyeU9mKCdHcmFuZENoaWxkU3RhY2tBJywgJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICdhcm46YXdzOmNsb3VkZm9ybWF0aW9uOmJlcm11ZGEtdHJpYW5nbGUtMTMzNzoxMjM0NTY3ODkwMTI6c3RhY2svR3JhbmRDaGlsZFN0YWNrQS9hYmNkJyxcbiAgICApLFxuICAgIHN0YWNrU3VtbWFyeU9mKCdHcmFuZENoaWxkU3RhY2tCJywgJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICdhcm46YXdzOmNsb3VkZm9ybWF0aW9uOmJlcm11ZGEtdHJpYW5nbGUtMTMzNzoxMjM0NTY3ODkwMTI6c3RhY2svR3JhbmRDaGlsZFN0YWNrQi9hYmNkJyxcbiAgICApLFxuICApO1xuICBwdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcygnR3JhbmRDaGlsZFN0YWNrQScsXG4gICAgc3RhY2tTdW1tYXJ5T2YoJ05lc3RlZFN0YWNrJywgJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICdhcm46YXdzOmNsb3VkZm9ybWF0aW9uOmJlcm11ZGEtdHJpYW5nbGUtMTMzNzoxMjM0NTY3ODkwMTI6c3RhY2svR3JhbmRDaGlsZEEvYWJjZCcsXG4gICAgKSxcbiAgKTtcbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoJ0dyYW5kQ2hpbGRTdGFja0InLFxuICAgIHN0YWNrU3VtbWFyeU9mKCdOZXN0ZWRTdGFjaycsICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAnYXJuOmF3czpjbG91ZGZvcm1hdGlvbjpiZXJtdWRhLXRyaWFuZ2xlLTEzMzc6MTIzNDU2Nzg5MDEyOnN0YWNrL0dyYW5kQ2hpbGRCL2FiY2QnLFxuICAgICksXG4gICk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCBkZXBsb3llZFRlbXBsYXRlID0gYXdhaXQgZGVwbG95bWVudHMucmVhZEN1cnJlbnRUZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja3Mocm9vdFN0YWNrKTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChkZXBsb3llZFRlbXBsYXRlKS50b0VxdWFsKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIE5lc3RlZFN0YWNrOiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgR3JhbmRDaGlsZFN0YWNrQToge1xuICAgICAgICAgICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgVGVtcGxhdGVVUkw6ICdodHRwczovL3d3dy5tYWdpYy11cmwuY29tJyxcbiAgICAgICAgICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICAgICAgICAgIFJlc291cmNlczoge1xuICAgICAgICAgICAgICAgICAgICAgIFNvbWVSZXNvdXJjZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVydHk6ICdvbGQtdmFsdWUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLXJlc291cmNlLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBHcmFuZENoaWxkU3RhY2tCOiB7XG4gICAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgICAgICAgICAgTmVzdGVkVGVtcGxhdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgU29tZVJlc291cmNlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpTb21ldGhpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9wZXJ0eTogJ29sZC12YWx1ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2Utc3RhY2submVzdGVkLnRlbXBsYXRlLmpzb24nLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFNvbWVSZXNvdXJjZToge1xuICAgICAgICAgICAgICAgIFR5cGU6ICdBV1M6OlNvbWV0aGluZycsXG4gICAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgUHJvcGVydHk6ICdvbGQtdmFsdWUnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29uZS1yZXNvdXJjZS10d28tc3RhY2tzLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgZXhwZWN0KHJvb3RTdGFjay50ZW1wbGF0ZSkudG9FcXVhbCh7XG4gICAgUmVzb3VyY2VzOiB7XG4gICAgICBOZXN0ZWRTdGFjazoge1xuICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgVGVtcGxhdGVVUkw6ICdodHRwczovL3d3dy5tYWdpYy11cmwuY29tJyxcbiAgICAgICAgICBOZXN0ZWRUZW1wbGF0ZToge1xuICAgICAgICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgICAgICAgIEdyYW5kQ2hpbGRTdGFja0E6IHtcbiAgICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgIFRlbXBsYXRlVVJMOiAnaHR0cHM6Ly93d3cubWFnaWMtdXJsLmNvbScsXG4gICAgICAgICAgICAgICAgICBOZXN0ZWRUZW1wbGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICBTb21lUmVzb3VyY2U6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGU6ICdBV1M6OlNvbWV0aGluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIFByb3BlcnR5OiAnbmV3LXZhbHVlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29uZS1yZXNvdXJjZS1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgR3JhbmRDaGlsZFN0YWNrQjoge1xuICAgICAgICAgICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgVGVtcGxhdGVVUkw6ICdodHRwczovL3d3dy5tYWdpYy11cmwuY29tJyxcbiAgICAgICAgICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICAgICAgICAgIFJlc291cmNlczoge1xuICAgICAgICAgICAgICAgICAgICAgIFNvbWVSZXNvdXJjZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVydHk6ICduZXctdmFsdWUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLXJlc291cmNlLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBTb21lUmVzb3VyY2U6IHtcbiAgICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpTb21ldGhpbmcnLFxuICAgICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgIFByb3BlcnR5OiAnbmV3LXZhbHVlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2UtdHdvLXN0YWNrcy1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xufSk7XG5cbnRlc3QoJ3JlYWRDdXJyZW50VGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tzKCkgb24gYW4gdW5kZXBsb3llZCBwYXJlbnQgc3RhY2sgd2l0aCBhbiAoYWxzbyB1bmRlcGxveWVkKSBuZXN0ZWQgc3RhY2sgd29ya3MnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGNmblN0YWNrID0gbmV3IEZha2VDbG91ZGZvcm1hdGlvblN0YWNrKHtcbiAgICBzdGFja05hbWU6ICdVbmRlcGxveWVkUGFyZW50JyxcbiAgICBzdGFja0lkOiAnU3RhY2tJZCcsXG4gIH0pO1xuICBDbG91ZEZvcm1hdGlvblN0YWNrLmxvb2t1cCA9IChhc3luYyAoX2NmbiwgX3N0YWNrTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgY2ZuU3RhY2sudGVtcGxhdGUgPSBhc3luYyAoKSA9PiAoe30pO1xuXG4gICAgcmV0dXJuIGNmblN0YWNrO1xuICB9KTtcbiAgY29uc3Qgcm9vdFN0YWNrID0gdGVzdFN0YWNrKHtcbiAgICBzdGFja05hbWU6ICdVbmRlcGxveWVkUGFyZW50JyxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIE5lc3RlZFN0YWNrOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2Utb25lLXN0YWNrLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IGRlcGxveWVkVGVtcGxhdGUgPSBhd2FpdCBkZXBsb3ltZW50cy5yZWFkQ3VycmVudFRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcyhyb290U3RhY2spO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGRlcGxveWVkVGVtcGxhdGUpLnRvRXF1YWwoe1xuICAgIFJlc291cmNlczoge1xuICAgICAgTmVzdGVkU3RhY2s6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgTmVzdGVkU3RhY2s6IHtcbiAgICAgICAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7fSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn0pO1xuXG50ZXN0KCdyZWFkQ3VycmVudFRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcygpIGNhY2hlcyBjYWxscyB0byBsaXN0U3RhY2tSZXNvdXJjZXMoKScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY2ZuU3RhY2sgPSBuZXcgRmFrZUNsb3VkZm9ybWF0aW9uU3RhY2soe1xuICAgIHN0YWNrTmFtZTogJ0NhY2hpbmdSb290JyxcbiAgICBzdGFja0lkOiAnU3RhY2tJZCcsXG4gIH0pO1xuICBDbG91ZEZvcm1hdGlvblN0YWNrLmxvb2t1cCA9IChhc3luYyAoX2NmbiwgX3N0YWNrTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgY2ZuU3RhY2sudGVtcGxhdGUgPSBhc3luYyAoKSA9PiAoe1xuICAgICAgUmVzb3VyY2VzOlxuICAgICAge1xuICAgICAgICBOZXN0ZWRTdGFja0E6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFRlbXBsYXRlVVJMOiAnaHR0cHM6Ly93d3cubWFnaWMtdXJsLmNvbScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29uZS1yZXNvdXJjZS1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgTmVzdGVkU3RhY2tCOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2Utc3RhY2submVzdGVkLnRlbXBsYXRlLmpzb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNmblN0YWNrO1xuICB9KTtcblxuICBjb25zdCByb290U3RhY2sgPSB0ZXN0U3RhY2soe1xuICAgIHN0YWNrTmFtZTogJ0NhY2hpbmdSb290JyxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIE5lc3RlZFN0YWNrQToge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgVGVtcGxhdGVVUkw6ICdodHRwczovL3d3dy5tYWdpYy11cmwuY29tJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLXJlc291cmNlLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBOZXN0ZWRTdGFja0I6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFRlbXBsYXRlVVJMOiAnaHR0cHM6Ly93d3cubWFnaWMtdXJsLmNvbScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29uZS1yZXNvdXJjZS1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoJ0NhY2hpbmdSb290JyxcbiAgICBzdGFja1N1bW1hcnlPZignTmVzdGVkU3RhY2tBJywgJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICdhcm46YXdzOmNsb3VkZm9ybWF0aW9uOmJlcm11ZGEtdHJpYW5nbGUtMTMzNzoxMjM0NTY3ODkwMTI6c3RhY2svb25lLXJlc291cmNlLXN0YWNrL2FiY2QnLFxuICAgICksXG4gICAgc3RhY2tTdW1tYXJ5T2YoJ05lc3RlZFN0YWNrQicsICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAnYXJuOmF3czpjbG91ZGZvcm1hdGlvbjpiZXJtdWRhLXRyaWFuZ2xlLTEzMzc6MTIzNDU2Nzg5MDEyOnN0YWNrL29uZS1yZXNvdXJjZS1zdGFjay9hYmNkJyxcbiAgICApLFxuICApO1xuXG4gIC8vIFdIRU5cbiAgYXdhaXQgZGVwbG95bWVudHMucmVhZEN1cnJlbnRUZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja3Mocm9vdFN0YWNrKTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChudW1iZXJPZlRpbWVzTGlzdFN0YWNrUmVzb3VyY2VzV2FzQ2FsbGVkKS50b0VxdWFsKDEpO1xufSk7XG5cbnRlc3QoJ3JlYWRDdXJyZW50VGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tzKCkgc3VjY2VzZnVsbHkgaWdub3JlcyBzdGFja3Mgd2l0aG91dCBtZXRhZGF0YScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY2ZuU3RhY2sgPSBuZXcgRmFrZUNsb3VkZm9ybWF0aW9uU3RhY2soe1xuICAgIHN0YWNrTmFtZTogJ01ldGFkYXRhUm9vdCcsXG4gICAgc3RhY2tJZDogJ1N0YWNrSWQnLFxuICB9KTtcbiAgQ2xvdWRGb3JtYXRpb25TdGFjay5sb29rdXAgPSAoYXN5bmMgKF8sIHN0YWNrTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgaWYgKHN0YWNrTmFtZSA9PT0gJ01ldGFkYXRhUm9vdCcpIHtcbiAgICAgIGNmblN0YWNrLnRlbXBsYXRlID0gYXN5bmMgKCkgPT4gKHtcbiAgICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgICAgV2l0aE1ldGFkYXRhOiB7XG4gICAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbmUtcmVzb3VyY2Utc3RhY2submVzdGVkLnRlbXBsYXRlLmpzb24nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgY2ZuU3RhY2sudGVtcGxhdGUgPSBhc3luYyAoKSA9PiAoe1xuICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICBTb21lUmVzb3VyY2U6IHtcbiAgICAgICAgICAgIFR5cGU6ICdBV1M6OlNvbWV0aGluZycsXG4gICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIFByb3BlcnR5OiAnb2xkLXZhbHVlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBjZm5TdGFjaztcbiAgfSk7XG5cbiAgY29uc3Qgcm9vdFN0YWNrID0gdGVzdFN0YWNrKHtcbiAgICBzdGFja05hbWU6ICdNZXRhZGF0YVJvb3QnLFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgV2l0aG91dE1ldGFkYXRhOiB7XG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgVGVtcGxhdGVVUkw6ICdodHRwczovL3d3dy5tYWdpYy11cmwuY29tJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIH0sXG4gICAgICAgIFdpdGhFbXB0eU1ldGFkYXRhOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICBXaXRoTWV0YWRhdGE6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFRlbXBsYXRlVVJMOiAnaHR0cHM6Ly93d3cubWFnaWMtdXJsLmNvbScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29uZS1yZXNvdXJjZS1zdGFjay5uZXN0ZWQudGVtcGxhdGUuanNvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoJ01ldGFkYXRhUm9vdCcsIHN0YWNrU3VtbWFyeU9mKCdXaXRoTWV0YWRhdGEnLCAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICdhcm46YXdzOmNsb3VkZm9ybWF0aW9uOmJlcm11ZGEtdHJpYW5nbGUtMTMzNzoxMjM0NTY3ODkwMTI6c3RhY2svb25lLXJlc291cmNlLXN0YWNrL2FiY2QnLFxuICApKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IGRlcGxveWVkVGVtcGxhdGUgPSBhd2FpdCBkZXBsb3ltZW50cy5yZWFkQ3VycmVudFRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcyhyb290U3RhY2spO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGRlcGxveWVkVGVtcGxhdGUpLnRvRXF1YWwoe1xuICAgIFJlc291cmNlczoge1xuICAgICAgV2l0aE1ldGFkYXRhOiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgU29tZVJlc291cmNlOiB7XG4gICAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nJyxcbiAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICBQcm9wZXJ0eTogJ29sZC12YWx1ZScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLXJlc291cmNlLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgZXhwZWN0KHJvb3RTdGFjay50ZW1wbGF0ZSkudG9FcXVhbCh7XG4gICAgUmVzb3VyY2VzOiB7XG4gICAgICBXaXRob3V0TWV0YWRhdGE6IHsgLy8gVW5jaGFuZ2VkXG4gICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIFdpdGhFbXB0eU1ldGFkYXRhOiB7IC8vIFVuY2hhbmdlZFxuICAgICAgICBUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgVGVtcGxhdGVVUkw6ICdodHRwczovL3d3dy5tYWdpYy11cmwuY29tJyxcbiAgICAgICAgfSxcbiAgICAgICAgTWV0YWRhdGE6IHt9LFxuICAgICAgfSxcbiAgICAgIFdpdGhNZXRhZGF0YTogeyAvLyBDaGFuZ2VkXG4gICAgICAgIFR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBUZW1wbGF0ZVVSTDogJ2h0dHBzOi8vd3d3Lm1hZ2ljLXVybC5jb20nLFxuICAgICAgICAgIE5lc3RlZFRlbXBsYXRlOiB7XG4gICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgU29tZVJlc291cmNlOiB7XG4gICAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nJyxcbiAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICBQcm9wZXJ0eTogJ25ldy12YWx1ZScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb25lLXJlc291cmNlLXN0YWNrLm5lc3RlZC50ZW1wbGF0ZS5qc29uJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG59KTtcblxuZnVuY3Rpb24gcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoc3RhY2tOYW1lOiBzdHJpbmcsIC4uLml0ZW1zOiBDbG91ZEZvcm1hdGlvbi5TdGFja1Jlc291cmNlU3VtbWFyeVtdKSB7XG4gIGlmICghY3VycmVudENmblN0YWNrUmVzb3VyY2VzW3N0YWNrTmFtZV0pIHtcbiAgICBjdXJyZW50Q2ZuU3RhY2tSZXNvdXJjZXNbc3RhY2tOYW1lXSA9IFtdO1xuICB9XG5cbiAgY3VycmVudENmblN0YWNrUmVzb3VyY2VzW3N0YWNrTmFtZV0ucHVzaCguLi5pdGVtcyk7XG59XG5cbmZ1bmN0aW9uIHN0YWNrU3VtbWFyeU9mKGxvZ2ljYWxJZDogc3RyaW5nLCByZXNvdXJjZVR5cGU6IHN0cmluZywgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmcpOiBDbG91ZEZvcm1hdGlvbi5TdGFja1Jlc291cmNlU3VtbWFyeSB7XG4gIHJldHVybiB7XG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGxvZ2ljYWxJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICBSZXNvdXJjZVR5cGU6IHJlc291cmNlVHlwZSxcbiAgICBSZXNvdXJjZVN0YXR1czogJ0NSRUFURV9DT01QTEVURScsXG4gICAgTGFzdFVwZGF0ZWRUaW1lc3RhbXA6IG5ldyBEYXRlKCksXG4gIH07XG59XG4iXX0=
|