UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

114 lines 22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadCurrentTemplate = exports.flattenNestedStackNames = exports.loadCurrentTemplateWithNestedStacks = void 0; const path = require("path"); const fs = require("fs-extra"); const evaluate_cloudformation_template_1 = require("./evaluate-cloudformation-template"); const cloudformation_1 = require("./util/cloudformation"); /** * Reads the currently deployed template from CloudFormation and adds a * property, `NestedTemplate`, to any nested stacks that appear in either * the deployed template or the newly synthesized template. `NestedTemplate` * is populated with contents of the nested template by mutating the * `template` property of `rootStackArtifact`. This is done for all * nested stack resources to arbitrary depths. */ async function loadCurrentTemplateWithNestedStacks(rootStackArtifact, sdk, retrieveProcessedTemplate = false) { const deployedTemplate = await loadCurrentTemplate(rootStackArtifact, sdk, retrieveProcessedTemplate); const nestedStackNames = await addNestedTemplatesToGeneratedAndDeployedStacks(rootStackArtifact, sdk, { generatedTemplate: rootStackArtifact.template, deployedTemplate: deployedTemplate, deployedStackName: rootStackArtifact.stackName, }); return { deployedTemplate, nestedStackNames, }; } exports.loadCurrentTemplateWithNestedStacks = loadCurrentTemplateWithNestedStacks; function flattenNestedStackNames(nestedStackNames) { const nameList = []; for (const key of Object.keys(nestedStackNames)) { nameList.push(key); if (Object.keys(nestedStackNames[key].nestedChildStackNames).length !== 0) { flattenNestedStacksHelper(nestedStackNames[key].nestedChildStackNames, nameList); } } return nameList; } exports.flattenNestedStackNames = flattenNestedStackNames; /** * Returns the currently deployed template from CloudFormation that corresponds to `stackArtifact`. */ async function loadCurrentTemplate(stackArtifact, sdk, retrieveProcessedTemplate = false) { return loadCurrentStackTemplate(stackArtifact.stackName, sdk, retrieveProcessedTemplate); } exports.loadCurrentTemplate = loadCurrentTemplate; async function loadCurrentStackTemplate(stackName, sdk, retrieveProcessedTemplate = false) { const cfn = sdk.cloudFormation(); const stack = await cloudformation_1.CloudFormationStack.lookup(cfn, stackName, retrieveProcessedTemplate); return stack.template(); } async function addNestedTemplatesToGeneratedAndDeployedStacks(rootStackArtifact, sdk, parentTemplates) { const listStackResources = parentTemplates.deployedStackName ? new evaluate_cloudformation_template_1.LazyListStackResources(sdk, parentTemplates.deployedStackName) : undefined; const nestedStackNames = {}; for (const [nestedStackLogicalId, generatedNestedStackResource] of Object.entries(parentTemplates.generatedTemplate.Resources ?? {})) { if (!isCdkManagedNestedStack(generatedNestedStackResource)) { continue; } const assetPath = generatedNestedStackResource.Metadata['aws:asset:path']; const nestedStackTemplates = await getNestedStackTemplates(rootStackArtifact, assetPath, nestedStackLogicalId, listStackResources, sdk); generatedNestedStackResource.Properties.NestedTemplate = nestedStackTemplates.generatedTemplate; const deployedParentTemplate = parentTemplates.deployedTemplate; deployedParentTemplate.Resources = deployedParentTemplate.Resources ?? {}; const deployedNestedStackResource = deployedParentTemplate.Resources[nestedStackLogicalId] ?? {}; deployedParentTemplate.Resources[nestedStackLogicalId] = deployedNestedStackResource; deployedNestedStackResource.Type = deployedNestedStackResource.Type ?? 'AWS::CloudFormation::Stack'; deployedNestedStackResource.Properties = deployedNestedStackResource.Properties ?? {}; deployedNestedStackResource.Properties.NestedTemplate = nestedStackTemplates.deployedTemplate; nestedStackNames[nestedStackLogicalId] = { nestedStackPhysicalName: nestedStackTemplates.deployedStackName, nestedChildStackNames: await addNestedTemplatesToGeneratedAndDeployedStacks(rootStackArtifact, sdk, nestedStackTemplates), }; } return nestedStackNames; } async function getNestedStackTemplates(rootStackArtifact, nestedTemplateAssetPath, nestedStackLogicalId, listStackResources, sdk) { const nestedTemplatePath = path.join(rootStackArtifact.assembly.directory, nestedTemplateAssetPath); // CFN generates the nested stack name in the form `ParentStackName-NestedStackLogicalID-SomeHashWeCan'tCompute, // the arn is of the form: arn:aws:cloudformation:region:123456789012:stack/NestedStackName/AnotherHashWeDon'tNeed // so we get the ARN and manually extract the name. const nestedStackArn = await getNestedStackArn(nestedStackLogicalId, listStackResources); const deployedStackName = nestedStackArn?.slice(nestedStackArn.indexOf('/') + 1, nestedStackArn.lastIndexOf('/')); return { generatedTemplate: JSON.parse(fs.readFileSync(nestedTemplatePath, 'utf-8')), deployedTemplate: deployedStackName ? await loadCurrentStackTemplate(deployedStackName, sdk) : {}, deployedStackName, }; } async function getNestedStackArn(nestedStackLogicalId, listStackResources) { try { const stackResources = await listStackResources?.listStackResources(); return stackResources?.find(sr => sr.LogicalResourceId === nestedStackLogicalId)?.PhysicalResourceId; } catch (e) { if (e.message.startsWith('Stack with id ') && e.message.endsWith(' does not exist')) { return; } throw e; } } function isCdkManagedNestedStack(stackResource) { return stackResource.Type === 'AWS::CloudFormation::Stack' && stackResource.Metadata && stackResource.Metadata['aws:asset:path']; } function flattenNestedStacksHelper(nestedStackNames, nameList) { for (const key of Object.keys(nestedStackNames)) { nameList.push(key); if (Object.keys(nestedStackNames[key].nestedChildStackNames).length !== 0) { flattenNestedStacksHelper(nestedStackNames[key].nestedChildStackNames, nameList); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVzdGVkLXN0YWNrLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJuZXN0ZWQtc3RhY2staGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBNkI7QUFFN0IsK0JBQStCO0FBRS9CLHlGQUFnRztBQUNoRywwREFBc0U7QUFpQnRFOzs7Ozs7O0dBT0c7QUFDSSxLQUFLLFVBQVUsbUNBQW1DLENBQ3ZELGlCQUFvRCxFQUFFLEdBQVMsRUFDL0QsNEJBQXFDLEtBQUs7SUFFMUMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLG1CQUFtQixDQUFDLGlCQUFpQixFQUFFLEdBQUcsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0lBQ3RHLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSw4Q0FBOEMsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUU7UUFDcEcsaUJBQWlCLEVBQUUsaUJBQWlCLENBQUMsUUFBUTtRQUM3QyxnQkFBZ0IsRUFBRSxnQkFBZ0I7UUFDbEMsaUJBQWlCLEVBQUUsaUJBQWlCLENBQUMsU0FBUztLQUMvQyxDQUFDLENBQUM7SUFFSCxPQUFPO1FBQ0wsZ0JBQWdCO1FBQ2hCLGdCQUFnQjtLQUNqQixDQUFDO0FBQ0osQ0FBQztBQWZELGtGQWVDO0FBRUQsU0FBZ0IsdUJBQXVCLENBQUMsZ0JBQXNFO0lBQzVHLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNwQixLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtRQUMvQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRW5CLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDekUseUJBQXlCLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMscUJBQXFCLEVBQUUsUUFBUSxD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QU0sQ0FBQyxDQUFDO0tBQ1Q7QUFDSCxDQUFDO0FBRUQsU0FBUyx1QkFBdUIsQ0FBQyxhQUFrQjtJQUNqRCxPQUFPLGFBQWEsQ0FBQyxJQUFJLEtBQUssNEJBQTRCLElBQUksYUFBYSxDQUFDLFFBQVEsSUFBSSxhQUFhLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDbkksQ0FBQztBQUVELFNBQVMseUJBQXlCLENBQUMsZ0JBQTJELEVBQUUsUUFBa0I7SUFDaEgsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUU7UUFDL0MsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVuQixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQ3pFLHlCQUF5QixDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLHFCQUFxQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ2xGO0tBQ0Y7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyBJU0RLIH0gZnJvbSAnLi9hd3MtYXV0aCc7XG5pbXBvcnQgeyBMYXp5TGlzdFN0YWNrUmVzb3VyY2VzLCBMaXN0U3RhY2tSZXNvdXJjZXMgfSBmcm9tICcuL2V2YWx1YXRlLWNsb3VkZm9ybWF0aW9uLXRlbXBsYXRlJztcbmltcG9ydCB7IENsb3VkRm9ybWF0aW9uU3RhY2ssIFRlbXBsYXRlIH0gZnJvbSAnLi91dGlsL2Nsb3VkZm9ybWF0aW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja05hbWVzIHtcbiAgcmVhZG9ubHkgZGVwbG95ZWRUZW1wbGF0ZTogVGVtcGxhdGU7XG4gIHJlYWRvbmx5IG5lc3RlZFN0YWNrTmFtZXM6IHsgW25lc3RlZFN0YWNrTG9naWNhbElkOiBzdHJpbmddOiBOZXN0ZWRTdGFja05hbWVzIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmVzdGVkU3RhY2tOYW1lcyB7XG4gIHJlYWRvbmx5IG5lc3RlZFN0YWNrUGh5c2ljYWxOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IG5lc3RlZENoaWxkU3RhY2tOYW1lczogeyBbbG9naWNhbElkOiBzdHJpbmddOiBOZXN0ZWRTdGFja05hbWVzIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVtcGxhdGVXaXRoTmVzdGVkU3RhY2tDb3VudCB7XG4gIHJlYWRvbmx5IGRlcGxveWVkVGVtcGxhdGU6IFRlbXBsYXRlO1xuICByZWFkb25seSBuZXN0ZWRTdGFja0NvdW50OiBudW1iZXI7XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGN1cnJlbnRseSBkZXBsb3llZCB0ZW1wbGF0ZSBmcm9tIENsb3VkRm9ybWF0aW9uIGFuZCBhZGRzIGFcbiAqIHByb3BlcnR5LCBgTmVzdGVkVGVtcGxhdGVgLCB0byBhbnkgbmVzdGVkIHN0YWNrcyB0aGF0IGFwcGVhciBpbiBlaXRoZXJcbiAqIHRoZSBkZXBsb3llZCB0ZW1wbGF0ZSBvciB0aGUgbmV3bHkgc3ludGhlc2l6ZWQgdGVtcGxhdGUuIGBOZXN0ZWRUZW1wbGF0ZWBcbiAqIGlzIHBvcHVsYXRlZCB3aXRoIGNvbnRlbnRzIG9mIHRoZSBuZXN0ZWQgdGVtcGxhdGUgYnkgbXV0YXRpbmcgdGhlXG4gKiBgdGVtcGxhdGVgIHByb3BlcnR5IG9mIGByb290U3RhY2tBcnRpZmFjdGAuIFRoaXMgaXMgZG9uZSBmb3IgYWxsXG4gKiBuZXN0ZWQgc3RhY2sgcmVzb3VyY2VzIHRvIGFyYml0cmFyeSBkZXB0aHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkQ3VycmVudFRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcyhcbiAgcm9vdFN0YWNrQXJ0aWZhY3Q6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCwgc2RrOiBJU0RLLFxuICByZXRyaWV2ZVByb2Nlc3NlZFRlbXBsYXRlOiBib29sZWFuID0gZmFsc2UsXG4pOiBQcm9taXNlPFRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrTmFtZXM+IHtcbiAgY29uc3QgZGVwbG95ZWRUZW1wbGF0ZSA9IGF3YWl0IGxvYWRDdXJyZW50VGVtcGxhdGUocm9vdFN0YWNrQXJ0aWZhY3QsIHNkaywgcmV0cmlldmVQcm9jZXNzZWRUZW1wbGF0ZSk7XG4gIGNvbnN0IG5lc3RlZFN0YWNrTmFtZXMgPSBhd2FpdCBhZGROZXN0ZWRUZW1wbGF0ZXNUb0dlbmVyYXRlZEFuZERlcGxveWVkU3RhY2tzKHJvb3RTdGFja0FydGlmYWN0LCBzZGssIHtcbiAgICBnZW5lcmF0ZWRUZW1wbGF0ZTogcm9vdFN0YWNrQXJ0aWZhY3QudGVtcGxhdGUsXG4gICAgZGVwbG95ZWRUZW1wbGF0ZTogZGVwbG95ZWRUZW1wbGF0ZSxcbiAgICBkZXBsb3llZFN0YWNrTmFtZTogcm9vdFN0YWNrQXJ0aWZhY3Quc3RhY2tOYW1lLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIGRlcGxveWVkVGVtcGxhdGUsXG4gICAgbmVzdGVkU3RhY2tOYW1lcyxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW5OZXN0ZWRTdGFja05hbWVzKG5lc3RlZFN0YWNrTmFtZXM6IHsgW25lc3RlZFN0YWNrTG9naWNhbElkOiBzdHJpbmddOiBOZXN0ZWRTdGFja05hbWVzIH0pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG5hbWVMaXN0ID0gW107XG4gIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG5lc3RlZFN0YWNrTmFtZXMpKSB7XG4gICAgbmFtZUxpc3QucHVzaChrZXkpO1xuXG4gICAgaWYgKE9iamVjdC5rZXlzKG5lc3RlZFN0YWNrTmFtZXNba2V5XS5uZXN0ZWRDaGlsZFN0YWNrTmFtZXMpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgZmxhdHRlbk5lc3RlZFN0YWNrc0hlbHBlcihuZXN0ZWRTdGFja05hbWVzW2tleV0ubmVzdGVkQ2hpbGRTdGFja05hbWVzLCBuYW1lTGlzdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWVMaXN0O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGN1cnJlbnRseSBkZXBsb3llZCB0ZW1wbGF0ZSBmcm9tIENsb3VkRm9ybWF0aW9uIHRoYXQgY29ycmVzcG9uZHMgdG8gYHN0YWNrQXJ0aWZhY3RgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZEN1cnJlbnRUZW1wbGF0ZShcbiAgc3RhY2tBcnRpZmFjdDogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LCBzZGs6IElTREssXG4gIHJldHJpZXZlUHJvY2Vzc2VkVGVtcGxhdGU6IGJvb2xlYW4gPSBmYWxzZSxcbik6IFByb21pc2U8VGVtcGxhdGU+IHtcbiAgcmV0dXJuIGxvYWRDdXJyZW50U3RhY2tUZW1wbGF0ZShzdGFja0FydGlmYWN0LnN0YWNrTmFtZSwgc2RrLCByZXRyaWV2ZVByb2Nlc3NlZFRlbXBsYXRlKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbG9hZEN1cnJlbnRTdGFja1RlbXBsYXRlKFxuICBzdGFja05hbWU6IHN0cmluZywgc2RrOiBJU0RLLCByZXRyaWV2ZVByb2Nlc3NlZFRlbXBsYXRlOiBib29sZWFuID0gZmFsc2UsXG4pIDogUHJvbWlzZTxUZW1wbGF0ZT4ge1xuICBjb25zdCBjZm4gPSBzZGsuY2xvdWRGb3JtYXRpb24oKTtcbiAgY29uc3Qgc3RhY2sgPSBhd2FpdCBDbG91ZEZvcm1hdGlvblN0YWNrLmxvb2t1cChjZm4sIHN0YWNrTmFtZSwgcmV0cmlldmVQcm9jZXNzZWRUZW1wbGF0ZSk7XG4gIHJldHVybiBzdGFjay50ZW1wbGF0ZSgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBhZGROZXN0ZWRUZW1wbGF0ZXNUb0dlbmVyYXRlZEFuZERlcGxveWVkU3RhY2tzKFxuICByb290U3RhY2tBcnRpZmFjdDogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LFxuICBzZGs6IElTREssXG4gIHBhcmVudFRlbXBsYXRlczogU3RhY2tUZW1wbGF0ZXMsXG4pOiBQcm9taXNlPHsgW25lc3RlZFN0YWNrTG9naWNhbElkOiBzdHJpbmddOiBOZXN0ZWRTdGFja05hbWVzIH0+IHtcbiAgY29uc3QgbGlzdFN0YWNrUmVzb3VyY2VzID0gcGFyZW50VGVtcGxhdGVzLmRlcGxveWVkU3RhY2tOYW1lID8gbmV3IExhenlMaXN0U3RhY2tSZXNvdXJjZXMoc2RrLCBwYXJlbnRUZW1wbGF0ZXMuZGVwbG95ZWRTdGFja05hbWUpIDogdW5kZWZpbmVkO1xuICBjb25zdCBuZXN0ZWRTdGFja05hbWVzOiB7IFtuZXN0ZWRTdGFja0xvZ2ljYWxJZDogc3RyaW5nXTogTmVzdGVkU3RhY2tOYW1lcyB9ID0ge307XG4gIGZvciAoY29uc3QgW25lc3RlZFN0YWNrTG9naWNhbElkLCBnZW5lcmF0ZWROZXN0ZWRTdGFja1Jlc291cmNlXSBvZiBPYmplY3QuZW50cmllcyhwYXJlbnRUZW1wbGF0ZXMuZ2VuZXJhdGVkVGVtcGxhdGUuUmVzb3VyY2VzID8/IHt9KSkge1xuICAgIGlmICghaXNDZGtNYW5hZ2VkTmVzdGVkU3RhY2soZ2VuZXJhdGVkTmVzdGVkU3RhY2tSZXNvdXJjZSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGFzc2V0UGF0aCA9IGdlbmVyYXRlZE5lc3RlZFN0YWNrUmVzb3VyY2UuTWV0YWRhdGFbJ2F3czphc3NldDpwYXRoJ107XG4gICAgY29uc3QgbmVzdGVkU3RhY2tUZW1wbGF0ZXMgPSBhd2FpdCBnZXROZXN0ZWRTdGFja1RlbXBsYXRlcyhyb290U3RhY2tBcnRpZmFjdCwgYXNzZXRQYXRoLCBuZXN0ZWRTdGFja0xvZ2ljYWxJZCwgbGlzdFN0YWNrUmVzb3VyY2VzLCBzZGspO1xuXG4gICAgZ2VuZXJhdGVkTmVzdGVkU3RhY2tSZXNvdXJjZS5Qcm9wZXJ0aWVzLk5lc3RlZFRlbXBsYXRlID0gbmVzdGVkU3RhY2tUZW1wbGF0ZXMuZ2VuZXJhdGVkVGVtcGxhdGU7XG5cbiAgICBjb25zdCBkZXBsb3llZFBhcmVudFRlbXBsYXRlID0gcGFyZW50VGVtcGxhdGVzLmRlcGxveWVkVGVtcGxhdGU7XG4gICAgZGVwbG95ZWRQYXJlbnRUZW1wbGF0ZS5SZXNvdXJjZXMgPSBkZXBsb3llZFBhcmVudFRlbXBsYXRlLlJlc291cmNlcyA/PyB7fTtcbiAgICBjb25zdCBkZXBsb3llZE5lc3RlZFN0YWNrUmVzb3VyY2UgPSBkZXBsb3llZFBhcmVudFRlbXBsYXRlLlJlc291cmNlc1tuZXN0ZWRTdGFja0xvZ2ljYWxJZF0gPz8ge307XG4gICAgZGVwbG95ZWRQYXJlbnRUZW1wbGF0ZS5SZXNvdXJjZXNbbmVzdGVkU3RhY2tMb2dpY2FsSWRdID0gZGVwbG95ZWROZXN0ZWRTdGFja1Jlc291cmNlO1xuICAgIGRlcGxveWVkTmVzdGVkU3RhY2tSZXNvdXJjZS5UeXBlID0gZGVwbG95ZWROZXN0ZWRTdGFja1Jlc291cmNlLlR5cGUgPz8gJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJztcbiAgICBkZXBsb3llZE5lc3RlZFN0YWNrUmVzb3VyY2UuUHJvcGVydGllcyA9IGRlcGxveWVkTmVzdGVkU3RhY2tSZXNvdXJjZS5Qcm9wZXJ0aWVzID8/IHt9O1xuICAgIGRlcGxveWVkTmVzdGVkU3RhY2tSZXNvdXJjZS5Qcm9wZXJ0aWVzLk5lc3RlZFRlbXBsYXRlID0gbmVzdGVkU3RhY2tUZW1wbGF0ZXMuZGVwbG95ZWRUZW1wbGF0ZTtcblxuICAgIG5lc3RlZFN0YWNrTmFtZXNbbmVzdGVkU3RhY2tMb2dpY2FsSWRdID0ge1xuICAgICAgbmVzdGVkU3RhY2tQaHlzaWNhbE5hbWU6IG5lc3RlZFN0YWNrVGVtcGxhdGVzLmRlcGxveWVkU3RhY2tOYW1lLFxuICAgICAgbmVzdGVkQ2hpbGRTdGFja05hbWVzOiBhd2FpdCBhZGROZXN0ZWRUZW1wbGF0ZXNUb0dlbmVyYXRlZEFuZERlcGxveWVkU3RhY2tzKFxuICAgICAgICByb290U3RhY2tBcnRpZmFjdCxcbiAgICAgICAgc2RrLFxuICAgICAgICBuZXN0ZWRTdGFja1RlbXBsYXRlcyxcbiAgICAgICksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBuZXN0ZWRTdGFja05hbWVzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXROZXN0ZWRTdGFja1RlbXBsYXRlcyhcbiAgcm9vdFN0YWNrQXJ0aWZhY3Q6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCwgbmVzdGVkVGVtcGxhdGVBc3NldFBhdGg6IHN0cmluZywgbmVzdGVkU3RhY2tMb2dpY2FsSWQ6IHN0cmluZyxcbiAgbGlzdFN0YWNrUmVzb3VyY2VzOiBMaXN0U3RhY2tSZXNvdXJjZXMgfCB1bmRlZmluZWQsIHNkazogSVNESyxcbik6IFByb21pc2U8U3RhY2tUZW1wbGF0ZXM+IHtcbiAgY29uc3QgbmVzdGVkVGVtcGxhdGVQYXRoID0gcGF0aC5qb2luKHJvb3RTdGFja0FydGlmYWN0LmFzc2VtYmx5LmRpcmVjdG9yeSwgbmVzdGVkVGVtcGxhdGVBc3NldFBhdGgpO1xuXG4gIC8vIENGTiBnZW5lcmF0ZXMgdGhlIG5lc3RlZCBzdGFjayBuYW1lIGluIHRoZSBmb3JtIGBQYXJlbnRTdGFja05hbWUtTmVzdGVkU3RhY2tMb2dpY2FsSUQtU29tZUhhc2hXZUNhbid0Q29tcHV0ZSxcbiAgLy8gdGhlIGFybiBpcyBvZiB0aGUgZm9ybTogYXJuOmF3czpjbG91ZGZvcm1hdGlvbjpyZWdpb246MTIzNDU2Nzg5MDEyOnN0YWNrL05lc3RlZFN0YWNrTmFtZS9Bbm90aGVySGFzaFdlRG9uJ3ROZWVkXG4gIC8vIHNvIHdlIGdldCB0aGUgQVJOIGFuZCBtYW51YWxseSBleHRyYWN0IHRoZSBuYW1lLlxuICBjb25zdCBuZXN0ZWRTdGFja0FybiA9IGF3YWl0IGdldE5lc3RlZFN0YWNrQXJuKG5lc3RlZFN0YWNrTG9naWNhbElkLCBsaXN0U3RhY2tSZXNvdXJjZXMpO1xuICBjb25zdCBkZXBsb3llZFN0YWNrTmFtZSA9IG5lc3RlZFN0YWNrQXJuPy5zbGljZShuZXN0ZWRTdGFja0Fybi5pbmRleE9mKCcvJykgKyAxLCBuZXN0ZWRTdGFja0Fybi5sYXN0SW5kZXhPZignLycpKTtcblxuICByZXR1cm4ge1xuICAgIGdlbmVyYXRlZFRlbXBsYXRlOiBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhuZXN0ZWRUZW1wbGF0ZVBhdGgsICd1dGYtOCcpKSxcbiAgICBkZXBsb3llZFRlbXBsYXRlOiBkZXBsb3llZFN0YWNrTmFtZVxuICAgICAgPyBhd2FpdCBsb2FkQ3VycmVudFN0YWNrVGVtcGxhdGUoZGVwbG95ZWRTdGFja05hbWUsIHNkaylcbiAgICAgIDoge30sXG4gICAgZGVwbG95ZWRTdGFja05hbWUsXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldE5lc3RlZFN0YWNrQXJuKFxuICBuZXN0ZWRTdGFja0xvZ2ljYWxJZDogc3RyaW5nLCBsaXN0U3RhY2tSZXNvdXJjZXM/OiBMaXN0U3RhY2tSZXNvdXJjZXMsXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHN0YWNrUmVzb3VyY2VzID0gYXdhaXQgbGlzdFN0YWNrUmVzb3VyY2VzPy5saXN0U3RhY2tSZXNvdXJjZXMoKTtcbiAgICByZXR1cm4gc3RhY2tSZXNvdXJjZXM/LmZpbmQoc3IgPT4gc3IuTG9naWNhbFJlc291cmNlSWQgPT09IG5lc3RlZFN0YWNrTG9naWNhbElkKT8uUGh5c2ljYWxSZXNvdXJjZUlkO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICBpZiAoZS5tZXNzYWdlLnN0YXJ0c1dpdGgoJ1N0YWNrIHdpdGggaWQgJykgJiYgZS5tZXNzYWdlLmVuZHNXaXRoKCcgZG9lcyBub3QgZXhpc3QnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2RrTWFuYWdlZE5lc3RlZFN0YWNrKHN0YWNrUmVzb3VyY2U6IGFueSk6IHN0YWNrUmVzb3VyY2UgaXMgTmVzdGVkU3RhY2tSZXNvdXJjZSB7XG4gIHJldHVybiBzdGFja1Jlc291cmNlLlR5cGUgPT09ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycgJiYgc3RhY2tSZXNvdXJjZS5NZXRhZGF0YSAmJiBzdGFja1Jlc291cmNlLk1ldGFkYXRhWydhd3M6YXNzZXQ6cGF0aCddO1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuTmVzdGVkU3RhY2tzSGVscGVyKG5lc3RlZFN0YWNrTmFtZXM6IHsgW2xvZ2ljYWxJZDogc3RyaW5nXTogTmVzdGVkU3RhY2tOYW1lcyB9LCBuYW1lTGlzdDogc3RyaW5nW10pIHtcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMobmVzdGVkU3RhY2tOYW1lcykpIHtcbiAgICBuYW1lTGlzdC5wdXNoKGtleSk7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMobmVzdGVkU3RhY2tOYW1lc1trZXldLm5lc3RlZENoaWxkU3RhY2tOYW1lcykubGVuZ3RoICE9PSAwKSB7XG4gICAgICBmbGF0dGVuTmVzdGVkU3RhY2tzSGVscGVyKG5lc3RlZFN0YWNrTmFtZXNba2V5XS5uZXN0ZWRDaGlsZFN0YWNrTmFtZXMsIG5hbWVMaXN0KTtcbiAgICB9XG4gIH1cbn1cblxuaW50ZXJmYWNlIFN0YWNrVGVtcGxhdGVzIHtcbiAgcmVhZG9ubHkgZ2VuZXJhdGVkVGVtcGxhdGU6IGFueTtcbiAgcmVhZG9ubHkgZGVwbG95ZWRUZW1wbGF0ZTogYW55O1xuICByZWFkb25seSBkZXBsb3llZFN0YWNrTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG5pbnRlcmZhY2UgTmVzdGVkU3RhY2tSZXNvdXJjZSB7XG4gIHJlYWRvbmx5IE1ldGFkYXRhOiB7ICdhd3M6YXNzZXQ6cGF0aCc6IHN0cmluZyB9O1xuICByZWFkb25seSBQcm9wZXJ0aWVzOiBhbnk7XG59XG4iXX0=