aws-cdk-lib
Version:
Version 2 of the AWS Cloud Development Kit library
5 lines (4 loc) • 9.47 kB
JavaScript
Object.defineProperty(exports,"__esModule",{value:!0}),exports.synthesize=synthesize,exports.addCustomSynthesis=addCustomSynthesis;var fs=()=>{var tmp=require("fs");return fs=()=>tmp,tmp},path=()=>{var tmp=require("path");return path=()=>tmp,tmp},metadata_resource_1=()=>{var tmp=require("./metadata-resource");return metadata_resource_1=()=>tmp,tmp},prepare_app_1=()=>{var tmp=require("./prepare-app");return prepare_app_1=()=>tmp,tmp},tree_metadata_1=()=>{var tmp=require("./tree-metadata");return tree_metadata_1=()=>tmp,tmp},cxapi=()=>{var tmp=require("../../../cx-api");return cxapi=()=>tmp,tmp},annotations_1=()=>{var tmp=require("../annotations");return annotations_1=()=>tmp,tmp},app_1=()=>{var tmp=require("../app");return app_1=()=>tmp,tmp},aspect_1=()=>{var tmp=require("../aspect");return aspect_1=()=>tmp,tmp},fs_1=()=>{var tmp=require("../fs");return fs_1=()=>tmp,tmp},stack_1=()=>{var tmp=require("../stack");return stack_1=()=>tmp,tmp},stage_1=()=>{var tmp=require("../stage");return stage_1=()=>tmp,tmp},construct_tree_1=()=>{var tmp=require("../validation/private/construct-tree");return construct_tree_1=()=>tmp,tmp},report_1=()=>{var tmp=require("../validation/private/report");return report_1=()=>tmp,tmp};const POLICY_VALIDATION_FILE_PATH="policy-validation-report.json",VALIDATION_REPORT_JSON_CONTEXT="@aws-cdk/core:validationReportJson";function synthesize(root,options={}){injectTreeMetadata(root),synthNestedAssemblies(root,options),options.aspectStabilization==!0?invokeAspectsV2(root):invokeAspects(root),injectMetadataResources(root),(0,prepare_app_1().prepareApp)(root),options.skipValidation||validateTree(root);const builder=stage_1().Stage.isStage(root)?root._assemblyBuilder:new(cxapi()).CloudAssemblyBuilder(options.outdir);synthesizeTree(root,builder,options.validateOnSynthesis);const assembly=builder.buildAssembly();return invokeValidationPlugins(root,builder.outdir,assembly),assembly}function getAssemblies(root,rootAssembly){const assemblies=new Map;return assemblies.set(root.artifactId,rootAssembly),visitAssemblies(root,"pre",construct=>{const stage=construct;stage.parentStage&&assemblies.has(stage.parentStage.artifactId)&&assemblies.set(stage.artifactId,assemblies.get(stage.parentStage.artifactId).getNestedAssembly(stage.artifactId))}),assemblies}function invokeValidationPlugins(root,outdir,assembly){if(!app_1().App.isApp(root))return;let hash;const assemblies=getAssemblies(root,assembly),templatePathsByPlugin=new Map;visitAssemblies(root,"post",construct=>{if(stage_1().Stage.isStage(construct))for(const plugin of construct.policyValidationBeta1){templatePathsByPlugin.has(plugin)||templatePathsByPlugin.set(plugin,[]);let assemblyToUse=assemblies.get(construct.artifactId);if(!assemblyToUse)throw new Error(`Validation failed, cannot find cloud assembly for stage ${construct.stageName}`);templatePathsByPlugin.get(plugin).push(...assemblyToUse.stacksRecursively.map(stack=>stack.templateFullPath))}});const reports=[];templatePathsByPlugin.size>0&&console.log(`Performing Policy Validations
`),templatePathsByPlugin.size>0&&(hash=fs_1().FileSystem.fingerprint(outdir));for(const[plugin,paths]of templatePathsByPlugin.entries()){try{const report=plugin.validate({templatePaths:paths});reports.push({...report,pluginName:plugin.name})}catch(e){reports.push({success:!1,pluginName:plugin.name,pluginVersion:plugin.version,violations:[],metadata:{error:`Validation plugin '${plugin.name}' failed: ${e.message}`}})}if(fs_1().FileSystem.fingerprint(outdir)!==hash)throw new Error(`Illegal operation: validation plugin '${plugin.name}' modified the cloud assembly`)}if(reports.length>0){const tree=new(construct_tree_1()).ConstructTree(root),formatter=new(report_1()).PolicyValidationReportFormatter(tree),formatJson=root.node.tryGetContext(VALIDATION_REPORT_JSON_CONTEXT)??!1,output=formatJson?formatter.formatJson(reports):formatter.formatPrettyPrinted(reports),reportFile=path().join(assembly.directory,POLICY_VALIDATION_FILE_PATH);if(formatJson?fs().writeFileSync(reportFile,JSON.stringify(output,void 0,2)):console.error(output),reports.some(r=>!r.success)){const message=formatJson?`Validation failed. See the validation report in '${reportFile}' for details`:"Validation failed. See the validation report above for details";console.log(message),process.exitCode=1}else console.log("Policy Validation Successful!")}}const CUSTOM_SYNTHESIS_SYM=Symbol.for("@aws-cdk/core:customSynthesis");function addCustomSynthesis(construct,synthesis){Object.defineProperty(construct,CUSTOM_SYNTHESIS_SYM,{value:synthesis,enumerable:!1})}function getCustomSynthesis(construct){return construct[CUSTOM_SYNTHESIS_SYM]}function synthNestedAssemblies(root,options){for(const child of root.node.children)stage_1().Stage.isStage(child)?child.synth(options):synthNestedAssemblies(child,options)}function invokeAspects(root){const invokedByPath={};let nestedAspectWarning=!1;recurse(root,[]);function recurse(construct,inheritedAspects){const node=construct.node,aspects=aspect_1().Aspects.of(construct);let localAspects=getAspectApplications(construct);const allAspectsHere=sortAspectsByPriority(inheritedAspects,localAspects),nodeAspectsCount=aspects.all.length;for(const aspectApplication of allAspectsHere){let invoked=invokedByPath[node.path];invoked||(invoked=invokedByPath[node.path]=[]),!invoked.some(invokedApp=>invokedApp.aspect===aspectApplication.aspect)&&(aspectApplication.aspect.visit(construct),!nestedAspectWarning&&nodeAspectsCount!==aspects.all.length&&(annotations_1().Annotations.of(construct).addWarningV2("@aws-cdk/core:ignoredAspect","We detected an Aspect was added via another Aspect, and will not be applied"),nestedAspectWarning=!0),invoked.push(aspectApplication))}for(const child of construct.node.children)stage_1().Stage.isStage(child)||recurse(child,allAspectsHere)}}function invokeAspectsV2(root){const invokedByPath={};recurse(root,[]);for(let i=0;i<=100;i++)if(!recurse(root,[]))return;throw new Error("We have detected a possible infinite loop while invoking Aspects. Please check your Aspects and verify there is no configuration that would cause infinite Aspect or Node creation.");function recurse(construct,inheritedAspects){const node=construct.node;let didSomething=!1,localAspects=getAspectApplications(construct);const allAspectsHere=sortAspectsByPriority(inheritedAspects,localAspects);for(const aspectApplication of allAspectsHere){let invoked=invokedByPath[node.path];if(invoked||(invoked=invokedByPath[node.path]=[]),invoked.some(invokedApp=>invokedApp.aspect===aspectApplication.aspect))continue;const lastInvokedAspect=invoked[invoked.length-1];if(lastInvokedAspect&&lastInvokedAspect.priority>aspectApplication.priority)throw new Error(`Cannot invoke Aspect ${aspectApplication.aspect.constructor.name} with priority ${aspectApplication.priority} on node ${node.path}: an Aspect ${lastInvokedAspect.aspect.constructor.name} with a lower priority (${lastInvokedAspect.priority}) was already invoked on this node.`);aspectApplication.aspect.visit(construct),didSomething=!0,invoked.push(aspectApplication)}let childDidSomething=!1;for(const child of construct.node.children)stage_1().Stage.isStage(child)||(childDidSomething=recurse(child,allAspectsHere)||childDidSomething);return didSomething||childDidSomething}}function sortAspectsByPriority(inheritedAspects,localAspects){return[...inheritedAspects,...localAspects].sort((a,b)=>{if(a.priority!==b.priority)return a.priority-b.priority;const isAInherited=inheritedAspects.includes(a),isBInherited=inheritedAspects.includes(b);return isAInherited&&!isBInherited?-1:!isAInherited&&isBInherited?1:0})}function getAspectApplications(node){const aspects=aspect_1().Aspects.of(node);return aspects.applied!==void 0?aspects.applied:aspects.all.map(aspect=>new(aspect_1()).AspectApplication(node,aspect,aspect_1().AspectPriority.DEFAULT))}function injectMetadataResources(root){visit(root,"post",construct=>{if(!stack_1().Stack.isStack(construct)||!construct._versionReportingEnabled)return;const CDKMetadata="CDKMetadata";construct.node.tryFindChild(CDKMetadata)||new(metadata_resource_1()).MetadataResource(construct,CDKMetadata)})}function injectTreeMetadata(root){visit(root,"post",construct=>{!app_1().App.isApp(construct)||!construct._treeMetadata||construct.node.tryFindChild("Tree")||new(tree_metadata_1()).TreeMetadata(construct)})}function synthesizeTree(root,builder,validateOnSynth=!1){visit(root,"post",construct=>{const session={outdir:builder.outdir,assembly:builder,validateOnSynth};stack_1().Stack.isStack(construct)?construct.synthesizer.synthesize(session):construct instanceof tree_metadata_1().TreeMetadata?construct._synthesizeTree(session):getCustomSynthesis(construct)?.onSynthesize(session)})}function validateTree(root){const errors=new Array;if(visit(root,"pre",construct=>{for(const message of construct.node.validate())errors.push({message,source:construct})}),errors.length>0){const errorList=errors.map(e=>`[${e.source.node.path}] ${e.message}`).join(`
`);throw new Error(`Validation failed with the following errors:
${errorList}`)}}function visitAssemblies(root,order,cb){order==="pre"&&cb(root);for(const child of root.node.children)stage_1().Stage.isStage(child)&&visitAssemblies(child,order,cb);order==="post"&&cb(root)}function visit(root,order,cb){order==="pre"&&cb(root);for(const child of root.node.children)stage_1().Stage.isStage(child)||visit(child,order,cb);order==="post"&&cb(root)}
;