UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

609 lines 84.4 kB
"use strict"; const cxapi = require("@aws-cdk/cx-api"); const lib_1 = require("../lib"); const util_1 = require("./util"); class Counter extends lib_1.CfnResource { constructor(scope, id, props) { super(scope, id, { type: 'My::Counter', properties: { Count: props.Count } }); this.arn = this.getAtt('Arn').toString(); this.url = this.getAtt('URL').toString(); this.count = props.Count; } increment(by = 1) { this.count += by; } get cfnProperties() { return { Count: this.count }; } } function withoutHash(logId) { return logId.substr(0, logId.length - 8); } class CustomizableResource extends lib_1.CfnResource { constructor(scope, id, props) { super(scope, id, { type: 'MyResourceType', properties: props }); if (props !== undefined) { this.prop1 = props.prop1; this.prop2 = props.prop2; this.prop3 = props.prop3; } } renderProperties() { const props = this.updatedProperites; const render = {}; for (const key of Object.keys(props)) { render[key.toUpperCase()] = props[key]; } return render; } get updatedProperites() { const props = { prop1: this.prop1, prop2: this.prop2, prop3: this.prop3, }; const cleanProps = {}; for (const key of Object.keys(props)) { if (props[key] === undefined) { continue; } cleanProps[key] = props[key]; } return cleanProps; } } module.exports = { 'all resources derive from Resource, which derives from Entity'(test) { const stack = new lib_1.Stack(); new lib_1.CfnResource(stack, 'MyResource', { type: 'MyResourceType', properties: { Prop1: 'p1', Prop2: 123 } }); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: "MyResourceType", Properties: { Prop1: "p1", Prop2: 123 } } } }); test.done(); }, 'resources must reside within a Stack and fail upon creation if not'(test) { const root = new lib_1.App(); test.throws(() => new lib_1.CfnResource(root, 'R1', { type: 'ResourceType' })); test.done(); }, 'all entities have a logical ID calculated based on their full path in the tree'(test) { const stack = new lib_1.Stack(undefined, 'TestStack'); const level1 = new lib_1.Construct(stack, 'level1'); const level2 = new lib_1.Construct(level1, 'level2'); const level3 = new lib_1.Construct(level2, 'level3'); const res1 = new lib_1.CfnResource(level1, 'childoflevel1', { type: 'MyResourceType1' }); const res2 = new lib_1.CfnResource(level3, 'childoflevel3', { type: 'MyResourceType2' }); test.equal(withoutHash(stack.resolve(res1.logicalId)), 'level1childoflevel1'); test.equal(withoutHash(stack.resolve(res2.logicalId)), 'level1level2level3childoflevel3'); test.done(); }, 'resource.props can only be accessed by derived classes'(test) { const stack = new lib_1.Stack(); const res = new Counter(stack, 'MyResource', { Count: 10 }); res.increment(); res.increment(2); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'My::Counter', Properties: { Count: 13 } } } }); test.done(); }, 'resource attributes can be retrieved using getAtt(s) or attribute properties'(test) { const stack = new lib_1.Stack(); const res = new Counter(stack, 'MyResource', { Count: 10 }); new lib_1.CfnResource(stack, 'YourResource', { type: 'Type', properties: { CounterName: res.getAtt('Name'), CounterArn: res.arn, CounterURL: res.url, } }); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'My::Counter', Properties: { Count: 10 } }, YourResource: { Type: 'Type', Properties: { CounterName: { 'Fn::GetAtt': ['MyResource', 'Name'] }, CounterArn: { 'Fn::GetAtt': ['MyResource', 'Arn'] }, CounterURL: { 'Fn::GetAtt': ['MyResource', 'URL'] } } } } }); test.done(); }, 'ARN-type resource attributes have some common functionality'(test) { const stack = new lib_1.Stack(); const res = new Counter(stack, 'MyResource', { Count: 1 }); new lib_1.CfnResource(stack, 'MyResource2', { type: 'Type', properties: { Perm: res.arn } }); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: "My::Counter", Properties: { Count: 1 } }, MyResource2: { Type: "Type", Properties: { Perm: { "Fn::GetAtt": ["MyResource", "Arn"] } } } } }); test.done(); }, 'resource.addDependency(e) can be used to add a DependsOn on another resource'(test) { const stack = new lib_1.Stack(); const r1 = new Counter(stack, 'Counter1', { Count: 1 }); const r2 = new Counter(stack, 'Counter2', { Count: 1 }); const r3 = new lib_1.CfnResource(stack, 'Resource3', { type: 'MyResourceType' }); r2.node.addDependency(r1); r2.node.addDependency(r3); lib_1.ConstructNode.prepare(stack.node); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Counter1: { Type: "My::Counter", Properties: { Count: 1 } }, Counter2: { Type: "My::Counter", Properties: { Count: 1 }, DependsOn: [ "Counter1", "Resource3" ] }, Resource3: { Type: "MyResourceType" } } }); test.done(); }, 'if addDependency is called multiple times with the same resource, it will only appear once'(test) { // GIVEN const stack = new lib_1.Stack(); const r1 = new Counter(stack, 'Counter1', { Count: 1 }); const dependent = new lib_1.CfnResource(stack, 'Dependent', { type: 'R' }); // WHEN dependent.addDependsOn(r1); dependent.addDependsOn(r1); dependent.addDependsOn(r1); dependent.addDependsOn(r1); dependent.addDependsOn(r1); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Counter1: { Type: "My::Counter", Properties: { Count: 1 } }, Dependent: { Type: "R", DependsOn: [ "Counter1" ] } } }); test.done(); }, 'conditions can be attached to a resource'(test) { const stack = new lib_1.Stack(); const r1 = new lib_1.CfnResource(stack, 'Resource', { type: 'Type' }); const cond = new lib_1.CfnCondition(stack, 'MyCondition', { expression: lib_1.Fn.conditionNot(lib_1.Fn.conditionEquals('a', 'b')) }); r1.cfnOptions.condition = cond; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Resource: { Type: 'Type', Condition: 'MyCondition' } }, Conditions: { MyCondition: { 'Fn::Not': [{ 'Fn::Equals': ['a', 'b'] }] } } }); test.done(); }, 'creation/update/updateReplace/deletion policies can be set on a resource'(test) { const stack = new lib_1.Stack(); const r1 = new lib_1.CfnResource(stack, 'Resource', { type: 'Type' }); r1.cfnOptions.creationPolicy = { autoScalingCreationPolicy: { minSuccessfulInstancesPercent: 10 } }; // tslint:disable-next-line:max-line-length r1.cfnOptions.updatePolicy = { autoScalingScheduledAction: { ignoreUnmodifiedGroupSizeProperties: false }, autoScalingReplacingUpdate: { willReplace: true }, codeDeployLambdaAliasUpdate: { applicationName: 'CodeDeployApplication', deploymentGroupName: 'CodeDeployDeploymentGroup', beforeAllowTrafficHook: 'lambda1', }, }; r1.cfnOptions.deletionPolicy = lib_1.CfnDeletionPolicy.RETAIN; r1.cfnOptions.updateReplacePolicy = lib_1.CfnDeletionPolicy.SNAPSHOT; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Resource: { Type: 'Type', CreationPolicy: { AutoScalingCreationPolicy: { MinSuccessfulInstancesPercent: 10 } }, UpdatePolicy: { AutoScalingScheduledAction: { IgnoreUnmodifiedGroupSizeProperties: false }, AutoScalingReplacingUpdate: { WillReplace: true }, CodeDeployLambdaAliasUpdate: { ApplicationName: 'CodeDeployApplication', DeploymentGroupName: 'CodeDeployDeploymentGroup', BeforeAllowTrafficHook: 'lambda1', }, }, DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Snapshot' } } }); test.done(); }, 'update policies UseOnlineResharding flag'(test) { const stack = new lib_1.Stack(); const r1 = new lib_1.CfnResource(stack, 'Resource', { type: 'Type' }); r1.cfnOptions.updatePolicy = { useOnlineResharding: true }; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Resource: { Type: 'Type', UpdatePolicy: { UseOnlineResharding: true, }, } } }); test.done(); }, 'metadata can be set on a resource'(test) { const stack = new lib_1.Stack(); const r1 = new lib_1.CfnResource(stack, 'Resource', { type: 'Type' }); r1.cfnOptions.metadata = { MyKey: 10, MyValue: 99 }; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Resource: { Type: "Type", Metadata: { MyKey: 10, MyValue: 99 } } } }); test.done(); }, 'the "type" property is required when creating a resource'(test) { const stack = new lib_1.Stack(); test.throws(() => new lib_1.CfnResource(stack, 'Resource', { notypehere: true })); test.done(); }, 'removal policy is a high level abstraction of deletion policy used by l2'(test) { const stack = new lib_1.Stack(); const retain = new lib_1.CfnResource(stack, 'Retain', { type: 'T1' }); const destroy = new lib_1.CfnResource(stack, 'Destroy', { type: 'T3' }); const def = new lib_1.CfnResource(stack, 'Default1', { type: 'T4' }); const def2 = new lib_1.CfnResource(stack, 'Default2', { type: 'T4' }); retain.applyRemovalPolicy(lib_1.RemovalPolicy.RETAIN); destroy.applyRemovalPolicy(lib_1.RemovalPolicy.DESTROY); def.applyRemovalPolicy(undefined, { default: lib_1.RemovalPolicy.DESTROY }); def2.applyRemovalPolicy(undefined); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Retain: { Type: 'T1', DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain' }, Destroy: { Type: 'T3', DeletionPolicy: 'Delete', UpdateReplacePolicy: 'Delete' }, Default1: { Type: 'T4', DeletionPolicy: 'Delete', UpdateReplacePolicy: 'Delete' }, Default2: { Type: 'T4', DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain' } // implicit default } }); test.done(); }, 'addDependency adds all dependencyElements of dependent constructs'(test) { class C1 extends lib_1.Construct { constructor(scope, id) { super(scope, id); this.r1 = new lib_1.CfnResource(this, 'R1', { type: 'T1' }); this.r2 = new lib_1.CfnResource(this, 'R2', { type: 'T2' }); } } class C2 extends lib_1.Construct { constructor(scope, id) { super(scope, id); this.r3 = new lib_1.CfnResource(this, 'R3', { type: 'T3' }); } } // C3 returns [ c2 ] for it's dependency elements // this should result in 'flattening' the list of elements. class C3 extends lib_1.Construct { constructor(scope, id) { super(scope, id); new C2(this, 'C2'); } } const stack = new lib_1.Stack(); const c1 = new C1(stack, 'MyC1'); const c2 = new C2(stack, 'MyC2'); const c3 = new C3(stack, 'MyC3'); const dependingResource = new lib_1.CfnResource(stack, 'MyResource', { type: 'R' }); dependingResource.node.addDependency(c1, c2); dependingResource.node.addDependency(c3); lib_1.ConstructNode.prepare(stack.node); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyC1R1FB2A562F: { Type: 'T1' }, MyC1R2AE2B5066: { Type: 'T2' }, MyC2R3809EEAD6: { Type: 'T3' }, MyC3C2R38CE6F9F7: { Type: 'T3' }, MyResource: { Type: 'R', DependsOn: ['MyC1R1FB2A562F', 'MyC1R2AE2B5066', 'MyC2R3809EEAD6', 'MyC3C2R38CE6F9F7'] } } }); test.done(); }, 'resource.ref returns the {Ref} token'(test) { const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'R' }); test.deepEqual(stack.resolve(r.ref), { Ref: 'MyResource' }); test.done(); }, 'overrides': { 'addOverride(p, v) allows assigning arbitrary values to synthesized resource definitions'(test) { // GIVEN const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'AWS::Resource::Type' }); // WHEN r.addOverride('Type', 'YouCanEvenOverrideTheType'); r.addOverride('Metadata', { Key: 12 }); r.addOverride('Use.Dot.Notation', 'To create subtrees'); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'YouCanEvenOverrideTheType', Use: { Dot: { Notation: 'To create subtrees' } }, Metadata: { Key: 12 } } } }); test.done(); }, 'addOverride(p, null) will assign an "null" value'(test) { // GIVEN const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'AWS::Resource::Type', properties: { Hello: { World: { Value1: 'Hello', Value2: 129, } } } }); // WHEN r.addOverride('Properties.Hello.World.Value2', null); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'AWS::Resource::Type', Properties: { Hello: { World: { Value1: 'Hello', Value2: null } } } } } }); test.done(); }, 'addOverride(p, undefined) can be used to delete a value'(test) { // GIVEN const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'AWS::Resource::Type', properties: { Hello: { World: { Value1: 'Hello', Value2: 129, } } } }); // WHEN r.addOverride('Properties.Hello.World.Value2', undefined); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'AWS::Resource::Type', Properties: { Hello: { World: { Value1: 'Hello' } } } } } }); test.done(); }, 'addOverride(p, undefined) will not create empty trees'(test) { // GIVEN const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'AWS::Resource::Type' }); // WHEN r.addPropertyOverride('Tree.Exists', 42); r.addPropertyOverride('Tree.Does.Not.Exist', undefined); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'AWS::Resource::Type', Properties: { Tree: { Exists: 42 } } } } }); test.done(); }, 'addDeletionOverride(p) and addPropertyDeletionOverride(pp) are sugar `undefined`'(test) { // GIVEN const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'AWS::Resource::Type', properties: { Hello: { World: { Value1: 'Hello', Value2: 129, Value3: ['foo', 'bar'] } } } }); // WHEN r.addDeletionOverride('Properties.Hello.World.Value2'); r.addPropertyDeletionOverride('Hello.World.Value3'); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'AWS::Resource::Type', Properties: { Hello: { World: { Value1: 'Hello' } } } } } }); test.done(); }, 'addOverride(p, v) will overwrite any non-objects along the path'(test) { // GIVEN const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'AWS::Resource::Type', properties: { Hello: { World: 42 } } }); // WHEN r.addOverride('Properties.Override1', ['Hello', 123]); r.addOverride('Properties.Override1.Override2', { Heyy: [1] }); r.addOverride('Properties.Hello.World.Foo.Bar', 42); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'AWS::Resource::Type', Properties: { Hello: { World: { Foo: { Bar: 42 } } }, Override1: { Override2: { Heyy: [1] } } } } } }); test.done(); }, 'addPropertyOverride(pp, v) is a sugar for overriding properties'(test) { // GIVEN const stack = new lib_1.Stack(); const r = new lib_1.CfnResource(stack, 'MyResource', { type: 'AWS::Resource::Type', properties: { Hello: { World: 42 } } }); // WHEN r.addPropertyOverride('Hello.World', { Hey: 'Jude' }); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'AWS::Resource::Type', Properties: { Hello: { World: { Hey: 'Jude' } } } } } }); test.done(); }, 'overrides are applied after render'(test) { // GIVEN class MyResource extends lib_1.CfnResource { renderProperties() { return { Fixed: 123 }; } } const stack = new lib_1.Stack(); const cfn = new MyResource(stack, 'rr', { type: 'AWS::Resource::Type' }); // WHEN cfn.addPropertyOverride('Boom', 'Hi'); cfn.addOverride('Properties.Foo.Bar', 'Bar'); // THEN test.deepEqual(util_1.toCloudFormation(stack), { Resources: { rr: { Type: 'AWS::Resource::Type', Properties: { Fixed: 123, Boom: 'Hi', Foo: { Bar: 'Bar' } } } } }); test.done(); }, 'using mutable properties': { 'can be used by derived classes to specify overrides before render()'(test) { const stack = new lib_1.Stack(); const r = new CustomizableResource(stack, 'MyResource', { prop1: 'foo' }); r.prop2 = 'bar'; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'MyResourceType', Properties: { PROP1: 'foo', PROP2: 'bar' } } } }); test.done(); }, '"properties" is undefined'(test) { const stack = new lib_1.Stack(); const r = new CustomizableResource(stack, 'MyResource'); r.prop3 = 'zoo'; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'MyResourceType', Properties: { PROP3: 'zoo' } } } }); test.done(); }, '"properties" is empty'(test) { const stack = new lib_1.Stack(); const r = new CustomizableResource(stack, 'MyResource', {}); r.prop3 = 'zoo'; r.prop2 = 'hey'; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'MyResourceType', Properties: { PROP2: 'hey', PROP3: 'zoo' } } } }); test.done(); }, } }, '"aws:cdk:path" metadata is added if "aws:cdk:path-metadata" context is set to true'(test) { const stack = new lib_1.Stack(); stack.node.setContext(cxapi.PATH_METADATA_ENABLE_CONTEXT, true); const parent = new lib_1.Construct(stack, 'Parent'); new lib_1.CfnResource(parent, 'MyResource', { type: 'MyResourceType', }); test.deepEqual(util_1.toCloudFormation(stack), { Resources: { ParentMyResource4B1FDBCC: { Type: 'MyResourceType', Metadata: { [cxapi.PATH_METADATA_KEY]: 'Parent/MyResource' } } } }); test.done(); }, 'cross-stack construct dependencies are not rendered but turned into stack dependencies'(test) { // GIVEN const app = new lib_1.App(); const stackA = new lib_1.Stack(app, 'StackA'); const resA = new lib_1.CfnResource(stackA, 'Resource', { type: 'R' }); const stackB = new lib_1.Stack(app, 'StackB'); const resB = new lib_1.CfnResource(stackB, 'Resource', { type: 'R' }); // WHEN resB.node.addDependency(resA); // THEN const assembly = app.synth(); const templateB = assembly.getStackByName(stackB.stackName).template; test.deepEqual(templateB, { Resources: { Resource: { Type: 'R' // Notice absence of 'DependsOn' } } }); test.deepEqual(stackB.dependencies.map(s => s.node.id), ['StackA']); test.done(); }, 'enableVersionUpgrade can be set on a resource'(test) { const stack = new lib_1.Stack(); const r1 = new lib_1.CfnResource(stack, 'Resource', { type: 'Type' }); r1.cfnOptions.updatePolicy = { enableVersionUpgrade: true }; test.deepEqual(util_1.toCloudFormation(stack), { Resources: { Resource: { Type: 'Type', UpdatePolicy: { EnableVersionUpgrade: true } } } }); test.done(); }, }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5yZXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QucmVzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHlDQUF5QztBQUV6QyxnQ0FFNkM7QUFDN0MsaUNBQTBDO0FBb3NCMUMsTUFBTSxPQUFRLFNBQVEsaUJBQVc7SUFNL0IsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFtQjtRQUMzRCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDOUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN6QyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7SUFDM0IsQ0FBQztJQUVNLFNBQVMsQ0FBQyxFQUFFLEdBQUcsQ0FBQztRQUNyQixJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQsSUFBYyxhQUFhO1FBQ3pCLE9BQU8sRUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBQyxDQUFDO0lBQzdCLENBQUM7Q0FDRjtBQUVELFNBQVMsV0FBVyxDQUFDLEtBQWE7SUFDaEMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRCxNQUFNLG9CQUFxQixTQUFRLGlCQUFXO0lBSzVDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBVztRQUNuRCxLQUFLLENBQUMsS0FB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