@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
609 lines • 84.4 kB
JavaScript
"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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