aws-cdk-lib
Version:
Version 2 of the AWS Cloud Development Kit library
2 lines (1 loc) • 18.3 kB
JavaScript
"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,this.dehydratedResources=props.dehydratedResources??[];for(const logicalId of this.dehydratedResources)if(!Object.keys(this.template.Resources).includes(logicalId))throw new(core()).ValidationError(`Logical ID '${logicalId}' was specified in 'dehydratedResources', but does not belong to a resource in the template.`,this);for(const logicalId of Object.keys(this.parametersToReplace))if(!(logicalId in(this.template.Parameters||{})))throw new(core()).ValidationError(`Parameter with logical ID '${logicalId}' was not found in the template`,this);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(core()).ValidationError(`Nested Stack with logical ID '${nestedStackId}' was not found in the template`,this);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(core()).ValidationError(`Resource with logical ID '${logicalId}' was not found in the template`,this);return ret}getCondition(conditionName){const ret=this.conditions[conditionName];if(!ret)throw new(core()).ValidationError(`Condition with name '${conditionName}' was not found in the template`,this);return ret}getParameter(parameterName){const ret=this.parameters[parameterName];if(!ret)throw new(core()).ValidationError(`Parameter with name '${parameterName}' was not found in the template`,this);return ret}getMapping(mappingName){const ret=this.mappings[mappingName];if(!ret)throw new(core()).ValidationError(`Mapping with name '${mappingName}' was not found in the template`,this);return ret}getOutput(logicalId){const ret=this.outputs[logicalId];if(!ret)throw new(core()).ValidationError(`Output with logical ID '${logicalId}' was not found in the template`,this);return ret}getRule(ruleName){const ret=this.rules[ruleName];if(!ret)throw new(core()).ValidationError(`Rule with name '${ruleName}' was not found in the template`,this);return ret}getHook(hookLogicalId){const ret=this.hooks[hookLogicalId];if(!ret)throw new(core()).ValidationError(`Hook with logical ID '${hookLogicalId}' was not found in the template`,this);return ret}getNestedStack(logicalId){if(!this.nestedStacks[logicalId])throw this.template.Resources[logicalId]?this.template.Resources[logicalId].Type!=="AWS::CloudFormation::Stack"?new(core()).ValidationError(`Resource with logical ID '${logicalId}' is not a CloudFormation Stack`,this):new(core()).ValidationError(`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`,this):new(core()).ValidationError(`Nested Stack with logical ID '${logicalId}' was not found in the template`,this);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(core()).ValidationError(`Nested Stack '${logicalId}' was already included in its parent template`,this);const cfnStack=this.resources[logicalId];if(!cfnStack)throw new(core()).ValidationError(`Nested Stack with logical ID '${logicalId}' was not found in the template`,this);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(core()).ValidationError(`Nested Stack with logical ID '${logicalId}' is not an AWS::CloudFormation::Stack resource`,this)}_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 self=this,cfnParser=new(cfn_parse()).CfnParser({finder:{findCondition(){throw new(core()).ValidationError("Referring to Conditions in Mapping definitions is not allowed",self)},findMapping(){throw new(core()).ValidationError("Referring to other Mappings in Mapping definitions is not allowed",self)},findRefTarget(){throw new(core()).ValidationError("Using Ref expressions in Mapping definitions is not allowed",self)},findResource(){throw new(core()).ValidationError("Using GetAtt expressions in Mapping definitions is not allowed",self)}},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 self=this,expression=new(cfn_parse()).CfnParser({finder:{findResource(){throw new(core()).ValidationError("Using GetAtt expressions in Parameter definitions is not allowed",self)},findRefTarget(){throw new(core()).ValidationError("Using Ref expressions in Parameter definitions is not allowed",self)},findCondition(){throw new(core()).ValidationError("Referring to Conditions in Parameter definitions is not allowed",self)},findMapping(){throw new(core()).ValidationError("Referring to Mappings in Parameter definitions is not allowed",self)}},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(core()).ValidationError("Using GetAtt expressions in Rule definitions is not allowed",self)},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(core()).ValidationError(`Output with name '${logicalId}' refers to a Condition with name '${outputAttributes.Condition}' which was not found in this template`,this)})()});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(core()).ValidationError("Using GetAtt in Condition definitions is not allowed",self)},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(core()).ValidationError(`Found a cycle between resources in the template: ${cycleChain.join(" depends on ")}`,this);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]&&this.dehydratedResources.includes(logicalId))throw new(core()).ValidationError(`nested stack '${logicalId}' was marked as dehydrated - nested stacks cannot be dehydrated`,this);if(this.nestedStacksToInclude[logicalId])l1Instance=this.createNestedStack(logicalId,cfnParser);else if(this.dehydratedResources.includes(logicalId)){l1Instance=new(core()).CfnResource(this,logicalId,{type:resourceAttributes.Type,properties:resourceAttributes.Properties});const cfnOptions=l1Instance.cfnOptions;return cfnOptions.creationPolicy=resourceAttributes.CreationPolicy,cfnOptions.updatePolicy=resourceAttributes.UpdatePolicy,cfnOptions.deletionPolicy=resourceAttributes.DeletionPolicy,cfnOptions.updateReplacePolicy=resourceAttributes.UpdateReplacePolicy,cfnOptions.version=resourceAttributes.Version,cfnOptions.description=resourceAttributes.Description,cfnOptions.metadata=resourceAttributes.Metadata,this.resources[logicalId]=l1Instance,l1Instance}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(core()).ValidationError(`Nested Stack with logical ID '${nestedStackId}' is not an AWS::CloudFormation::Stack resource`,this);if(nestedStackAttributes.CreationPolicy)throw new(core()).ValidationError("CreationPolicy is not supported by the AWS::CloudFormation::Stack resource",this);if(nestedStackAttributes.UpdatePolicy)throw new(core()).ValidationError("UpdatePolicy is not supported by the AWS::CloudFormation::Stack resource",this);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.185.0"};