UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

2 lines (1 loc) 16.3 kB
"use strict";var _a;Object.defineProperty(exports,"__esModule",{value:!0}),exports.CfnInclude=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var constructs_1=()=>{var tmp=require("constructs");return constructs_1=()=>tmp,tmp},cfn_type_to_l1_mapping=()=>{var tmp=require("./cfn-type-to-l1-mapping");return cfn_type_to_l1_mapping=()=>tmp,tmp},futils=()=>{var tmp=require("./file-utils");return futils=()=>tmp,tmp},core=()=>{var tmp=require("../../core");return core=()=>tmp,tmp},cfn_parse=()=>{var tmp=require("../../core/lib/helpers-internal");return cfn_parse=()=>tmp,tmp};class CfnInclude extends core().CfnElement{constructor(scope,id,props){super(scope,id),this.conditions={},this.resources={},this.parameters={},this.mappings={},this.rules={},this.hooks={},this.outputs={},this.nestedStacks={};try{jsiiDeprecationWarnings().aws_cdk_lib_cloudformation_include_CfnIncludeProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,CfnInclude),error}this.allowCyclicalReferences=props.allowCyclicalReferences??!1,this.logicalIdToPlaceholderMap=new Map,this.parametersToReplace=props.parameters||{},this.template=futils().readYamlSync(props.templateFile),this.preserveLogicalIds=props.preserveLogicalIds??!0;for(const logicalId of Object.keys(this.parametersToReplace))if(!(logicalId in(this.template.Parameters||{})))throw new Error(`Parameter with logical ID '${logicalId}' was not found in the template`);this.mappingsScope=new(constructs_1()).Construct(this,"$Mappings");for(const mappingName of Object.keys(this.template.Mappings||{}))this.createMapping(mappingName);for(const logicalId of Object.keys(this.template.Parameters||{}))this.createParameter(logicalId);this.conditionsScope=new(constructs_1()).Construct(this,"$Conditions");for(const conditionName of Object.keys(this.template.Conditions||{}))this.getOrCreateCondition(conditionName);this.rulesScope=new(constructs_1()).Construct(this,"$Rules");for(const ruleName of Object.keys(this.template.Rules||{}))this.createRule(ruleName);this.nestedStacksToInclude=props.loadNestedStacks||{};for(const logicalId of Object.keys(this.template.Resources||{}))this.getOrCreateResource(logicalId);for(const nestedStackId of Object.keys(props.loadNestedStacks||{}))if(!(nestedStackId in this.resources))throw new Error(`Nested Stack with logical ID '${nestedStackId}' was not found in the template`);this.hooksScope=new(constructs_1()).Construct(this,"$Hooks");for(const hookName of Object.keys(this.template.Hooks||{}))this.createHook(hookName);const outputScope=new(constructs_1()).Construct(this,"$Outputs");for(const logicalId of Object.keys(this.template.Outputs||{}))this.createOutput(logicalId,outputScope)}getResource(logicalId){const ret=this.resources[logicalId];if(!ret)throw new Error(`Resource with logical ID '${logicalId}' was not found in the template`);return ret}getCondition(conditionName){const ret=this.conditions[conditionName];if(!ret)throw new Error(`Condition with name '${conditionName}' was not found in the template`);return ret}getParameter(parameterName){const ret=this.parameters[parameterName];if(!ret)throw new Error(`Parameter with name '${parameterName}' was not found in the template`);return ret}getMapping(mappingName){const ret=this.mappings[mappingName];if(!ret)throw new Error(`Mapping with name '${mappingName}' was not found in the template`);return ret}getOutput(logicalId){const ret=this.outputs[logicalId];if(!ret)throw new Error(`Output with logical ID '${logicalId}' was not found in the template`);return ret}getRule(ruleName){const ret=this.rules[ruleName];if(!ret)throw new Error(`Rule with name '${ruleName}' was not found in the template`);return ret}getHook(hookLogicalId){const ret=this.hooks[hookLogicalId];if(!ret)throw new Error(`Hook with logical ID '${hookLogicalId}' was not found in the template`);return ret}getNestedStack(logicalId){if(!this.nestedStacks[logicalId])throw this.template.Resources[logicalId]?this.template.Resources[logicalId].Type!=="AWS::CloudFormation::Stack"?new Error(`Resource with logical ID '${logicalId}' is not a CloudFormation Stack`):new Error(`Nested Stack '${logicalId}' was not included in the parent template. To retrieve an included nested stack, it must be specified either in the \`loadNestedStacks\` property, or through the \`loadNestedStack\` method`):new Error(`Nested Stack with logical ID '${logicalId}' was not found in the template`);return this.nestedStacks[logicalId]}loadNestedStack(logicalId,nestedStackProps){try{jsiiDeprecationWarnings().aws_cdk_lib_cloudformation_include_CfnIncludeProps(nestedStackProps)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.loadNestedStack),error}if(logicalId in this.nestedStacks)throw new Error(`Nested Stack '${logicalId}' was already included in its parent template`);const cfnStack=this.resources[logicalId];if(!cfnStack)throw new Error(`Nested Stack with logical ID '${logicalId}' was not found in the template`);if(cfnStack instanceof core().CfnStack)return this.node.tryRemoveChild(logicalId),delete this.resources[logicalId],this.nestedStacksToInclude[logicalId]=nestedStackProps,this.getOrCreateResource(logicalId),this.nestedStacks[logicalId];throw new Error(`Nested Stack with logical ID '${logicalId}' is not an AWS::CloudFormation::Stack resource`)}_toCloudFormation(){const ret={};for(const section of Object.keys(this.template)){const self=this,finder={findResource(lId){return self.resources[lId]},findRefTarget(elementName){return self.resources[elementName]??self.parameters[elementName]},findCondition(conditionName){return self.conditions[conditionName]},findMapping(mappingName){return self.mappings[mappingName]}},cfnParser=new(cfn_parse()).CfnParser({finder,parameters:this.parametersToReplace});switch(section){case"Conditions":case"Mappings":case"Resources":case"Parameters":case"Rules":case"Hooks":case"Outputs":break;default:ret[section]=cfnParser.parseValue(this.template[section])}}return ret}createMapping(mappingName){const cfnParser=new(cfn_parse()).CfnParser({finder:{findCondition(){throw new Error("Referring to Conditions in Mapping definitions is not allowed")},findMapping(){throw new Error("Referring to other Mappings in Mapping definitions is not allowed")},findRefTarget(){throw new Error("Using Ref expressions in Mapping definitions is not allowed")},findResource(){throw new Error("Using GetAtt expressions in Mapping definitions is not allowed")}},parameters:{}}),cfnMapping=new(core()).CfnMapping(this.mappingsScope,mappingName,{mapping:cfnParser.parseValue(this.template.Mappings[mappingName])});this.mappings[mappingName]=cfnMapping,this.overrideLogicalIdIfNeeded(cfnMapping,mappingName)}createParameter(logicalId){if(logicalId in this.parametersToReplace)return;const expression=new(cfn_parse()).CfnParser({finder:{findResource(){throw new Error("Using GetAtt expressions in Parameter definitions is not allowed")},findRefTarget(){throw new Error("Using Ref expressions in Parameter definitions is not allowed")},findCondition(){throw new Error("Referring to Conditions in Parameter definitions is not allowed")},findMapping(){throw new Error("Referring to Mappings in Parameter definitions is not allowed")}},parameters:{}}).parseValue(this.template.Parameters[logicalId]),cfnParameter=new(core()).CfnParameter(this,logicalId,{type:expression.Type,default:expression.Default,allowedPattern:expression.AllowedPattern,allowedValues:expression.AllowedValues,constraintDescription:expression.ConstraintDescription,description:expression.Description,maxLength:expression.MaxLength,maxValue:expression.MaxValue,minLength:expression.MinLength,minValue:expression.MinValue,noEcho:expression.NoEcho});this.overrideLogicalIdIfNeeded(cfnParameter,logicalId),this.parameters[logicalId]=cfnParameter}createRule(ruleName){const self=this,ruleProperties=new(cfn_parse()).CfnParser({finder:{findRefTarget(refTarget){return self.parameters[refTarget]},findResource(){throw new Error("Using GetAtt expressions in Rule definitions is not allowed")},findCondition(conditionName){return self.conditions[conditionName]},findMapping(mappingName){return self.mappings[mappingName]}},parameters:this.parametersToReplace,context:cfn_parse().CfnParsingContext.RULES}).parseValue(this.template.Rules[ruleName]),rule=new(core()).CfnRule(this.rulesScope,ruleName,{ruleCondition:ruleProperties.RuleCondition,assertions:ruleProperties.Assertions});this.rules[ruleName]=rule,this.overrideLogicalIdIfNeeded(rule,ruleName)}createHook(hookName){const self=this,cfnParser=new(cfn_parse()).CfnParser({finder:{findResource(lId){return self.resources[lId]},findRefTarget(elementName){return self.resources[elementName]??self.parameters[elementName]},findCondition(conditionName){return self.conditions[conditionName]},findMapping(mappingName){return self.mappings[mappingName]}},parameters:this.parametersToReplace}),hookAttributes=this.template.Hooks[hookName];let hook;switch(hookAttributes.Type){case"AWS::CodeDeploy::BlueGreen":hook=core().CfnCodeDeployBlueGreenHook._fromCloudFormation(this.hooksScope,hookName,hookAttributes,{parser:cfnParser});break;default:{const hookProperties=cfnParser.parseValue(hookAttributes.Properties)??{};hook=new(core()).CfnHook(this.hooksScope,hookName,{type:hookAttributes.Type,properties:hookProperties})}}this.hooks[hookName]=hook,this.overrideLogicalIdIfNeeded(hook,hookName)}createOutput(logicalId,scope){const self=this,outputAttributes=new(cfn_parse()).CfnParser({finder:{findResource(lId){return self.resources[lId]},findRefTarget(elementName){return self.resources[elementName]??self.parameters[elementName]},findCondition(conditionName){return self.conditions[conditionName]},findMapping(mappingName){return self.mappings[mappingName]}},parameters:this.parametersToReplace}).parseValue(this.template.Outputs[logicalId]),cfnOutput=new(core()).CfnOutput(scope,logicalId,{value:outputAttributes.Value,description:outputAttributes.Description,exportName:outputAttributes.Export?outputAttributes.Export.Name:void 0,condition:(()=>{if(outputAttributes.Condition){if(this.conditions[outputAttributes.Condition])return self.getCondition(outputAttributes.Condition)}else return;throw new Error(`Output with name '${logicalId}' refers to a Condition with name '${outputAttributes.Condition}' which was not found in this template`)})()});this.overrideLogicalIdIfNeeded(cfnOutput,logicalId),this.outputs[logicalId]=cfnOutput}getOrCreateCondition(conditionName){if(conditionName in this.conditions)return this.conditions[conditionName];const self=this,cfnParser=new(cfn_parse()).CfnParser({finder:{findResource(){throw new Error("Using GetAtt in Condition definitions is not allowed")},findRefTarget(elementName){return self.parameters[elementName]},findCondition(cName){return cName in(self.template.Conditions||{})?self.getOrCreateCondition(cName):void 0},findMapping(mappingName){return self.mappings[mappingName]}},context:cfn_parse().CfnParsingContext.CONDITIONS,parameters:this.parametersToReplace}),cfnCondition=new(core()).CfnCondition(this.conditionsScope,conditionName,{expression:cfnParser.parseValue(this.template.Conditions[conditionName])});return this.overrideLogicalIdIfNeeded(cfnCondition,conditionName),this.conditions[conditionName]=cfnCondition,cfnCondition}getPlaceholderID(){return`Placeholder${this.logicalIdToPlaceholderMap.size}`}getOrCreateResource(logicalId,cycleChain=[]){if(cycleChain=cycleChain.concat([logicalId]),cycleChain.length!==new Set(cycleChain).size){if(!this.allowCyclicalReferences)throw new Error(`Found a cycle between resources in the template: ${cycleChain.join(" depends on ")}`);if(this.logicalIdToPlaceholderMap.get(logicalId))return this.resources[this.logicalIdToPlaceholderMap.get(logicalId)];let placeholderResourceAttributes=this.template.Resources[logicalId],placeholderId=this.getPlaceholderID();this.logicalIdToPlaceholderMap.set(logicalId,placeholderId);let placeholderInstance=new(core()).CfnResource(this,placeholderId,{type:placeholderResourceAttributes.Type,properties:{}});return placeholderInstance.overrideLogicalId(placeholderId),this.resources[placeholderId]=placeholderInstance,placeholderInstance}const ret=this.resources[logicalId];if(ret)return ret;const self=this,finder={findCondition(conditionName){return self.conditions[conditionName]},findMapping(mappingName){return self.mappings[mappingName]},findResource(lId){if(lId in(self.template.Resources||{}))return self.getOrCreateResource(lId,cycleChain)},findRefTarget(elementName){return elementName in self.parameters?self.parameters[elementName]:this.findResource(elementName)}},cfnParser=new(cfn_parse()).CfnParser({finder,parameters:this.parametersToReplace}),resourceAttributes=this.template.Resources[logicalId];let l1Instance;if(this.nestedStacksToInclude[logicalId])l1Instance=this.createNestedStack(logicalId,cfnParser);else{const l1ClassFqn=cfn_type_to_l1_mapping().lookup(resourceAttributes.Type);if(l1ClassFqn&&resourceAttributes.Type!=="AWS::CloudFormation::CustomResource"){const options={parser:cfnParser},[moduleName,...className]=l1ClassFqn.split(".");l1Instance=require(moduleName)[className.join(".")]._fromCloudFormation(this,logicalId,resourceAttributes,options)}else l1Instance=new(core()).CfnResource(this,logicalId,{type:resourceAttributes.Type,properties:cfnParser.parseValue(resourceAttributes.Properties)}),cfnParser.handleAttributes(l1Instance,resourceAttributes,logicalId)}if(this.logicalIdToPlaceholderMap.get(logicalId)){let placeholderId=this.logicalIdToPlaceholderMap.get(logicalId);this.resources[placeholderId].overrideLogicalId(logicalId),this.node.tryRemoveChild(placeholderId),delete this.resources[placeholderId]}this.overrideLogicalIdIfNeeded(l1Instance,logicalId),this.resources[logicalId]=l1Instance;const knownAttributes=["Condition","DependsOn","Description","Metadata","Properties","Type","Version","CreationPolicy","DeletionPolicy","UpdatePolicy","UpdateReplacePolicy"];for(const[attrName,attrValue]of Object.entries(resourceAttributes))knownAttributes.includes(attrName)||l1Instance.addOverride(attrName,cfnParser.parseValue(attrValue));return l1Instance}createNestedStack(nestedStackId,cfnParser){const nestedStackAttributes=(this.template.Resources||{})[nestedStackId]||{};if(nestedStackAttributes.Type!=="AWS::CloudFormation::Stack")throw new Error(`Nested Stack with logical ID '${nestedStackId}' is not an AWS::CloudFormation::Stack resource`);if(nestedStackAttributes.CreationPolicy)throw new Error("CreationPolicy is not supported by the AWS::CloudFormation::Stack resource");if(nestedStackAttributes.UpdatePolicy)throw new Error("UpdatePolicy is not supported by the AWS::CloudFormation::Stack resource");const nestedStackProps=cfnParser.parseValue(nestedStackAttributes.Properties),nestedStack=new(core()).NestedStack(this,nestedStackId,{parameters:this.parametersForNestedStack(nestedStackProps.Parameters,nestedStackId),notificationArns:cfn_parse().FromCloudFormation.getStringArray(nestedStackProps.NotificationARNs).value,timeout:this.timeoutForNestedStack(nestedStackProps.TimeoutInMinutes)}),template=new CfnInclude(nestedStack,nestedStackId,this.nestedStacksToInclude[nestedStackId]);this.nestedStacks[nestedStackId]={stack:nestedStack,includedTemplate:template};const nestedStackResource=nestedStack.nestedStackResource;return cfnParser.handleAttributes(nestedStackResource,nestedStackAttributes,nestedStackId),nestedStackResource}parametersForNestedStack(parameters,nestedStackId){if(parameters==null)return;const parametersToReplace=this.nestedStacksToInclude[nestedStackId].parameters??{},ret={};for(const paramName of Object.keys(parameters))paramName in parametersToReplace||(ret[paramName]=cfn_parse().FromCloudFormation.getString(parameters[paramName]).value);return ret}timeoutForNestedStack(value){if(value!=null)return core().Duration.minutes(cfn_parse().FromCloudFormation.getNumber(value).value)}overrideLogicalIdIfNeeded(element,id){this.preserveLogicalIds&&element.overrideLogicalId(id)}}exports.CfnInclude=CfnInclude,_a=JSII_RTTI_SYMBOL_1,CfnInclude[_a]={fqn:"aws-cdk-lib.cloudformation_include.CfnInclude",version:"2.130.0"};