From b7fbd1a15def7848d4300e8f230e18631d93230f Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 28 Jun 2019 11:50:25 +0200 Subject: [PATCH] feat(core): add Tokenization.isResolvable for aspects Add an example of a validating aspect, add `Tokenization.isResolvable()` to make it easier/possible to rule out `IResolvable`s from L1 properties. Included unit tests validates that the bug reported in #3026 is not systemic. --- packages/@aws-cdk/aws-s3/test/test.aspect.ts | 52 ++++++++++++++++++++ packages/@aws-cdk/core/lib/token.ts | 11 +++++ packages/@aws-cdk/core/package-lock.json | 2 +- packages/aws-cdk/package-lock.json | 2 +- 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 packages/@aws-cdk/aws-s3/test/test.aspect.ts diff --git a/packages/@aws-cdk/aws-s3/test/test.aspect.ts b/packages/@aws-cdk/aws-s3/test/test.aspect.ts new file mode 100644 index 0000000000000..29a5ae07e46ae --- /dev/null +++ b/packages/@aws-cdk/aws-s3/test/test.aspect.ts @@ -0,0 +1,52 @@ +// import { expect, haveResource, haveResourceLike, SynthUtils } from '@aws-cdk/assert'; +import { SynthUtils } from '@aws-cdk/assert'; +import cdk = require('@aws-cdk/core'); +import { Stack, Tokenization } from '@aws-cdk/core'; +import { Test } from 'nodeunit'; +import s3 = require('../lib'); + +export = { + 'bucket must have versioning: failure'(test: Test) { + // GIVEN + const stack = new Stack(); + new s3.Bucket(stack, 'MyBucket'); + + // WHEN + stack.node.applyAspect(new BucketVersioningChecker()); + + // THEN + const assembly = SynthUtils.synthesize(stack); + const errorMessage = assembly.messages.find(m => m.entry.data === 'Bucket versioning is not enabled'); + test.ok(errorMessage, 'Error message not reported'); + + test.done(); + }, + + 'bucket must have versioning: success'(test: Test) { + // GIVEN + const stack = new Stack(); + new s3.Bucket(stack, 'MyBucket', { + versioned: true + }); + + // WHEN + stack.node.applyAspect(new BucketVersioningChecker()); + + // THEN + const assembly = SynthUtils.synthesize(stack); + test.deepEqual(assembly.messages, []); + + test.done(); + }, +}; + +class BucketVersioningChecker implements cdk.IAspect { + public visit(node: cdk.IConstruct): void { + if (node instanceof s3.CfnBucket) { + if (!node.versioningConfiguration || + (!Tokenization.isResolvable(node.versioningConfiguration) && node.versioningConfiguration.status !== 'Enabled')) { + node.node.addError('Bucket versioning is not enabled'); + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/core/lib/token.ts b/packages/@aws-cdk/core/lib/token.ts index e5c5127873943..ddb2856d756e1 100644 --- a/packages/@aws-cdk/core/lib/token.ts +++ b/packages/@aws-cdk/core/lib/token.ts @@ -114,6 +114,17 @@ export class Tokenization { return resolve(obj, options); } + /** + * Return whether the given object is an IResolvable object + * + * This is different from Token.isUnresolved() which will also check for + * encoded Tokens, whereas this method will only do a type check on the given + * object. + */ + public static isResolvable(obj: any): obj is IResolvable { + return isResolvableObject(obj); + } + private constructor() { } } diff --git a/packages/@aws-cdk/core/package-lock.json b/packages/@aws-cdk/core/package-lock.json index f5839593207f3..a87b1452be9a1 100644 --- a/packages/@aws-cdk/core/package-lock.json +++ b/packages/@aws-cdk/core/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/core", - "version": "0.35.0", + "version": "0.36.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/aws-cdk/package-lock.json b/packages/aws-cdk/package-lock.json index 5cf170ac1a8ce..13eea297f04f6 100644 --- a/packages/aws-cdk/package-lock.json +++ b/packages/aws-cdk/package-lock.json @@ -1,6 +1,6 @@ { "name": "aws-cdk", - "version": "0.35.0", + "version": "0.36.0", "lockfileVersion": 1, "requires": true, "dependencies": {