aws-cdk-lib
Version:
Version 2 of the AWS Cloud Development Kit library
8 lines (6 loc) • 7.37 kB
JavaScript
Object.defineProperty(exports,"__esModule",{value:!0}),exports.CUSTOMIZE_ROLES_CONTEXT_KEY=exports.PolicySynthesizer=exports.PolicySynthesizerTokenResolver=exports.POLICY_SYNTHESIZER_ID=void 0,exports.getPrecreatedRoleConfig=getPrecreatedRoleConfig,exports.getCustomizeRolesConfig=getCustomizeRolesConfig;var fs=()=>{var tmp=require("fs");return fs=()=>tmp,tmp},path=()=>{var tmp=require("path");return path=()=>tmp,tmp},constructs_1=()=>{var tmp=require("constructs");return constructs_1=()=>tmp,tmp},annotations_1=()=>{var tmp=require("../annotations");return annotations_1=()=>tmp,tmp},app_1=()=>{var tmp=require("../app");return app_1=()=>tmp,tmp},errors_1=()=>{var tmp=require("../errors");return errors_1=()=>tmp,tmp},reference_1=()=>{var tmp=require("../reference");return reference_1=()=>tmp,tmp},resolvable_1=()=>{var tmp=require("../resolvable");return resolvable_1=()=>tmp,tmp},token_1=()=>{var tmp=require("../token");return token_1=()=>tmp,tmp};exports.POLICY_SYNTHESIZER_ID="PolicySynthesizer";class PolicySynthesizerTokenResolver extends resolvable_1().DefaultTokenResolver{constructor(concat){super(concat)}resolveToken(t,context,postProcessor){try{let resolved=t.resolve(context);const resolvable=token_1().Tokenization.reverseString(resolved);return resolvable.length===1&&reference_1().Reference.isReference(resolvable.firstToken)?`(${resolvable.firstToken.target.node.path}.${resolvable.firstToken.displayName})`:(resolved=context.resolve(resolved),resolved=postProcessor.postProcess(resolved,context),resolved)}catch(e){let message=`Resolution error: ${e.message}.`;throw t.creationStack&&t.creationStack.length>0&&(message+=`
Object creation stack:
at ${t.creationStack.join(`
at `)}`),e.message=message,e}}}exports.PolicySynthesizerTokenResolver=PolicySynthesizerTokenResolver;class PolicySynthesizer extends constructs_1().Construct{static getOrCreate(scope){const synthesizer=scope.node.root.node.tryFindChild(exports.POLICY_SYNTHESIZER_ID);return synthesizer||new PolicySynthesizer(scope)}constructor(scope){super(scope.node.root,exports.POLICY_SYNTHESIZER_ID),this.roleReport={},this.managedPolicyReport={},this._scope=scope,(0,app_1().attachCustomSynthesis)(this,{onSynthesize:session=>{const report=this.createJsonReport();if(report.roles?.length>0){const filePath=path().join(session.outdir,"iam-policy-report");fs().writeFileSync(filePath+".txt",this.createHumanReport(report)),fs().writeFileSync(filePath+".json",JSON.stringify(report,void 0,2))}}})}createJsonReport(){return Object.entries(this.roleReport).reduce((acc,[key,value])=>{const{policyArns,policyStatements}=this.renderManagedPoliciesForRole(key,value.managedPolicies);return acc={roles:[...acc.roles??[],{roleConstructPath:key,roleName:value.missing?"missing role":value.roleName,missing:value.missing,assumeRolePolicy:this.resolveReferences(value.assumeRolePolicy),managedPolicyArns:this.resolveReferences(policyArns),managedPolicyStatements:this.resolveReferences(policyStatements),identityPolicyStatements:this.resolveReferences(value.policyStatements)}]},acc},{})}createHumanReport(report){return report.roles.map(role=>[`<${role.missing?"missing role":role.roleName}> (${role.roleConstructPath})`,"","AssumeRole Policy:",...this.toJsonString(role.assumeRolePolicy),"","Managed Policy ARNs:",...this.toJsonString(role.managedPolicyArns),"","Managed Policies Statements:",this.toJsonString(role.managedPolicyStatements),"","Identity Policy Statements:",this.toJsonString(role.identityPolicyStatements)].join(`
`)).join(`
`)}toJsonString(value){return Array.isArray(value)&&value.length===0||!value?["NONE"]:[JSON.stringify(value,void 0,2)]}renderManagedPoliciesForRole(rolePath,managedPolicies){const policyStatements=[];Object.values(this.managedPolicyReport).forEach(value=>{value.roles?.includes(rolePath)&&policyStatements.push(...value.policyStatements)});const policyArns=[];return managedPolicies.forEach(policy=>{constructs_1().Construct.isConstruct(policy)&&this.managedPolicyReport.hasOwnProperty(policy.node.path)?policyStatements.push(...this.managedPolicyReport[policy.node.path].policyStatements):policyArns.push(policy.managedPolicyArn)}),{policyArns,policyStatements}}resolveReferences(ref){if(Array.isArray(ref)&&ref.length===0||!ref)return[];if(Array.isArray(ref))return ref.map(r=>this.resolveReferences(r));if(typeof ref=="object")return this.resolveJsonObject(ref);const resolvable=token_1().Tokenization.reverseString(ref);return resolvable.length===1&&reference_1().Reference.isReference(resolvable.firstToken)?`(${resolvable.firstToken.target.node.path}.${resolvable.firstToken.displayName})`:resolvable.mapTokens({mapToken:r=>{if(reference_1().Reference.isReference(r))return`(${r.target.node.path}.${r.displayName})`;const resolved=token_1().Tokenization.resolve(r,{scope:this._scope,resolver:new PolicySynthesizerTokenResolver(new(resolvable_1()).StringConcat)});if(typeof resolved=="object"&&resolved.hasOwnProperty("Ref"))switch(resolved.Ref){case"AWS::AccountId":return"(ACCOUNT)";case"AWS::Partition":return"(PARTITION)";case"AWS::Region":return"(REGION)";case"AWS::NoValue":return"(NOVALUE)";default:return r}return token_1().Token.isUnresolved(r)&&typeof resolved=="string"&&resolved?resolved:r}}).join(new(resolvable_1()).StringConcat)}resolveJsonObject(statement){const newStatement=statement;for(const[key,value]of Object.entries(statement))newStatement[key]=this.resolveReferences(value);return newStatement}addRole(rolePath,options){if(this.roleReport.hasOwnProperty(rolePath))throw new(errors_1()).ValidationError(`IAM Policy Report already has an entry for role: ${rolePath}`,this);this.roleReport[rolePath]=options}addManagedPolicy(policyPath,options){if(this.managedPolicyReport.hasOwnProperty(policyPath))throw new(errors_1()).ValidationError(`IAM Policy Report already has an entry for managed policy: ${policyPath}`,this);this.managedPolicyReport[policyPath]=options}}exports.PolicySynthesizer=PolicySynthesizer;function getPrecreatedRoleConfig(scope,rolePath){const precreatedRolePath=rolePath??scope.node.path,customizeRolesContext=scope.node.tryGetContext(exports.CUSTOMIZE_ROLES_CONTEXT_KEY);if(customizeRolesContext!==void 0){const customizeRoles=customizeRolesContext;if(customizeRoles.preventSynthesis===!1)return{preventSynthesis:!1,enabled:!0};if(customizeRoles.usePrecreatedRoles?.hasOwnProperty(precreatedRolePath))if(token_1().Token.isUnresolved(customizeRoles.usePrecreatedRoles[precreatedRolePath]))annotations_1().Annotations.of(scope).addError(`Cannot resolve precreated role name at path "${precreatedRolePath}". The value may be a token.`);else return{enabled:!0,preventSynthesis:!0,precreatedRoleName:customizeRoles.usePrecreatedRoles[precreatedRolePath]};else annotations_1().Annotations.of(scope).addError(`IAM Role is being created at path "${precreatedRolePath}" and customizeRoles.preventSynthesis is enabled. You must provide a precreated role name in customizeRoles.precreatedRoles`);return{enabled:!0,preventSynthesis:!0}}return{enabled:!1}}exports.CUSTOMIZE_ROLES_CONTEXT_KEY="@aws-cdk/iam:customizeRoles";function getCustomizeRolesConfig(scope){const customizeRolesContext=scope.node.tryGetContext(exports.CUSTOMIZE_ROLES_CONTEXT_KEY);return{preventSynthesis:customizeRolesContext!==void 0&&customizeRolesContext.preventSynthesis!==!1,enabled:customizeRolesContext!==void 0}}
;