From 006954d837054590172f829e669dbd7b17a14c46 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 11:28:56 +0300 Subject: [PATCH 01/14] feat(core): facility to warn when using deprecated apis Introduce `Annotations.addDeprecation()` which will attach a warning to the construct indicating that a deprecated API is used. At the moment, we only use this to warn when `.node` is used instead of `.construct`, but we will gradually use this to report the usage of all deprecated APIs as a preparation for v2.0. If the environment variable `CDK_BLOCK_DEPRECATIONS` is set (and it is set in `cdk-test`), it will cause usage of deprecated APIs to throw an error instead. Related: https://github.com/aws/aws-cdk-rfcs/issues/192 --- packages/@aws-cdk/core/lib/annotations.ts | 49 +++++++++- .../@aws-cdk/core/lib/construct-compat.ts | 24 ++--- .../@aws-cdk/core/test/test.annotations.ts | 95 +++++++++++++++++++ tools/cdk-build-tools/bin/cdk-test.ts | 3 +- 4 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 packages/@aws-cdk/core/test/test.annotations.ts diff --git a/packages/@aws-cdk/core/lib/annotations.ts b/packages/@aws-cdk/core/lib/annotations.ts index 8f13e09987035..838a5d4fab2b1 100644 --- a/packages/@aws-cdk/core/lib/annotations.ts +++ b/packages/@aws-cdk/core/lib/annotations.ts @@ -1,6 +1,8 @@ import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import { IConstruct } from './construct-compat'; +const DEPRECATIONS_SYMBOL = Symbol.for('@aws-cdk/core.deprecations'); + /** * Includes API for attaching annotations such as warning messages to constructs. */ @@ -49,6 +51,38 @@ export class Annotations { this.addMessage(cxschema.ArtifactMetadataEntryType.ERROR, message); } + /** + * Adds a deprecation warning for a specific API. + * + * Deprecations will be added only once per construct as a warning and will be + * deduplicated based on the `api`. + * + * If the environment variable `CDK_BLOCK_DEPRECATIONS` is set, this method + * will throw an error instead with the deprecation message. + * + * @param api The API being deprecated in the format `module.Class.property` + * (e.g. `@aws-cdk/core.Construct.node`). + * @param message The deprecation message to display, with information about + * alternatives. + */ + public addDeprecation(api: string, message: string) { + const text = `The API ${api} is deprecated: ${message}. This API should will be removed in the next major version of the AWS CDK`; + + // throw if CDK_BLOCK_DEPRECATIONS is set + if (process.env.CDK_BLOCK_DEPRECATIONS) { + throw new Error(`${this.scope.construct.path}: ${text}`); + } + + // de-dup based on api key + const set = this.deprecationsReported; + if (set.has(api)) { + return; + } + + this.addWarning(text); + set.add(api); + } + /** * Adds a message metadata entry to the construct node, to be displayed by the CDK CLI. * @param level The message level @@ -57,4 +91,17 @@ export class Annotations { private addMessage(level: string, message: string) { this.scope.node.addMetadata(level, message); } -} \ No newline at end of file + + /** + * Returns the set of deprecations reported on this construct. + */ + private get deprecationsReported() { + let set = (this.scope as any)[DEPRECATIONS_SYMBOL]; + if (!set) { + set = new Set(); + Object.defineProperty(this.scope, DEPRECATIONS_SYMBOL, { value: set }); + } + + return set; + } +} diff --git a/packages/@aws-cdk/core/lib/construct-compat.ts b/packages/@aws-cdk/core/lib/construct-compat.ts index 6b3832ecba636..ecfc9ce50ef99 100644 --- a/packages/@aws-cdk/core/lib/construct-compat.ts +++ b/packages/@aws-cdk/core/lib/construct-compat.ts @@ -64,15 +64,6 @@ export class Construct extends constructs.Construct implements IConstruct { return typeof x === 'object' && x !== null && CONSTRUCT_SYMBOL in x; } - /** - * The construct tree node associated with this construct. - * - * @deprecate `Construct.node` is being deprecated in favor of - * `Construct.construct`. This API will be removed in the next major version - * of the AWS CDK, please migrate your code to use `construct` instead. - */ - public readonly node: ConstructNode; - /** * Construct API. */ @@ -91,8 +82,7 @@ export class Construct extends constructs.Construct implements IConstruct { } Object.defineProperty(this, CONSTRUCT_SYMBOL, { value: true }); - this.node = ConstructNode._unwrap(constructs.Node.of(this)); - this.construct = this.node; + this.construct = ConstructNode._unwrap(constructs.Node.of(this)); const disableTrace = this.construct.tryGetContext(cxapi.DISABLE_METADATA_STACK_TRACE) || @@ -106,6 +96,18 @@ export class Construct extends constructs.Construct implements IConstruct { } } + /** + * The construct tree node associated with this construct. + * + * @deprecate `Construct.node` is being deprecated in favor of + * `Construct.construct`. This API will be removed in the next major version + * of the AWS CDK, please migrate your code to use `construct` instead. + */ + public get node(): ConstructNode { + Annotations.of(this).addDeprecation('@aws-cdk/core.Construct.node', 'Use "@aws-cdk/core.Construct.construct" instead'); + return this.construct; + } + /** * Validate the current construct. * diff --git a/packages/@aws-cdk/core/test/test.annotations.ts b/packages/@aws-cdk/core/test/test.annotations.ts new file mode 100644 index 0000000000000..1065d95033fd0 --- /dev/null +++ b/packages/@aws-cdk/core/test/test.annotations.ts @@ -0,0 +1,95 @@ +import { CloudAssembly } from '@aws-cdk/cx-api'; +import { Test } from 'nodeunit'; +import { Construct, App, Stack } from '../lib'; +import { Annotations } from '../lib/annotations'; + +const restore = process.env.CDK_BLOCK_DEPRECATIONS; + +export = { + 'tearDown'(cb: any) { + process.env.CDK_BLOCK_DEPRECATIONS = restore; // restore to the original value + cb(); + }, + + 'addDeprecation() annotates the usage of a deprecated API'(test: Test) { + // GIVEN + const app = new App(); + const stack = new Stack(app, 'MyStack'); + const c1 = new Construct(stack, 'Hello'); + + // WHEN + delete process.env.CDK_BLOCK_DEPRECATIONS; + Annotations.of(c1).addDeprecation('@aws-cdk/core.Construct.node', 'use @aws-cdk.Construct.construct instead'); + + // THEN + test.deepEqual(getWarnings(app.synth()), [ + { + path: '/MyStack/Hello', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + }, + ]); + test.done(); + }, + + 'deduplicated per node based on "api"'(test: Test) { + // GIVEN + const app = new App(); + const stack1 = new Stack(app, 'MyStack1'); + const stack2 = new Stack(app, 'MyStack2'); + const c1 = new Construct(stack1, 'Hello'); + const c2 = new Construct(stack1, 'World'); + const c3 = new Construct(stack2, 'FooBar'); + + // WHEN + delete process.env.CDK_BLOCK_DEPRECATIONS; + Annotations.of(c1).addDeprecation('@aws-cdk/core.Construct.node', 'use @aws-cdk.Construct.construct instead'); + Annotations.of(c2).addDeprecation('@aws-cdk/core.Construct.node', 'use @aws-cdk.Construct.construct instead'); + Annotations.of(c1).addDeprecation('@aws-cdk/core.Construct.node', 'use @aws-cdk.Construct.construct instead'); + Annotations.of(c3).addDeprecation('@aws-cdk/core.Construct.node', 'use @aws-cdk.Construct.construct instead'); + Annotations.of(c1).addDeprecation('@aws-cdk/core.Construct.node', 'use @aws-cdk.Construct.construct instead'); + Annotations.of(c1).addDeprecation('@aws-cdk/core.Construct.node', 'use @aws-cdk.Construct.construct instead'); + + // THEN + test.deepEqual(getWarnings(app.synth()), [ + { + path: '/MyStack1/Hello', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + }, + { + path: '/MyStack1/World', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + }, + { + path: '/MyStack2/FooBar', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + }, + ]); + test.done(); + }, + + 'CDK_BLOCK_DEPRECATIONS will throw if a deprecated API is used'(test: Test) { + // GIVEN + const app = new App(); + const stack = new Stack(app, 'MyStack'); + const c1 = new Construct(stack, 'Hello'); + + // THEN + process.env.CDK_BLOCK_DEPRECATIONS = '1'; + test.throws(() => Annotations.of(c1).addDeprecation('foo', 'bar'), /MyStack\/Hello: The API foo is deprecated: bar\. This API should will be removed in the next major version of the AWS CDK/); + test.done(); + }, +}; + +function getWarnings(casm: CloudAssembly) { + const result = new Array<{ path: string, message: string }>(); + for (const stack of Object.values(casm.manifest.artifacts ?? {})) { + for (const [path, md] of Object.entries(stack.metadata ?? {})) { + for (const x of md) { + if (x.type === 'aws:cdk:warning') { + result.push({ path, message: x.data as string }); + } + } + } + } + return result; +} \ No newline at end of file diff --git a/tools/cdk-build-tools/bin/cdk-test.ts b/tools/cdk-build-tools/bin/cdk-test.ts index 5a9ad332568ef..ec7ac8f166c5d 100644 --- a/tools/cdk-build-tools/bin/cdk-test.ts +++ b/tools/cdk-build-tools/bin/cdk-test.ts @@ -33,7 +33,8 @@ async function main() { const defaultShellOptions = { timers, env: { - CDK_DISABLE_STACK_TRACE: '1', + CDK_DISABLE_STACK_TRACE: '1', // skip all stack trace collection (expensive) + CDK_BLOCK_DEPRECATIONS: '1', // forbid the usage of deprecated APIs }, }; From 05dc349873b12524cc0c647dc924a1e3fefc4de4 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 12:44:25 +0300 Subject: [PATCH 02/14] Update packages/@aws-cdk/core/lib/construct-compat.ts Co-authored-by: Niranjan Jayakar --- packages/@aws-cdk/core/lib/construct-compat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/core/lib/construct-compat.ts b/packages/@aws-cdk/core/lib/construct-compat.ts index ecfc9ce50ef99..eca8a8b20f8db 100644 --- a/packages/@aws-cdk/core/lib/construct-compat.ts +++ b/packages/@aws-cdk/core/lib/construct-compat.ts @@ -99,7 +99,7 @@ export class Construct extends constructs.Construct implements IConstruct { /** * The construct tree node associated with this construct. * - * @deprecate `Construct.node` is being deprecated in favor of + * @deprecated `Construct.node` is being deprecated in favor of * `Construct.construct`. This API will be removed in the next major version * of the AWS CDK, please migrate your code to use `construct` instead. */ From 102909276b02b9824bbb1b721d56baa375c27694 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 13:53:20 +0300 Subject: [PATCH 03/14] Update annotations.ts --- packages/@aws-cdk/core/lib/annotations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/core/lib/annotations.ts b/packages/@aws-cdk/core/lib/annotations.ts index 444e661c6362d..9f016c11f7c51 100644 --- a/packages/@aws-cdk/core/lib/annotations.ts +++ b/packages/@aws-cdk/core/lib/annotations.ts @@ -66,7 +66,7 @@ export class Annotations { * alternatives. */ public addDeprecation(api: string, message: string) { - const text = `The API ${api} is deprecated: ${message}. This API should will be removed in the next major version of the AWS CDK`; + const text = `The API ${api} is deprecated: ${message}. This API will be removed in the next major release`; // throw if CDK_BLOCK_DEPRECATIONS is set if (process.env.CDK_BLOCK_DEPRECATIONS) { From 4df5d1b0fb21a96887c7672d8b1f37f9a729a0d5 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 13:53:38 +0300 Subject: [PATCH 04/14] Update test.annotations.ts --- packages/@aws-cdk/core/test/test.annotations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/core/test/test.annotations.ts b/packages/@aws-cdk/core/test/test.annotations.ts index 1065d95033fd0..50eedc5038457 100644 --- a/packages/@aws-cdk/core/test/test.annotations.ts +++ b/packages/@aws-cdk/core/test/test.annotations.ts @@ -25,7 +25,7 @@ export = { test.deepEqual(getWarnings(app.synth()), [ { path: '/MyStack/Hello', - message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API will be removed in the next major release', }, ]); test.done(); @@ -92,4 +92,4 @@ function getWarnings(casm: CloudAssembly) { } } return result; -} \ No newline at end of file +} From d90bdf85881f8faa75bf780d04aea432032472f9 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 14:01:51 +0300 Subject: [PATCH 05/14] Update test.annotations.ts --- packages/@aws-cdk/core/test/test.annotations.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/core/test/test.annotations.ts b/packages/@aws-cdk/core/test/test.annotations.ts index 50eedc5038457..4a193452a95c2 100644 --- a/packages/@aws-cdk/core/test/test.annotations.ts +++ b/packages/@aws-cdk/core/test/test.annotations.ts @@ -53,15 +53,15 @@ export = { test.deepEqual(getWarnings(app.synth()), [ { path: '/MyStack1/Hello', - message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API will be removed in the next major release', }, { path: '/MyStack1/World', - message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API will be removed in the next major release', }, { path: '/MyStack2/FooBar', - message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API should will be removed in the next major version of the AWS CDK', + message: 'The API @aws-cdk/core.Construct.node is deprecated: use @aws-cdk.Construct.construct instead. This API will be removed in the next major release', }, ]); test.done(); @@ -75,7 +75,7 @@ export = { // THEN process.env.CDK_BLOCK_DEPRECATIONS = '1'; - test.throws(() => Annotations.of(c1).addDeprecation('foo', 'bar'), /MyStack\/Hello: The API foo is deprecated: bar\. This API should will be removed in the next major version of the AWS CDK/); + test.throws(() => Annotations.of(c1).addDeprecation('foo', 'bar'), /MyStack\/Hello: The API foo is deprecated: bar\. This API will be removed in the next major release/); test.done(); }, }; From 31d41985caf41b06ed2ea4debed41ed0fe2a77dd Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 14:24:04 +0300 Subject: [PATCH 06/14] fixup --- .../@aws-cdk/aws-codepipeline/test/test.general-validation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts b/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts index d1d4f288e8563..35260a5ee00a6 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts @@ -49,7 +49,7 @@ export = { const stack = new cdk.Stack(); const pipeline = new Pipeline(stack, 'Pipeline'); - test.deepEqual(cdk.ConstructNode.validate(pipeline.node).length, 1); + test.deepEqual(cdk.ConstructNode.validate(pipeline.construct).length, 1); test.done(); }, @@ -68,7 +68,7 @@ export = { ], }); - test.deepEqual(cdk.ConstructNode.validate(pipeline.node).length, 1); + test.deepEqual(cdk.ConstructNode.validate(pipeline.construct).length, 1); test.done(); }, From 8a9125f45dd398f9efed2e1d0cfa7fe7675b2d9a Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 15:25:22 +0300 Subject: [PATCH 07/14] export Annotations from core --- packages/@aws-cdk/core/lib/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/@aws-cdk/core/lib/index.ts b/packages/@aws-cdk/core/lib/index.ts index 6c54a222901d6..d18b91b3e70f2 100644 --- a/packages/@aws-cdk/core/lib/index.ts +++ b/packages/@aws-cdk/core/lib/index.ts @@ -37,6 +37,7 @@ export * from './stack-trace'; export * from './app'; export * from './context-provider'; export * from './environment'; +export * from './annotations'; export * from './runtime'; export * from './secret-value'; From 298a8c7a3614843668c6ea097e7c9800c5eddb82 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 11 Aug 2020 15:25:29 +0300 Subject: [PATCH 08/14] fixup --- packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts b/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts index dc023846667e3..a65cfb7668fa5 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts @@ -285,7 +285,7 @@ export = { }, }; -function validate(construct: cdk.IConstruct): cdk.ValidationError[] { - cdk.ConstructNode.prepare(construct.node); - return cdk.ConstructNode.validate(construct.node); +function validate(scope: cdk.IConstruct): cdk.ValidationError[] { + cdk.ConstructNode.prepare(scope.construct); + return cdk.ConstructNode.validate(scope.construct); } From 6d9d0b6e1aa5916f9125ef756a6e8b4e5cdde575 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 19 Aug 2020 16:54:43 +0300 Subject: [PATCH 09/14] revert changes related to "node"=>"construct" --- .../@aws-cdk/aws-codepipeline/test/test.artifacts.ts | 6 +++--- .../aws-codepipeline/test/test.general-validation.ts | 4 ++-- packages/@aws-cdk/core/lib/construct-compat.ts | 12 ------------ tools/cdk-build-tools/bin/cdk-test.ts | 3 +-- 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts b/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts index a65cfb7668fa5..dc023846667e3 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.artifacts.ts @@ -285,7 +285,7 @@ export = { }, }; -function validate(scope: cdk.IConstruct): cdk.ValidationError[] { - cdk.ConstructNode.prepare(scope.construct); - return cdk.ConstructNode.validate(scope.construct); +function validate(construct: cdk.IConstruct): cdk.ValidationError[] { + cdk.ConstructNode.prepare(construct.node); + return cdk.ConstructNode.validate(construct.node); } diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts b/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts index 35260a5ee00a6..d1d4f288e8563 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts @@ -49,7 +49,7 @@ export = { const stack = new cdk.Stack(); const pipeline = new Pipeline(stack, 'Pipeline'); - test.deepEqual(cdk.ConstructNode.validate(pipeline.construct).length, 1); + test.deepEqual(cdk.ConstructNode.validate(pipeline.node).length, 1); test.done(); }, @@ -68,7 +68,7 @@ export = { ], }); - test.deepEqual(cdk.ConstructNode.validate(pipeline.construct).length, 1); + test.deepEqual(cdk.ConstructNode.validate(pipeline.node).length, 1); test.done(); }, diff --git a/packages/@aws-cdk/core/lib/construct-compat.ts b/packages/@aws-cdk/core/lib/construct-compat.ts index b3ed1e67a27b1..306e299016f7c 100644 --- a/packages/@aws-cdk/core/lib/construct-compat.ts +++ b/packages/@aws-cdk/core/lib/construct-compat.ts @@ -91,18 +91,6 @@ export class Construct extends constructs.Construct implements IConstruct { } } - /** - * The construct tree node associated with this construct. - * - * @deprecated `Construct.node` is being deprecated in favor of - * `Construct.construct`. This API will be removed in the next major version - * of the AWS CDK, please migrate your code to use `construct` instead. - */ - public get node(): ConstructNode { - Annotations.of(this).addDeprecation('@aws-cdk/core.Construct.node', 'Use "@aws-cdk/core.Construct.construct" instead'); - return this.construct; - } - /** * Validate the current construct. * diff --git a/tools/cdk-build-tools/bin/cdk-test.ts b/tools/cdk-build-tools/bin/cdk-test.ts index ec7ac8f166c5d..5a9ad332568ef 100644 --- a/tools/cdk-build-tools/bin/cdk-test.ts +++ b/tools/cdk-build-tools/bin/cdk-test.ts @@ -33,8 +33,7 @@ async function main() { const defaultShellOptions = { timers, env: { - CDK_DISABLE_STACK_TRACE: '1', // skip all stack trace collection (expensive) - CDK_BLOCK_DEPRECATIONS: '1', // forbid the usage of deprecated APIs + CDK_DISABLE_STACK_TRACE: '1', }, }; From c10429e24c76dce47eab63413fab496bfbafd152 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 19 Aug 2020 16:56:46 +0300 Subject: [PATCH 10/14] add deprecation annotation to applyAspect --- packages/@aws-cdk/core/lib/construct-compat.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/core/lib/construct-compat.ts b/packages/@aws-cdk/core/lib/construct-compat.ts index 306e299016f7c..312ec463a92e6 100644 --- a/packages/@aws-cdk/core/lib/construct-compat.ts +++ b/packages/@aws-cdk/core/lib/construct-compat.ts @@ -447,7 +447,10 @@ export class ConstructNode { * @deprecated This API is going to be removed in the next major version of * the AWS CDK. Please use `Aspects.of(scope).add()` instead. */ - public applyAspect(aspect: IAspect): void { Aspects.of(this.host).add(aspect); } + public applyAspect(aspect: IAspect): void { + Annotations.of(this.host).addDeprecation('@aws-cdk/core.ConstructNode.applyAspect', 'Use "Aspects.of(construct).add(aspect)" instead'); + Aspects.of(this.host).add(aspect); + } /** * All parent scopes of this construct. From b741baa90514ee308739c738004bab53722f1a21 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 19 Aug 2020 16:59:44 +0300 Subject: [PATCH 11/14] fixup --- packages/@aws-cdk/core/lib/annotations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/core/lib/annotations.ts b/packages/@aws-cdk/core/lib/annotations.ts index 17ba15057510e..8ddeedda108a2 100644 --- a/packages/@aws-cdk/core/lib/annotations.ts +++ b/packages/@aws-cdk/core/lib/annotations.ts @@ -70,7 +70,7 @@ export class Annotations { // throw if CDK_BLOCK_DEPRECATIONS is set if (process.env.CDK_BLOCK_DEPRECATIONS) { - throw new Error(`${this.scope.construct.path}: ${text}`); + throw new Error(`${this.scope.node.path}: ${text}`); } // de-dup based on api key From c31e71f69c9722298a3252dc70a428743ae70f89 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 19 Aug 2020 20:04:45 +0300 Subject: [PATCH 12/14] remove usage of applyAspect --- packages/@aws-cdk/aws-s3/test/test.aspect.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-s3/test/test.aspect.ts b/packages/@aws-cdk/aws-s3/test/test.aspect.ts index ba2049b0f993e..e85e4d243dca0 100644 --- a/packages/@aws-cdk/aws-s3/test/test.aspect.ts +++ b/packages/@aws-cdk/aws-s3/test/test.aspect.ts @@ -11,7 +11,7 @@ export = { new s3.Bucket(stack, 'MyBucket'); // WHEN - stack.node.applyAspect(new BucketVersioningChecker()); + cdk.Aspects.of(stack).add(new BucketVersioningChecker()); // THEN const assembly = SynthUtils.synthesize(stack); @@ -29,7 +29,7 @@ export = { }); // WHEN - stack.node.applyAspect(new BucketVersioningChecker()); + cdk.Aspects.of(stack).add(new BucketVersioningChecker()); // THEN const assembly = SynthUtils.synthesize(stack); From dcfc9155633b4413d15a9ec39ac8577d166394c9 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 19 Aug 2020 22:59:11 +0300 Subject: [PATCH 13/14] Remove usage of deprecated aspects and tags APIs --- packages/@aws-cdk/aws-athena/test/athena.test.ts | 4 ++-- .../@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts | 4 ++-- .../aws-autoscaling/test/auto-scaling-group.test.ts | 5 +++-- packages/@aws-cdk/aws-backup/lib/selection.ts | 4 ++-- packages/@aws-cdk/aws-cognito/test/user-pool.test.ts | 4 ++-- packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts | 10 +++++----- .../aws-dynamodb/test/integ.dynamodb.ondemand.ts | 4 ++-- .../@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts | 4 ++-- packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts | 4 ++-- packages/@aws-cdk/aws-ec2/lib/instance.ts | 4 ++-- packages/@aws-cdk/aws-ec2/lib/volume.ts | 10 +++++----- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 10 +++++----- packages/@aws-cdk/aws-ec2/test/volume.test.ts | 2 +- packages/@aws-cdk/aws-ec2/test/vpc.test.ts | 8 ++++---- packages/@aws-cdk/aws-efs/lib/efs-file-system.ts | 4 ++-- packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts | 4 ++-- packages/@aws-cdk/aws-eks-legacy/lib/cluster.ts | 6 +++--- packages/@aws-cdk/aws-eks/lib/cluster.ts | 6 +++--- packages/@aws-cdk/aws-eks/lib/legacy-cluster.ts | 6 +++--- packages/@aws-cdk/aws-eks/test/test.fargate.ts | 6 +++--- packages/@aws-cdk/aws-kms/test/test.key.ts | 8 ++++---- packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts | 2 +- .../aws-s3-notifications/test/notifications.test.ts | 2 +- packages/@aws-cdk/core/lib/tag-aspect.ts | 3 +++ packages/@aws-cdk/pipelines/lib/pipeline.ts | 4 ++-- packages/@aws-cdk/pipelines/lib/stage.ts | 4 ++-- 26 files changed, 68 insertions(+), 64 deletions(-) diff --git a/packages/@aws-cdk/aws-athena/test/athena.test.ts b/packages/@aws-cdk/aws-athena/test/athena.test.ts index 25a43aeec0679..6cadc1a5a8310 100644 --- a/packages/@aws-cdk/aws-athena/test/athena.test.ts +++ b/packages/@aws-cdk/aws-athena/test/athena.test.ts @@ -43,8 +43,8 @@ describe('Athena Workgroup Tags', () => { }); test('test tag aspect spec correction', () => { const stack = new cdk.Stack(); - cdk.Tag.add(stack, 'key1', 'value1'); - cdk.Tag.add(stack, 'key2', 'value2'); + cdk.Tags.of(stack).add('key1', 'value1'); + cdk.Tags.of(stack).add('key2', 'value2'); new CfnWorkGroup(stack, 'Athena-Workgroup', { name: 'HelloWorld', description: 'A WorkGroup', diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index db3de7c3fece2..d3056d32d418a 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -7,7 +7,7 @@ import * as sns from '@aws-cdk/aws-sns'; import { CfnAutoScalingRollingUpdate, Construct, Duration, Fn, IResource, Lazy, PhysicalName, Resource, Stack, - Tag, Tokenization, withResolved, + Tokenization, withResolved, Tags, } from '@aws-cdk/core'; import { CfnAutoScalingGroup, CfnAutoScalingGroupProps, CfnLaunchConfiguration } from './autoscaling.generated'; import { BasicLifecycleHookProps, LifecycleHook } from './lifecycle-hook'; @@ -595,7 +595,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements }); this.connections = new ec2.Connections({ securityGroups: [this.securityGroup] }); this.securityGroups.push(this.securityGroup); - this.node.applyAspect(new Tag(NAME_TAG, this.node.path)); + Tags.of(this).add(NAME_TAG, this.node.path); this.role = props.role || new iam.Role(this, 'InstanceRole', { roleName: PhysicalName.GENERATE_IF_NEEDED, diff --git a/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts b/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts index 67335c9cdf4ea..4e4e800828780 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts @@ -512,8 +512,9 @@ nodeunitShim({ pauseTime: cdk.Duration.seconds(345), }, }); - asg.node.applyAspect(new cdk.Tag('superfood', 'acai')); - asg.node.applyAspect(new cdk.Tag('notsuper', 'caramel', { applyToLaunchedInstances: false })); + + cdk.Tags.of(asg).add('superfood', 'acai'); + cdk.Tags.of(asg).add('notsuper', 'caramel', { applyToLaunchedInstances: false }); // THEN expect(stack).to(haveResource('AWS::AutoScaling::AutoScalingGroup', { diff --git a/packages/@aws-cdk/aws-backup/lib/selection.ts b/packages/@aws-cdk/aws-backup/lib/selection.ts index 735d55974ed6f..6b4c1c37b1b97 100644 --- a/packages/@aws-cdk/aws-backup/lib/selection.ts +++ b/packages/@aws-cdk/aws-backup/lib/selection.ts @@ -1,5 +1,5 @@ import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Lazy, Resource } from '@aws-cdk/core'; +import { Construct, Lazy, Resource, Aspects } from '@aws-cdk/core'; import { CfnBackupSelection } from './backup.generated'; import { BackupableResourcesCollector } from './backupable-resources-collector'; import { IBackupPlan } from './plan'; @@ -126,7 +126,7 @@ export class BackupSelection extends Resource implements iam.IGrantable { } if (resource.construct) { - resource.construct.node.applyAspect(this.backupableResourcesCollector); + Aspects.of(resource.construct).add(this.backupableResourcesCollector); // Cannot push `this.backupableResourcesCollector.resources` to // `this.resources` here because it has not been evaluated yet. // Will be concatenated to `this.resources` in a `Lazy.listValue` diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts index 28f5480ee998d..7576dacdf1c65 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts @@ -2,7 +2,7 @@ import '@aws-cdk/assert/jest'; import { ABSENT } from '@aws-cdk/assert/lib/assertions/have-resource'; import { Role, ServicePrincipal } from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; -import { CfnParameter, Construct, Duration, Stack, Tag } from '@aws-cdk/core'; +import { CfnParameter, Construct, Duration, Stack, Tags } from '@aws-cdk/core'; import { AccountRecovery, Mfa, NumberAttribute, StringAttribute, UserPool, UserPoolIdentityProvider, UserPoolOperation, VerificationEmailStyle } from '../lib'; describe('User Pool', () => { @@ -227,7 +227,7 @@ describe('User Pool', () => { const pool = new UserPool(stack, 'Pool', { userPoolName: 'myPool', }); - Tag.add(pool, 'PoolTag', 'PoolParty'); + Tags.of(pool).add('PoolTag', 'PoolParty'); // THEN expect(stack).toHaveResourceLike('AWS::Cognito::UserPool', { diff --git a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts index b50a78c97fac0..f464f7c03f1f9 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts @@ -3,7 +3,7 @@ import '@aws-cdk/assert/jest'; import * as appscaling from '@aws-cdk/aws-applicationautoscaling'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; -import { App, CfnDeletionPolicy, ConstructNode, Duration, PhysicalName, RemovalPolicy, Stack, Tag } from '@aws-cdk/core'; +import { App, CfnDeletionPolicy, ConstructNode, Duration, PhysicalName, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, @@ -324,7 +324,7 @@ test('when specifying every property', () => { partitionKey: TABLE_PARTITION_KEY, sortKey: TABLE_SORT_KEY, }); - table.node.applyAspect(new Tag('Environment', 'Production')); + Tags.of(table).add('Environment', 'Production'); expect(stack).toHaveResource('AWS::DynamoDB::Table', { @@ -357,7 +357,7 @@ test('when specifying sse with customer managed CMK', () => { encryption: TableEncryption.CUSTOMER_MANAGED, partitionKey: TABLE_PARTITION_KEY, }); - table.node.applyAspect(new Tag('Environment', 'Production')); + Tags.of(table).add('Environment', 'Production'); expect(stack).toHaveResource('AWS::DynamoDB::Table', { 'SSESpecification': { @@ -383,7 +383,7 @@ test('when specifying only encryptionKey', () => { encryptionKey, partitionKey: TABLE_PARTITION_KEY, }); - table.node.applyAspect(new Tag('Environment', 'Production')); + Tags.of(table).add('Environment', 'Production'); expect(stack).toHaveResource('AWS::DynamoDB::Table', { 'SSESpecification': { @@ -410,7 +410,7 @@ test('when specifying sse with customer managed CMK with encryptionKey provided encryptionKey, partitionKey: TABLE_PARTITION_KEY, }); - table.node.applyAspect(new Tag('Environment', 'Production')); + Tags.of(table).add('Environment', 'Production'); expect(stack).toHaveResource('AWS::DynamoDB::Table', { 'SSESpecification': { diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts index 3304c8defec2e..a25f74abd1fd8 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts @@ -1,4 +1,4 @@ -import { App, RemovalPolicy, Stack, Tag } from '@aws-cdk/core'; +import { App, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, BillingMode, ProjectionType, StreamViewType, Table } from '../lib'; // CDK parameters @@ -58,7 +58,7 @@ const tableWithGlobalAndLocalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL removalPolicy: RemovalPolicy.DESTROY, }); -tableWithGlobalAndLocalSecondaryIndex.node.applyAspect(new Tag('Environment', 'Production')); +Tags.of(tableWithGlobalAndLocalSecondaryIndex).add('Environment', 'Production'); tableWithGlobalAndLocalSecondaryIndex.addGlobalSecondaryIndex({ indexName: GSI_TEST_CASE_1, diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts index b1f3dca8b75a3..c4e0524ad04b2 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts @@ -1,6 +1,6 @@ import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; -import { App, RemovalPolicy, Stack, Tag } from '@aws-cdk/core'; +import { App, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, ProjectionType, StreamViewType, Table, TableEncryption } from '../lib'; // CDK parameters @@ -58,7 +58,7 @@ const tableWithGlobalAndLocalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL removalPolicy: RemovalPolicy.DESTROY, }); -tableWithGlobalAndLocalSecondaryIndex.node.applyAspect(new Tag('Environment', 'Production')); +Tags.of(tableWithGlobalAndLocalSecondaryIndex).add('Environment', 'Production'); tableWithGlobalAndLocalSecondaryIndex.addGlobalSecondaryIndex({ indexName: GSI_TEST_CASE_1, partitionKey: GSI_PARTITION_KEY, diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts index 35c81b6486d3b..afb7c2d453867 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts @@ -1,5 +1,5 @@ import * as iam from '@aws-cdk/aws-iam'; -import { App, RemovalPolicy, Stack, Tag } from '@aws-cdk/core'; +import { App, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, ProjectionType, StreamViewType, Table } from '../lib'; // CDK parameters @@ -56,7 +56,7 @@ const tableWithGlobalAndLocalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL removalPolicy: RemovalPolicy.DESTROY, }); -tableWithGlobalAndLocalSecondaryIndex.node.applyAspect(new Tag('Environment', 'Production')); +Tags.of(tableWithGlobalAndLocalSecondaryIndex).add('Environment', 'Production'); tableWithGlobalAndLocalSecondaryIndex.addGlobalSecondaryIndex({ indexName: GSI_TEST_CASE_1, partitionKey: GSI_PARTITION_KEY, diff --git a/packages/@aws-cdk/aws-ec2/lib/instance.ts b/packages/@aws-cdk/aws-ec2/lib/instance.ts index 455b024c62caa..a9ef8112dc379 100644 --- a/packages/@aws-cdk/aws-ec2/lib/instance.ts +++ b/packages/@aws-cdk/aws-ec2/lib/instance.ts @@ -1,7 +1,7 @@ import * as crypto from 'crypto'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Duration, Fn, IResource, Lazy, Resource, Stack, Tag } from '@aws-cdk/core'; +import { Construct, Duration, Fn, IResource, Lazy, Resource, Stack, Tags } from '@aws-cdk/core'; import { CloudFormationInit } from './cfn-init'; import { Connections, IConnectable } from './connections'; import { CfnInstance } from './ec2.generated'; @@ -309,7 +309,7 @@ export class Instance extends Resource implements IInstance { } this.connections = new Connections({ securityGroups: [this.securityGroup] }); this.securityGroups.push(this.securityGroup); - Tag.add(this, NAME_TAG, props.instanceName || this.node.path); + Tags.of(this).add(NAME_TAG, props.instanceName || this.node.path); this.role = props.role || new iam.Role(this, 'InstanceRole', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), diff --git a/packages/@aws-cdk/aws-ec2/lib/volume.ts b/packages/@aws-cdk/aws-ec2/lib/volume.ts index 8817a08025e92..72c9af36fd079 100644 --- a/packages/@aws-cdk/aws-ec2/lib/volume.ts +++ b/packages/@aws-cdk/aws-ec2/lib/volume.ts @@ -2,7 +2,7 @@ import * as crypto from 'crypto'; import { AccountRootPrincipal, Grant, IGrantable } from '@aws-cdk/aws-iam'; import { IKey, ViaServicePrincipal } from '@aws-cdk/aws-kms'; -import { Construct, IResource, Resource, Size, SizeRoundingBehavior, Stack, Tag, Token } from '@aws-cdk/core'; +import { Construct, IResource, Resource, Size, SizeRoundingBehavior, Stack, Token, Tags } from '@aws-cdk/core'; import { CfnInstance, CfnVolume } from './ec2.generated'; import { IInstance } from './instance'; @@ -507,8 +507,8 @@ abstract class VolumeBase extends Resource implements IVolume { // The ResourceTag condition requires that all resources involved in the operation have // the given tag, so we tag this and all constructs given. - Tag.add(this, tagKey, tagValue); - constructs.forEach(construct => Tag.add(construct, tagKey, tagValue)); + Tags.of(this).add(tagKey, tagValue); + constructs.forEach(construct => Tags.of(construct).add(tagKey, tagValue)); return result; } @@ -536,8 +536,8 @@ abstract class VolumeBase extends Resource implements IVolume { // The ResourceTag condition requires that all resources involved in the operation have // the given tag, so we tag this and all constructs given. - Tag.add(this, tagKey, tagValue); - constructs.forEach(construct => Tag.add(construct, tagKey, tagValue)); + Tags.of(this).add(tagKey, tagValue); + constructs.forEach(construct => Tags.of(construct).add(tagKey, tagValue)); return result; } diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 7c4d792fcc684..6fa50c0de2175 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1,7 +1,7 @@ import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import { ConcreteDependable, Construct, ContextProvider, DependableTrait, IConstruct, - IDependable, IResource, Lazy, Resource, Stack, Tag, Token, + IDependable, IResource, Lazy, Resource, Stack, Token, Tags, } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { @@ -1182,7 +1182,7 @@ export class Vpc extends VpcBase { this.vpcDefaultSecurityGroup = this.resource.attrDefaultSecurityGroup; this.vpcIpv6CidrBlocks = this.resource.attrIpv6CidrBlocks; - this.node.applyAspect(new Tag(NAME_TAG, this.node.path)); + Tags.of(this).add(NAME_TAG, this.node.path); this.availabilityZones = stack.availabilityZones; @@ -1369,8 +1369,8 @@ export class Vpc extends VpcBase { // These values will be used to recover the config upon provider import const includeResourceTypes = [CfnSubnet.CFN_RESOURCE_TYPE_NAME]; - subnet.node.applyAspect(new Tag(SUBNETNAME_TAG, subnetConfig.name, { includeResourceTypes })); - subnet.node.applyAspect(new Tag(SUBNETTYPE_TAG, subnetTypeTagValue(subnetConfig.subnetType), { includeResourceTypes })); + Tags.of(subnet).add(SUBNETNAME_TAG, subnetConfig.name, { includeResourceTypes }); + Tags.of(subnet).add(SUBNETTYPE_TAG, subnetTypeTagValue(subnetConfig.subnetType), { includeResourceTypes }); }); } } @@ -1488,7 +1488,7 @@ export class Subnet extends Resource implements ISubnet { Object.defineProperty(this, VPC_SUBNET_SYMBOL, { value: true }); - this.node.applyAspect(new Tag(NAME_TAG, this.node.path)); + Tags.of(this).add(NAME_TAG, this.node.path); this.availabilityZone = props.availabilityZone; const subnet = new CfnSubnet(this, 'Subnet', { diff --git a/packages/@aws-cdk/aws-ec2/test/volume.test.ts b/packages/@aws-cdk/aws-ec2/test/volume.test.ts index 05ae59f8d7a0f..e0d37a232c6d6 100644 --- a/packages/@aws-cdk/aws-ec2/test/volume.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/volume.test.ts @@ -73,7 +73,7 @@ nodeunitShim({ }); // WHEN - cdk.Tag.add(volume, 'TagKey', 'TagValue'); + cdk.Tags.of(volume).add('TagKey', 'TagValue'); // THEN cdkExpect(stack).to(haveResource('AWS::EC2::Volume', { diff --git a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts index ce94f1c9e10ed..87752fef51bdb 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts @@ -1,5 +1,5 @@ import { countResources, expect, haveResource, haveResourceLike, isSuperObject, MatchStyle } from '@aws-cdk/assert'; -import { CfnOutput, Lazy, Stack, Tag } from '@aws-cdk/core'; +import { CfnOutput, Lazy, Stack, Tags } from '@aws-cdk/core'; import { nodeunitShim, Test } from 'nodeunit-shim'; import { AclCidr, AclTraffic, CfnSubnet, CfnVPC, DefaultInstanceTenancy, GenericLinuxImage, InstanceType, InterfaceVpcEndpoint, @@ -1035,8 +1035,8 @@ nodeunitShim({ const vpc = new Vpc(stack, 'TheVPC'); // overwrite to set propagate - vpc.node.applyAspect(new Tag('BusinessUnit', 'Marketing', { includeResourceTypes: [CfnVPC.CFN_RESOURCE_TYPE_NAME] })); - vpc.node.applyAspect(new Tag('VpcType', 'Good')); + Tags.of(vpc).add('BusinessUnit', 'Marketing', { includeResourceTypes: [CfnVPC.CFN_RESOURCE_TYPE_NAME] }); + Tags.of(vpc).add('VpcType', 'Good'); expect(stack).to(haveResource('AWS::EC2::VPC', hasTags(toCfnTags(allTags)))); const taggables = ['Subnet', 'InternetGateway', 'NatGateway', 'RouteTable']; const propTags = toCfnTags(tags); @@ -1067,7 +1067,7 @@ nodeunitShim({ const vpc = new Vpc(stack, 'TheVPC'); const tag = { Key: 'Late', Value: 'Adder' }; expect(stack).notTo(haveResource('AWS::EC2::VPC', hasTags([tag]))); - vpc.node.applyAspect(new Tag(tag.Key, tag.Value)); + Tags.of(vpc).add(tag.Key, tag.Value); expect(stack).to(haveResource('AWS::EC2::VPC', hasTags([tag]))); test.done(); }, diff --git a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts index 854503f388f7d..775eaea806af6 100644 --- a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts +++ b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts @@ -1,6 +1,6 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; -import { ConcreteDependable, Construct, IDependable, IResource, RemovalPolicy, Resource, Size, Tag } from '@aws-cdk/core'; +import { ConcreteDependable, Construct, IDependable, IResource, RemovalPolicy, Resource, Size, Tags } from '@aws-cdk/core'; import { AccessPoint, AccessPointOptions } from './access-point'; import { CfnFileSystem, CfnMountTarget } from './efs.generated'; @@ -255,7 +255,7 @@ export class FileSystem extends Resource implements IFileSystem { filesystem.applyRemovalPolicy(props.removalPolicy); this.fileSystemId = filesystem.ref; - Tag.add(this, 'Name', props.fileSystemName || this.node.path); + Tags.of(this).add('Name', props.fileSystemName || this.node.path); const securityGroup = (props.securityGroup || new ec2.SecurityGroup(this, 'EfsSecurityGroup', { vpc: props.vpc, diff --git a/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts b/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts index 738f81cb12369..02369563bd9a5 100644 --- a/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts +++ b/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts @@ -1,7 +1,7 @@ import { expect as expectCDK, haveResource, ResourcePart } from '@aws-cdk/assert'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; -import { RemovalPolicy, Size, Stack, Tag } from '@aws-cdk/core'; +import { RemovalPolicy, Size, Stack, Tags } from '@aws-cdk/core'; import { FileSystem, LifecyclePolicy, PerformanceMode, ThroughputMode } from '../lib'; let stack = new Stack(); @@ -176,7 +176,7 @@ test('support tags', () => { const fileSystem = new FileSystem(stack, 'EfsFileSystem', { vpc, }); - Tag.add(fileSystem, 'Name', 'LookAtMeAndMyFancyTags'); + Tags.of(fileSystem).add('Name', 'LookAtMeAndMyFancyTags'); // THEN expectCDK(stack).to(haveResource('AWS::EFS::FileSystem', { diff --git a/packages/@aws-cdk/aws-eks-legacy/lib/cluster.ts b/packages/@aws-cdk/aws-eks-legacy/lib/cluster.ts index 49fde85d6d49d..c7597df495297 100644 --- a/packages/@aws-cdk/aws-eks-legacy/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks-legacy/lib/cluster.ts @@ -4,7 +4,7 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import * as ssm from '@aws-cdk/aws-ssm'; -import { CfnOutput, Construct, Duration, IResource, Resource, Stack, Tag, Token } from '@aws-cdk/core'; +import { CfnOutput, Construct, Duration, IResource, Resource, Stack, Token, Tags } from '@aws-cdk/core'; import { AwsAuth } from './aws-auth'; import { ClusterResource } from './cluster-resource'; import { CfnCluster, CfnClusterProps } from './eks.generated'; @@ -523,7 +523,7 @@ export class Cluster extends Resource implements ICluster { autoScalingGroup.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly')); // EKS Required Tags - Tag.add(autoScalingGroup, `kubernetes.io/cluster/${this.clusterName}`, 'owned', { + Tags.of(autoScalingGroup).add(`kubernetes.io/cluster/${this.clusterName}`, 'owned', { applyToLaunchedInstances: true, }); @@ -640,7 +640,7 @@ export class Cluster extends Resource implements ICluster { continue; } - subnet.node.applyAspect(new Tag(tag, '1')); + Tags.of(subnet).add(tag, '1'); } }; diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index 9204f9ff4b475..7db245a814efb 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -4,7 +4,7 @@ import * as autoscaling from '@aws-cdk/aws-autoscaling'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as ssm from '@aws-cdk/aws-ssm'; -import { CfnOutput, CfnResource, Construct, IResource, Resource, Stack, Tag, Token, Duration } from '@aws-cdk/core'; +import { CfnOutput, CfnResource, Construct, IResource, Resource, Stack, Tags, Token, Duration } from '@aws-cdk/core'; import * as YAML from 'yaml'; import { AwsAuth } from './aws-auth'; import { clusterArnComponents, ClusterResource } from './cluster-resource'; @@ -872,7 +872,7 @@ export class Cluster extends Resource implements ICluster { autoScalingGroup.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly')); // EKS Required Tags - Tag.add(autoScalingGroup, `kubernetes.io/cluster/${this.clusterName}`, 'owned', { + Tags.of(autoScalingGroup).add(`kubernetes.io/cluster/${this.clusterName}`, 'owned', { applyToLaunchedInstances: true, }); @@ -1180,7 +1180,7 @@ export class Cluster extends Resource implements ICluster { continue; } - subnet.node.applyAspect(new Tag(tag, '1')); + Tags.of(subnet).add(tag, '1'); } }; diff --git a/packages/@aws-cdk/aws-eks/lib/legacy-cluster.ts b/packages/@aws-cdk/aws-eks/lib/legacy-cluster.ts index 02708d0dc9d0f..7aec7be0cd693 100644 --- a/packages/@aws-cdk/aws-eks/lib/legacy-cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/legacy-cluster.ts @@ -2,7 +2,7 @@ import * as autoscaling from '@aws-cdk/aws-autoscaling'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as ssm from '@aws-cdk/aws-ssm'; -import { CfnOutput, Construct, Resource, Stack, Tag, Token } from '@aws-cdk/core'; +import { CfnOutput, Construct, Resource, Stack, Token, Tags } from '@aws-cdk/core'; import { ICluster, ClusterAttributes, KubernetesVersion, NodeType, DefaultCapacityType, EksOptimizedImage, CapacityOptions, MachineImageType, AutoScalingGroupOptions, CommonClusterOptions } from './cluster'; import { clusterArnComponents } from './cluster-resource'; import { CfnCluster, CfnClusterProps } from './eks.generated'; @@ -327,7 +327,7 @@ export class LegacyCluster extends Resource implements ICluster { autoScalingGroup.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly')); // EKS Required Tags - Tag.add(autoScalingGroup, `kubernetes.io/cluster/${this.clusterName}`, 'owned', { + Tags.of(autoScalingGroup).add(`kubernetes.io/cluster/${this.clusterName}`, 'owned', { applyToLaunchedInstances: true, }); @@ -361,7 +361,7 @@ export class LegacyCluster extends Resource implements ICluster { continue; } - subnet.node.applyAspect(new Tag(tag, '1')); + Tags.of(subnet).add(tag, '1'); } }; diff --git a/packages/@aws-cdk/aws-eks/test/test.fargate.ts b/packages/@aws-cdk/aws-eks/test/test.fargate.ts index f490d3f38df10..2787122883b82 100644 --- a/packages/@aws-cdk/aws-eks/test/test.fargate.ts +++ b/packages/@aws-cdk/aws-eks/test/test.fargate.ts @@ -1,7 +1,7 @@ import { expect, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/assert'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; -import { Stack, Tag } from '@aws-cdk/core'; +import { Stack, Tags } from '@aws-cdk/core'; import { Test } from 'nodeunit'; import * as eks from '../lib'; @@ -85,8 +85,8 @@ export = { selectors: [{ namespace: 'default' }], }); - Tag.add(stack, 'aspectTag', 'hello'); - Tag.add(cluster, 'propTag', '123'); + Tags.of(stack).add('aspectTag', 'hello'); + Tags.of(cluster).add('propTag', '123'); // THEN expect(stack).to(haveResource('Custom::AWSCDK-EKS-FargateProfile', { diff --git a/packages/@aws-cdk/aws-kms/test/test.key.ts b/packages/@aws-cdk/aws-kms/test/test.key.ts index a428ea1c05f73..bcbaaec7f1c13 100644 --- a/packages/@aws-cdk/aws-kms/test/test.key.ts +++ b/packages/@aws-cdk/aws-kms/test/test.key.ts @@ -8,7 +8,7 @@ import { SynthUtils, } from '@aws-cdk/assert'; import * as iam from '@aws-cdk/aws-iam'; -import { App, CfnOutput, RemovalPolicy, Stack, Tag } from '@aws-cdk/core'; +import { App, CfnOutput, RemovalPolicy, Stack, Tags } from '@aws-cdk/core'; import { Test } from 'nodeunit'; import { Key } from '../lib'; @@ -160,9 +160,9 @@ export = { p.addArnPrincipal('arn'); key.addToResourcePolicy(p); - key.node.applyAspect(new Tag('tag1', 'value1')); - key.node.applyAspect(new Tag('tag2', 'value2')); - key.node.applyAspect(new Tag('tag3', '')); + Tags.of(key).add('tag1', 'value1'); + Tags.of(key).add('tag2', 'value2'); + Tags.of(key).add('tag3', ''); expect(stack).to(exactlyMatchTemplate({ Resources: { diff --git a/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts b/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts index 45eaed8e8cafb..37d80a5908a9b 100644 --- a/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts @@ -39,7 +39,7 @@ export = { const hostedZone = new HostedZone(stack, 'HostedZone', { zoneName: 'test.zone', }); - cdk.Tag.add(hostedZone, 'zoneTag', 'inMyZone'); + cdk.Tags.of(hostedZone).add('zoneTag', 'inMyZone'); // THEN expect(stack).toMatch({ diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts b/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts index c919f1473aa4b..8c826e9217204 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts +++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts @@ -39,7 +39,7 @@ test('when notification are added, a custom resource is provisioned + a lambda h test('when notification are added, you can tag the lambda', () => { const stack = new cdk.Stack(); - stack.node.applyAspect(new cdk.Tag('Lambda', 'AreTagged')); + cdk.Tags.of(stack).add('Lambda', 'AreTagged'); const bucket = new s3.Bucket(stack, 'MyBucket'); diff --git a/packages/@aws-cdk/core/lib/tag-aspect.ts b/packages/@aws-cdk/core/lib/tag-aspect.ts index 3c8fd7b01a6b8..34d9a6dfd4e40 100644 --- a/packages/@aws-cdk/core/lib/tag-aspect.ts +++ b/packages/@aws-cdk/core/lib/tag-aspect.ts @@ -2,6 +2,7 @@ import { IAspect, Aspects } from './aspect'; import { Construct, IConstruct } from './construct-compat'; import { ITaggable, TagManager } from './tag-manager'; +import { Annotations } from './annotations'; /** * Properties for a tag @@ -91,6 +92,7 @@ export class Tag extends TagBase { * @deprecated use `Tags.of(scope).add()` */ public static add(scope: Construct, key: string, value: string, props: TagProps = {}) { + Annotations.of(scope).addDeprecation('@aws-cdk/core.Tag.add(scope,k,v)', 'Use "Tags.of(scope).add(k,v)" instead'); Tags.of(scope).add(key, value, props); } @@ -100,6 +102,7 @@ export class Tag extends TagBase { * @deprecated use `Tags.of(scope).remove()` */ public static remove(scope: Construct, key: string, props: TagProps = {}) { + Annotations.of(scope).addDeprecation('@aws-cdk/core.Tag.remove(scope,k,v)', 'Use "Tags.of(scope).remove(k,v)" instead'); Tags.of(scope).remove(key, props); } diff --git a/packages/@aws-cdk/pipelines/lib/pipeline.ts b/packages/@aws-cdk/pipelines/lib/pipeline.ts index f20021b34d1a8..6b63c6216b959 100644 --- a/packages/@aws-cdk/pipelines/lib/pipeline.ts +++ b/packages/@aws-cdk/pipelines/lib/pipeline.ts @@ -1,7 +1,7 @@ import * as path from 'path'; import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as iam from '@aws-cdk/aws-iam'; -import { App, CfnOutput, Construct, PhysicalName, Stack, Stage } from '@aws-cdk/core'; +import { App, CfnOutput, Construct, PhysicalName, Stack, Stage, Aspects } from '@aws-cdk/core'; import { AssetType, DeployCdkStackAction, PublishAssetsAction, UpdatePipelineAction } from './actions'; import { appOf, assemblyBuilderOf } from './private/construct-internals'; import { AddStageOptions, AssetPublishingCommand, CdkStage, StackOutput } from './stage'; @@ -103,7 +103,7 @@ export class CdkPipeline extends Construct { projectName: maybeSuffix(props.pipelineName, '-publish'), }); - this.node.applyAspect({ visit: () => this._assets.removeAssetsStageIfEmpty() }); + Aspects.of(this).add({ visit: () => this._assets.removeAssetsStageIfEmpty() }); } /** diff --git a/packages/@aws-cdk/pipelines/lib/stage.ts b/packages/@aws-cdk/pipelines/lib/stage.ts index dd5aa28c5e50e..e916d8131c7a2 100644 --- a/packages/@aws-cdk/pipelines/lib/stage.ts +++ b/packages/@aws-cdk/pipelines/lib/stage.ts @@ -1,6 +1,6 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as cpactions from '@aws-cdk/aws-codepipeline-actions'; -import { Construct, Stage } from '@aws-cdk/core'; +import { Construct, Stage, Aspects } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { AssetType, DeployCdkStackAction } from './actions'; import { AssetManifestReader, DockerImageManifestEntry, FileManifestEntry } from './private/asset-manifest'; @@ -55,7 +55,7 @@ export class CdkStage extends Construct { this.cloudAssemblyArtifact = props.cloudAssemblyArtifact; this.host = props.host; - this.node.applyAspect({ visit: () => this.prepareStage() }); + Aspects.of(this).add({ visit: () => this.prepareStage() }); } /** From c1f4b9dca63dde1ca16851c53698a8b8dec69773 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 20 Aug 2020 14:56:33 +0300 Subject: [PATCH 14/14] fix compilation issues --- packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts | 2 +- packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts | 2 +- packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts | 2 +- packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts index f464f7c03f1f9..4e52868bd6a92 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts @@ -3,7 +3,7 @@ import '@aws-cdk/assert/jest'; import * as appscaling from '@aws-cdk/aws-applicationautoscaling'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; -import { App, CfnDeletionPolicy, ConstructNode, Duration, PhysicalName, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; +import { App, CfnDeletionPolicy, ConstructNode, Duration, PhysicalName, RemovalPolicy, Stack, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts index a25f74abd1fd8..83495c01355cd 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts @@ -1,4 +1,4 @@ -import { App, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; +import { App, RemovalPolicy, Stack, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, BillingMode, ProjectionType, StreamViewType, Table } from '../lib'; // CDK parameters diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts index c4e0524ad04b2..de077281b7479 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.ts @@ -1,6 +1,6 @@ import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; -import { App, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; +import { App, RemovalPolicy, Stack, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, ProjectionType, StreamViewType, Table, TableEncryption } from '../lib'; // CDK parameters diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts index afb7c2d453867..e01d3dd996101 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts @@ -1,5 +1,5 @@ import * as iam from '@aws-cdk/aws-iam'; -import { App, RemovalPolicy, Stack, Tag, Tags } from '@aws-cdk/core'; +import { App, RemovalPolicy, Stack, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, ProjectionType, StreamViewType, Table } from '../lib'; // CDK parameters