aws-cdk-lib
Version:
Version 2 of the AWS Cloud Development Kit library
2 lines (1 loc) • 7.17 kB
JavaScript
"use strict";var _a,_b;Object.defineProperty(exports,"__esModule",{value:!0}),exports.StackOutput=exports.CdkStage=void 0;const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti"),codebuild=require("../../../aws-codebuild"),cpactions=require("../../../aws-codepipeline-actions"),aws_codepipeline_actions_1=require("../../../aws-codepipeline-actions"),core_1=require("../../../core"),constructs_1=require("constructs"),actions_1=require("./actions"),pipeline_1=require("./pipeline"),asset_type_1=require("../blueprint/asset-type"),application_security_check_1=require("../private/application-security-check"),asset_manifest_1=require("../private/asset-manifest"),construct_internals_1=require("../private/construct-internals"),toposort_1=require("../private/toposort");class CdkStage extends constructs_1.Construct{constructor(scope,id,props){super(scope,id),this._nextSequentialRunOrder=1,this._manualApprovalCounter=1,this.stacksToDeploy=new Array,this._prepared=!1,scope instanceof pipeline_1.CdkPipeline&&(this.pipeline=scope),this.stageName=props.stageName,this.pipelineStage=props.pipelineStage,this.cloudAssemblyArtifact=props.cloudAssemblyArtifact,this.host=props.host,this.confirmBroadeningPermissions=props.confirmBroadeningPermissions??!1,this.securityNotificationTopic=props.securityNotificationTopic,core_1.Aspects.of(this).add({visit:()=>this.prepareStage()})}addApplication(appStage,options={}){const asm=construct_internals_1.pipelineSynth(appStage),extraRunOrderSpace=options.extraRunOrderSpace??0;if((options.confirmBroadeningPermissions??this.confirmBroadeningPermissions)&&this.addSecurityCheck(appStage,options),asm.stacks.length===0)throw new Error(`The given Stage construct ('${appStage.node.path}') should contain at least one Stack`);const sortedTranches=toposort_1.topologicalSort(asm.stacks,stack=>stack.id,stack=>stack.dependencies.map(d=>d.id));for(const stacks of sortedTranches){const runOrder=this.nextSequentialRunOrder(extraRunOrderSpace+2);let executeRunOrder=runOrder+extraRunOrderSpace+1;options.manualApprovals&&(this.addManualApprovalAction({runOrder:runOrder+1}),executeRunOrder=this.nextSequentialRunOrder());for(const stack of stacks)this.addStackArtifactDeployment(stack,{runOrder,executeRunOrder})}}getApplicationSecurityCheck(){return this._applicationSecurityCheck?this._applicationSecurityCheck:(this._applicationSecurityCheck=this.pipeline?this.pipeline._getApplicationSecurityCheck():new application_security_check_1.ApplicationSecurityCheck(this,"StageApplicationSecurityCheck",{codePipeline:this.pipelineStage.pipeline}),this._applicationSecurityCheck)}addStackArtifactDeployment(stackArtifact,options={}){this.publishAssetDependencies(stackArtifact);const runOrder=options.runOrder??this.nextSequentialRunOrder(2),executeRunOrder=options.executeRunOrder??runOrder+1;this.stacksToDeploy.push({prepareRunOrder:runOrder,executeRunOrder,stackArtifact}),this.advanceRunOrderPast(runOrder),this.advanceRunOrderPast(executeRunOrder)}addManualApprovalAction(options={}){let actionName=options.actionName;actionName||(actionName=`ManualApproval${this._manualApprovalCounter>1?this._manualApprovalCounter:""}`,this._manualApprovalCounter+=1),this.addActions(new cpactions.ManualApprovalAction({actionName,runOrder:options.runOrder??this.nextSequentialRunOrder()}))}addActions(...actions){for(const action of actions)this.pipelineStage.addAction(action)}nextSequentialRunOrder(count=1){const ret=this._nextSequentialRunOrder;return this._nextSequentialRunOrder+=count,ret}deploysStack(artifactId){return this.stacksToDeploy.map(s=>s.stackArtifact.id).includes(artifactId)}prepareStage(){if(!this._prepared){this._prepared=!0;for(const{prepareRunOrder,stackArtifact,executeRunOrder}of this.stacksToDeploy){const artifact=this.host.stackOutputArtifact(stackArtifact.id);this.pipelineStage.addAction(actions_1.DeployCdkStackAction.fromStackArtifact(this,stackArtifact,{baseActionName:this.simplifyStackName(stackArtifact.stackName),cloudAssemblyInput:this.cloudAssemblyArtifact,output:artifact,outputFileName:artifact?"outputs.json":void 0,prepareRunOrder,executeRunOrder}))}}}advanceRunOrderPast(lastUsed){this._nextSequentialRunOrder=Math.max(lastUsed+1,this._nextSequentialRunOrder)}simplifyStackName(s){return stripPrefix(s,`${this.stageName}-`)}addSecurityCheck(appStage,options){const{cdkDiffProject}=this.getApplicationSecurityCheck(),notificationTopic=options?.securityNotificationTopic??this.securityNotificationTopic;notificationTopic?.grantPublish(cdkDiffProject);const appStageName=appStage.stageName,approveActionName=`${appStageName}ManualApproval`,diffAction=new aws_codepipeline_actions_1.CodeBuildAction({runOrder:this.nextSequentialRunOrder(),actionName:`${appStageName}SecurityCheck`,input:this.cloudAssemblyArtifact,project:cdkDiffProject,variablesNamespace:`${appStageName}SecurityCheck`,environmentVariables:{STAGE_PATH:{value:constructs_1.Node.of(appStage).path,type:codebuild.BuildEnvironmentVariableType.PLAINTEXT},STAGE_NAME:{value:this.stageName,type:codebuild.BuildEnvironmentVariableType.PLAINTEXT},ACTION_NAME:{value:approveActionName,type:codebuild.BuildEnvironmentVariableType.PLAINTEXT},...notificationTopic?{NOTIFICATION_ARN:{value:notificationTopic.topicArn,type:codebuild.BuildEnvironmentVariableType.PLAINTEXT},NOTIFICATION_SUBJECT:{value:`Confirm permission broadening in ${appStageName}`,type:codebuild.BuildEnvironmentVariableType.PLAINTEXT}}:{}}}),approve=new cpactions.ManualApprovalAction({actionName:approveActionName,runOrder:this.nextSequentialRunOrder(),additionalInformation:`#{${appStageName}SecurityCheck.MESSAGE}`,externalEntityLink:`#{${appStageName}SecurityCheck.LINK}`});this.addActions(diffAction,approve)}publishAssetDependencies(stackArtifact){const assetManifests=stackArtifact.dependencies.filter(isAssetManifest);for(const manifestArtifact of assetManifests){const manifest=asset_manifest_1.AssetManifestReader.fromFile(manifestArtifact.file);for(const entry of manifest.entries){let assetType;if(entry instanceof asset_manifest_1.DockerImageManifestEntry)assetType=asset_type_1.AssetType.DOCKER_IMAGE;else if(entry instanceof asset_manifest_1.FileManifestEntry){if(entry.source.packaging==="file"&&entry.source.path===stackArtifact.templateFile)continue;assetType=asset_type_1.AssetType.FILE}else throw new Error(`Unrecognized asset type: ${entry.type}`);if(!entry.destination.assumeRoleArn)throw new Error("assumeRoleArn is missing on asset and required");this.host.publishAsset({assetManifestPath:manifestArtifact.file,assetId:entry.id.assetId,assetSelector:entry.id.toString(),assetType,assetPublishingRoleArn:entry.destination.assumeRoleArn})}}}}exports.CdkStage=CdkStage,_a=JSII_RTTI_SYMBOL_1,CdkStage[_a]={fqn:"aws-cdk-lib.pipelines.CdkStage",version:"2.70.0"};class StackOutput{constructor(artifactFile,outputName){this.artifactFile=artifactFile,this.outputName=outputName}}exports.StackOutput=StackOutput,_b=JSII_RTTI_SYMBOL_1,StackOutput[_b]={fqn:"aws-cdk-lib.pipelines.StackOutput",version:"2.70.0"};function stripPrefix(s,prefix){return s.startsWith(prefix)?s.slice(prefix.length):s}function isAssetManifest(s){return s.constructor.name==="AssetManifestArtifact"}