Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(custom-resources): unable to use a resource attributes as dictionary keys in AwsCustomResource #13074

Merged
merged 90 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
0fd66c4
fix(custom-resources): unable to use a resource attributes as diction…
Feb 16, 2021
6766749
remove decodeBooleans test
Feb 16, 2021
4d500d4
Fix lambda test
Feb 16, 2021
c3aa252
update snapshot
Feb 16, 2021
762c810
update route53 tests
Feb 17, 2021
b6103b3
chore(deps): bump @typescript-eslint/eslint-plugin from 4.15.0 to 4.1…
dependabot-preview[bot] Feb 15, 2021
eed60d7
fix(rds): proxy cannot connect to cluster/instance (#12953)
skinny85 Feb 15, 2021
a08b048
feat(aws-ecs-patterns): allow ScheduledTaskBase be created in a DISAB…
ScottWalkerAU Feb 15, 2021
cc1264a
chore(deps): bump eslint-import-resolver-typescript from 2.3.0 to 2.4…
dependabot-preview[bot] Feb 16, 2021
da4cf2c
chore(deps): bump aws-sdk from 2.843.0 to 2.844.0 (#13061)
dependabot-preview[bot] Feb 16, 2021
c5e4c77
chore(core): add monocdk to reporting (#13071)
NetaNir Feb 16, 2021
173b660
fix(codecommit): take the region and account of an imported Repositor…
skinny85 Feb 16, 2021
68d6a9c
chore(rds): use nodeunit-shim (#13077)
rix0rrr Feb 16, 2021
1681505
chore: backport CHANGELOG generation fix (#13082)
njlynch Feb 16, 2021
8913b83
fix(core): `exportValue()` does not work with resource names (#13052)
rix0rrr Feb 16, 2021
c2bb428
chore(cdk-build-tools): backport feature flag based conditional from …
Feb 16, 2021
ed17b9f
chore: update contribution guide with feature flag support for v2 (#1…
Feb 16, 2021
1f43a40
fix(aws-rds): correct Policy resource for Proxy::grantConnect() (#12416)
jdvornek Feb 16, 2021
b201085
feat(ecs): support Fargate and Fargate spot capacity providers (#12893)
SoManyHs Feb 16, 2021
29fddd8
chore(deps): bump aws-sdk from 2.844.0 to 2.845.0 (#13089)
dependabot-preview[bot] Feb 16, 2021
d8e9f66
chore(deps): bump eslint-plugin-jest from 24.1.3 to 24.1.4 (#13092)
dependabot-preview[bot] Feb 17, 2021
d3f2dc6
chore(deps): bump eslint-plugin-jest from 24.1.4 to 24.1.5 (#13096)
dependabot-preview[bot] Feb 17, 2021
5769bd3
feat(ecs-patterns): Add support for taskSubnets and securityGroups o…
lgvo Feb 17, 2021
79971cb
docs: fix typos in DESIGN_GUIDELINES (#13097)
SoManyHs Feb 17, 2021
bb22b6e
feat(eks): support Kubernetes 1.19 (#13094)
pahud Feb 17, 2021
6a80670
fix(cloudfront): bucket policy for Origin Access Identities is overly…
njlynch Feb 17, 2021
d563037
chore: fix issue assignment worfklows should to use tagged versions (…
iliapolo Feb 17, 2021
87aa337
chore: fix unmatched parenthesis in issue-label-assign (#13111)
njlynch Feb 17, 2021
095446d
feat(glue): Connection construct (#12444)
humanzz Feb 17, 2021
56b2fbb
chore: enable feature flags on all integ tests (#13110)
Feb 17, 2021
212775e
chore: make NPM dist tag explicit for all packages (#13109)
njlynch Feb 17, 2021
fcc1ba9
feat(core): customize bundling output packaging (#13076)
jogold Feb 17, 2021
e1a34db
chore(ecr-assets): migrate image-asset.test.ts to use jest (#13115)
Feb 17, 2021
c2cc886
chore(release): 1.90.0
Feb 17, 2021
d6faf6c
Update CHANGELOG.md
NetaNir Feb 17, 2021
cfeac6e
Update CHANGELOG.md
NetaNir Feb 17, 2021
75a5966
fix(core): ENOTDIR invalid cwd on "cdk deploy" (#13145)
Feb 19, 2021
e08dcec
chore(release): 1.90.1
NetaNir Feb 19, 2021
34815d8
chore: adjust changelog
NetaNir Feb 19, 2021
8d26c15
chore(deps-dev): bump standard-version from 9.1.0 to 9.1.1 (#13124)
dependabot-preview[bot] Feb 17, 2021
7f92aa4
chore(deps): bump aws-sdk from 2.845.0 to 2.846.0 (#13117)
dependabot-preview[bot] Feb 17, 2021
151522f
chore(deps-dev): bump esbuild from 0.8.46 to 0.8.47 (#13128)
dependabot-preview[bot] Feb 18, 2021
9eb79d1
fix(eks): Deployment fails for the first deployment in an account (#1…
iliapolo Feb 18, 2021
f9000b8
docs(rds): fix weird rendering of socketAddress property in Endpoint …
skinny85 Feb 18, 2021
bdc2292
docs: fix typos in CONTRIBUTING.md (#13116)
SoManyHs Feb 18, 2021
bf28acc
feat(lambda): Code.fromDockerBuildAsset (#12258)
jogold Feb 18, 2021
804f25b
chore(deps-dev): bump esbuild from 0.8.47 to 0.8.48 (#13135)
dependabot-preview[bot] Feb 18, 2021
9646e20
feat(cfnspec): cloudformation spec v28.0.0 (#13101)
aws-cdk-automation Feb 18, 2021
7ee342d
docs(s3-deployment): Reflect new stability of CloudFront and completi…
robertd Feb 18, 2021
efd298f
chore: enable feature flags on all integ tests (#13133)
Feb 18, 2021
6678afe
feat(ecs-patterns): Add support for assignPublicIp for QueueProcessin…
lgvo Feb 18, 2021
3e867da
chore(deps): bump aws-sdk from 2.846.0 to 2.847.0 (#13138)
dependabot-preview[bot] Feb 18, 2021
f886da1
chore(deps-dev): bump @types/node from 10.17.52 to 10.17.53 (#13140)
dependabot-preview[bot] Feb 18, 2021
52940a6
chore(deps-dev): bump @octokit/rest from 18.1.1 to 18.2.0 (#13141)
dependabot-preview[bot] Feb 19, 2021
909563f
fix(core): ENOTDIR invalid cwd on "cdk deploy" (#13145)
Feb 19, 2021
e8c8fae
chore(deps-dev): bump esbuild from 0.8.48 to 0.8.49 (#13149)
dependabot-preview[bot] Feb 19, 2021
80c5d23
chore(cdk): remove expired feature flags from init templates (#13085)
Feb 19, 2021
62e3b92
fix(cfn-diff): handle Fn::If inside policies and statements (#12975)
skinny85 Feb 19, 2021
98d4f34
chore(deps-dev): bump @types/node from 10.17.53 to 10.17.54 (#13161)
dependabot-preview[bot] Feb 19, 2021
9afdaaf
docs(appsync): fix argument in Values.projecting() call (#12855)
Feb 19, 2021
bbb65bc
feat(aws-appsync): add databaseName to rdsDataSource (#12575)
monholm Feb 19, 2021
0b9612e
chore(deps): bump aws-sdk from 2.847.0 to 2.848.0 (#13162)
dependabot-preview[bot] Feb 20, 2021
b83426f
chore(deps-dev): bump lodash from 4.17.20 to 4.17.21 (#13171)
dependabot-preview[bot] Feb 20, 2021
d14b479
fix(eks): `KubectlProvider` creates un-necessary security group (#13178)
iliapolo Feb 21, 2021
e775eb6
docs(s3-deployment): cleanup (#13143)
robertd Feb 21, 2021
948cc07
chore(eks): Misplaced paragraph about endpoint access in the README (…
iliapolo Feb 21, 2021
ff6a054
chore(s3): Default value documentation of `blockPublicAccess` is misl…
iliapolo Feb 21, 2021
6b3ba91
chore(deps-dev): bump esbuild from 0.8.49 to 0.8.50 (#13185)
dependabot-preview[bot] Feb 21, 2021
fe645ed
feat(synthetics): Update CloudWatch Synthetics NodeJS runtimes (#12907)
naamancampbell Feb 21, 2021
f0724d7
fix(appsync): revert to allow resolver creation from data source (#12…
BryanPan342 Feb 22, 2021
837fb23
chore: npm-check-updates && yarn upgrade (#13190)
NetaNir Feb 22, 2021
6b332f1
chore: do not use Dependabot for npm dependencies (#13047)
Feb 22, 2021
d5866bf
update elasticsearch tests
Feb 22, 2021
0eb53f7
Merge remote-tracking branch 'origin/master' into benisrae/stringify-…
Feb 22, 2021
498a59b
update snapshots
Feb 23, 2021
0aa3747
revert core changes
Feb 23, 2021
b39270b
use IResolvable instead of toJSON
Feb 23, 2021
9add57c
Merge remote-tracking branch 'origin/master' into benisrae/stringify-…
Feb 23, 2021
83b93ca
progress
Feb 23, 2021
55aa643
revert change to singleton-lambda code
Feb 23, 2021
318a205
revert merge stuff
Feb 23, 2021
0c38450
update snapshots
Feb 23, 2021
ca6fb69
update snapshots
Feb 23, 2021
85b1355
fix test
Feb 23, 2021
90263c1
update snapshots
Feb 23, 2021
3a3f332
Merge remote-tracking branch 'origin/master' into benisrae/stringify-…
Feb 23, 2021
5b9fa93
update aws-events-targets
Feb 23, 2021
645f442
update snapshots
Feb 23, 2021
cdbf576
restore toJSON
Feb 24, 2021
3ac2523
Merge remote-tracking branch 'origin/master' into benisrae/stringify-…
Feb 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@aws-cdk/core/lib/cfn-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class CfnJson extends CoreConstruct implements IResolvable {
* Normally there is no need to use this property since `CfnJson` is an
* IResolvable, so it can be simply used as a value.
*/
private readonly value: Reference;
eladb marked this conversation as resolved.
Show resolved Hide resolved
public readonly value: Reference;

private readonly jsonString: string;

Expand Down
7 changes: 7 additions & 0 deletions packages/@aws-cdk/core/lib/private/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ export function resolve(obj: any, options: IResolveOptions): any {
throw new Error('Trying to resolve() a Construct at ' + pathName);
}

// respect JavaScript's toJSON(): if the object has a toJSON() method, call it
// and continue with the returned value.
if ('toJSON' in obj && typeof(obj.toJSON) === 'function') {
eladb marked this conversation as resolved.
Show resolved Hide resolved
const value = obj.toJSON();
return resolve(value, options);
}

const result: any = { };
for (const key of Object.keys(obj)) {
const resolvedKey = makeContext()[0].resolve(key);
Expand Down
16 changes: 16 additions & 0 deletions packages/@aws-cdk/core/test/cloudformation-json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,22 @@ nodeunitShim({

test.done();
},

'Respects toJSON() methods on objects'(test: Test) {
// GIVEN
const app = new App();
const stack = new Stack(app, 'Stack1');
class Foo {
toJSON() { return 1234; }
}

// WHEN
const actual = stack.toJsonString(new Foo());

// THEN
expect(stack.resolve(actual)).toStrictEqual(JSON.stringify(1234));
test.done();
},
});

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,9 @@ export class AwsCustomResource extends CoreConstruct implements iam.IGrantable {
serviceToken: provider.functionArn,
pascalCaseProperties: true,
properties: {
create: create && encodeBooleans(create),
update: props.onUpdate && encodeBooleans(props.onUpdate),
delete: props.onDelete && encodeBooleans(props.onDelete),
create: create && this.encodeJson(create),
update: props.onUpdate && this.encodeJson(props.onUpdate),
delete: props.onDelete && this.encodeJson(props.onDelete),
installLatestAwsSdk: props.installLatestAwsSdk ?? true,
},
});
Expand Down Expand Up @@ -418,6 +418,9 @@ export class AwsCustomResource extends CoreConstruct implements iam.IGrantable {
return this.customResource.getAttString(dataPath);
}

private encodeJson(obj: any) {
return cdk.Stack.of(this).toJsonString(obj);
}
}

/**
Expand Down Expand Up @@ -452,19 +455,3 @@ function awsSdkToIamAction(service: string, action: string): string {
const iamAction = action.charAt(0).toUpperCase() + action.slice(1);
return `${iamService}:${iamAction}`;
}

/**
* Encodes booleans as special strings
*/
function encodeBooleans(object: object) {
return JSON.parse(JSON.stringify(object), (_k, v) => {
switch (v) {
case true:
return 'TRUE:BOOLEAN';
case false:
return 'FALSE:BOOLEAN';
default:
return v;
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,11 @@ export function flatten(object: object): { [key: string]: string } {
}

/**
* Decodes encoded special values (booleans and physicalResourceId)
* Decodes encoded special values (physicalResourceId)
*/
function decodeSpecialValues(object: object, physicalResourceId: string) {
return JSON.parse(JSON.stringify(object), (_k, v) => {
switch (v) {
case 'TRUE:BOOLEAN':
return true;
case 'FALSE:BOOLEAN':
return false;
case PHYSICAL_RESOURCE_ID_REFERENCE:
return physicalResourceId;
default:
Expand Down Expand Up @@ -96,6 +92,9 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent
console.log(JSON.stringify(event));
console.log('AWS SDK VERSION: ' + AWS.VERSION);

event.ResourceProperties.Create = decodeCall(event.ResourceProperties.Create);
event.ResourceProperties.Update = decodeCall(event.ResourceProperties.Update);
event.ResourceProperties.Delete = decodeCall(event.ResourceProperties.Delete);
// Default physical resource id
let physicalResourceId: string;
switch (event.RequestType) {
Expand Down Expand Up @@ -185,3 +184,8 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent
});
}
}

function decodeCall(call: string | undefined) {
if (!call) { return undefined; }
return JSON.parse(call);
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ test('create event with physical resource id path', async () => {
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
Create: {
Create: JSON.stringify({
service: 'S3',
action: 'listObjects',
parameters: {
Bucket: 'my-bucket',
},
physicalResourceId: PhysicalResourceId.fromResponse('Contents.1.ETag'),
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand Down Expand Up @@ -98,15 +98,15 @@ test('update event with physical resource id', async () => {
OldResourceProperties: {},
ResourceProperties: {
ServiceToken: 'token',
Update: {
Update: JSON.stringify({
service: 'SNS',
action: 'publish',
parameters: {
Message: 'hello',
TopicArn: 'topicarn',
},
physicalResourceId: PhysicalResourceId.of('topicarn'),
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand All @@ -131,14 +131,14 @@ test('delete event', async () => {
PhysicalResourceId: 'physicalResourceId',
ResourceProperties: {
ServiceToken: 'token',
Create: {
Create: JSON.stringify({
service: 'S3',
action: 'listObjects',
parameters: {
Bucket: 'my-bucket',
},
physicalResourceId: PhysicalResourceId.fromResponse('Contents.1.ETag'),
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand Down Expand Up @@ -166,13 +166,13 @@ test('delete event with Delete call and no physical resource id in call', async
PhysicalResourceId: 'physicalResourceId',
ResourceProperties: {
ServiceToken: 'token',
Delete: {
Delete: JSON.stringify({
service: 'SSM',
action: 'deleteParameter',
parameters: {
Name: 'my-param',
},
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand Down Expand Up @@ -200,13 +200,13 @@ test('create event with Delete call only', async () => {
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
Delete: {
Delete: JSON.stringify({
service: 'SSM',
action: 'deleteParameter',
parameters: {
Name: 'my-param',
},
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand Down Expand Up @@ -234,15 +234,15 @@ test('catch errors', async () => {
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
Create: {
Create: JSON.stringify({
service: 'S3',
action: 'listObjects',
parameters: {
Bucket: 'my-bucket',
},
physicalResourceId: PhysicalResourceId.of('physicalResourceId'),
ignoreErrorCodesMatching: 'NoSuchBucket',
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand All @@ -257,68 +257,6 @@ test('catch errors', async () => {
expect(request.isDone()).toBeTruthy();
});

test('decodes booleans', async () => {
const putItemFake = sinon.fake.resolves({});

AWS.mock('DynamoDB', 'putItem', putItemFake);

const event: AWSLambda.CloudFormationCustomResourceCreateEvent = {
...eventCommon,
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
Create: {
service: 'DynamoDB',
action: 'putItem',
parameters: {
TableName: 'table',
Item: {
True: {
BOOL: 'TRUE:BOOLEAN',
},
TrueString: {
S: 'true',
},
False: {
BOOL: 'FALSE:BOOLEAN',
},
FalseString: {
S: 'false',
},
},
},
physicalResourceId: PhysicalResourceId.of('put-item'),
} as AwsSdkCall,
},
};

const request = createRequest(body =>
body.Status === 'SUCCESS',
);

await handler(event, {} as AWSLambda.Context);

sinon.assert.calledWith(putItemFake, {
TableName: 'table',
Item: {
True: {
BOOL: true,
},
TrueString: {
S: 'true',
},
False: {
BOOL: false,
},
FalseString: {
S: 'false',
},
},
});

expect(request.isDone()).toBeTruthy();
});

test('restrict output path', async () => {
const listObjectsFake = sinon.fake.resolves({
Contents: [
Expand All @@ -340,15 +278,15 @@ test('restrict output path', async () => {
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
Create: {
Create: JSON.stringify({
service: 'S3',
action: 'listObjects',
parameters: {
Bucket: 'my-bucket',
},
physicalResourceId: PhysicalResourceId.of('id'),
outputPath: 'Contents.0',
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand All @@ -374,7 +312,7 @@ test('can specify apiVersion and region', async () => {
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
Create: {
Create: JSON.stringify({
service: 'SNS',
action: 'publish',
parameters: {
Expand All @@ -384,7 +322,7 @@ test('can specify apiVersion and region', async () => {
apiVersion: '2010-03-31',
region: 'eu-west-1',
physicalResourceId: PhysicalResourceId.of('id'),
} as AwsSdkCall,
} as AwsSdkCall),
},
};

Expand Down Expand Up @@ -454,15 +392,15 @@ test('installs the latest SDK', async () => {
RequestType: 'Create',
ResourceProperties: {
ServiceToken: 'token',
Create: {
Create: JSON.stringify({
service: 'SNS',
action: 'publish',
parameters: {
Message: 'message',
TopicArn: 'topic',
},
physicalResourceId: PhysicalResourceId.of('id'),
} as AwsSdkCall,
} as AwsSdkCall),
InstallLatestAwsSdk: 'true',
},
};
Expand Down
Loading