From 9a81faaafb46512acae917b3374ed1ffb12ba744 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Tue, 2 Feb 2021 06:24:44 +0000 Subject: [PATCH 01/21] chore(eslint-plugin-cdk): tests for rule no-qualified-construct (#12809) Add missing tests ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../eslint-plugin-cdk/test/rules/eslintrc.js | 12 ---- .../test/rules/fixtures.test.ts | 63 +++++++++++++++++++ .../qualified-heritage.expected.ts | 8 +++ .../qualified-heritage.ts | 4 ++ .../qualified-usage.expected.ts | 4 ++ .../no-qualified-construct/qualified-usage.ts | 3 + .../test/rules/no-core-construct.test.ts | 44 ------------- 7 files changed, 82 insertions(+), 56 deletions(-) delete mode 100644 tools/eslint-plugin-cdk/test/rules/eslintrc.js create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures.test.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.ts delete mode 100644 tools/eslint-plugin-cdk/test/rules/no-core-construct.test.ts diff --git a/tools/eslint-plugin-cdk/test/rules/eslintrc.js b/tools/eslint-plugin-cdk/test/rules/eslintrc.js deleted file mode 100644 index c68b2066acce3..0000000000000 --- a/tools/eslint-plugin-cdk/test/rules/eslintrc.js +++ /dev/null @@ -1,12 +0,0 @@ -const path = require('path'); -const rulesDirPlugin = require('eslint-plugin-rulesdir'); -rulesDirPlugin.RULES_DIR = path.join(__dirname, '../../lib/rules'); - -module.exports = { - parser: '@typescript-eslint/parser', - plugins: ['rulesdir'], - rules: { - quotes: [ 'error', 'single', { avoidEscape: true }], - 'rulesdir/no-core-construct': [ 'error' ], - } -} diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts b/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts new file mode 100644 index 0000000000000..89f0568048fbd --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts @@ -0,0 +1,63 @@ +import { ESLint } from 'eslint'; +import * as fs from 'fs-extra'; +import * as path from 'path'; + +const rulesDirPlugin = require('eslint-plugin-rulesdir'); +rulesDirPlugin.RULES_DIR = path.join(__dirname, '../../lib/rules'); + +const linter = new ESLint({ + baseConfig: { + parser: '@typescript-eslint/parser', + plugins: ['rulesdir'], + rules: { + quotes: [ 'error', 'single', { avoidEscape: true }], + 'rulesdir/no-core-construct': [ 'error' ], + 'rulesdir/no-qualified-construct': [ 'error' ], + } + }, + rulePaths: [ + path.join(__dirname, '../../lib/rules'), + ], + fix: true, +}); + +const outputRoot = path.join(process.cwd(), '.test-output'); +fs.mkdirpSync(outputRoot); + +const fixturesRoot = path.join(__dirname, 'fixtures'); + +fs.readdirSync(fixturesRoot).filter(f => fs.lstatSync(path.join(fixturesRoot, f)).isDirectory()).forEach(d => { + describe(d, () => { + const outputDir = path.join(outputRoot, d); + fs.mkdirpSync(outputDir); + + const fixturesDir = path.join(fixturesRoot, d); + const fixtureFiles = fs.readdirSync(fixturesDir).filter(f => f.endsWith('.ts') && !f.endsWith('.expected.ts')); + + fixtureFiles.forEach(f => { + test(f, async (done) => { + const actualFile = await lintAndFix(path.join(fixturesDir, f), outputDir); + const expectedFile = path.join(fixturesDir, `${path.basename(f, '.ts')}.expected.ts`); + if (!fs.existsSync(expectedFile)) { + done.fail(`Expected file not found. Generated output at ${actualFile}`); + } + const actual = await fs.readFile(actualFile, { encoding: 'utf8' }); + const expected = await fs.readFile(expectedFile, { encoding: 'utf8' }); + if (actual !== expected) { + done.fail(`Linted file did not match expectations. Expected: ${expectedFile}. Actual: ${actualFile}`); + } + done(); + }); + }); + }); +}); + +async function lintAndFix(file: string, outputDir: string) { + const newPath = path.join(outputDir, path.basename(file)) + let result = await linter.lintFiles(file); + await ESLint.outputFixes(result.map(r => { + r.filePath = newPath; + return r; + })); + return newPath; +} diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.expected.ts new file mode 100644 index 0000000000000..6510d7dd5542f --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.expected.ts @@ -0,0 +1,8 @@ +import * as cdk from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + +class MyConstruct extends Construct { +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.ts new file mode 100644 index 0000000000000..3f8b877e32c2e --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-heritage.ts @@ -0,0 +1,4 @@ +import * as cdk from '@aws-cdk/core'; + +class MyConstruct extends cdk.Construct { +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts new file mode 100644 index 0000000000000..af7c0f393f307 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts @@ -0,0 +1,4 @@ +import * as cdk from '@aws-cdk/core'; +import * as constructs from 'constructs'; + +let x: constructs.Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.ts new file mode 100644 index 0000000000000..d2ebc12dc01ff --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.ts @@ -0,0 +1,3 @@ +import * as cdk from '@aws-cdk/core'; + +let x: cdk.Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/no-core-construct.test.ts b/tools/eslint-plugin-cdk/test/rules/no-core-construct.test.ts deleted file mode 100644 index c2272cfd39353..0000000000000 --- a/tools/eslint-plugin-cdk/test/rules/no-core-construct.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ESLint } from 'eslint'; -import * as fs from 'fs-extra'; -import * as path from 'path'; - -const linter = new ESLint({ - overrideConfigFile: path.join(__dirname, 'eslintrc.js'), - rulePaths: [ - path.join(__dirname, '../../lib/rules'), - ], - fix: true, -}); - -const outputDir = path.join(process.cwd(), '.test-output'); -fs.mkdirpSync(outputDir); -const fixturesDir = path.join(__dirname, 'fixtures', 'no-core-construct'); - -describe('no-core-construct', () => { - const fixtureFiles = fs.readdirSync(fixturesDir).filter(f => f.endsWith('.ts') && !f.endsWith('.expected.ts')); - fixtureFiles.forEach(f => { - test(f, async (done) => { - const actualFile = await lintAndFix(path.join(fixturesDir, f)); - const expectedFile = path.join(fixturesDir, `${path.basename(f, '.ts')}.expected.ts`); - if (!fs.existsSync(expectedFile)) { - done.fail(`Expected file not found. Generated output at ${actualFile}`); - } - const actual = await fs.readFile(actualFile, { encoding: 'utf8' }); - const expected = await fs.readFile(expectedFile, { encoding: 'utf8' }); - if (actual !== expected) { - done.fail(`Linted file did not match expectations. Expected: ${expectedFile}. Actual: ${actualFile}`); - } - done(); - }); - }); -}); - -async function lintAndFix(file: string) { - const newPath = path.join(outputDir, path.basename(file)) - let result = await linter.lintFiles(file); - await ESLint.outputFixes(result.map(r => { - r.filePath = newPath; - return r; - })); - return newPath; -} From 721344b592c93094a278ed5525be8cba2a549762 Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Tue, 2 Feb 2021 19:05:18 +0200 Subject: [PATCH 02/21] chore(stepfunctions): Fix examples (#12824) fixes #12823 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-stepfunctions/README.md | 71 +++++++++---------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions/README.md b/packages/@aws-cdk/aws-stepfunctions/README.md index 1fb164cc6e8e2..ae6635358d0ec 100644 --- a/packages/@aws-cdk/aws-stepfunctions/README.md +++ b/packages/@aws-cdk/aws-stepfunctions/README.md @@ -84,9 +84,9 @@ definition. The definition is specified by its start state, and encompasses all states reachable from the start state: ```ts -const startState = new stepfunctions.Pass(this, 'StartState'); +const startState = new sfn.Pass(this, 'StartState'); -new stepfunctions.StateMachine(this, 'StateMachine', { +new sfn.StateMachine(this, 'StateMachine', { definition: startState }); ``` @@ -138,8 +138,8 @@ will be passed as the state's output. ```ts // Makes the current JSON state { ..., "subObject": { "hello": "world" } } -const pass = new stepfunctions.Pass(this, 'Add Hello World', { - result: stepfunctions.Result.fromObject({ hello: 'world' }), +const pass = new sfn.Pass(this, 'Add Hello World', { + result: sfn.Result.fromObject({ hello: 'world' }), resultPath: '$.subObject', }); @@ -154,9 +154,9 @@ The following example filters the `greeting` field from the state input and also injects a field called `otherData`. ```ts -const pass = new stepfunctions.Pass(this, 'Filter input and inject data', { +const pass = new sfn.Pass(this, 'Filter input and inject data', { parameters: { // input to the pass state - input: stepfunctions.JsonPath.stringAt('$.input.greeting'), + input: sfn.JsonPath.stringAt('$.input.greeting'), otherData: 'some-extra-stuff' }, }); @@ -177,8 +177,8 @@ state. ```ts // Wait until it's the time mentioned in the the state object's "triggerTime" // field. -const wait = new stepfunctions.Wait(this, 'Wait For Trigger Time', { - time: stepfunctions.WaitTime.timestampPath('$.triggerTime'), +const wait = new sfn.Wait(this, 'Wait For Trigger Time', { + time: sfn.WaitTime.timestampPath('$.triggerTime'), }); // Set the next state @@ -191,11 +191,11 @@ A `Choice` state can take a different path through the workflow based on the values in the execution's JSON state: ```ts -const choice = new stepfunctions.Choice(this, 'Did it work?'); +const choice = new sfn.Choice(this, 'Did it work?'); // Add conditions with .when() -choice.when(stepfunctions.Condition.stringEqual('$.status', 'SUCCESS'), successState); -choice.when(stepfunctions.Condition.numberGreaterThan('$.attempts', 5), failureState); +choice.when(sfn.Condition.stringEquals('$.status', 'SUCCESS'), successState); +choice.when(sfn.Condition.numberGreaterThan('$.attempts', 5), failureState); // Use .otherwise() to indicate what should be done if none of the conditions match choice.otherwise(tryAgainState); @@ -206,9 +206,9 @@ all branches come together and continuing as one (similar to how an `if ... then ... else` works in a programming language), use the `.afterwards()` method: ```ts -const choice = new stepfunctions.Choice(this, 'What color is it?'); -choice.when(stepfunctions.Condition.stringEqual('$.color', 'BLUE'), handleBlueItem); -choice.when(stepfunctions.Condition.stringEqual('$.color', 'RED'), handleRedItem); +const choice = new sfn.Choice(this, 'What color is it?'); +choice.when(sfn.Condition.stringEquals('$.color', 'BLUE'), handleBlueItem); +choice.when(sfn.Condition.stringEquals('$.color', 'RED'), handleRedItem); choice.otherwise(handleOtherItemColor); // Use .afterwards() to join all possible paths back together and continue @@ -275,7 +275,7 @@ A `Parallel` state executes one or more subworkflows in parallel. It can also be used to catch and recover from errors in subworkflows. ```ts -const parallel = new stepfunctions.Parallel(this, 'Do the work in parallel'); +const parallel = new sfn.Parallel(this, 'Do the work in parallel'); // Add branches to be executed in parallel parallel.branch(shipItem); @@ -298,7 +298,7 @@ Reaching a `Succeed` state terminates the state machine execution with a succesful status. ```ts -const success = new stepfunctions.Succeed(this, 'We did it!'); +const success = new sfn.Succeed(this, 'We did it!'); ``` ### Fail @@ -308,7 +308,7 @@ failure status. The fail state should report the reason for the failure. Failures can be caught by encompassing `Parallel` states. ```ts -const success = new stepfunctions.Fail(this, 'Fail', { +const success = new sfn.Fail(this, 'Fail', { error: 'WorkflowFailure', cause: "Something went wrong" }); @@ -323,11 +323,11 @@ While the `Parallel` state executes multiple branches of steps using the same in execute the same steps for multiple entries of an array in the state input. ```ts -const map = new stepfunctions.Map(this, 'Map State', { +const map = new sfn.Map(this, 'Map State', { maxConcurrency: 1, - itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap') + itemsPath: sfn.JsonPath.stringAt('$.inputForMap') }); -map.iterator(new stepfunctions.Pass(this, 'Pass State')); +map.iterator(new sfn.Pass(this, 'Pass State')); ``` ### Custom State @@ -420,7 +420,7 @@ const definition = step1 .branch(step9.next(step10))) .next(finish); -new stepfunctions.StateMachine(this, 'StateMachine', { +new sfn.StateMachine(this, 'StateMachine', { definition, }); ``` @@ -429,14 +429,13 @@ If you don't like the visual look of starting a chain directly off the first step, you can use `Chain.start`: ```ts -const definition = stepfunctions.Chain +const definition = sfn.Chain .start(step1) .next(step2) .next(step3) // ... ``` - ## State Machine Fragments It is possible to define reusable (or abstracted) mini-state machines by @@ -461,16 +460,16 @@ interface MyJobProps { jobFlavor: string; } -class MyJob extends stepfunctions.StateMachineFragment { - public readonly startState: State; - public readonly endStates: INextable[]; +class MyJob extends sfn.StateMachineFragment { + public readonly startState: sfn.State; + public readonly endStates: sfn.INextable[]; constructor(parent: cdk.Construct, id: string, props: MyJobProps) { super(parent, id); - const first = new stepfunctions.Task(this, 'First', { ... }); + const first = new sfn.Task(this, 'First', { ... }); // ... - const last = new stepfunctions.Task(this, 'Last', { ... }); + const last = new sfn.Task(this, 'Last', { ... }); this.startState = first; this.endStates = [last]; @@ -478,7 +477,7 @@ class MyJob extends stepfunctions.StateMachineFragment { } // Do 3 different variants of MyJob in parallel -new stepfunctions.Parallel(this, 'All jobs') +new sfn.Parallel(this, 'All jobs') .branch(new MyJob(this, 'Quick', { jobFlavor: 'quick' }).prefixStates()) .branch(new MyJob(this, 'Medium', { jobFlavor: 'medium' }).prefixStates()) .branch(new MyJob(this, 'Slow', { jobFlavor: 'slow' }).prefixStates()); @@ -500,7 +499,7 @@ You need the ARN to do so, so if you use Activities be sure to pass the Activity ARN into your worker pool: ```ts -const activity = new stepfunctions.Activity(this, 'Activity'); +const activity = new sfn.Activity(this, 'Activity'); // Read this CloudFormation Output from your application and use it to poll for work on // the activity. @@ -512,7 +511,7 @@ new cdk.CfnOutput(this, 'ActivityArn', { value: activity.activityArn }); Granting IAM permissions to an activity can be achieved by calling the `grant(principal, actions)` API: ```ts -const activity = new stepfunctions.Activity(this, 'Activity'); +const activity = new sfn.Activity(this, 'Activity'); const role = new iam.Role(stack, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), @@ -564,11 +563,11 @@ destination LogGroup: ```ts const logGroup = new logs.LogGroup(stack, 'MyLogGroup'); -new stepfunctions.StateMachine(stack, 'MyStateMachine', { - definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'Pass')), +new sfn.StateMachine(stack, 'MyStateMachine', { + definition: sfn.Chain.start(new sfn.Pass(stack, 'Pass')), logs: { destination: logGroup, - level: stepfunctions.LogLevel.ALL, + level: sfn.LogLevel.ALL, } }); ``` @@ -580,8 +579,8 @@ Enable X-Ray tracing for StateMachine: ```ts const logGroup = new logs.LogGroup(stack, 'MyLogGroup'); -new stepfunctions.StateMachine(stack, 'MyStateMachine', { - definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'Pass')), +new sfn.StateMachine(stack, 'MyStateMachine', { + definition: sfn.Chain.start(new sfn.Pass(stack, 'Pass')), tracingEnabled: true }); ``` From 06b6d820b4ad7f913b8538bab63ce3a42af4be8f Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Tue, 2 Feb 2021 20:43:45 +0200 Subject: [PATCH 03/21] chore(s3): Remove unused KMS key in example (#12826) fixes #12825 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-s3/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/@aws-cdk/aws-s3/README.md b/packages/@aws-cdk/aws-s3/README.md index 1ce00f56ba0a9..12ae88bb02d2e 100644 --- a/packages/@aws-cdk/aws-s3/README.md +++ b/packages/@aws-cdk/aws-s3/README.md @@ -67,8 +67,6 @@ assert(bucket.encryptionKey === myKmsKey); Enable KMS-SSE encryption via [S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html): ```ts -const myKmsKey = new kms.Key(this, 'MyKey'); - const bucket = new Bucket(this, 'MyEncryptedBucket', { encryption: BucketEncryption.KMS, bucketKeyEnabled: true From 0963f786e49fc3cef9cc5c4cde3ecba5540a2749 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Tue, 2 Feb 2021 12:06:21 -0800 Subject: [PATCH 04/21] revert: revert "chore: add new interfaces for Assets (#12700)" (#12832) Needs reverting because of https://github.com/aws/jsii/issues/2256 . This reverts commit 1a9f2a81. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/assets/lib/fs/options.ts | 1 - .../aws-ecr-assets/lib/image-asset.ts | 19 ++----- packages/@aws-cdk/aws-s3-assets/lib/asset.ts | 4 +- packages/@aws-cdk/core/lib/fs/options.ts | 51 +++++-------------- 4 files changed, 19 insertions(+), 56 deletions(-) diff --git a/packages/@aws-cdk/assets/lib/fs/options.ts b/packages/@aws-cdk/assets/lib/fs/options.ts index 548fa4bda42ee..3ccc107d3700d 100644 --- a/packages/@aws-cdk/assets/lib/fs/options.ts +++ b/packages/@aws-cdk/assets/lib/fs/options.ts @@ -10,7 +10,6 @@ export interface CopyOptions { * A strategy for how to handle symlinks. * * @default Never - * @deprecated use `followSymlinks` instead */ readonly follow?: FollowMode; diff --git a/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts b/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts index 91d3f06b5f6a2..2f6f5ff436baa 100644 --- a/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts +++ b/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts @@ -2,16 +2,14 @@ import * as fs from 'fs'; import * as path from 'path'; import * as assets from '@aws-cdk/assets'; import * as ecr from '@aws-cdk/aws-ecr'; -import { - Annotations, AssetStaging, Construct as CoreConstruct, FeatureFlags, FileFingerprintOptions, IgnoreMode, Stack, SymlinkFollowMode, Token, -} from '@aws-cdk/core'; +import { Annotations, Construct as CoreConstruct, FeatureFlags, IgnoreMode, Stack, Token } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; /** * Options for DockerImageAsset */ -export interface DockerImageAssetOptions extends assets.FingerprintOptions, FileFingerprintOptions { +export interface DockerImageAssetOptions extends assets.FingerprintOptions { /** * ECR repository name * @@ -139,9 +137,8 @@ export class DockerImageAsset extends CoreConstruct implements assets.IAsset { // deletion of the ECR repository the app used). extraHash.version = '1.21.0'; - const staging = new AssetStaging(this, 'Staging', { + const staging = new assets.Staging(this, 'Staging', { ...props, - follow: props.followSymlinks ?? toSymlinkFollow(props.follow), exclude, ignoreMode, sourcePath: dir, @@ -184,13 +181,3 @@ function validateBuildArgs(buildArgs?: { [key: string]: string }) { } } } - -function toSymlinkFollow(follow?: assets.FollowMode): SymlinkFollowMode | undefined { - switch (follow) { - case undefined: return undefined; - case assets.FollowMode.NEVER: return SymlinkFollowMode.NEVER; - case assets.FollowMode.ALWAYS: return SymlinkFollowMode.ALWAYS; - case assets.FollowMode.BLOCK_EXTERNAL: return SymlinkFollowMode.BLOCK_EXTERNAL; - case assets.FollowMode.EXTERNAL: return SymlinkFollowMode.EXTERNAL; - } -} diff --git a/packages/@aws-cdk/aws-s3-assets/lib/asset.ts b/packages/@aws-cdk/aws-s3-assets/lib/asset.ts index d674d083b248b..938778d1381f4 100644 --- a/packages/@aws-cdk/aws-s3-assets/lib/asset.ts +++ b/packages/@aws-cdk/aws-s3-assets/lib/asset.ts @@ -15,7 +15,7 @@ import { Construct as CoreConstruct } from '@aws-cdk/core'; const ARCHIVE_EXTENSIONS = ['.zip', '.jar']; -export interface AssetOptions extends assets.CopyOptions, cdk.FileCopyOptions, cdk.AssetOptions { +export interface AssetOptions extends assets.CopyOptions, cdk.AssetOptions { /** * A list of principals that should be able to read this asset from S3. * You can use `asset.grantRead(principal)` to grant read permissions later. @@ -128,7 +128,7 @@ export class Asset extends CoreConstruct implements cdk.IAsset { const staging = new cdk.AssetStaging(this, 'Stage', { ...props, sourcePath: path.resolve(props.path), - follow: props.followSymlinks ?? toSymlinkFollow(props.follow), + follow: toSymlinkFollow(props.follow), assetHash: props.assetHash ?? props.sourceHash, }); diff --git a/packages/@aws-cdk/core/lib/fs/options.ts b/packages/@aws-cdk/core/lib/fs/options.ts index baf73bd7ffd30..3ea836a24e831 100644 --- a/packages/@aws-cdk/core/lib/fs/options.ts +++ b/packages/@aws-cdk/core/lib/fs/options.ts @@ -56,9 +56,19 @@ export enum IgnoreMode { * context flag is set. */ DOCKER = 'docker' -} +}; + +/** + * Obtains applied when copying directories into the staging location. + */ +export interface CopyOptions { + /** + * A strategy for how to handle symlinks. + * + * @default SymlinkFollowMode.NEVER + */ + readonly follow?: SymlinkFollowMode; -interface FileOptions { /** * Glob patterns to exclude from the copy. * @@ -75,30 +85,9 @@ interface FileOptions { } /** - * Options applied when copying directories - */ -export interface CopyOptions extends FileOptions { - /** - * A strategy for how to handle symlinks. - * - * @default SymlinkFollowMode.NEVER - */ - readonly follow?: SymlinkFollowMode; -} - -/** - * Options applied when copying directories into the staging location. + * Options related to calculating source hash. */ -export interface FileCopyOptions extends FileOptions { - /** - * A strategy for how to handle symlinks. - * - * @default SymlinkFollowMode.NEVER - */ - readonly followSymlinks?: SymlinkFollowMode; -} - -interface ExtraHashOptions { +export interface FingerprintOptions extends CopyOptions { /** * Extra information to encode into the fingerprint (e.g. build instructions * and other inputs) @@ -107,15 +96,3 @@ interface ExtraHashOptions { */ readonly extraHash?: string; } - -/** - * Options related to calculating source hash. - */ -export interface FingerprintOptions extends CopyOptions, ExtraHashOptions { -} - -/** - * Options related to calculating source hash. - */ -export interface FileFingerprintOptions extends FileCopyOptions, ExtraHashOptions { -} From 59cb6d032a55515ec5e9903f899de588d18d4cb5 Mon Sep 17 00:00:00 2001 From: Robert Djurasaj Date: Wed, 3 Feb 2021 03:02:18 -0700 Subject: [PATCH 05/21] feat(cloudfront): add PublicKey and KeyGroup L2 constructs (#12743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @njlynch This is my humble start on creating L2 constructs for `PublicKey` and `KeyGroup` for CloudFront module. I'm going to need some guidance/mentorship as this is my first L2 construct from the scratch. I'll convert this PR to draft and I'll post some of my thoughts and ideas around this feature tomorrow. I'm trying to address feature requests in https://github.com/aws/aws-cdk/issues/11791. I've decided to lump `PublicKey` and `KeyGroup` features together as they seem to depend on each other. All in the good spirits of learning how to extend CDK 🍻 . Any ideas and/or constructive criticism is more than welcome... that's the best way to learn.✌️ ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-cloudfront/README.md | 37 ++++ packages/@aws-cdk/aws-cloudfront/lib/index.ts | 2 + .../@aws-cdk/aws-cloudfront/lib/key-group.ts | 75 +++++++ .../@aws-cdk/aws-cloudfront/lib/public-key.ts | 83 ++++++++ packages/@aws-cdk/aws-cloudfront/package.json | 4 +- .../integ.cloudfront-key-group.expected.json | 27 +++ .../test/integ.cloudfront-key-group.ts | 25 +++ .../aws-cloudfront/test/key-group.test.ts | 187 ++++++++++++++++++ .../aws-cloudfront/test/public-key.test.ts | 85 ++++++++ 9 files changed, 524 insertions(+), 1 deletion(-) create mode 100644 packages/@aws-cdk/aws-cloudfront/lib/key-group.ts create mode 100644 packages/@aws-cdk/aws-cloudfront/lib/public-key.ts create mode 100644 packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.expected.json create mode 100644 packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.ts create mode 100644 packages/@aws-cdk/aws-cloudfront/test/key-group.test.ts create mode 100644 packages/@aws-cdk/aws-cloudfront/test/public-key.test.ts diff --git a/packages/@aws-cdk/aws-cloudfront/README.md b/packages/@aws-cdk/aws-cloudfront/README.md index f42d6a15f7abc..1355d7a64d31d 100644 --- a/packages/@aws-cdk/aws-cloudfront/README.md +++ b/packages/@aws-cdk/aws-cloudfront/README.md @@ -520,3 +520,40 @@ new CloudFrontWebDistribution(stack, 'ADistribution', { ], }); ``` + +## KeyGroup & PublicKey API + +Now you can create a key group to use with CloudFront signed URLs and signed cookies. You can add public keys to use with CloudFront features such as signed URLs, signed cookies, and field-level encryption. + +The following example command uses OpenSSL to generate an RSA key pair with a length of 2048 bits and save to the file named `private_key.pem`. + +```bash +openssl genrsa -out private_key.pem 2048 +``` + +The resulting file contains both the public and the private key. The following example command extracts the public key from the file named `private_key.pem` and stores it in `public_key.pem`. + +```bash +openssl rsa -pubout -in private_key.pem -out public_key.pem +``` + +Note: Don't forget to copy/paste the contents of `public_key.pem` file including `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----` lines into `encodedKey` parameter when creating a `PublicKey`. + +Example: + +```ts + new cloudfront.KeyGroup(stack, 'MyKeyGroup', { + items: [ + new cloudfront.PublicKey(stack, 'MyPublicKey', { + encodedKey: '...', // contents of public_key.pem file + // comment: 'Key is expiring on ...', + }), + ], + // comment: 'Key group containing public keys ...', + }); +``` + +See: + +* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html +* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html diff --git a/packages/@aws-cdk/aws-cloudfront/lib/index.ts b/packages/@aws-cdk/aws-cloudfront/lib/index.ts index 726a1d1d01948..7de2aa62b4412 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/index.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/index.ts @@ -1,9 +1,11 @@ export * from './cache-policy'; export * from './distribution'; export * from './geo-restriction'; +export * from './key-group'; export * from './origin'; export * from './origin-access-identity'; export * from './origin-request-policy'; +export * from './public-key'; export * from './web-distribution'; export * as experimental from './experimental'; diff --git a/packages/@aws-cdk/aws-cloudfront/lib/key-group.ts b/packages/@aws-cdk/aws-cloudfront/lib/key-group.ts new file mode 100644 index 0000000000000..aea7bf451f305 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/lib/key-group.ts @@ -0,0 +1,75 @@ +import { IResource, Names, Resource } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { CfnKeyGroup } from './cloudfront.generated'; +import { IPublicKey } from './public-key'; + +/** + * Represents a Key Group + */ +export interface IKeyGroup extends IResource { + /** + * The ID of the key group. + * @attribute + */ + readonly keyGroupId: string; +} + +/** + * Properties for creating a Public Key + */ +export interface KeyGroupProps { + /** + * A name to identify the key group. + * @default - generated from the `id` + */ + readonly keyGroupName?: string; + + /** + * A comment to describe the key group. + * @default - no comment + */ + readonly comment?: string; + + /** + * A list of public keys to add to the key group. + */ + readonly items: IPublicKey[]; +} + +/** + * A Key Group configuration + * + * @resource AWS::CloudFront::KeyGroup + */ +export class KeyGroup extends Resource implements IKeyGroup { + + /** Imports a Key Group from its id. */ + public static fromKeyGroupId(scope: Construct, id: string, keyGroupId: string): IKeyGroup { + return new class extends Resource implements IKeyGroup { + public readonly keyGroupId = keyGroupId; + }(scope, id); + } + public readonly keyGroupId: string; + + constructor(scope: Construct, id: string, props: KeyGroupProps) { + super(scope, id); + + const resource = new CfnKeyGroup(this, 'Resource', { + keyGroupConfig: { + name: props.keyGroupName ?? this.generateName(), + comment: props.comment, + items: props.items.map(key => key.publicKeyId), + }, + }); + + this.keyGroupId = resource.ref; + } + + private generateName(): string { + const name = Names.uniqueId(this); + if (name.length > 80) { + return name.substring(0, 40) + name.substring(name.length - 40); + } + return name; + } +} diff --git a/packages/@aws-cdk/aws-cloudfront/lib/public-key.ts b/packages/@aws-cdk/aws-cloudfront/lib/public-key.ts new file mode 100644 index 0000000000000..e2c2b6e044cdb --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/lib/public-key.ts @@ -0,0 +1,83 @@ +import { IResource, Names, Resource, Token } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { CfnPublicKey } from './cloudfront.generated'; + +/** + * Represents a Public Key + */ +export interface IPublicKey extends IResource { + /** + * The ID of the key group. + * @attribute + */ + readonly publicKeyId: string; +} + +/** + * Properties for creating a Public Key + */ +export interface PublicKeyProps { + /** + * A name to identify the public key. + * @default - generated from the `id` + */ + readonly publicKeyName?: string; + + /** + * A comment to describe the public key. + * @default - no comment + */ + readonly comment?: string; + + /** + * The public key that you can use with signed URLs and signed cookies, or with field-level encryption. + * The `encodedKey` parameter must include `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----` lines. + * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html + * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/field-level-encryption.html + */ + readonly encodedKey: string; +} + +/** + * A Public Key Configuration + * + * @resource AWS::CloudFront::PublicKey + */ +export class PublicKey extends Resource implements IPublicKey { + + /** Imports a Public Key from its id. */ + public static fromPublicKeyId(scope: Construct, id: string, publicKeyId: string): IPublicKey { + return new class extends Resource implements IPublicKey { + public readonly publicKeyId = publicKeyId; + }(scope, id); + } + + public readonly publicKeyId: string; + + constructor(scope: Construct, id: string, props: PublicKeyProps) { + super(scope, id); + + if (!Token.isUnresolved(props.encodedKey) && !/^-----BEGIN PUBLIC KEY-----/.test(props.encodedKey)) { + throw new Error(`Public key must be in PEM format (with the BEGIN/END PUBLIC KEY lines); got ${props.encodedKey}`); + } + + const resource = new CfnPublicKey(this, 'Resource', { + publicKeyConfig: { + name: props.publicKeyName ?? this.generateName(), + callerReference: this.node.addr, + encodedKey: props.encodedKey, + comment: props.comment, + }, + }); + + this.publicKeyId = resource.ref; + } + + private generateName(): string { + const name = Names.uniqueId(this); + if (name.length > 80) { + return name.substring(0, 40) + name.substring(name.length - 40); + } + return name; + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index 651d22e95e668..c781a065bbc0a 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -153,7 +153,9 @@ "resource-attribute:@aws-cdk/aws-cloudfront.CachePolicy.cachePolicyLastModifiedTime", "construct-interface-extends-iconstruct:@aws-cdk/aws-cloudfront.IOriginRequestPolicy", "resource-interface-extends-resource:@aws-cdk/aws-cloudfront.IOriginRequestPolicy", - "resource-attribute:@aws-cdk/aws-cloudfront.OriginRequestPolicy.originRequestPolicyLastModifiedTime" + "resource-attribute:@aws-cdk/aws-cloudfront.OriginRequestPolicy.originRequestPolicyLastModifiedTime", + "resource-attribute:@aws-cdk/aws-cloudfront.KeyGroup.keyGroupLastModifiedTime", + "resource-attribute:@aws-cdk/aws-cloudfront.PublicKey.publicKeyCreatedTime" ] }, "awscdkio": { diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.expected.json b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.expected.json new file mode 100644 index 0000000000000..45191bad86cff --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.expected.json @@ -0,0 +1,27 @@ +{ + "Resources": { + "AwesomePublicKeyED3E7F55": { + "Type": "AWS::CloudFront::PublicKey", + "Properties": { + "PublicKeyConfig": { + "CallerReference": "c88e460888c5762c9c47ac0cdc669370d787fb2d9f", + "EncodedKey": "-----BEGIN PUBLIC KEY-----\n MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS\n JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa\n dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj\n 6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e\n 0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD\n /3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx\n NQIDAQAB\n -----END PUBLIC KEY-----\n ", + "Name": "awscdkcloudfrontcustomAwesomePublicKey0E83393B" + } + } + }, + "AwesomeKeyGroup3EF8348B": { + "Type": "AWS::CloudFront::KeyGroup", + "Properties": { + "KeyGroupConfig": { + "Items": [ + { + "Ref": "AwesomePublicKeyED3E7F55" + } + ], + "Name": "awscdkcloudfrontcustomAwesomeKeyGroup73FD4DCA" + } + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.ts new file mode 100644 index 0000000000000..7bfdbbe645446 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-key-group.ts @@ -0,0 +1,25 @@ +import * as cdk from '@aws-cdk/core'; +import * as cloudfront from '../lib'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'aws-cdk-cloudfront-custom'); + +new cloudfront.KeyGroup(stack, 'AwesomeKeyGroup', { + items: [ + new cloudfront.PublicKey(stack, 'AwesomePublicKey', { + encodedKey: `-----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS + JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa + dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj + 6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e + 0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD + /3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx + NQIDAQAB + -----END PUBLIC KEY----- + `, + }), + ], +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudfront/test/key-group.test.ts b/packages/@aws-cdk/aws-cloudfront/test/key-group.test.ts new file mode 100644 index 0000000000000..f5a0ae43c0855 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/test/key-group.test.ts @@ -0,0 +1,187 @@ +import '@aws-cdk/assert/jest'; +import { expect as expectStack } from '@aws-cdk/assert'; +import { App, Stack } from '@aws-cdk/core'; +import { KeyGroup, PublicKey } from '../lib'; + +const publicKey1 = `-----BEGIN PUBLIC KEY----- +FIRST_KEYgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS +JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa +dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj +6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e +0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD +/3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx +NQIDAQAB +-----END PUBLIC KEY-----`; + +const publicKey2 = `-----BEGIN PUBLIC KEY----- +SECOND_KEYkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS +JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa +dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj +6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e +0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD +/3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx +NQIDAQAB +-----END PUBLIC KEY-----`; + +describe('KeyGroup', () => { + let app: App; + let stack: Stack; + + beforeEach(() => { + app = new App(); + stack = new Stack(app, 'Stack', { + env: { account: '123456789012', region: 'testregion' }, + }); + }); + + test('import existing key group by id', () => { + const keyGroupId = '344f6fe5-7ce5-4df0-a470-3f14177c549c'; + const keyGroup = KeyGroup.fromKeyGroupId(stack, 'MyKeyGroup', keyGroupId); + expect(keyGroup.keyGroupId).toEqual(keyGroupId); + }); + + test('minimal example', () => { + new KeyGroup(stack, 'MyKeyGroup', { + items: [ + new PublicKey(stack, 'MyPublicKey', { + encodedKey: publicKey1, + }), + ], + }); + + expectStack(stack).toMatch({ + Resources: { + MyPublicKey78071F3D: { + Type: 'AWS::CloudFront::PublicKey', + Properties: { + PublicKeyConfig: { + CallerReference: 'c872d91ae0d2943aad25d4b31f1304d0a62c658ace', + EncodedKey: publicKey1, + Name: 'StackMyPublicKey36EDA6AB', + }, + }, + }, + MyKeyGroupAF22FD35: { + Type: 'AWS::CloudFront::KeyGroup', + Properties: { + KeyGroupConfig: { + Items: [ + { + Ref: 'MyPublicKey78071F3D', + }, + ], + Name: 'StackMyKeyGroupC9D82374', + }, + }, + }, + }, + }); + }); + + test('maximum example', () => { + new KeyGroup(stack, 'MyKeyGroup', { + keyGroupName: 'AcmeKeyGroup', + comment: 'Key group created on 1/1/1984', + items: [ + new PublicKey(stack, 'MyPublicKey', { + publicKeyName: 'pub-key', + encodedKey: publicKey1, + comment: 'Key expiring on 1/1/1984', + }), + ], + }); + + expectStack(stack).toMatch({ + Resources: { + MyPublicKey78071F3D: { + Type: 'AWS::CloudFront::PublicKey', + Properties: { + PublicKeyConfig: { + CallerReference: 'c872d91ae0d2943aad25d4b31f1304d0a62c658ace', + EncodedKey: publicKey1, + Name: 'pub-key', + Comment: 'Key expiring on 1/1/1984', + }, + }, + }, + MyKeyGroupAF22FD35: { + Type: 'AWS::CloudFront::KeyGroup', + Properties: { + KeyGroupConfig: { + Items: [ + { + Ref: 'MyPublicKey78071F3D', + }, + ], + Name: 'AcmeKeyGroup', + Comment: 'Key group created on 1/1/1984', + }, + }, + }, + }, + }); + }); + + test('multiple keys example', () => { + new KeyGroup(stack, 'MyKeyGroup', { + keyGroupName: 'AcmeKeyGroup', + comment: 'Key group created on 1/1/1984', + items: [ + new PublicKey(stack, 'BingoKey', { + publicKeyName: 'Bingo-Key', + encodedKey: publicKey1, + comment: 'Key expiring on 1/1/1984', + }), + new PublicKey(stack, 'RollyKey', { + publicKeyName: 'Rolly-Key', + encodedKey: publicKey2, + comment: 'Key expiring on 1/1/1984', + }), + ], + }); + + expectStack(stack).toMatch({ + Resources: { + BingoKeyCBEC786C: { + Type: 'AWS::CloudFront::PublicKey', + Properties: { + PublicKeyConfig: { + CallerReference: 'c847cb3dc23f619c0a1e400a44afaf1060d27a1d1a', + EncodedKey: publicKey1, + Name: 'Bingo-Key', + Comment: 'Key expiring on 1/1/1984', + }, + }, + }, + RollyKey83F8BC5B: { + Type: 'AWS::CloudFront::PublicKey', + Properties: { + PublicKeyConfig: { + CallerReference: 'c83a16945c386bf6cd88a3aaa1aa603eeb4b6c6c57', + EncodedKey: publicKey2, + Name: 'Rolly-Key', + Comment: 'Key expiring on 1/1/1984', + }, + }, + }, + MyKeyGroupAF22FD35: { + Type: 'AWS::CloudFront::KeyGroup', + Properties: { + KeyGroupConfig: { + Items: [ + { + Ref: 'BingoKeyCBEC786C', + }, + { + Ref: 'RollyKey83F8BC5B', + }, + ], + Name: 'AcmeKeyGroup', + Comment: 'Key group created on 1/1/1984', + }, + }, + }, + }, + }); + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudfront/test/public-key.test.ts b/packages/@aws-cdk/aws-cloudfront/test/public-key.test.ts new file mode 100644 index 0000000000000..934b1a9dc8107 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/test/public-key.test.ts @@ -0,0 +1,85 @@ +import '@aws-cdk/assert/jest'; +import { expect as expectStack } from '@aws-cdk/assert'; +import { App, Stack } from '@aws-cdk/core'; +import { PublicKey } from '../lib'; + +const publicKey = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS +JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa +dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj +6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e +0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD +/3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx +NQIDAQAB +-----END PUBLIC KEY-----`; + +describe('PublicKey', () => { + let app: App; + let stack: Stack; + + beforeEach(() => { + app = new App(); + stack = new Stack(app, 'Stack', { + env: { account: '123456789012', region: 'testregion' }, + }); + }); + + test('import existing key group by id', () => { + const publicKeyId = 'K36X4X2EO997HM'; + const pubKey = PublicKey.fromPublicKeyId(stack, 'MyPublicKey', publicKeyId); + expect(pubKey.publicKeyId).toEqual(publicKeyId); + }); + + test('minimal example', () => { + new PublicKey(stack, 'MyPublicKey', { + encodedKey: publicKey, + }); + + expectStack(stack).toMatch({ + Resources: { + MyPublicKey78071F3D: { + Type: 'AWS::CloudFront::PublicKey', + Properties: { + PublicKeyConfig: { + CallerReference: 'c872d91ae0d2943aad25d4b31f1304d0a62c658ace', + EncodedKey: publicKey, + Name: 'StackMyPublicKey36EDA6AB', + }, + }, + }, + }, + }); + }); + + test('maximum example', () => { + new PublicKey(stack, 'MyPublicKey', { + publicKeyName: 'pub-key', + encodedKey: publicKey, + comment: 'Key expiring on 1/1/1984', + }); + + expectStack(stack).toMatch({ + Resources: { + MyPublicKey78071F3D: { + Type: 'AWS::CloudFront::PublicKey', + Properties: { + PublicKeyConfig: { + CallerReference: 'c872d91ae0d2943aad25d4b31f1304d0a62c658ace', + Comment: 'Key expiring on 1/1/1984', + EncodedKey: publicKey, + Name: 'pub-key', + }, + }, + }, + }, + }); + }); + + test('bad key example', () => { + expect(() => new PublicKey(stack, 'MyPublicKey', { + publicKeyName: 'pub-key', + encodedKey: 'bad-key', + comment: 'Key expiring on 1/1/1984', + })).toThrow(/Public key must be in PEM format [(]with the BEGIN\/END PUBLIC KEY lines[)]; got (.*?)/); + }); +}); \ No newline at end of file From 8a1a9b82a36e681334fd45be595f6ecdf904ad34 Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Wed, 3 Feb 2021 17:04:11 +0530 Subject: [PATCH 06/21] feat(apigateway): import an existing Resource (#12785) feat(apigateway): add fromResourceAttribute helper for importing Resource closes #4432 NOTE: No change in Readme is done since I was not able to find a good place for it in the Readme. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-apigateway/lib/resource.ts | 44 +++++++++++++++++++ .../aws-apigateway/test/resource.test.ts | 21 +++++++++ 2 files changed, 65 insertions(+) diff --git a/packages/@aws-cdk/aws-apigateway/lib/resource.ts b/packages/@aws-cdk/aws-apigateway/lib/resource.ts index 04d9598303ad8..33ec6f1d5f7fd 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/resource.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/resource.ts @@ -373,7 +373,51 @@ export abstract class ResourceBase extends ResourceConstruct implements IResourc } } +/** + * Attributes that can be specified when importing a Resource + */ +export interface ResourceAttributes { + /** + * The ID of the resource. + */ + readonly resourceId: string; + + /** + * The rest API that this resource is part of. + */ + readonly restApi: IRestApi; + + /** + * The full path of this resource. + */ + readonly path: string; +} + export class Resource extends ResourceBase { + /** + * Import an existing resource + */ + public static fromResourceAttributes(scope: Construct, id: string, attrs: ResourceAttributes): IResource { + class Import extends ResourceBase { + public readonly api = attrs.restApi; + public readonly resourceId = attrs.resourceId; + public readonly path = attrs.path; + public readonly defaultIntegration?: Integration = undefined; + public readonly defaultMethodOptions?: MethodOptions = undefined; + public readonly defaultCorsPreflightOptions?: CorsOptions = undefined; + + public get parentResource(): IResource { + throw new Error('parentResource is not configured for imported resource.'); + } + + public get restApi(): RestApi { + throw new Error('restApi is not configured for imported resource.'); + } + } + + return new Import(scope, id); + } + public readonly parentResource?: IResource; public readonly api: IRestApi; public readonly resourceId: string; diff --git a/packages/@aws-cdk/aws-apigateway/test/resource.test.ts b/packages/@aws-cdk/aws-apigateway/test/resource.test.ts index ecad61cb1905c..0a20483f4261c 100644 --- a/packages/@aws-cdk/aws-apigateway/test/resource.test.ts +++ b/packages/@aws-cdk/aws-apigateway/test/resource.test.ts @@ -236,6 +236,27 @@ describe('resource', () => { }); + test('fromResourceAttributes()', () => { + // GIVEN + const stack = new Stack(); + const resourceId = 'resource-id'; + const api = new apigw.RestApi(stack, 'MyRestApi'); + + // WHEN + const imported = apigw.Resource.fromResourceAttributes(stack, 'imported-resource', { + resourceId, + restApi: api, + path: 'some-path', + }); + imported.addMethod('GET'); + + // THEN + expect(stack).toHaveResource('AWS::ApiGateway::Method', { + HttpMethod: 'GET', + ResourceId: resourceId, + }); + }); + describe('getResource', () => { describe('root resource', () => { From 8d3aabaffe436e6a3eebc0a58fe361c5b4b93f08 Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Wed, 3 Feb 2021 14:13:05 +0200 Subject: [PATCH 07/21] feat(lambda): inline code for Python 3.8 (#12788) fixes #6503 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda/lib/runtime.ts | 1 + .../integ.runtime.inlinecode.expected.json | 65 +++++++++++++++++-- .../test/integ.runtime.inlinecode.ts | 9 ++- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda/lib/runtime.ts b/packages/@aws-cdk/aws-lambda/lib/runtime.ts index 1f94401afa17f..05d4996ff5e4f 100644 --- a/packages/@aws-cdk/aws-lambda/lib/runtime.ts +++ b/packages/@aws-cdk/aws-lambda/lib/runtime.ts @@ -103,6 +103,7 @@ export class Runtime { * The Python 3.8 runtime (python3.8) */ public static readonly PYTHON_3_8 = new Runtime('python3.8', RuntimeFamily.PYTHON, { + supportsInlineCode: true, supportsCodeGuruProfiling: true, }); diff --git a/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.expected.json b/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.expected.json index 8bbe8cdef572a..30d39828cc39d 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.expected.json +++ b/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.expected.json @@ -37,13 +37,13 @@ "Code": { "ZipFile": "exports.handler = async function(event) { return \"success\" }" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "NODEJS10XServiceRole2FD24B65", "Arn" ] }, + "Handler": "index.handler", "Runtime": "nodejs10.x" }, "DependsOn": [ @@ -87,13 +87,13 @@ "Code": { "ZipFile": "exports.handler = async function(event) { return \"success\" }" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "NODEJS12XServiceRole59E71436", "Arn" ] }, + "Handler": "index.handler", "Runtime": "nodejs12.x" }, "DependsOn": [ @@ -137,13 +137,13 @@ "Code": { "ZipFile": "def handler(event, context):\n return \"success\"" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "PYTHON27ServiceRoleF484A17D", "Arn" ] }, + "Handler": "index.handler", "Runtime": "python2.7" }, "DependsOn": [ @@ -187,13 +187,13 @@ "Code": { "ZipFile": "def handler(event, context):\n return \"success\"" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "PYTHON36ServiceRole814B3AD9", "Arn" ] }, + "Handler": "index.handler", "Runtime": "python3.6" }, "DependsOn": [ @@ -237,18 +237,68 @@ "Code": { "ZipFile": "def handler(event, context):\n return \"success\"" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "PYTHON37ServiceRoleDE7E561E", "Arn" ] }, + "Handler": "index.handler", "Runtime": "python3.7" }, "DependsOn": [ "PYTHON37ServiceRoleDE7E561E" ] + }, + "PYTHON38ServiceRole3EA86BBE": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "PYTHON38A180AE47": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context):\n return \"success\"" + }, + "Role": { + "Fn::GetAtt": [ + "PYTHON38ServiceRole3EA86BBE", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "python3.8" + }, + "DependsOn": [ + "PYTHON38ServiceRole3EA86BBE" + ] } }, "Outputs": { @@ -276,6 +326,11 @@ "Value": { "Ref": "PYTHON37D3A10E04" } + }, + "PYTHON38functionName": { + "Value": { + "Ref": "PYTHON38A180AE47" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.ts b/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.ts index aa4ef06e6a5e1..56f5bd27f7746 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.runtime.inlinecode.ts @@ -50,4 +50,11 @@ const python37 = new Function(stack, 'PYTHON_3_7', { }); new CfnOutput(stack, 'PYTHON_3_7-functionName', { value: python37.functionName }); -app.synth(); \ No newline at end of file +const python38 = new Function(stack, 'PYTHON_3_8', { + code: new InlineCode('def handler(event, context):\n return "success"'), + handler: 'index.handler', + runtime: Runtime.PYTHON_3_8, +}); +new CfnOutput(stack, 'PYTHON_3_8-functionName', { value: python38.functionName }); + +app.synth(); From 2aba609929de3b4517795aa06129b2fe31bf11b6 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Wed, 3 Feb 2021 12:50:28 +0000 Subject: [PATCH 08/21] chore(eslint-plugin-cdk): fix tests and expectations (#12831) The previous change - 9a81faaa - to add test cases to this package had a bug. Two different eslint rules were being applied simultaneously creating corrupt expectation. Fixing the test so it only runs the specific eslint rule for that fixture, and fixing the expectation. At the same time, added a test case that was previously missed. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/rules/fixtures.test.ts | 32 +++++++++---------- .../fixtures/no-core-construct/eslintrc.js | 6 ++++ .../both-constructs.expected.ts | 9 ++++++ .../no-qualified-construct/both-constructs.ts | 5 +++ .../no-qualified-construct/eslintrc.js | 6 ++++ .../qualified-usage.expected.ts | 7 ++-- 6 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-core-construct/eslintrc.js create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/eslintrc.js diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts b/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts index 89f0568048fbd..b65670f43b429 100644 --- a/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts +++ b/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts @@ -5,21 +5,7 @@ import * as path from 'path'; const rulesDirPlugin = require('eslint-plugin-rulesdir'); rulesDirPlugin.RULES_DIR = path.join(__dirname, '../../lib/rules'); -const linter = new ESLint({ - baseConfig: { - parser: '@typescript-eslint/parser', - plugins: ['rulesdir'], - rules: { - quotes: [ 'error', 'single', { avoidEscape: true }], - 'rulesdir/no-core-construct': [ 'error' ], - 'rulesdir/no-qualified-construct': [ 'error' ], - } - }, - rulePaths: [ - path.join(__dirname, '../../lib/rules'), - ], - fix: true, -}); +let linter: ESLint; const outputRoot = path.join(process.cwd(), '.test-output'); fs.mkdirpSync(outputRoot); @@ -28,10 +14,24 @@ const fixturesRoot = path.join(__dirname, 'fixtures'); fs.readdirSync(fixturesRoot).filter(f => fs.lstatSync(path.join(fixturesRoot, f)).isDirectory()).forEach(d => { describe(d, () => { + const fixturesDir = path.join(fixturesRoot, d); + + beforeAll(() => { + linter = new ESLint({ + baseConfig: { + parser: '@typescript-eslint/parser', + }, + overrideConfigFile: path.join(fixturesDir, 'eslintrc.js'), + rulePaths: [ + path.join(__dirname, '../../lib/rules'), + ], + fix: true, + }); + }); + const outputDir = path.join(outputRoot, d); fs.mkdirpSync(outputDir); - const fixturesDir = path.join(fixturesRoot, d); const fixtureFiles = fs.readdirSync(fixturesDir).filter(f => f.endsWith('.ts') && !f.endsWith('.expected.ts')); fixtureFiles.forEach(f => { diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-core-construct/eslintrc.js b/tools/eslint-plugin-cdk/test/rules/fixtures/no-core-construct/eslintrc.js new file mode 100644 index 0000000000000..3bd78e797f728 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-core-construct/eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['rulesdir'], + rules: { + 'rulesdir/no-core-construct': [ 'error' ], + } +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.expected.ts new file mode 100644 index 0000000000000..20caf8244cd1b --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.expected.ts @@ -0,0 +1,9 @@ +import { Construct } from 'constructs' +import * as cdk from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + +let x: CoreConstruct; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.ts new file mode 100644 index 0000000000000..bd92a909af763 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/both-constructs.ts @@ -0,0 +1,5 @@ +import { Construct } from 'constructs' +import * as cdk from '@aws-cdk/core'; + +let x: cdk.Construct; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/eslintrc.js b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/eslintrc.js new file mode 100644 index 0000000000000..30de0b87a63df --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['rulesdir'], + rules: { + 'rulesdir/no-qualified-construct': [ 'error' ], + } +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts index af7c0f393f307..bba5c3ae8aa50 100644 --- a/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/no-qualified-construct/qualified-usage.expected.ts @@ -1,4 +1,7 @@ import * as cdk from '@aws-cdk/core'; -import * as constructs from 'constructs'; -let x: constructs.Construct; \ No newline at end of file +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + +let x: Construct; \ No newline at end of file From ff1e5b3c580119c107fe26c67fe3cc220f9ee7c9 Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Wed, 3 Feb 2021 19:38:17 +0530 Subject: [PATCH 09/21] feat(apigateway): cognito user pool authorizer (#12786) feat(apigateway): add support for cognito user pool authorizer closes #5618 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-apigateway/README.md | 20 ++ .../aws-apigateway/lib/authorizers/cognito.ts | 115 +++++++++++ .../aws-apigateway/lib/authorizers/index.ts | 1 + packages/@aws-cdk/aws-apigateway/package.json | 2 + .../test/authorizers/cognito.test.ts | 66 ++++++ .../integ.cognito-authorizer.expected.json | 191 ++++++++++++++++++ .../authorizers/integ.cognito-authorizer.ts | 43 ++++ 7 files changed, 438 insertions(+) create mode 100644 packages/@aws-cdk/aws-apigateway/lib/authorizers/cognito.ts create mode 100644 packages/@aws-cdk/aws-apigateway/test/authorizers/cognito.test.ts create mode 100644 packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.expected.json create mode 100644 packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.ts diff --git a/packages/@aws-cdk/aws-apigateway/README.md b/packages/@aws-cdk/aws-apigateway/README.md index 60d2cdcfa3654..4d4d1a79eb797 100644 --- a/packages/@aws-cdk/aws-apigateway/README.md +++ b/packages/@aws-cdk/aws-apigateway/README.md @@ -32,6 +32,7 @@ running on AWS Lambda, or any web application. - [IAM-based authorizer](#iam-based-authorizer) - [Lambda-based token authorizer](#lambda-based-token-authorizer) - [Lambda-based request authorizer](#lambda-based-request-authorizer) + - [Cognito User Pools authorizer](#cognito-user-pools-authorizer) - [Mutual TLS](#mutal-tls-mtls) - [Deployments](#deployments) - [Deep dive: Invalidation of deployments](#deep-dive-invalidation-of-deployments) @@ -580,6 +581,25 @@ Authorizers can also be passed via the `defaultMethodOptions` property within th explicitly overridden, the specified defaults will be applied across all `Method`s across the `RestApi` or across all `Resource`s, depending on where the defaults were specified. +### Cognito User Pools authorizer + +API Gateway also allows [Amazon Cognito user pools as authorizer](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html) + +The following snippet configures a Cognito user pool as an authorizer: + +```ts +const userPool = new cognito.UserPool(stack, 'UserPool'); + +const auth = new apigateway.CognitoUserPoolsAuthorizer(this, 'booksAuthorizer', { + cognitoUserPools: [userPool] +}); + +books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), { + authorizer: auth, + authorizationType: apigateway.AuthorizationType.COGNITO, +}); +``` + ## Mutual TLS (mTLS) Mutual TLS can be configured to limit access to your API based by using client certificates instead of (or as an extension of) using authorization headers. diff --git a/packages/@aws-cdk/aws-apigateway/lib/authorizers/cognito.ts b/packages/@aws-cdk/aws-apigateway/lib/authorizers/cognito.ts new file mode 100644 index 0000000000000..a1d000189354c --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/lib/authorizers/cognito.ts @@ -0,0 +1,115 @@ +import * as cognito from '@aws-cdk/aws-cognito'; +import { Duration, Lazy, Names, Stack } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { CfnAuthorizer } from '../apigateway.generated'; +import { Authorizer, IAuthorizer } from '../authorizer'; +import { AuthorizationType } from '../method'; +import { IRestApi } from '../restapi'; + +/** + * Properties for CognitoUserPoolsAuthorizer + */ +export interface CognitoUserPoolsAuthorizerProps { + /** + * An optional human friendly name for the authorizer. Note that, this is not the primary identifier of the authorizer. + * + * @default - the unique construct ID + */ + readonly authorizerName?: string; + + /** + * The user pools to associate with this authorizer. + */ + readonly cognitoUserPools: cognito.IUserPool[]; + + /** + * How long APIGateway should cache the results. Max 1 hour. + * Disable caching by setting this to 0. + * + * @default Duration.minutes(5) + */ + readonly resultsCacheTtl?: Duration; + + /** + * The request header mapping expression for the bearer token. This is typically passed as part of the header, in which case + * this should be `method.request.header.Authorizer` where Authorizer is the header containing the bearer token. + * @see https://docs.aws.amazon.com/apigateway/api-reference/link-relation/authorizer-create/#identitySource + * @default `IdentitySource.header('Authorization')` + */ + readonly identitySource?: string; +} + +/** + * Cognito user pools based custom authorizer + * + * @resource AWS::ApiGateway::Authorizer + */ +export class CognitoUserPoolsAuthorizer extends Authorizer implements IAuthorizer { + /** + * The id of the authorizer. + * @attribute + */ + public readonly authorizerId: string; + + /** + * The ARN of the authorizer to be used in permission policies, such as IAM and resource-based grants. + * @attribute + */ + public readonly authorizerArn: string; + + /** + * The authorization type of this authorizer. + */ + public readonly authorizationType?: AuthorizationType; + + private restApiId?: string; + + constructor(scope: Construct, id: string, props: CognitoUserPoolsAuthorizerProps) { + super(scope, id); + + const restApiId = this.lazyRestApiId(); + const resource = new CfnAuthorizer(this, 'Resource', { + name: props.authorizerName ?? Names.uniqueId(this), + restApiId, + type: 'COGNITO_USER_POOLS', + providerArns: props.cognitoUserPools.map(userPool => userPool.userPoolArn), + authorizerResultTtlInSeconds: props.resultsCacheTtl?.toSeconds(), + identitySource: props.identitySource || 'method.request.header.Authorization', + }); + + this.authorizerId = resource.ref; + this.authorizerArn = Stack.of(this).formatArn({ + service: 'execute-api', + resource: restApiId, + resourceName: `authorizers/${this.authorizerId}`, + }); + this.authorizationType = AuthorizationType.COGNITO; + } + + /** + * Attaches this authorizer to a specific REST API. + * @internal + */ + public _attachToApi(restApi: IRestApi): void { + if (this.restApiId && this.restApiId !== restApi.restApiId) { + throw new Error('Cannot attach authorizer to two different rest APIs'); + } + + this.restApiId = restApi.restApiId; + } + + /** + * Returns a token that resolves to the Rest Api Id at the time of synthesis. + * Throws an error, during token resolution, if no RestApi is attached to this authorizer. + */ + private lazyRestApiId() { + return Lazy.string({ + produce: () => { + if (!this.restApiId) { + throw new Error(`Authorizer (${this.node.path}) must be attached to a RestApi`); + } + return this.restApiId; + }, + }); + } +} diff --git a/packages/@aws-cdk/aws-apigateway/lib/authorizers/index.ts b/packages/@aws-cdk/aws-apigateway/lib/authorizers/index.ts index 57289c931f760..fd93db036fefe 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/authorizers/index.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/authorizers/index.ts @@ -1,2 +1,3 @@ export * from './lambda'; export * from './identity-source'; +export * from './cognito'; diff --git a/packages/@aws-cdk/aws-apigateway/package.json b/packages/@aws-cdk/aws-apigateway/package.json index c9650deeb9a4b..3a0641e8b1162 100644 --- a/packages/@aws-cdk/aws-apigateway/package.json +++ b/packages/@aws-cdk/aws-apigateway/package.json @@ -80,6 +80,7 @@ "dependencies": { "@aws-cdk/aws-certificatemanager": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", + "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-elasticloadbalancingv2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", @@ -95,6 +96,7 @@ "peerDependencies": { "@aws-cdk/aws-certificatemanager": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", + "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-elasticloadbalancingv2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/cognito.test.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/cognito.test.ts new file mode 100644 index 0000000000000..e59339177d5d4 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/cognito.test.ts @@ -0,0 +1,66 @@ +import '@aws-cdk/assert/jest'; +import * as cognito from '@aws-cdk/aws-cognito'; +import { Duration, Stack } from '@aws-cdk/core'; +import { AuthorizationType, CognitoUserPoolsAuthorizer, RestApi } from '../../lib'; + +describe('Cognito Authorizer', () => { + test('default cognito authorizer', () => { + // GIVEN + const stack = new Stack(); + const userPool = new cognito.UserPool(stack, 'UserPool'); + + // WHEN + const authorizer = new CognitoUserPoolsAuthorizer(stack, 'myauthorizer', { + cognitoUserPools: [userPool], + }); + + const restApi = new RestApi(stack, 'myrestapi'); + restApi.root.addMethod('ANY', undefined, { + authorizer, + authorizationType: AuthorizationType.COGNITO, + }); + + // THEN + expect(stack).toHaveResource('AWS::ApiGateway::Authorizer', { + Type: 'COGNITO_USER_POOLS', + RestApiId: stack.resolve(restApi.restApiId), + IdentitySource: 'method.request.header.Authorization', + ProviderARNs: [stack.resolve(userPool.userPoolArn)], + }); + + expect(authorizer.authorizerArn.endsWith(`/authorizers/${authorizer.authorizerId}`)).toBeTruthy(); + }); + + test('cognito authorizer with all parameters specified', () => { + // GIVEN + const stack = new Stack(); + const userPool1 = new cognito.UserPool(stack, 'UserPool1'); + const userPool2 = new cognito.UserPool(stack, 'UserPool2'); + + // WHEN + const authorizer = new CognitoUserPoolsAuthorizer(stack, 'myauthorizer', { + cognitoUserPools: [userPool1, userPool2], + identitySource: 'method.request.header.whoami', + authorizerName: 'myauthorizer', + resultsCacheTtl: Duration.minutes(1), + }); + + const restApi = new RestApi(stack, 'myrestapi'); + restApi.root.addMethod('ANY', undefined, { + authorizer, + authorizationType: AuthorizationType.COGNITO, + }); + + // THEN + expect(stack).toHaveResource('AWS::ApiGateway::Authorizer', { + Type: 'COGNITO_USER_POOLS', + Name: 'myauthorizer', + RestApiId: stack.resolve(restApi.restApiId), + IdentitySource: 'method.request.header.whoami', + AuthorizerResultTtlInSeconds: 60, + ProviderARNs: [stack.resolve(userPool1.userPoolArn), stack.resolve(userPool2.userPoolArn)], + }); + + expect(authorizer.authorizerArn.endsWith(`/authorizers/${authorizer.authorizerId}`)).toBeTruthy(); + }); +}); diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.expected.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.expected.json new file mode 100644 index 0000000000000..990619cb495d4 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.expected.json @@ -0,0 +1,191 @@ +{ + "Resources": { + "UserPool6BA7E5F2": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "AccountRecoverySetting": { + "RecoveryMechanisms": [ + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } + ] + }, + "AdminCreateUserConfig": { + "AllowAdminCreateUserOnly": true + }, + "EmailVerificationMessage": "The verification code to your new account is {####}", + "EmailVerificationSubject": "Verify your new account", + "SmsVerificationMessage": "The verification code to your new account is {####}", + "VerificationMessageTemplate": { + "DefaultEmailOption": "CONFIRM_WITH_CODE", + "EmailMessage": "The verification code to your new account is {####}", + "EmailSubject": "Verify your new account", + "SmsMessage": "The verification code to your new account is {####}" + } + } + }, + "myauthorizer23CB99DD": { + "Type": "AWS::ApiGateway::Authorizer", + "Properties": { + "RestApiId": { + "Ref": "myrestapi551C8392" + }, + "Type": "COGNITO_USER_POOLS", + "IdentitySource": "method.request.header.Authorization", + "Name": "CognitoUserPoolsAuthorizerIntegmyauthorizer10C804C1", + "ProviderARNs": [ + { + "Fn::GetAtt": [ + "UserPool6BA7E5F2", + "Arn" + ] + } + ] + } + }, + "myrestapi551C8392": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Name": "myrestapi" + } + }, + "myrestapiCloudWatchRoleC48DA1DD": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + ] + ] + } + ] + } + }, + "myrestapiAccountA49A05BE": { + "Type": "AWS::ApiGateway::Account", + "Properties": { + "CloudWatchRoleArn": { + "Fn::GetAtt": [ + "myrestapiCloudWatchRoleC48DA1DD", + "Arn" + ] + } + }, + "DependsOn": [ + "myrestapi551C8392" + ] + }, + "myrestapiDeployment419B1464b903292b53d7532ca4296973bcb95b1a": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "myrestapi551C8392" + }, + "Description": "Automatically created by the RestApi construct" + }, + "DependsOn": [ + "myrestapiANY94B0497F" + ] + }, + "myrestapiDeploymentStageprodA9250EA4": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "RestApiId": { + "Ref": "myrestapi551C8392" + }, + "DeploymentId": { + "Ref": "myrestapiDeployment419B1464b903292b53d7532ca4296973bcb95b1a" + }, + "StageName": "prod" + } + }, + "myrestapiANY94B0497F": { + "Type": "AWS::ApiGateway::Method", + "Properties": { + "HttpMethod": "ANY", + "ResourceId": { + "Fn::GetAtt": [ + "myrestapi551C8392", + "RootResourceId" + ] + }, + "RestApiId": { + "Ref": "myrestapi551C8392" + }, + "AuthorizationType": "COGNITO_USER_POOLS", + "AuthorizerId": { + "Ref": "myauthorizer23CB99DD" + }, + "Integration": { + "IntegrationResponses": [ + { + "StatusCode": "200" + } + ], + "PassthroughBehavior": "NEVER", + "RequestTemplates": { + "application/json": "{ \"statusCode\": 200 }" + }, + "Type": "MOCK" + }, + "MethodResponses": [ + { + "StatusCode": "200" + } + ] + } + } + }, + "Outputs": { + "myrestapiEndpointE06F9D98": { + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Ref": "myrestapi551C8392" + }, + ".execute-api.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Ref": "myrestapiDeploymentStageprodA9250EA4" + }, + "/" + ] + ] + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.ts new file mode 100644 index 0000000000000..4830dc83ae29f --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.cognito-authorizer.ts @@ -0,0 +1,43 @@ +import * as cognito from '@aws-cdk/aws-cognito'; +import { App, Stack } from '@aws-cdk/core'; +import { AuthorizationType, CognitoUserPoolsAuthorizer, MockIntegration, PassthroughBehavior, RestApi } from '../../lib'; + +/* + * Stack verification steps: + * * 1. Get the IdToken for the created pool by adding user/app-client and using aws cognito-idp: + * * a. aws cognito-idp create-user-pool-client --user-pool-id --client-name --no-generate-secret + * * b. aws cognito-idp admin-create-user --user-pool-id --username --temporary-password + * * c. aws cognito-idp initiate-auth --client-id --auth-flow USER_PASSWORD_AUTH --auth-parameters USERNAME=,PASSWORD= + * * d. aws cognito-idp respond-to-auth-challenge --client-id --challenge-name --session + * * + * * 2. Verify the stack using above obtained token: + * * a. `curl -s -o /dev/null -w "%{http_code}" ` should return 401 + * * b. `curl -s -o /dev/null -w "%{http_code}" -H 'Authorization: ' ` should return 403 + * * c. `curl -s -o /dev/null -w "%{http_code}" -H 'Authorization: ' ` should return 200 + */ + +const app = new App(); +const stack = new Stack(app, 'CognitoUserPoolsAuthorizerInteg'); + +const userPool = new cognito.UserPool(stack, 'UserPool'); + +const authorizer = new CognitoUserPoolsAuthorizer(stack, 'myauthorizer', { + cognitoUserPools: [userPool], +}); + +const restApi = new RestApi(stack, 'myrestapi'); +restApi.root.addMethod('ANY', new MockIntegration({ + integrationResponses: [ + { statusCode: '200' }, + ], + passthroughBehavior: PassthroughBehavior.NEVER, + requestTemplates: { + 'application/json': '{ "statusCode": 200 }', + }, +}), { + methodResponses: [ + { statusCode: '200' }, + ], + authorizer, + authorizationType: AuthorizationType.COGNITO, +}); From 208a7c1904d2e58a255a32133acec5238d23affc Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Wed, 3 Feb 2021 22:16:20 +0000 Subject: [PATCH 10/21] chore(release): 1.88.0 --- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++++ version.v1.json | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d66ae0944d6..55ff1bfa44ad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,43 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.88.0](https://github.com/aws/aws-cdk/compare/v1.87.1...v1.88.0) (2021-02-03) + + +### ⚠ BREAKING CHANGES TO EXPERIMENTAL FEATURES + +* **appmesh:** the properties virtualRouter and virtualNode of VirtualServiceProps have been replaced with the union-like class VirtualServiceProvider +* **appmesh**: the method `addVirtualService` has been removed from `IMesh` +* **cloudfront:** experimental EdgeFunction stack names have changed from 'edge-lambda-stack-${region}' to 'edge-lambda-stack-${stackid}' to support multiple independent CloudFront distributions with EdgeFunctions. + +### Features + +* **apigateway:** cognito user pool authorizer ([#12786](https://github.com/aws/aws-cdk/issues/12786)) ([ff1e5b3](https://github.com/aws/aws-cdk/commit/ff1e5b3c580119c107fe26c67fe3cc220f9ee7c9)), closes [#5618](https://github.com/aws/aws-cdk/issues/5618) +* **apigateway:** import an existing Resource ([#12785](https://github.com/aws/aws-cdk/issues/12785)) ([8a1a9b8](https://github.com/aws/aws-cdk/commit/8a1a9b82a36e681334fd45be595f6ecdf904ad34)), closes [#4432](https://github.com/aws/aws-cdk/issues/4432) +* **appmesh:** change VirtualService provider to a union-like class ([#11978](https://github.com/aws/aws-cdk/issues/11978)) ([dfc765a](https://github.com/aws/aws-cdk/commit/dfc765af44c755f10be8f6c1c2eae55f62e2aa08)), closes [#9490](https://github.com/aws/aws-cdk/issues/9490) +* **aws-route53:** cross account DNS delegations ([#12680](https://github.com/aws/aws-cdk/issues/12680)) ([126a693](https://github.com/aws/aws-cdk/commit/126a6935cacc1f68b1d1155e484912d4ed6978f2)), closes [#8776](https://github.com/aws/aws-cdk/issues/8776) +* **cloudfront:** add PublicKey and KeyGroup L2 constructs ([#12743](https://github.com/aws/aws-cdk/issues/12743)) ([59cb6d0](https://github.com/aws/aws-cdk/commit/59cb6d032a55515ec5e9903f899de588d18d4cb5)) +* **core:** `stack.exportValue()` can be used to solve "deadly embrace" ([#12778](https://github.com/aws/aws-cdk/issues/12778)) ([3b66088](https://github.com/aws/aws-cdk/commit/3b66088010b6f2315a215e92505d5279680f16d4)), closes [#7602](https://github.com/aws/aws-cdk/issues/7602) [#2036](https://github.com/aws/aws-cdk/issues/2036) +* **ecr:** Public Gallery authorization token ([#12775](https://github.com/aws/aws-cdk/issues/12775)) ([8434294](https://github.com/aws/aws-cdk/commit/84342943ad9f2ea8a83773f00816a0b8117c4d17)) +* **ecs-patterns:** Add PlatformVersion option to ScheduledFargateTask props ([#12676](https://github.com/aws/aws-cdk/issues/12676)) ([3cbf38b](https://github.com/aws/aws-cdk/commit/3cbf38b09a9e66a6c009f833481fb25b8c5fc26c)), closes [#12623](https://github.com/aws/aws-cdk/issues/12623) +* **elbv2:** support for 2020 SSL policy ([#12710](https://github.com/aws/aws-cdk/issues/12710)) ([1dd3d05](https://github.com/aws/aws-cdk/commit/1dd3d0518dc2a70c725f87dd5d4377338389125c)), closes [#12595](https://github.com/aws/aws-cdk/issues/12595) +* **iam:** Permissions Boundaries ([#12777](https://github.com/aws/aws-cdk/issues/12777)) ([415eb86](https://github.com/aws/aws-cdk/commit/415eb861c65829cc53eabbbb8706f83f08c74570)), closes [aws/aws-cdk-rfcs#5](https://github.com/aws/aws-cdk-rfcs/issues/5) [#3242](https://github.com/aws/aws-cdk/issues/3242) +* **lambda:** inline code for Python 3.8 ([#12788](https://github.com/aws/aws-cdk/issues/12788)) ([8d3aaba](https://github.com/aws/aws-cdk/commit/8d3aabaffe436e6a3eebc0a58fe361c5b4b93f08)), closes [#6503](https://github.com/aws/aws-cdk/issues/6503) + + +### Bug Fixes + +* **apigateway:** stack update fails to replace api key ([#12745](https://github.com/aws/aws-cdk/issues/12745)) ([ffe7e42](https://github.com/aws/aws-cdk/commit/ffe7e425e605144a465cea9befa68d4fe19f9d8c)), closes [#12698](https://github.com/aws/aws-cdk/issues/12698) +* **cfn-include:** AWS::CloudFormation resources fail in monocdk ([#12758](https://github.com/aws/aws-cdk/issues/12758)) ([5060782](https://github.com/aws/aws-cdk/commit/5060782b00e17bdf44e225f8f5ef03344be238c7)), closes [#11595](https://github.com/aws/aws-cdk/issues/11595) +* **cli, codepipeline:** renamed bootstrap stack still not supported ([#12771](https://github.com/aws/aws-cdk/issues/12771)) ([40b32bb](https://github.com/aws/aws-cdk/commit/40b32bbda272b6e2f92fd5dd8de7ca5bf405ce52)), closes [#12594](https://github.com/aws/aws-cdk/issues/12594) [#12732](https://github.com/aws/aws-cdk/issues/12732) +* **cloudfront:** use node addr for edgeStackId name ([#12702](https://github.com/aws/aws-cdk/issues/12702)) ([c429bb7](https://github.com/aws/aws-cdk/commit/c429bb7df2406346426dce22d716cabc484ec7e6)), closes [#12323](https://github.com/aws/aws-cdk/issues/12323) +* **codedeploy:** wrong syntax on Windows 'installAgent' flag ([#12736](https://github.com/aws/aws-cdk/issues/12736)) ([238742e](https://github.com/aws/aws-cdk/commit/238742e4323310ce850d8edc70abe4b0e9f53186)), closes [#12734](https://github.com/aws/aws-cdk/issues/12734) +* **codepipeline:** permission denied for Action-level environment variables ([#12761](https://github.com/aws/aws-cdk/issues/12761)) ([99fd074](https://github.com/aws/aws-cdk/commit/99fd074a07ead624f64d3fe64685ba67c798976e)), closes [#12742](https://github.com/aws/aws-cdk/issues/12742) +* **ec2:** ARM-backed bastion hosts try to run x86-based Amazon Linux AMI ([#12280](https://github.com/aws/aws-cdk/issues/12280)) ([1a73d76](https://github.com/aws/aws-cdk/commit/1a73d761ad2363842567a1b6e0488ceb093e70b2)), closes [#12279](https://github.com/aws/aws-cdk/issues/12279) +* **efs:** EFS fails to create when using a VPC with multiple subnets per availability zone ([#12097](https://github.com/aws/aws-cdk/issues/12097)) ([889d673](https://github.com/aws/aws-cdk/commit/889d6734c10174f2661e45057c345cd112a44187)), closes [#10170](https://github.com/aws/aws-cdk/issues/10170) +* **iam:** cannot use the same Role for multiple Config Rules ([#12724](https://github.com/aws/aws-cdk/issues/12724)) ([2f6521a](https://github.com/aws/aws-cdk/commit/2f6521a1d8670b2653f7dee281309351181cf918)), closes [#12714](https://github.com/aws/aws-cdk/issues/12714) +* **lambda:** codeguru profiler not set up for Node runtime ([#12712](https://github.com/aws/aws-cdk/issues/12712)) ([59db763](https://github.com/aws/aws-cdk/commit/59db763e7d05d68fd85b6fd37246d69d4670d7d5)), closes [#12624](https://github.com/aws/aws-cdk/issues/12624) + ## [1.87.1](https://github.com/aws/aws-cdk/compare/v1.87.0...v1.87.1) (2021-01-28) diff --git a/version.v1.json b/version.v1.json index 816b141bbbf4a..f804856ae4ccf 100644 --- a/version.v1.json +++ b/version.v1.json @@ -1,3 +1,3 @@ { - "version": "1.87.1" + "version": "1.88.0" } From 5664480a97958263ee7cb903c2aff0276e738dc3 Mon Sep 17 00:00:00 2001 From: Steven Swartz Date: Thu, 4 Feb 2021 04:51:07 -0500 Subject: [PATCH 11/21] feat(lambda): layer version removal policy (#12792) closes #12718 Allows providing a removal policy for the `Lambda::LayerVersion` L2 construct to retain previous layer versions when the layer is updated. When a value is not provided, the default CloudFormation behavior is used, which is to delete the previous version defined in the stack. --- packages/@aws-cdk/aws-lambda/README.md | 11 +++++++++++ packages/@aws-cdk/aws-lambda/lib/layers.ts | 14 +++++++++++++- .../@aws-cdk/aws-lambda/test/layers.test.ts | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-lambda/README.md b/packages/@aws-cdk/aws-lambda/README.md index a59dc1a311936..de6940cd249e8 100644 --- a/packages/@aws-cdk/aws-lambda/README.md +++ b/packages/@aws-cdk/aws-lambda/README.md @@ -189,6 +189,17 @@ granting permissions to other AWS accounts or organizations. [Example of Lambda Layer usage](test/integ.layer-version.lit.ts) +By default, updating a layer creates a new layer version, and CloudFormation will delete the old version as part of the stack update. + +Alternatively, a removal policy can be used to retain the old version: + +```ts +import { LayerVersion } from '@aws-cdk/aws-lambda'; +new LayerVersion(this, 'MyLayer', { + removalPolicy: RemovalPolicy.RETAIN +}); +``` + ## Event Rule Target You can use an AWS Lambda function as a target for an Amazon CloudWatch event diff --git a/packages/@aws-cdk/aws-lambda/lib/layers.ts b/packages/@aws-cdk/aws-lambda/lib/layers.ts index 92de56f57e7a8..babf91079b8b6 100644 --- a/packages/@aws-cdk/aws-lambda/lib/layers.ts +++ b/packages/@aws-cdk/aws-lambda/lib/layers.ts @@ -1,4 +1,4 @@ -import { IResource, Resource } from '@aws-cdk/core'; +import { IResource, RemovalPolicy, Resource } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { Code } from './code'; import { CfnLayerVersion, CfnLayerVersionPermission } from './lambda.generated'; @@ -28,6 +28,14 @@ export interface LayerVersionOptions { * @default - A name will be generated. */ readonly layerVersionName?: string; + + /** + * Whether to retain this version of the layer when a new version is added + * or when the stack is deleted. + * + * @default RemovalPolicy.DESTROY + */ + readonly removalPolicy?: RemovalPolicy; } export interface LayerVersionProps extends LayerVersionOptions { @@ -198,6 +206,10 @@ export class LayerVersion extends LayerVersionBase { licenseInfo: props.license, }); + if (props.removalPolicy) { + resource.applyRemovalPolicy(props.removalPolicy); + } + props.code.bindToResource(resource, { resourceProperty: 'Content', }); diff --git a/packages/@aws-cdk/aws-lambda/test/layers.test.ts b/packages/@aws-cdk/aws-lambda/test/layers.test.ts index 0806f6d823dba..4a8f0e94ed6cb 100644 --- a/packages/@aws-cdk/aws-lambda/test/layers.test.ts +++ b/packages/@aws-cdk/aws-lambda/test/layers.test.ts @@ -86,4 +86,21 @@ describe('layers', () => { }, }, ResourcePart.CompleteDefinition); }); + + test('creating a layer with a removal policy', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new lambda.LayerVersion(stack, 'layer', { + code: lambda.Code.fromAsset(path.join(__dirname, 'layer-code')), + removalPolicy: cdk.RemovalPolicy.RETAIN, + }); + + // THEN + expect(canonicalizeTemplate(SynthUtils.toCloudFormation(stack))).toHaveResource('AWS::Lambda::LayerVersion', { + UpdateReplacePolicy: 'Retain', + DeletionPolicy: 'Retain', + }, ResourcePart.CompleteDefinition); + }); }); From 404b5569bb76e3f579dd3005dcf06eeeae9df7f6 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Thu, 4 Feb 2021 10:30:28 +0000 Subject: [PATCH 12/21] chore: isolate CoreConstruct imports to avoid merge conflicts (#12850) As part of CDKv2, the construct layer in '@aws-cdk/core' is being replaced with the constructs API in the 'constructs' module. During the transition period between v1 and v2, both exist. On the `master` branch, code will include importing `Construct` from the '@aws-cdk/core' module but this will not be possible in the `v2-main` branch where this API does not exist. Any change to the same line as the import of the `Construct` symbol will cause merge conflicts. Hence, move the import into a separate line and section to avoid these conflicts. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/assets/lib/staging.ts | 6 +- .../@aws-cdk/aws-apigateway/lib/deployment.ts | 6 +- .../lib/lambda-hook.ts | 6 +- .../lib/lifecycle-hook-target.ts | 6 +- .../lib/step-scaling-action.ts | 6 +- .../lib/step-scaling-policy.ts | 6 +- .../lib/target-tracking-scaling-policy.ts | 6 +- .../test/integ.core-custom-resources.ts | 6 +- .../test/integ.nested-stack.ts | 6 +- .../test/integ.nested-stacks-assets.ts | 6 +- .../test/integ.nested-stacks-multi.ts | 6 +- .../test/integ.nested-stacks-refs1.ts | 6 +- .../test/integ.nested-stacks-refs2.ts | 6 +- .../test/integ.nested-stacks-refs3.ts | 6 +- .../test/test.nested-stack.ts | 6 +- .../@aws-cdk/aws-cloudfront/lib/origin.ts | 6 +- .../aws-cloudwatch/lib/alarm-action.ts | 6 +- .../aws-codepipeline-actions/lib/action.ts | 6 +- .../lib/alexa-ask/deploy-action.ts | 6 +- .../lib/bitbucket/source-action.ts | 6 +- .../lib/codecommit/source-action.ts | 6 +- .../lib/codedeploy/ecs-deploy-action.ts | 6 +- .../lib/codedeploy/server-deploy-action.ts | 6 +- .../lib/ecr/source-action.ts | 6 +- .../lib/ecs/deploy-action.ts | 6 +- .../lib/github/source-action.ts | 6 +- .../lib/jenkins/jenkins-action.ts | 6 +- .../lib/lambda/invoke-action.ts | 6 +- .../lib/s3/deploy-action.ts | 6 +- .../lib/s3/source-action.ts | 6 +- .../lib/servicecatalog/deploy-action.ts | 6 +- .../@aws-cdk/aws-codepipeline/lib/action.ts | 6 +- .../@aws-cdk/aws-codepipeline/lib/pipeline.ts | 6 +- .../lib/private/rich-action.ts | 6 +- .../aws-dynamodb/lib/replica-provider.ts | 6 +- packages/@aws-cdk/aws-dynamodb/lib/table.ts | 6 +- packages/@aws-cdk/aws-ec2/lib/cfn-init.ts | 6 +- .../@aws-cdk/aws-ec2/lib/machine-image.ts | 6 +- .../aws-ecr-assets/lib/image-asset.ts | 6 +- .../@aws-cdk/aws-eks-legacy/lib/aws-auth.ts | 6 +- .../aws-eks-legacy/lib/cluster-resource.ts | 6 +- .../@aws-cdk/aws-eks-legacy/lib/cluster.ts | 6 +- .../@aws-cdk/aws-eks-legacy/lib/helm-chart.ts | 6 +- .../aws-eks-legacy/lib/k8s-resource.ts | 6 +- .../aws-eks-legacy/lib/kubectl-layer.ts | 6 +- .../lib/alb/application-listener-action.ts | 6 +- .../lib/alb/application-target-group.ts | 6 +- .../lib/nlb/network-listener-action.ts | 6 +- .../@aws-cdk/aws-events-targets/lib/util.ts | 6 +- .../lib/accelerator-security-group.ts | 6 +- .../aws-iam/test/immutable-role.test.ts | 6 +- packages/@aws-cdk/aws-kms/test/alias.test.ts | 6 +- .../lib/event-bridge.ts | 6 +- .../aws-lambda-destinations/lib/lambda.ts | 6 +- .../@aws-cdk/aws-lambda/lib/destination.ts | 6 +- .../private/scalable-function-attribute.ts | 6 +- packages/@aws-cdk/aws-rds/lib/private/util.ts | 6 +- packages/@aws-cdk/aws-route53/lib/util.ts | 6 +- .../aws-s3-notifications/lib/lambda.ts | 6 +- .../aws-sns-subscriptions/lib/lambda.ts | 6 +- .../@aws-cdk/aws-sns-subscriptions/lib/sqs.ts | 6 +- packages/@aws-cdk/aws-sns/lib/subscriber.ts | 6 +- packages/@aws-cdk/aws-sns/lib/topic-base.ts | 6 +- .../lib/provider-framework/provider.ts | 6 +- .../waiter-state-machine.ts | 6 +- .../lib/synths/simple-synth-action.ts | 6 +- .../lib/validation/shell-script-action.ts | 6 +- tools/cdk-build-tools/config/eslintrc.js | 1 + tools/eslint-plugin-cdk/lib/index.ts | 1 + .../lib/rules/construct-import-order.ts | 109 ++++++++++++++++++ .../construct-class-usage.expected.ts | 9 ++ .../construct-class-usage.ts | 5 + .../construct-multiple-specifiers.expected.ts | 8 ++ .../construct-multiple-specifiers.ts | 4 + .../construct-nonfinal.expected.ts | 9 ++ .../construct-nonfinal.ts | 5 + .../coreconstruct-class-usage.expected.ts | 9 ++ .../coreconstruct-class-usage.ts | 5 + ...econstruct-multiple-specifiers.expected.ts | 9 ++ .../coreconstruct-multiple-specifiers.ts | 5 + .../coreconstruct-nonfinal.expected.ts | 9 ++ .../coreconstruct-nonfinal.ts | 5 + .../construct-import-order/eslintrc.js | 6 + 83 files changed, 534 insertions(+), 67 deletions(-) create mode 100644 tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.expected.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.ts create mode 100644 tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/eslintrc.js diff --git a/packages/@aws-cdk/assets/lib/staging.ts b/packages/@aws-cdk/assets/lib/staging.ts index 3a441a0219f55..fe573ce442fdc 100644 --- a/packages/@aws-cdk/assets/lib/staging.ts +++ b/packages/@aws-cdk/assets/lib/staging.ts @@ -1,7 +1,11 @@ -import { AssetStaging, Construct } from '@aws-cdk/core'; +import { AssetStaging } from '@aws-cdk/core'; import { toSymlinkFollow } from './compat'; import { FingerprintOptions } from './fs/options'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Deprecated * @deprecated use `core.AssetStagingProps` diff --git a/packages/@aws-cdk/aws-apigateway/lib/deployment.ts b/packages/@aws-cdk/aws-apigateway/lib/deployment.ts index a286e978fdafb..d44b2ab223f4a 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/deployment.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/deployment.ts @@ -1,10 +1,14 @@ import * as crypto from 'crypto'; -import { Construct as CoreConstruct, Lazy, RemovalPolicy, Resource, CfnResource } from '@aws-cdk/core'; +import { Lazy, RemovalPolicy, Resource, CfnResource } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeployment } from './apigateway.generated'; import { Method } from './method'; import { IRestApi, RestApi, SpecRestApi, RestApiBase } from './restapi'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + export interface DeploymentProps { /** * The Rest API to deploy. diff --git a/packages/@aws-cdk/aws-autoscaling-hooktargets/lib/lambda-hook.ts b/packages/@aws-cdk/aws-autoscaling-hooktargets/lib/lambda-hook.ts index 6c3c9cd4caae2..dbe170438320e 100644 --- a/packages/@aws-cdk/aws-autoscaling-hooktargets/lib/lambda-hook.ts +++ b/packages/@aws-cdk/aws-autoscaling-hooktargets/lib/lambda-hook.ts @@ -3,9 +3,13 @@ import * as kms from '@aws-cdk/aws-kms'; import * as lambda from '@aws-cdk/aws-lambda'; import * as sns from '@aws-cdk/aws-sns'; import * as subs from '@aws-cdk/aws-sns-subscriptions'; -import { Construct } from '@aws-cdk/core'; + import { TopicHook } from './topic-hook'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Use a Lambda Function as a hook target * diff --git a/packages/@aws-cdk/aws-autoscaling/lib/lifecycle-hook-target.ts b/packages/@aws-cdk/aws-autoscaling/lib/lifecycle-hook-target.ts index b72a3245eb4d5..e15ae3ef081b5 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/lifecycle-hook-target.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/lifecycle-hook-target.ts @@ -1,6 +1,10 @@ -import { Construct } from '@aws-cdk/core'; + import { ILifecycleHook } from './lifecycle-hook'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Interface for autoscaling lifecycle hook targets */ diff --git a/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-action.ts b/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-action.ts index 9b9939d740d16..35b397e81dd04 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-action.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-action.ts @@ -1,8 +1,12 @@ -import { Construct as CoreConstruct, Duration, Lazy } from '@aws-cdk/core'; +import { Duration, Lazy } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { IAutoScalingGroup } from './auto-scaling-group'; import { CfnScalingPolicy } from './autoscaling.generated'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + /** * Properties for a scaling policy */ diff --git a/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts b/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts index a3a417bd126d5..c3b51a892c222 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/step-scaling-policy.ts @@ -1,10 +1,14 @@ import { findAlarmThresholds, normalizeIntervals } from '@aws-cdk/aws-autoscaling-common'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; -import { Construct as CoreConstruct, Duration } from '@aws-cdk/core'; +import { Duration } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { IAutoScalingGroup } from './auto-scaling-group'; import { AdjustmentType, MetricAggregationType, StepScalingAction } from './step-scaling-action'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + export interface BasicStepScalingPolicyProps { /** * Metric to scale on. diff --git a/packages/@aws-cdk/aws-autoscaling/lib/target-tracking-scaling-policy.ts b/packages/@aws-cdk/aws-autoscaling/lib/target-tracking-scaling-policy.ts index 5631016066761..9a89faef3b045 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/target-tracking-scaling-policy.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/target-tracking-scaling-policy.ts @@ -1,9 +1,13 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; -import { Construct as CoreConstruct, Duration } from '@aws-cdk/core'; +import { Duration } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { IAutoScalingGroup } from './auto-scaling-group'; import { CfnScalingPolicy } from './autoscaling.generated'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + /** * Base interface for target tracking props * diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-custom-resources.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.core-custom-resources.ts index 41029448ec1dc..1743444c1ad57 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.core-custom-resources.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-custom-resources.ts @@ -7,7 +7,11 @@ * - GetAtt.Attribute1: "foo" * - GetAtt.Attribute2: 1234 */ -import { App, CfnOutput, Construct, CustomResource, CustomResourceProvider, CustomResourceProviderRuntime, Stack, Token } from '@aws-cdk/core'; +import { App, CfnOutput, CustomResource, CustomResourceProvider, CustomResourceProviderRuntime, Stack, Token } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; /* eslint-disable cdk/no-core-construct */ diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stack.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stack.ts index 650609c0e6d40..9bb2ba7e5f852 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stack.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stack.ts @@ -2,9 +2,13 @@ import * as lambda from '@aws-cdk/aws-lambda'; import * as sns from '@aws-cdk/aws-sns'; import * as sns_subscriptions from '@aws-cdk/aws-sns-subscriptions'; import * as sqs from '@aws-cdk/aws-sqs'; -import { App, CfnParameter, Construct, Stack } from '@aws-cdk/core'; +import { App, CfnParameter, Stack } from '@aws-cdk/core'; import * as cfn from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /* eslint-disable cdk/no-core-construct */ interface MyNestedStackProps { diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-assets.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-assets.ts index 4a6599c289928..ad7ed4e85d294 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-assets.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-assets.ts @@ -1,9 +1,13 @@ /// !cdk-integ pragma:ignore-assets import * as path from 'path'; import * as lambda from '@aws-cdk/aws-lambda'; -import { App, Construct, Stack } from '@aws-cdk/core'; +import { App, Stack } from '@aws-cdk/core'; import * as cfn from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /* eslint-disable cdk/no-core-construct */ class NestedStack extends cfn.NestedStack { diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-multi.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-multi.ts index 109b151138b19..67f11d0f31878 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-multi.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-multi.ts @@ -1,8 +1,12 @@ /// !cdk-integ pragma:ignore-assets import * as sns from '@aws-cdk/aws-sns'; -import { App, Construct, Stack } from '@aws-cdk/core'; +import { App, Stack } from '@aws-cdk/core'; import * as cfn from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /* eslint-disable cdk/no-core-construct */ class YourNestedStack extends cfn.NestedStack { diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs1.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs1.ts index b6ca8b087f7ad..1240d8d39e5b3 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs1.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs1.ts @@ -5,9 +5,13 @@ /* eslint-disable cdk/no-core-construct */ import * as sns from '@aws-cdk/aws-sns'; -import { App, Construct, Stack } from '@aws-cdk/core'; +import { App, Stack } from '@aws-cdk/core'; import * as cfn from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + class ConsumerNestedStack extends cfn.NestedStack { constructor(scope: Construct, id: string, topic: sns.Topic) { super(scope, id); diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs2.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs2.ts index 5b884b209786b..712de493fa9a3 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs2.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs2.ts @@ -1,8 +1,12 @@ /// !cdk-integ * import * as sns from '@aws-cdk/aws-sns'; -import { App, Construct, Fn, Stack } from '@aws-cdk/core'; +import { App, Fn, Stack } from '@aws-cdk/core'; import * as cfn from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + // non-nested non-parent stack consumes a resource from a nested stack /* eslint-disable cdk/no-core-construct */ diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs3.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs3.ts index ab1f51be91330..f44eb1b1f731a 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs3.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-refs3.ts @@ -1,8 +1,12 @@ /// !cdk-integ * import * as sns from '@aws-cdk/aws-sns'; -import { App, Construct, Fn, Stack } from '@aws-cdk/core'; +import { App, Fn, Stack } from '@aws-cdk/core'; import * as cfn from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + // references between siblings /* eslint-disable cdk/no-core-construct */ diff --git a/packages/@aws-cdk/aws-cloudformation/test/test.nested-stack.ts b/packages/@aws-cdk/aws-cloudformation/test/test.nested-stack.ts index 056849c1dc12b..64656faf0fca3 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/test.nested-stack.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/test.nested-stack.ts @@ -3,10 +3,14 @@ import * as path from 'path'; import { expect, haveResource, matchTemplate, SynthUtils } from '@aws-cdk/assert'; import * as s3_assets from '@aws-cdk/aws-s3-assets'; import * as sns from '@aws-cdk/aws-sns'; -import { App, CfnParameter, CfnResource, Construct, ContextProvider, LegacyStackSynthesizer, Names, Stack } from '@aws-cdk/core'; +import { App, CfnParameter, CfnResource, ContextProvider, LegacyStackSynthesizer, Names, Stack } from '@aws-cdk/core'; import { Test } from 'nodeunit'; import { NestedStack } from '../lib/nested-stack'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /* eslint-disable cdk/no-core-construct */ /* eslint-disable max-len */ diff --git a/packages/@aws-cdk/aws-cloudfront/lib/origin.ts b/packages/@aws-cdk/aws-cloudfront/lib/origin.ts index 0722dff17099d..6f5a42e407e01 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/origin.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/origin.ts @@ -1,6 +1,10 @@ -import { Construct, Duration, Token } from '@aws-cdk/core'; +import { Duration, Token } from '@aws-cdk/core'; import { CfnDistribution } from './cloudfront.generated'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * The failover configuration used for Origin Groups, * returned in {@link OriginBindConfig.failoverConfig}. diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/alarm-action.ts b/packages/@aws-cdk/aws-cloudwatch/lib/alarm-action.ts index 7b48d0f055873..fb7afe98d7725 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/alarm-action.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/alarm-action.ts @@ -1,6 +1,10 @@ -import { Construct } from '@aws-cdk/core'; + import { IAlarm } from './alarm-base'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Interface for objects that can be the targets of CloudWatch alarm actions */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/action.ts index b3ce90e2aa793..c2f7ca5ca5305 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/action.ts @@ -1,6 +1,10 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as events from '@aws-cdk/aws-events'; -import { Construct, Lazy } from '@aws-cdk/core'; +import { Lazy } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; /** * Low-level class for generic CodePipeline Actions. diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/alexa-ask/deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/alexa-ask/deploy-action.ts index ebbe9fd060168..f5eb7c4e64579 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/alexa-ask/deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/alexa-ask/deploy-action.ts @@ -1,7 +1,11 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; -import { Construct, SecretValue } from '@aws-cdk/core'; +import { SecretValue } from '@aws-cdk/core'; import { Action } from '../action'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Construction properties of the {@link AlexaSkillDeployAction Alexa deploy Action}. */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/bitbucket/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/bitbucket/source-action.ts index 75f34777471e5..7d7625ab4fca4 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/bitbucket/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/bitbucket/source-action.ts @@ -1,9 +1,13 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct } from '@aws-cdk/core'; + import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Construction properties for {@link BitBucketSourceAction}. * diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts index 2b18bb9db6071..602a168487830 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts @@ -2,10 +2,14 @@ import * as codecommit from '@aws-cdk/aws-codecommit'; import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as targets from '@aws-cdk/aws-events-targets'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Names, Token } from '@aws-cdk/core'; +import { Names, Token } from '@aws-cdk/core'; import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * How should the CodeCommit Action detect changes. * This is the type of the {@link CodeCommitSourceAction.trigger} property. diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/ecs-deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/ecs-deploy-action.ts index 33bc07c148b1e..dd9ff5247e828 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/ecs-deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/ecs-deploy-action.ts @@ -1,9 +1,13 @@ import * as codedeploy from '@aws-cdk/aws-codedeploy'; import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Lazy } from '@aws-cdk/core'; +import { Lazy } from '@aws-cdk/core'; import { Action } from '../action'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Configuration for replacing a placeholder string in the ECS task * definition template file with an image URI. diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts index 07c0662824481..519a47708b74a 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts @@ -1,10 +1,14 @@ import * as codedeploy from '@aws-cdk/aws-codedeploy'; import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct } from '@aws-cdk/core'; + import { Action } from '../action'; import { deployArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Construction properties of the {@link CodeDeployServerDeployAction CodeDeploy server deploy CodePipeline Action}. */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts index f788c60d6aeea..6042d701017a5 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts @@ -2,10 +2,14 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as ecr from '@aws-cdk/aws-ecr'; import * as targets from '@aws-cdk/aws-events-targets'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Names } from '@aws-cdk/core'; +import { Names } from '@aws-cdk/core'; import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * The CodePipeline variables emitted by the ECR source Action. */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts index ec5dfb7ad2999..22c9988ac3ff5 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts @@ -1,10 +1,14 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as ecs from '@aws-cdk/aws-ecs'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Duration } from '@aws-cdk/core'; +import { Duration } from '@aws-cdk/core'; import { Action } from '../action'; import { deployArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Construction properties of {@link EcsDeployAction}. */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/github/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/github/source-action.ts index 82ca0b033120c..96b90a0ecb19b 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/github/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/github/source-action.ts @@ -1,8 +1,12 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; -import { Construct, SecretValue } from '@aws-cdk/core'; +import { SecretValue } from '@aws-cdk/core'; import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * If and how the GitHub source action should be triggered */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-action.ts index 5ebb614ea4ee7..81da65206b12a 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-action.ts @@ -1,8 +1,12 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; -import { Construct } from '@aws-cdk/core'; + import { Action } from '../action'; import { IJenkinsProvider, jenkinsArtifactsBounds } from './jenkins-provider'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * The type of the Jenkins Action that determines its CodePipeline Category - * Build, or Test. diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts index 987968728cb4d..f8a49d977f6b4 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts @@ -1,9 +1,13 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Construct, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; import { Action } from '../action'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Construction properties of the {@link LambdaInvokeAction Lambda invoke CodePipeline Action}. */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts index aebc8ba2548c8..75998456f4a39 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts @@ -1,10 +1,14 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as s3 from '@aws-cdk/aws-s3'; -import { Construct, Duration } from '@aws-cdk/core'; +import { Duration } from '@aws-cdk/core'; import { kebab as toKebabCase } from 'case'; import { Action } from '../action'; import { deployArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + // Class copied verbatim from the aws-s3-deployment module. // Yes, it sucks that we didn't abstract this properly in a common class, // but having 2 different CacheControl classes that behave differently would be worse I think. diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts index 2470ea6cca25f..cb86bd2591c6a 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts @@ -1,10 +1,14 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as targets from '@aws-cdk/aws-events-targets'; import * as s3 from '@aws-cdk/aws-s3'; -import { Construct, Names, Token } from '@aws-cdk/core'; +import { Names, Token } from '@aws-cdk/core'; import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * How should the S3 Action detect changes. * This is the type of the {@link S3SourceAction.trigger} property. diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/servicecatalog/deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/servicecatalog/deploy-action.ts index f55766315c070..9059af1ac0ba1 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/servicecatalog/deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/servicecatalog/deploy-action.ts @@ -1,8 +1,12 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct } from '@aws-cdk/core'; + import { Action } from '../action'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Construction properties of the {@link ServiceCatalogDeployAction ServiceCatalog deploy CodePipeline Action}. * diff --git a/packages/@aws-cdk/aws-codepipeline/lib/action.ts b/packages/@aws-cdk/aws-codepipeline/lib/action.ts index b2b6e79154699..6b28bcc8a3749 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/action.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/action.ts @@ -1,9 +1,13 @@ import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; -import { Construct, IResource } from '@aws-cdk/core'; +import { IResource } from '@aws-cdk/core'; import { Artifact } from './artifact'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + export enum ActionCategory { SOURCE = 'Source', BUILD = 'Build', diff --git a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts index ba7fd8d87233d..760e049c6ed73 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts @@ -3,7 +3,7 @@ import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as s3 from '@aws-cdk/aws-s3'; import { - App, BootstraplessSynthesizer, Construct as CoreConstruct, DefaultStackSynthesizer, + App, BootstraplessSynthesizer, DefaultStackSynthesizer, IStackSynthesizer, Lazy, Names, PhysicalName, RemovalPolicy, Resource, Stack, Token, } from '@aws-cdk/core'; import { Construct } from 'constructs'; @@ -15,6 +15,10 @@ import { RichAction } from './private/rich-action'; import { Stage } from './private/stage'; import { validateName, validateNamespaceName, validateSourceAction } from './private/validation'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + /** * Allows you to control where to place a new Stage when it's added to the Pipeline. * Note that you can provide only one of the below properties - diff --git a/packages/@aws-cdk/aws-codepipeline/lib/private/rich-action.ts b/packages/@aws-cdk/aws-codepipeline/lib/private/rich-action.ts index f218344da61fa..e2cde045f88a3 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/private/rich-action.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/private/rich-action.ts @@ -1,7 +1,11 @@ import * as events from '@aws-cdk/aws-events'; -import { Construct, ResourceEnvironment, Stack, Token, TokenComparison } from '@aws-cdk/core'; +import { ResourceEnvironment, Stack, Token, TokenComparison } from '@aws-cdk/core'; import { ActionBindOptions, ActionConfig, ActionProperties, IAction, IPipeline, IStage } from '../action'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Helper routines to work with Actions * diff --git a/packages/@aws-cdk/aws-dynamodb/lib/replica-provider.ts b/packages/@aws-cdk/aws-dynamodb/lib/replica-provider.ts index 45182672e45a0..718c0e693e454 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/replica-provider.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/replica-provider.ts @@ -1,10 +1,14 @@ import * as path from 'path'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Construct as CoreConstruct, Duration, NestedStack, Stack } from '@aws-cdk/core'; +import { Duration, NestedStack, Stack } from '@aws-cdk/core'; import * as cr from '@aws-cdk/custom-resources'; import { Construct } from 'constructs'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + export class ReplicaProvider extends NestedStack { /** * Creates a stack-singleton resource provider nested stack. diff --git a/packages/@aws-cdk/aws-dynamodb/lib/table.ts b/packages/@aws-cdk/aws-dynamodb/lib/table.ts index 792f68f4cca3e..b1c7c4f339ccd 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/table.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/table.ts @@ -3,7 +3,7 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import { - Aws, CfnCondition, CfnCustomResource, Construct as CoreConstruct, CustomResource, Fn, + Aws, CfnCondition, CfnCustomResource, CustomResource, Fn, IResource, Lazy, Names, RemovalPolicy, Resource, Stack, Token, } from '@aws-cdk/core'; import { Construct } from 'constructs'; @@ -14,6 +14,10 @@ import { ReplicaProvider } from './replica-provider'; import { EnableScalingProps, IScalableTableAttribute } from './scalable-attribute-api'; import { ScalableTableAttribute } from './scalable-table-attribute'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + const HASH_KEY_TYPE = 'HASH'; const RANGE_KEY_TYPE = 'RANGE'; diff --git a/packages/@aws-cdk/aws-ec2/lib/cfn-init.ts b/packages/@aws-cdk/aws-ec2/lib/cfn-init.ts index 324847845849b..2388c80736df4 100644 --- a/packages/@aws-cdk/aws-ec2/lib/cfn-init.ts +++ b/packages/@aws-cdk/aws-ec2/lib/cfn-init.ts @@ -1,11 +1,15 @@ import * as crypto from 'crypto'; import * as iam from '@aws-cdk/aws-iam'; -import { Aws, CfnResource, Construct } from '@aws-cdk/core'; +import { Aws, CfnResource } from '@aws-cdk/core'; import { InitElement } from './cfn-init-elements'; import { OperatingSystemType } from './machine-image'; import { InitBindOptions, InitElementConfig, InitElementType, InitPlatform } from './private/cfn-init-internal'; import { UserData } from './user-data'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * A CloudFormation-init configuration */ diff --git a/packages/@aws-cdk/aws-ec2/lib/machine-image.ts b/packages/@aws-cdk/aws-ec2/lib/machine-image.ts index 34405181774a1..1871fc1e75ac5 100644 --- a/packages/@aws-cdk/aws-ec2/lib/machine-image.ts +++ b/packages/@aws-cdk/aws-ec2/lib/machine-image.ts @@ -1,10 +1,14 @@ import * as ssm from '@aws-cdk/aws-ssm'; import * as cxschema from '@aws-cdk/cloud-assembly-schema'; -import { Construct, ContextProvider, Stack, Token } from '@aws-cdk/core'; +import { ContextProvider, Stack, Token } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { UserData } from './user-data'; import { WindowsVersion } from './windows-versions'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Interface for classes that can select an appropriate machine image to use */ diff --git a/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts b/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts index 2f6f5ff436baa..26a3a40f35335 100644 --- a/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts +++ b/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts @@ -2,10 +2,14 @@ import * as fs from 'fs'; import * as path from 'path'; import * as assets from '@aws-cdk/assets'; import * as ecr from '@aws-cdk/aws-ecr'; -import { Annotations, Construct as CoreConstruct, FeatureFlags, IgnoreMode, Stack, Token } from '@aws-cdk/core'; +import { Annotations, FeatureFlags, IgnoreMode, Stack, Token } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + /** * Options for DockerImageAsset */ diff --git a/packages/@aws-cdk/aws-eks-legacy/lib/aws-auth.ts b/packages/@aws-cdk/aws-eks-legacy/lib/aws-auth.ts index 276937847d558..933ccbb144ea1 100644 --- a/packages/@aws-cdk/aws-eks-legacy/lib/aws-auth.ts +++ b/packages/@aws-cdk/aws-eks-legacy/lib/aws-auth.ts @@ -1,9 +1,13 @@ import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Lazy, Stack } from '@aws-cdk/core'; +import { Lazy, Stack } from '@aws-cdk/core'; import { Mapping } from './aws-auth-mapping'; import { Cluster } from './cluster'; import { KubernetesResource } from './k8s-resource'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + export interface AwsAuthProps { /** * The EKS cluster to apply this configuration to. diff --git a/packages/@aws-cdk/aws-eks-legacy/lib/cluster-resource.ts b/packages/@aws-cdk/aws-eks-legacy/lib/cluster-resource.ts index 8c7600d3a1d34..81c04ef56653a 100644 --- a/packages/@aws-cdk/aws-eks-legacy/lib/cluster-resource.ts +++ b/packages/@aws-cdk/aws-eks-legacy/lib/cluster-resource.ts @@ -2,10 +2,14 @@ import * as path from 'path'; import * as cfn from '@aws-cdk/aws-cloudformation'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Construct, Duration, Token } from '@aws-cdk/core'; +import { Duration, Token } from '@aws-cdk/core'; import { CfnClusterProps } from './eks.generated'; import { KubectlLayer } from './kubectl-layer'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * A low-level CFN resource Amazon EKS cluster implemented through a custom * resource. diff --git a/packages/@aws-cdk/aws-eks-legacy/lib/cluster.ts b/packages/@aws-cdk/aws-eks-legacy/lib/cluster.ts index 61f3ccc01fe3d..a00358d7395ce 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 { Annotations, CfnOutput, Construct, Duration, IResource, Resource, Stack, Token, Tags } from '@aws-cdk/core'; +import { Annotations, CfnOutput, 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'; @@ -14,6 +14,10 @@ import { KubectlLayer } from './kubectl-layer'; import { spotInterruptHandler } from './spot-interrupt-handler'; import { renderUserData } from './user-data'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + // defaults are based on https://eksctl.io const DEFAULT_CAPACITY_COUNT = 2; const DEFAULT_CAPACITY_TYPE = ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE); diff --git a/packages/@aws-cdk/aws-eks-legacy/lib/helm-chart.ts b/packages/@aws-cdk/aws-eks-legacy/lib/helm-chart.ts index 9be42e435123c..a427353e9f6c7 100644 --- a/packages/@aws-cdk/aws-eks-legacy/lib/helm-chart.ts +++ b/packages/@aws-cdk/aws-eks-legacy/lib/helm-chart.ts @@ -1,10 +1,14 @@ import * as path from 'path'; import { CustomResource, CustomResourceProvider } from '@aws-cdk/aws-cloudformation'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Construct, Duration, Names, Stack } from '@aws-cdk/core'; +import { Duration, Names, Stack } from '@aws-cdk/core'; import { Cluster } from './cluster'; import { KubectlLayer } from './kubectl-layer'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Helm Chart options. */ diff --git a/packages/@aws-cdk/aws-eks-legacy/lib/k8s-resource.ts b/packages/@aws-cdk/aws-eks-legacy/lib/k8s-resource.ts index d5fd29d272903..14aa566d50406 100644 --- a/packages/@aws-cdk/aws-eks-legacy/lib/k8s-resource.ts +++ b/packages/@aws-cdk/aws-eks-legacy/lib/k8s-resource.ts @@ -1,7 +1,11 @@ import * as cfn from '@aws-cdk/aws-cloudformation'; -import { Construct, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; import { Cluster } from './cluster'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + export interface KubernetesResourceProps { /** * The EKS cluster to apply this configuration to. diff --git a/packages/@aws-cdk/aws-eks-legacy/lib/kubectl-layer.ts b/packages/@aws-cdk/aws-eks-legacy/lib/kubectl-layer.ts index 33aebc224d6ce..7121b34a277d6 100644 --- a/packages/@aws-cdk/aws-eks-legacy/lib/kubectl-layer.ts +++ b/packages/@aws-cdk/aws-eks-legacy/lib/kubectl-layer.ts @@ -1,6 +1,10 @@ import * as crypto from 'crypto'; import * as lambda from '@aws-cdk/aws-lambda'; -import { CfnResource, Construct, Resource, Stack, Token } from '@aws-cdk/core'; +import { CfnResource, Resource, Stack, Token } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; const KUBECTL_APP_ARN = 'arn:aws:serverlessrepo:us-east-1:903779448426:applications/lambda-layer-kubectl'; const KUBECTL_APP_VERSION = '1.13.7'; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts index 09ae095c46a92..91d839a605d74 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts @@ -1,9 +1,13 @@ -import { Construct, Duration, IConstruct, SecretValue, Tokenization } from '@aws-cdk/core'; +import { Duration, IConstruct, SecretValue, Tokenization } from '@aws-cdk/core'; import { CfnListener } from '../elasticloadbalancingv2.generated'; import { IListenerAction } from '../shared/listener-action'; import { IApplicationListener } from './application-listener'; import { IApplicationTargetGroup } from './application-target-group'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * What to do when a client makes a request to a listener * diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts index a457878c63bb9..a1d3de25bf82d 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts @@ -1,6 +1,6 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; -import { Annotations, Construct as CoreConstruct, Duration } from '@aws-cdk/core'; +import { Annotations, Duration } from '@aws-cdk/core'; import { IConstruct, Construct } from 'constructs'; import { ApplicationELBMetrics } from '../elasticloadbalancingv2-canned-metrics.generated'; import { @@ -13,6 +13,10 @@ import { determineProtocolAndPort } from '../shared/util'; import { IApplicationListener } from './application-listener'; import { HttpCodeTarget } from './application-load-balancer'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + /** * Properties for defining an Application Target Group */ diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener-action.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener-action.ts index 81b45a5e3b146..cc86ca0458ef7 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener-action.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener-action.ts @@ -1,9 +1,13 @@ -import { Construct, Duration } from '@aws-cdk/core'; +import { Duration } from '@aws-cdk/core'; import { CfnListener } from '../elasticloadbalancingv2.generated'; import { IListenerAction } from '../shared/listener-action'; import { INetworkListener } from './network-listener'; import { INetworkTargetGroup } from './network-target-group'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * What to do when a client makes a request to a listener * diff --git a/packages/@aws-cdk/aws-events-targets/lib/util.ts b/packages/@aws-cdk/aws-events-targets/lib/util.ts index fe41154b6037c..74465558bb3f9 100644 --- a/packages/@aws-cdk/aws-events-targets/lib/util.ts +++ b/packages/@aws-cdk/aws-events-targets/lib/util.ts @@ -1,7 +1,11 @@ import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Construct, ConstructNode, IConstruct, Names } from '@aws-cdk/core'; +import { ConstructNode, IConstruct, Names } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; /** * Obtain the Role for the EventBridge event diff --git a/packages/@aws-cdk/aws-globalaccelerator/lib/accelerator-security-group.ts b/packages/@aws-cdk/aws-globalaccelerator/lib/accelerator-security-group.ts index 793ae6b3aceca..9197613d69b61 100644 --- a/packages/@aws-cdk/aws-globalaccelerator/lib/accelerator-security-group.ts +++ b/packages/@aws-cdk/aws-globalaccelerator/lib/accelerator-security-group.ts @@ -1,8 +1,12 @@ import { ISecurityGroup, SecurityGroup, IVpc } from '@aws-cdk/aws-ec2'; -import { Construct } from '@aws-cdk/core'; + import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from '@aws-cdk/custom-resources'; import { EndpointGroup } from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * The security group used by a Global Accelerator to send traffic to resources in a VPC. */ diff --git a/packages/@aws-cdk/aws-iam/test/immutable-role.test.ts b/packages/@aws-cdk/aws-iam/test/immutable-role.test.ts index 0a14afee947a5..343c437c494e4 100644 --- a/packages/@aws-cdk/aws-iam/test/immutable-role.test.ts +++ b/packages/@aws-cdk/aws-iam/test/immutable-role.test.ts @@ -1,7 +1,11 @@ import '@aws-cdk/assert/jest'; -import { Construct, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; import * as iam from '../lib'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /* eslint-disable quote-props */ describe('ImmutableRole', () => { diff --git a/packages/@aws-cdk/aws-kms/test/alias.test.ts b/packages/@aws-cdk/aws-kms/test/alias.test.ts index b39ea8bf5b232..6c4356a7e8f36 100644 --- a/packages/@aws-cdk/aws-kms/test/alias.test.ts +++ b/packages/@aws-cdk/aws-kms/test/alias.test.ts @@ -1,9 +1,13 @@ import '@aws-cdk/assert/jest'; import { ArnPrincipal, PolicyStatement } from '@aws-cdk/aws-iam'; -import { App, CfnOutput, Construct, Stack } from '@aws-cdk/core'; +import { App, CfnOutput, Stack } from '@aws-cdk/core'; import { Alias } from '../lib/alias'; import { IKey, Key } from '../lib/key'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + test('default alias', () => { const app = new App(); const stack = new Stack(app, 'Test'); diff --git a/packages/@aws-cdk/aws-lambda-destinations/lib/event-bridge.ts b/packages/@aws-cdk/aws-lambda-destinations/lib/event-bridge.ts index 893a0096f92fd..f61d8409da7bd 100644 --- a/packages/@aws-cdk/aws-lambda-destinations/lib/event-bridge.ts +++ b/packages/@aws-cdk/aws-lambda-destinations/lib/event-bridge.ts @@ -1,6 +1,10 @@ import * as events from '@aws-cdk/aws-events'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Construct, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; /** * Use an Event Bridge event bus as a Lambda destination. diff --git a/packages/@aws-cdk/aws-lambda-destinations/lib/lambda.ts b/packages/@aws-cdk/aws-lambda-destinations/lib/lambda.ts index eaa6d020de3e7..319546471473d 100644 --- a/packages/@aws-cdk/aws-lambda-destinations/lib/lambda.ts +++ b/packages/@aws-cdk/aws-lambda-destinations/lib/lambda.ts @@ -1,9 +1,13 @@ import * as events from '@aws-cdk/aws-events'; import * as targets from '@aws-cdk/aws-events-targets'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Construct } from '@aws-cdk/core'; + import { EventBridgeDestination } from './event-bridge'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Options for a Lambda destination */ diff --git a/packages/@aws-cdk/aws-lambda/lib/destination.ts b/packages/@aws-cdk/aws-lambda/lib/destination.ts index 8fb6ab956db6d..8e2917ab827fc 100644 --- a/packages/@aws-cdk/aws-lambda/lib/destination.ts +++ b/packages/@aws-cdk/aws-lambda/lib/destination.ts @@ -1,6 +1,10 @@ -import { Construct } from '@aws-cdk/core'; + import { IFunction } from './function-base'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * A destination configuration */ diff --git a/packages/@aws-cdk/aws-lambda/lib/private/scalable-function-attribute.ts b/packages/@aws-cdk/aws-lambda/lib/private/scalable-function-attribute.ts index 3e1c2e634e0b1..34ceb28ad861f 100644 --- a/packages/@aws-cdk/aws-lambda/lib/private/scalable-function-attribute.ts +++ b/packages/@aws-cdk/aws-lambda/lib/private/scalable-function-attribute.ts @@ -1,7 +1,11 @@ import * as appscaling from '@aws-cdk/aws-applicationautoscaling'; -import { Construct, Token } from '@aws-cdk/core'; +import { Token } from '@aws-cdk/core'; import { IScalableFunctionAttribute, UtilizationScalingOptions } from '../scalable-attribute-api'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * A scalable lambda alias attribute */ diff --git a/packages/@aws-cdk/aws-rds/lib/private/util.ts b/packages/@aws-cdk/aws-rds/lib/private/util.ts index 8cba1e4a1ee1e..ca5f16d21e038 100644 --- a/packages/@aws-cdk/aws-rds/lib/private/util.ts +++ b/packages/@aws-cdk/aws-rds/lib/private/util.ts @@ -1,10 +1,14 @@ import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; -import { Construct, CfnDeletionPolicy, CfnResource, RemovalPolicy } from '@aws-cdk/core'; +import { CfnDeletionPolicy, CfnResource, RemovalPolicy } from '@aws-cdk/core'; import { DatabaseSecret } from '../database-secret'; import { IEngine } from '../engine'; import { Credentials } from '../props'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * The default set of characters we exclude from generated passwords for database users. * It's a combination of characters that have a tendency to cause problems in shell scripts, diff --git a/packages/@aws-cdk/aws-route53/lib/util.ts b/packages/@aws-cdk/aws-route53/lib/util.ts index a316e2ecd59f9..d703c77348538 100644 --- a/packages/@aws-cdk/aws-route53/lib/util.ts +++ b/packages/@aws-cdk/aws-route53/lib/util.ts @@ -1,6 +1,10 @@ -import { Construct, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; import { IHostedZone } from './hosted-zone-ref'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Validates a zone name is valid by Route53 specifc naming rules, * and that there is no trailing dot in the name. diff --git a/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts b/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts index 36ad917ec4ec4..183512a996e26 100644 --- a/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts +++ b/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts @@ -1,7 +1,11 @@ import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; -import { CfnResource, Construct, Names, Stack } from '@aws-cdk/core'; +import { CfnResource, Names, Stack } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; /** * Use a Lambda function as a bucket notification destination diff --git a/packages/@aws-cdk/aws-sns-subscriptions/lib/lambda.ts b/packages/@aws-cdk/aws-sns-subscriptions/lib/lambda.ts index 3ecab463d2c2c..aa7581653d5ba 100644 --- a/packages/@aws-cdk/aws-sns-subscriptions/lib/lambda.ts +++ b/packages/@aws-cdk/aws-sns-subscriptions/lib/lambda.ts @@ -1,9 +1,13 @@ import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import * as sns from '@aws-cdk/aws-sns'; -import { Construct, Names, Stack } from '@aws-cdk/core'; +import { Names, Stack } from '@aws-cdk/core'; import { SubscriptionProps } from './subscription'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Properties for a Lambda subscription */ diff --git a/packages/@aws-cdk/aws-sns-subscriptions/lib/sqs.ts b/packages/@aws-cdk/aws-sns-subscriptions/lib/sqs.ts index bac6a13859d9c..4a41c5e43feb2 100644 --- a/packages/@aws-cdk/aws-sns-subscriptions/lib/sqs.ts +++ b/packages/@aws-cdk/aws-sns-subscriptions/lib/sqs.ts @@ -1,9 +1,13 @@ import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; import * as sqs from '@aws-cdk/aws-sqs'; -import { Construct, Names, Stack } from '@aws-cdk/core'; +import { Names, Stack } from '@aws-cdk/core'; import { SubscriptionProps } from './subscription'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Properties for an SQS subscription */ diff --git a/packages/@aws-cdk/aws-sns/lib/subscriber.ts b/packages/@aws-cdk/aws-sns/lib/subscriber.ts index edfd3632d415a..d63667dde46e5 100644 --- a/packages/@aws-cdk/aws-sns/lib/subscriber.ts +++ b/packages/@aws-cdk/aws-sns/lib/subscriber.ts @@ -1,7 +1,11 @@ -import { Construct } from '@aws-cdk/core'; + import { SubscriptionOptions } from './subscription'; import { ITopic } from './topic-base'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Subscription configuration */ diff --git a/packages/@aws-cdk/aws-sns/lib/topic-base.ts b/packages/@aws-cdk/aws-sns/lib/topic-base.ts index bddfde6288748..db262ef87e068 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic-base.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic-base.ts @@ -1,9 +1,13 @@ import * as iam from '@aws-cdk/aws-iam'; -import { Construct, IResource, Resource, Token } from '@aws-cdk/core'; +import { IResource, Resource, Token } from '@aws-cdk/core'; import { TopicPolicy } from './policy'; import { ITopicSubscription } from './subscriber'; import { Subscription } from './subscription'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Represents an SNS topic */ diff --git a/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts b/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts index 3ae10fdf2e560..9da696f268b92 100644 --- a/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts +++ b/packages/@aws-cdk/custom-resources/lib/provider-framework/provider.ts @@ -3,12 +3,16 @@ import * as cfn from '@aws-cdk/aws-cloudformation'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as lambda from '@aws-cdk/aws-lambda'; import * as logs from '@aws-cdk/aws-logs'; -import { Construct as CoreConstruct, Duration } from '@aws-cdk/core'; +import { Duration } from '@aws-cdk/core'; import { Construct } from 'constructs'; import * as consts from './runtime/consts'; import { calculateRetryPolicy } from './util'; import { WaiterStateMachine } from './waiter-state-machine'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + const RUNTIME_HANDLER_PATH = path.join(__dirname, 'runtime'); const FRAMEWORK_HANDLER_TIMEOUT = Duration.minutes(15); // keep it simple for now diff --git a/packages/@aws-cdk/custom-resources/lib/provider-framework/waiter-state-machine.ts b/packages/@aws-cdk/custom-resources/lib/provider-framework/waiter-state-machine.ts index 513e18d7f9c8b..6799fb3178123 100644 --- a/packages/@aws-cdk/custom-resources/lib/provider-framework/waiter-state-machine.ts +++ b/packages/@aws-cdk/custom-resources/lib/provider-framework/waiter-state-machine.ts @@ -1,6 +1,10 @@ import { Grant, IGrantable, PolicyStatement, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; import { IFunction } from '@aws-cdk/aws-lambda'; -import { CfnResource, Construct, Duration, Stack } from '@aws-cdk/core'; +import { CfnResource, Duration, Stack } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; export interface WaiterStateMachineProps { /** diff --git a/packages/@aws-cdk/pipelines/lib/synths/simple-synth-action.ts b/packages/@aws-cdk/pipelines/lib/synths/simple-synth-action.ts index 0a67af8a5609d..415f49f703e26 100644 --- a/packages/@aws-cdk/pipelines/lib/synths/simple-synth-action.ts +++ b/packages/@aws-cdk/pipelines/lib/synths/simple-synth-action.ts @@ -6,11 +6,15 @@ import * as codepipeline_actions from '@aws-cdk/aws-codepipeline-actions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; import { cloudAssemblyBuildSpecDir } from '../private/construct-internals'; import { toPosixPath } from '../private/fs'; import { copyEnvironmentVariables, filterEmpty } from './_util'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Configuration options for a SimpleSynth */ diff --git a/packages/@aws-cdk/pipelines/lib/validation/shell-script-action.ts b/packages/@aws-cdk/pipelines/lib/validation/shell-script-action.ts index f70aa7897c1be..59f64555a76b5 100644 --- a/packages/@aws-cdk/pipelines/lib/validation/shell-script-action.ts +++ b/packages/@aws-cdk/pipelines/lib/validation/shell-script-action.ts @@ -4,9 +4,13 @@ import * as codepipeline_actions from '@aws-cdk/aws-codepipeline-actions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct } from '@aws-cdk/core'; + import { StackOutput } from '../stage'; +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + /** * Properties for ShellScriptAction */ diff --git a/tools/cdk-build-tools/config/eslintrc.js b/tools/cdk-build-tools/config/eslintrc.js index 446af2c2e2ff4..8fda93acca482 100644 --- a/tools/cdk-build-tools/config/eslintrc.js +++ b/tools/cdk-build-tools/config/eslintrc.js @@ -41,6 +41,7 @@ module.exports = { }, ignorePatterns: ['*.js', '*.d.ts', 'node_modules/', '*.generated.ts'], rules: { + 'cdk/construct-import-order': [ 'error' ], 'cdk/no-core-construct': [ 'error' ], 'cdk/no-qualified-construct': [ 'error' ], // Require use of the `import { foo } from 'bar';` form instead of `import foo = require('bar');` diff --git a/tools/eslint-plugin-cdk/lib/index.ts b/tools/eslint-plugin-cdk/lib/index.ts index 94eef4dd8f57f..a9eb84b77ef0f 100644 --- a/tools/eslint-plugin-cdk/lib/index.ts +++ b/tools/eslint-plugin-cdk/lib/index.ts @@ -1,4 +1,5 @@ export const rules = { 'no-core-construct': require('./rules/no-core-construct'), 'no-qualified-construct': require('./rules/no-qualified-construct'), + 'construct-import-order': require('./rules/construct-import-order'), }; diff --git a/tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts b/tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts new file mode 100644 index 0000000000000..bc6d5a0e160bf --- /dev/null +++ b/tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts @@ -0,0 +1,109 @@ +// +// This rule ensures that the `@aws-cdk/core.Construct` class is always +// imported at the end, and in a separate section. In the `v2-main` branch, +// this class is removed and so is the import. Keeping it in a separate line +// and section ensures that any other adjustments to the import do not cause +// conflicts on forward merges. +// + +import { ImportDeclaration } from 'estree'; +import { Rule } from 'eslint'; + +interface ImportOrderViolation { + node: ImportDeclaration; + localName: string; + range: [number, number]; +} + +let importOrderViolation: ImportOrderViolation | undefined; +let coreConstructImportLine: ImportDeclaration | undefined; +let lastImport: Rule.Node | undefined; + +export function create(context: Rule.RuleContext): Rule.NodeListener { + // skip core + if (context.getFilename().includes('@aws-cdk/core')) { + return {}; + } + + return { + Program: _ => { + // reset for every file + importOrderViolation = undefined; + coreConstructImportLine = undefined; + lastImport = undefined; + }, + + // collect all "import" statements. we will later use them to determine + // exactly how to import `core.Construct`. + ImportDeclaration: node => { + lastImport = node; + + if (coreConstructImportLine && coreConstructImportLine.range) { + // If CoreConstruct import was previously seen, this import line should not succeed it. + + importOrderViolation = { + node: coreConstructImportLine, + range: coreConstructImportLine.range, + localName: coreConstructImportLine.specifiers[0].local.name, + }; + } + + for (const [i, s] of node.specifiers.entries()) { + const isConstruct = (s.local.name === 'CoreConstruct' || s.local.name === 'Construct') && node.source.value === '@aws-cdk/core'; + if (isConstruct && s.range) { + if (node.specifiers.length > 1) { + // if there is more than one specifier on the line that also imports CoreConstruct, i.e., + // `import { Resource, Construct as CoreConstruct, Token } from '@aws-cdk/core'` + + // If this is the last specifier, delete just that. If not, delete until the beginning of the next specifier. + const range: [number, number] = (i === node.specifiers.length - 1) ? s.range : [s.range[0], node.specifiers[i + 1].range![0]]; + importOrderViolation = { node, range, localName: s.local.name }; + } else { + // This means that CoreConstruct is the only import within this line, + // so record the node so the whole line can be removed if there are imports that follow + + coreConstructImportLine = node; + } + } + } + }, + + Identifier: node => { + if ( + node.parent.type !== 'ImportSpecifier' && + (node.name === 'CoreConstruct' || node.name === 'Construct') && + importOrderViolation + ) { + reportImportOrderViolations(context); + } + }, + } +} + +function reportImportOrderViolations(context: Rule.RuleContext) { + if (importOrderViolation && lastImport) { + const violation = importOrderViolation; + const _lastImport = lastImport; + context.report({ + message: 'To avoid merge conflicts with the v2 branch, import of "@aws-cdk/core.Construct" must be in its own line, ' + + 'and as the very last import.', + node: violation.node, + fix: fixer => { + const fixes: Rule.Fix[] = []; + fixes.push(fixer.removeRange(violation.range)); + const sym = violation.localName === 'Construct' ? 'Construct' : 'Construct as CoreConstruct' + const addImport = `import { ${sym} } from '@aws-cdk/core';`; + fixes.push(fixer.insertTextAfter(_lastImport, [ + "", + "", + "// keep this import separate from other imports to reduce chance for merge conflicts with v2-main", + "// eslint-disable-next-line no-duplicate-imports, import/order", + addImport, + ].join('\n'))); + return fixes; + } + }); + // reset, so that this is reported only once + importOrderViolation = undefined; + } +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.expected.ts new file mode 100644 index 0000000000000..a6c9ecede29f0 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.expected.ts @@ -0,0 +1,9 @@ + +import { Something } from 'Somewhere'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + +class MyConstruct extends Construct { +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.ts new file mode 100644 index 0000000000000..8689366792602 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-class-usage.ts @@ -0,0 +1,5 @@ +import { Construct } from '@aws-cdk/core'; +import { Something } from 'Somewhere'; + +class MyConstruct extends Construct { +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.expected.ts new file mode 100644 index 0000000000000..b0458a380f220 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.expected.ts @@ -0,0 +1,8 @@ +import { Resource } from '@aws-cdk/core'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + +let x: Resource; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.ts new file mode 100644 index 0000000000000..c417c728ab86c --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-multiple-specifiers.ts @@ -0,0 +1,4 @@ +import { Construct, Resource } from '@aws-cdk/core'; + +let x: Resource; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.expected.ts new file mode 100644 index 0000000000000..a9e29b0d3a912 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.expected.ts @@ -0,0 +1,9 @@ + +import { Something } from 'Somewhere'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + +let x: Something; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.ts new file mode 100644 index 0000000000000..d7716d82c3d12 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/construct-nonfinal.ts @@ -0,0 +1,5 @@ +import { Construct } from '@aws-cdk/core'; +import { Something } from 'Somewhere'; + +let x: Something; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.expected.ts new file mode 100644 index 0000000000000..eccef051ab56c --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.expected.ts @@ -0,0 +1,9 @@ + +import { Something } from 'Somewhere'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + +class MyConstruct extends CoreConstruct { +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.ts new file mode 100644 index 0000000000000..5cf72993ecbe9 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-class-usage.ts @@ -0,0 +1,5 @@ +import { Construct as CoreConstruct } from '@aws-cdk/core'; +import { Something } from 'Somewhere'; + +class MyConstruct extends CoreConstruct { +} \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.expected.ts new file mode 100644 index 0000000000000..8a8b9c6efe4b4 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.expected.ts @@ -0,0 +1,9 @@ +import { Resource, Token } from '@aws-cdk/core'; +import { Construct } from 'constructs' + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + +let x: CoreConstruct; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.ts new file mode 100644 index 0000000000000..403f5166a31bc --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-multiple-specifiers.ts @@ -0,0 +1,5 @@ +import { Construct as CoreConstruct, Resource, Token } from '@aws-cdk/core'; +import { Construct } from 'constructs' + +let x: CoreConstruct; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.expected.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.expected.ts new file mode 100644 index 0000000000000..a0430db275df2 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.expected.ts @@ -0,0 +1,9 @@ + +import { Construct } from 'constructs'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct as CoreConstruct } from '@aws-cdk/core'; + +let x: CoreConstruct; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.ts b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.ts new file mode 100644 index 0000000000000..98baab61bb84c --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/coreconstruct-nonfinal.ts @@ -0,0 +1,5 @@ +import { Construct as CoreConstruct } from '@aws-cdk/core'; +import { Construct } from 'constructs'; + +let x: CoreConstruct; +let y: Construct; \ No newline at end of file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/eslintrc.js b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/eslintrc.js new file mode 100644 index 0000000000000..3082e03d4ed79 --- /dev/null +++ b/tools/eslint-plugin-cdk/test/rules/fixtures/construct-import-order/eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['rulesdir'], + rules: { + 'rulesdir/construct-import-order': [ 'error' ], + } +} \ No newline at end of file From be7202fa229435607e81d480726e9ce7f625b85a Mon Sep 17 00:00:00 2001 From: Chris McKnight Date: Thu, 4 Feb 2021 06:03:42 -0600 Subject: [PATCH 13/21] fix(core): incorrect GetParameter permissions in nonstandard partitions (#12813) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml b/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml index ee30856453ff9..b541401f930e7 100644 --- a/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml +++ b/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml @@ -358,7 +358,7 @@ Resources: Action: - ssm:GetParameter Resource: - - Fn::Sub: "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter${CdkBootstrapVersion}" + - Fn::Sub: "arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter${CdkBootstrapVersion}" Version: '2012-10-17' PolicyName: default RoleName: From a53032976ee4119375a46861bbaa9907725f9745 Mon Sep 17 00:00:00 2001 From: Robert Djurasaj Date: Thu, 4 Feb 2021 05:43:44 -0700 Subject: [PATCH 14/21] chore(core): minor typo in Names.ts in core (#12738) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/core/lib/names.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/core/lib/names.ts b/packages/@aws-cdk/core/lib/names.ts index 03998fcebe902..2d204c298d9fe 100644 --- a/packages/@aws-cdk/core/lib/names.ts +++ b/packages/@aws-cdk/core/lib/names.ts @@ -9,7 +9,7 @@ import { makeUniqueId } from './private/uniqueid'; export class Names { /** * Returns a CloudFormation-compatible unique identifier for a construct based - * on its path. The identifier includes a human readable porition rendered + * on its path. The identifier includes a human readable portion rendered * from the path components and a hash suffix. * * @param construct The construct @@ -23,7 +23,7 @@ export class Names { /** * Returns a CloudFormation-compatible unique identifier for a construct based - * on its path. The identifier includes a human readable porition rendered + * on its path. The identifier includes a human readable portion rendered * from the path components and a hash suffix. * * TODO (v2): replace with API to use `constructs.Node`. From b16ea9fe55892637c5352d73d44a90cd7aae1789 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Thu, 4 Feb 2021 13:21:38 +0000 Subject: [PATCH 15/21] chore: update error message with the correct property name (#12863) A previous commit - 715a0300 - introduced the `sameEnvironment` property but incorrectly stated this as `allowPermissions` property in the error message. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda/lib/function-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-lambda/lib/function-base.ts b/packages/@aws-cdk/aws-lambda/lib/function-base.ts index 8b8dd585c21c2..92ca396cafbb2 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function-base.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function-base.ts @@ -326,7 +326,7 @@ export abstract class FunctionBase extends Resource implements IFunction { const permissionNode = this._functionNode().tryFindChild(identifier); if (!permissionNode) { throw new Error('Cannot modify permission to lambda function. Function is either imported or $LATEST version. ' - + 'If the function is imported from the same account use `fromFunctionAttributes()` API with the `allowPermissions` flag.'); + + 'If the function is imported from the same account use `fromFunctionAttributes()` API with the `sameEnvironment` flag.'); } return { statementAdded: true, policyDependable: permissionNode }; }, From f959b3a2eeb5a9a9e44ea3f88622f77f7667bfa4 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Thu, 4 Feb 2021 16:37:35 +0200 Subject: [PATCH 16/21] feat(cfnspec): cloudformation spec v26.0.0 (#12841) Co-authored-by: AWS CDK Team Co-authored-by: Eli Polonsky Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../@aws-cdk/aws-lookoutvision/.eslintrc.js | 3 + .../@aws-cdk/aws-lookoutvision/.gitignore | 19 + .../@aws-cdk/aws-lookoutvision/.npmignore | 28 + packages/@aws-cdk/aws-lookoutvision/LICENSE | 201 +++++ packages/@aws-cdk/aws-lookoutvision/NOTICE | 2 + packages/@aws-cdk/aws-lookoutvision/README.md | 20 + .../@aws-cdk/aws-lookoutvision/jest.config.js | 2 + .../@aws-cdk/aws-lookoutvision/lib/index.ts | 2 + .../@aws-cdk/aws-lookoutvision/package.json | 97 +++ .../test/lookoutvision.test.ts | 6 + packages/@aws-cdk/cfnspec/CHANGELOG.md | 84 +++ packages/@aws-cdk/cfnspec/cfn.version | 2 +- ...0_CloudFormationResourceSpecification.json | 710 +++++++++++++++++- .../cloudformation-include/package.json | 2 + packages/aws-cdk-lib/package.json | 1 + packages/decdk/package.json | 1 + packages/monocdk/package.json | 1 + 17 files changed, 1146 insertions(+), 35 deletions(-) create mode 100644 packages/@aws-cdk/aws-lookoutvision/.eslintrc.js create mode 100644 packages/@aws-cdk/aws-lookoutvision/.gitignore create mode 100644 packages/@aws-cdk/aws-lookoutvision/.npmignore create mode 100644 packages/@aws-cdk/aws-lookoutvision/LICENSE create mode 100644 packages/@aws-cdk/aws-lookoutvision/NOTICE create mode 100644 packages/@aws-cdk/aws-lookoutvision/README.md create mode 100644 packages/@aws-cdk/aws-lookoutvision/jest.config.js create mode 100644 packages/@aws-cdk/aws-lookoutvision/lib/index.ts create mode 100644 packages/@aws-cdk/aws-lookoutvision/package.json create mode 100644 packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts diff --git a/packages/@aws-cdk/aws-lookoutvision/.eslintrc.js b/packages/@aws-cdk/aws-lookoutvision/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-lookoutvision/.gitignore b/packages/@aws-cdk/aws-lookoutvision/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/.gitignore @@ -0,0 +1,19 @@ +*.js +*.js.map +*.d.ts +tsconfig.json +node_modules +*.generated.ts +dist +.jsii + +.LAST_BUILD +.nyc_output +coverage +.nycrc +.LAST_PACKAGE +*.snk +nyc.config.js +!.eslintrc.js +!jest.config.js +junit.xml diff --git a/packages/@aws-cdk/aws-lookoutvision/.npmignore b/packages/@aws-cdk/aws-lookoutvision/.npmignore new file mode 100644 index 0000000000000..e4486030fcb17 --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/.npmignore @@ -0,0 +1,28 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json + +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ diff --git a/packages/@aws-cdk/aws-lookoutvision/LICENSE b/packages/@aws-cdk/aws-lookoutvision/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/aws-lookoutvision/NOTICE b/packages/@aws-cdk/aws-lookoutvision/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/aws-lookoutvision/README.md b/packages/@aws-cdk/aws-lookoutvision/README.md new file mode 100644 index 0000000000000..b0082462251d2 --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/README.md @@ -0,0 +1,20 @@ +# AWS::LookoutVision Construct Library + + +--- + +![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge) + +> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use. +> +> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib + +--- + + + +This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. + +```ts +import lookoutvision = require('@aws-cdk/aws-lookoutvision'); +``` diff --git a/packages/@aws-cdk/aws-lookoutvision/jest.config.js b/packages/@aws-cdk/aws-lookoutvision/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-lookoutvision/lib/index.ts b/packages/@aws-cdk/aws-lookoutvision/lib/index.ts new file mode 100644 index 0000000000000..1be824f5b354f --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::LookoutVision CloudFormation Resources: +export * from './lookoutvision.generated'; diff --git a/packages/@aws-cdk/aws-lookoutvision/package.json b/packages/@aws-cdk/aws-lookoutvision/package.json new file mode 100644 index 0000000000000..9f7d59fd4c321 --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/package.json @@ -0,0 +1,97 @@ +{ + "name": "@aws-cdk/aws-lookoutvision", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::LookoutVision", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.LookoutVision", + "packageId": "Amazon.CDK.AWS.LookoutVision", + "signAssembly": true, + "assemblyOriginatorKeyFile": "../../key.snk", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "java": { + "package": "software.amazon.awscdk.services.lookoutvision", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "lookoutvision" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-lookoutvision", + "module": "aws_cdk.aws_lookoutvision" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-lookoutvision" + }, + "homepage": "https://github.com/aws/aws-cdk", + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "cfn2ts": "cfn2ts", + "build+test": "yarn build && yarn test", + "build+test+package": "yarn build+test && yarn package", + "compat": "cdk-compat", + "gen": "cfn2ts", + "rosetta:extract": "yarn --silent jsii-rosetta extract" + }, + "cdk-build": { + "cloudformation": "AWS::LookoutVision", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::LookoutVision", + "aws-lookoutvision" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/assert": "0.0.0", + "cdk-build-tools": "0.0.0", + "cfn2ts": "0.0.0", + "pkglint": "0.0.0" + }, + "dependencies": { + "@aws-cdk/core": "0.0.0" + }, + "peerDependencies": { + "@aws-cdk/core": "0.0.0" + }, + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "stability": "experimental", + "maturity": "cfn-only", + "awscdkio": { + "announce": false + } +} diff --git a/packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts b/packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts new file mode 100644 index 0000000000000..e394ef336bfb4 --- /dev/null +++ b/packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts @@ -0,0 +1,6 @@ +import '@aws-cdk/assert/jest'; +import {} from '../lib'; + +test('No tests are specified for this package', () => { + expect(true).toBe(true); +}); diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index bf8b43b6865e2..2d117eebb4978 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,87 @@ +# CloudFormation Resource Specification v26.0.0 + +## New Resource Types + +* AWS::LookoutVision::Project +* AWS::SageMaker::FeatureGroup + +## Attribute Changes + +* AWS::MediaConnect::FlowVpcInterface FlowArn (__deleted__) +* AWS::MediaConnect::FlowVpcInterface Name (__deleted__) +* AWS::S3::AccessPoint NetworkOrigin (__added__) +* AWS::S3::AccessPoint PolicyStatus (__added__) + +## Property Changes + +* AWS::ACMPCA::Certificate ApiPassthrough (__added__) +* AWS::ACMPCA::Certificate ValidityNotBefore (__added__) +* AWS::AmazonMQ::Configuration AuthenticationStrategy (__added__) +* AWS::ApiGatewayV2::Stage AccessPolicyId (__added__) +* AWS::ECS::Cluster Configuration (__added__) +* AWS::Kinesis::Stream Tags.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::MediaConnect::FlowVpcInterface FlowArn (__added__) +* AWS::MediaConnect::FlowVpcInterface Name (__added__) +* AWS::S3::AccessPoint NetworkOrigin (__deleted__) +* AWS::S3::AccessPoint PolicyStatus (__deleted__) +* AWS::SSM::MaintenanceWindowTask MaxConcurrency.Required (__changed__) + * Old: true + * New: false +* AWS::SSM::MaintenanceWindowTask MaxErrors.Required (__changed__) + * Old: true + * New: false +* AWS::SSM::MaintenanceWindowTask Targets.Required (__changed__) + * Old: true + * New: false +* AWS::SSO::InstanceAccessControlAttributeConfiguration InstanceAccessControlAttributeConfiguration (__deleted__) +* AWS::SageMaker::Device Tags.ItemType (__changed__) + * Old: Json + * New: Tag +* AWS::SageMaker::Device Tags.Type (__changed__) + * Old: Tag + * New: List +* AWS::SageMaker::DeviceFleet Tags.ItemType (__changed__) + * Old: Json + * New: Tag +* AWS::SageMaker::DeviceFleet Tags.Type (__changed__) + * Old: Tag + * New: List +* AWS::SageMaker::Model InferenceExecutionConfig (__added__) + +## Property Type Changes + +* AWS::ACMPCA::Certificate.ApiPassthrough (__added__) +* AWS::ACMPCA::Certificate.CertificatePolicyList (__added__) +* AWS::ACMPCA::Certificate.EdiPartyName (__added__) +* AWS::ACMPCA::Certificate.ExtendedKeyUsage (__added__) +* AWS::ACMPCA::Certificate.ExtendedKeyUsageList (__added__) +* AWS::ACMPCA::Certificate.Extensions (__added__) +* AWS::ACMPCA::Certificate.GeneralName (__added__) +* AWS::ACMPCA::Certificate.GeneralNameList (__added__) +* AWS::ACMPCA::Certificate.KeyUsage (__added__) +* AWS::ACMPCA::Certificate.OtherName (__added__) +* AWS::ACMPCA::Certificate.PolicyInformation (__added__) +* AWS::ACMPCA::Certificate.PolicyQualifierInfo (__added__) +* AWS::ACMPCA::Certificate.PolicyQualifierInfoList (__added__) +* AWS::ACMPCA::Certificate.Qualifier (__added__) +* AWS::ACMPCA::Certificate.Subject (__added__) +* AWS::AppFlow::Flow.IdFieldNamesList (__added__) +* AWS::ECS::Cluster.ClusterConfiguration (__added__) +* AWS::ECS::Cluster.ExecuteCommandConfiguration (__added__) +* AWS::ECS::Cluster.ExecuteCommandLogConfiguration (__added__) +* AWS::SageMaker::Model.InferenceExecutionConfig (__added__) +* AWS::AppFlow::Flow.SalesforceDestinationProperties IdFieldNames (__added__) +* AWS::AppFlow::Flow.SalesforceDestinationProperties WriteOperationType (__added__) +* AWS::DLM::LifecyclePolicy.CreateRule Location (__added__) +* AWS::DLM::LifecyclePolicy.CrossRegionCopyRule Target (__added__) +* AWS::DLM::LifecyclePolicy.CrossRegionCopyRule TargetRegion.Required (__changed__) + * Old: true + * New: false +* AWS::DLM::LifecyclePolicy.PolicyDetails ResourceLocations (__added__) + + # CloudFormation Resource Specification v24.0.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index 51105aade994f..1e212a919f492 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -24.0.0 +26.0.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index 909704a8ddc33..9391cf7efc80d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -1,5 +1,396 @@ { "PropertyTypes": { + "AWS::ACMPCA::Certificate.ApiPassthrough": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-apipassthrough.html", + "Properties": { + "Extensions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-apipassthrough.html#cfn-acmpca-certificate-apipassthrough-extensions", + "Required": false, + "Type": "Extensions", + "UpdateType": "Immutable" + }, + "Subject": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-apipassthrough.html#cfn-acmpca-certificate-apipassthrough-subject", + "Required": false, + "Type": "Subject", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.CertificatePolicyList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-certificatepolicylist.html", + "Properties": { + "CertificatePolicyList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-certificatepolicylist.html#cfn-acmpca-certificate-certificatepolicylist-certificatepolicylist", + "ItemType": "PolicyInformation", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.EdiPartyName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-edipartyname.html", + "Properties": { + "NameAssigner": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-edipartyname.html#cfn-acmpca-certificate-edipartyname-nameassigner", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "PartyName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-edipartyname.html#cfn-acmpca-certificate-edipartyname-partyname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.ExtendedKeyUsage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extendedkeyusage.html", + "Properties": { + "ExtendedKeyUsageObjectIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extendedkeyusage.html#cfn-acmpca-certificate-extendedkeyusage-extendedkeyusageobjectidentifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "ExtendedKeyUsageType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extendedkeyusage.html#cfn-acmpca-certificate-extendedkeyusage-extendedkeyusagetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.ExtendedKeyUsageList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extendedkeyusagelist.html", + "Properties": { + "ExtendedKeyUsageList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extendedkeyusagelist.html#cfn-acmpca-certificate-extendedkeyusagelist-extendedkeyusagelist", + "ItemType": "ExtendedKeyUsage", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.Extensions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extensions.html", + "Properties": { + "CertificatePolicies": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extensions.html#cfn-acmpca-certificate-extensions-certificatepolicies", + "Required": false, + "Type": "CertificatePolicyList", + "UpdateType": "Immutable" + }, + "ExtendedKeyUsage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extensions.html#cfn-acmpca-certificate-extensions-extendedkeyusage", + "Required": false, + "Type": "ExtendedKeyUsageList", + "UpdateType": "Immutable" + }, + "KeyUsage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extensions.html#cfn-acmpca-certificate-extensions-keyusage", + "Required": false, + "Type": "KeyUsage", + "UpdateType": "Immutable" + }, + "SubjectAlternativeNames": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-extensions.html#cfn-acmpca-certificate-extensions-subjectalternativenames", + "Required": false, + "Type": "GeneralNameList", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.GeneralName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html", + "Properties": { + "DirectoryName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-directoryname", + "Required": false, + "Type": "Subject", + "UpdateType": "Immutable" + }, + "DnsName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-dnsname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "EdiPartyName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-edipartyname", + "Required": false, + "Type": "EdiPartyName", + "UpdateType": "Immutable" + }, + "IpAddress": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-ipaddress", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "OtherName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-othername", + "Required": false, + "Type": "OtherName", + "UpdateType": "Immutable" + }, + "RegisteredId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-registeredid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Rfc822Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-rfc822name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "UniformResourceIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalname.html#cfn-acmpca-certificate-generalname-uniformresourceidentifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.GeneralNameList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalnamelist.html", + "Properties": { + "GeneralNameList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-generalnamelist.html#cfn-acmpca-certificate-generalnamelist-generalnamelist", + "ItemType": "GeneralName", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.KeyUsage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html", + "Properties": { + "CRLSign": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-crlsign", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "DataEncipherment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-dataencipherment", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "DecipherOnly": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-decipheronly", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "DigitalSignature": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-digitalsignature", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "EncipherOnly": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-encipheronly", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "KeyAgreement": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-keyagreement", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "KeyCertSign": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-keycertsign", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "KeyEncipherment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-keyencipherment", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "NonRepudiation": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-keyusage.html#cfn-acmpca-certificate-keyusage-nonrepudiation", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.OtherName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-othername.html", + "Properties": { + "TypeId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-othername.html#cfn-acmpca-certificate-othername-typeid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Value": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-othername.html#cfn-acmpca-certificate-othername-value", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.PolicyInformation": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyinformation.html", + "Properties": { + "CertPolicyId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyinformation.html#cfn-acmpca-certificate-policyinformation-certpolicyid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "PolicyQualifiers": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyinformation.html#cfn-acmpca-certificate-policyinformation-policyqualifiers", + "Required": false, + "Type": "PolicyQualifierInfoList", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.PolicyQualifierInfo": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyqualifierinfo.html", + "Properties": { + "PolicyQualifierId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyqualifierinfo.html#cfn-acmpca-certificate-policyqualifierinfo-policyqualifierid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Qualifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyqualifierinfo.html#cfn-acmpca-certificate-policyqualifierinfo-qualifier", + "Required": true, + "Type": "Qualifier", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.PolicyQualifierInfoList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyqualifierinfolist.html", + "Properties": { + "PolicyQualifierInfoList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-policyqualifierinfolist.html#cfn-acmpca-certificate-policyqualifierinfolist-policyqualifierinfolist", + "ItemType": "PolicyQualifierInfo", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.Qualifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-qualifier.html", + "Properties": { + "CpsUri": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-qualifier.html#cfn-acmpca-certificate-qualifier-cpsuri", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, + "AWS::ACMPCA::Certificate.Subject": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html", + "Properties": { + "CommonName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-commonname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Country": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-country", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "DistinguishedNameQualifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-distinguishednamequalifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "GenerationQualifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-generationqualifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "GivenName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-givenname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Initials": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-initials", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Locality": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-locality", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Organization": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-organization", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "OrganizationalUnit": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-organizationalunit", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Pseudonym": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-pseudonym", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "SerialNumber": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-serialnumber", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "State": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-state", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Surname": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-surname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Title": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-subject.html#cfn-acmpca-certificate-subject-title", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::ACMPCA::Certificate.Validity": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-validity.html", "Properties": { @@ -3033,6 +3424,18 @@ } } }, + "AWS::AppFlow::Flow.IdFieldNamesList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-idfieldnameslist.html", + "Properties": { + "IdFieldNamesList": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-idfieldnameslist.html#cfn-appflow-flow-idfieldnameslist-idfieldnameslist", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::AppFlow::Flow.IncrementalPullConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-incrementalpullconfig.html", "Properties": { @@ -3184,11 +3587,23 @@ "Type": "ErrorHandlingConfig", "UpdateType": "Mutable" }, + "IdFieldNames": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-salesforcedestinationproperties.html#cfn-appflow-flow-salesforcedestinationproperties-idfieldnames", + "Required": false, + "Type": "IdFieldNamesList", + "UpdateType": "Mutable" + }, "Object": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-salesforcedestinationproperties.html#cfn-appflow-flow-salesforcedestinationproperties-object", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" + }, + "WriteOperationType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-salesforcedestinationproperties.html#cfn-appflow-flow-salesforcedestinationproperties-writeoperationtype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" } } }, @@ -12981,6 +13396,12 @@ "Required": false, "UpdateType": "Mutable" }, + "Location": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-createrule.html#cfn-dlm-lifecyclepolicy-createrule-location", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "Times": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-createrule.html#cfn-dlm-lifecyclepolicy-createrule-times", "PrimitiveItemType": "String", @@ -13057,10 +13478,16 @@ "Type": "CrossRegionCopyRetainRule", "UpdateType": "Mutable" }, + "Target": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopyrule.html#cfn-dlm-lifecyclepolicy-crossregioncopyrule-target", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "TargetRegion": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopyrule.html#cfn-dlm-lifecyclepolicy-crossregioncopyrule-targetregion", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Mutable" } } @@ -13198,6 +13625,13 @@ "Required": false, "UpdateType": "Mutable" }, + "ResourceLocations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-policydetails.html#cfn-dlm-lifecyclepolicy-policydetails-resourcelocations", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "ResourceTypes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-policydetails.html#cfn-dlm-lifecyclepolicy-policydetails-resourcetypes", "PrimitiveItemType": "String", @@ -18020,6 +18454,17 @@ } } }, + "AWS::ECS::Cluster.ClusterConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-clusterconfiguration.html", + "Properties": { + "ExecuteCommandConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-clusterconfiguration.html#cfn-ecs-cluster-clusterconfiguration-executecommandconfiguration", + "Required": false, + "Type": "ExecuteCommandConfiguration", + "UpdateType": "Mutable" + } + } + }, "AWS::ECS::Cluster.ClusterSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-clustersettings.html", "Properties": { @@ -18037,6 +18482,64 @@ } } }, + "AWS::ECS::Cluster.ExecuteCommandConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandconfiguration.html", + "Properties": { + "KmsKeyId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandconfiguration.html#cfn-ecs-cluster-executecommandconfiguration-kmskeyid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "LogConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandconfiguration.html#cfn-ecs-cluster-executecommandconfiguration-logconfiguration", + "Required": false, + "Type": "ExecuteCommandLogConfiguration", + "UpdateType": "Mutable" + }, + "Logging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandconfiguration.html#cfn-ecs-cluster-executecommandconfiguration-logging", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::ECS::Cluster.ExecuteCommandLogConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandlogconfiguration.html", + "Properties": { + "CloudWatchEncryptionEnabled": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandlogconfiguration.html#cfn-ecs-cluster-executecommandlogconfiguration-cloudwatchencryptionenabled", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "CloudWatchLogGroupName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandlogconfiguration.html#cfn-ecs-cluster-executecommandlogconfiguration-cloudwatchloggroupname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "S3BucketName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandlogconfiguration.html#cfn-ecs-cluster-executecommandlogconfiguration-s3bucketname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "S3EncryptionEnabled": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandlogconfiguration.html#cfn-ecs-cluster-executecommandlogconfiguration-s3encryptionenabled", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "S3KeyPrefix": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-executecommandlogconfiguration.html#cfn-ecs-cluster-executecommandlogconfiguration-s3keyprefix", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::ECS::Service.AwsVpcConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-service-awsvpcconfiguration.html", "Properties": { @@ -47726,6 +48229,23 @@ } } }, + "AWS::SageMaker::FeatureGroup.FeatureDefinition": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-featuregroup-featuredefinition.html", + "Properties": { + "FeatureName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-featuregroup-featuredefinition.html#cfn-sagemaker-featuregroup-featuredefinition-featurename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "FeatureType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-featuregroup-featuredefinition.html#cfn-sagemaker-featuregroup-featuredefinition-featuretype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::SageMaker::Model.ContainerDefinition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-model-containerdefinition.html", "Properties": { @@ -47790,6 +48310,17 @@ } } }, + "AWS::SageMaker::Model.InferenceExecutionConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-model-inferenceexecutionconfig.html", + "Properties": { + "Mode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-model-inferenceexecutionconfig.html#cfn-sagemaker-model-inferenceexecutionconfig-mode", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::SageMaker::Model.MultiModelConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-model-containerdefinition-multimodelconfig.html", "Properties": { @@ -51929,7 +52460,7 @@ } } }, - "ResourceSpecificationVersion": "24.0.0", + "ResourceSpecificationVersion": "26.0.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -51942,6 +52473,12 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-acmpca-certificate.html", "Properties": { + "ApiPassthrough": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-acmpca-certificate.html#cfn-acmpca-certificate-apipassthrough", + "Required": false, + "Type": "ApiPassthrough", + "UpdateType": "Immutable" + }, "CertificateAuthorityArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-acmpca-certificate.html#cfn-acmpca-certificate-certificateauthorityarn", "PrimitiveType": "String", @@ -51971,6 +52508,12 @@ "Required": true, "Type": "Validity", "UpdateType": "Immutable" + }, + "ValidityNotBefore": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-acmpca-certificate.html#cfn-acmpca-certificate-validitynotbefore", + "Required": false, + "Type": "Validity", + "UpdateType": "Immutable" } } }, @@ -52267,6 +52810,12 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amazonmq-configuration.html", "Properties": { + "AuthenticationStrategy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amazonmq-configuration.html#cfn-amazonmq-configuration-authenticationstrategy", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "Data": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amazonmq-configuration.html#cfn-amazonmq-configuration-data", "PrimitiveType": "String", @@ -54041,6 +54590,12 @@ "Type": "AccessLogSettings", "UpdateType": "Mutable" }, + "AccessPolicyId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-stage.html#cfn-apigatewayv2-stage-accesspolicyid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "ApiId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-stage.html#cfn-apigatewayv2-stage-apiid", "PrimitiveType": "String", @@ -64723,6 +65278,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "Configuration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-configuration", + "Required": false, + "Type": "ClusterConfiguration", + "UpdateType": "Mutable" + }, "DefaultCapacityProviderStrategy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-defaultcapacityproviderstrategy", "ItemType": "CapacityProviderStrategyItem", @@ -72208,7 +72769,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-kinesis-stream.html#cfn-kinesis-stream-tags", - "DuplicatesAllowed": false, + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -73334,6 +73895,22 @@ } } }, + "AWS::LookoutVision::Project": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lookoutvision-project.html", + "Properties": { + "ProjectName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lookoutvision-project.html#cfn-lookoutvision-project-projectname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::MSK::Cluster": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-cluster.html", "Properties": { @@ -74013,12 +74590,6 @@ }, "AWS::MediaConnect::FlowVpcInterface": { "Attributes": { - "FlowArn": { - "PrimitiveType": "String" - }, - "Name": { - "PrimitiveType": "String" - }, "NetworkInterfaceIds": { "PrimitiveItemType": "String", "Type": "List" @@ -74026,6 +74597,18 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mediaconnect-flowvpcinterface.html", "Properties": { + "FlowArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mediaconnect-flowvpcinterface.html#cfn-mediaconnect-flowvpcinterface-flowarn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mediaconnect-flowvpcinterface.html#cfn-mediaconnect-flowvpcinterface-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mediaconnect-flowvpcinterface.html#cfn-mediaconnect-flowvpcinterface-rolearn", "PrimitiveType": "String", @@ -79615,6 +80198,14 @@ } }, "AWS::S3::AccessPoint": { + "Attributes": { + "NetworkOrigin": { + "PrimitiveType": "String" + }, + "PolicyStatus": { + "PrimitiveType": "Json" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-accesspoint.html", "Properties": { "Bucket": { @@ -79629,24 +80220,12 @@ "Required": false, "UpdateType": "Mutable" }, - "NetworkOrigin": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-accesspoint.html#cfn-s3-accesspoint-networkorigin", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, "Policy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-accesspoint.html#cfn-s3-accesspoint-policy", "PrimitiveType": "Json", "Required": false, "UpdateType": "Mutable" }, - "PolicyStatus": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-accesspoint.html#cfn-s3-accesspoint-policystatus", - "PrimitiveType": "Json", - "Required": false, - "UpdateType": "Mutable" - }, "PublicAccessBlockConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-accesspoint.html#cfn-s3-accesspoint-publicaccessblockconfiguration", "Required": false, @@ -80454,13 +81033,13 @@ "MaxConcurrency": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-maintenancewindowtask.html#cfn-ssm-maintenancewindowtask-maxconcurrency", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Mutable" }, "MaxErrors": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-maintenancewindowtask.html#cfn-ssm-maintenancewindowtask-maxerrors", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Mutable" }, "Name": { @@ -80484,7 +81063,7 @@ "Targets": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-maintenancewindowtask.html#cfn-ssm-maintenancewindowtask-targets", "ItemType": "Target", - "Required": true, + "Required": false, "Type": "List", "UpdateType": "Mutable" }, @@ -80785,12 +81364,6 @@ "Type": "List", "UpdateType": "Mutable" }, - "InstanceAccessControlAttributeConfiguration": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sso-instanceaccesscontrolattributeconfiguration.html#cfn-sso-instanceaccesscontrolattributeconfiguration-instanceaccesscontrolattributeconfiguration", - "PrimitiveType": "Json", - "Required": false, - "UpdateType": "Mutable" - }, "InstanceArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sso-instanceaccesscontrolattributeconfiguration.html#cfn-sso-instanceaccesscontrolattributeconfiguration-instancearn", "PrimitiveType": "String", @@ -80973,9 +81546,9 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-device.html#cfn-sagemaker-device-tags", - "ItemType": "Json", + "ItemType": "Tag", "Required": false, - "Type": "Tag", + "Type": "List", "UpdateType": "Mutable" } } @@ -81009,9 +81582,9 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-devicefleet.html#cfn-sagemaker-devicefleet-tags", - "ItemType": "Json", + "ItemType": "Tag", "Required": false, - "Type": "Tag", + "Type": "List", "UpdateType": "Mutable" } } @@ -81106,6 +81679,69 @@ } } }, + "AWS::SageMaker::FeatureGroup": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "EventTimeFeatureName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-eventtimefeaturename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "FeatureDefinitions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-featuredefinitions", + "DuplicatesAllowed": true, + "ItemType": "FeatureDefinition", + "Required": true, + "Type": "List", + "UpdateType": "Immutable" + }, + "FeatureGroupName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-featuregroupname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "OfflineStoreConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-offlinestoreconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, + "OnlineStoreConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-onlinestoreconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, + "RecordIdentifierFeatureName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-recordidentifierfeaturename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "RoleArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-rolearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-featuregroup.html#cfn-sagemaker-featuregroup-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, "AWS::SageMaker::Model": { "Attributes": { "ModelName": { @@ -81133,6 +81769,12 @@ "Required": true, "UpdateType": "Immutable" }, + "InferenceExecutionConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-model.html#cfn-sagemaker-model-inferenceexecutionconfig", + "Required": false, + "Type": "InferenceExecutionConfig", + "UpdateType": "Immutable" + }, "ModelName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-model.html#cfn-sagemaker-model-modelname", "PrimitiveType": "String", diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json index 6a3dd4c17346d..1732065bd3a96 100644 --- a/packages/@aws-cdk/cloudformation-include/package.json +++ b/packages/@aws-cdk/cloudformation-include/package.json @@ -159,6 +159,7 @@ "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-licensemanager": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", + "@aws-cdk/aws-lookoutvision": "0.0.0", "@aws-cdk/aws-macie": "0.0.0", "@aws-cdk/aws-managedblockchain": "0.0.0", "@aws-cdk/aws-mediaconnect": "0.0.0", @@ -306,6 +307,7 @@ "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-licensemanager": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", + "@aws-cdk/aws-lookoutvision": "0.0.0", "@aws-cdk/aws-macie": "0.0.0", "@aws-cdk/aws-managedblockchain": "0.0.0", "@aws-cdk/aws-mediaconnect": "0.0.0", diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 7c938b86bd7e0..10849cc784a4a 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -213,6 +213,7 @@ "@aws-cdk/aws-licensemanager": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-logs-destinations": "0.0.0", + "@aws-cdk/aws-lookoutvision": "0.0.0", "@aws-cdk/aws-macie": "0.0.0", "@aws-cdk/aws-managedblockchain": "0.0.0", "@aws-cdk/aws-mediaconnect": "0.0.0", diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 7f8ace298e383..a5c184e65f1d5 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -139,6 +139,7 @@ "@aws-cdk/aws-licensemanager": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-logs-destinations": "0.0.0", + "@aws-cdk/aws-lookoutvision": "0.0.0", "@aws-cdk/aws-macie": "0.0.0", "@aws-cdk/aws-managedblockchain": "0.0.0", "@aws-cdk/aws-mediaconnect": "0.0.0", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index dddf5eb0b77fd..a02fee1b78939 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -218,6 +218,7 @@ "@aws-cdk/aws-licensemanager": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-logs-destinations": "0.0.0", + "@aws-cdk/aws-lookoutvision": "0.0.0", "@aws-cdk/aws-macie": "0.0.0", "@aws-cdk/aws-managedblockchain": "0.0.0", "@aws-cdk/aws-mediaconnect": "0.0.0", From 77b9d3930ec722be3a40e4013cd9335f90b0d945 Mon Sep 17 00:00:00 2001 From: Alex Kokachev Date: Fri, 5 Feb 2021 04:31:38 +1100 Subject: [PATCH 17/21] fix(core): append file extension to s3 asset key in new style synthesizer (#12765) - This change fixes the issue with new style synthesizer, when s3 files assets are uploaded without file extension. This was breaking integration with some services, in particular Glue, which requires jar files to have "jar" extension in order to compile. - Legacy synthesizer was creating s3 key with extension, so this change effectively aligns old and new synthesizers. fixes #12740 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../core/lib/stack-synthesizers/default-synthesizer.ts | 3 ++- .../core/test/stack-synthesis/new-style-synthesis.test.ts | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts index b4f9f29cf732a..a92d3b6fe04d0 100644 --- a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts +++ b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts @@ -291,7 +291,8 @@ export class DefaultStackSynthesizer extends StackSynthesizer { assertBound(this.bucketName); validateFileAssetSource(asset); - const objectKey = this.bucketPrefix + asset.sourceHash + (asset.packaging === FileAssetPackaging.ZIP_DIRECTORY ? '.zip' : ''); + const extension = asset.fileName != undefined ? path.extname(asset.fileName) : ''; + const objectKey = this.bucketPrefix + asset.sourceHash + (asset.packaging === FileAssetPackaging.ZIP_DIRECTORY ? '.zip' : extension); // Add to manifest this.files[asset.sourceHash] = { diff --git a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts index 0131b7a4acc63..6780f07fbd879 100644 --- a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts +++ b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts @@ -52,7 +52,7 @@ nodeunitShim({ destinations: { 'current_account-current_region': { bucketName: 'cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}', - objectKey: templateHash, + objectKey: templateHash + '.json', assumeRoleArn: 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}', }, }, @@ -111,7 +111,7 @@ nodeunitShim({ // THEN - we have a fixed asset location with region placeholders test.equals(evalCFN(location.bucketName), 'cdk-hnb659fds-assets-the_account-the_region'); - test.equals(evalCFN(location.s3Url), 'https://s3.the_region.domain.aws/cdk-hnb659fds-assets-the_account-the_region/abcdef'); + test.equals(evalCFN(location.s3Url), 'https://s3.the_region.domain.aws/cdk-hnb659fds-assets-the_account-the_region/abcdef.js'); // THEN - object key contains source hash somewhere test.ok(location.objectKey.indexOf('abcdef') > -1); @@ -208,7 +208,7 @@ nodeunitShim({ test.deepEqual(manifest.files?.['file-asset-hash']?.destinations?.['current_account-current_region'], { bucketName: 'file-asset-bucket', - objectKey: 'file-asset-hash', + objectKey: 'file-asset-hash.js', assumeRoleArn: 'file:role:arn', assumeRoleExternalId: 'file-external-id', }); @@ -256,7 +256,7 @@ nodeunitShim({ // THEN test.deepEqual(manifest.files?.['file-asset-hash-with-prefix']?.destinations?.['current_account-current_region'], { bucketName: 'file-asset-bucket', - objectKey: '000000000000/file-asset-hash-with-prefix', + objectKey: '000000000000/file-asset-hash-with-prefix.js', assumeRoleArn: 'file:role:arn', assumeRoleExternalId: 'file-external-id', }); From 12c224a0f54230b6226de8defa527f7b53f9bc65 Mon Sep 17 00:00:00 2001 From: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Date: Thu, 4 Feb 2021 10:49:22 -0800 Subject: [PATCH 18/21] feat(lambda): nodejs14.x runtime (#12861) Blog post: [Node.js 14.x runtime now available in AWS Lambda](https://aws.amazon.com/blogs/compute/node-js-14-x-runtime-now-available-in-aws-lambda/) Developer Guide: [Node.js lambda runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda/lib/runtime.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/@aws-cdk/aws-lambda/lib/runtime.ts b/packages/@aws-cdk/aws-lambda/lib/runtime.ts index 05d4996ff5e4f..3bbd8bcc43f6e 100644 --- a/packages/@aws-cdk/aws-lambda/lib/runtime.ts +++ b/packages/@aws-cdk/aws-lambda/lib/runtime.ts @@ -78,6 +78,11 @@ export class Runtime { */ public static readonly NODEJS_12_X = new Runtime('nodejs12.x', RuntimeFamily.NODEJS, { supportsInlineCode: true }); + /** + * The NodeJS 14.x runtime (nodejs14.x) + */ + public static readonly NODEJS_14_X = new Runtime('nodejs14.x', RuntimeFamily.NODEJS, { supportsInlineCode: false }); + /** * The Python 2.7 runtime (python2.7) */ From 349a6e2bfaa72440deb3767fb1e28e38cc4d73ef Mon Sep 17 00:00:00 2001 From: Robert Djurasaj Date: Thu, 4 Feb 2021 12:26:43 -0700 Subject: [PATCH 19/21] feat(cloudfront): add support for TrustedKeyGroups in Distribution and CloudFrontWebDistribution (#12847) @njlynch Closes #11791 https://media3.giphy.com/media/3o7aCWJavAgtBzLWrS/giphy.gif ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-cloudfront/README.md | 76 +++++++++++++++++-- .../aws-cloudfront/lib/distribution.ts | 9 +++ .../lib/private/cache-behavior.ts | 13 ++-- .../aws-cloudfront/lib/web-distribution.ts | 11 +++ ...integ.distribution-key-group.expected.json | 57 ++++++++++++++ .../test/integ.distribution-key-group.ts | 32 ++++++++ .../test/private/cache-behavior.test.ts | 24 +++++- .../test/web-distribution.test.ts | 53 ++++++++++++- 8 files changed, 259 insertions(+), 16 deletions(-) create mode 100644 packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.expected.json create mode 100644 packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.ts diff --git a/packages/@aws-cdk/aws-cloudfront/README.md b/packages/@aws-cdk/aws-cloudfront/README.md index 1355d7a64d31d..3a5834d98d51f 100644 --- a/packages/@aws-cdk/aws-cloudfront/README.md +++ b/packages/@aws-cdk/aws-cloudfront/README.md @@ -239,6 +239,34 @@ new cloudfront.Distribution(this, 'myDistCustomPolicy', { }); ``` +### Validating signed URLs or signed cookies with Trusted Key Groups + +CloudFront Distribution now supports validating signed URLs or signed cookies using key groups. When a cache behavior contains trusted key groups, CloudFront requires signed URLs or signed cookies for all requests that match the cache behavior. + +Example: + +```ts +// public key in PEM format +const pubKey = new PublicKey(stack, 'MyPubKey', { + encodedKey: publicKey, +}); + +const keyGroup = new KeyGroup(stack, 'MyKeyGroup', { + items: [ + pubKey, + ], +}); + +new cloudfront.Distribution(stack, 'Dist', { + defaultBehavior: { + origin: new origins.HttpOrigin('www.example.com'), + trustedKeyGroups: [ + keyGroup, + ], + }, +}); +``` + ### Lambda@Edge Lambda@Edge is an extension of AWS Lambda, a compute service that lets you execute functions that customize the content that CloudFront delivers. @@ -274,7 +302,7 @@ new cloudfront.Distribution(this, 'myDist', { > **Note:** Lambda@Edge functions must be created in the `us-east-1` region, regardless of the region of the CloudFront distribution and stack. > To make it easier to request functions for Lambda@Edge, the `EdgeFunction` construct can be used. > The `EdgeFunction` construct will automatically request a function in `us-east-1`, regardless of the region of the current stack. -> `EdgeFunction` has the same interface as `Function` and can be created and used interchangably. +> `EdgeFunction` has the same interface as `Function` and can be created and used interchangeably. > Please note that using `EdgeFunction` requires that the `us-east-1` region has been bootstrapped. > See https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html for more about bootstrapping regions. @@ -289,7 +317,7 @@ const myFunc = new lambda.Function(this, 'MyFunction', { ``` If the stack is not in `us-east-1`, and you need references from different applications on the same account, -you can also set a specific stack ID for each Lamba@Edge. +you can also set a specific stack ID for each Lambda@Edge. ```ts const myFunc1 = new cloudfront.experimental.EdgeFunction(this, 'MyFunction1', { @@ -427,7 +455,7 @@ You can customize the default certificate aliases. This is intended to be used i Example: -[create a distrubution with an default certificiate example](test/example.default-cert-alias.lit.ts) +[create a distribution with an default certificate example](test/example.default-cert-alias.lit.ts) #### ACM certificate @@ -438,7 +466,7 @@ For more information, see [the aws-certificatemanager module documentation](http Example: -[create a distrubution with an acm certificate example](test/example.acm-cert-alias.lit.ts) +[create a distribution with an acm certificate example](test/example.acm-cert-alias.lit.ts) #### IAM certificate @@ -448,7 +476,43 @@ See [Importing an SSL/TLS Certificate](https://docs.aws.amazon.com/AmazonCloudFr Example: -[create a distrubution with an iam certificate example](test/example.iam-cert-alias.lit.ts) +[create a distribution with an iam certificate example](test/example.iam-cert-alias.lit.ts) + +### Trusted Key Groups + +CloudFront Web Distributions supports validating signed URLs or signed cookies using key groups. When a cache behavior contains trusted key groups, CloudFront requires signed URLs or signed cookies for all requests that match the cache behavior. + +Example: + +```ts +const pubKey = new PublicKey(stack, 'MyPubKey', { + encodedKey: publicKey, +}); + +const keyGroup = new KeyGroup(stack, 'MyKeyGroup', { + items: [ + pubKey, + ], +}); + +new CloudFrontWebDistribution(stack, 'AnAmazingWebsiteProbably', { + originConfigs: [ + { + s3OriginSource: { + s3BucketSource: sourceBucket, + }, + behaviors: [ + { + isDefaultBehavior: true, + trustedKeyGroups: [ + keyGroup, + ], + }, + ], + }, + ], +}); +``` ### Restrictions @@ -505,7 +569,7 @@ new CloudFrontWebDistribution(stack, 'ADistribution', { }, failoverS3OriginSource: { s3BucketSource: s3.Bucket.fromBucketName(stack, 'aBucketFallback', 'myoriginbucketfallback'), - originPath: '/somwhere', + originPath: '/somewhere', originHeaders: { 'myHeader2': '21', }, diff --git a/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts b/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts index 05534862026ae..02e3d092295f3 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts @@ -6,6 +6,7 @@ import { Construct } from 'constructs'; import { ICachePolicy } from './cache-policy'; import { CfnDistribution } from './cloudfront.generated'; import { GeoRestriction } from './geo-restriction'; +import { IKeyGroup } from './key-group'; import { IOrigin, OriginBindConfig, OriginBindOptions } from './origin'; import { IOriginRequestPolicy } from './origin-request-policy'; import { CacheBehavior } from './private/cache-behavior'; @@ -706,6 +707,14 @@ export interface AddBehaviorOptions { * @see https://aws.amazon.com/lambda/edge */ readonly edgeLambdas?: EdgeLambda[]; + + /** + * A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies. + * + * @default - no KeyGroups are associated with cache behavior + * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html + */ + readonly trustedKeyGroups?: IKeyGroup[]; } /** diff --git a/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts b/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts index 4b700e166cecc..d804dd8465750 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts @@ -50,13 +50,12 @@ export class CacheBehavior { originRequestPolicyId: this.props.originRequestPolicy?.originRequestPolicyId, smoothStreaming: this.props.smoothStreaming, viewerProtocolPolicy: this.props.viewerProtocolPolicy ?? ViewerProtocolPolicy.ALLOW_ALL, - lambdaFunctionAssociations: this.props.edgeLambdas - ? this.props.edgeLambdas.map(edgeLambda => ({ - lambdaFunctionArn: edgeLambda.functionVersion.edgeArn, - eventType: edgeLambda.eventType.toString(), - includeBody: edgeLambda.includeBody, - })) - : undefined, + lambdaFunctionAssociations: this.props.edgeLambdas?.map(edgeLambda => ({ + lambdaFunctionArn: edgeLambda.functionVersion.edgeArn, + eventType: edgeLambda.eventType.toString(), + includeBody: edgeLambda.includeBody, + })), + trustedKeyGroups: this.props.trustedKeyGroups?.map(keyGroup => keyGroup.keyGroupId), }; } diff --git a/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts b/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts index c62e1e09ed3f4..ae3cbae6051d3 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts @@ -7,6 +7,7 @@ import { Construct } from 'constructs'; import { CfnDistribution } from './cloudfront.generated'; import { HttpVersion, IDistribution, LambdaEdgeEventType, OriginProtocolPolicy, PriceClass, ViewerProtocolPolicy, SSLMethod, SecurityPolicyProtocol } from './distribution'; import { GeoRestriction } from './geo-restriction'; +import { IKeyGroup } from './key-group'; import { IOriginAccessIdentity } from './origin-access-identity'; /** @@ -347,9 +348,18 @@ export interface Behavior { * The signers are the account IDs that are allowed to sign cookies/presigned URLs for this distribution. * * If you pass a non empty value, all requests for this behavior must be signed (no public access will be allowed) + * @deprecated - We recommend using trustedKeyGroups instead of trustedSigners. */ readonly trustedSigners?: string[]; + /** + * A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies. + * + * @default - no KeyGroups are associated with cache behavior + * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html + */ + readonly trustedKeyGroups?: IKeyGroup[]; + /** * * The default amount of time CloudFront will cache an object. @@ -932,6 +942,7 @@ export class CloudFrontWebDistribution extends cdk.Resource implements IDistribu forwardedValues: input.forwardedValues || { queryString: false, cookies: { forward: 'none' } }, maxTtl: input.maxTtl && input.maxTtl.toSeconds(), minTtl: input.minTtl && input.minTtl.toSeconds(), + trustedKeyGroups: input.trustedKeyGroups?.map(key => key.keyGroupId), trustedSigners: input.trustedSigners, targetOriginId: input.targetOriginId, viewerProtocolPolicy: protoPolicy || ViewerProtocolPolicy.REDIRECT_TO_HTTPS, diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.expected.json b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.expected.json new file mode 100644 index 0000000000000..afae558dee709 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.expected.json @@ -0,0 +1,57 @@ +{ + "Resources": { + "MyPublicKey78071F3D": { + "Type": "AWS::CloudFront::PublicKey", + "Properties": { + "PublicKeyConfig": { + "CallerReference": "c8752fac3fe06fc93f3fbd12d7e0282d8967409e4d", + "EncodedKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS\nJAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa\ndlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj\n6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e\n0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD\n/3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx\nNQIDAQAB\n-----END PUBLIC KEY-----", + "Name": "integdistributionkeygroupMyPublicKeyC0F3B115" + } + } + }, + "MyKeyGroupAF22FD35": { + "Type": "AWS::CloudFront::KeyGroup", + "Properties": { + "KeyGroupConfig": { + "Items": [ + { + "Ref": "MyPublicKey78071F3D" + } + ], + "Name": "integdistributionkeygroupMyKeyGroupF179E01A" + } + } + }, + "DistB3B78991": { + "Type": "AWS::CloudFront::Distribution", + "Properties": { + "DistributionConfig": { + "DefaultCacheBehavior": { + "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "Compress": true, + "TargetOriginId": "integdistributionkeygroupDistOrigin1B9677703", + "TrustedKeyGroups": [ + { + "Ref": "MyKeyGroupAF22FD35" + } + ], + "ViewerProtocolPolicy": "allow-all" + }, + "Enabled": true, + "HttpVersion": "http2", + "IPV6Enabled": true, + "Origins": [ + { + "CustomOriginConfig": { + "OriginProtocolPolicy": "https-only" + }, + "DomainName": "www.example.com", + "Id": "integdistributionkeygroupDistOrigin1B9677703" + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.ts new file mode 100644 index 0000000000000..e0a124b26f904 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-key-group.ts @@ -0,0 +1,32 @@ +import * as cdk from '@aws-cdk/core'; +import * as cloudfront from '../lib'; +import { TestOrigin } from './test-origin'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'integ-distribution-key-group'); +const publicKey = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS +JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa +dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj +6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e +0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD +/3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx +NQIDAQAB +-----END PUBLIC KEY-----`; + +new cloudfront.Distribution(stack, 'Dist', { + defaultBehavior: { + origin: new TestOrigin('www.example.com'), + trustedKeyGroups: [ + new cloudfront.KeyGroup(stack, 'MyKeyGroup', { + items: [ + new cloudfront.PublicKey(stack, 'MyPublicKey', { + encodedKey: publicKey, + }), + ], + }), + ], + }, +}); + +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts b/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts index a1e315fdcdd96..c9500b23eaddf 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts @@ -1,11 +1,20 @@ import '@aws-cdk/assert/jest'; import * as lambda from '@aws-cdk/aws-lambda'; import { App, Stack } from '@aws-cdk/core'; -import { AllowedMethods, CachedMethods, CachePolicy, LambdaEdgeEventType, OriginRequestPolicy, ViewerProtocolPolicy } from '../../lib'; +import { AllowedMethods, CachedMethods, CachePolicy, KeyGroup, LambdaEdgeEventType, OriginRequestPolicy, PublicKey, ViewerProtocolPolicy } from '../../lib'; import { CacheBehavior } from '../../lib/private/cache-behavior'; let app: App; let stack: Stack; +const publicKey = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS +JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa +dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj +6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e +0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD +/3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx +NQIDAQAB +-----END PUBLIC KEY-----`; beforeEach(() => { app = new App(); @@ -30,6 +39,15 @@ test('renders the minimum template with an origin and path specified', () => { test('renders with all properties specified', () => { const fnVersion = lambda.Version.fromVersionArn(stack, 'Version', 'arn:aws:lambda:testregion:111111111111:function:myTestFun:v1'); + const pubKey = new PublicKey(stack, 'MyPublicKey', { + encodedKey: publicKey, + }); + const keyGroup = new KeyGroup(stack, 'MyKeyGroup', { + items: [ + pubKey, + ], + }); + const behavior = new CacheBehavior('origin_id', { pathPattern: '*', allowedMethods: AllowedMethods.ALLOW_ALL, @@ -44,6 +62,7 @@ test('renders with all properties specified', () => { includeBody: true, functionVersion: fnVersion, }], + trustedKeyGroups: [keyGroup], }); expect(behavior._renderBehavior()).toEqual({ @@ -61,6 +80,9 @@ test('renders with all properties specified', () => { eventType: 'origin-request', includeBody: true, }], + trustedKeyGroups: [ + keyGroup.keyGroupId, + ], }); }); diff --git a/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts b/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts index ea2fbf3f22295..8eea2cad5bc92 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts @@ -8,7 +8,9 @@ import { CfnDistribution, CloudFrontWebDistribution, GeoRestriction, + KeyGroup, LambdaEdgeEventType, + PublicKey, SecurityPolicyProtocol, SSLMethod, ViewerCertificate, @@ -17,6 +19,16 @@ import { /* eslint-disable quote-props */ +const publicKey = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudf8/iNkQgdvjEdm6xYS +JAyxd/kGTbJfQNg9YhInb7TSm0dGu0yx8yZ3fnpmxuRPqJIlaVr+fT4YRl71gEYa +dlhHmnVegyPNjP9dNqZ7zwNqMEPOPnS/NOHbJj1KYKpn1f8pPNycQ5MQCntKGnSj +6fc+nbcC0joDvGz80xuy1W4hLV9oC9c3GT26xfZb2jy9MVtA3cppNuTwqrFi3t6e +0iGpraxZlT5wewjZLpQkngqYr6s3aucPAZVsGTEYPo4nD5mswmtZOm+tgcOrivtD +/3sD/qZLQ6c5siqyS8aTraD6y+VXugujfarTU65IeZ6QAUbLMsWuZOIi5Jn8zAwx +NQIDAQAB +-----END PUBLIC KEY-----`; + nodeunitShim({ 'distribution with custom origin adds custom origin'(test: Test) { @@ -188,6 +200,14 @@ nodeunitShim({ 'distribution with trusted signers on default distribution'(test: Test) { const stack = new cdk.Stack(); const sourceBucket = new s3.Bucket(stack, 'Bucket'); + const pubKey = new PublicKey(stack, 'MyPubKey', { + encodedKey: publicKey, + }); + const keyGroup = new KeyGroup(stack, 'MyKeyGroup', { + items: [ + pubKey, + ], + }); new CloudFrontWebDistribution(stack, 'AnAmazingWebsiteProbably', { originConfigs: [ @@ -199,6 +219,9 @@ nodeunitShim({ { isDefaultBehavior: true, trustedSigners: ['1234'], + trustedKeyGroups: [ + keyGroup, + ], }, ], }, @@ -212,6 +235,29 @@ nodeunitShim({ 'DeletionPolicy': 'Retain', 'UpdateReplacePolicy': 'Retain', }, + 'MyPubKey6ADA4CF5': { + 'Type': 'AWS::CloudFront::PublicKey', + 'Properties': { + 'PublicKeyConfig': { + 'CallerReference': 'c8141e732ea37b19375d4cbef2b2d2c6f613f0649a', + 'EncodedKey': publicKey, + 'Name': 'MyPubKey', + }, + }, + }, + 'MyKeyGroupAF22FD35': { + 'Type': 'AWS::CloudFront::KeyGroup', + 'Properties': { + 'KeyGroupConfig': { + 'Items': [ + { + 'Ref': 'MyPubKey6ADA4CF5', + }, + ], + 'Name': 'MyKeyGroup', + }, + }, + }, 'AnAmazingWebsiteProbablyCFDistribution47E3983B': { 'Type': 'AWS::CloudFront::Distribution', 'Properties': { @@ -250,9 +296,12 @@ nodeunitShim({ 'QueryString': false, 'Cookies': { 'Forward': 'none' }, }, - 'TrustedSigners': [ - '1234', + 'TrustedKeyGroups': [ + { + 'Ref': 'MyKeyGroupAF22FD35', + }, ], + 'TrustedSigners': ['1234'], 'Compress': true, }, 'Enabled': true, From 22eb7e1816fa457cbbba5474aff08974f2793e2d Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Thu, 4 Feb 2021 21:21:55 +0000 Subject: [PATCH 20/21] chore(eslint-plugin-cdk): clean up around tests (#12867) Couple of minor changes: - remove the exclusion for running the 'construct-import-order' rule for the 'core' module. This isn't required, and should be fixed if the rule is violated in any module. Currently, it makes no difference. - update the test runner so that it also handles the case that where no eslint fixes are required. Prior to this fix, no 'actual' file will be produced leading to weird error messaging. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/rules/construct-import-order.ts | 5 ----- .../eslint-plugin-cdk/test/rules/fixtures.test.ts | 14 ++++++++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts b/tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts index bc6d5a0e160bf..fc6066e486747 100644 --- a/tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts +++ b/tools/eslint-plugin-cdk/lib/rules/construct-import-order.ts @@ -20,11 +20,6 @@ let coreConstructImportLine: ImportDeclaration | undefined; let lastImport: Rule.Node | undefined; export function create(context: Rule.RuleContext): Rule.NodeListener { - // skip core - if (context.getFilename().includes('@aws-cdk/core')) { - return {}; - } - return { Program: _ => { // reset for every file diff --git a/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts b/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts index b65670f43b429..bf1c03f359047 100644 --- a/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts +++ b/tools/eslint-plugin-cdk/test/rules/fixtures.test.ts @@ -55,9 +55,15 @@ fs.readdirSync(fixturesRoot).filter(f => fs.lstatSync(path.join(fixturesRoot, f) async function lintAndFix(file: string, outputDir: string) { const newPath = path.join(outputDir, path.basename(file)) let result = await linter.lintFiles(file); - await ESLint.outputFixes(result.map(r => { - r.filePath = newPath; - return r; - })); + const hasFixes = result.find(r => typeof(r.output) === 'string') !== undefined; + if (hasFixes) { + await ESLint.outputFixes(result.map(r => { + r.filePath = newPath; + return r; + })); + } else { + // If there are no fixes, copy the input file as output + await fs.copyFile(file, newPath); + } return newPath; } From b4e1b682604946c30ab63164017c73bd8d828728 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 5 Feb 2021 11:29:03 +0100 Subject: [PATCH 21/21] chore(core): fix bug introduced in recent PR (#12880) In #12765, a bug was introduced where there was a mismatch between the file entry written to the asset manifest for the stack template, and the template location written to the cloud assembly, thereby causing all deployments to fail. The error was "Access Denied" (because that's what S3 says when it doesn't want to tell you "File not found"). Fix the inconsistency. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../core/lib/stack-synthesizers/default-synthesizer.ts | 7 ++++++- .../core/test/stack-synthesis/new-style-synthesis.test.ts | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts index a92d3b6fe04d0..2527bca98c9d6 100644 --- a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts +++ b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts @@ -449,7 +449,12 @@ export class DefaultStackSynthesizer extends StackSynthesizer { // // Instead, we'll have a protocol with the CLI that we put an 's3://.../...' URL here, and the CLI // is going to resolve it to the correct 'https://.../' URL before it gives it to CloudFormation. - return `s3://${this.bucketName}/${this.bucketPrefix}${sourceHash}`; + // + // ALSO: it would be great to reuse the return value of `addFileAsset()` here, except those contain + // CloudFormation REFERENCES to locations, not actual locations (can contain `{ Ref: AWS::Region }` and + // `{ Ref: SomeParameter }` etc). We therefore have to duplicate some logic here :(. + const extension = path.extname(this.stack.templateFile); + return `s3://${this.bucketName}/${this.bucketPrefix}${sourceHash}${extension}`; } /** diff --git a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts index 6780f07fbd879..73f8f185f06ba 100644 --- a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts +++ b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts @@ -36,9 +36,9 @@ nodeunitShim({ // THEN -- the S3 url is advertised on the stack artifact const stackArtifact = asm.getStackArtifact('Stack'); - const templateHash = last(stackArtifact.stackTemplateAssetObjectUrl?.split('/')); + const templateObjectKey = last(stackArtifact.stackTemplateAssetObjectUrl?.split('/')); - test.equals(stackArtifact.stackTemplateAssetObjectUrl, `s3://cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}/${templateHash}`); + test.equals(stackArtifact.stackTemplateAssetObjectUrl, `s3://cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}/${templateObjectKey}`); // THEN - the template is in the asset manifest const manifestArtifact = asm.artifacts.filter(isAssetManifest)[0]; @@ -52,7 +52,7 @@ nodeunitShim({ destinations: { 'current_account-current_region': { bucketName: 'cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}', - objectKey: templateHash + '.json', + objectKey: templateObjectKey, assumeRoleArn: 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}', }, },