From 810d736a8d20638e778c5773507f0edb12733a49 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Fri, 16 Dec 2022 18:26:54 +0100 Subject: [PATCH 01/22] chore(cli): make the typescript version compat task compatible with npm v6 (#23374) Current script breaks with when npm v6 is installed due to the use of `npm pkg` command which was introduced in npm v7. However npm v6 is still the default version for Node.js <=14. ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/integ/init/test-typescript-versions.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/test/integ/init/test-typescript-versions.sh b/packages/aws-cdk/test/integ/init/test-typescript-versions.sh index 8df00129a7bff..da5793661a97e 100755 --- a/packages/aws-cdk/test/integ/init/test-typescript-versions.sh +++ b/packages/aws-cdk/test/integ/init/test-typescript-versions.sh @@ -15,15 +15,22 @@ MIN_SUPPORTED_TS_VERSION=${1:-"3.9"} SUPPORTED_TS_VERSIONS=$(node ${integdir}/typescript-versions.js ${MIN_SUPPORTED_TS_VERSION}) for version in $SUPPORTED_TS_VERSIONS; do - echo "Testing against TypeScript v$version" + header TypeScript v$version setup + set -x + node --version + npm --version + cdk init -l typescript sample-app --generate-only - npm pkg delete devDependencies + sed '/\"devDependencies\"/,/}/ d; /^$/d' package.json > package.json.new && rm package.json && mv package.json.new package.json npm install --save-dev typescript@$version + npm install # Older versions of npm require this to be a separate step from the one above npm prune && npm ls rm test/* npm run build cdk synth + + set +x done From 86b6c6f796cbd15b7c53a4c0482a2b189d45300f Mon Sep 17 00:00:00 2001 From: Varun Wachaspati J Date: Sun, 18 Dec 2022 04:11:36 +0530 Subject: [PATCH 02/22] fix(apigateway): allow multi-level base path mapping (#23362) API Gateway allows multi-level base path mapping but CDK doesn't support the same yet. ([AWS Announcement Post](https://aws.amazon.com/about-aws/whats-new/2021/03/amazon-api-gateway-custom-domain-names-support-multi-level-base-path-mappings/)) Also, added new base path mapping validations such as shouldn't start or end with `/` or shouldn't contain consecutive `/`. fixes #23347 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-apigateway/lib/base-path-mapping.ts | 10 +- .../test/base-path-mapping.test.ts | 110 ++++++++++++++++-- .../manifest.json | 6 + .../test-stack.template.json | 10 ++ .../tree.json | 28 +++++ .../test/integ.base-path-mapping.ts | 7 ++ 6 files changed, 162 insertions(+), 9 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts b/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts index 066ec229b832f..0df48fcb89e3b 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts @@ -56,8 +56,14 @@ export class BasePathMapping extends Resource { super(scope, id); if (props.basePath && !Token.isUnresolved(props.basePath)) { - if (!props.basePath.match(/^[a-zA-Z0-9$_.+!*'()-]+$/)) { - throw new Error(`A base path may only contain letters, numbers, and one of "$-_.+!*'()", received: ${props.basePath}`); + if (props.basePath.startsWith('/') || props.basePath.endsWith('/')) { + throw new Error(`A base path cannot start or end with /", received: ${props.basePath}`); + } + if (props.basePath.match(/\/{2,}/)) { + throw new Error(`A base path cannot have more than one consecutive /", received: ${props.basePath}`); + } + if (!props.basePath.match(/^[a-zA-Z0-9$_.+!*'()-/]+$/)) { + throw new Error(`A base path may only contain letters, numbers, and one of "$-_.+!*'()/", received: ${props.basePath}`); } } diff --git a/packages/@aws-cdk/aws-apigateway/test/base-path-mapping.test.ts b/packages/@aws-cdk/aws-apigateway/test/base-path-mapping.test.ts index c3da93e83ba26..69e7e98d9146f 100644 --- a/packages/@aws-cdk/aws-apigateway/test/base-path-mapping.test.ts +++ b/packages/@aws-cdk/aws-apigateway/test/base-path-mapping.test.ts @@ -8,7 +8,7 @@ describe('BasePathMapping', () => { // GIVEN const stack = new cdk.Stack(); const api = new apigw.RestApi(stack, 'MyApi'); - api.root.addMethod('GET'); // api must have atleast one method. + api.root.addMethod('GET'); // api must have at least one method. const domain = new apigw.DomainName(stack, 'MyDomain', { domainName: 'example.com', certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), @@ -33,7 +33,7 @@ describe('BasePathMapping', () => { // GIVEN const stack = new cdk.Stack(); const api = new apigw.RestApi(stack, 'MyApi'); - api.root.addMethod('GET'); // api must have atleast one method. + api.root.addMethod('GET'); // api must have at least one method. const domain = new apigw.DomainName(stack, 'MyDomain', { domainName: 'example.com', certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), @@ -53,11 +53,11 @@ describe('BasePathMapping', () => { }); }); - test('throw error for invalid basePath property', () => { + test('specify multi-level basePath property', () => { // GIVEN const stack = new cdk.Stack(); const api = new apigw.RestApi(stack, 'MyApi'); - api.root.addMethod('GET'); // api must have atleast one method. + api.root.addMethod('GET'); // api must have at least one method. const domain = new apigw.DomainName(stack, 'MyDomain', { domainName: 'example.com', certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), @@ -65,7 +65,31 @@ describe('BasePathMapping', () => { }); // WHEN - const invalidBasePath = '/invalid-/base-path'; + new apigw.BasePathMapping(stack, 'MyBasePath', { + restApi: api, + domainName: domain, + basePath: 'api/v1/example', + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::BasePathMapping', { + BasePath: 'api/v1/example', + }); + }); + + test('throws when basePath contains an invalid character', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigw.RestApi(stack, 'MyApi'); + api.root.addMethod('GET'); // api must have at least one method. + const domain = new apigw.DomainName(stack, 'MyDomain', { + domainName: 'example.com', + certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), + endpointType: apigw.EndpointType.REGIONAL, + }); + + // WHEN + const invalidBasePath = 'invalid-/base-path?'; // THEN expect(() => { @@ -77,11 +101,83 @@ describe('BasePathMapping', () => { }).toThrowError(/base path may only contain/); }); + test('throw error for basePath starting with /', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigw.RestApi(stack, 'MyApi'); + api.root.addMethod('GET'); // api must have at least one method. + const domain = new apigw.DomainName(stack, 'MyDomain', { + domainName: 'example.com', + certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), + endpointType: apigw.EndpointType.REGIONAL, + }); + + // WHEN + const invalidBasePath = '/invalid-base-path'; + + // THEN + expect(() => { + new apigw.BasePathMapping(stack, 'MyBasePath', { + restApi: api, + domainName: domain, + basePath: invalidBasePath, + }); + }).toThrowError(/A base path cannot start or end with/); + }); + + test('throw error for basePath ending with /', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigw.RestApi(stack, 'MyApi'); + api.root.addMethod('GET'); // api must have at least one method. + const domain = new apigw.DomainName(stack, 'MyDomain', { + domainName: 'example.com', + certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), + endpointType: apigw.EndpointType.REGIONAL, + }); + + // WHEN + const invalidBasePath = 'invalid-base-path/'; + + // THEN + expect(() => { + new apigw.BasePathMapping(stack, 'MyBasePath', { + restApi: api, + domainName: domain, + basePath: invalidBasePath, + }); + }).toThrowError(/A base path cannot start or end with/); + }); + + test('throw error for basePath containing more than one consecutive /', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigw.RestApi(stack, 'MyApi'); + api.root.addMethod('GET'); // api must have at least one method. + const domain = new apigw.DomainName(stack, 'MyDomain', { + domainName: 'example.com', + certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), + endpointType: apigw.EndpointType.REGIONAL, + }); + + // WHEN + const invalidBasePath = 'in//valid-base-path'; + + // THEN + expect(() => { + new apigw.BasePathMapping(stack, 'MyBasePath', { + restApi: api, + domainName: domain, + basePath: invalidBasePath, + }); + }).toThrowError(/A base path cannot have more than one consecutive \//); + }); + test('specify stage property', () => { // GIVEN const stack = new cdk.Stack(); const api = new apigw.RestApi(stack, 'MyApi'); - api.root.addMethod('GET'); // api must have atleast one method. + api.root.addMethod('GET'); // api must have at least one method. const domain = new apigw.DomainName(stack, 'MyDomain', { domainName: 'example.com', certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), @@ -111,7 +207,7 @@ describe('BasePathMapping', () => { // GIVEN const stack = new cdk.Stack(); const api = new apigw.RestApi(stack, 'MyApi'); - api.root.addMethod('GET'); // api must have atleast one method. + api.root.addMethod('GET'); // api must have at least one method. const domain = new apigw.DomainName(stack, 'MyDomain', { domainName: 'example.com', certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/manifest.json b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/manifest.json index a57c7ce4a9fcd..0049bafae7b8e 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/manifest.json @@ -81,6 +81,12 @@ "data": "MappingTwo551C79ED" } ], + "/test-stack/MappingThree/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MappingThree36BBA1B6" + } + ], "/test-stack/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/test-stack.template.json b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/test-stack.template.json index 52d687e8b3f2d..022e83846fdab 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/test-stack.template.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/test-stack.template.json @@ -70,6 +70,16 @@ "Ref": "ApiF70053CD" } } + }, + "MappingThree36BBA1B6": { + "Type": "AWS::ApiGateway::BasePathMapping", + "Properties": { + "DomainName": "domainName", + "BasePath": "api/v1/multi-level-path", + "RestApiId": { + "Ref": "ApiF70053CD" + } + } } }, "Outputs": { diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/tree.json b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/tree.json index 2a9baa7dc204d..814e1397b0795 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.js.snapshot/tree.json @@ -217,6 +217,34 @@ "fqn": "@aws-cdk/aws-apigateway.BasePathMapping", "version": "0.0.0" } + }, + "MappingThree": { + "id": "MappingThree", + "path": "test-stack/MappingThree", + "children": { + "Resource": { + "id": "Resource", + "path": "test-stack/MappingThree/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::BasePathMapping", + "aws:cdk:cloudformation:props": { + "domainName": "domainName", + "basePath": "path", + "restApiId": { + "Ref": "ApiF70053CD" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnBasePathMapping", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.BasePathMapping", + "version": "0.0.0" + } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.ts b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.ts index 9d3a31a3a205e..f25b572545f49 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.base-path-mapping.ts @@ -27,6 +27,13 @@ export class TestStack extends cdk.Stack { basePath: 'path', attachToStage: false, }); + + new apigateway.BasePathMapping(this, 'MappingThree', { + domainName, + restApi, + basePath: 'api/v1/multi-level-path', + attachToStage: false, + }); } } From ecedb00ee3a3cfcaa2564a679fa635aff38f32d8 Mon Sep 17 00:00:00 2001 From: Justin Frahm Date: Mon, 19 Dec 2022 09:22:02 -0700 Subject: [PATCH 03/22] feat(core): CfnResource dependency methods (#23383) Reopening #20419 from a personal fork to allow maintainer edits. @comcalvi :wave: Add some new methods to allow a minimal interface for viewing and editing resource-to-resource dependencies that mirrors the behavior of CfnResource.addDependsOn(). Related to #20418 - details for justification are there ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-appsync/lib/appsync-function.ts | 4 +- .../@aws-cdk/aws-appsync/lib/graphqlapi.ts | 6 +- packages/@aws-cdk/aws-appsync/lib/resolver.ts | 2 +- .../@aws-cdk/aws-cloudformation/package.json | 1 + ...efaultTestDeployAssert3B3B50E2.assets.json | 19 + ...aultTestDeployAssert3B3B50E2.template.json | 36 + .../index.d.ts | 1 + .../index.js | 209 ++++++ .../index.ts | 221 ++++++ .../test/core-deps.integ.snapshot/cdk.out | 1 + .../test/core-deps.integ.snapshot/integ.json | 13 + .../core-deps.integ.snapshot/manifest.json | 224 ++++++ .../nested-stack-depends-test.assets.json | 45 ++ .../nested-stack-depends-test.template.json | 95 +++ ...ndstestStack1DE6783D8.nested.template.json | 54 ++ ...ndstestStack2A36722CF.nested.template.json | 54 ++ .../replace-depends-on-test.assets.json | 32 + .../replace-depends-on-test.template.json | 188 +++++ .../test/core-deps.integ.snapshot/tree.json | 582 +++++++++++++++ .../aws-cloudformation/test/deps.test.ts | 6 +- ...efaultTestDeployAssert3B3B50E2.assets.json | 19 + ...aultTestDeployAssert3B3B50E2.template.json | 36 + .../index.d.ts | 1 + .../index.js | 209 ++++++ .../index.ts | 221 ++++++ .../test/integ.core-deps.js.snapshot/cdk.out | 1 + .../integ.core-deps.js.snapshot/integ.json | 13 + .../integ.core-deps.js.snapshot/manifest.json | 224 ++++++ .../nested-stack-depends-test.assets.json | 45 ++ .../nested-stack-depends-test.template.json | 95 +++ ...ndstestStack1DE6783D8.nested.template.json | 54 ++ ...ndstestStack2A36722CF.nested.template.json | 54 ++ .../replace-depends-on-test.assets.json | 32 + .../replace-depends-on-test.template.json | 188 +++++ .../integ.core-deps.js.snapshot/tree.json | 664 ++++++++++++++++++ .../test/integ.core-deps.ts | 74 ++ ...integ.pipeilne-elastic-beanstalk-deploy.ts | 6 +- .../test/integ.alb.dualstack.ts | 2 +- .../@aws-cdk/aws-logs/lib/log-retention.ts | 4 +- .../lib/private/association-manager.ts | 10 +- .../test/databrew/integ.start-job-run.ts | 6 +- packages/@aws-cdk/core/README.md | 8 +- packages/@aws-cdk/core/lib/cfn-resource.ts | 75 +- .../custom-resource-provider.ts | 2 +- packages/@aws-cdk/core/lib/deps.ts | 130 +++- packages/@aws-cdk/core/lib/index.ts | 1 + .../@aws-cdk/core/lib/private/prepare-app.ts | 2 +- packages/@aws-cdk/core/lib/stack.ts | 136 +++- .../@aws-cdk/core/test/cfn-resource.test.ts | 137 ++++ packages/@aws-cdk/core/test/deps.test.ts | 128 ++++ .../core/test/integration.deps.readme | 5 + packages/@aws-cdk/core/test/resource.test.ts | 10 +- packages/@aws-cdk/core/test/stack.test.ts | 202 +++++- packages/aws-cdk-lib/README.md | 8 +- 54 files changed, 4520 insertions(+), 75 deletions(-) create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.assets.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.assets.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.assets.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.assets.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.template.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.ts create mode 100644 packages/@aws-cdk/core/test/deps.test.ts create mode 100644 packages/@aws-cdk/core/test/integration.deps.readme diff --git a/packages/@aws-cdk/aws-appsync/lib/appsync-function.ts b/packages/@aws-cdk/aws-appsync/lib/appsync-function.ts index 7423317d0fa3e..46019afe6c2a9 100644 --- a/packages/@aws-cdk/aws-appsync/lib/appsync-function.ts +++ b/packages/@aws-cdk/aws-appsync/lib/appsync-function.ts @@ -142,7 +142,7 @@ export class AppsyncFunction extends Resource implements IAppsyncFunction { this.functionId = this.function.attrFunctionId; this.dataSource = props.dataSource; - this.function.addDependsOn(this.dataSource.ds); + this.function.addDependency(this.dataSource.ds); props.api.addSchemaDependency(this.function); } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts b/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts index 83027eafd5603..0f7f16a37f0ab 100644 --- a/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts +++ b/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts @@ -518,7 +518,7 @@ export class GraphqlApi extends GraphqlApiBase { apiId: this.apiId, }); - domainNameAssociation.addDependsOn(this.domainNameResource); + domainNameAssociation.addDependency(this.domainNameResource); } if (modes.some((mode) => mode.authorizationType === AuthorizationType.API_KEY)) { @@ -526,7 +526,7 @@ export class GraphqlApi extends GraphqlApiBase { return mode.authorizationType === AuthorizationType.API_KEY && mode.apiKeyConfig; })?.apiKeyConfig; this.apiKeyResource = this.createAPIKey(config); - this.apiKeyResource.addDependsOn(this.schemaResource); + this.apiKeyResource.addDependency(this.schemaResource); this.apiKey = this.apiKeyResource.attrApiKey; } @@ -631,7 +631,7 @@ export class GraphqlApi extends GraphqlApiBase { * @param construct the dependee */ public addSchemaDependency(construct: CfnResource): boolean { - construct.addDependsOn(this.schemaResource); + construct.addDependency(this.schemaResource); return true; } diff --git a/packages/@aws-cdk/aws-appsync/lib/resolver.ts b/packages/@aws-cdk/aws-appsync/lib/resolver.ts index 3df7f44a068c5..72818cb59b966 100644 --- a/packages/@aws-cdk/aws-appsync/lib/resolver.ts +++ b/packages/@aws-cdk/aws-appsync/lib/resolver.ts @@ -122,7 +122,7 @@ export class Resolver extends Construct { }); props.api.addSchemaDependency(this.resolver); if (props.dataSource) { - this.resolver.addDependsOn(props.dataSource.ds); + this.resolver.addDependency(props.dataSource.ds); } this.arn = this.resolver.attrResolverArn; } diff --git a/packages/@aws-cdk/aws-cloudformation/package.json b/packages/@aws-cdk/aws-cloudformation/package.json index e77fc63a8af4a..ebeda6f56846a 100644 --- a/packages/@aws-cdk/aws-cloudformation/package.json +++ b/packages/@aws-cdk/aws-cloudformation/package.json @@ -78,6 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assertions": "0.0.0", + "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", "@aws-cdk/aws-sns-subscriptions": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json new file mode 100644 index 0000000000000..a513dc6283811 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts new file mode 100644 index 0000000000000..9bbf5854684b6 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts @@ -0,0 +1 @@ +export declare function handler(event: AWSLambda.CloudFormationCustomResourceEvent, context: AWSLambda.Context): Promise; diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js new file mode 100644 index 0000000000000..d8d501f248a23 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js @@ -0,0 +1,209 @@ +"use strict"; +/* eslint-disable no-console */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +// eslint-disable-next-line import/no-extraneous-dependencies +const AWS = require("aws-sdk"); +/** + * Creates a log group and doesn't throw if it exists. + * + * @param logGroupName the name of the log group to create. + * @param region to create the log group in + * @param options CloudWatch API SDK options. + */ +async function createLogGroupSafe(logGroupName, region, options) { + // If we set the log retention for a lambda, then due to the async nature of + // Lambda logging there could be a race condition when the same log group is + // already being created by the lambda execution. This can sometime result in + // an error "OperationAbortedException: A conflicting operation is currently + // in progress...Please try again." + // To avoid an error, we do as requested and try again. + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.createLogGroup({ logGroupName }).promise(); + return; + } + catch (error) { + if (error.code === 'ResourceAlreadyExistsException') { + // The log group is already created by the lambda execution + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } + else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} +//delete a log group +async function deleteLogGroup(logGroupName, region, options) { + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.deleteLogGroup({ logGroupName }).promise(); + return; + } + catch (error) { + if (error.code === 'ResourceNotFoundException') { + // The log group doesn't exist + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } + else { + // The log group is still being deleted by another execution but we are out of retries + throw new Error('Out of attempts to delete a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} +/** + * Puts or deletes a retention policy on a log group. + * + * @param logGroupName the name of the log group to create + * @param region the region of the log group + * @param options CloudWatch API SDK options. + * @param retentionInDays the number of days to retain the log events in the specified log group. + */ +async function setRetentionPolicy(logGroupName, region, options, retentionInDays) { + // The same as in createLogGroupSafe(), here we could end up with the race + // condition where a log group is either already being created or its retention + // policy is being updated. This would result in an OperationAbortedException, + // which we will try to catch and retry the command a number of times before failing + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + if (!retentionInDays) { + await cloudwatchlogs.deleteRetentionPolicy({ logGroupName }).promise(); + } + else { + await cloudwatchlogs.putRetentionPolicy({ logGroupName, retentionInDays }).promise(); + } + return; + } + catch (error) { + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } + else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} +async function handler(event, context) { + try { + console.log(JSON.stringify({ ...event, ResponseURL: '...' })); + // The target log group + const logGroupName = event.ResourceProperties.LogGroupName; + // The region of the target log group + const logGroupRegion = event.ResourceProperties.LogGroupRegion; + // Parse to AWS SDK retry options + const retryOptions = parseRetryOptions(event.ResourceProperties.SdkRetry); + if (event.RequestType === 'Create' || event.RequestType === 'Update') { + // Act on the target log group + await createLogGroupSafe(logGroupName, logGroupRegion, retryOptions); + await setRetentionPolicy(logGroupName, logGroupRegion, retryOptions, parseInt(event.ResourceProperties.RetentionInDays, 10)); + if (event.RequestType === 'Create') { + // Set a retention policy of 1 day on the logs of this very function. + // Due to the async nature of the log group creation, the log group for this function might + // still be not created yet at this point. Therefore we attempt to create it. + // In case it is being created, createLogGroupSafe will handle the conflict. + const region = process.env.AWS_REGION; + await createLogGroupSafe(`/aws/lambda/${context.functionName}`, region, retryOptions); + // If createLogGroupSafe fails, the log group is not created even after multiple attempts. + // In this case we have nothing to set the retention policy on but an exception will skip + // the next line. + await setRetentionPolicy(`/aws/lambda/${context.functionName}`, region, retryOptions, 1); + } + } + //When the requestType is delete, delete the log group if the removal policy is delete + if (event.RequestType === 'Delete' && event.ResourceProperties.RemovalPolicy === 'destroy') { + await deleteLogGroup(logGroupName, logGroupRegion, retryOptions); + //else retain the log group + } + await respond('SUCCESS', 'OK', logGroupName); + } + catch (e) { + console.log(e); + await respond('FAILED', e.message, event.ResourceProperties.LogGroupName); + } + function respond(responseStatus, reason, physicalResourceId) { + const responseBody = JSON.stringify({ + Status: responseStatus, + Reason: reason, + PhysicalResourceId: physicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: { + // Add log group name as part of the response so that it's available via Fn::GetAtt + LogGroupName: event.ResourceProperties.LogGroupName, + }, + }); + console.log('Responding', responseBody); + // eslint-disable-next-line @typescript-eslint/no-require-imports + const parsedUrl = require('url').parse(event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + return new Promise((resolve, reject) => { + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const request = require('https').request(requestOptions, resolve); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); + } + function parseRetryOptions(rawOptions) { + const retryOptions = {}; + if (rawOptions) { + if (rawOptions.maxRetries) { + retryOptions.maxRetries = parseInt(rawOptions.maxRetries, 10); + } + if (rawOptions.base) { + retryOptions.retryOptions = { + base: parseInt(rawOptions.base, 10), + }; + } + } + return retryOptions; + } +} +exports.handler = handler; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0JBQStCOzs7QUFFL0IsNkRBQTZEO0FBQzdELCtCQUErQjtBQVMvQjs7Ozs7O0dBTUc7QUFDSCxLQUFLLFVBQVUsa0JBQWtCLENBQUMsWUFBb0IsRUFBRSxNQUFlLEVBQUUsT0FBeUI7SUFDaEcsNEVBQTRFO0lBQzVFLDRFQUE0RTtJQUM1RSw2RUFBNkU7SUFDN0UsNEVBQTRFO0lBQzVFLG1DQUFtQztJQUNuQyx1REFBdUQ7SUFDdkQsSUFBSSxVQUFVLEdBQUcsT0FBTyxFQUFFLFVBQVUsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztJQUM1RSxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsWUFBWSxFQUFFLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDeEYsR0FBRztRQUNELElBQUk7WUFDRixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDaEcsTUFBTSxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNoRSxPQUFPO1NBQ1I7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxnQ0FBZ0MsRUFBRTtnQkFDbkQsMkRBQTJEO2dCQUMzRCxPQUFPO2FBQ1I7WUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssMkJBQTJCLEVBQUU7Z0JBQzlDLElBQUksVUFBVSxHQUFHLENBQUMsRUFBRTtvQkFDbEIsVUFBVSxFQUFFLENBQUM7b0JBQ2IsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDekQsU0FBUztpQkFDVjtxQkFBTTtvQkFDTCxzRkFBc0Y7b0JBQ3RGLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztpQkFDekQ7YUFDRjtZQUNELE1BQU0sS0FBSyxDQUFDO1NBQ2I7S0FDRixRQUFRLElBQUksRUFBRSxDQUFDLG9DQUFvQztBQUN0RCxDQUFDO0FBRUQsb0JBQW9CO0FBQ3BCLEtBQUssVUFBVSxjQUFjLENBQUMsWUFBb0IsRUFBRSxNQUFlLEVBQUUsT0FBeUI7SUFDNUYsSUFBSSxVQUFVLEdBQUcsT0FBTyxFQUFFLFVBQVUsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztJQUM1RSxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsWUFBWSxFQUFFLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDeEYsR0FBRztRQUNELElBQUk7WUFDRixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDaEcsTUFBTSxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNoRSxPQUFPO1NBQ1I7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLElBQUksS0FBSyxDQUFDLElBQUksS0FBSywyQkFBMkIsRUFBRTtnQkFDOUMsOEJBQThCO2dCQUM5QixPQUFPO2FBQ1I7WUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssMkJBQTJCLEVBQUU7Z0JBQzlDLElBQUksVUFBVSxHQUFHLENBQUMsRUFBRTtvQkFDbEIsVUFBVSxFQUFFLENBQUM7b0JBQ2IsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDekQsU0FBUztpQkFDVjtxQkFBTTtvQkFDTCxzRkFBc0Y7b0JBQ3RGLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztpQkFDekQ7YUFDRjtZQUNELE1BQU0sS0FBSyxDQUFDO1NBQ2I7S0FDRixRQUFRLElBQUksRUFBRSxDQUFDLG9DQUFvQztBQUN0RCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxZQUFvQixFQUFFLE1BQWUsRUFBRSxPQUF5QixFQUFFLGVBQXdCO0lBQzFILDBFQUEwRTtJQUMxRSwrRUFBK0U7SUFDL0UsOEVBQThFO0lBQzlFLG9GQUFvRjtJQUNwRixJQUFJLFVBQVUsR0FBRyxPQUFPLEVBQUUsVUFBVSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQzVFLE1BQU0sS0FBSyxHQUFHLE9BQU8sRUFBRSxZQUFZLEVBQUUsSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztJQUN4RixHQUFHO1FBQ0QsSUFBSTtZQUNGLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNoRyxJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUNwQixNQUFNLGNBQWMsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDeEU7aUJBQU07Z0JBQ0wsTUFBTSxjQUFjLENBQUMsa0JBQWtCLENBQUMsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUN0RjtZQUNELE9BQU87U0FFUjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLDJCQUEyQixFQUFFO2dCQUM5QyxJQUFJLFVBQVUsR0FBRyxDQUFDLEVBQUU7b0JBQ2xCLFVBQVUsRUFBRSxDQUFDO29CQUNiLE1BQU0sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQ3pELFNBQVM7aUJBQ1Y7cUJBQU07b0JBQ0wsc0ZBQXNGO29CQUN0RixNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7aUJBQ3pEO2FBQ0Y7WUFDRCxNQUFNLEtBQUssQ0FBQztTQUNiO0tBQ0YsUUFBUSxJQUFJLEVBQUUsQ0FBQyxvQ0FBb0M7QUFDdEQsQ0FBQztBQUVNLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBa0QsRUFBRSxPQUEwQjtJQUMxRyxJQUFJO1FBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUU5RCx1QkFBdUI7UUFDdkIsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQztRQUUzRCxxQ0FBcUM7UUFDckMsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQztRQUUvRCxpQ0FBaUM7UUFDakMsTUFBTSxZQUFZLEdBQUcsaUJBQWlCLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTFFLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUU7WUFDcEUsOEJBQThCO1lBQzlCLE1BQU0sa0JBQWtCLENBQUMsWUFBWSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNyRSxNQUFNLGtCQUFrQixDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFN0gsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEMscUVBQXFFO2dCQUNyRSwyRkFBMkY7Z0JBQzNGLDZFQUE2RTtnQkFDN0UsNEVBQTRFO2dCQUM1RSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztnQkFDdEMsTUFBTSxrQkFBa0IsQ0FBQyxlQUFlLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQ3RGLDBGQUEwRjtnQkFDMUYseUZBQXlGO2dCQUN6RixpQkFBaUI7Z0JBQ2pCLE1BQU0sa0JBQWtCLENBQUMsZUFBZSxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQzthQUMxRjtTQUNGO1FBRUQsc0ZBQXNGO1FBQ3RGLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDLGFBQWEsS0FBSyxTQUFTLEVBQUU7WUFDMUYsTUFBTSxjQUFjLENBQUMsWUFBWSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNqRSwyQkFBMkI7U0FDNUI7UUFFRCxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDO0tBQzlDO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWYsTUFBTSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDO0tBQzNFO0lBRUQsU0FBUyxPQUFPLENBQUMsY0FBc0IsRUFBRSxNQUFjLEVBQUUsa0JBQTBCO1FBQ2pGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDbEMsTUFBTSxFQUFFLGNBQWM7WUFDdEIsTUFBTSxFQUFFLE1BQU07WUFDZCxrQkFBa0IsRUFBRSxrQkFBa0I7WUFDdEMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztZQUMxQixpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO1lBQzFDLElBQUksRUFBRTtnQkFDSixtRkFBbUY7Z0JBQ25GLFlBQVksRUFBRSxLQUFLLENBQUMsa0JBQWtCLENBQUMsWUFBWTthQUNwRDtTQUNGLENBQUMsQ0FBQztRQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRXhDLGlFQUFpRTtRQUNqRSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxRCxNQUFNLGNBQWMsR0FBRztZQUNyQixRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7WUFDNUIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1lBQ3BCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFO1NBQ3ZFLENBQUM7UUFFRixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUk7Z0JBQ0YsaUVBQWlFO2dCQUNqRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUNmO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ1g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTLGlCQUFpQixDQUFDLFVBQWU7UUFDeEMsTUFBTSxZQUFZLEdBQW9CLEVBQUUsQ0FBQztRQUN6QyxJQUFJLFVBQVUsRUFBRTtZQUNkLElBQUksVUFBVSxDQUFDLFVBQVUsRUFBRTtnQkFDekIsWUFBWSxDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUMvRDtZQUNELElBQUksVUFBVSxDQUFDLElBQUksRUFBRTtnQkFDbkIsWUFBWSxDQUFDLFlBQVksR0FBRztvQkFDMUIsSUFBSSxFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztpQkFDcEMsQ0FBQzthQUNIO1NBQ0Y7UUFDRCxPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDO0FBQ0gsQ0FBQztBQWpHRCwwQkFpR0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcbmltcG9ydCAqIGFzIEFXUyBmcm9tICdhd3Mtc2RrJztcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcbmltcG9ydCB0eXBlIHsgUmV0cnlEZWxheU9wdGlvbnMgfSBmcm9tICdhd3Mtc2RrL2xpYi9jb25maWctYmFzZSc7XG5cbmludGVyZmFjZSBTZGtSZXRyeU9wdGlvbnMge1xuICBtYXhSZXRyaWVzPzogbnVtYmVyO1xuICByZXRyeU9wdGlvbnM/OiBSZXRyeURlbGF5T3B0aW9ucztcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbG9nIGdyb3VwIGFuZCBkb2Vzbid0IHRocm93IGlmIGl0IGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gbG9nR3JvdXBOYW1lIHRoZSBuYW1lIG9mIHRoZSBsb2cgZ3JvdXAgdG8gY3JlYXRlLlxuICogQHBhcmFtIHJlZ2lvbiB0byBjcmVhdGUgdGhlIGxvZyBncm91cCBpblxuICogQHBhcmFtIG9wdGlvbnMgQ2xvdWRXYXRjaCBBUEkgU0RLIG9wdGlvbnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUxvZ0dyb3VwU2FmZShsb2dHcm91cE5hbWU6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBvcHRpb25zPzogU2RrUmV0cnlPcHRpb25zKSB7XG4gIC8vIElmIHdlIHNldCB0aGUgbG9nIHJldGVudGlvbiBmb3IgYSBsYW1iZGEsIHRoZW4gZHVlIHRvIHRoZSBhc3luYyBuYXR1cmUgb2ZcbiAgLy8gTGFtYmRhIGxvZ2dpbmcgdGhlcmUgY291bGQgYmUgYSByYWNlIGNvbmRpdGlvbiB3aGVuIHRoZSBzYW1lIGxvZyBncm91cCBpc1xuICAvLyBhbHJlYWR5IGJlaW5nIGNyZWF0ZWQgYnkgdGhlIGxhbWJkYSBleGVjdXRpb24uIFRoaXMgY2FuIHNvbWV0aW1lIHJlc3VsdCBpblxuICAvLyBhbiBlcnJvciBcIk9wZXJhdGlvbkFib3J0ZWRFeGNlcHRpb246IEEgY29uZmxpY3Rpbmcgb3BlcmF0aW9uIGlzIGN1cnJlbnRseVxuICAvLyBpbiBwcm9ncmVzcy4uLlBsZWFzZSB0cnkgYWdhaW4uXCJcbiAgLy8gVG8gYXZvaWQgYW4gZXJyb3IsIHdlIGRvIGFzIHJlcXVlc3RlZCBhbmQgdHJ5IGFnYWluLlxuICBsZXQgcmV0cnlDb3VudCA9IG9wdGlvbnM/Lm1heFJldHJpZXMgPT0gdW5kZWZpbmVkID8gMTAgOiBvcHRpb25zLm1heFJldHJpZXM7XG4gIGNvbnN0IGRlbGF5ID0gb3B0aW9ucz8ucmV0cnlPcHRpb25zPy5iYXNlID09IHVuZGVmaW5lZCA/IDEwIDogb3B0aW9ucy5yZXRyeU9wdGlvbnMuYmFzZTtcbiAgZG8ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjbG91ZHdhdGNobG9ncyA9IG5ldyBBV1MuQ2xvdWRXYXRjaExvZ3MoeyBhcGlWZXJzaW9uOiAnMjAxNC0wMy0yOCcsIHJlZ2lvbiwgLi4ub3B0aW9ucyB9KTtcbiAgICAgIGF3YWl0IGNsb3Vkd2F0Y2hsb2dzLmNyZWF0ZUxvZ0dyb3VwKHsgbG9nR3JvdXBOYW1lIH0pLnByb21pc2UoKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT09ICdSZXNvdXJjZUFscmVhZHlFeGlzdHNFeGNlcHRpb24nKSB7XG4gICAgICAgIC8vIFRoZSBsb2cgZ3JvdXAgaXMgYWxyZWFkeSBjcmVhdGVkIGJ5IHRoZSBsYW1iZGEgZXhlY3V0aW9uXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvci5jb2RlID09PSAnT3BlcmF0aW9uQWJvcnRlZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgaWYgKHJldHJ5Q291bnQgPiAwKSB7XG4gICAgICAgICAgcmV0cnlDb3VudC0tO1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBkZWxheSkpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFRoZSBsb2cgZ3JvdXAgaXMgc3RpbGwgYmVpbmcgY3JlYXRlZCBieSBhbm90aGVyIGV4ZWN1dGlvbiBidXQgd2UgYXJlIG91dCBvZiByZXRyaWVzXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdPdXQgb2YgYXR0ZW1wdHMgdG8gY3JlYXRlIGEgbG9nR3JvdXAnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9IHdoaWxlICh0cnVlKTsgLy8gZXhpdCBoYXBwZW5zIG9uIHJldHJ5IGNvdW50IGNoZWNrXG59XG5cbi8vZGVsZXRlIGEgbG9nIGdyb3VwXG5hc3luYyBmdW5jdGlvbiBkZWxldGVMb2dHcm91cChsb2dHcm91cE5hbWU6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBvcHRpb25zPzogU2RrUmV0cnlPcHRpb25zKSB7XG4gIGxldCByZXRyeUNvdW50ID0gb3B0aW9ucz8ubWF4UmV0cmllcyA9PSB1bmRlZmluZWQgPyAxMCA6IG9wdGlvbnMubWF4UmV0cmllcztcbiAgY29uc3QgZGVsYXkgPSBvcHRpb25zPy5yZXRyeU9wdGlvbnM/LmJhc2UgPT0gdW5kZWZpbmVkID8gMTAgOiBvcHRpb25zLnJldHJ5T3B0aW9ucy5iYXNlO1xuICBkbyB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNsb3Vkd2F0Y2hsb2dzID0gbmV3IEFXUy5DbG91ZFdhdGNoTG9ncyh7IGFwaVZlcnNpb246ICcyMDE0LTAzLTI4JywgcmVnaW9uLCAuLi5vcHRpb25zIH0pO1xuICAgICAgYXdhaXQgY2xvdWR3YXRjaGxvZ3MuZGVsZXRlTG9nR3JvdXAoeyBsb2dHcm91cE5hbWUgfSkucHJvbWlzZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24nKSB7XG4gICAgICAgIC8vIFRoZSBsb2cgZ3JvdXAgZG9lc24ndCBleGlzdFxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ09wZXJhdGlvbkFib3J0ZWRFeGNlcHRpb24nKSB7XG4gICAgICAgIGlmIChyZXRyeUNvdW50ID4gMCkge1xuICAgICAgICAgIHJldHJ5Q291bnQtLTtcbiAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgZGVsYXkpKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBUaGUgbG9nIGdyb3VwIGlzIHN0aWxsIGJlaW5nIGRlbGV0ZWQgYnkgYW5vdGhlciBleGVjdXRpb24gYnV0IHdlIGFyZSBvdXQgb2YgcmV0cmllc1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignT3V0IG9mIGF0dGVtcHRzIHRvIGRlbGV0ZSBhIGxvZ0dyb3VwJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfSB3aGlsZSAodHJ1ZSk7IC8vIGV4aXQgaGFwcGVucyBvbiByZXRyeSBjb3VudCBjaGVja1xufVxuXG4vKipcbiAqIFB1dHMgb3IgZGVsZXRlcyBhIHJldGVudGlvbiBwb2xpY3kgb24gYSBsb2cgZ3JvdXAuXG4gKlxuICogQHBhcmFtIGxvZ0dyb3VwTmFtZSB0aGUgbmFtZSBvZiB0aGUgbG9nIGdyb3VwIHRvIGNyZWF0ZVxuICogQHBhcmFtIHJlZ2lvbiB0aGUgcmVnaW9uIG9mIHRoZSBsb2cgZ3JvdXBcbiAqIEBwYXJhbSBvcHRpb25zIENsb3VkV2F0Y2ggQVBJIFNESyBvcHRpb25zLlxuICogQHBhcmFtIHJldGVudGlvbkluRGF5cyB0aGUgbnVtYmVyIG9mIGRheXMgdG8gcmV0YWluIHRoZSBsb2cgZXZlbnRzIGluIHRoZSBzcGVjaWZpZWQgbG9nIGdyb3VwLlxuICovXG5hc3luYyBmdW5jdGlvbiBzZXRSZXRlbnRpb25Qb2xpY3kobG9nR3JvdXBOYW1lOiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgb3B0aW9ucz86IFNka1JldHJ5T3B0aW9ucywgcmV0ZW50aW9uSW5EYXlzPzogbnVtYmVyKSB7XG4gIC8vIFRoZSBzYW1lIGFzIGluIGNyZWF0ZUxvZ0dyb3VwU2FmZSgpLCBoZXJlIHdlIGNvdWxkIGVuZCB1cCB3aXRoIHRoZSByYWNlXG4gIC8vIGNvbmRpdGlvbiB3aGVyZSBhIGxvZyBncm91cCBpcyBlaXRoZXIgYWxyZWFkeSBiZWluZyBjcmVhdGVkIG9yIGl0cyByZXRlbnRpb25cbiAgLy8gcG9saWN5IGlzIGJlaW5nIHVwZGF0ZWQuIFRoaXMgd291bGQgcmVzdWx0IGluIGFuIE9wZXJhdGlvbkFib3J0ZWRFeGNlcHRpb24sXG4gIC8vIHdoaWNoIHdlIHdpbGwgdHJ5IHRvIGNhdGNoIGFuZCByZXRyeSB0aGUgY29tbWFuZCBhIG51bWJlciBvZiB0aW1lcyBiZWZvcmUgZmFpbGluZ1xuICBsZXQgcmV0cnlDb3VudCA9IG9wdGlvbnM/Lm1heFJldHJpZXMgPT0gdW5kZWZpbmVkID8gMTAgOiBvcHRpb25zLm1heFJldHJpZXM7XG4gIGNvbnN0IGRlbGF5ID0gb3B0aW9ucz8ucmV0cnlPcHRpb25zPy5iYXNlID09IHVuZGVmaW5lZCA/IDEwIDogb3B0aW9ucy5yZXRyeU9wdGlvbnMuYmFzZTtcbiAgZG8ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjbG91ZHdhdGNobG9ncyA9IG5ldyBBV1MuQ2xvdWRXYXRjaExvZ3MoeyBhcGlWZXJzaW9uOiAnMjAxNC0wMy0yOCcsIHJlZ2lvbiwgLi4ub3B0aW9ucyB9KTtcbiAgICAgIGlmICghcmV0ZW50aW9uSW5EYXlzKSB7XG4gICAgICAgIGF3YWl0IGNsb3Vkd2F0Y2hsb2dzLmRlbGV0ZVJldGVudGlvblBvbGljeSh7IGxvZ0dyb3VwTmFtZSB9KS5wcm9taXNlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBjbG91ZHdhdGNobG9ncy5wdXRSZXRlbnRpb25Qb2xpY3koeyBsb2dHcm91cE5hbWUsIHJldGVudGlvbkluRGF5cyB9KS5wcm9taXNlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG5cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT09ICdPcGVyYXRpb25BYm9ydGVkRXhjZXB0aW9uJykge1xuICAgICAgICBpZiAocmV0cnlDb3VudCA+IDApIHtcbiAgICAgICAgICByZXRyeUNvdW50LS07XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGRlbGF5KSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhlIGxvZyBncm91cCBpcyBzdGlsbCBiZWluZyBjcmVhdGVkIGJ5IGFub3RoZXIgZXhlY3V0aW9uIGJ1dCB3ZSBhcmUgb3V0IG9mIHJldHJpZXNcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ091dCBvZiBhdHRlbXB0cyB0byBjcmVhdGUgYSBsb2dHcm91cCcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH0gd2hpbGUgKHRydWUpOyAvLyBleGl0IGhhcHBlbnMgb24gcmV0cnkgY291bnQgY2hlY2tcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIHRyeSB7XG4gICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoeyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH0pKTtcblxuICAgIC8vIFRoZSB0YXJnZXQgbG9nIGdyb3VwXG4gICAgY29uc3QgbG9nR3JvdXBOYW1lID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkxvZ0dyb3VwTmFtZTtcblxuICAgIC8vIFRoZSByZWdpb24gb2YgdGhlIHRhcmdldCBsb2cgZ3JvdXBcbiAgICBjb25zdCBsb2dHcm91cFJlZ2lvbiA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Mb2dHcm91cFJlZ2lvbjtcblxuICAgIC8vIFBhcnNlIHRvIEFXUyBTREsgcmV0cnkgb3B0aW9uc1xuICAgIGNvbnN0IHJldHJ5T3B0aW9ucyA9IHBhcnNlUmV0cnlPcHRpb25zKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5TZGtSZXRyeSk7XG5cbiAgICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdDcmVhdGUnIHx8IGV2ZW50LlJlcXVlc3RUeXBlID09PSAnVXBkYXRlJykge1xuICAgICAgLy8gQWN0IG9uIHRoZSB0YXJnZXQgbG9nIGdyb3VwXG4gICAgICBhd2FpdCBjcmVhdGVMb2dHcm91cFNhZmUobG9nR3JvdXBOYW1lLCBsb2dHcm91cFJlZ2lvbiwgcmV0cnlPcHRpb25zKTtcbiAgICAgIGF3YWl0IHNldFJldGVudGlvblBvbGljeShsb2dHcm91cE5hbWUsIGxvZ0dyb3VwUmVnaW9uLCByZXRyeU9wdGlvbnMsIHBhcnNlSW50KGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5SZXRlbnRpb25JbkRheXMsIDEwKSk7XG5cbiAgICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICAgICAgLy8gU2V0IGEgcmV0ZW50aW9uIHBvbGljeSBvZiAxIGRheSBvbiB0aGUgbG9ncyBvZiB0aGlzIHZlcnkgZnVuY3Rpb24uXG4gICAgICAgIC8vIER1ZSB0byB0aGUgYXN5bmMgbmF0dXJlIG9mIHRoZSBsb2cgZ3JvdXAgY3JlYXRpb24sIHRoZSBsb2cgZ3JvdXAgZm9yIHRoaXMgZnVuY3Rpb24gbWlnaHRcbiAgICAgICAgLy8gc3RpbGwgYmUgbm90IGNyZWF0ZWQgeWV0IGF0IHRoaXMgcG9pbnQuIFRoZXJlZm9yZSB3ZSBhdHRlbXB0IHRvIGNyZWF0ZSBpdC5cbiAgICAgICAgLy8gSW4gY2FzZSBpdCBpcyBiZWluZyBjcmVhdGVkLCBjcmVhdGVMb2dHcm91cFNhZmUgd2lsbCBoYW5kbGUgdGhlIGNvbmZsaWN0LlxuICAgICAgICBjb25zdCByZWdpb24gPSBwcm9jZXNzLmVudi5BV1NfUkVHSU9OO1xuICAgICAgICBhd2FpdCBjcmVhdGVMb2dHcm91cFNhZmUoYC9hd3MvbGFtYmRhLyR7Y29udGV4dC5mdW5jdGlvbk5hbWV9YCwgcmVnaW9uLCByZXRyeU9wdGlvbnMpO1xuICAgICAgICAvLyBJZiBjcmVhdGVMb2dHcm91cFNhZmUgZmFpbHMsIHRoZSBsb2cgZ3JvdXAgaXMgbm90IGNyZWF0ZWQgZXZlbiBhZnRlciBtdWx0aXBsZSBhdHRlbXB0cy5cbiAgICAgICAgLy8gSW4gdGhpcyBjYXNlIHdlIGhhdmUgbm90aGluZyB0byBzZXQgdGhlIHJldGVudGlvbiBwb2xpY3kgb24gYnV0IGFuIGV4Y2VwdGlvbiB3aWxsIHNraXBcbiAgICAgICAgLy8gdGhlIG5leHQgbGluZS5cbiAgICAgICAgYXdhaXQgc2V0UmV0ZW50aW9uUG9saWN5KGAvYXdzL2xhbWJkYS8ke2NvbnRleHQuZnVuY3Rpb25OYW1lfWAsIHJlZ2lvbiwgcmV0cnlPcHRpb25zLCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvL1doZW4gdGhlIHJlcXVlc3RUeXBlIGlzIGRlbGV0ZSwgZGVsZXRlIHRoZSBsb2cgZ3JvdXAgaWYgdGhlIHJlbW92YWwgcG9saWN5IGlzIGRlbGV0ZVxuICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScgJiYgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLlJlbW92YWxQb2xpY3kgPT09ICdkZXN0cm95Jykge1xuICAgICAgYXdhaXQgZGVsZXRlTG9nR3JvdXAobG9nR3JvdXBOYW1lLCBsb2dHcm91cFJlZ2lvbiwgcmV0cnlPcHRpb25zKTtcbiAgICAgIC8vZWxzZSByZXRhaW4gdGhlIGxvZyBncm91cFxuICAgIH1cblxuICAgIGF3YWl0IHJlc3BvbmQoJ1NVQ0NFU1MnLCAnT0snLCBsb2dHcm91cE5hbWUpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5sb2coZSk7XG5cbiAgICBhd2FpdCByZXNwb25kKCdGQUlMRUQnLCBlLm1lc3NhZ2UsIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Mb2dHcm91cE5hbWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzcG9uZChyZXNwb25zZVN0YXR1czogc3RyaW5nLCByZWFzb246IHN0cmluZywgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBTdGF0dXM6IHJlc3BvbnNlU3RhdHVzLFxuICAgICAgUmVhc29uOiByZWFzb24sXG4gICAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCxcbiAgICAgIERhdGE6IHtcbiAgICAgICAgLy8gQWRkIGxvZyBncm91cCBuYW1lIGFzIHBhcnQgb2YgdGhlIHJlc3BvbnNlIHNvIHRoYXQgaXQncyBhdmFpbGFibGUgdmlhIEZuOjpHZXRBdHRcbiAgICAgICAgTG9nR3JvdXBOYW1lOiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuTG9nR3JvdXBOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKCdSZXNwb25kaW5nJywgcmVzcG9uc2VCb2R5KTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgcGFyc2VkVXJsID0gcmVxdWlyZSgndXJsJykucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgICAgbWV0aG9kOiAnUFVUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnaHR0cHMnKS5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCByZXNvbHZlKTtcbiAgICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlUmV0cnlPcHRpb25zKHJhd09wdGlvbnM6IGFueSk6IFNka1JldHJ5T3B0aW9ucyB7XG4gICAgY29uc3QgcmV0cnlPcHRpb25zOiBTZGtSZXRyeU9wdGlvbnMgPSB7fTtcbiAgICBpZiAocmF3T3B0aW9ucykge1xuICAgICAgaWYgKHJhd09wdGlvbnMubWF4UmV0cmllcykge1xuICAgICAgICByZXRyeU9wdGlvbnMubWF4UmV0cmllcyA9IHBhcnNlSW50KHJhd09wdGlvbnMubWF4UmV0cmllcywgMTApO1xuICAgICAgfVxuICAgICAgaWYgKHJhd09wdGlvbnMuYmFzZSkge1xuICAgICAgICByZXRyeU9wdGlvbnMucmV0cnlPcHRpb25zID0ge1xuICAgICAgICAgIGJhc2U6IHBhcnNlSW50KHJhd09wdGlvbnMuYmFzZSwgMTApLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0cnlPcHRpb25zO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts new file mode 100644 index 0000000000000..1bb38a9f3d774 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts @@ -0,0 +1,221 @@ +/* eslint-disable no-console */ + +// eslint-disable-next-line import/no-extraneous-dependencies +import * as AWS from 'aws-sdk'; +// eslint-disable-next-line import/no-extraneous-dependencies +import type { RetryDelayOptions } from 'aws-sdk/lib/config-base'; + +interface SdkRetryOptions { + maxRetries?: number; + retryOptions?: RetryDelayOptions; +} + +/** + * Creates a log group and doesn't throw if it exists. + * + * @param logGroupName the name of the log group to create. + * @param region to create the log group in + * @param options CloudWatch API SDK options. + */ +async function createLogGroupSafe(logGroupName: string, region?: string, options?: SdkRetryOptions) { + // If we set the log retention for a lambda, then due to the async nature of + // Lambda logging there could be a race condition when the same log group is + // already being created by the lambda execution. This can sometime result in + // an error "OperationAbortedException: A conflicting operation is currently + // in progress...Please try again." + // To avoid an error, we do as requested and try again. + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.createLogGroup({ logGroupName }).promise(); + return; + } catch (error) { + if (error.code === 'ResourceAlreadyExistsException') { + // The log group is already created by the lambda execution + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} + +//delete a log group +async function deleteLogGroup(logGroupName: string, region?: string, options?: SdkRetryOptions) { + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.deleteLogGroup({ logGroupName }).promise(); + return; + } catch (error) { + if (error.code === 'ResourceNotFoundException') { + // The log group doesn't exist + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } else { + // The log group is still being deleted by another execution but we are out of retries + throw new Error('Out of attempts to delete a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} + +/** + * Puts or deletes a retention policy on a log group. + * + * @param logGroupName the name of the log group to create + * @param region the region of the log group + * @param options CloudWatch API SDK options. + * @param retentionInDays the number of days to retain the log events in the specified log group. + */ +async function setRetentionPolicy(logGroupName: string, region?: string, options?: SdkRetryOptions, retentionInDays?: number) { + // The same as in createLogGroupSafe(), here we could end up with the race + // condition where a log group is either already being created or its retention + // policy is being updated. This would result in an OperationAbortedException, + // which we will try to catch and retry the command a number of times before failing + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + if (!retentionInDays) { + await cloudwatchlogs.deleteRetentionPolicy({ logGroupName }).promise(); + } else { + await cloudwatchlogs.putRetentionPolicy({ logGroupName, retentionInDays }).promise(); + } + return; + + } catch (error) { + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} + +export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent, context: AWSLambda.Context) { + try { + console.log(JSON.stringify({ ...event, ResponseURL: '...' })); + + // The target log group + const logGroupName = event.ResourceProperties.LogGroupName; + + // The region of the target log group + const logGroupRegion = event.ResourceProperties.LogGroupRegion; + + // Parse to AWS SDK retry options + const retryOptions = parseRetryOptions(event.ResourceProperties.SdkRetry); + + if (event.RequestType === 'Create' || event.RequestType === 'Update') { + // Act on the target log group + await createLogGroupSafe(logGroupName, logGroupRegion, retryOptions); + await setRetentionPolicy(logGroupName, logGroupRegion, retryOptions, parseInt(event.ResourceProperties.RetentionInDays, 10)); + + if (event.RequestType === 'Create') { + // Set a retention policy of 1 day on the logs of this very function. + // Due to the async nature of the log group creation, the log group for this function might + // still be not created yet at this point. Therefore we attempt to create it. + // In case it is being created, createLogGroupSafe will handle the conflict. + const region = process.env.AWS_REGION; + await createLogGroupSafe(`/aws/lambda/${context.functionName}`, region, retryOptions); + // If createLogGroupSafe fails, the log group is not created even after multiple attempts. + // In this case we have nothing to set the retention policy on but an exception will skip + // the next line. + await setRetentionPolicy(`/aws/lambda/${context.functionName}`, region, retryOptions, 1); + } + } + + //When the requestType is delete, delete the log group if the removal policy is delete + if (event.RequestType === 'Delete' && event.ResourceProperties.RemovalPolicy === 'destroy') { + await deleteLogGroup(logGroupName, logGroupRegion, retryOptions); + //else retain the log group + } + + await respond('SUCCESS', 'OK', logGroupName); + } catch (e) { + console.log(e); + + await respond('FAILED', e.message, event.ResourceProperties.LogGroupName); + } + + function respond(responseStatus: string, reason: string, physicalResourceId: string) { + const responseBody = JSON.stringify({ + Status: responseStatus, + Reason: reason, + PhysicalResourceId: physicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: { + // Add log group name as part of the response so that it's available via Fn::GetAtt + LogGroupName: event.ResourceProperties.LogGroupName, + }, + }); + + console.log('Responding', responseBody); + + // eslint-disable-next-line @typescript-eslint/no-require-imports + const parsedUrl = require('url').parse(event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + + return new Promise((resolve, reject) => { + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const request = require('https').request(requestOptions, resolve); + request.on('error', reject); + request.write(responseBody); + request.end(); + } catch (e) { + reject(e); + } + }); + } + + function parseRetryOptions(rawOptions: any): SdkRetryOptions { + const retryOptions: SdkRetryOptions = {}; + if (rawOptions) { + if (rawOptions.maxRetries) { + retryOptions.maxRetries = parseInt(rawOptions.maxRetries, 10); + } + if (rawOptions.base) { + retryOptions.retryOptions = { + base: parseInt(rawOptions.base, 10), + }; + } + } + return retryOptions; + } +} diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/integ.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/integ.json new file mode 100644 index 0000000000000..46d61a98f2f47 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "21.0.0", + "testCases": { + "DependsOnTest/DefaultTest": { + "stacks": [ + "replace-depends-on-test", + "nested-stack-depends-test" + ], + "assertionStack": "DependsOnTest/DefaultTest/DeployAssert", + "assertionStackName": "DependsOnTestDefaultTestDeployAssert3B3B50E2" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/manifest.json new file mode 100644 index 0000000000000..158178cf68b01 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/manifest.json @@ -0,0 +1,224 @@ +{ + "version": "21.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "replace-depends-on-test.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "replace-depends-on-test.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "replace-depends-on-test": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "replace-depends-on-test.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/57d6494f80ed197e8ed81877d3521488a65bc202ee15ffb64f4e58eabff000af.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "replace-depends-on-test.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "replace-depends-on-test.assets" + ], + "metadata": { + "/replace-depends-on-test/MyLambda/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaServiceRole4539ECB6" + } + ], + "/replace-depends-on-test/MyLambda/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaCCE802FB" + } + ], + "/replace-depends-on-test/MyLambda/LogRetention/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaLogRetention48BA931C" + } + ], + "/replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ], + "/replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A" + } + ], + "/replace-depends-on-test/CustomPolicy": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomPolicy" + } + ], + "/replace-depends-on-test/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/replace-depends-on-test/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "replace-depends-on-test" + }, + "nested-stack-depends-test.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "nested-stack-depends-test.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "nested-stack-depends-test": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "nested-stack-depends-test.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c4e1a28f651cf56ff9d696ef9e4ce1c771896e999777d763e55f06b089b7c81a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "nested-stack-depends-test.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "nested-stack-depends-test.assets" + ], + "metadata": { + "/nested-stack-depends-test/Stack1/Lambda1/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda1ServiceRoleF188C4B8" + } + ], + "/nested-stack-depends-test/Stack1/Lambda1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda1DB8E9965" + } + ], + "/nested-stack-depends-test/Stack1.NestedStack/Stack1.NestedStackResource": [ + { + "type": "aws:cdk:logicalId", + "data": "Stack1NestedStackStack1NestedStackResource256CB8C4" + } + ], + "/nested-stack-depends-test/Stack2/Lambda2/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda2ServiceRole31A072E1" + } + ], + "/nested-stack-depends-test/Stack2/Lambda2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda217CFB423" + } + ], + "/nested-stack-depends-test/Stack2.NestedStack/Stack2.NestedStackResource": [ + { + "type": "aws:cdk:logicalId", + "data": "Stack2NestedStackStack2NestedStackResource9F0678CF" + } + ], + "/nested-stack-depends-test/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/nested-stack-depends-test/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "nested-stack-depends-test" + }, + "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "DependsOnTestDefaultTestDeployAssert3B3B50E2": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets" + ], + "metadata": { + "/DependsOnTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/DependsOnTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "DependsOnTest/DefaultTest/DeployAssert" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.assets.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.assets.json new file mode 100644 index 0000000000000..7f73a85d9077c --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.assets.json @@ -0,0 +1,45 @@ +{ + "version": "21.0.0", + "files": { + "d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2": { + "source": { + "path": "nestedstackdependstestStack1DE6783D8.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431": { + "source": { + "path": "nestedstackdependstestStack2A36722CF.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "c4e1a28f651cf56ff9d696ef9e4ce1c771896e999777d763e55f06b089b7c81a": { + "source": { + "path": "nested-stack-depends-test.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "c4e1a28f651cf56ff9d696ef9e4ce1c771896e999777d763e55f06b089b7c81a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.template.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.template.json new file mode 100644 index 0000000000000..cf6d4b0d46cee --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nested-stack-depends-test.template.json @@ -0,0 +1,95 @@ +{ + "Resources": { + "Stack1NestedStackStack1NestedStackResource256CB8C4": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2.json" + ] + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Stack2NestedStackStack2NestedStackResource9F0678CF": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431.json" + ] + ] + } + }, + "DependsOn": [ + "Stack1NestedStackStack1NestedStackResource256CB8C4" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json new file mode 100644 index 0000000000000..8b39a08a02151 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json @@ -0,0 +1,54 @@ +{ + "Resources": { + "Lambda1ServiceRoleF188C4B8": { + "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" + ] + ] + } + ] + } + }, + "Lambda1DB8E9965": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "Lambda1ServiceRoleF188C4B8", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "Lambda1ServiceRoleF188C4B8" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json new file mode 100644 index 0000000000000..d1b0202b0afc1 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json @@ -0,0 +1,54 @@ +{ + "Resources": { + "Lambda2ServiceRole31A072E1": { + "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" + ] + ] + } + ] + } + }, + "Lambda217CFB423": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "Lambda2ServiceRole31A072E1", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "Lambda2ServiceRole31A072E1" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.assets.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.assets.json new file mode 100644 index 0000000000000..e2083cbfc507f --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.assets.json @@ -0,0 +1,32 @@ +{ + "version": "21.0.0", + "files": { + "d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347": { + "source": { + "path": "asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "57d6494f80ed197e8ed81877d3521488a65bc202ee15ffb64f4e58eabff000af": { + "source": { + "path": "replace-depends-on-test.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "57d6494f80ed197e8ed81877d3521488a65bc202ee15ffb64f4e58eabff000af.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.template.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.template.json new file mode 100644 index 0000000000000..5574a9b261d30 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/replace-depends-on-test.template.json @@ -0,0 +1,188 @@ +{ + "Resources": { + "MyLambdaServiceRole4539ECB6": { + "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" + ] + ] + } + ] + } + }, + "MyLambdaCCE802FB": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "MyLambdaServiceRole4539ECB6", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyLambdaServiceRole4539ECB6" + ] + }, + "MyLambdaLogRetention48BA931C": { + "Type": "Custom::LogRetention", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A", + "Arn" + ] + }, + "LogGroupName": { + "Fn::Join": [ + "", + [ + "/aws/lambda/", + { + "Ref": "MyLambdaCCE802FB" + } + ] + ] + }, + "RetentionInDays": 1 + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB": { + "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" + ] + ] + } + ] + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Runtime": "nodejs14.x", + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347.zip" + }, + "Role": { + "Fn::GetAtt": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB", + "Arn" + ] + } + }, + "DependsOn": [ + "CustomPolicy", + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + ] + }, + "CustomPolicy": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:DeleteRetentionPolicy", + "logs:PutRetentionPolicy" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "Roles": [ + { + "Ref": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/tree.json b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/tree.json new file mode 100644 index 0000000000000..9b65fee29f707 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/core-deps.integ.snapshot/tree.json @@ -0,0 +1,582 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.129" + } + }, + "replace-depends-on-test": { + "id": "replace-depends-on-test", + "path": "replace-depends-on-test", + "children": { + "MyLambda": { + "id": "MyLambda", + "path": "replace-depends-on-test/MyLambda", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "replace-depends-on-test/MyLambda/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/MyLambda/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/MyLambda/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "MyLambdaServiceRole4539ECB6", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + }, + "LogRetention": { + "id": "LogRetention", + "path": "replace-depends-on-test/MyLambda/LogRetention", + "children": { + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/MyLambda/LogRetention/Resource", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-logs.LogRetention", + "version": "0.0.0" + } + }, + "LogGroup": { + "id": "LogGroup", + "path": "replace-depends-on-test/MyLambda/LogGroup", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a": { + "id": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a", + "children": { + "Code": { + "id": "Code", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "ServiceRole": { + "id": "ServiceRole", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Resource", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.129" + } + }, + "CustomPolicy": { + "id": "CustomPolicy", + "path": "replace-depends-on-test/CustomPolicy", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::ManagedPolicy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "logs:DeleteRetentionPolicy", + "logs:PutRetentionPolicy" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "roles": [ + { + "Ref": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnManagedPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "nested-stack-depends-test": { + "id": "nested-stack-depends-test", + "path": "nested-stack-depends-test", + "children": { + "Stack1": { + "id": "Stack1", + "path": "nested-stack-depends-test/Stack1", + "children": { + "Lambda1": { + "id": "Lambda1", + "path": "nested-stack-depends-test/Stack1/Lambda1", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "nested-stack-depends-test/Stack1/Lambda1/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack1/Lambda1/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack1/Lambda1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "Lambda1ServiceRoleF188C4B8", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.NestedStack", + "version": "0.0.0" + } + }, + "Stack1.NestedStack": { + "id": "Stack1.NestedStack", + "path": "nested-stack-depends-test/Stack1.NestedStack", + "children": { + "Stack1.NestedStackResource": { + "id": "Stack1.NestedStackResource", + "path": "nested-stack-depends-test/Stack1.NestedStack/Stack1.NestedStackResource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFormation::Stack", + "aws:cdk:cloudformation:props": { + "templateUrl": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2.json" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CfnStack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.129" + } + }, + "Stack2": { + "id": "Stack2", + "path": "nested-stack-depends-test/Stack2", + "children": { + "Lambda2": { + "id": "Lambda2", + "path": "nested-stack-depends-test/Stack2/Lambda2", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "nested-stack-depends-test/Stack2/Lambda2/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack2/Lambda2/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack2/Lambda2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "Lambda2ServiceRole31A072E1", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.NestedStack", + "version": "0.0.0" + } + }, + "Stack2.NestedStack": { + "id": "Stack2.NestedStack", + "path": "nested-stack-depends-test/Stack2.NestedStack", + "children": { + "Stack2.NestedStackResource": { + "id": "Stack2.NestedStackResource", + "path": "nested-stack-depends-test/Stack2.NestedStack/Stack2.NestedStackResource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFormation::Stack", + "aws:cdk:cloudformation:props": { + "templateUrl": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431.json" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CfnStack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.129" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "DependsOnTest": { + "id": "DependsOnTest", + "path": "DependsOnTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "DependsOnTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "DependsOnTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.129" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "DependsOnTest/DefaultTest/DeployAssert", + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/deps.test.ts b/packages/@aws-cdk/aws-cloudformation/test/deps.test.ts index 980f17ef6fcb9..0dbb1a9c5ec1b 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/deps.test.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/deps.test.ts @@ -15,7 +15,7 @@ describe('resource dependencies', () => { const r2 = new CfnResource(stack, 'r2', { type: 'r2' }); // WHEN - r1.addDependsOn(r2); + r1.addDependency(r2); // THEN expect(app.synth().getStackArtifact(stack.artifactId).template?.Resources).toEqual({ @@ -304,7 +304,7 @@ describe('stack dependencies', () => { * Given a test function which sets the stage and verifies a dependency scenario * between two CloudFormation resources, returns two tests which exercise both * "construct dependency" (i.e. node.addDependency) and "resource dependency" - * (i.e. resource.addDependsOn). + * (i.e. resource.addDependency). * * @param testFunction The test function */ @@ -314,7 +314,7 @@ function matrixForResourceDependencyTest(testFunction: (addDep: (source: CfnReso testFunction((source, target) => source.node.addDependency(target)); }); test('resource dependency', () => { - testFunction((source, target) => source.addDependsOn(target)); + testFunction((source, target) => source.addDependency(target)); }); }; } diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json new file mode 100644 index 0000000000000..a513dc6283811 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts new file mode 100644 index 0000000000000..9bbf5854684b6 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.d.ts @@ -0,0 +1 @@ +export declare function handler(event: AWSLambda.CloudFormationCustomResourceEvent, context: AWSLambda.Context): Promise; diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js new file mode 100644 index 0000000000000..d8d501f248a23 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.js @@ -0,0 +1,209 @@ +"use strict"; +/* eslint-disable no-console */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +// eslint-disable-next-line import/no-extraneous-dependencies +const AWS = require("aws-sdk"); +/** + * Creates a log group and doesn't throw if it exists. + * + * @param logGroupName the name of the log group to create. + * @param region to create the log group in + * @param options CloudWatch API SDK options. + */ +async function createLogGroupSafe(logGroupName, region, options) { + // If we set the log retention for a lambda, then due to the async nature of + // Lambda logging there could be a race condition when the same log group is + // already being created by the lambda execution. This can sometime result in + // an error "OperationAbortedException: A conflicting operation is currently + // in progress...Please try again." + // To avoid an error, we do as requested and try again. + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.createLogGroup({ logGroupName }).promise(); + return; + } + catch (error) { + if (error.code === 'ResourceAlreadyExistsException') { + // The log group is already created by the lambda execution + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } + else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} +//delete a log group +async function deleteLogGroup(logGroupName, region, options) { + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.deleteLogGroup({ logGroupName }).promise(); + return; + } + catch (error) { + if (error.code === 'ResourceNotFoundException') { + // The log group doesn't exist + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } + else { + // The log group is still being deleted by another execution but we are out of retries + throw new Error('Out of attempts to delete a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} +/** + * Puts or deletes a retention policy on a log group. + * + * @param logGroupName the name of the log group to create + * @param region the region of the log group + * @param options CloudWatch API SDK options. + * @param retentionInDays the number of days to retain the log events in the specified log group. + */ +async function setRetentionPolicy(logGroupName, region, options, retentionInDays) { + // The same as in createLogGroupSafe(), here we could end up with the race + // condition where a log group is either already being created or its retention + // policy is being updated. This would result in an OperationAbortedException, + // which we will try to catch and retry the command a number of times before failing + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + if (!retentionInDays) { + await cloudwatchlogs.deleteRetentionPolicy({ logGroupName }).promise(); + } + else { + await cloudwatchlogs.putRetentionPolicy({ logGroupName, retentionInDays }).promise(); + } + return; + } + catch (error) { + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } + else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} +async function handler(event, context) { + try { + console.log(JSON.stringify({ ...event, ResponseURL: '...' })); + // The target log group + const logGroupName = event.ResourceProperties.LogGroupName; + // The region of the target log group + const logGroupRegion = event.ResourceProperties.LogGroupRegion; + // Parse to AWS SDK retry options + const retryOptions = parseRetryOptions(event.ResourceProperties.SdkRetry); + if (event.RequestType === 'Create' || event.RequestType === 'Update') { + // Act on the target log group + await createLogGroupSafe(logGroupName, logGroupRegion, retryOptions); + await setRetentionPolicy(logGroupName, logGroupRegion, retryOptions, parseInt(event.ResourceProperties.RetentionInDays, 10)); + if (event.RequestType === 'Create') { + // Set a retention policy of 1 day on the logs of this very function. + // Due to the async nature of the log group creation, the log group for this function might + // still be not created yet at this point. Therefore we attempt to create it. + // In case it is being created, createLogGroupSafe will handle the conflict. + const region = process.env.AWS_REGION; + await createLogGroupSafe(`/aws/lambda/${context.functionName}`, region, retryOptions); + // If createLogGroupSafe fails, the log group is not created even after multiple attempts. + // In this case we have nothing to set the retention policy on but an exception will skip + // the next line. + await setRetentionPolicy(`/aws/lambda/${context.functionName}`, region, retryOptions, 1); + } + } + //When the requestType is delete, delete the log group if the removal policy is delete + if (event.RequestType === 'Delete' && event.ResourceProperties.RemovalPolicy === 'destroy') { + await deleteLogGroup(logGroupName, logGroupRegion, retryOptions); + //else retain the log group + } + await respond('SUCCESS', 'OK', logGroupName); + } + catch (e) { + console.log(e); + await respond('FAILED', e.message, event.ResourceProperties.LogGroupName); + } + function respond(responseStatus, reason, physicalResourceId) { + const responseBody = JSON.stringify({ + Status: responseStatus, + Reason: reason, + PhysicalResourceId: physicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: { + // Add log group name as part of the response so that it's available via Fn::GetAtt + LogGroupName: event.ResourceProperties.LogGroupName, + }, + }); + console.log('Responding', responseBody); + // eslint-disable-next-line @typescript-eslint/no-require-imports + const parsedUrl = require('url').parse(event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + return new Promise((resolve, reject) => { + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const request = require('https').request(requestOptions, resolve); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); + } + function parseRetryOptions(rawOptions) { + const retryOptions = {}; + if (rawOptions) { + if (rawOptions.maxRetries) { + retryOptions.maxRetries = parseInt(rawOptions.maxRetries, 10); + } + if (rawOptions.base) { + retryOptions.retryOptions = { + base: parseInt(rawOptions.base, 10), + }; + } + } + return retryOptions; + } +} +exports.handler = handler; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0JBQStCOzs7QUFFL0IsNkRBQTZEO0FBQzdELCtCQUErQjtBQVMvQjs7Ozs7O0dBTUc7QUFDSCxLQUFLLFVBQVUsa0JBQWtCLENBQUMsWUFBb0IsRUFBRSxNQUFlLEVBQUUsT0FBeUI7SUFDaEcsNEVBQTRFO0lBQzVFLDRFQUE0RTtJQUM1RSw2RUFBNkU7SUFDN0UsNEVBQTRFO0lBQzVFLG1DQUFtQztJQUNuQyx1REFBdUQ7SUFDdkQsSUFBSSxVQUFVLEdBQUcsT0FBTyxFQUFFLFVBQVUsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztJQUM1RSxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsWUFBWSxFQUFFLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDeEYsR0FBRztRQUNELElBQUk7WUFDRixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDaEcsTUFBTSxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNoRSxPQUFPO1NBQ1I7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxnQ0FBZ0MsRUFBRTtnQkFDbkQsMkRBQTJEO2dCQUMzRCxPQUFPO2FBQ1I7WUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssMkJBQTJCLEVBQUU7Z0JBQzlDLElBQUksVUFBVSxHQUFHLENBQUMsRUFBRTtvQkFDbEIsVUFBVSxFQUFFLENBQUM7b0JBQ2IsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDekQsU0FBUztpQkFDVjtxQkFBTTtvQkFDTCxzRkFBc0Y7b0JBQ3RGLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztpQkFDekQ7YUFDRjtZQUNELE1BQU0sS0FBSyxDQUFDO1NBQ2I7S0FDRixRQUFRLElBQUksRUFBRSxDQUFDLG9DQUFvQztBQUN0RCxDQUFDO0FBRUQsb0JBQW9CO0FBQ3BCLEtBQUssVUFBVSxjQUFjLENBQUMsWUFBb0IsRUFBRSxNQUFlLEVBQUUsT0FBeUI7SUFDNUYsSUFBSSxVQUFVLEdBQUcsT0FBTyxFQUFFLFVBQVUsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztJQUM1RSxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsWUFBWSxFQUFFLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDeEYsR0FBRztRQUNELElBQUk7WUFDRixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDaEcsTUFBTSxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNoRSxPQUFPO1NBQ1I7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLElBQUksS0FBSyxDQUFDLElBQUksS0FBSywyQkFBMkIsRUFBRTtnQkFDOUMsOEJBQThCO2dCQUM5QixPQUFPO2FBQ1I7WUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssMkJBQTJCLEVBQUU7Z0JBQzlDLElBQUksVUFBVSxHQUFHLENBQUMsRUFBRTtvQkFDbEIsVUFBVSxFQUFFLENBQUM7b0JBQ2IsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDekQsU0FBUztpQkFDVjtxQkFBTTtvQkFDTCxzRkFBc0Y7b0JBQ3RGLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztpQkFDekQ7YUFDRjtZQUNELE1BQU0sS0FBSyxDQUFDO1NBQ2I7S0FDRixRQUFRLElBQUksRUFBRSxDQUFDLG9DQUFvQztBQUN0RCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxZQUFvQixFQUFFLE1BQWUsRUFBRSxPQUF5QixFQUFFLGVBQXdCO0lBQzFILDBFQUEwRTtJQUMxRSwrRUFBK0U7SUFDL0UsOEVBQThFO0lBQzlFLG9GQUFvRjtJQUNwRixJQUFJLFVBQVUsR0FBRyxPQUFPLEVBQUUsVUFBVSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQzVFLE1BQU0sS0FBSyxHQUFHLE9BQU8sRUFBRSxZQUFZLEVBQUUsSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztJQUN4RixHQUFHO1FBQ0QsSUFBSTtZQUNGLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNoRyxJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUNwQixNQUFNLGNBQWMsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDeEU7aUJBQU07Z0JBQ0wsTUFBTSxjQUFjLENBQUMsa0JBQWtCLENBQUMsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUN0RjtZQUNELE9BQU87U0FFUjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLDJCQUEyQixFQUFFO2dCQUM5QyxJQUFJLFVBQVUsR0FBRyxDQUFDLEVBQUU7b0JBQ2xCLFVBQVUsRUFBRSxDQUFDO29CQUNiLE1BQU0sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQ3pELFNBQVM7aUJBQ1Y7cUJBQU07b0JBQ0wsc0ZBQXNGO29CQUN0RixNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7aUJBQ3pEO2FBQ0Y7WUFDRCxNQUFNLEtBQUssQ0FBQztTQUNiO0tBQ0YsUUFBUSxJQUFJLEVBQUUsQ0FBQyxvQ0FBb0M7QUFDdEQsQ0FBQztBQUVNLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBa0QsRUFBRSxPQUEwQjtJQUMxRyxJQUFJO1FBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUU5RCx1QkFBdUI7UUFDdkIsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQztRQUUzRCxxQ0FBcUM7UUFDckMsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQztRQUUvRCxpQ0FBaUM7UUFDakMsTUFBTSxZQUFZLEdBQUcsaUJBQWlCLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTFFLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUU7WUFDcEUsOEJBQThCO1lBQzlCLE1BQU0sa0JBQWtCLENBQUMsWUFBWSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNyRSxNQUFNLGtCQUFrQixDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFN0gsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEMscUVBQXFFO2dCQUNyRSwyRkFBMkY7Z0JBQzNGLDZFQUE2RTtnQkFDN0UsNEVBQTRFO2dCQUM1RSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztnQkFDdEMsTUFBTSxrQkFBa0IsQ0FBQyxlQUFlLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQ3RGLDBGQUEwRjtnQkFDMUYseUZBQXlGO2dCQUN6RixpQkFBaUI7Z0JBQ2pCLE1BQU0sa0JBQWtCLENBQUMsZUFBZSxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQzthQUMxRjtTQUNGO1FBRUQsc0ZBQXNGO1FBQ3RGLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDLGFBQWEsS0FBSyxTQUFTLEVBQUU7WUFDMUYsTUFBTSxjQUFjLENBQUMsWUFBWSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNqRSwyQkFBMkI7U0FDNUI7UUFFRCxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDO0tBQzlDO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWYsTUFBTSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDO0tBQzNFO0lBRUQsU0FBUyxPQUFPLENBQUMsY0FBc0IsRUFBRSxNQUFjLEVBQUUsa0JBQTBCO1FBQ2pGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDbEMsTUFBTSxFQUFFLGNBQWM7WUFDdEIsTUFBTSxFQUFFLE1BQU07WUFDZCxrQkFBa0IsRUFBRSxrQkFBa0I7WUFDdEMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztZQUMxQixpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO1lBQzFDLElBQUksRUFBRTtnQkFDSixtRkFBbUY7Z0JBQ25GLFlBQVksRUFBRSxLQUFLLENBQUMsa0JBQWtCLENBQUMsWUFBWTthQUNwRDtTQUNGLENBQUMsQ0FBQztRQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRXhDLGlFQUFpRTtRQUNqRSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxRCxNQUFNLGNBQWMsR0FBRztZQUNyQixRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7WUFDNUIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1lBQ3BCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFO1NBQ3ZFLENBQUM7UUFFRixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUk7Z0JBQ0YsaUVBQWlFO2dCQUNqRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUNmO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ1g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTLGlCQUFpQixDQUFDLFVBQWU7UUFDeEMsTUFBTSxZQUFZLEdBQW9CLEVBQUUsQ0FBQztRQUN6QyxJQUFJLFVBQVUsRUFBRTtZQUNkLElBQUksVUFBVSxDQUFDLFVBQVUsRUFBRTtnQkFDekIsWUFBWSxDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUMvRDtZQUNELElBQUksVUFBVSxDQUFDLElBQUksRUFBRTtnQkFDbkIsWUFBWSxDQUFDLFlBQVksR0FBRztvQkFDMUIsSUFBSSxFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztpQkFDcEMsQ0FBQzthQUNIO1NBQ0Y7UUFDRCxPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDO0FBQ0gsQ0FBQztBQWpHRCwwQkFpR0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcbmltcG9ydCAqIGFzIEFXUyBmcm9tICdhd3Mtc2RrJztcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcbmltcG9ydCB0eXBlIHsgUmV0cnlEZWxheU9wdGlvbnMgfSBmcm9tICdhd3Mtc2RrL2xpYi9jb25maWctYmFzZSc7XG5cbmludGVyZmFjZSBTZGtSZXRyeU9wdGlvbnMge1xuICBtYXhSZXRyaWVzPzogbnVtYmVyO1xuICByZXRyeU9wdGlvbnM/OiBSZXRyeURlbGF5T3B0aW9ucztcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbG9nIGdyb3VwIGFuZCBkb2Vzbid0IHRocm93IGlmIGl0IGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gbG9nR3JvdXBOYW1lIHRoZSBuYW1lIG9mIHRoZSBsb2cgZ3JvdXAgdG8gY3JlYXRlLlxuICogQHBhcmFtIHJlZ2lvbiB0byBjcmVhdGUgdGhlIGxvZyBncm91cCBpblxuICogQHBhcmFtIG9wdGlvbnMgQ2xvdWRXYXRjaCBBUEkgU0RLIG9wdGlvbnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUxvZ0dyb3VwU2FmZShsb2dHcm91cE5hbWU6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBvcHRpb25zPzogU2RrUmV0cnlPcHRpb25zKSB7XG4gIC8vIElmIHdlIHNldCB0aGUgbG9nIHJldGVudGlvbiBmb3IgYSBsYW1iZGEsIHRoZW4gZHVlIHRvIHRoZSBhc3luYyBuYXR1cmUgb2ZcbiAgLy8gTGFtYmRhIGxvZ2dpbmcgdGhlcmUgY291bGQgYmUgYSByYWNlIGNvbmRpdGlvbiB3aGVuIHRoZSBzYW1lIGxvZyBncm91cCBpc1xuICAvLyBhbHJlYWR5IGJlaW5nIGNyZWF0ZWQgYnkgdGhlIGxhbWJkYSBleGVjdXRpb24uIFRoaXMgY2FuIHNvbWV0aW1lIHJlc3VsdCBpblxuICAvLyBhbiBlcnJvciBcIk9wZXJhdGlvbkFib3J0ZWRFeGNlcHRpb246IEEgY29uZmxpY3Rpbmcgb3BlcmF0aW9uIGlzIGN1cnJlbnRseVxuICAvLyBpbiBwcm9ncmVzcy4uLlBsZWFzZSB0cnkgYWdhaW4uXCJcbiAgLy8gVG8gYXZvaWQgYW4gZXJyb3IsIHdlIGRvIGFzIHJlcXVlc3RlZCBhbmQgdHJ5IGFnYWluLlxuICBsZXQgcmV0cnlDb3VudCA9IG9wdGlvbnM/Lm1heFJldHJpZXMgPT0gdW5kZWZpbmVkID8gMTAgOiBvcHRpb25zLm1heFJldHJpZXM7XG4gIGNvbnN0IGRlbGF5ID0gb3B0aW9ucz8ucmV0cnlPcHRpb25zPy5iYXNlID09IHVuZGVmaW5lZCA/IDEwIDogb3B0aW9ucy5yZXRyeU9wdGlvbnMuYmFzZTtcbiAgZG8ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjbG91ZHdhdGNobG9ncyA9IG5ldyBBV1MuQ2xvdWRXYXRjaExvZ3MoeyBhcGlWZXJzaW9uOiAnMjAxNC0wMy0yOCcsIHJlZ2lvbiwgLi4ub3B0aW9ucyB9KTtcbiAgICAgIGF3YWl0IGNsb3Vkd2F0Y2hsb2dzLmNyZWF0ZUxvZ0dyb3VwKHsgbG9nR3JvdXBOYW1lIH0pLnByb21pc2UoKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT09ICdSZXNvdXJjZUFscmVhZHlFeGlzdHNFeGNlcHRpb24nKSB7XG4gICAgICAgIC8vIFRoZSBsb2cgZ3JvdXAgaXMgYWxyZWFkeSBjcmVhdGVkIGJ5IHRoZSBsYW1iZGEgZXhlY3V0aW9uXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvci5jb2RlID09PSAnT3BlcmF0aW9uQWJvcnRlZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgaWYgKHJldHJ5Q291bnQgPiAwKSB7XG4gICAgICAgICAgcmV0cnlDb3VudC0tO1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBkZWxheSkpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFRoZSBsb2cgZ3JvdXAgaXMgc3RpbGwgYmVpbmcgY3JlYXRlZCBieSBhbm90aGVyIGV4ZWN1dGlvbiBidXQgd2UgYXJlIG91dCBvZiByZXRyaWVzXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdPdXQgb2YgYXR0ZW1wdHMgdG8gY3JlYXRlIGEgbG9nR3JvdXAnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9IHdoaWxlICh0cnVlKTsgLy8gZXhpdCBoYXBwZW5zIG9uIHJldHJ5IGNvdW50IGNoZWNrXG59XG5cbi8vZGVsZXRlIGEgbG9nIGdyb3VwXG5hc3luYyBmdW5jdGlvbiBkZWxldGVMb2dHcm91cChsb2dHcm91cE5hbWU6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBvcHRpb25zPzogU2RrUmV0cnlPcHRpb25zKSB7XG4gIGxldCByZXRyeUNvdW50ID0gb3B0aW9ucz8ubWF4UmV0cmllcyA9PSB1bmRlZmluZWQgPyAxMCA6IG9wdGlvbnMubWF4UmV0cmllcztcbiAgY29uc3QgZGVsYXkgPSBvcHRpb25zPy5yZXRyeU9wdGlvbnM/LmJhc2UgPT0gdW5kZWZpbmVkID8gMTAgOiBvcHRpb25zLnJldHJ5T3B0aW9ucy5iYXNlO1xuICBkbyB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNsb3Vkd2F0Y2hsb2dzID0gbmV3IEFXUy5DbG91ZFdhdGNoTG9ncyh7IGFwaVZlcnNpb246ICcyMDE0LTAzLTI4JywgcmVnaW9uLCAuLi5vcHRpb25zIH0pO1xuICAgICAgYXdhaXQgY2xvdWR3YXRjaGxvZ3MuZGVsZXRlTG9nR3JvdXAoeyBsb2dHcm91cE5hbWUgfSkucHJvbWlzZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24nKSB7XG4gICAgICAgIC8vIFRoZSBsb2cgZ3JvdXAgZG9lc24ndCBleGlzdFxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ09wZXJhdGlvbkFib3J0ZWRFeGNlcHRpb24nKSB7XG4gICAgICAgIGlmIChyZXRyeUNvdW50ID4gMCkge1xuICAgICAgICAgIHJldHJ5Q291bnQtLTtcbiAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgZGVsYXkpKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBUaGUgbG9nIGdyb3VwIGlzIHN0aWxsIGJlaW5nIGRlbGV0ZWQgYnkgYW5vdGhlciBleGVjdXRpb24gYnV0IHdlIGFyZSBvdXQgb2YgcmV0cmllc1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignT3V0IG9mIGF0dGVtcHRzIHRvIGRlbGV0ZSBhIGxvZ0dyb3VwJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfSB3aGlsZSAodHJ1ZSk7IC8vIGV4aXQgaGFwcGVucyBvbiByZXRyeSBjb3VudCBjaGVja1xufVxuXG4vKipcbiAqIFB1dHMgb3IgZGVsZXRlcyBhIHJldGVudGlvbiBwb2xpY3kgb24gYSBsb2cgZ3JvdXAuXG4gKlxuICogQHBhcmFtIGxvZ0dyb3VwTmFtZSB0aGUgbmFtZSBvZiB0aGUgbG9nIGdyb3VwIHRvIGNyZWF0ZVxuICogQHBhcmFtIHJlZ2lvbiB0aGUgcmVnaW9uIG9mIHRoZSBsb2cgZ3JvdXBcbiAqIEBwYXJhbSBvcHRpb25zIENsb3VkV2F0Y2ggQVBJIFNESyBvcHRpb25zLlxuICogQHBhcmFtIHJldGVudGlvbkluRGF5cyB0aGUgbnVtYmVyIG9mIGRheXMgdG8gcmV0YWluIHRoZSBsb2cgZXZlbnRzIGluIHRoZSBzcGVjaWZpZWQgbG9nIGdyb3VwLlxuICovXG5hc3luYyBmdW5jdGlvbiBzZXRSZXRlbnRpb25Qb2xpY3kobG9nR3JvdXBOYW1lOiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgb3B0aW9ucz86IFNka1JldHJ5T3B0aW9ucywgcmV0ZW50aW9uSW5EYXlzPzogbnVtYmVyKSB7XG4gIC8vIFRoZSBzYW1lIGFzIGluIGNyZWF0ZUxvZ0dyb3VwU2FmZSgpLCBoZXJlIHdlIGNvdWxkIGVuZCB1cCB3aXRoIHRoZSByYWNlXG4gIC8vIGNvbmRpdGlvbiB3aGVyZSBhIGxvZyBncm91cCBpcyBlaXRoZXIgYWxyZWFkeSBiZWluZyBjcmVhdGVkIG9yIGl0cyByZXRlbnRpb25cbiAgLy8gcG9saWN5IGlzIGJlaW5nIHVwZGF0ZWQuIFRoaXMgd291bGQgcmVzdWx0IGluIGFuIE9wZXJhdGlvbkFib3J0ZWRFeGNlcHRpb24sXG4gIC8vIHdoaWNoIHdlIHdpbGwgdHJ5IHRvIGNhdGNoIGFuZCByZXRyeSB0aGUgY29tbWFuZCBhIG51bWJlciBvZiB0aW1lcyBiZWZvcmUgZmFpbGluZ1xuICBsZXQgcmV0cnlDb3VudCA9IG9wdGlvbnM/Lm1heFJldHJpZXMgPT0gdW5kZWZpbmVkID8gMTAgOiBvcHRpb25zLm1heFJldHJpZXM7XG4gIGNvbnN0IGRlbGF5ID0gb3B0aW9ucz8ucmV0cnlPcHRpb25zPy5iYXNlID09IHVuZGVmaW5lZCA/IDEwIDogb3B0aW9ucy5yZXRyeU9wdGlvbnMuYmFzZTtcbiAgZG8ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjbG91ZHdhdGNobG9ncyA9IG5ldyBBV1MuQ2xvdWRXYXRjaExvZ3MoeyBhcGlWZXJzaW9uOiAnMjAxNC0wMy0yOCcsIHJlZ2lvbiwgLi4ub3B0aW9ucyB9KTtcbiAgICAgIGlmICghcmV0ZW50aW9uSW5EYXlzKSB7XG4gICAgICAgIGF3YWl0IGNsb3Vkd2F0Y2hsb2dzLmRlbGV0ZVJldGVudGlvblBvbGljeSh7IGxvZ0dyb3VwTmFtZSB9KS5wcm9taXNlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBjbG91ZHdhdGNobG9ncy5wdXRSZXRlbnRpb25Qb2xpY3koeyBsb2dHcm91cE5hbWUsIHJldGVudGlvbkluRGF5cyB9KS5wcm9taXNlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG5cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT09ICdPcGVyYXRpb25BYm9ydGVkRXhjZXB0aW9uJykge1xuICAgICAgICBpZiAocmV0cnlDb3VudCA+IDApIHtcbiAgICAgICAgICByZXRyeUNvdW50LS07XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGRlbGF5KSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhlIGxvZyBncm91cCBpcyBzdGlsbCBiZWluZyBjcmVhdGVkIGJ5IGFub3RoZXIgZXhlY3V0aW9uIGJ1dCB3ZSBhcmUgb3V0IG9mIHJldHJpZXNcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ091dCBvZiBhdHRlbXB0cyB0byBjcmVhdGUgYSBsb2dHcm91cCcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH0gd2hpbGUgKHRydWUpOyAvLyBleGl0IGhhcHBlbnMgb24gcmV0cnkgY291bnQgY2hlY2tcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIHRyeSB7XG4gICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoeyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH0pKTtcblxuICAgIC8vIFRoZSB0YXJnZXQgbG9nIGdyb3VwXG4gICAgY29uc3QgbG9nR3JvdXBOYW1lID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkxvZ0dyb3VwTmFtZTtcblxuICAgIC8vIFRoZSByZWdpb24gb2YgdGhlIHRhcmdldCBsb2cgZ3JvdXBcbiAgICBjb25zdCBsb2dHcm91cFJlZ2lvbiA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Mb2dHcm91cFJlZ2lvbjtcblxuICAgIC8vIFBhcnNlIHRvIEFXUyBTREsgcmV0cnkgb3B0aW9uc1xuICAgIGNvbnN0IHJldHJ5T3B0aW9ucyA9IHBhcnNlUmV0cnlPcHRpb25zKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5TZGtSZXRyeSk7XG5cbiAgICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdDcmVhdGUnIHx8IGV2ZW50LlJlcXVlc3RUeXBlID09PSAnVXBkYXRlJykge1xuICAgICAgLy8gQWN0IG9uIHRoZSB0YXJnZXQgbG9nIGdyb3VwXG4gICAgICBhd2FpdCBjcmVhdGVMb2dHcm91cFNhZmUobG9nR3JvdXBOYW1lLCBsb2dHcm91cFJlZ2lvbiwgcmV0cnlPcHRpb25zKTtcbiAgICAgIGF3YWl0IHNldFJldGVudGlvblBvbGljeShsb2dHcm91cE5hbWUsIGxvZ0dyb3VwUmVnaW9uLCByZXRyeU9wdGlvbnMsIHBhcnNlSW50KGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5SZXRlbnRpb25JbkRheXMsIDEwKSk7XG5cbiAgICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICAgICAgLy8gU2V0IGEgcmV0ZW50aW9uIHBvbGljeSBvZiAxIGRheSBvbiB0aGUgbG9ncyBvZiB0aGlzIHZlcnkgZnVuY3Rpb24uXG4gICAgICAgIC8vIER1ZSB0byB0aGUgYXN5bmMgbmF0dXJlIG9mIHRoZSBsb2cgZ3JvdXAgY3JlYXRpb24sIHRoZSBsb2cgZ3JvdXAgZm9yIHRoaXMgZnVuY3Rpb24gbWlnaHRcbiAgICAgICAgLy8gc3RpbGwgYmUgbm90IGNyZWF0ZWQgeWV0IGF0IHRoaXMgcG9pbnQuIFRoZXJlZm9yZSB3ZSBhdHRlbXB0IHRvIGNyZWF0ZSBpdC5cbiAgICAgICAgLy8gSW4gY2FzZSBpdCBpcyBiZWluZyBjcmVhdGVkLCBjcmVhdGVMb2dHcm91cFNhZmUgd2lsbCBoYW5kbGUgdGhlIGNvbmZsaWN0LlxuICAgICAgICBjb25zdCByZWdpb24gPSBwcm9jZXNzLmVudi5BV1NfUkVHSU9OO1xuICAgICAgICBhd2FpdCBjcmVhdGVMb2dHcm91cFNhZmUoYC9hd3MvbGFtYmRhLyR7Y29udGV4dC5mdW5jdGlvbk5hbWV9YCwgcmVnaW9uLCByZXRyeU9wdGlvbnMpO1xuICAgICAgICAvLyBJZiBjcmVhdGVMb2dHcm91cFNhZmUgZmFpbHMsIHRoZSBsb2cgZ3JvdXAgaXMgbm90IGNyZWF0ZWQgZXZlbiBhZnRlciBtdWx0aXBsZSBhdHRlbXB0cy5cbiAgICAgICAgLy8gSW4gdGhpcyBjYXNlIHdlIGhhdmUgbm90aGluZyB0byBzZXQgdGhlIHJldGVudGlvbiBwb2xpY3kgb24gYnV0IGFuIGV4Y2VwdGlvbiB3aWxsIHNraXBcbiAgICAgICAgLy8gdGhlIG5leHQgbGluZS5cbiAgICAgICAgYXdhaXQgc2V0UmV0ZW50aW9uUG9saWN5KGAvYXdzL2xhbWJkYS8ke2NvbnRleHQuZnVuY3Rpb25OYW1lfWAsIHJlZ2lvbiwgcmV0cnlPcHRpb25zLCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvL1doZW4gdGhlIHJlcXVlc3RUeXBlIGlzIGRlbGV0ZSwgZGVsZXRlIHRoZSBsb2cgZ3JvdXAgaWYgdGhlIHJlbW92YWwgcG9saWN5IGlzIGRlbGV0ZVxuICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScgJiYgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLlJlbW92YWxQb2xpY3kgPT09ICdkZXN0cm95Jykge1xuICAgICAgYXdhaXQgZGVsZXRlTG9nR3JvdXAobG9nR3JvdXBOYW1lLCBsb2dHcm91cFJlZ2lvbiwgcmV0cnlPcHRpb25zKTtcbiAgICAgIC8vZWxzZSByZXRhaW4gdGhlIGxvZyBncm91cFxuICAgIH1cblxuICAgIGF3YWl0IHJlc3BvbmQoJ1NVQ0NFU1MnLCAnT0snLCBsb2dHcm91cE5hbWUpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5sb2coZSk7XG5cbiAgICBhd2FpdCByZXNwb25kKCdGQUlMRUQnLCBlLm1lc3NhZ2UsIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Mb2dHcm91cE5hbWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzcG9uZChyZXNwb25zZVN0YXR1czogc3RyaW5nLCByZWFzb246IHN0cmluZywgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBTdGF0dXM6IHJlc3BvbnNlU3RhdHVzLFxuICAgICAgUmVhc29uOiByZWFzb24sXG4gICAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCxcbiAgICAgIERhdGE6IHtcbiAgICAgICAgLy8gQWRkIGxvZyBncm91cCBuYW1lIGFzIHBhcnQgb2YgdGhlIHJlc3BvbnNlIHNvIHRoYXQgaXQncyBhdmFpbGFibGUgdmlhIEZuOjpHZXRBdHRcbiAgICAgICAgTG9nR3JvdXBOYW1lOiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuTG9nR3JvdXBOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKCdSZXNwb25kaW5nJywgcmVzcG9uc2VCb2R5KTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgcGFyc2VkVXJsID0gcmVxdWlyZSgndXJsJykucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgICAgbWV0aG9kOiAnUFVUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnaHR0cHMnKS5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCByZXNvbHZlKTtcbiAgICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlUmV0cnlPcHRpb25zKHJhd09wdGlvbnM6IGFueSk6IFNka1JldHJ5T3B0aW9ucyB7XG4gICAgY29uc3QgcmV0cnlPcHRpb25zOiBTZGtSZXRyeU9wdGlvbnMgPSB7fTtcbiAgICBpZiAocmF3T3B0aW9ucykge1xuICAgICAgaWYgKHJhd09wdGlvbnMubWF4UmV0cmllcykge1xuICAgICAgICByZXRyeU9wdGlvbnMubWF4UmV0cmllcyA9IHBhcnNlSW50KHJhd09wdGlvbnMubWF4UmV0cmllcywgMTApO1xuICAgICAgfVxuICAgICAgaWYgKHJhd09wdGlvbnMuYmFzZSkge1xuICAgICAgICByZXRyeU9wdGlvbnMucmV0cnlPcHRpb25zID0ge1xuICAgICAgICAgIGJhc2U6IHBhcnNlSW50KHJhd09wdGlvbnMuYmFzZSwgMTApLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0cnlPcHRpb25zO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts new file mode 100644 index 0000000000000..1bb38a9f3d774 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347/index.ts @@ -0,0 +1,221 @@ +/* eslint-disable no-console */ + +// eslint-disable-next-line import/no-extraneous-dependencies +import * as AWS from 'aws-sdk'; +// eslint-disable-next-line import/no-extraneous-dependencies +import type { RetryDelayOptions } from 'aws-sdk/lib/config-base'; + +interface SdkRetryOptions { + maxRetries?: number; + retryOptions?: RetryDelayOptions; +} + +/** + * Creates a log group and doesn't throw if it exists. + * + * @param logGroupName the name of the log group to create. + * @param region to create the log group in + * @param options CloudWatch API SDK options. + */ +async function createLogGroupSafe(logGroupName: string, region?: string, options?: SdkRetryOptions) { + // If we set the log retention for a lambda, then due to the async nature of + // Lambda logging there could be a race condition when the same log group is + // already being created by the lambda execution. This can sometime result in + // an error "OperationAbortedException: A conflicting operation is currently + // in progress...Please try again." + // To avoid an error, we do as requested and try again. + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.createLogGroup({ logGroupName }).promise(); + return; + } catch (error) { + if (error.code === 'ResourceAlreadyExistsException') { + // The log group is already created by the lambda execution + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} + +//delete a log group +async function deleteLogGroup(logGroupName: string, region?: string, options?: SdkRetryOptions) { + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + await cloudwatchlogs.deleteLogGroup({ logGroupName }).promise(); + return; + } catch (error) { + if (error.code === 'ResourceNotFoundException') { + // The log group doesn't exist + return; + } + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } else { + // The log group is still being deleted by another execution but we are out of retries + throw new Error('Out of attempts to delete a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} + +/** + * Puts or deletes a retention policy on a log group. + * + * @param logGroupName the name of the log group to create + * @param region the region of the log group + * @param options CloudWatch API SDK options. + * @param retentionInDays the number of days to retain the log events in the specified log group. + */ +async function setRetentionPolicy(logGroupName: string, region?: string, options?: SdkRetryOptions, retentionInDays?: number) { + // The same as in createLogGroupSafe(), here we could end up with the race + // condition where a log group is either already being created or its retention + // policy is being updated. This would result in an OperationAbortedException, + // which we will try to catch and retry the command a number of times before failing + let retryCount = options?.maxRetries == undefined ? 10 : options.maxRetries; + const delay = options?.retryOptions?.base == undefined ? 10 : options.retryOptions.base; + do { + try { + const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28', region, ...options }); + if (!retentionInDays) { + await cloudwatchlogs.deleteRetentionPolicy({ logGroupName }).promise(); + } else { + await cloudwatchlogs.putRetentionPolicy({ logGroupName, retentionInDays }).promise(); + } + return; + + } catch (error) { + if (error.code === 'OperationAbortedException') { + if (retryCount > 0) { + retryCount--; + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } else { + // The log group is still being created by another execution but we are out of retries + throw new Error('Out of attempts to create a logGroup'); + } + } + throw error; + } + } while (true); // exit happens on retry count check +} + +export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent, context: AWSLambda.Context) { + try { + console.log(JSON.stringify({ ...event, ResponseURL: '...' })); + + // The target log group + const logGroupName = event.ResourceProperties.LogGroupName; + + // The region of the target log group + const logGroupRegion = event.ResourceProperties.LogGroupRegion; + + // Parse to AWS SDK retry options + const retryOptions = parseRetryOptions(event.ResourceProperties.SdkRetry); + + if (event.RequestType === 'Create' || event.RequestType === 'Update') { + // Act on the target log group + await createLogGroupSafe(logGroupName, logGroupRegion, retryOptions); + await setRetentionPolicy(logGroupName, logGroupRegion, retryOptions, parseInt(event.ResourceProperties.RetentionInDays, 10)); + + if (event.RequestType === 'Create') { + // Set a retention policy of 1 day on the logs of this very function. + // Due to the async nature of the log group creation, the log group for this function might + // still be not created yet at this point. Therefore we attempt to create it. + // In case it is being created, createLogGroupSafe will handle the conflict. + const region = process.env.AWS_REGION; + await createLogGroupSafe(`/aws/lambda/${context.functionName}`, region, retryOptions); + // If createLogGroupSafe fails, the log group is not created even after multiple attempts. + // In this case we have nothing to set the retention policy on but an exception will skip + // the next line. + await setRetentionPolicy(`/aws/lambda/${context.functionName}`, region, retryOptions, 1); + } + } + + //When the requestType is delete, delete the log group if the removal policy is delete + if (event.RequestType === 'Delete' && event.ResourceProperties.RemovalPolicy === 'destroy') { + await deleteLogGroup(logGroupName, logGroupRegion, retryOptions); + //else retain the log group + } + + await respond('SUCCESS', 'OK', logGroupName); + } catch (e) { + console.log(e); + + await respond('FAILED', e.message, event.ResourceProperties.LogGroupName); + } + + function respond(responseStatus: string, reason: string, physicalResourceId: string) { + const responseBody = JSON.stringify({ + Status: responseStatus, + Reason: reason, + PhysicalResourceId: physicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: { + // Add log group name as part of the response so that it's available via Fn::GetAtt + LogGroupName: event.ResourceProperties.LogGroupName, + }, + }); + + console.log('Responding', responseBody); + + // eslint-disable-next-line @typescript-eslint/no-require-imports + const parsedUrl = require('url').parse(event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + + return new Promise((resolve, reject) => { + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const request = require('https').request(requestOptions, resolve); + request.on('error', reject); + request.write(responseBody); + request.end(); + } catch (e) { + reject(e); + } + }); + } + + function parseRetryOptions(rawOptions: any): SdkRetryOptions { + const retryOptions: SdkRetryOptions = {}; + if (rawOptions) { + if (rawOptions.maxRetries) { + retryOptions.maxRetries = parseInt(rawOptions.maxRetries, 10); + } + if (rawOptions.base) { + retryOptions.retryOptions = { + base: parseInt(rawOptions.base, 10), + }; + } + } + return retryOptions; + } +} diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/integ.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/integ.json new file mode 100644 index 0000000000000..46d61a98f2f47 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "21.0.0", + "testCases": { + "DependsOnTest/DefaultTest": { + "stacks": [ + "replace-depends-on-test", + "nested-stack-depends-test" + ], + "assertionStack": "DependsOnTest/DefaultTest/DeployAssert", + "assertionStackName": "DependsOnTestDefaultTestDeployAssert3B3B50E2" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/manifest.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/manifest.json new file mode 100644 index 0000000000000..f546ab43d55c3 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/manifest.json @@ -0,0 +1,224 @@ +{ + "version": "21.0.0", + "artifacts": { + "replace-depends-on-test.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "replace-depends-on-test.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "replace-depends-on-test": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "replace-depends-on-test.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/57d6494f80ed197e8ed81877d3521488a65bc202ee15ffb64f4e58eabff000af.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "replace-depends-on-test.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "replace-depends-on-test.assets" + ], + "metadata": { + "/replace-depends-on-test/MyLambda/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaServiceRole4539ECB6" + } + ], + "/replace-depends-on-test/MyLambda/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaCCE802FB" + } + ], + "/replace-depends-on-test/MyLambda/LogRetention/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaLogRetention48BA931C" + } + ], + "/replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ], + "/replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A" + } + ], + "/replace-depends-on-test/CustomPolicy": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomPolicy" + } + ], + "/replace-depends-on-test/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/replace-depends-on-test/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "replace-depends-on-test" + }, + "nested-stack-depends-test.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "nested-stack-depends-test.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "nested-stack-depends-test": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "nested-stack-depends-test.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c4e1a28f651cf56ff9d696ef9e4ce1c771896e999777d763e55f06b089b7c81a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "nested-stack-depends-test.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "nested-stack-depends-test.assets" + ], + "metadata": { + "/nested-stack-depends-test/Stack1/Lambda1/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda1ServiceRoleF188C4B8" + } + ], + "/nested-stack-depends-test/Stack1/Lambda1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda1DB8E9965" + } + ], + "/nested-stack-depends-test/Stack1.NestedStack/Stack1.NestedStackResource": [ + { + "type": "aws:cdk:logicalId", + "data": "Stack1NestedStackStack1NestedStackResource256CB8C4" + } + ], + "/nested-stack-depends-test/Stack2/Lambda2/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda2ServiceRole31A072E1" + } + ], + "/nested-stack-depends-test/Stack2/Lambda2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Lambda217CFB423" + } + ], + "/nested-stack-depends-test/Stack2.NestedStack/Stack2.NestedStackResource": [ + { + "type": "aws:cdk:logicalId", + "data": "Stack2NestedStackStack2NestedStackResource9F0678CF" + } + ], + "/nested-stack-depends-test/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/nested-stack-depends-test/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "nested-stack-depends-test" + }, + "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "DependsOnTestDefaultTestDeployAssert3B3B50E2": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "DependsOnTestDefaultTestDeployAssert3B3B50E2.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "DependsOnTestDefaultTestDeployAssert3B3B50E2.assets" + ], + "metadata": { + "/DependsOnTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/DependsOnTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "DependsOnTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.assets.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.assets.json new file mode 100644 index 0000000000000..7f73a85d9077c --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.assets.json @@ -0,0 +1,45 @@ +{ + "version": "21.0.0", + "files": { + "d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2": { + "source": { + "path": "nestedstackdependstestStack1DE6783D8.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431": { + "source": { + "path": "nestedstackdependstestStack2A36722CF.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "c4e1a28f651cf56ff9d696ef9e4ce1c771896e999777d763e55f06b089b7c81a": { + "source": { + "path": "nested-stack-depends-test.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "c4e1a28f651cf56ff9d696ef9e4ce1c771896e999777d763e55f06b089b7c81a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.template.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.template.json new file mode 100644 index 0000000000000..cf6d4b0d46cee --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nested-stack-depends-test.template.json @@ -0,0 +1,95 @@ +{ + "Resources": { + "Stack1NestedStackStack1NestedStackResource256CB8C4": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2.json" + ] + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Stack2NestedStackStack2NestedStackResource9F0678CF": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431.json" + ] + ] + } + }, + "DependsOn": [ + "Stack1NestedStackStack1NestedStackResource256CB8C4" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json new file mode 100644 index 0000000000000..8b39a08a02151 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack1DE6783D8.nested.template.json @@ -0,0 +1,54 @@ +{ + "Resources": { + "Lambda1ServiceRoleF188C4B8": { + "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" + ] + ] + } + ] + } + }, + "Lambda1DB8E9965": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "Lambda1ServiceRoleF188C4B8", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "Lambda1ServiceRoleF188C4B8" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json new file mode 100644 index 0000000000000..d1b0202b0afc1 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/nestedstackdependstestStack2A36722CF.nested.template.json @@ -0,0 +1,54 @@ +{ + "Resources": { + "Lambda2ServiceRole31A072E1": { + "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" + ] + ] + } + ] + } + }, + "Lambda217CFB423": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "Lambda2ServiceRole31A072E1", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "Lambda2ServiceRole31A072E1" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.assets.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.assets.json new file mode 100644 index 0000000000000..e2083cbfc507f --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.assets.json @@ -0,0 +1,32 @@ +{ + "version": "21.0.0", + "files": { + "d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347": { + "source": { + "path": "asset.d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "57d6494f80ed197e8ed81877d3521488a65bc202ee15ffb64f4e58eabff000af": { + "source": { + "path": "replace-depends-on-test.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "57d6494f80ed197e8ed81877d3521488a65bc202ee15ffb64f4e58eabff000af.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.template.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.template.json new file mode 100644 index 0000000000000..5574a9b261d30 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/replace-depends-on-test.template.json @@ -0,0 +1,188 @@ +{ + "Resources": { + "MyLambdaServiceRole4539ECB6": { + "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" + ] + ] + } + ] + } + }, + "MyLambdaCCE802FB": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "MyLambdaServiceRole4539ECB6", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyLambdaServiceRole4539ECB6" + ] + }, + "MyLambdaLogRetention48BA931C": { + "Type": "Custom::LogRetention", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A", + "Arn" + ] + }, + "LogGroupName": { + "Fn::Join": [ + "", + [ + "/aws/lambda/", + { + "Ref": "MyLambdaCCE802FB" + } + ] + ] + }, + "RetentionInDays": 1 + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB": { + "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" + ] + ] + } + ] + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Runtime": "nodejs14.x", + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "d01c24641c7d8cb6488393ffceaefff282370a9a522bf9d77b21da73fa257347.zip" + }, + "Role": { + "Fn::GetAtt": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB", + "Arn" + ] + } + }, + "DependsOn": [ + "CustomPolicy", + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + ] + }, + "CustomPolicy": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:DeleteRetentionPolicy", + "logs:PutRetentionPolicy" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "Roles": [ + { + "Ref": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/tree.json b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/tree.json new file mode 100644 index 0000000000000..45159d69f419f --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.js.snapshot/tree.json @@ -0,0 +1,664 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "replace-depends-on-test": { + "id": "replace-depends-on-test", + "path": "replace-depends-on-test", + "children": { + "MyLambda": { + "id": "MyLambda", + "path": "replace-depends-on-test/MyLambda", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "replace-depends-on-test/MyLambda/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "replace-depends-on-test/MyLambda/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/MyLambda/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/MyLambda/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "MyLambdaServiceRole4539ECB6", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + }, + "LogRetention": { + "id": "LogRetention", + "path": "replace-depends-on-test/MyLambda/LogRetention", + "children": { + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/MyLambda/LogRetention/Resource", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-logs.LogRetention", + "version": "0.0.0" + } + }, + "LogGroup": { + "id": "LogGroup", + "path": "replace-depends-on-test/MyLambda/LogGroup", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a": { + "id": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a", + "children": { + "Code": { + "id": "Code", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "ServiceRole": { + "id": "ServiceRole", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "replace-depends-on-test/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Resource", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "CustomPolicy": { + "id": "CustomPolicy", + "path": "replace-depends-on-test/CustomPolicy", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::ManagedPolicy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "logs:DeleteRetentionPolicy", + "logs:PutRetentionPolicy" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "roles": [ + { + "Ref": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnManagedPolicy", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "replace-depends-on-test/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "replace-depends-on-test/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "nested-stack-depends-test": { + "id": "nested-stack-depends-test", + "path": "nested-stack-depends-test", + "children": { + "Stack1": { + "id": "Stack1", + "path": "nested-stack-depends-test/Stack1", + "children": { + "Lambda1": { + "id": "Lambda1", + "path": "nested-stack-depends-test/Stack1/Lambda1", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "nested-stack-depends-test/Stack1/Lambda1/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "nested-stack-depends-test/Stack1/Lambda1/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack1/Lambda1/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack1/Lambda1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "Lambda1ServiceRoleF188C4B8", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.NestedStack", + "version": "0.0.0" + } + }, + "Stack1.NestedStack": { + "id": "Stack1.NestedStack", + "path": "nested-stack-depends-test/Stack1.NestedStack", + "children": { + "Stack1.NestedStackResource": { + "id": "Stack1.NestedStackResource", + "path": "nested-stack-depends-test/Stack1.NestedStack/Stack1.NestedStackResource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFormation::Stack", + "aws:cdk:cloudformation:props": { + "templateUrl": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/d80f241007964c163f30b1e491fb22d85422a376901bdf57f34ef94d71dcf4a2.json" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CfnStack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "Stack2": { + "id": "Stack2", + "path": "nested-stack-depends-test/Stack2", + "children": { + "Lambda2": { + "id": "Lambda2", + "path": "nested-stack-depends-test/Stack2/Lambda2", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "nested-stack-depends-test/Stack2/Lambda2/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "nested-stack-depends-test/Stack2/Lambda2/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack2/Lambda2/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "nested-stack-depends-test/Stack2/Lambda2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "Lambda2ServiceRole31A072E1", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.NestedStack", + "version": "0.0.0" + } + }, + "Stack2.NestedStack": { + "id": "Stack2.NestedStack", + "path": "nested-stack-depends-test/Stack2.NestedStack", + "children": { + "Stack2.NestedStackResource": { + "id": "Stack2.NestedStackResource", + "path": "nested-stack-depends-test/Stack2.NestedStack/Stack2.NestedStackResource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFormation::Stack", + "aws:cdk:cloudformation:props": { + "templateUrl": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/caff9f6719171b7d0611de54f70e0ef42e8e4f56432babf0d4beae6cb8bba431.json" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CfnStack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "nested-stack-depends-test/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "nested-stack-depends-test/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "DependsOnTest": { + "id": "DependsOnTest", + "path": "DependsOnTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "DependsOnTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "DependsOnTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "DependsOnTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "DependsOnTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "DependsOnTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.ts new file mode 100644 index 0000000000000..b8ea66419e9cc --- /dev/null +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.core-deps.ts @@ -0,0 +1,74 @@ +/* + * Real replaceDependency use case to test + * + * TestStack verification steps: + * - Deploy with `--no-clean` + * - Verify that the CloudFormation stack LogRetention CfnResource dependencies list CustomPolicy, not DefaultPolicy + * + * TestNestedStack verification steps: + * - Deploy with `--no-clean` + * - Verify that Stack2 lists Stack1 in DependsOn + */ +import * as iam from '@aws-cdk/aws-iam'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { RetentionDays } from '@aws-cdk/aws-logs'; +import { App, Stack, CfnResource, NestedStack } from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; +import { Construct } from 'constructs'; + +class TestStack extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + new lambda.Function(this, 'MyLambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_14_X, + logRetention: RetentionDays.ONE_DAY, + }); + const logRetentionFunction = this.node.tryFindChild('LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a')!; + const serviceRole = logRetentionFunction.node.tryFindChild('ServiceRole') as iam.Role; + const defaultPolicy = serviceRole.node.tryFindChild('DefaultPolicy')!.node.defaultChild! as iam.CfnPolicy; + const customPolicy = new iam.CfnManagedPolicy(this, 'CustomPolicy', { + policyDocument: defaultPolicy.policyDocument, + roles: defaultPolicy.roles, + }); + const logRetentionResource = logRetentionFunction.node.tryFindChild('Resource') as CfnResource; + // Without replacing the dependency, Cfn will reject the template because it references this non-existent logical id + logRetentionResource.replaceDependency(defaultPolicy, customPolicy); + serviceRole.node.tryRemoveChild('DefaultPolicy'); + } +} + +class TestNestedStack extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + const stack1 = new NestedStack(this, 'Stack1'); + const stack2 = new NestedStack(this, 'Stack2'); + const resource1 = new lambda.Function(stack1, 'Lambda1', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_14_X, + }).node.defaultChild! as CfnResource; + const resource2 = new lambda.Function(stack2, 'Lambda2', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_14_X, + }).node.defaultChild! as CfnResource; + + // The following two statements should cancel each other out + resource1.addDependency(resource2); + resource1.removeDependency(resource2); + + resource2.addDependency(resource1); + } +} + +const app = new App(); +const stack = new TestStack(app, 'replace-depends-on-test'); +const nestedStack = new TestNestedStack(app, 'nested-stack-depends-test'); + +new integ.IntegTest(app, 'DependsOnTest', { + testCases: [stack, nestedStack], +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeilne-elastic-beanstalk-deploy.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeilne-elastic-beanstalk-deploy.ts index 631c3d6f84c26..c5239f88f3f9f 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeilne-elastic-beanstalk-deploy.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeilne-elastic-beanstalk-deploy.ts @@ -103,8 +103,8 @@ const beanstalkEnv = new elasticbeanstalk.CfnEnvironment(stack, 'beanstlk-env', ], }); -beanstalkEnv.addDependsOn(instanceProfile); -beanstalkEnv.addDependsOn(beanstalkApp); +beanstalkEnv.addDependency(instanceProfile); +beanstalkEnv.addDependency(beanstalkApp); const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { artifactBucket: bucket, @@ -144,4 +144,4 @@ new integ.IntegTest(app, 'codepipeline-elastic-beanstalk-deploy', { stackUpdateWorkflow: false, }); -app.synth(); \ No newline at end of file +app.synth(); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.ts index f19c0d7cbaa70..40034ed72c1c8 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.ts @@ -94,7 +94,7 @@ vpc.publicSubnets.forEach((subnet, idx) => { cfnSubnet.ipv6CidrBlock = cdk.Fn.select(idx, ipv6Cidrs); // The subnet depends on the ipv6 cidr being allocated. - cfnSubnet.addDependsOn(ipv6Block); + cfnSubnet.addDependency(ipv6Block); group1.node.addDependency(subnet); group2.node.addDependency(subnet); diff --git a/packages/@aws-cdk/aws-logs/lib/log-retention.ts b/packages/@aws-cdk/aws-logs/lib/log-retention.ts index 0f1c8ebcd8902..7350d089488c3 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-retention.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-retention.ts @@ -186,10 +186,10 @@ class LogRetentionFunction extends Construct implements cdk.ITaggable { // Function dependencies role.node.children.forEach((child) => { if (cdk.CfnResource.isCfnResource(child)) { - resource.addDependsOn(child); + resource.addDependency(child); } if (Construct.isConstruct(child) && child.node.defaultChild && cdk.CfnResource.isCfnResource(child.node.defaultChild)) { - resource.addDependsOn(child.node.defaultChild); + resource.addDependency(child.node.defaultChild); } }); } diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts b/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts index dd44ef0f022fc..d9bd1e68475d8 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts @@ -50,7 +50,7 @@ export class AssociationManager { }); // Add dependsOn to force proper order in deployment. - constraint.addDependsOn(association.cfnPortfolioProductAssociation); + constraint.addDependency(association.cfnPortfolioProductAssociation); } else { throw new Error(`Cannot have multiple tag update constraints for association ${this.prettyPrintAssociation(portfolio, product)}`); } @@ -70,7 +70,7 @@ export class AssociationManager { }); // Add dependsOn to force proper order in deployment. - constraint.addDependsOn(association.cfnPortfolioProductAssociation); + constraint.addDependency(association.cfnPortfolioProductAssociation); } else { throw new Error(`Topic ${topic.node.path} is already subscribed to association ${this.prettyPrintAssociation(portfolio, product)}`); } @@ -93,7 +93,7 @@ export class AssociationManager { }); // Add dependsOn to force proper order in deployment. - constraint.addDependsOn(association.cfnPortfolioProductAssociation); + constraint.addDependency(association.cfnPortfolioProductAssociation); } else { throw new Error(`Provisioning rule ${options.rule.ruleName} already configured on association ${this.prettyPrintAssociation(portfolio, product)}`); } @@ -133,7 +133,7 @@ export class AssociationManager { }); // Add dependsOn to force proper order in deployment. - constraint.addDependsOn(association.cfnPortfolioProductAssociation); + constraint.addDependency(association.cfnPortfolioProductAssociation); } else { throw new Error(`Cannot configure multiple StackSet deployment constraints for association ${this.prettyPrintAssociation(portfolio, product)}`); } @@ -173,7 +173,7 @@ export class AssociationManager { }); // Add dependsOn to force proper order in deployment. - constraint.addDependsOn(association.cfnPortfolioProductAssociation); + constraint.addDependency(association.cfnPortfolioProductAssociation); } else { throw new Error(`Cannot set multiple launch roles for association ${this.prettyPrintAssociation(portfolio, product)}`); } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/databrew/integ.start-job-run.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/databrew/integ.start-job-run.ts index 973f405880c2c..056d97535a81e 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/databrew/integ.start-job-run.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/databrew/integ.start-job-run.ts @@ -86,8 +86,8 @@ class GlueDataBrewJobStack extends cdk.Stack { datasetName: dataset.name, recipeName: recipe.name, }); - project.addDependsOn(dataset); - project.addDependsOn(recipe); + project.addDependency(dataset); + project.addDependency(recipe); const job = new databrew.CfnJob(this, 'DataBrew Job', { name: 'job-1', @@ -100,7 +100,7 @@ class GlueDataBrewJobStack extends cdk.Stack { }, }], }); - job.addDependsOn(project); + job.addDependency(project); const startGlueDataBrewJob = new GlueDataBrewStartJobRun(this, 'Start DataBrew Job run', { name: job.name, diff --git a/packages/@aws-cdk/core/README.md b/packages/@aws-cdk/core/README.md index da983bbf62ca5..c9a97272cf271 100644 --- a/packages/@aws-cdk/core/README.md +++ b/packages/@aws-cdk/core/README.md @@ -460,6 +460,10 @@ A stack dependency has the following implications: automatically deploy `stackB`. - `stackB`'s deployment will be performed *before* `stackA`'s deployment. +### CfnResource Dependencies + +To make declaring dependencies between `CfnResource` objects easier, you can declare dependencies from one `CfnResource` object on another by using the `cfnResource1.addDependency(cfnResource2)` method. This method will work for resources both within the same stack and across stacks as it detects the relative location of the two resources and adds the dependency either to the resource or between the relevant stacks, as appropriate. If more complex logic is in needed, you can similarly remove, replace, or view dependencies between `CfnResource` objects with the `CfnResource` `removeDependency`, `replaceDependency`, and `obtainDependencies` methods, respectively. + ## Custom Resources Custom Resources are CloudFormation resources that are implemented by arbitrary @@ -885,13 +889,13 @@ rawBucket.cfnOptions.metadata = { ``` Resource dependencies (the `DependsOn` attribute) is modified using the -`cfnResource.addDependsOn` method: +`cfnResource.addDependency` method: ```ts const resourceA = new CfnResource(this, 'ResourceA', resourceProps); const resourceB = new CfnResource(this, 'ResourceB', resourceProps); -resourceB.addDependsOn(resourceA); +resourceB.addDependency(resourceA); ``` [cfn-resource-attributes]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-product-attribute-reference.html diff --git a/packages/@aws-cdk/core/lib/cfn-resource.ts b/packages/@aws-cdk/core/lib/cfn-resource.ts index ebd6e0825fdb8..b99053c40665c 100644 --- a/packages/@aws-cdk/core/lib/cfn-resource.ts +++ b/packages/@aws-cdk/core/lib/cfn-resource.ts @@ -6,7 +6,7 @@ import { CfnCondition } from './cfn-condition'; import { CfnRefElement } from './cfn-element'; import { CfnCreationPolicy, CfnDeletionPolicy, CfnUpdatePolicy } from './cfn-resource-policy'; import { Construct, IConstruct, Node } from 'constructs'; -import { addDependency } from './deps'; +import { addDependency, obtainDependencies, removeDependency } from './deps'; import { CfnReference } from './private/cfn-reference'; import { CLOUDFORMATION_TOKEN_RESOLVER } from './private/cloudformation-lang'; import { Reference } from './reference'; @@ -274,6 +274,16 @@ export class CfnResource extends CfnRefElement { this.addPropertyOverride(propertyPath, undefined); } + /** + * Indicates that this resource depends on another resource and cannot be + * provisioned unless the other resource has been successfully provisioned. + * + * @deprecated use addDependency + */ + public addDependsOn(target: CfnResource) { + return this.addDependency(target); + } + /** * Indicates that this resource depends on another resource and cannot be * provisioned unless the other resource has been successfully provisioned. @@ -281,13 +291,52 @@ export class CfnResource extends CfnRefElement { * This can be used for resources across stacks (or nested stack) boundaries * and the dependency will automatically be transferred to the relevant scope. */ - public addDependsOn(target: CfnResource) { + public addDependency(target: CfnResource) { + // skip this dependency if the target is not part of the output + if (!target.shouldSynthesize()) { + return; + } + + addDependency(this, target); + } + + /** + * Indicates that this resource no longer depends on another resource. + * + * This can be used for resources across stacks (including nested stacks) + * and the dependency will automatically be removed from the relevant scope. + */ + public removeDependency(target: CfnResource) : void { // skip this dependency if the target is not part of the output if (!target.shouldSynthesize()) { return; } - addDependency(this, target, `"${Node.of(this).path}" depends on "${Node.of(target).path}"`); + removeDependency(this, target); + } + + /** + * Retrieves an array of resources this resource depends on. + * + * This assembles dependencies on resources across stacks (including nested stacks) + * automatically. + */ + public obtainDependencies() { + return obtainDependencies(this); + } + + /** + * Replaces one dependency with another. + * @param target The dependency to replace + * @param newTarget The new dependency to add + */ + public replaceDependency(target: CfnResource, newTarget: CfnResource) : void { + if (this.obtainDependencies().includes(target)) { + this.removeDependency(target); + this.addDependency(newTarget); + } else { + throw new Error(`"${Node.of(this).path}" does not depend on "${Node.of(target).path}"`); + } } /** @@ -330,7 +379,7 @@ export class CfnResource extends CfnRefElement { * dependency between two resources that are directly defined in the same * stacks. * - * Use `resource.addDependsOn` to define the dependency between two resources, + * Use `resource.addDependency` to define the dependency between two resources, * which also takes stack boundaries into account. * * @internal @@ -339,6 +388,24 @@ export class CfnResource extends CfnRefElement { this.dependsOn.add(target); } + /** + * Get a shallow copy of dependencies between this resource and other resources + * in the same stack. + */ + public obtainResourceDependencies() { + return Array.from(this.dependsOn.values()); + } + + /** + * Remove a dependency between this resource and other resources in the same + * stack. + * + * @internal + */ + public _removeResourceDependency(target: CfnResource) { + this.dependsOn.delete(target); + } + /** * Emits CloudFormation for this resource. * @internal diff --git a/packages/@aws-cdk/core/lib/custom-resource-provider/custom-resource-provider.ts b/packages/@aws-cdk/core/lib/custom-resource-provider/custom-resource-provider.ts index aa39ffb609f27..593a88caf3d93 100644 --- a/packages/@aws-cdk/core/lib/custom-resource-provider/custom-resource-provider.ts +++ b/packages/@aws-cdk/core/lib/custom-resource-provider/custom-resource-provider.ts @@ -305,7 +305,7 @@ export class CustomResourceProvider extends Construct { }); if (this._role) { - handler.addDependsOn(this._role); + handler.addDependency(this._role); } if (this.node.tryGetContext(cxapi.ASSET_RESOURCE_METADATA_ENABLED_CONTEXT)) { diff --git a/packages/@aws-cdk/core/lib/deps.ts b/packages/@aws-cdk/core/lib/deps.ts index e0ef970b6e359..23579a7a8a734 100644 --- a/packages/@aws-cdk/core/lib/deps.ts +++ b/packages/@aws-cdk/core/lib/deps.ts @@ -3,7 +3,7 @@ import { Stack } from './stack'; import { Stage } from './stage'; import { findLastCommonElement, pathToTopLevelStack as pathToRoot } from './util'; -type Element = CfnResource | Stack; +export type Element = CfnResource | Stack; /** * Adds a dependency between two resources or stacks, across stack and nested @@ -13,18 +13,53 @@ type Element = CfnResource | Stack; * - Try to find the deepest common stack between the two elements * - If there isn't a common stack, it means the elements belong to two * disjoined stack-trees and therefore we apply the dependency at the - * assembly/app level between the two topl-level stacks. + * assembly/app level between the two top-level stacks. * - If we did find a common stack, we apply the dependency as a CloudFormation * "DependsOn" between the resources that "represent" our source and target * either directly or through the AWS::CloudFormation::Stack resources that * "lead" to them. * - * @param source The source resource/stack (the depedent) + * @param source The source resource/stack (the dependent) * @param target The target resource/stack (the dependency) - * @param reason Optional resource to associate with the dependency for + */ +export function addDependency(source: Element, target: Element, reason?: string) { + operateOnDependency(DependencyOperation.ADD, source, target, reason); +} + +/** + * Removes a dependency between two resources or stacks, across stack and nested + * stack boundaries. + * + * The algorithm consists of: + * - Try to find the deepest common stack between the two elements + * - If there isn't a common stack, it means the elements belong to two + * disjoined stack-trees and therefore we applied the dependency at the + * assembly/app level between the two top-level stacks; remove it there. + * - If we did find a common stack, we applied the dependency as a CloudFormation + * "DependsOn" between the resources that "represent" our source and target + * either directly or through the AWS::CloudFormation::Stack resources that + * "lead" to them and must remove it there. + * + * @param source The source resource/stack (the dependent) + * @param target The target resource/stack (the dependency) + * @param reason Optional description to associate with the dependency for * diagnostics */ -export function addDependency(source: T, target: T, reason?: string) { +export function removeDependency(source: Element, target: Element) { + operateOnDependency(DependencyOperation.REMOVE, source, target); +} + +enum DependencyOperation { + ADD, + REMOVE +} + +/** + * Find the appropriate location for a dependency and add or remove it + * + * @internal + */ +function operateOnDependency(operation: DependencyOperation, source: Element, target: Element, description?: string) { if (source === target) { return; } @@ -36,7 +71,7 @@ export function addDependency(source: T, target: T, reason?: const targetStage = Stage.of(targetStack); if (sourceStage !== targetStage) { // eslint-disable-next-line max-len - throw new Error(`You cannot add a dependency from '${source.node.path}' (in ${describeStage(sourceStage)}) to '${target.node.path}' (in ${describeStage(targetStage)}): dependency cannot cross stage boundaries`); + throw new Error(`You cannot have a dependency from '${source.node.path}' (in ${describeStage(sourceStage)}) to '${target.node.path}' (in ${describeStage(targetStage)}): dependency cannot cross stage boundaries`); } // find the deepest common stack between the two elements @@ -44,12 +79,25 @@ export function addDependency(source: T, target: T, reason?: const targetPath = pathToRoot(targetStack); const commonStack = findLastCommonElement(sourcePath, targetPath); - // if there is no common stack, then define a assembly-level dependency + // if there is no common stack, then look for an assembly-level dependency // between the two top-level stacks if (!commonStack) { const topLevelSource = sourcePath[0]; // first path element is the top-level stack const topLevelTarget = targetPath[0]; - topLevelSource._addAssemblyDependency(topLevelTarget, reason); + const reason = { source, target, description }; + switch (operation) { + case DependencyOperation.ADD: { + topLevelSource._addAssemblyDependency(topLevelTarget, reason); + break; + } + case DependencyOperation.REMOVE: { + topLevelSource._removeAssemblyDependency(topLevelTarget, reason); + break; + } + default: { + throw new Error(`Unsupported dependency operation: ${operation}`); + } + } return; } @@ -70,31 +118,67 @@ export function addDependency(source: T, target: T, reason?: // `source` is a direct or indirect nested stack of `target`, and this is not // possible (nested stacks cannot depend on their parents). if (commonStack === target) { - throw new Error(`Nested stack '${sourceStack.node.path}' cannot depend on a parent stack '${targetStack.node.path}': ${reason}`); + throw new Error(`Nested stack '${sourceStack.node.path}' cannot depend on a parent stack '${targetStack.node.path}'`); } // we have a common stack from which we can reach both `source` and `target` // now we need to find two resources which are defined directly in this stack // and which can "lead us" to the source/target. - const sourceResource = resourceInCommonStackFor(source); - const targetResource = resourceInCommonStackFor(target); - sourceResource._addResourceDependency(targetResource); - - function resourceInCommonStackFor(element: CfnResource | Stack): CfnResource { - const resource = Stack.isStack(element) ? element.nestedStackResource : element; - if (!resource) { - throw new Error('assertion failure'); // see "assertion" above + const sourceResource = resourceInCommonStackFor(source, commonStack); + const targetResource = resourceInCommonStackFor(target, commonStack); + switch (operation) { + case DependencyOperation.ADD: { + sourceResource._addResourceDependency(targetResource); + break; + } + case DependencyOperation.REMOVE: { + sourceResource._removeResourceDependency(targetResource); + break; } + default: { + throw new Error(`Unsupported dependency operation: ${operation}`); + } + } +} - const resourceStack = Stack.of(resource); +/** + * Get a list of all resource-to-resource dependencies assembled from this Element, Stack or assembly-dependencies + * @param source The source resource/stack (the dependent) + */ +export function obtainDependencies(source: Element) { + let dependencies: Element[] = []; + if (source instanceof CfnResource) { + dependencies = source.obtainResourceDependencies(); + } - // we reached a resource defined in the common stack - if (commonStack === resourceStack) { - return resource; - } + let stacks = pathToRoot(Stack.of(source)); + stacks.forEach((stack) => { + dependencies = [...dependencies, ...stack._obtainAssemblyDependencies({ source: source })]; + }); - return resourceInCommonStackFor(resourceStack); + return dependencies; +} + +/** + * Find the resource in a common stack that 'points' to the given element + * + * @internal + */ +function resourceInCommonStackFor(element: Element, commonStack: Stack): CfnResource { + const resource: CfnResource = (Stack.isStack(element) ? element.nestedStackResource : element) as CfnResource; + if (!resource) { + // see "assertion" in operateOnDependency above + throw new Error(`Unexpected value for resource when looking at ${element}!`); } + + const resourceStack = Stack.of(resource); + + // we reached a resource defined in the common stack + if (commonStack === resourceStack) { + return resource; + } + + return resourceInCommonStackFor(resourceStack, commonStack); } /** diff --git a/packages/@aws-cdk/core/lib/index.ts b/packages/@aws-cdk/core/lib/index.ts index 378017a1fdefb..11a30ae57a65e 100644 --- a/packages/@aws-cdk/core/lib/index.ts +++ b/packages/@aws-cdk/core/lib/index.ts @@ -34,6 +34,7 @@ export * from './duration'; export * from './expiration'; export * from './size'; export * from './stack-trace'; +export { Element } from './deps'; export * from './app'; export * from './context-provider'; diff --git a/packages/@aws-cdk/core/lib/private/prepare-app.ts b/packages/@aws-cdk/core/lib/private/prepare-app.ts index 7e1959b4a4293..e7d73ee631cb2 100644 --- a/packages/@aws-cdk/core/lib/private/prepare-app.ts +++ b/packages/@aws-cdk/core/lib/private/prepare-app.ts @@ -22,7 +22,7 @@ export function prepareApp(root: IConstruct) { for (const target of targetCfnResources) { for (const source of sourceCfnResources) { - source.addDependsOn(target); + source.addDependency(target); } } } diff --git a/packages/@aws-cdk/core/lib/stack.ts b/packages/@aws-cdk/core/lib/stack.ts index e1e71d06ebdf3..7d7997bd3d328 100644 --- a/packages/@aws-cdk/core/lib/stack.ts +++ b/packages/@aws-cdk/core/lib/stack.ts @@ -859,32 +859,137 @@ export class Stack extends Construct implements ITaggable { * * @internal */ - public _addAssemblyDependency(target: Stack, reason?: string) { + public _addAssemblyDependency(target: Stack, reason: StackDependencyReason = {}) { // defensive: we should never get here for nested stacks if (this.nested || target.nested) { throw new Error('Cannot add assembly-level dependencies for nested stacks'); } + // Fill in reason details if not provided + if (!reason.source) { + reason.source = this; + } + if (!reason.target) { + reason.target = target; + } + if (!reason.description) { + reason.description = 'no description provided'; + } - reason = reason || 'dependency added using stack.addDependency()'; const cycle = target.stackDependencyReasons(this); if (cycle !== undefined) { + const cycleDescription = cycle.map((cycleReason) => { + return cycleReason.description; + }).join(', '); // eslint-disable-next-line max-len - throw new Error(`'${target.node.path}' depends on '${this.node.path}' (${cycle.join(', ')}). Adding this dependency (${reason}) would create a cyclic reference.`); + throw new Error(`'${target.node.path}' depends on '${this.node.path}' (${cycleDescription}). Adding this dependency (${reason.description}) would create a cyclic reference.`); } let dep = this._stackDependencies[Names.uniqueId(target)]; if (!dep) { - dep = this._stackDependencies[Names.uniqueId(target)] = { - stack: target, - reasons: [], - }; + dep = this._stackDependencies[Names.uniqueId(target)] = { stack: target, reasons: [] }; + } + // Check for a duplicate reason already existing + let existingReasons: Set = new Set(); + dep.reasons.forEach((existingReason) => { + if (existingReason.source == reason.source && existingReason.target == reason.target) { + existingReasons.add(existingReason); + } + }); + if (existingReasons.size > 0) { + // Dependency already exists and for the provided reason + return; } - dep.reasons.push(reason); if (process.env.CDK_DEBUG_DEPS) { // eslint-disable-next-line no-console - console.error(`[CDK_DEBUG_DEPS] stack "${this.node.path}" depends on "${target.node.path}" because: ${reason}`); + console.error(`[CDK_DEBUG_DEPS] stack "${reason.source.node.path}" depends on "${reason.target.node.path}"`); + } + } + + /** + * Called implicitly by the `obtainDependencies` helper function in order to + * collect resource dependencies across two top-level stacks at the assembly level. + * + * Use `stack.obtainDependencies` to see the dependencies between any two stacks. + * + * @internal + */ + public _obtainAssemblyDependencies(reasonFilter: StackDependencyReason): Element[] { + if (!reasonFilter.source) { + throw new Error('reasonFilter.source must be defined!'); + } + // Assume reasonFilter has only source defined + let dependencies: Set = new Set(); + Object.values(this._stackDependencies).forEach((dep) => { + dep.reasons.forEach((reason) => { + if (reasonFilter.source == reason.source) { + if (!reason.target) { + throw new Error(`Encountered an invalid dependency target from source '${reasonFilter.source!.node.path}'`); + } + dependencies.add(reason.target); + } + }); + }); + return Array.from(dependencies); + } + + /** + * Called implicitly by the `removeDependency` helper function in order to + * remove a dependency between two top-level stacks at the assembly level. + * + * Use `stack.addDependency` to define the dependency between any two stacks, + * and take into account nested stack relationships. + * + * @internal + */ + public _removeAssemblyDependency(target: Stack, reasonFilter: StackDependencyReason={}) { + // defensive: we should never get here for nested stacks + if (this.nested || target.nested) { + throw new Error('There cannot be assembly-level dependencies for nested stacks'); + } + // No need to check for a dependency cycle when removing one + + // Fill in reason details if not provided + if (!reasonFilter.source) { + reasonFilter.source = this; + } + if (!reasonFilter.target) { + reasonFilter.target = target; + } + + let dep = this._stackDependencies[Names.uniqueId(target)]; + if (!dep) { + // Dependency doesn't exist - return now + return; + } + + // Find and remove the specified reason from the dependency + let matchedReasons: Set = new Set(); + dep.reasons.forEach((reason) => { + if (reasonFilter.source == reason.source && reasonFilter.target == reason.target) { + matchedReasons.add(reason); + } + }); + if (matchedReasons.size > 1) { + throw new Error(`There cannot be more than one reason for dependency removal, found: ${matchedReasons}`); + } + if (matchedReasons.size == 0) { + // Reason is already not there - return now + return; + } + let matchedReason = Array.from(matchedReasons)[0]; + + let index = dep.reasons.indexOf(matchedReason, 0); + dep.reasons.splice(index, 1); + // If that was the last reason, remove the dependency + if (dep.reasons.length == 0) { + delete this._stackDependencies[Names.uniqueId(target)]; + } + + if (process.env.CDK_DEBUG_DEPS) { + // eslint-disable-next-line no-console + console.log(`[CDK_DEBUG_DEPS] stack "${this.node.path}" no longer depends on "${target.node.path}" because: ${reasonFilter}`); } } @@ -1261,7 +1366,7 @@ export class Stack extends Construct implements ITaggable { * Returns the list of reasons on the dependency path, or undefined * if there is no dependency. */ - private stackDependencyReasons(other: Stack): string[] | undefined { + private stackDependencyReasons(other: Stack): StackDependencyReason[] | undefined { if (this === other) { return []; } for (const dep of Object.values(this._stackDependencies)) { const ret = dep.stack.stackDependencyReasons(other); @@ -1537,9 +1642,15 @@ function generateExportName(stackExports: Construct, id: string) { return prefix + localPart.slice(Math.max(0, localPart.length - maxLength + prefix.length)); } +interface StackDependencyReason { + source?: Element; + target?: Element; + description?: string; +} + interface StackDependency { stack: Stack; - reasons: string[]; + reasons: StackDependencyReason[]; } interface ResolvedExport { @@ -1575,7 +1686,7 @@ function count(xs: string[]): Record { // These imports have to be at the end to prevent circular imports import { CfnOutput } from './cfn-output'; -import { addDependency } from './deps'; +import { addDependency, Element } from './deps'; import { FileSystem } from './fs'; import { Names } from './names'; import { Reference } from './reference'; @@ -1589,4 +1700,3 @@ import { getExportable } from './private/refs'; import { Fact, RegionInfo } from '@aws-cdk/region-info'; import { deployTimeLookup } from './private/region-lookup'; import { makeUniqueResourceName } from './private/unique-resource-name'; - diff --git a/packages/@aws-cdk/core/test/cfn-resource.test.ts b/packages/@aws-cdk/core/test/cfn-resource.test.ts index 4bc11c5ea43a4..8ab282f10c5ac 100644 --- a/packages/@aws-cdk/core/test/cfn-resource.test.ts +++ b/packages/@aws-cdk/core/test/cfn-resource.test.ts @@ -3,6 +3,7 @@ import { VALIDATE_SNAPSHOT_REMOVAL_POLICY } from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; import * as core from '../lib'; import { getWarnings } from './util'; +import { Names } from '../lib'; describe('cfn resource', () => { describe('._toCloudFormation', () => { @@ -136,6 +137,142 @@ describe('cfn resource', () => { }); }); + describe('dependency methods', () => { + test('can explicitly add a dependency between resources', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack, 'Resource2', { type: 'Test::Resource::Fake2' }); + resource1.addDependency(resource2); + + expect(app.synth().getStackByName(stack.stackName).template.Resources).toEqual({ + Resource1: { + Type: 'Test::Resource::Fake1', + DependsOn: [ + 'Resource2', + ], + }, + Resource2: { + Type: 'Test::Resource::Fake2', + }, + }); + }); + + test('can explicitly remove a dependency between resources', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack, 'Resource2', { type: 'Test::Resource::Fake2' }); + resource1.addDependency(resource2); + resource1.removeDependency(resource2); + + expect(app.synth().getStackByName(stack.stackName).template.Resources).toEqual({ + Resource1: { + Type: 'Test::Resource::Fake1', + }, + Resource2: { + Type: 'Test::Resource::Fake2', + }, + }); + }); + + test('can explicitly add, obtain, and remove dependencies across stacks', () => { + const app = new core.App(); + const stack1 = new core.Stack(app, 'TestStack1'); + // Use a really long construct id to identify issues between Names.uniqueId and Names.uniqueResourceName + const reallyLongConstructId = 'A'.repeat(247); + const stack2 = new core.Stack(app, reallyLongConstructId, { stackName: 'TestStack2' }); + // Sanity check since this test depends on the discrepancy + expect(Names.uniqueId(stack2)).not.toBe(Names.uniqueResourceName(stack2, {})); + const resource1 = new core.CfnResource(stack1, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack2, 'Resource2', { type: 'Test::Resource::Fake2' }); + const resource3 = new core.CfnResource(stack1, 'Resource3', { type: 'Test::Resource::Fake3' }); + + resource1.addDependency(resource2); + // Adding the same resource dependency twice should be a no-op + resource1.addDependency(resource2); + resource1.addDependency(resource3); + expect(stack1.dependencies.length).toEqual(1); + expect(stack1.dependencies[0].node.id).toEqual(stack2.node.id); + // obtainDependencies should assemble and flatten resource-to-resource dependencies even across stacks + expect(resource1.obtainDependencies().map(x => x.node.path)).toEqual([resource3.node.path, resource2.node.path]); + + resource1.removeDependency(resource2); + // For symmetry, removing a dependency that doesn't exist should be a no-op + resource1.removeDependency(resource2); + expect(stack1.dependencies.length).toEqual(0); + }); + + test('can explicitly add, then replace dependencies across stacks', () => { + const app = new core.App(); + const stack1 = new core.Stack(app, 'TestStack1'); + const stack2 = new core.Stack(app, 'TestStack2'); + const stack3 = new core.Stack(app, 'TestStack3'); + const resource1 = new core.CfnResource(stack1, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack2, 'Resource2', { type: 'Test::Resource::Fake2' }); + const resource3 = new core.CfnResource(stack3, 'Resource3', { type: 'Test::Resource::Fake3' }); + + resource1.addDependency(resource2); + // Adding the same resource dependency twice should be a no-op + resource1.replaceDependency(resource2, resource3); + expect(stack1.dependencies).toEqual([stack3]); + // obtainDependencies should assemble and flatten resource-to-resource dependencies even across stacks + expect(resource1.obtainDependencies().map(x => x.node.path)).toEqual([resource3.node.path]); + + // Replacing a dependency that doesn't exist should raise an exception + expect(() => { + resource1.replaceDependency(resource2, resource3); + }).toThrow(/ does not depend on /); + }); + + test('do nothing if source is target', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + resource1.addDependency(resource1); + + expect(app.synth().getStackByName(stack.stackName).template.Resources).toEqual({ + Resource1: { + Type: 'Test::Resource::Fake1', + }, + }); + }); + + test('do nothing if target does not synth', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + + class NoSynthResource extends core.CfnResource { + protected shouldSynthesize(): boolean { + return false; + } + } + + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new NoSynthResource(stack, 'Resource2', { type: 'Test::Resource::Fake2' }); + resource1.removeDependency(resource2); + resource1.addDependency(resource2); + + expect(app.synth().getStackByName(stack.stackName).template.Resources).toEqual({ + Resource1: { + Type: 'Test::Resource::Fake1', + }, + }); + }); + + test('replace throws an error if oldTarget is not depended on', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack, 'Resource2', { type: 'Test::Resource::Fake2' }); + const resource3 = new core.CfnResource(stack, 'Resource3', { type: 'Test::Resource::Fake3' }); + expect(() => { + resource1.replaceDependency(resource2, resource3); + }).toThrow(/does not depend on/); + }); + }); + test('applyRemovalPolicy default includes Update policy', () => { // GIVEN const app = new core.App(); diff --git a/packages/@aws-cdk/core/test/deps.test.ts b/packages/@aws-cdk/core/test/deps.test.ts new file mode 100644 index 0000000000000..5a6eb0a40a8d9 --- /dev/null +++ b/packages/@aws-cdk/core/test/deps.test.ts @@ -0,0 +1,128 @@ +import * as core from '../lib'; +import { Names } from '../lib'; +import { addDependency, obtainDependencies, removeDependency } from '../lib/deps'; +import { Construct } from 'constructs'; + +describe('deps', () => { + describe('dependency methods', () => { + test('can explicitly add a dependency between resources', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack, 'Resource2', { type: 'Test::Resource::Fake2' }); + addDependency(resource1, resource2); + + expect(app.synth().getStackByName(stack.stackName).template.Resources).toEqual({ + Resource1: { + Type: 'Test::Resource::Fake1', + DependsOn: [ + 'Resource2', + ], + }, + Resource2: { + Type: 'Test::Resource::Fake2', + }, + }); + }); + + test('can explicitly remove a dependency between resources', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack, 'Resource2', { type: 'Test::Resource::Fake2' }); + addDependency(resource1, resource2); + removeDependency(resource1, resource2); + + expect(app.synth().getStackByName(stack.stackName).template.Resources).toEqual({ + Resource1: { + Type: 'Test::Resource::Fake1', + }, + Resource2: { + Type: 'Test::Resource::Fake2', + }, + }); + }); + + test('can explicitly add, obtain, and remove dependencies across stacks', () => { + const app = new core.App(); + const stack1 = new core.Stack(app, 'TestStack1'); + // Use a really long construct id to identify issues between Names.uniqueId and Names.uniqueResourceName + const reallyLongConstructId = 'A'.repeat(247); + const stack2 = new core.Stack(app, reallyLongConstructId, { stackName: 'TestStack2' }); + // Sanity check since this test depends on the discrepancy + expect(Names.uniqueId(stack2)).not.toBe(Names.uniqueResourceName(stack2, {})); + const resource1 = new core.CfnResource(stack1, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(stack2, 'Resource2', { type: 'Test::Resource::Fake2' }); + const resource3 = new core.CfnResource(stack1, 'Resource3', { type: 'Test::Resource::Fake3' }); + + addDependency(resource1, resource2); + // Adding the same resource dependency twice should be a no-op + addDependency(resource1, resource2); + addDependency(resource1, resource3); + expect(stack1.dependencies.length).toEqual(1); + expect(stack1.dependencies[0].node.id).toEqual(stack2.node.id); + // obtainDependencies should assemble and flatten resource-to-resource dependencies even across stacks + expect(obtainDependencies(resource1).map(x => x.node.path)).toEqual([resource3.node.path, resource2.node.path]); + + removeDependency(resource1, resource2); + // For symmetry, removing a dependency that doesn't exist should be a no-op + removeDependency(resource1, resource2); + expect(stack1.dependencies.length).toEqual(0); + }); + + test('do nothing if source is target', () => { + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + const resource1 = new core.CfnResource(stack, 'Resource1', { type: 'Test::Resource::Fake1' }); + addDependency(resource1, resource1); + + expect(app.synth().getStackByName(stack.stackName).template.Resources).toEqual({ + Resource1: { + Type: 'Test::Resource::Fake1', + }, + }); + }); + + test('handle source being common stack', () => { + const app = new core.App(); + const stack1 = new core.Stack(app, 'TestStack1'); + const resource1 = new core.CfnResource(stack1, 'Resource1', { type: 'Test::Resource::Fake1' }); + + // If source is the common stack, this should be a noop + addDependency(stack1, resource1); + expect(stack1.dependencies.length).toEqual(0); + }); + + test('throws error if target is common stack', () => { + const app = new core.App(); + const stack1 = new core.Stack(app, 'TestStack1'); + const resource1 = new core.CfnResource(stack1, 'Resource1', { type: 'Test::Resource::Fake1' }); + + expect(() => { + addDependency(resource1, stack1); + }).toThrow(/cannot depend on /); + }); + + test('can explicitly add, obtain, and remove dependencies across nested stacks', () => { + const app = new core.App(); + const stack1 = new core.Stack(app, 'TestStack1'); + const construct1 = new Construct(stack1, 'CommonConstruct'); + // Use a really long construct id to identify issues between Names.uniqueId and Names.uniqueResourceName + const nestedStack1 = new core.Stack(construct1, 'TestNestedStack1'); + const nestedStack2 = new core.Stack(construct1, 'TestNestedStack2'); + const resource1 = new core.CfnResource(nestedStack1, 'Resource1', { type: 'Test::Resource::Fake1' }); + const resource2 = new core.CfnResource(nestedStack2, 'Resource2', { type: 'Test::Resource::Fake2' }); + + addDependency(resource1, resource2); + // Adding the same resource dependency twice should be a no-op + addDependency(resource1, resource2); + expect(nestedStack1.dependencies.length).toEqual(1); + expect(nestedStack1.dependencies[0].node.id).toEqual(nestedStack2.node.id); + + removeDependency(resource1, resource2); + // For symmetry, removing a dependency that doesn't exist should be a no-op + removeDependency(resource1, resource2); + expect(stack1.dependencies.length).toEqual(0); + }); + }); +}); diff --git a/packages/@aws-cdk/core/test/integration.deps.readme b/packages/@aws-cdk/core/test/integration.deps.readme new file mode 100644 index 0000000000000..4797f34bca848 --- /dev/null +++ b/packages/@aws-cdk/core/test/integration.deps.readme @@ -0,0 +1,5 @@ ++--------------------------------------------------------------------------+ +| Since cdk-integ depends on cdk which depends on @aws-cdk/core (as a "dev | +| dependency"), this integration test has been added to the package | +| @aws-cdk/aws-cloudformation under `test/integ.core-deps.ts` | ++--------------------------------------------------------------------------+ diff --git a/packages/@aws-cdk/core/test/resource.test.ts b/packages/@aws-cdk/core/test/resource.test.ts index fe247827bb3d6..07f53d3e8fe66 100644 --- a/packages/@aws-cdk/core/test/resource.test.ts +++ b/packages/@aws-cdk/core/test/resource.test.ts @@ -151,11 +151,11 @@ describe('resource', () => { const dependent = new CfnResource(stack, 'Dependent', { type: 'R' }); // WHEN - dependent.addDependsOn(r1); - dependent.addDependsOn(r1); - dependent.addDependsOn(r1); - dependent.addDependsOn(r1); - dependent.addDependsOn(r1); + dependent.addDependency(r1); + dependent.addDependency(r1); + dependent.addDependency(r1); + dependent.addDependency(r1); + dependent.addDependency(r1); // THEN expect(toCloudFormation(stack)).toEqual({ diff --git a/packages/@aws-cdk/core/test/stack.test.ts b/packages/@aws-cdk/core/test/stack.test.ts index 8a7da057a9def..ee1a12412d3ca 100644 --- a/packages/@aws-cdk/core/test/stack.test.ts +++ b/packages/@aws-cdk/core/test/stack.test.ts @@ -1080,7 +1080,7 @@ describe('stack', () => { RefToResource1: resourceA.ref, }, }); - resource2.addDependsOn(resourceB); + resource2.addDependency(resourceB); // THEN const assembly = app.synth(); @@ -1116,6 +1116,206 @@ describe('stack', () => { expect(assembly.getStackArtifact(child2.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual(['ParentChild18FAEF419']); }); + test('_addAssemblyDependency adds to _stackDependencies', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const childA = new Stack(parent, 'ChildA'); + const resource1 = new CfnResource(child1, 'Resource1', { type: 'R1' }); + const resource2 = new CfnResource(child1, 'Resource2', { type: 'R2' }); + const resourceA = new CfnResource(childA, 'ResourceA', { type: 'RA' }); + + childA._addAssemblyDependency(child1, { source: resourceA, target: resource1 }); + childA._addAssemblyDependency(child1, { source: resourceA, target: resource2 }); + + expect(childA._obtainAssemblyDependencies({ source: resourceA })) + .toEqual([resource1, resource2]); + + const assembly = app.synth(); + + expect(assembly.getStackArtifact(child1.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual([]); + expect(assembly.getStackArtifact(childA.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual(['ParentChild18FAEF419']); + }); + + test('_addAssemblyDependency adds one StackDependencyReason with defaults', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const childA = new Stack(parent, 'ChildA'); + + childA._addAssemblyDependency(child1); + + expect(childA._obtainAssemblyDependencies({ source: childA })) + .toEqual([child1]); + + const assembly = app.synth(); + + expect(assembly.getStackArtifact(child1.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual([]); + expect(assembly.getStackArtifact(childA.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual(['ParentChild18FAEF419']); + }); + + test('_addAssemblyDependency raises error on cycle', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const child2 = new Stack(parent, 'Child2'); + + child2._addAssemblyDependency(child1); + expect(() => child1._addAssemblyDependency(child2)).toThrow("'Parent/Child2' depends on"); + }); + + test('_addAssemblyDependency raises error for nested stacks', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new NestedStack(parent, 'Child1'); + const child2 = new NestedStack(parent, 'Child2'); + + expect(() => child1._addAssemblyDependency(child2)).toThrow('Cannot add assembly-level'); + }); + + test('_addAssemblyDependency handles duplicate dependency reasons', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const child2 = new Stack(parent, 'Child2'); + + child2._addAssemblyDependency(child1); + const depsBefore = child2._obtainAssemblyDependencies({ source: child2 }); + child2._addAssemblyDependency(child1); + expect(depsBefore).toEqual(child2._obtainAssemblyDependencies({ source: child2 })); + }); + + test('_removeAssemblyDependency removes one StackDependencyReason of two from _stackDependencies', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const childA = new Stack(parent, 'ChildA'); + const resource1 = new CfnResource(child1, 'Resource1', { type: 'R1' }); + const resource2 = new CfnResource(child1, 'Resource2', { type: 'R2' }); + const resourceA = new CfnResource(childA, 'ResourceA', { type: 'RA' }); + + childA._addAssemblyDependency(child1, { source: resourceA, target: resource1 }); + childA._addAssemblyDependency(child1, { source: resourceA, target: resource2 }); + childA._removeAssemblyDependency(child1, { source: resourceA, target: resource1 }); + + expect(childA._obtainAssemblyDependencies({ source: resourceA })).toEqual([resource2]); + + const assembly = app.synth(); + + expect(assembly.getStackArtifact(child1.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual([]); + expect(assembly.getStackArtifact(childA.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual(['ParentChild18FAEF419']); + }); + + test('_removeAssemblyDependency removes a StackDependency from _stackDependencies with the last reason', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const childA = new Stack(parent, 'Child2'); + const resource1 = new CfnResource(child1, 'Resource1', { type: 'R1' }); + const resource2 = new CfnResource(child1, 'Resource2', { type: 'R2' }); + const resourceA = new CfnResource(childA, 'ResourceA', { type: 'RA' }); + + childA._addAssemblyDependency(child1, { source: resourceA, target: resource1 }); + childA._addAssemblyDependency(child1, { source: resourceA, target: resource2 }); + childA._removeAssemblyDependency(child1, { source: resourceA, target: resource1 }); + childA._removeAssemblyDependency(child1, { source: resourceA, target: resource2 }); + + expect(childA._obtainAssemblyDependencies({ source: childA })).toEqual([]); + + const assembly = app.synth(); + + expect(assembly.getStackArtifact(child1.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual([]); + expect(assembly.getStackArtifact(childA.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual([]); + }); + + test('_removeAssemblyDependency removes a StackDependency with default reason', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const childA = new Stack(parent, 'Child2'); + + childA._addAssemblyDependency(child1); + childA._removeAssemblyDependency(child1); + + expect(childA._obtainAssemblyDependencies({ source: childA })).toEqual([]); + + const assembly = app.synth(); + + expect(assembly.getStackArtifact(child1.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual([]); + expect(assembly.getStackArtifact(childA.artifactId).dependencies.map((x: { id: any; }) => x.id)).toEqual([]); + }); + + test('_removeAssemblyDependency raises an error for nested stacks', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new NestedStack(parent, 'Child1'); + const childA = new NestedStack(parent, 'Child2'); + + expect(() => childA._removeAssemblyDependency(child1)).toThrow('There cannot be assembly-level'); + }); + + test('_removeAssemblyDependency handles a non-matching dependency reason', () => { + const app = new App({ + context: { + '@aws-cdk/core:stackRelativeExports': true, + [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false, + }, + }); + const parent = new Stack(app, 'Parent'); + const child1 = new Stack(parent, 'Child1'); + const childA = new Stack(parent, 'Child2'); + const resource1 = new CfnResource(child1, 'Resource1', { type: 'R1' }); + const resourceA = new CfnResource(childA, 'ResourceA', { type: 'RA' }); + + childA._addAssemblyDependency(child1); + childA._removeAssemblyDependency(child1, { source: resourceA, target: resource1 }); + }); + test('automatic cross-stack references and manual exports look the same', () => { // GIVEN: automatic const appA = new App({ context: { '@aws-cdk/core:stackRelativeExports': true } }); diff --git a/packages/aws-cdk-lib/README.md b/packages/aws-cdk-lib/README.md index da983bbf62ca5..c9a97272cf271 100644 --- a/packages/aws-cdk-lib/README.md +++ b/packages/aws-cdk-lib/README.md @@ -460,6 +460,10 @@ A stack dependency has the following implications: automatically deploy `stackB`. - `stackB`'s deployment will be performed *before* `stackA`'s deployment. +### CfnResource Dependencies + +To make declaring dependencies between `CfnResource` objects easier, you can declare dependencies from one `CfnResource` object on another by using the `cfnResource1.addDependency(cfnResource2)` method. This method will work for resources both within the same stack and across stacks as it detects the relative location of the two resources and adds the dependency either to the resource or between the relevant stacks, as appropriate. If more complex logic is in needed, you can similarly remove, replace, or view dependencies between `CfnResource` objects with the `CfnResource` `removeDependency`, `replaceDependency`, and `obtainDependencies` methods, respectively. + ## Custom Resources Custom Resources are CloudFormation resources that are implemented by arbitrary @@ -885,13 +889,13 @@ rawBucket.cfnOptions.metadata = { ``` Resource dependencies (the `DependsOn` attribute) is modified using the -`cfnResource.addDependsOn` method: +`cfnResource.addDependency` method: ```ts const resourceA = new CfnResource(this, 'ResourceA', resourceProps); const resourceB = new CfnResource(this, 'ResourceB', resourceProps); -resourceB.addDependsOn(resourceA); +resourceB.addDependency(resourceA); ``` [cfn-resource-attributes]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-product-attribute-reference.html From 78d474a12bce7805f88be96df926149c130bf513 Mon Sep 17 00:00:00 2001 From: Tietew Date: Tue, 20 Dec 2022 04:23:59 +0900 Subject: [PATCH 04/22] fix(cognito): quote or mime-encode `fromName` to comply RFC 5322 (#23227) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #18903 When `fromName` of `UserPoolEmail.withSES()` does not comply RFC 5322 atom or quoted-string, it will be quoted or mime-encoded. For example: |`fromName`|Template|Description| |-|-|-| |`'simple atom'`|`"simple atom "`|as is| |`'"quoted string"'`|`"\"quoted string\" "`|as is| |`'あいう'`|`"=?UTF-8?B?44GC44GE44GG?= "`|mime encode (RFC 2047)| |`'name@company'`|`"\"name@company\" "`|make quoted-string| For details, see [RFC 5322 Section 3.4](https://www.rfc-editor.org/rfc/rfc5322#section-3.4) and [RFC 2047](https://www.rfc-editor.org/rfc/rfc2047) ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *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-cognito/README.md | 12 ++ .../aws-cognito/lib/user-pool-email.ts | 63 +++++++- ...efaultTestDeployAssertE3E7D2A4.assets.json | 19 +++ ...aultTestDeployAssertE3E7D2A4.template.json | 36 +++++ .../cdk.out | 2 +- ....json => integ-user-ses-email.assets.json} | 8 +- ...son => integ-user-ses-email.template.json} | 2 +- .../integ.json | 14 +- .../manifest.json | 85 +++++++--- .../tree.json | 110 ++++++++++--- .../test/integ.user-pool-ses-email.ts | 7 +- .../aws-cognito/test/user-pool.test.ts | 151 ++++++++++++++++++ 12 files changed, 450 insertions(+), 59 deletions(-) create mode 100644 packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json create mode 100644 packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json rename packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/{integ-user-pool-signup-code.assets.json => integ-user-ses-email.assets.json} (62%) rename packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/{integ-user-pool-signup-code.template.json => integ-user-ses-email.template.json} (97%) diff --git a/packages/@aws-cdk/aws-cognito/README.md b/packages/@aws-cdk/aws-cognito/README.md index f01f8646a4d1f..f11f9d7ebb294 100644 --- a/packages/@aws-cdk/aws-cognito/README.md +++ b/packages/@aws-cdk/aws-cognito/README.md @@ -431,6 +431,18 @@ new cognito.UserPool(this, 'myuserpool', { }); ``` +If `fromName` does not comply RFC 5322 atom or quoted-string, it will be quoted or mime-encoded. + +```ts +new cognito.UserPool(this, 'myuserpool', { + email: cognito.UserPoolEmail.withSES({ + fromEmail: 'noreply@myawesomeapp.com', + fromName: 'myname@mycompany.com', + }), +}); +// => From: "myname@mycompany.com" +``` + ### Device Tracking User pools can be configured to track devices that users have logged in to. diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool-email.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool-email.ts index 27eb3f8c240d3..d275c4d3a5dd2 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool-email.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool-email.ts @@ -164,9 +164,10 @@ class SESEmail extends UserPoolEmail { throw new Error('Your stack region cannot be determined so "sesRegion" is required in SESOptions'); } - let from = this.options.fromEmail; + let from = encodeAndTest(this.options.fromEmail); if (this.options.fromName) { - from = `${this.options.fromName} <${this.options.fromEmail}>`; + const fromName = formatFromName(this.options.fromName); + from = `${fromName} <${from}>`; } if (this.options.sesVerifiedDomain) { @@ -177,7 +178,7 @@ class SESEmail extends UserPoolEmail { } return { - from: encodeAndTest(from), + from, replyToEmailAddress: encodeAndTest(this.options.replyTo), configurationSet: this.options.configurationSetName, emailSendingAccount: 'DEVELOPER', @@ -202,3 +203,59 @@ function encodeAndTest(input: string | undefined): string | undefined { return undefined; } } + +/** + * Formats `fromName` to comply RFC 5322 + * + * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.4 + */ +function formatFromName(fromName: string): string { + // mime encode for non US-ASCII characters + // see RFC 2047 for details https://www.rfc-editor.org/rfc/rfc2047 + if (!isAscii(fromName)) { + const base64Name = Buffer.from(fromName, 'utf-8').toString('base64'); + return `=?UTF-8?B?${base64Name}?=`; + } + + // makes a quoted-string unless fromName is a phrase (only atext and space) + // or a quoted-string already + if (!(isSimplePhrase(fromName) || isQuotedString(fromName))) { + // in quoted-string, `\` and `"` should be escaped by `\` + // e.g. `"foo \"bar\" \\baz"` + const quotedName = fromName.replace(/[\\"]/g, (ch) => `\\${ch}`); + return `"${quotedName}"`; + } + + // otherwise, returns as is + return fromName; +} + +/** + * Returns whether the input is a printable US-ASCII string + */ +function isAscii(input: string): boolean { + // U+0020 (space) - U+007E (`~`) + return /^[\u0020-\u007E]+$/u.test(input); +} + +/** + * Returns whether the input is a phrase excluding quoted-string + * + * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.2 + */ +function isSimplePhrase(input: string): boolean { + return /^[\w !#$%&'*+-\/=?^_`{|}~]+$/.test(input); +} + +/** + * Returns whether the input is already a quoted-string + * + * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.2.4 + */ +function isQuotedString(input: string): boolean { + // in quoted-string, `\` and `"` should be esacaped by `\` + // + // match: `"foo.bar"` / `"foo \"bar\""` / `"foo \\ bar"` + // not match: `"bare " dquote"` / `"unclosed escape \"` / `"unclosed dquote` + return /^"(?:[^\\"]|\\.)*"$/.test(input); +} diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json new file mode 100644 index 0000000000000..ab8ca0bd4a1f2 --- /dev/null +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/cdk.out index 588d7b269d34f..145739f539580 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-pool-signup-code.assets.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-ses-email.assets.json similarity index 62% rename from packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-pool-signup-code.assets.json rename to packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-ses-email.assets.json index ecc9fe25929b4..f41ed844f36e1 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-pool-signup-code.assets.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-ses-email.assets.json @@ -1,15 +1,15 @@ { - "version": "20.0.0", + "version": "22.0.0", "files": { - "3294a2beef1e4a711276251bf311cdf22b70152f30241f0d155898e2ab9ad091": { + "55384e618066ba251d0576ca224e2109d90f1e97e067d2d9bfb1476d43fff838": { "source": { - "path": "integ-user-pool-signup-code.template.json", + "path": "integ-user-ses-email.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "3294a2beef1e4a711276251bf311cdf22b70152f30241f0d155898e2ab9ad091.json", + "objectKey": "55384e618066ba251d0576ca224e2109d90f1e97e067d2d9bfb1476d43fff838.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-pool-signup-code.template.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-ses-email.template.json similarity index 97% rename from packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-pool-signup-code.template.json rename to packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-ses-email.template.json index 76d04227ceaed..06d48aad9d5dd 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-pool-signup-code.template.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ-user-ses-email.template.json @@ -20,7 +20,7 @@ }, "EmailConfiguration": { "EmailSendingAccount": "DEVELOPER", - "From": "noreply@example.com", + "From": "\"myname@mycompany.com\" ", "ReplyToEmailAddress": "support@example.com", "SourceArn": { "Fn::Join": [ diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ.json index b0fa49a1c72f9..7719605f8486c 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/integ.json @@ -1,14 +1,12 @@ { - "version": "20.0.0", + "version": "22.0.0", "testCases": { - "integ.user-pool-ses-email": { + "IntegTest/DefaultTest": { "stacks": [ - "integ-user-pool-signup-code" + "integ-user-ses-email" ], - "diffAssets": false, - "stackUpdateWorkflow": true + "assertionStack": "IntegTest/DefaultTest/DeployAssert", + "assertionStackName": "IntegTestDefaultTestDeployAssertE3E7D2A4" } - }, - "synthContext": {}, - "enableLookups": false + } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/manifest.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/manifest.json index d04a7ad4df06b..4f837b695cd65 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/manifest.json @@ -1,33 +1,27 @@ { - "version": "20.0.0", + "version": "22.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, - "integ-user-pool-signup-code.assets": { + "integ-user-ses-email.assets": { "type": "cdk:asset-manifest", "properties": { - "file": "integ-user-pool-signup-code.assets.json", + "file": "integ-user-ses-email.assets.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } }, - "integ-user-pool-signup-code": { + "integ-user-ses-email": { "type": "aws:cloudformation:stack", "environment": "aws://unknown-account/unknown-region", "properties": { - "templateFile": "integ-user-pool-signup-code.template.json", + "templateFile": "integ-user-ses-email.template.json", "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/3294a2beef1e4a711276251bf311cdf22b70152f30241f0d155898e2ab9ad091.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/55384e618066ba251d0576ca224e2109d90f1e97e067d2d9bfb1476d43fff838.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ - "integ-user-pool-signup-code.assets" + "integ-user-ses-email.assets" ], "lookupRole": { "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", @@ -36,35 +30,88 @@ } }, "dependencies": [ - "integ-user-pool-signup-code.assets" + "integ-user-ses-email.assets" ], "metadata": { - "/integ-user-pool-signup-code/myuserpool/Resource": [ + "/integ-user-ses-email/myuserpool/Resource": [ { "type": "aws:cdk:logicalId", "data": "myuserpool01998219" } ], - "/integ-user-pool-signup-code/user-pool-id": [ + "/integ-user-ses-email/user-pool-id": [ { "type": "aws:cdk:logicalId", "data": "userpoolid" } ], - "/integ-user-pool-signup-code/BootstrapVersion": [ + "/integ-user-ses-email/BootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "BootstrapVersion" } ], - "/integ-user-pool-signup-code/CheckBootstrapVersion": [ + "/integ-user-ses-email/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } ] }, - "displayName": "integ-user-pool-signup-code" + "displayName": "integ-user-ses-email" + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "metadata": { + "/IntegTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "IntegTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/tree.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/tree.json index fb6d64ba764b1..df43736a6cf7d 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.js.snapshot/tree.json @@ -4,25 +4,17 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, - "integ-user-pool-signup-code": { - "id": "integ-user-pool-signup-code", - "path": "integ-user-pool-signup-code", + "integ-user-ses-email": { + "id": "integ-user-ses-email", + "path": "integ-user-ses-email", "children": { "myuserpool": { "id": "myuserpool", - "path": "integ-user-pool-signup-code/myuserpool", + "path": "integ-user-ses-email/myuserpool", "children": { "Resource": { "id": "Resource", - "path": "integ-user-pool-signup-code/myuserpool/Resource", + "path": "integ-user-ses-email/myuserpool/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::Cognito::UserPool", "aws:cdk:cloudformation:props": { @@ -42,7 +34,7 @@ "allowAdminCreateUserOnly": true }, "emailConfiguration": { - "from": "noreply@example.com", + "from": "\"myname@mycompany.com\" ", "replyToEmailAddress": "support@example.com", "emailSendingAccount": "DEVELOPER", "sourceArn": { @@ -87,22 +79,100 @@ }, "user-pool-id": { "id": "user-pool-id", - "path": "integ-user-pool-signup-code/user-pool-id", + "path": "integ-user-ses-email/user-pool-id", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-user-ses-email/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-user-ses-email/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "IntegTest": { + "id": "IntegTest", + "path": "IntegTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "IntegTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "IntegTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "IntegTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.168" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.ts b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.ts index 8278649d12f7f..d4064158ff784 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.ts +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-ses-email.ts @@ -1,9 +1,9 @@ import { App, CfnOutput, RemovalPolicy, Stack } from '@aws-cdk/core'; +import { IntegTest } from '@aws-cdk/integ-tests'; import { UserPool, UserPoolEmail } from '../lib'; - const app = new App(); -const stack = new Stack(app, 'integ-user-pool-signup-code'); +const stack = new Stack(app, 'integ-user-ses-email'); const userpool = new UserPool(stack, 'myuserpool', { removalPolicy: RemovalPolicy.DESTROY, @@ -11,6 +11,7 @@ const userpool = new UserPool(stack, 'myuserpool', { email: UserPoolEmail.withSES({ sesRegion: 'us-east-1', fromEmail: 'noreply@example.com', + fromName: 'myname@mycompany.com', replyTo: 'support@example.com', sesVerifiedDomain: 'example.com', }), @@ -20,4 +21,4 @@ new CfnOutput(stack, 'user-pool-id', { value: userpool.userPoolId, }); -app.synth(); +new IntegTest(app, 'IntegTest', { testCases: [stack] }); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts index 9cc1cfc5fb4a8..edec04ad26fb5 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts @@ -1708,7 +1708,158 @@ describe('User Pool', () => { }, }, }); + }); + + test('email withSES with name as quoted-string', () => { + // GIVEN + const stack = new Stack(undefined, undefined, { + env: { + region: 'us-east-1', + account: '11111111111', + }, + }); + + // WHEN + new UserPool(stack, 'Pool', { + email: UserPoolEmail.withSES({ + fromEmail: 'mycustomemail@example.com', + fromName: '"My Custom Email"', + }), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + EmailConfiguration: { + EmailSendingAccount: 'DEVELOPER', + From: '"My Custom Email" ', + SourceArn: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ses:us-east-1:11111111111:identity/mycustomemail@example.com', + ], + ], + }, + }, + }); + }); + + test('email withSES with name with non atom characters', () => { + // GIVEN + const stack = new Stack(undefined, undefined, { + env: { + region: 'us-east-1', + account: '11111111111', + }, + }); + // WHEN + new UserPool(stack, 'Pool', { + email: UserPoolEmail.withSES({ + fromEmail: 'mycustomemail@example.com', + fromName: 'mycustomname@example.com', + }), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + EmailConfiguration: { + EmailSendingAccount: 'DEVELOPER', + From: '"mycustomname@example.com" ', + SourceArn: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ses:us-east-1:11111111111:identity/mycustomemail@example.com', + ], + ], + }, + }, + }); + }); + + test('email withSES with name with quotes', () => { + // GIVEN + const stack = new Stack(undefined, undefined, { + env: { + region: 'us-east-1', + account: '11111111111', + }, + }); + + // WHEN + new UserPool(stack, 'Pool', { + email: UserPoolEmail.withSES({ + fromEmail: 'mycustomemail@example.com', + fromName: 'Foo "Bar" \\Baz', + }), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + EmailConfiguration: { + EmailSendingAccount: 'DEVELOPER', + From: '"Foo \\"Bar\\" \\\\Baz" ', + SourceArn: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ses:us-east-1:11111111111:identity/mycustomemail@example.com', + ], + ], + }, + }, + }); + }); + + test('email withSES with name with non US-ASCII characters', () => { + // GIVEN + const stack = new Stack(undefined, undefined, { + env: { + region: 'us-east-1', + account: '11111111111', + }, + }); + + // WHEN + new UserPool(stack, 'Pool', { + email: UserPoolEmail.withSES({ + fromEmail: 'mycustomemail@example.com', + fromName: 'あいう', + }), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + EmailConfiguration: { + EmailSendingAccount: 'DEVELOPER', + From: '=?UTF-8?B?44GC44GE44GG?= ', + SourceArn: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ses:us-east-1:11111111111:identity/mycustomemail@example.com', + ], + ], + }, + }, + }); }); test('email withSES with valid region', () => { From 4acfc6ace575a4ad750fdf4a5ee4f18e909d8675 Mon Sep 17 00:00:00 2001 From: Cameron Childress Date: Mon, 19 Dec 2022 15:02:28 -0500 Subject: [PATCH 05/22] chore(aws-cloudfront): Added support for managed origin policy "AllViewerAndCloudFrontHeaders-2022-06" (#23358) This adds support for the managed policy "AllViewerAndCloudFrontHeaders-2022-06", added earlier this year, which includes newer CloudFront Headers such as CloudFront-Viewer-Latitude CloudFront-Viewer-Longitude. Detail about this managed policy: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-and-cloudfront ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [NO] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [NO] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *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/lib/origin-request-policy.ts | 2 ++ .../@aws-cdk/aws-cloudfront/test/origin-request-policy.test.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/@aws-cdk/aws-cloudfront/lib/origin-request-policy.ts b/packages/@aws-cdk/aws-cloudfront/lib/origin-request-policy.ts index 2a72736e95e5f..d8a87ffaade7d 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/origin-request-policy.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/origin-request-policy.ts @@ -66,6 +66,8 @@ export class OriginRequestPolicy extends Resource implements IOriginRequestPolic public static readonly ALL_VIEWER = OriginRequestPolicy.fromManagedOriginRequestPolicy('216adef6-5c7f-47e4-b989-5492eafa07d3'); /** This policy is designed for use with an origin that is an AWS Elemental MediaTailor endpoint. */ public static readonly ELEMENTAL_MEDIA_TAILOR = OriginRequestPolicy.fromManagedOriginRequestPolicy('775133bc-15f2-49f9-abea-afb2e0bf67d2'); + /** This policy includes all values (headers, cookies, and query strings) in the viewer request, and all CloudFront headers that were released through June 2022 (CloudFront headers released after June 2022 are not included). */ + public static readonly ALL_VIEWER_AND_CLOUDFRONT_2022 = OriginRequestPolicy.fromManagedOriginRequestPolicy('33f36d7e-f396-46d9-90e0-52428a34d9dc'); /** Imports a Origin Request Policy from its id. */ public static fromOriginRequestPolicyId(scope: Construct, id: string, originRequestPolicyId: string): IOriginRequestPolicy { diff --git a/packages/@aws-cdk/aws-cloudfront/test/origin-request-policy.test.ts b/packages/@aws-cdk/aws-cloudfront/test/origin-request-policy.test.ts index bda5a09058e67..b0fbbd93539c8 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/origin-request-policy.test.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/origin-request-policy.test.ts @@ -108,6 +108,7 @@ test('managed policies are provided', () => { expect(OriginRequestPolicy.CORS_S3_ORIGIN.originRequestPolicyId).toEqual('88a5eaf4-2fd4-4709-b370-b4c650ea3fcf'); expect(OriginRequestPolicy.ALL_VIEWER.originRequestPolicyId).toEqual('216adef6-5c7f-47e4-b989-5492eafa07d3'); expect(OriginRequestPolicy.ELEMENTAL_MEDIA_TAILOR.originRequestPolicyId).toEqual('775133bc-15f2-49f9-abea-afb2e0bf67d2'); + expect(OriginRequestPolicy.ALL_VIEWER_AND_CLOUDFRONT_2022.originRequestPolicyId).toEqual('33f36d7e-f396-46d9-90e0-52428a34d9dc'); }); // OriginRequestCookieBehavior and OriginRequestQueryStringBehavior have identical behavior From 87bd42d41f11667aef673d9087c28cecedb87f66 Mon Sep 17 00:00:00 2001 From: Hoon Oh <2078254+hoonoh@users.noreply.github.com> Date: Tue, 20 Dec 2022 05:40:49 +0900 Subject: [PATCH 06/22] fix(core): cross region ssm writer update (#23356) Hello, I have come across many errors with cross region export feature when updating the export values. Without this fix when updating cross region export values and there are no ssm parameters to be deleted, the Lambda function would throw with error: ``` ERROR Error processing event: AccessDeniedException: User: arn:aws:sts::xxx:assumed-role/xxx-CustomCrossRegionExportWrite-xxx/xxx-CustomCrossRegionExportWrite-xxx is not authorized to perform: ssm:DeleteParameters on resource: arn:aws:ssm:us-east-1:xxx:* because no identity-based policy allows the ssm:DeleteParameters action at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:686:14) at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12) at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9) at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:688:12) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) { code: 'AccessDeniedException', time: 2022-12-15T10:13:59.977Z, requestId: 'xxx', statusCode: 400, retryable: false, retryDelay: 10.941837950279254 }} ``` This is because `ssm.deleteParameters` would be called with empty array for `Names` parameter as: ```js await ssm.deleteParameters({ Names: [], }).promise(); ``` ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cross-region-ssm-writer-handler/index.ts | 10 +++++++--- .../cross-region-ssm-writer-handler.test.ts | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/core/lib/custom-resource-provider/cross-region-export-providers/cross-region-ssm-writer-handler/index.ts b/packages/@aws-cdk/core/lib/custom-resource-provider/cross-region-export-providers/cross-region-ssm-writer-handler/index.ts index 84d0e4fe679b1..9f1f2d62d7b99 100644 --- a/packages/@aws-cdk/core/lib/custom-resource-provider/cross-region-export-providers/cross-region-ssm-writer-handler/index.ts +++ b/packages/@aws-cdk/core/lib/custom-resource-provider/cross-region-export-providers/cross-region-ssm-writer-handler/index.ts @@ -30,9 +30,13 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent const removedExports = except(oldExports, exports); await throwIfAnyInUse(ssm, removedExports); // if the ones we are removing are not in use then delete them - await ssm.deleteParameters({ - Names: Object.keys(removedExports), - }).promise(); + // skip if no export names are to be deleted + const removedExportsNames = Object.keys(removedExports); + if (removedExportsNames.length > 0) { + await ssm.deleteParameters({ + Names: removedExportsNames, + }).promise(); + } // also throw an error if we are creating a new export that already exists for some reason await throwIfAnyInUse(ssm, newExports); diff --git a/packages/@aws-cdk/core/test/custom-resource-provider/cross-region-ssm-writer-handler.test.ts b/packages/@aws-cdk/core/test/custom-resource-provider/cross-region-ssm-writer-handler.test.ts index 17ee6b3c26a31..e5079668b3b8c 100644 --- a/packages/@aws-cdk/core/test/custom-resource-provider/cross-region-ssm-writer-handler.test.ts +++ b/packages/@aws-cdk/core/test/custom-resource-provider/cross-region-ssm-writer-handler.test.ts @@ -177,6 +177,7 @@ describe('cross-region-ssm-writer entrypoint', () => { }); expect(mockPutParameter).toHaveBeenCalledTimes(1); expect(mocklistTagsForResource).toHaveBeenCalledTimes(1); + expect(mockDeleteParameters).toHaveBeenCalledTimes(0); }); test('removed exports are deleted', async () => { From fcf1bfaab173ee57bbf64d95be62bf10cbb1b851 Mon Sep 17 00:00:00 2001 From: Vinayak Kukreja <78971045+vinayak-kukreja@users.noreply.github.com> Date: Mon, 19 Dec 2022 16:07:55 -0800 Subject: [PATCH 07/22] fix(dynamodb): add kms permissions to grantStreamRead (#23400) Currently [combinedGrant](https://github.com/aws/aws-cdk/blob/dfcfb8da34a495987214e70713b0c61f368ce962/packages/%40aws-cdk/aws-dynamodb/lib/table.ts#L1025-L1061) method does nothing if an encryption key is provided with stream action(s) present for the table. This impacts `grantStreamRead` method and is not attaching relevant KMS permissions to the policy. Resolves https://github.com/aws/aws-cdk/issues/22796 ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *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-dynamodb/lib/table.ts | 6 +- .../aws-dynamodb/test/dynamodb.test.ts | 54 ++++ .../aws-cdk-dynamodb.assets.json | 6 +- .../aws-cdk-dynamodb.template.json | 137 +++++++++ .../test/integ.dynamodb.js.snapshot/cdk.out | 2 +- .../integ.dynamodb.js.snapshot/integ.json | 2 +- .../integ.dynamodb.js.snapshot/manifest.json | 40 ++- .../test/integ.dynamodb.js.snapshot/tree.json | 275 ++++++++++++++++-- .../aws-cdk-dynamodb.assets.json | 6 +- .../aws-cdk-dynamodb.template.json | 26 +- .../integ.dynamodb.sse.js.snapshot/cdk.out | 2 +- .../integ.dynamodb.sse.js.snapshot/integ.json | 2 +- .../manifest.json | 16 +- .../integ.dynamodb.sse.js.snapshot/tree.json | 88 ++++-- .../aws-dynamodb/test/integ.dynamodb.ts | 18 ++ 15 files changed, 587 insertions(+), 93 deletions(-) diff --git a/packages/@aws-cdk/aws-dynamodb/lib/table.ts b/packages/@aws-cdk/aws-dynamodb/lib/table.ts index 539761ba96032..122820039d038 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/table.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/table.ts @@ -1026,6 +1026,9 @@ abstract class TableBase extends Resource implements ITable { grantee: iam.IGrantable, opts: { keyActions?: string[], tableActions?: string[], streamActions?: string[] }, ): iam.Grant { + if (this.encryptionKey && opts.keyActions) { + this.encryptionKey.grant(grantee, ...opts.keyActions); + } if (opts.tableActions) { const resources = [this.tableArn, Lazy.string({ produce: () => this.hasIndex ? `${this.tableArn}/index/*` : Aws.NO_VALUE }), @@ -1039,9 +1042,6 @@ abstract class TableBase extends Resource implements ITable { resourceArns: resources, scope: this, }); - if (this.encryptionKey && opts.keyActions) { - this.encryptionKey.grant(grantee, ...opts.keyActions); - } return ret; } if (opts.streamActions) { diff --git a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts index 35145edd0d57c..02ccd0b1540d6 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts @@ -2264,6 +2264,60 @@ describe('import', () => { }); }); + test('if an encryption key is included, encrypt/decrypt permissions are added to the principal for grantStreamRead', () => { + const stack = new Stack(); + + const tableName = 'MyTable'; + const tableStreamArn = 'arn:foo:bar:baz:TrustMeThisIsATableStream'; + const encryptionKey = new kms.Key(stack, 'Key', { + enableKeyRotation: true, + }); + + const table = Table.fromTableAttributes(stack, 'ImportedTable', { tableName, tableStreamArn, encryptionKey }); + + const role = new iam.Role(stack, 'NewRole', { + assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), + }); + + expect(table.grantStreamRead(role)).toBeDefined(); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + 'Action': 'dynamodb:ListStreams', + 'Effect': 'Allow', + 'Resource': '*', + }, + { + 'Action': [ + 'kms:Decrypt', + 'kms:DescribeKey', + ], + 'Effect': 'Allow', + 'Resource': { + 'Fn::GetAtt': [ + 'Key961B73FD', + 'Arn', + ], + }, + }, + { + 'Action': [ + 'dynamodb:DescribeStream', + 'dynamodb:GetRecords', + 'dynamodb:GetShardIterator', + ], + 'Effect': 'Allow', + 'Resource': 'arn:foo:bar:baz:TrustMeThisIsATableStream', + }, + ], + Version: '2012-10-17', + }, + Roles: [stack.resolve(role.roleName)], + }); + }); + test('creates the correct index grant if indexes have been provided when importing', () => { const stack = new Stack(); diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json index aa3256624691c..8f13a49bbff39 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "22.0.0", "files": { - "28f29dc1ca8be205ffc54093c72bcd51a45a56b3375537b6cfa7e2b132bbdc9e": { + "aaaac6e8f3f1ffa9992cbb900021f1d1b5ec67af132595b4b296680991a0d152": { "source": { "path": "aws-cdk-dynamodb.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "28f29dc1ca8be205ffc54093c72bcd51a45a56b3375537b6cfa7e2b132bbdc9e.json", + "objectKey": "aaaac6e8f3f1ffa9992cbb900021f1d1b5ec67af132595b4b296680991a0d152.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json index b4c641169a41e..5c90ea1dde1a9 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json @@ -371,6 +371,143 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "Key961B73FD": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "EnableKeyRotation": true + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "TableWithCustomerManagedKeyD5C58807": { + "Type": "AWS::DynamoDB::Table", + "Properties": { + "KeySchema": [ + { + "AttributeName": "hashKey", + "KeyType": "HASH" + } + ], + "AttributeDefinitions": [ + { + "AttributeName": "hashKey", + "AttributeType": "S" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "SSESpecification": { + "KMSMasterKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "SSEEnabled": true, + "SSEType": "KMS" + }, + "StreamSpecification": { + "StreamViewType": "NEW_AND_OLD_IMAGES" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Role1ABCC5F0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sqs.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "RoleDefaultPolicy5FFB7DAB": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "dynamodb:ListStreams", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + } + }, + { + "Action": [ + "dynamodb:DescribeStream", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableWithCustomerManagedKeyD5C58807", + "StreamArn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "RoleDefaultPolicy5FFB7DAB", + "Roles": [ + { + "Ref": "Role1ABCC5F0" + } + ] + } + }, "User00B015A1": { "Type": "AWS::IAM::User" }, diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out index 588d7b269d34f..145739f539580 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json index 6de1a0399c7a2..45afa8d3160a6 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "22.0.0", "testCases": { "integ.dynamodb": { "stacks": [ diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json index 293f1e74490ca..5f09227f142a1 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "22.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-dynamodb.assets": { "type": "cdk:asset-manifest", "properties": { @@ -23,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/28f29dc1ca8be205ffc54093c72bcd51a45a56b3375537b6cfa7e2b132bbdc9e.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/aaaac6e8f3f1ffa9992cbb900021f1d1b5ec67af132595b4b296680991a0d152.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -63,6 +57,30 @@ "data": "TableWithLocalSecondaryIndex4DA3D08F" } ], + "/aws-cdk-dynamodb/Key/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Key961B73FD" + } + ], + "/aws-cdk-dynamodb/TableWithCustomerManagedKey/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TableWithCustomerManagedKeyD5C58807" + } + ], + "/aws-cdk-dynamodb/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Role1ABCC5F0" + } + ], + "/aws-cdk-dynamodb/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RoleDefaultPolicy5FFB7DAB" + } + ], "/aws-cdk-dynamodb/User/Resource": [ { "type": "aws:cdk:logicalId", @@ -89,6 +107,12 @@ ] }, "displayName": "aws-cdk-dynamodb" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json index 202cabc0f7115..4db3749ed870a 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "aws-cdk-dynamodb": { "id": "aws-cdk-dynamodb", "path": "aws-cdk-dynamodb", @@ -53,8 +45,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/Table/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -327,8 +319,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalAndLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -396,8 +388,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -473,8 +465,120 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-dynamodb.Table", + "version": "0.0.0" + } + }, + "Key": { + "id": "Key", + "path": "aws-cdk-dynamodb/Key", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/Key/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KMS::Key", + "aws:cdk:cloudformation:props": { + "keyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "enableKeyRotation": true + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-kms.CfnKey", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-kms.Key", + "version": "0.0.0" + } + }, + "TableWithCustomerManagedKey": { + "id": "TableWithCustomerManagedKey", + "path": "aws-cdk-dynamodb/TableWithCustomerManagedKey", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/TableWithCustomerManagedKey/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::DynamoDB::Table", + "aws:cdk:cloudformation:props": { + "keySchema": [ + { + "attributeName": "hashKey", + "keyType": "HASH" + } + ], + "attributeDefinitions": [ + { + "attributeName": "hashKey", + "attributeType": "S" + } + ], + "provisionedThroughput": { + "readCapacityUnits": 5, + "writeCapacityUnits": 5 + }, + "sseSpecification": { + "sseEnabled": true, + "kmsMasterKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "sseType": "KMS" + }, + "streamSpecification": { + "streamViewType": "NEW_AND_OLD_IMAGES" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-dynamodb.CfnTable", + "version": "0.0.0" + } + }, + "ScalingRole": { + "id": "ScalingRole", + "path": "aws-cdk-dynamodb/TableWithCustomerManagedKey/ScalingRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -483,6 +587,115 @@ "version": "0.0.0" } }, + "Role": { + "id": "Role", + "path": "aws-cdk-dynamodb/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-dynamodb/Role/ImportRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sqs.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-dynamodb/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "dynamodb:ListStreams", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + } + }, + { + "Action": [ + "dynamodb:DescribeStream", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableWithCustomerManagedKeyD5C58807", + "StreamArn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "RoleDefaultPolicy5FFB7DAB", + "roles": [ + { + "Ref": "Role1ABCC5F0" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, "User": { "id": "User", "path": "aws-cdk-dynamodb/User", @@ -582,17 +795,41 @@ "fqn": "@aws-cdk/aws-iam.User", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-dynamodb/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-dynamodb/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.189" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json index 7f8b8258d7abc..90f3a7d2343f5 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "22.0.0", "files": { - "449ab31c53e48708bdc4d899497ed3129e2565e94bbdf22cd8704751fc73fcb5": { + "67bada7a8e782ac86bb16bf47c61bc2039c780e5e42eaae93c8bc65e9b3e7cbb": { "source": { "path": "aws-cdk-dynamodb.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "449ab31c53e48708bdc4d899497ed3129e2565e94bbdf22cd8704751fc73fcb5.json", + "objectKey": "67bada7a8e782ac86bb16bf47c61bc2039c780e5e42eaae93c8bc65e9b3e7cbb.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json index fdcaf307d248c..6cd6ef9769f51 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json @@ -489,6 +489,19 @@ "Properties": { "PolicyDocument": { "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableKey25666F95", + "Arn" + ] + } + }, { "Action": [ "dynamodb:BatchGetItem", @@ -532,19 +545,6 @@ "Ref": "AWS::NoValue" } ] - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "TableKey25666F95", - "Arn" - ] - } } ], "Version": "2012-10-17" diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out index 588d7b269d34f..145739f539580 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json index 14c805d5166f4..85acd063c33d2 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "22.0.0", "testCases": { "integ.dynamodb.sse": { "stacks": [ diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json index 8460159e46960..487bca37f7c43 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "22.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-dynamodb.assets": { "type": "cdk:asset-manifest", "properties": { @@ -23,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/449ab31c53e48708bdc4d899497ed3129e2565e94bbdf22cd8704751fc73fcb5.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/67bada7a8e782ac86bb16bf47c61bc2039c780e5e42eaae93c8bc65e9b3e7cbb.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -101,6 +95,12 @@ ] }, "displayName": "aws-cdk-dynamodb" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json index 4d9a73bb877d9..15241edf76fe3 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "aws-cdk-dynamodb": { "id": "aws-cdk-dynamodb", "path": "aws-cdk-dynamodb", @@ -116,8 +108,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/Table/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -390,8 +382,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalAndLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -521,8 +513,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -601,8 +593,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -615,6 +607,14 @@ "id": "Role", "path": "aws-cdk-dynamodb/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-dynamodb/Role/ImportRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-dynamodb/Role/Resource", @@ -652,6 +652,19 @@ "aws:cdk:cloudformation:props": { "policyDocument": { "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableKey25666F95", + "Arn" + ] + } + }, { "Action": [ "dynamodb:BatchGetItem", @@ -695,19 +708,6 @@ "Ref": "AWS::NoValue" } ] - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "TableKey25666F95", - "Arn" - ] - } } ], "Version": "2012-10-17" @@ -736,17 +736,41 @@ "fqn": "@aws-cdk/aws-iam.Role", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-dynamodb/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-dynamodb/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.189" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts index f016561c441db..762e513df1cd1 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts @@ -1,4 +1,5 @@ import * as iam from '@aws-cdk/aws-iam'; +import * as kms from '@aws-cdk/aws-kms'; import { App, RemovalPolicy, Stack, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, ProjectionType, StreamViewType, Table, TableEncryption } from '../lib'; @@ -7,6 +8,7 @@ const STACK_NAME = 'aws-cdk-dynamodb'; // DynamoDB table parameters const TABLE = 'Table'; +const TABLE_WITH_CMK = 'TableWithCustomerManagedKey'; const TABLE_WITH_GLOBAL_AND_LOCAL_SECONDARY_INDEX = 'TableWithGlobalAndLocalSecondaryIndex'; const TABLE_WITH_GLOBAL_SECONDARY_INDEX = 'TableWithGlobalSecondaryIndex'; const TABLE_WITH_LOCAL_SECONDARY_INDEX = 'TableWithLocalSecondaryIndex'; @@ -127,6 +129,22 @@ tableWithLocalSecondaryIndex.addLocalSecondaryIndex({ sortKey: LSI_SORT_KEY, }); +const encryptionKey = new kms.Key(stack, 'Key', { + enableKeyRotation: true, +}); + +const tableWithCMK = new Table(stack, TABLE_WITH_CMK, { + partitionKey: TABLE_PARTITION_KEY, + removalPolicy: RemovalPolicy.DESTROY, + stream: StreamViewType.NEW_AND_OLD_IMAGES, + encryptionKey: encryptionKey, +}); + +const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('sqs.amazonaws.com'), +}); +tableWithCMK.grantStreamRead(role); + const user = new iam.User(stack, 'User'); table.grantReadData(user); tableWithGlobalAndLocalSecondaryIndex.grantReadData(user); From 606837d3de5d048e3fb1674c30a3048e918f680a Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Mon, 19 Dec 2022 19:46:56 -0500 Subject: [PATCH 08/22] fix(aws-eks): fail to update both logging and access at the same time (#22957) This PR addresses the following known issues: 1. When updating the cluster endpoint access type only with logging predefined yet unchanged, the cluster-resource-handler updates both the logging and access, which is not allowed and throws the SDK error. This PR fixed this and will update access type only, which is allowed. 2. When updating the cluster endpoint public cidr with exactly the same size of cidr, the `setsEqual` function should return correctly. 3. When updating the cluster endpoint public access from one cidr to multiple cidr with logging predefined yet unchanged, the update should return correctly. 4. Updating both access and logging now throws an error from CDK custom resource. This PR is just a temporary fix that does not implement multiple operations in the cluster-resource-handler custom resource provider(i.e. update both logging and access). Fixes: https://github.com/aws/aws-cdk/issues/21439 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/cluster-resource-handler/cluster.ts | 10 +- .../test/cluster-resource-provider.test.ts | 105 ++++++++++++++++-- 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts index 0177a7e21b695..e6930b7844d32 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts @@ -136,10 +136,16 @@ export class ClusterResourceHandler extends ResourceHandler { return this.updateClusterVersion(this.newProps.version); } + if (updates.updateLogging && updates.updateAccess) { + throw new Error('Cannot update logging and access at the same time'); + } + if (updates.updateLogging || updates.updateAccess) { const config: aws.EKS.UpdateClusterConfigRequest = { name: this.clusterName, - logging: this.newProps.logging, + }; + if (updates.updateLogging) { + config.logging = this.newProps.logging; }; if (updates.updateAccess) { // Updating the cluster with securityGroupIds and subnetIds (as specified in the warning here: @@ -334,5 +340,5 @@ function analyzeUpdate(oldProps: Partial, newProps } function setsEqual(first: Set, second: Set) { - return first.size === second.size || [...first].every((e: string) => second.has(e)); + return first.size === second.size && [...first].every((e: string) => second.has(e)); } diff --git a/packages/@aws-cdk/aws-eks/test/cluster-resource-provider.test.ts b/packages/@aws-cdk/aws-eks/test/cluster-resource-provider.test.ts index 5bec15aaed2d8..f1ad11b562838 100644 --- a/packages/@aws-cdk/aws-eks/test/cluster-resource-provider.test.ts +++ b/packages/@aws-cdk/aws-eks/test/cluster-resource-provider.test.ts @@ -588,11 +588,16 @@ describe('cluster resource provider', () => { logging: undefined, resourcesVpcConfig: undefined, })); - - const resp = await handler.onEvent(); - expect(resp).toEqual({ EksUpdateId: mocks.MOCK_UPDATE_STATUS_ID }); - expect(mocks.actualRequest.updateClusterConfigRequest!).toEqual({ - name: 'physical-resource-id', + let error: any; + try { + await handler.onEvent(); + } catch (e) { + error = e; + } + expect(error.message).toEqual('Cannot update logging and access at the same time'); + }); + test('both logging and access defined and modify both of them', async () => { + const handler = new ClusterResourceHandler(mocks.client, mocks.newRequest('Update', { logging: { clusterLogging: [ { @@ -601,13 +606,99 @@ describe('cluster resource provider', () => { }, ], }, + resourcesVpcConfig: { + endpointPrivateAccess: true, + endpointPublicAccess: false, + publicAccessCidrs: ['0.0.0.0/0'], + }, + }, { + logging: { + clusterLogging: [ + { + types: ['api', 'audit', 'authenticator', 'controllerManager'], + enabled: true, + }, + ], + }, resourcesVpcConfig: { endpointPrivateAccess: true, endpointPublicAccess: true, publicAccessCidrs: ['0.0.0.0/0'], }, - }); - expect(mocks.actualRequest.createClusterRequest).toEqual(undefined); + })); + let error: any; + try { + await handler.onEvent(); + } catch (e) { + error = e; + } + expect(error.message).toEqual('Cannot update logging and access at the same time'); + }); + test('Given logging enabled and unchanged, updating the only publicAccessCidrs is allowed ', async () => { + const handler = new ClusterResourceHandler(mocks.client, mocks.newRequest('Update', { + logging: { + clusterLogging: [ + { + types: ['api', 'audit', 'authenticator', 'controllerManager', 'scheduler'], + enabled: true, + }, + ], + }, + resourcesVpcConfig: { + endpointPrivateAccess: true, + endpointPublicAccess: true, + publicAccessCidrs: ['1.2.3.4/32'], + }, + }, { + logging: { + clusterLogging: [ + { + types: ['api', 'audit', 'authenticator', 'controllerManager', 'scheduler'], + enabled: true, + }, + ], + }, + resourcesVpcConfig: { + endpointPrivateAccess: true, + endpointPublicAccess: true, + publicAccessCidrs: ['0.0.0.0/0'], + }, + })); + const resp = await handler.onEvent(); + expect(resp).toEqual({ EksUpdateId: 'MockEksUpdateStatusId' }); + }); + test('Given logging enabled and unchanged, updating publicAccessCidrs from one to multiple entries is allowed ', async () => { + const handler = new ClusterResourceHandler(mocks.client, mocks.newRequest('Update', { + logging: { + clusterLogging: [ + { + types: ['api', 'audit', 'authenticator', 'controllerManager', 'scheduler'], + enabled: true, + }, + ], + }, + resourcesVpcConfig: { + endpointPrivateAccess: true, + endpointPublicAccess: true, + publicAccessCidrs: ['2.4.6.0/24', '1.2.3.4/32', '3.3.3.3/32'], + }, + }, { + logging: { + clusterLogging: [ + { + types: ['api', 'audit', 'authenticator', 'controllerManager', 'scheduler'], + enabled: true, + }, + ], + }, + resourcesVpcConfig: { + endpointPrivateAccess: true, + endpointPublicAccess: true, + publicAccessCidrs: ['2.4.6.0/24'], + }, + })); + const resp = await handler.onEvent(); + expect(resp).toEqual({ EksUpdateId: 'MockEksUpdateStatusId' }); }); }); }); From 8896fb902ad9c8d91a5ddb63df64963186bd09e1 Mon Sep 17 00:00:00 2001 From: Yoshiyuki Nakano Date: Wed, 21 Dec 2022 08:57:34 +0900 Subject: [PATCH 09/22] feat(aws-cognito): add AuthSessionValidity property on a UserPoolClient (#23040) Fixes #22854 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *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-cognito/README.md | 11 + .../aws-cognito/lib/user-pool-client.ts | 15 ++ .../index.js | 252 ----------------- .../index.js | 253 ++++++++++++++++++ .../cdk.out | 2 +- ...ser-pool-client-explicit-props.assets.json | 12 +- ...r-pool-client-explicit-props.template.json | 3 +- .../integ.json | 2 +- .../manifest.json | 16 +- .../tree.json | 61 +++-- .../integ.user-pool-client-explicit-props.ts | 3 +- .../aws-cognito/test/user-pool-client.test.ts | 80 ++++++ 12 files changed, 422 insertions(+), 288 deletions(-) delete mode 100644 packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286/index.js create mode 100644 packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js diff --git a/packages/@aws-cdk/aws-cognito/README.md b/packages/@aws-cdk/aws-cognito/README.md index f11f9d7ebb294..3e0e035a13318 100644 --- a/packages/@aws-cdk/aws-cognito/README.md +++ b/packages/@aws-cdk/aws-cognito/README.md @@ -720,6 +720,17 @@ const client = pool.addClient('app-client', { client.node.addDependency(provider); ``` +The property `authSessionValidity` is the session token for each API request in the authentication flow. +Valid duration is from 3 to 15 minutes. + +```ts +const pool = new cognito.UserPool(this, 'Pool'); +pool.addClient('app-client', { + // ... + authSessionValidity: Duration.minutes(15), +}); +``` + In accordance with the OIDC open standard, Cognito user pool clients provide access tokens, ID tokens and refresh tokens. More information is available at [Using Tokens with User Pools](https://docs.aws.amazon.com/en_us/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html). The expiration time for these tokens can be configured as shown below. diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts index cabcae64a2c8f..a36f113b37b3e 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts @@ -239,6 +239,15 @@ export interface UserPoolClientOptions { */ readonly oAuth?: OAuthSettings; + /** + * Cognito creates a session token for each API request in an authentication flow. + * AuthSessionValidity is the duration, in minutes, of that session token. + * see defaults in `AuthSessionValidity`. Valid duration is from 3 to 15 minutes. + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpoolclient.html#cfn-cognito-userpoolclient-authsessionvalidity + * @default - Duration.minutes(3) + */ + readonly authSessionValidity?: Duration; + /** * Whether Cognito returns a UserNotFoundException exception when the * user does not exist in the user pool (false), or whether it returns @@ -409,6 +418,7 @@ export class UserPoolClient extends Resource implements IUserPoolClient { writeAttributes: props.writeAttributes?.attributes(), enableTokenRevocation: props.enableTokenRevocation, }); + this.configureAuthSessionValidity(resource, props); this.configureTokenValidity(resource, props); this.userPoolClientId = resource.ref; @@ -522,6 +532,11 @@ export class UserPoolClient extends Resource implements IUserPoolClient { return Array.from(providers); } + private configureAuthSessionValidity(resource: CfnUserPoolClient, props: UserPoolClientProps) { + this.validateDuration('authSessionValidity', Duration.minutes(3), Duration.minutes(15), props.authSessionValidity); + resource.authSessionValidity = props.authSessionValidity ? props.authSessionValidity.toMinutes() : undefined; + } + private configureTokenValidity(resource: CfnUserPoolClient, props: UserPoolClientProps) { this.validateDuration('idTokenValidity', Duration.minutes(5), Duration.days(1), props.idTokenValidity); this.validateDuration('accessTokenValidity', Duration.minutes(5), Duration.days(1), props.accessTokenValidity); diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286/index.js b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286/index.js deleted file mode 100644 index 7bae87b06d44d..0000000000000 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286/index.js +++ /dev/null @@ -1,252 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.handler = exports.forceSdkInstallation = exports.flatten = exports.PHYSICAL_RESOURCE_ID_REFERENCE = void 0; -/* eslint-disable no-console */ -const child_process_1 = require("child_process"); -const fs = require("fs"); -const path_1 = require("path"); -/** - * Serialized form of the physical resource id for use in the operation parameters - */ -exports.PHYSICAL_RESOURCE_ID_REFERENCE = 'PHYSICAL:RESOURCEID:'; -/** - * Flattens a nested object - * - * @param object the object to be flattened - * @returns a flat object with path as keys - */ -function flatten(object) { - return Object.assign({}, ...function _flatten(child, path = []) { - return [].concat(...Object.keys(child) - .map(key => { - const childKey = Buffer.isBuffer(child[key]) ? child[key].toString('utf8') : child[key]; - return typeof childKey === 'object' && childKey !== null - ? _flatten(childKey, path.concat([key])) - : ({ [path.concat([key]).join('.')]: childKey }); - })); - }(object)); -} -exports.flatten = flatten; -/** - * Decodes encoded special values (physicalResourceId) - */ -function decodeSpecialValues(object, physicalResourceId) { - return JSON.parse(JSON.stringify(object), (_k, v) => { - switch (v) { - case exports.PHYSICAL_RESOURCE_ID_REFERENCE: - return physicalResourceId; - default: - return v; - } - }); -} -/** - * Filters the keys of an object. - */ -function filterKeys(object, pred) { - return Object.entries(object) - .reduce((acc, [k, v]) => pred(k) - ? { ...acc, [k]: v } - : acc, {}); -} -let latestSdkInstalled = false; -function forceSdkInstallation() { - latestSdkInstalled = false; -} -exports.forceSdkInstallation = forceSdkInstallation; -/** - * Installs latest AWS SDK v2 - */ -function installLatestSdk() { - console.log('Installing latest AWS SDK v2'); - // Both HOME and --prefix are needed here because /tmp is the only writable location - child_process_1.execSync('HOME=/tmp npm install aws-sdk@2 --production --no-package-lock --no-save --prefix /tmp'); - latestSdkInstalled = true; -} -// no currently patched services -const patchedServices = []; -/** - * Patches the AWS SDK by loading service models in the same manner as the actual SDK - */ -function patchSdk(awsSdk) { - const apiLoader = awsSdk.apiLoader; - patchedServices.forEach(({ serviceName, apiVersions }) => { - const lowerServiceName = serviceName.toLowerCase(); - if (!awsSdk.Service.hasService(lowerServiceName)) { - apiLoader.services[lowerServiceName] = {}; - awsSdk[serviceName] = awsSdk.Service.defineService(lowerServiceName, apiVersions); - } - else { - awsSdk.Service.addVersions(awsSdk[serviceName], apiVersions); - } - apiVersions.forEach(apiVersion => { - Object.defineProperty(apiLoader.services[lowerServiceName], apiVersion, { - get: function get() { - const modelFilePrefix = `aws-sdk-patch/${lowerServiceName}-${apiVersion}`; - const model = JSON.parse(fs.readFileSync(path_1.join(__dirname, `${modelFilePrefix}.service.json`), 'utf-8')); - model.paginators = JSON.parse(fs.readFileSync(path_1.join(__dirname, `${modelFilePrefix}.paginators.json`), 'utf-8')).pagination; - return model; - }, - enumerable: true, - configurable: true, - }); - }); - }); - return awsSdk; -} -/* eslint-disable @typescript-eslint/no-require-imports, import/no-extraneous-dependencies */ -async function handler(event, context) { - try { - let AWS; - if (!latestSdkInstalled && event.ResourceProperties.InstallLatestAwsSdk === 'true') { - try { - installLatestSdk(); - AWS = require('/tmp/node_modules/aws-sdk'); - } - catch (e) { - console.log(`Failed to install latest AWS SDK v2: ${e}`); - AWS = require('aws-sdk'); // Fallback to pre-installed version - } - } - else if (latestSdkInstalled) { - AWS = require('/tmp/node_modules/aws-sdk'); - } - else { - AWS = require('aws-sdk'); - } - try { - AWS = patchSdk(AWS); - } - catch (e) { - console.log(`Failed to patch AWS SDK: ${e}. Proceeding with the installed copy.`); - } - console.log(JSON.stringify({ ...event, ResponseURL: '...' })); - console.log('AWS SDK VERSION: ' + AWS.VERSION); - event.ResourceProperties.Create = decodeCall(event.ResourceProperties.Create); - event.ResourceProperties.Update = decodeCall(event.ResourceProperties.Update); - event.ResourceProperties.Delete = decodeCall(event.ResourceProperties.Delete); - // Default physical resource id - let physicalResourceId; - switch (event.RequestType) { - case 'Create': - physicalResourceId = event.ResourceProperties.Create?.physicalResourceId?.id ?? - event.ResourceProperties.Update?.physicalResourceId?.id ?? - event.ResourceProperties.Delete?.physicalResourceId?.id ?? - event.LogicalResourceId; - break; - case 'Update': - case 'Delete': - physicalResourceId = event.ResourceProperties[event.RequestType]?.physicalResourceId?.id ?? event.PhysicalResourceId; - break; - } - let flatData = {}; - let data = {}; - const call = event.ResourceProperties[event.RequestType]; - if (call) { - let credentials; - if (call.assumedRoleArn) { - const timestamp = (new Date()).getTime(); - const params = { - RoleArn: call.assumedRoleArn, - RoleSessionName: `${timestamp}-${physicalResourceId}`.substring(0, 64), - }; - credentials = new AWS.ChainableTemporaryCredentials({ - params: params, - }); - } - if (!Object.prototype.hasOwnProperty.call(AWS, call.service)) { - throw Error(`Service ${call.service} does not exist in AWS SDK version ${AWS.VERSION}.`); - } - const awsService = new AWS[call.service]({ - apiVersion: call.apiVersion, - credentials: credentials, - region: call.region, - }); - try { - const response = await awsService[call.action](call.parameters && decodeSpecialValues(call.parameters, physicalResourceId)).promise(); - flatData = { - apiVersion: awsService.config.apiVersion, - region: awsService.config.region, - ...flatten(response), - }; - let outputPaths; - if (call.outputPath) { - outputPaths = [call.outputPath]; - } - else if (call.outputPaths) { - outputPaths = call.outputPaths; - } - if (outputPaths) { - data = filterKeys(flatData, startsWithOneOf(outputPaths)); - } - else { - data = flatData; - } - } - catch (e) { - if (!call.ignoreErrorCodesMatching || !new RegExp(call.ignoreErrorCodesMatching).test(e.code)) { - throw e; - } - } - if (call.physicalResourceId?.responsePath) { - physicalResourceId = flatData[call.physicalResourceId.responsePath]; - } - } - await respond('SUCCESS', 'OK', physicalResourceId, data); - } - catch (e) { - console.log(e); - await respond('FAILED', e.message || 'Internal Error', context.logStreamName, {}); - } - function respond(responseStatus, reason, physicalResourceId, data) { - const responseBody = JSON.stringify({ - Status: responseStatus, - Reason: reason, - PhysicalResourceId: physicalResourceId, - StackId: event.StackId, - RequestId: event.RequestId, - LogicalResourceId: event.LogicalResourceId, - NoEcho: false, - Data: data, - }); - console.log('Responding', responseBody); - // eslint-disable-next-line @typescript-eslint/no-require-imports - const parsedUrl = require('url').parse(event.ResponseURL); - const requestOptions = { - hostname: parsedUrl.hostname, - path: parsedUrl.path, - method: 'PUT', - headers: { 'content-type': '', 'content-length': responseBody.length }, - }; - return new Promise((resolve, reject) => { - try { - // eslint-disable-next-line @typescript-eslint/no-require-imports - const request = require('https').request(requestOptions, resolve); - request.on('error', reject); - request.write(responseBody); - request.end(); - } - catch (e) { - reject(e); - } - }); - } -} -exports.handler = handler; -function decodeCall(call) { - if (!call) { - return undefined; - } - return JSON.parse(call); -} -function startsWithOneOf(searchStrings) { - return function (string) { - for (const searchString of searchStrings) { - if (string.startsWith(searchString)) { - return true; - } - } - return false; - }; -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsaURBQXlDO0FBQ3pDLHlCQUF5QjtBQUN6QiwrQkFBNEI7QUFTNUI7O0dBRUc7QUFDVSxRQUFBLDhCQUE4QixHQUFHLHNCQUFzQixDQUFDO0FBRXJFOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLE1BQWM7SUFDcEMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQixFQUFFLEVBQ0YsR0FBRyxTQUFTLFFBQVEsQ0FBQyxLQUFVLEVBQUUsT0FBaUIsRUFBRTtRQUNsRCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEYsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksUUFBUSxLQUFLLElBQUk7Z0JBQ3RELENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUNWLENBQUM7QUFDSixDQUFDO0FBYkQsMEJBYUM7QUFFRDs7R0FFRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBYyxFQUFFLGtCQUEwQjtJQUNyRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNsRCxRQUFRLENBQUMsRUFBRTtZQUNULEtBQUssc0NBQThCO2dCQUNqQyxPQUFPLGtCQUFrQixDQUFDO1lBQzVCO2dCQUNFLE9BQU8sQ0FBQyxDQUFDO1NBQ1o7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWMsRUFBRSxJQUE4QjtJQUNoRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1NBQzFCLE1BQU0sQ0FDTCxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0QixDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtRQUNwQixDQUFDLENBQUMsR0FBRyxFQUNQLEVBQUUsQ0FDSCxDQUFDO0FBQ04sQ0FBQztBQUVELElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO0FBRS9CLFNBQWdCLG9CQUFvQjtJQUNsQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7QUFDN0IsQ0FBQztBQUZELG9EQUVDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGdCQUFnQjtJQUN2QixPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDNUMsb0ZBQW9GO0lBQ3BGLHdCQUFRLENBQUMsd0ZBQXdGLENBQUMsQ0FBQztJQUNuRyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDNUIsQ0FBQztBQUVELGdDQUFnQztBQUNoQyxNQUFNLGVBQWUsR0FBcUQsRUFBRSxDQUFDO0FBQzdFOztHQUVHO0FBQ0gsU0FBUyxRQUFRLENBQUMsTUFBVztJQUMzQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO0lBQ25DLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFO1FBQ3ZELE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQ2hELFNBQVMsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDMUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1NBQ25GO2FBQU07WUFDTCxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7U0FDOUQ7UUFDRCxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFVBQVUsRUFBRTtnQkFDdEUsR0FBRyxFQUFFLFNBQVMsR0FBRztvQkFDZixNQUFNLGVBQWUsR0FBRyxpQkFBaUIsZ0JBQWdCLElBQUksVUFBVSxFQUFFLENBQUM7b0JBQzFFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsZUFBZSxlQUFlLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUN2RyxLQUFLLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsZUFBZSxrQkFBa0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO29CQUMxSCxPQUFPLEtBQUssQ0FBQztnQkFDZixDQUFDO2dCQUNELFVBQVUsRUFBRSxJQUFJO2dCQUNoQixZQUFZLEVBQUUsSUFBSTthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELDZGQUE2RjtBQUN0RixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsSUFBSTtRQUNGLElBQUksR0FBUSxDQUFDO1FBQ2IsSUFBSSxDQUFDLGtCQUFrQixJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsS0FBSyxNQUFNLEVBQUU7WUFDbEYsSUFBSTtnQkFDRixnQkFBZ0IsRUFBRSxDQUFDO2dCQUNuQixHQUFHLEdBQUcsT0FBTyxDQUFDLDJCQUEyQixDQUFDLENBQUM7YUFDNUM7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixPQUFPLENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN6RCxHQUFHLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsb0NBQW9DO2FBQy9EO1NBQ0Y7YUFBTSxJQUFJLGtCQUFrQixFQUFFO1lBQzdCLEdBQUcsR0FBRyxPQUFPLENBQUMsMkJBQTJCLENBQUMsQ0FBQztTQUM1QzthQUFNO1lBQ0wsR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUMxQjtRQUNELElBQUk7WUFDRixHQUFHLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3JCO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLHVDQUF1QyxDQUFDLENBQUM7U0FDbkY7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlELE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRS9DLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5RSxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUUsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzlFLCtCQUErQjtRQUMvQixJQUFJLGtCQUEwQixDQUFDO1FBQy9CLFFBQVEsS0FBSyxDQUFDLFdBQVcsRUFBRTtZQUN6QixLQUFLLFFBQVE7Z0JBQ1gsa0JBQWtCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxFQUFFO29CQUN2RCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLGtCQUFrQixFQUFFLEVBQUU7b0JBQ3ZELEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsRUFBRTtvQkFDdkQsS0FBSyxDQUFDLGlCQUFpQixDQUFDO2dCQUM3QyxNQUFNO1lBQ1IsS0FBSyxRQUFRLENBQUM7WUFDZCxLQUFLLFFBQVE7Z0JBQ1gsa0JBQWtCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxFQUFFLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDO2dCQUNySCxNQUFNO1NBQ1Q7UUFFRCxJQUFJLFFBQVEsR0FBOEIsRUFBRSxDQUFDO1FBQzdDLElBQUksSUFBSSxHQUE4QixFQUFFLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQTJCLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFakYsSUFBSSxJQUFJLEVBQUU7WUFFUixJQUFJLFdBQVcsQ0FBQztZQUNoQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQ3ZCLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUV6QyxNQUFNLE1BQU0sR0FBRztvQkFDYixPQUFPLEVBQUUsSUFBSSxDQUFDLGNBQWM7b0JBQzVCLGVBQWUsRUFBRSxHQUFHLFNBQVMsSUFBSSxrQkFBa0IsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO2lCQUN2RSxDQUFDO2dCQUVGLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQztvQkFDbEQsTUFBTSxFQUFFLE1BQU07aUJBQ2YsQ0FBQyxDQUFDO2FBQ0o7WUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQzVELE1BQU0sS0FBSyxDQUFDLFdBQVcsSUFBSSxDQUFDLE9BQU8sc0NBQXNDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO2FBQzFGO1lBQ0QsTUFBTSxVQUFVLEdBQUcsSUFBSyxHQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNoRCxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7Z0JBQzNCLFdBQVcsRUFBRSxXQUFXO2dCQUN4QixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07YUFDcEIsQ0FBQyxDQUFDO1lBRUgsSUFBSTtnQkFDRixNQUFNLFFBQVEsR0FBRyxNQUFNLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQzVDLElBQUksQ0FBQyxVQUFVLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3pGLFFBQVEsR0FBRztvQkFDVCxVQUFVLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxVQUFVO29CQUN4QyxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNO29CQUNoQyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7aUJBQ3JCLENBQUM7Z0JBRUYsSUFBSSxXQUFpQyxDQUFDO2dCQUN0QyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7b0JBQ25CLFdBQVcsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztpQkFDakM7cUJBQU0sSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO29CQUMzQixXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztpQkFDaEM7Z0JBRUQsSUFBSSxXQUFXLEVBQUU7b0JBQ2YsSUFBSSxHQUFHLFVBQVUsQ0FBQyxRQUFRLEVBQUUsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7aUJBQzNEO3FCQUFNO29CQUNMLElBQUksR0FBRyxRQUFRLENBQUM7aUJBQ2pCO2FBQ0Y7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixJQUFJLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRTtvQkFDN0YsTUFBTSxDQUFDLENBQUM7aUJBQ1Q7YUFDRjtZQUVELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLFlBQVksRUFBRTtnQkFDekMsa0JBQWtCLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUNyRTtTQUNGO1FBRUQsTUFBTSxPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLENBQUMsQ0FBQztLQUMxRDtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNmLE1BQU0sT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsT0FBTyxJQUFJLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDbkY7SUFFRCxTQUFTLE9BQU8sQ0FBQyxjQUFzQixFQUFFLE1BQWMsRUFBRSxrQkFBMEIsRUFBRSxJQUFTO1FBQzVGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDbEMsTUFBTSxFQUFFLGNBQWM7WUFDdEIsTUFBTSxFQUFFLE1BQU07WUFDZCxrQkFBa0IsRUFBRSxrQkFBa0I7WUFDdEMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztZQUMxQixpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO1lBQzFDLE1BQU0sRUFBRSxLQUFLO1lBQ2IsSUFBSSxFQUFFLElBQUk7U0FDWCxDQUFDLENBQUM7UUFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUV4QyxpRUFBaUU7UUFDakUsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDMUQsTUFBTSxjQUFjLEdBQUc7WUFDckIsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1lBQzVCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtZQUNwQixNQUFNLEVBQUUsS0FBSztZQUNiLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRTtTQUN2RSxDQUFDO1FBRUYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUNyQyxJQUFJO2dCQUNGLGlFQUFpRTtnQkFDakUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2xFLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM1QixPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7YUFDZjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNYO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQztBQWpKRCwwQkFpSkM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxJQUF3QjtJQUMxQyxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQUUsT0FBTyxTQUFTLENBQUM7S0FBRTtJQUNoQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLGFBQXVCO0lBQzlDLE9BQU8sVUFBUyxNQUFjO1FBQzVCLEtBQUssTUFBTSxZQUFZLElBQUksYUFBYSxFQUFFO1lBQ3hDLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFDbkMsT0FBTyxJQUFJLENBQUM7YUFDYjtTQUNGO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbi8vIGltcG9ydCB0aGUgQVdTTGFtYmRhIHBhY2thZ2UgZXhwbGljaXRseSxcbi8vIHdoaWNoIGlzIGdsb2JhbGx5IGF2YWlsYWJsZSBpbiB0aGUgTGFtYmRhIHJ1bnRpbWUsXG4vLyBhcyBvdGhlcndpc2UgbGlua2luZyB0aGlzIHJlcG9zaXRvcnkgd2l0aCBsaW5rLWFsbC5zaFxuLy8gZmFpbHMgaW4gdGhlIENESyBhcHAgZXhlY3V0ZWQgd2l0aCB0cy1ub2RlXG4vKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzLGltcG9ydC9uby11bnJlc29sdmVkICovXG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBBd3NTZGtDYWxsIH0gZnJvbSAnLi4vYXdzLWN1c3RvbS1yZXNvdXJjZSc7XG5cbi8qKlxuICogU2VyaWFsaXplZCBmb3JtIG9mIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBpZCBmb3IgdXNlIGluIHRoZSBvcGVyYXRpb24gcGFyYW1ldGVyc1xuICovXG5leHBvcnQgY29uc3QgUEhZU0lDQUxfUkVTT1VSQ0VfSURfUkVGRVJFTkNFID0gJ1BIWVNJQ0FMOlJFU09VUkNFSUQ6JztcblxuLyoqXG4gKiBGbGF0dGVucyBhIG5lc3RlZCBvYmplY3RcbiAqXG4gKiBAcGFyYW0gb2JqZWN0IHRoZSBvYmplY3QgdG8gYmUgZmxhdHRlbmVkXG4gKiBAcmV0dXJucyBhIGZsYXQgb2JqZWN0IHdpdGggcGF0aCBhcyBrZXlzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuKG9iamVjdDogb2JqZWN0KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKFxuICAgIHt9LFxuICAgIC4uLmZ1bmN0aW9uIF9mbGF0dGVuKGNoaWxkOiBhbnksIHBhdGg6IHN0cmluZ1tdID0gW10pOiBhbnkge1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdCguLi5PYmplY3Qua2V5cyhjaGlsZClcbiAgICAgICAgLm1hcChrZXkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkS2V5ID0gQnVmZmVyLmlzQnVmZmVyKGNoaWxkW2tleV0pID8gY2hpbGRba2V5XS50b1N0cmluZygndXRmOCcpIDogY2hpbGRba2V5XTtcbiAgICAgICAgICByZXR1cm4gdHlwZW9mIGNoaWxkS2V5ID09PSAnb2JqZWN0JyAmJiBjaGlsZEtleSAhPT0gbnVsbFxuICAgICAgICAgICAgPyBfZmxhdHRlbihjaGlsZEtleSwgcGF0aC5jb25jYXQoW2tleV0pKVxuICAgICAgICAgICAgOiAoeyBbcGF0aC5jb25jYXQoW2tleV0pLmpvaW4oJy4nKV06IGNoaWxkS2V5IH0pO1xuICAgICAgICB9KSk7XG4gICAgfShvYmplY3QpLFxuICApO1xufVxuXG4vKipcbiAqIERlY29kZXMgZW5jb2RlZCBzcGVjaWFsIHZhbHVlcyAocGh5c2ljYWxSZXNvdXJjZUlkKVxuICovXG5mdW5jdGlvbiBkZWNvZGVTcGVjaWFsVmFsdWVzKG9iamVjdDogb2JqZWN0LCBwaHlzaWNhbFJlc291cmNlSWQ6IHN0cmluZykge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmplY3QpLCAoX2ssIHYpID0+IHtcbiAgICBzd2l0Y2ggKHYpIHtcbiAgICAgIGNhc2UgUEhZU0lDQUxfUkVTT1VSQ0VfSURfUkVGRVJFTkNFOlxuICAgICAgICByZXR1cm4gcGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHY7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBGaWx0ZXJzIHRoZSBrZXlzIG9mIGFuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZmlsdGVyS2V5cyhvYmplY3Q6IG9iamVjdCwgcHJlZDogKGtleTogc3RyaW5nKSA9PiBib29sZWFuKSB7XG4gIHJldHVybiBPYmplY3QuZW50cmllcyhvYmplY3QpXG4gICAgLnJlZHVjZShcbiAgICAgIChhY2MsIFtrLCB2XSkgPT4gcHJlZChrKVxuICAgICAgICA/IHsgLi4uYWNjLCBba106IHYgfVxuICAgICAgICA6IGFjYyxcbiAgICAgIHt9LFxuICAgICk7XG59XG5cbmxldCBsYXRlc3RTZGtJbnN0YWxsZWQgPSBmYWxzZTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZvcmNlU2RrSW5zdGFsbGF0aW9uKCkge1xuICBsYXRlc3RTZGtJbnN0YWxsZWQgPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBJbnN0YWxscyBsYXRlc3QgQVdTIFNESyB2MlxuICovXG5mdW5jdGlvbiBpbnN0YWxsTGF0ZXN0U2RrKCk6IHZvaWQge1xuICBjb25zb2xlLmxvZygnSW5zdGFsbGluZyBsYXRlc3QgQVdTIFNESyB2MicpO1xuICAvLyBCb3RoIEhPTUUgYW5kIC0tcHJlZml4IGFyZSBuZWVkZWQgaGVyZSBiZWNhdXNlIC90bXAgaXMgdGhlIG9ubHkgd3JpdGFibGUgbG9jYXRpb25cbiAgZXhlY1N5bmMoJ0hPTUU9L3RtcCBucG0gaW5zdGFsbCBhd3Mtc2RrQDIgLS1wcm9kdWN0aW9uIC0tbm8tcGFja2FnZS1sb2NrIC0tbm8tc2F2ZSAtLXByZWZpeCAvdG1wJyk7XG4gIGxhdGVzdFNka0luc3RhbGxlZCA9IHRydWU7XG59XG5cbi8vIG5vIGN1cnJlbnRseSBwYXRjaGVkIHNlcnZpY2VzXG5jb25zdCBwYXRjaGVkU2VydmljZXM6IHsgc2VydmljZU5hbWU6IHN0cmluZzsgYXBpVmVyc2lvbnM6IHN0cmluZ1tdIH1bXSA9IFtdO1xuLyoqXG4gKiBQYXRjaGVzIHRoZSBBV1MgU0RLIGJ5IGxvYWRpbmcgc2VydmljZSBtb2RlbHMgaW4gdGhlIHNhbWUgbWFubmVyIGFzIHRoZSBhY3R1YWwgU0RLXG4gKi9cbmZ1bmN0aW9uIHBhdGNoU2RrKGF3c1NkazogYW55KTogYW55IHtcbiAgY29uc3QgYXBpTG9hZGVyID0gYXdzU2RrLmFwaUxvYWRlcjtcbiAgcGF0Y2hlZFNlcnZpY2VzLmZvckVhY2goKHsgc2VydmljZU5hbWUsIGFwaVZlcnNpb25zIH0pID0+IHtcbiAgICBjb25zdCBsb3dlclNlcnZpY2VOYW1lID0gc2VydmljZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoIWF3c1Nkay5TZXJ2aWNlLmhhc1NlcnZpY2UobG93ZXJTZXJ2aWNlTmFtZSkpIHtcbiAgICAgIGFwaUxvYWRlci5zZXJ2aWNlc1tsb3dlclNlcnZpY2VOYW1lXSA9IHt9O1xuICAgICAgYXdzU2RrW3NlcnZpY2VOYW1lXSA9IGF3c1Nkay5TZXJ2aWNlLmRlZmluZVNlcnZpY2UobG93ZXJTZXJ2aWNlTmFtZSwgYXBpVmVyc2lvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd3NTZGsuU2VydmljZS5hZGRWZXJzaW9ucyhhd3NTZGtbc2VydmljZU5hbWVdLCBhcGlWZXJzaW9ucyk7XG4gICAgfVxuICAgIGFwaVZlcnNpb25zLmZvckVhY2goYXBpVmVyc2lvbiA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXBpTG9hZGVyLnNlcnZpY2VzW2xvd2VyU2VydmljZU5hbWVdLCBhcGlWZXJzaW9uLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgIGNvbnN0IG1vZGVsRmlsZVByZWZpeCA9IGBhd3Mtc2RrLXBhdGNoLyR7bG93ZXJTZXJ2aWNlTmFtZX0tJHthcGlWZXJzaW9ufWA7XG4gICAgICAgICAgY29uc3QgbW9kZWwgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgYCR7bW9kZWxGaWxlUHJlZml4fS5zZXJ2aWNlLmpzb25gKSwgJ3V0Zi04JykpO1xuICAgICAgICAgIG1vZGVsLnBhZ2luYXRvcnMgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgYCR7bW9kZWxGaWxlUHJlZml4fS5wYWdpbmF0b3JzLmpzb25gKSwgJ3V0Zi04JykpLnBhZ2luYXRpb247XG4gICAgICAgICAgcmV0dXJuIG1vZGVsO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBhd3NTZGs7XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMsIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIHRyeSB7XG4gICAgbGV0IEFXUzogYW55O1xuICAgIGlmICghbGF0ZXN0U2RrSW5zdGFsbGVkICYmIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5JbnN0YWxsTGF0ZXN0QXdzU2RrID09PSAndHJ1ZScpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGluc3RhbGxMYXRlc3RTZGsoKTtcbiAgICAgICAgQVdTID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvYXdzLXNkaycpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgRmFpbGVkIHRvIGluc3RhbGwgbGF0ZXN0IEFXUyBTREsgdjI6ICR7ZX1gKTtcbiAgICAgICAgQVdTID0gcmVxdWlyZSgnYXdzLXNkaycpOyAvLyBGYWxsYmFjayB0byBwcmUtaW5zdGFsbGVkIHZlcnNpb25cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxhdGVzdFNka0luc3RhbGxlZCkge1xuICAgICAgQVdTID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvYXdzLXNkaycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBBV1MgPSByZXF1aXJlKCdhd3Mtc2RrJyk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBBV1MgPSBwYXRjaFNkayhBV1MpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUubG9nKGBGYWlsZWQgdG8gcGF0Y2ggQVdTIFNESzogJHtlfS4gUHJvY2VlZGluZyB3aXRoIHRoZSBpbnN0YWxsZWQgY29weS5gKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh7IC4uLmV2ZW50LCBSZXNwb25zZVVSTDogJy4uLicgfSkpO1xuICAgIGNvbnNvbGUubG9nKCdBV1MgU0RLIFZFUlNJT046ICcgKyBBV1MuVkVSU0lPTik7XG5cbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ3JlYXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ3JlYXRlKTtcbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlKTtcbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlKTtcbiAgICAvLyBEZWZhdWx0IHBoeXNpY2FsIHJlc291cmNlIGlkXG4gICAgbGV0IHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nO1xuICAgIHN3aXRjaCAoZXZlbnQuUmVxdWVzdFR5cGUpIHtcbiAgICAgIGNhc2UgJ0NyZWF0ZSc6XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGU/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLlVwZGF0ZT8ucGh5c2ljYWxSZXNvdXJjZUlkPy5pZCA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1VwZGF0ZSc6XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXNbZXZlbnQuUmVxdWVzdFR5cGVdPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgbGV0IGZsYXREYXRhOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgbGV0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBjYWxsOiBBd3NTZGtDYWxsIHwgdW5kZWZpbmVkID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzW2V2ZW50LlJlcXVlc3RUeXBlXTtcblxuICAgIGlmIChjYWxsKSB7XG5cbiAgICAgIGxldCBjcmVkZW50aWFscztcbiAgICAgIGlmIChjYWxsLmFzc3VtZWRSb2xlQXJuKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIFJvbGVBcm46IGNhbGwuYXNzdW1lZFJvbGVBcm4sXG4gICAgICAgICAgUm9sZVNlc3Npb25OYW1lOiBgJHt0aW1lc3RhbXB9LSR7cGh5c2ljYWxSZXNvdXJjZUlkfWAuc3Vic3RyaW5nKDAsIDY0KSxcbiAgICAgICAgfTtcblxuICAgICAgICBjcmVkZW50aWFscyA9IG5ldyBBV1MuQ2hhaW5hYmxlVGVtcG9yYXJ5Q3JlZGVudGlhbHMoe1xuICAgICAgICAgIHBhcmFtczogcGFyYW1zLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoQVdTLCBjYWxsLnNlcnZpY2UpKSB7XG4gICAgICAgIHRocm93IEVycm9yKGBTZXJ2aWNlICR7Y2FsbC5zZXJ2aWNlfSBkb2VzIG5vdCBleGlzdCBpbiBBV1MgU0RLIHZlcnNpb24gJHtBV1MuVkVSU0lPTn0uYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBhd3NTZXJ2aWNlID0gbmV3IChBV1MgYXMgYW55KVtjYWxsLnNlcnZpY2VdKHtcbiAgICAgICAgYXBpVmVyc2lvbjogY2FsbC5hcGlWZXJzaW9uLFxuICAgICAgICBjcmVkZW50aWFsczogY3JlZGVudGlhbHMsXG4gICAgICAgIHJlZ2lvbjogY2FsbC5yZWdpb24sXG4gICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBhd3NTZXJ2aWNlW2NhbGwuYWN0aW9uXShcbiAgICAgICAgICBjYWxsLnBhcmFtZXRlcnMgJiYgZGVjb2RlU3BlY2lhbFZhbHVlcyhjYWxsLnBhcmFtZXRlcnMsIHBoeXNpY2FsUmVzb3VyY2VJZCkpLnByb21pc2UoKTtcbiAgICAgICAgZmxhdERhdGEgPSB7XG4gICAgICAgICAgYXBpVmVyc2lvbjogYXdzU2VydmljZS5jb25maWcuYXBpVmVyc2lvbiwgLy8gRm9yIHRlc3QgcHVycG9zZXM6IGNoZWNrIGlmIGFwaVZlcnNpb24gd2FzIGNvcnJlY3RseSBwYXNzZWQuXG4gICAgICAgICAgcmVnaW9uOiBhd3NTZXJ2aWNlLmNvbmZpZy5yZWdpb24sIC8vIEZvciB0ZXN0IHB1cnBvc2VzOiBjaGVjayBpZiByZWdpb24gd2FzIGNvcnJlY3RseSBwYXNzZWQuXG4gICAgICAgICAgLi4uZmxhdHRlbihyZXNwb25zZSksXG4gICAgICAgIH07XG5cbiAgICAgICAgbGV0IG91dHB1dFBhdGhzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGNhbGwub3V0cHV0UGF0aCkge1xuICAgICAgICAgIG91dHB1dFBhdGhzID0gW2NhbGwub3V0cHV0UGF0aF07XG4gICAgICAgIH0gZWxzZSBpZiAoY2FsbC5vdXRwdXRQYXRocykge1xuICAgICAgICAgIG91dHB1dFBhdGhzID0gY2FsbC5vdXRwdXRQYXRocztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvdXRwdXRQYXRocykge1xuICAgICAgICAgIGRhdGEgPSBmaWx0ZXJLZXlzKGZsYXREYXRhLCBzdGFydHNXaXRoT25lT2Yob3V0cHV0UGF0aHMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhID0gZmxhdERhdGE7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKCFjYWxsLmlnbm9yZUVycm9yQ29kZXNNYXRjaGluZyB8fCAhbmV3IFJlZ0V4cChjYWxsLmlnbm9yZUVycm9yQ29kZXNNYXRjaGluZykudGVzdChlLmNvZGUpKSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY2FsbC5waHlzaWNhbFJlc291cmNlSWQ/LnJlc3BvbnNlUGF0aCkge1xuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQgPSBmbGF0RGF0YVtjYWxsLnBoeXNpY2FsUmVzb3VyY2VJZC5yZXNwb25zZVBhdGhdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGF3YWl0IHJlc3BvbmQoJ1NVQ0NFU1MnLCAnT0snLCBwaHlzaWNhbFJlc291cmNlSWQsIGRhdGEpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5sb2coZSk7XG4gICAgYXdhaXQgcmVzcG9uZCgnRkFJTEVEJywgZS5tZXNzYWdlIHx8ICdJbnRlcm5hbCBFcnJvcicsIGNvbnRleHQubG9nU3RyZWFtTmFtZSwge30pO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzcG9uZChyZXNwb25zZVN0YXR1czogc3RyaW5nLCByZWFzb246IHN0cmluZywgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmcsIGRhdGE6IGFueSkge1xuICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIFN0YXR1czogcmVzcG9uc2VTdGF0dXMsXG4gICAgICBSZWFzb246IHJlYXNvbixcbiAgICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICAgICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICAgIFJlcXVlc3RJZDogZXZlbnQuUmVxdWVzdElkLFxuICAgICAgTG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgICAgTm9FY2hvOiBmYWxzZSxcbiAgICAgIERhdGE6IGRhdGEsXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmxvZygnUmVzcG9uZGluZycsIHJlc3BvbnNlQm9keSk7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgIGNvbnN0IHBhcnNlZFVybCA9IHJlcXVpcmUoJ3VybCcpLnBhcnNlKGV2ZW50LlJlc3BvbnNlVVJMKTtcbiAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgIGhvc3RuYW1lOiBwYXJzZWRVcmwuaG9zdG5hbWUsXG4gICAgICBwYXRoOiBwYXJzZWRVcmwucGF0aCxcbiAgICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnJywgJ2NvbnRlbnQtbGVuZ3RoJzogcmVzcG9uc2VCb2R5Lmxlbmd0aCB9LFxuICAgIH07XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJ2h0dHBzJykucmVxdWVzdChyZXF1ZXN0T3B0aW9ucywgcmVzb2x2ZSk7XG4gICAgICAgIHJlcXVlc3Qub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgICByZXF1ZXN0LmVuZCgpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVjb2RlQ2FsbChjYWxsOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgaWYgKCFjYWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgcmV0dXJuIEpTT04ucGFyc2UoY2FsbCk7XG59XG5cbmZ1bmN0aW9uIHN0YXJ0c1dpdGhPbmVPZihzZWFyY2hTdHJpbmdzOiBzdHJpbmdbXSk6IChzdHJpbmc6IHN0cmluZykgPT4gYm9vbGVhbiB7XG4gIHJldHVybiBmdW5jdGlvbihzdHJpbmc6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3Qgc2VhcmNoU3RyaW5nIG9mIHNlYXJjaFN0cmluZ3MpIHtcbiAgICAgIGlmIChzdHJpbmcuc3RhcnRzV2l0aChzZWFyY2hTdHJpbmcpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js new file mode 100644 index 0000000000000..d913ab9defaa1 --- /dev/null +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js @@ -0,0 +1,253 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = exports.forceSdkInstallation = exports.flatten = exports.PHYSICAL_RESOURCE_ID_REFERENCE = void 0; +/* eslint-disable no-console */ +const child_process_1 = require("child_process"); +const fs = require("fs"); +const path_1 = require("path"); +/** + * Serialized form of the physical resource id for use in the operation parameters + */ +exports.PHYSICAL_RESOURCE_ID_REFERENCE = 'PHYSICAL:RESOURCEID:'; +/** + * Flattens a nested object + * + * @param object the object to be flattened + * @returns a flat object with path as keys + */ +function flatten(object) { + return Object.assign({}, ...function _flatten(child, path = []) { + return [].concat(...Object.keys(child) + .map(key => { + const childKey = Buffer.isBuffer(child[key]) ? child[key].toString('utf8') : child[key]; + return typeof childKey === 'object' && childKey !== null + ? _flatten(childKey, path.concat([key])) + : ({ [path.concat([key]).join('.')]: childKey }); + })); + }(object)); +} +exports.flatten = flatten; +/** + * Decodes encoded special values (physicalResourceId) + */ +function decodeSpecialValues(object, physicalResourceId) { + return JSON.parse(JSON.stringify(object), (_k, v) => { + switch (v) { + case exports.PHYSICAL_RESOURCE_ID_REFERENCE: + return physicalResourceId; + default: + return v; + } + }); +} +/** + * Filters the keys of an object. + */ +function filterKeys(object, pred) { + return Object.entries(object) + .reduce((acc, [k, v]) => pred(k) + ? { ...acc, [k]: v } + : acc, {}); +} +let latestSdkInstalled = false; +function forceSdkInstallation() { + latestSdkInstalled = false; +} +exports.forceSdkInstallation = forceSdkInstallation; +/** + * Installs latest AWS SDK v2 + */ +function installLatestSdk() { + console.log('Installing latest AWS SDK v2'); + // Both HOME and --prefix are needed here because /tmp is the only writable location + child_process_1.execSync('HOME=/tmp npm install aws-sdk@2 --production --no-package-lock --no-save --prefix /tmp'); + latestSdkInstalled = true; +} +// no currently patched services +const patchedServices = []; +/** + * Patches the AWS SDK by loading service models in the same manner as the actual SDK + */ +function patchSdk(awsSdk) { + const apiLoader = awsSdk.apiLoader; + patchedServices.forEach(({ serviceName, apiVersions }) => { + const lowerServiceName = serviceName.toLowerCase(); + if (!awsSdk.Service.hasService(lowerServiceName)) { + apiLoader.services[lowerServiceName] = {}; + awsSdk[serviceName] = awsSdk.Service.defineService(lowerServiceName, apiVersions); + } + else { + awsSdk.Service.addVersions(awsSdk[serviceName], apiVersions); + } + apiVersions.forEach(apiVersion => { + Object.defineProperty(apiLoader.services[lowerServiceName], apiVersion, { + get: function get() { + const modelFilePrefix = `aws-sdk-patch/${lowerServiceName}-${apiVersion}`; + const model = JSON.parse(fs.readFileSync(path_1.join(__dirname, `${modelFilePrefix}.service.json`), 'utf-8')); + model.paginators = JSON.parse(fs.readFileSync(path_1.join(__dirname, `${modelFilePrefix}.paginators.json`), 'utf-8')).pagination; + return model; + }, + enumerable: true, + configurable: true, + }); + }); + }); + return awsSdk; +} +/* eslint-disable @typescript-eslint/no-require-imports, import/no-extraneous-dependencies */ +async function handler(event, context) { + try { + let AWS; + if (!latestSdkInstalled && event.ResourceProperties.InstallLatestAwsSdk === 'true') { + try { + installLatestSdk(); + AWS = require('/tmp/node_modules/aws-sdk'); + } + catch (e) { + console.log(`Failed to install latest AWS SDK v2: ${e}`); + AWS = require('aws-sdk'); // Fallback to pre-installed version + } + } + else if (latestSdkInstalled) { + AWS = require('/tmp/node_modules/aws-sdk'); + } + else { + AWS = require('aws-sdk'); + } + try { + AWS = patchSdk(AWS); + } + catch (e) { + console.log(`Failed to patch AWS SDK: ${e}. Proceeding with the installed copy.`); + } + console.log(JSON.stringify({ ...event, ResponseURL: '...' })); + console.log('AWS SDK VERSION: ' + AWS.VERSION); + event.ResourceProperties.Create = decodeCall(event.ResourceProperties.Create); + event.ResourceProperties.Update = decodeCall(event.ResourceProperties.Update); + event.ResourceProperties.Delete = decodeCall(event.ResourceProperties.Delete); + // Default physical resource id + let physicalResourceId; + switch (event.RequestType) { + case 'Create': + physicalResourceId = event.ResourceProperties.Create?.physicalResourceId?.id ?? + event.ResourceProperties.Update?.physicalResourceId?.id ?? + event.ResourceProperties.Delete?.physicalResourceId?.id ?? + event.LogicalResourceId; + break; + case 'Update': + case 'Delete': + physicalResourceId = event.ResourceProperties[event.RequestType]?.physicalResourceId?.id ?? event.PhysicalResourceId; + break; + } + let flatData = {}; + let data = {}; + const call = event.ResourceProperties[event.RequestType]; + if (call) { + let credentials; + if (call.assumedRoleArn) { + const timestamp = (new Date()).getTime(); + const params = { + RoleArn: call.assumedRoleArn, + RoleSessionName: `${timestamp}-${physicalResourceId}`.substring(0, 64), + }; + credentials = new AWS.ChainableTemporaryCredentials({ + params: params, + stsConfig: { stsRegionalEndpoints: 'regional' }, + }); + } + if (!Object.prototype.hasOwnProperty.call(AWS, call.service)) { + throw Error(`Service ${call.service} does not exist in AWS SDK version ${AWS.VERSION}.`); + } + const awsService = new AWS[call.service]({ + apiVersion: call.apiVersion, + credentials: credentials, + region: call.region, + }); + try { + const response = await awsService[call.action](call.parameters && decodeSpecialValues(call.parameters, physicalResourceId)).promise(); + flatData = { + apiVersion: awsService.config.apiVersion, + region: awsService.config.region, + ...flatten(response), + }; + let outputPaths; + if (call.outputPath) { + outputPaths = [call.outputPath]; + } + else if (call.outputPaths) { + outputPaths = call.outputPaths; + } + if (outputPaths) { + data = filterKeys(flatData, startsWithOneOf(outputPaths)); + } + else { + data = flatData; + } + } + catch (e) { + if (!call.ignoreErrorCodesMatching || !new RegExp(call.ignoreErrorCodesMatching).test(e.code)) { + throw e; + } + } + if (call.physicalResourceId?.responsePath) { + physicalResourceId = flatData[call.physicalResourceId.responsePath]; + } + } + await respond('SUCCESS', 'OK', physicalResourceId, data); + } + catch (e) { + console.log(e); + await respond('FAILED', e.message || 'Internal Error', context.logStreamName, {}); + } + function respond(responseStatus, reason, physicalResourceId, data) { + const responseBody = JSON.stringify({ + Status: responseStatus, + Reason: reason, + PhysicalResourceId: physicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + NoEcho: false, + Data: data, + }); + console.log('Responding', responseBody); + // eslint-disable-next-line @typescript-eslint/no-require-imports + const parsedUrl = require('url').parse(event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + return new Promise((resolve, reject) => { + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const request = require('https').request(requestOptions, resolve); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); + } +} +exports.handler = handler; +function decodeCall(call) { + if (!call) { + return undefined; + } + return JSON.parse(call); +} +function startsWithOneOf(searchStrings) { + return function (string) { + for (const searchString of searchStrings) { + if (string.startsWith(searchString)) { + return true; + } + } + return false; + }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsaURBQXlDO0FBQ3pDLHlCQUF5QjtBQUN6QiwrQkFBNEI7QUFTNUI7O0dBRUc7QUFDVSxRQUFBLDhCQUE4QixHQUFHLHNCQUFzQixDQUFDO0FBRXJFOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLE1BQWM7SUFDcEMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQixFQUFFLEVBQ0YsR0FBRyxTQUFTLFFBQVEsQ0FBQyxLQUFVLEVBQUUsT0FBaUIsRUFBRTtRQUNsRCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEYsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksUUFBUSxLQUFLLElBQUk7Z0JBQ3RELENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUNWLENBQUM7QUFDSixDQUFDO0FBYkQsMEJBYUM7QUFFRDs7R0FFRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBYyxFQUFFLGtCQUEwQjtJQUNyRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNsRCxRQUFRLENBQUMsRUFBRTtZQUNULEtBQUssc0NBQThCO2dCQUNqQyxPQUFPLGtCQUFrQixDQUFDO1lBQzVCO2dCQUNFLE9BQU8sQ0FBQyxDQUFDO1NBQ1o7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsVUFBVSxDQUFDLE1BQWMsRUFBRSxJQUE4QjtJQUNoRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1NBQzFCLE1BQU0sQ0FDTCxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0QixDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtRQUNwQixDQUFDLENBQUMsR0FBRyxFQUNQLEVBQUUsQ0FDSCxDQUFDO0FBQ04sQ0FBQztBQUVELElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO0FBRS9CLFNBQWdCLG9CQUFvQjtJQUNsQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7QUFDN0IsQ0FBQztBQUZELG9EQUVDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGdCQUFnQjtJQUN2QixPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDNUMsb0ZBQW9GO0lBQ3BGLHdCQUFRLENBQUMsd0ZBQXdGLENBQUMsQ0FBQztJQUNuRyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDNUIsQ0FBQztBQUVELGdDQUFnQztBQUNoQyxNQUFNLGVBQWUsR0FBcUQsRUFBRSxDQUFDO0FBQzdFOztHQUVHO0FBQ0gsU0FBUyxRQUFRLENBQUMsTUFBVztJQUMzQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO0lBQ25DLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFO1FBQ3ZELE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQ2hELFNBQVMsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDMUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1NBQ25GO2FBQU07WUFDTCxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7U0FDOUQ7UUFDRCxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFVBQVUsRUFBRTtnQkFDdEUsR0FBRyxFQUFFLFNBQVMsR0FBRztvQkFDZixNQUFNLGVBQWUsR0FBRyxpQkFBaUIsZ0JBQWdCLElBQUksVUFBVSxFQUFFLENBQUM7b0JBQzFFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsZUFBZSxlQUFlLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUN2RyxLQUFLLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsZUFBZSxrQkFBa0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO29CQUMxSCxPQUFPLEtBQUssQ0FBQztnQkFDZixDQUFDO2dCQUNELFVBQVUsRUFBRSxJQUFJO2dCQUNoQixZQUFZLEVBQUUsSUFBSTthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELDZGQUE2RjtBQUN0RixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsSUFBSTtRQUNGLElBQUksR0FBUSxDQUFDO1FBQ2IsSUFBSSxDQUFDLGtCQUFrQixJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsS0FBSyxNQUFNLEVBQUU7WUFDbEYsSUFBSTtnQkFDRixnQkFBZ0IsRUFBRSxDQUFDO2dCQUNuQixHQUFHLEdBQUcsT0FBTyxDQUFDLDJCQUEyQixDQUFDLENBQUM7YUFDNUM7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixPQUFPLENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN6RCxHQUFHLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsb0NBQW9DO2FBQy9EO1NBQ0Y7YUFBTSxJQUFJLGtCQUFrQixFQUFFO1lBQzdCLEdBQUcsR0FBRyxPQUFPLENBQUMsMkJBQTJCLENBQUMsQ0FBQztTQUM1QzthQUFNO1lBQ0wsR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUMxQjtRQUNELElBQUk7WUFDRixHQUFHLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3JCO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLHVDQUF1QyxDQUFDLENBQUM7U0FDbkY7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlELE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRS9DLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5RSxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUUsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzlFLCtCQUErQjtRQUMvQixJQUFJLGtCQUEwQixDQUFDO1FBQy9CLFFBQVEsS0FBSyxDQUFDLFdBQVcsRUFBRTtZQUN6QixLQUFLLFFBQVE7Z0JBQ1gsa0JBQWtCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxFQUFFO29CQUN2RCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLGtCQUFrQixFQUFFLEVBQUU7b0JBQ3ZELEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsRUFBRTtvQkFDdkQsS0FBSyxDQUFDLGlCQUFpQixDQUFDO2dCQUM3QyxNQUFNO1lBQ1IsS0FBSyxRQUFRLENBQUM7WUFDZCxLQUFLLFFBQVE7Z0JBQ1gsa0JBQWtCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxFQUFFLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDO2dCQUNySCxNQUFNO1NBQ1Q7UUFFRCxJQUFJLFFBQVEsR0FBOEIsRUFBRSxDQUFDO1FBQzdDLElBQUksSUFBSSxHQUE4QixFQUFFLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQTJCLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFakYsSUFBSSxJQUFJLEVBQUU7WUFFUixJQUFJLFdBQVcsQ0FBQztZQUNoQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQ3ZCLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUV6QyxNQUFNLE1BQU0sR0FBRztvQkFDYixPQUFPLEVBQUUsSUFBSSxDQUFDLGNBQWM7b0JBQzVCLGVBQWUsRUFBRSxHQUFHLFNBQVMsSUFBSSxrQkFBa0IsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO2lCQUN2RSxDQUFDO2dCQUVGLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQztvQkFDbEQsTUFBTSxFQUFFLE1BQU07b0JBQ2QsU0FBUyxFQUFFLEVBQUUsb0JBQW9CLEVBQUUsVUFBVSxFQUFFO2lCQUNoRCxDQUFDLENBQUM7YUFDSjtZQUVELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDNUQsTUFBTSxLQUFLLENBQUMsV0FBVyxJQUFJLENBQUMsT0FBTyxzQ0FBc0MsR0FBRyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7YUFDMUY7WUFDRCxNQUFNLFVBQVUsR0FBRyxJQUFLLEdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ2hELFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtnQkFDM0IsV0FBVyxFQUFFLFdBQVc7Z0JBQ3hCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTthQUNwQixDQUFDLENBQUM7WUFFSCxJQUFJO2dCQUNGLE1BQU0sUUFBUSxHQUFHLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FDNUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDekYsUUFBUSxHQUFHO29CQUNULFVBQVUsRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLFVBQVU7b0JBQ3hDLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU07b0JBQ2hDLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztpQkFDckIsQ0FBQztnQkFFRixJQUFJLFdBQWlDLENBQUM7Z0JBQ3RDLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtvQkFDbkIsV0FBVyxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2lCQUNqQztxQkFBTSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQzNCLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO2lCQUNoQztnQkFFRCxJQUFJLFdBQVcsRUFBRTtvQkFDZixJQUFJLEdBQUcsVUFBVSxDQUFDLFFBQVEsRUFBRSxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztpQkFDM0Q7cUJBQU07b0JBQ0wsSUFBSSxHQUFHLFFBQVEsQ0FBQztpQkFDakI7YUFDRjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUM3RixNQUFNLENBQUMsQ0FBQztpQkFDVDthQUNGO1lBRUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFFO2dCQUN6QyxrQkFBa0IsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQ3JFO1NBQ0Y7UUFFRCxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLElBQUksQ0FBQyxDQUFDO0tBQzFEO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2YsTUFBTSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLElBQUksZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztLQUNuRjtJQUVELFNBQVMsT0FBTyxDQUFDLGNBQXNCLEVBQUUsTUFBYyxFQUFFLGtCQUEwQixFQUFFLElBQVM7UUFDNUYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNsQyxNQUFNLEVBQUUsY0FBYztZQUN0QixNQUFNLEVBQUUsTUFBTTtZQUNkLGtCQUFrQixFQUFFLGtCQUFrQjtZQUN0QyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87WUFDdEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1lBQzFCLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxpQkFBaUI7WUFDMUMsTUFBTSxFQUFFLEtBQUs7WUFDYixJQUFJLEVBQUUsSUFBSTtTQUNYLENBQUMsQ0FBQztRQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRXhDLGlFQUFpRTtRQUNqRSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxRCxNQUFNLGNBQWMsR0FBRztZQUNyQixRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7WUFDNUIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1lBQ3BCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFO1NBQ3ZFLENBQUM7UUFFRixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUk7Z0JBQ0YsaUVBQWlFO2dCQUNqRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUNmO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ1g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDO0FBbEpELDBCQWtKQztBQUVELFNBQVMsVUFBVSxDQUFDLElBQXdCO0lBQzFDLElBQUksQ0FBQyxJQUFJLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQztLQUFFO0lBQ2hDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsYUFBdUI7SUFDOUMsT0FBTyxVQUFTLE1BQWM7UUFDNUIsS0FBSyxNQUFNLFlBQVksSUFBSSxhQUFhLEVBQUU7WUFDeEMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNuQyxPQUFPLElBQUksQ0FBQzthQUNiO1NBQ0Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyBleGVjU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuLy8gaW1wb3J0IHRoZSBBV1NMYW1iZGEgcGFja2FnZSBleHBsaWNpdGx5LFxuLy8gd2hpY2ggaXMgZ2xvYmFsbHkgYXZhaWxhYmxlIGluIHRoZSBMYW1iZGEgcnVudGltZSxcbi8vIGFzIG90aGVyd2lzZSBsaW5raW5nIHRoaXMgcmVwb3NpdG9yeSB3aXRoIGxpbmstYWxsLnNoXG4vLyBmYWlscyBpbiB0aGUgQ0RLIGFwcCBleGVjdXRlZCB3aXRoIHRzLW5vZGVcbi8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMsaW1wb3J0L25vLXVucmVzb2x2ZWQgKi9cbmltcG9ydCAqIGFzIEFXU0xhbWJkYSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7IEF3c1Nka0NhbGwgfSBmcm9tICcuLi9hd3MtY3VzdG9tLXJlc291cmNlJztcblxuLyoqXG4gKiBTZXJpYWxpemVkIGZvcm0gb2YgdGhlIHBoeXNpY2FsIHJlc291cmNlIGlkIGZvciB1c2UgaW4gdGhlIG9wZXJhdGlvbiBwYXJhbWV0ZXJzXG4gKi9cbmV4cG9ydCBjb25zdCBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0UgPSAnUEhZU0lDQUw6UkVTT1VSQ0VJRDonO1xuXG4vKipcbiAqIEZsYXR0ZW5zIGEgbmVzdGVkIG9iamVjdFxuICpcbiAqIEBwYXJhbSBvYmplY3QgdGhlIG9iamVjdCB0byBiZSBmbGF0dGVuZWRcbiAqIEByZXR1cm5zIGEgZmxhdCBvYmplY3Qgd2l0aCBwYXRoIGFzIGtleXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4ob2JqZWN0OiBvYmplY3QpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oXG4gICAge30sXG4gICAgLi4uZnVuY3Rpb24gX2ZsYXR0ZW4oY2hpbGQ6IGFueSwgcGF0aDogc3RyaW5nW10gPSBbXSk6IGFueSB7XG4gICAgICByZXR1cm4gW10uY29uY2F0KC4uLk9iamVjdC5rZXlzKGNoaWxkKVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgY2hpbGRLZXkgPSBCdWZmZXIuaXNCdWZmZXIoY2hpbGRba2V5XSkgPyBjaGlsZFtrZXldLnRvU3RyaW5nKCd1dGY4JykgOiBjaGlsZFtrZXldO1xuICAgICAgICAgIHJldHVybiB0eXBlb2YgY2hpbGRLZXkgPT09ICdvYmplY3QnICYmIGNoaWxkS2V5ICE9PSBudWxsXG4gICAgICAgICAgICA/IF9mbGF0dGVuKGNoaWxkS2V5LCBwYXRoLmNvbmNhdChba2V5XSkpXG4gICAgICAgICAgICA6ICh7IFtwYXRoLmNvbmNhdChba2V5XSkuam9pbignLicpXTogY2hpbGRLZXkgfSk7XG4gICAgICAgIH0pKTtcbiAgICB9KG9iamVjdCksXG4gICk7XG59XG5cbi8qKlxuICogRGVjb2RlcyBlbmNvZGVkIHNwZWNpYWwgdmFsdWVzIChwaHlzaWNhbFJlc291cmNlSWQpXG4gKi9cbmZ1bmN0aW9uIGRlY29kZVNwZWNpYWxWYWx1ZXMob2JqZWN0OiBvYmplY3QsIHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iamVjdCksIChfaywgdikgPT4ge1xuICAgIHN3aXRjaCAodikge1xuICAgICAgY2FzZSBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0U6XG4gICAgICAgIHJldHVybiBwaHlzaWNhbFJlc291cmNlSWQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdjtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIEZpbHRlcnMgdGhlIGtleXMgb2YgYW4gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBmaWx0ZXJLZXlzKG9iamVjdDogb2JqZWN0LCBwcmVkOiAoa2V5OiBzdHJpbmcpID0+IGJvb2xlYW4pIHtcbiAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iamVjdClcbiAgICAucmVkdWNlKFxuICAgICAgKGFjYywgW2ssIHZdKSA9PiBwcmVkKGspXG4gICAgICAgID8geyAuLi5hY2MsIFtrXTogdiB9XG4gICAgICAgIDogYWNjLFxuICAgICAge30sXG4gICAgKTtcbn1cblxubGV0IGxhdGVzdFNka0luc3RhbGxlZCA9IGZhbHNlO1xuXG5leHBvcnQgZnVuY3Rpb24gZm9yY2VTZGtJbnN0YWxsYXRpb24oKSB7XG4gIGxhdGVzdFNka0luc3RhbGxlZCA9IGZhbHNlO1xufVxuXG4vKipcbiAqIEluc3RhbGxzIGxhdGVzdCBBV1MgU0RLIHYyXG4gKi9cbmZ1bmN0aW9uIGluc3RhbGxMYXRlc3RTZGsoKTogdm9pZCB7XG4gIGNvbnNvbGUubG9nKCdJbnN0YWxsaW5nIGxhdGVzdCBBV1MgU0RLIHYyJyk7XG4gIC8vIEJvdGggSE9NRSBhbmQgLS1wcmVmaXggYXJlIG5lZWRlZCBoZXJlIGJlY2F1c2UgL3RtcCBpcyB0aGUgb25seSB3cml0YWJsZSBsb2NhdGlvblxuICBleGVjU3luYygnSE9NRT0vdG1wIG5wbSBpbnN0YWxsIGF3cy1zZGtAMiAtLXByb2R1Y3Rpb24gLS1uby1wYWNrYWdlLWxvY2sgLS1uby1zYXZlIC0tcHJlZml4IC90bXAnKTtcbiAgbGF0ZXN0U2RrSW5zdGFsbGVkID0gdHJ1ZTtcbn1cblxuLy8gbm8gY3VycmVudGx5IHBhdGNoZWQgc2VydmljZXNcbmNvbnN0IHBhdGNoZWRTZXJ2aWNlczogeyBzZXJ2aWNlTmFtZTogc3RyaW5nOyBhcGlWZXJzaW9uczogc3RyaW5nW10gfVtdID0gW107XG4vKipcbiAqIFBhdGNoZXMgdGhlIEFXUyBTREsgYnkgbG9hZGluZyBzZXJ2aWNlIG1vZGVscyBpbiB0aGUgc2FtZSBtYW5uZXIgYXMgdGhlIGFjdHVhbCBTREtcbiAqL1xuZnVuY3Rpb24gcGF0Y2hTZGsoYXdzU2RrOiBhbnkpOiBhbnkge1xuICBjb25zdCBhcGlMb2FkZXIgPSBhd3NTZGsuYXBpTG9hZGVyO1xuICBwYXRjaGVkU2VydmljZXMuZm9yRWFjaCgoeyBzZXJ2aWNlTmFtZSwgYXBpVmVyc2lvbnMgfSkgPT4ge1xuICAgIGNvbnN0IGxvd2VyU2VydmljZU5hbWUgPSBzZXJ2aWNlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICghYXdzU2RrLlNlcnZpY2UuaGFzU2VydmljZShsb3dlclNlcnZpY2VOYW1lKSkge1xuICAgICAgYXBpTG9hZGVyLnNlcnZpY2VzW2xvd2VyU2VydmljZU5hbWVdID0ge307XG4gICAgICBhd3NTZGtbc2VydmljZU5hbWVdID0gYXdzU2RrLlNlcnZpY2UuZGVmaW5lU2VydmljZShsb3dlclNlcnZpY2VOYW1lLCBhcGlWZXJzaW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3c1Nkay5TZXJ2aWNlLmFkZFZlcnNpb25zKGF3c1Nka1tzZXJ2aWNlTmFtZV0sIGFwaVZlcnNpb25zKTtcbiAgICB9XG4gICAgYXBpVmVyc2lvbnMuZm9yRWFjaChhcGlWZXJzaW9uID0+IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcGlMb2FkZXIuc2VydmljZXNbbG93ZXJTZXJ2aWNlTmFtZV0sIGFwaVZlcnNpb24sIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgICAgY29uc3QgbW9kZWxGaWxlUHJlZml4ID0gYGF3cy1zZGstcGF0Y2gvJHtsb3dlclNlcnZpY2VOYW1lfS0ke2FwaVZlcnNpb259YDtcbiAgICAgICAgICBjb25zdCBtb2RlbCA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGpvaW4oX19kaXJuYW1lLCBgJHttb2RlbEZpbGVQcmVmaXh9LnNlcnZpY2UuanNvbmApLCAndXRmLTgnKSk7XG4gICAgICAgICAgbW9kZWwucGFnaW5hdG9ycyA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGpvaW4oX19kaXJuYW1lLCBgJHttb2RlbEZpbGVQcmVmaXh9LnBhZ2luYXRvcnMuanNvbmApLCAndXRmLTgnKSkucGFnaW5hdGlvbjtcbiAgICAgICAgICByZXR1cm4gbW9kZWw7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIGF3c1Nkaztcbn1cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cywgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpIHtcbiAgdHJ5IHtcbiAgICBsZXQgQVdTOiBhbnk7XG4gICAgaWYgKCFsYXRlc3RTZGtJbnN0YWxsZWQgJiYgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkluc3RhbGxMYXRlc3RBd3NTZGsgPT09ICd0cnVlJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW5zdGFsbExhdGVzdFNkaygpO1xuICAgICAgICBBV1MgPSByZXF1aXJlKCcvdG1wL25vZGVfbW9kdWxlcy9hd3Mtc2RrJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBGYWlsZWQgdG8gaW5zdGFsbCBsYXRlc3QgQVdTIFNESyB2MjogJHtlfWApO1xuICAgICAgICBBV1MgPSByZXF1aXJlKCdhd3Mtc2RrJyk7IC8vIEZhbGxiYWNrIHRvIHByZS1pbnN0YWxsZWQgdmVyc2lvblxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobGF0ZXN0U2RrSW5zdGFsbGVkKSB7XG4gICAgICBBV1MgPSByZXF1aXJlKCcvdG1wL25vZGVfbW9kdWxlcy9hd3Mtc2RrJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIEFXUyA9IHJlcXVpcmUoJ2F3cy1zZGsnKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIEFXUyA9IHBhdGNoU2RrKEFXUyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5sb2coYEZhaWxlZCB0byBwYXRjaCBBV1MgU0RLOiAke2V9LiBQcm9jZWVkaW5nIHdpdGggdGhlIGluc3RhbGxlZCBjb3B5LmApO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9KSk7XG4gICAgY29uc29sZS5sb2coJ0FXUyBTREsgVkVSU0lPTjogJyArIEFXUy5WRVJTSU9OKTtcblxuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGUpO1xuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5VcGRhdGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5VcGRhdGUpO1xuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGUpO1xuICAgIC8vIERlZmF1bHQgcGh5c2ljYWwgcmVzb3VyY2UgaWRcbiAgICBsZXQgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmc7XG4gICAgc3dpdGNoIChldmVudC5SZXF1ZXN0VHlwZSkge1xuICAgICAgY2FzZSAnQ3JlYXRlJzpcbiAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkNyZWF0ZT8ucGh5c2ljYWxSZXNvdXJjZUlkPy5pZCA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGU/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuTG9naWNhbFJlc291cmNlSWQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnVXBkYXRlJzpcbiAgICAgIGNhc2UgJ0RlbGV0ZSc6XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllc1tldmVudC5SZXF1ZXN0VHlwZV0/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz8gZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBsZXQgZmxhdERhdGE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBsZXQgZGF0YTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIGNvbnN0IGNhbGw6IEF3c1Nka0NhbGwgfCB1bmRlZmluZWQgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXNbZXZlbnQuUmVxdWVzdFR5cGVdO1xuXG4gICAgaWYgKGNhbGwpIHtcblxuICAgICAgbGV0IGNyZWRlbnRpYWxzO1xuICAgICAgaWYgKGNhbGwuYXNzdW1lZFJvbGVBcm4pIHtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgUm9sZUFybjogY2FsbC5hc3N1bWVkUm9sZUFybixcbiAgICAgICAgICBSb2xlU2Vzc2lvbk5hbWU6IGAke3RpbWVzdGFtcH0tJHtwaHlzaWNhbFJlc291cmNlSWR9YC5zdWJzdHJpbmcoMCwgNjQpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNyZWRlbnRpYWxzID0gbmV3IEFXUy5DaGFpbmFibGVUZW1wb3JhcnlDcmVkZW50aWFscyh7XG4gICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgICAgc3RzQ29uZmlnOiB7IHN0c1JlZ2lvbmFsRW5kcG9pbnRzOiAncmVnaW9uYWwnIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChBV1MsIGNhbGwuc2VydmljZSkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoYFNlcnZpY2UgJHtjYWxsLnNlcnZpY2V9IGRvZXMgbm90IGV4aXN0IGluIEFXUyBTREsgdmVyc2lvbiAke0FXUy5WRVJTSU9OfS5gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGF3c1NlcnZpY2UgPSBuZXcgKEFXUyBhcyBhbnkpW2NhbGwuc2VydmljZV0oe1xuICAgICAgICBhcGlWZXJzaW9uOiBjYWxsLmFwaVZlcnNpb24sXG4gICAgICAgIGNyZWRlbnRpYWxzOiBjcmVkZW50aWFscyxcbiAgICAgICAgcmVnaW9uOiBjYWxsLnJlZ2lvbixcbiAgICAgIH0pO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF3c1NlcnZpY2VbY2FsbC5hY3Rpb25dKFxuICAgICAgICAgIGNhbGwucGFyYW1ldGVycyAmJiBkZWNvZGVTcGVjaWFsVmFsdWVzKGNhbGwucGFyYW1ldGVycywgcGh5c2ljYWxSZXNvdXJjZUlkKSkucHJvbWlzZSgpO1xuICAgICAgICBmbGF0RGF0YSA9IHtcbiAgICAgICAgICBhcGlWZXJzaW9uOiBhd3NTZXJ2aWNlLmNvbmZpZy5hcGlWZXJzaW9uLCAvLyBGb3IgdGVzdCBwdXJwb3NlczogY2hlY2sgaWYgYXBpVmVyc2lvbiB3YXMgY29ycmVjdGx5IHBhc3NlZC5cbiAgICAgICAgICByZWdpb246IGF3c1NlcnZpY2UuY29uZmlnLnJlZ2lvbiwgLy8gRm9yIHRlc3QgcHVycG9zZXM6IGNoZWNrIGlmIHJlZ2lvbiB3YXMgY29ycmVjdGx5IHBhc3NlZC5cbiAgICAgICAgICAuLi5mbGF0dGVuKHJlc3BvbnNlKSxcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgb3V0cHV0UGF0aHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoY2FsbC5vdXRwdXRQYXRoKSB7XG4gICAgICAgICAgb3V0cHV0UGF0aHMgPSBbY2FsbC5vdXRwdXRQYXRoXTtcbiAgICAgICAgfSBlbHNlIGlmIChjYWxsLm91dHB1dFBhdGhzKSB7XG4gICAgICAgICAgb3V0cHV0UGF0aHMgPSBjYWxsLm91dHB1dFBhdGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG91dHB1dFBhdGhzKSB7XG4gICAgICAgICAgZGF0YSA9IGZpbHRlcktleXMoZmxhdERhdGEsIHN0YXJ0c1dpdGhPbmVPZihvdXRwdXRQYXRocykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGEgPSBmbGF0RGF0YTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIWNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nIHx8ICFuZXcgUmVnRXhwKGNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nKS50ZXN0KGUuY29kZSkpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjYWxsLnBoeXNpY2FsUmVzb3VyY2VJZD8ucmVzcG9uc2VQYXRoKSB7XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGZsYXREYXRhW2NhbGwucGh5c2ljYWxSZXNvdXJjZUlkLnJlc3BvbnNlUGF0aF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgcmVzcG9uZCgnU1VDQ0VTUycsICdPSycsIHBoeXNpY2FsUmVzb3VyY2VJZCwgZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmxvZyhlKTtcbiAgICBhd2FpdCByZXNwb25kKCdGQUlMRUQnLCBlLm1lc3NhZ2UgfHwgJ0ludGVybmFsIEVycm9yJywgY29udGV4dC5sb2dTdHJlYW1OYW1lLCB7fSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNwb25kKHJlc3BvbnNlU3RhdHVzOiBzdHJpbmcsIHJlYXNvbjogc3RyaW5nLCBwaHlzaWNhbFJlc291cmNlSWQ6IHN0cmluZywgZGF0YTogYW55KSB7XG4gICAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgU3RhdHVzOiByZXNwb25zZVN0YXR1cyxcbiAgICAgIFJlYXNvbjogcmVhc29uLFxuICAgICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBwaHlzaWNhbFJlc291cmNlSWQsXG4gICAgICBTdGFja0lkOiBldmVudC5TdGFja0lkLFxuICAgICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgICBOb0VjaG86IGZhbHNlLFxuICAgICAgRGF0YTogZGF0YSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKCdSZXNwb25kaW5nJywgcmVzcG9uc2VCb2R5KTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgcGFyc2VkVXJsID0gcmVxdWlyZSgndXJsJykucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgICAgbWV0aG9kOiAnUFVUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnaHR0cHMnKS5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCByZXNvbHZlKTtcbiAgICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWNvZGVDYWxsKGNhbGw6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICBpZiAoIWNhbGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICByZXR1cm4gSlNPTi5wYXJzZShjYWxsKTtcbn1cblxuZnVuY3Rpb24gc3RhcnRzV2l0aE9uZU9mKHNlYXJjaFN0cmluZ3M6IHN0cmluZ1tdKTogKHN0cmluZzogc3RyaW5nKSA9PiBib29sZWFuIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBzZWFyY2hTdHJpbmcgb2Ygc2VhcmNoU3RyaW5ncykge1xuICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKHNlYXJjaFN0cmluZykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/cdk.out index 588d7b269d34f..8ecc185e9dbee 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.assets.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.assets.json index 969d21c874896..f85aabe27e77e 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.assets.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.assets.json @@ -1,20 +1,20 @@ { - "version": "20.0.0", + "version": "21.0.0", "files": { - "105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286": { + "a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476": { "source": { - "path": "asset.105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286", + "path": "asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286.zip", + "objectKey": "a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "800ae0e8612e8f6d8cb727c55cf20dc51d4cbcc37c1e1701560675517ff5134a": { + "c2d925005ce1ea0db47e73cb0e76cc9f0f9347ede3ba8abe8f0768effe102872": { "source": { "path": "integ-user-pool-client-explicit-props.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "800ae0e8612e8f6d8cb727c55cf20dc51d4cbcc37c1e1701560675517ff5134a.json", + "objectKey": "c2d925005ce1ea0db47e73cb0e76cc9f0f9347ede3ba8abe8f0768effe102872.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.template.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.template.json index da5a9d5a2388d..f76f3ff409e22 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.template.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ-user-pool-client-explicit-props.template.json @@ -59,6 +59,7 @@ "profile", "aws.cognito.signin.user.admin" ], + "AuthSessionValidity": 3, "CallbackURLs": [ "https://redirect-here.myapp.com" ], @@ -203,7 +204,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286.zip" + "S3Key": "a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476.zip" }, "Role": { "Fn::GetAtt": [ diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ.json index 9a94e157d7d16..556572edaf738 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "testCases": { "integ.user-pool-client-explicit-props": { "stacks": [ diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/manifest.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/manifest.json index e46124e0f630a..50556b9c7f614 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "21.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "integ-user-pool-client-explicit-props.assets": { "type": "cdk:asset-manifest", "properties": { @@ -23,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/800ae0e8612e8f6d8cb727c55cf20dc51d4cbcc37c1e1701560675517ff5134a.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c2d925005ce1ea0db47e73cb0e76cc9f0f9347ede3ba8abe8f0768effe102872.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -95,6 +89,12 @@ ] }, "displayName": "integ-user-pool-client-explicit-props" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/tree.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/tree.json index cee7825f705ba..350f08f329fe5 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "integ-user-pool-client-explicit-props": { "id": "integ-user-pool-client-explicit-props", "path": "integ-user-pool-client-explicit-props", @@ -92,6 +84,7 @@ "profile", "aws.cognito.signin.user.admin" ], + "authSessionValidity": 3, "callbackUrLs": [ "https://redirect-here.myapp.com" ], @@ -156,14 +149,14 @@ "id": "Default", "path": "integ-user-pool-client-explicit-props/myuserpool/myuserpoolclient/DescribeCognitoUserPoolClient/Resource/Default", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" } }, "CustomResourcePolicy": { @@ -236,6 +229,14 @@ "id": "ServiceRole", "path": "integ-user-pool-client-explicit-props/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole", "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "integ-user-pool-client-explicit-props/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "integ-user-pool-client-explicit-props/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource", @@ -289,8 +290,8 @@ "id": "Stage", "path": "integ-user-pool-client-explicit-props/AWS679f53fac002430cb0da5b7982bd2287/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -317,7 +318,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "s3Key": "105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286.zip" + "s3Key": "a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476.zip" }, "role": { "Fn::GetAtt": [ @@ -369,17 +370,41 @@ "fqn": "@aws-cdk/aws-secretsmanager.Secret", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-user-pool-client-explicit-props/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-user-pool-client-explicit-props/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.161" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.ts b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.ts index 26f715f29180d..1c12e2104a4ba 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.ts +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.ts @@ -1,5 +1,5 @@ import { Secret } from '@aws-cdk/aws-secretsmanager'; -import { App, RemovalPolicy, Stack } from '@aws-cdk/core'; +import { App, Duration, RemovalPolicy, Stack } from '@aws-cdk/core'; import { ClientAttributes, OAuthScope, StringAttribute, UserPool } from '../lib'; const app = new App(); @@ -37,6 +37,7 @@ const client = userpool.addClient('myuserpoolclient', { callbackUrls: ['https://redirect-here.myapp.com'], }, preventUserExistenceErrors: true, + authSessionValidity: Duration.minutes(3), writeAttributes: (new ClientAttributes()).withStandardAttributes( { address: true, diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts index 8d4f54c88ccba..e285a10f24480 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts @@ -777,6 +777,86 @@ describe('User Pool Client', () => { }); }); + describe('auth session validity', () => { + test('default', () => { + // GIVEN + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + + // WHEN + pool.addClient('Client1', { + userPoolClientName: 'Client1', + authSessionValidity: Duration.minutes(3), + }); + pool.addClient('Client2', { + userPoolClientName: 'Client2', + authSessionValidity: Duration.minutes(9), + }); + pool.addClient('Client3', { + userPoolClientName: 'Client3', + authSessionValidity: Duration.minutes(15), + }); + pool.addClient('Client5', { + userPoolClientName: 'Client4', + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + ClientName: 'Client1', + AuthSessionValidity: 3, + }); + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + ClientName: 'Client2', + AuthSessionValidity: 9, + }); + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + ClientName: 'Client3', + AuthSessionValidity: 15, + }); + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + ClientName: 'Client4', + }); + }); + + test.each([ + Duration.minutes(0), + Duration.minutes(1), + Duration.minutes(3).minus(Duration.minutes(1)), + Duration.minutes(15).plus(Duration.minutes(1)), + Duration.minutes(100), + ])('validates authSessionValidity is a duration between 3 and 15 minutes', (validity) => { + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + expect(() => { + pool.addClient('Client1', { + userPoolClientName: 'Client1', + authSessionValidity: validity, + }); + }).toThrow(`authSessionValidity: Must be a duration between 3 minutes and 15 minutes (inclusive); received ${validity.toHumanString()}.`); + }); + + test.each([ + Duration.minutes(3), + Duration.minutes(9), + Duration.minutes(15), + ])('validates authSessionValidity is a duration between 3 and 15 minutes (valid)', (validity) => { + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + + // WHEN + pool.addClient('Client1', { + userPoolClientName: 'Client1', + authSessionValidity: validity, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + ClientName: 'Client1', + AuthSessionValidity: validity.toMinutes(), + }); + }); + }); + describe('token validity', () => { test('default', () => { // GIVEN From 07acd180d778b7084d8519234cfc3570bb8846ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20F=C3=BCrstenberg?= Date: Wed, 21 Dec 2022 01:35:57 +0100 Subject: [PATCH 10/22] fix(autoscaling): Allow adding AutoScalingGroup to multiple target groups (#23044) While this doesn't solve the underlying problem, which will require an API breakage in `scaleOnRequestCount()` (see https://github.com/aws/aws-cdk/issues/5667#issuecomment-636657482). As `scaleOnRequestCount()` seems to be the only part that is affected by this, we'll only issue a validation error if we have multiple `targetGroupArns` and `scaleOnRequestCount()` has been called. closes #5667 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-autoscaling/lib/auto-scaling-group.ts | 18 +- .../@aws-cdk/aws-autoscaling/package.json | 3 +- .../test/auto-scaling-group.test.ts | 56 + ...efaultTestDeployAssert1AF2B360.assets.json | 19 + ...aultTestDeployAssert1AF2B360.template.json | 36 + .../aws-cdk-asg-atg-integ.assets.json | 19 + .../aws-cdk-asg-atg-integ.template.json | 710 ++++++++++ .../aws-cdk-asg-integ.assets.json | 2 +- .../integ.asg-w-elbv2.js.snapshot/cdk.out | 2 +- .../integ.asg-w-elbv2.js.snapshot/integ.json | 15 +- .../manifest.json | 336 ++++- .../integ.asg-w-elbv2.js.snapshot/tree.json | 1226 ++++++++++++++++- .../aws-autoscaling/test/integ.asg-w-elbv2.ts | 109 +- 13 files changed, 2495 insertions(+), 56 deletions(-) create mode 100644 packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json create mode 100644 packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json create mode 100644 packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.assets.json create mode 100644 packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.template.json diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index c70c32271c331..9226cd703f6bf 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -985,6 +985,7 @@ abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGrou public abstract readonly osType: ec2.OperatingSystemType; protected albTargetGroup?: elbv2.ApplicationTargetGroup; public readonly grantPrincipal: iam.IPrincipal = new iam.UnknownPrincipal({ resource: this }); + protected hasCalledScaleOnRequestCount: boolean = false; /** * Send a message to either an SQS queue or SNS topic when instances launch or terminate @@ -1088,6 +1089,7 @@ abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGrou }); policy.node.addDependency(this.albTargetGroup.loadBalancerAttached); + this.hasCalledScaleOnRequestCount = true; return policy; } @@ -1388,6 +1390,8 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements if (props.requireImdsv2) { Aspects.of(this).add(new AutoScalingGroupRequireImdsv2Aspect()); } + + this.node.addValidation({ validate: () => this.validateTargetGroup() }); } /** @@ -1415,10 +1419,6 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements * Attach to ELBv2 Application Target Group */ public attachToApplicationTargetGroup(targetGroup: elbv2.IApplicationTargetGroup): elbv2.LoadBalancerTargetProps { - if (this.albTargetGroup !== undefined) { - throw new Error('Cannot add AutoScalingGroup to 2nd Target Group'); - } - this.targetGroupArns.push(targetGroup.targetGroupArn); if (targetGroup instanceof elbv2.ApplicationTargetGroup) { // Copy onto self if it's a concrete type. We need this for autoscaling @@ -1765,6 +1765,16 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements }; } } + + + private validateTargetGroup(): string[] { + const errors = new Array(); + if (this.hasCalledScaleOnRequestCount && this.targetGroupArns.length > 1) { + errors.push('Cannon use multiple target groups if `scaleOnRequestCount()` is being used.'); + } + + return errors; + } } /** diff --git a/packages/@aws-cdk/aws-autoscaling/package.json b/packages/@aws-cdk/aws-autoscaling/package.json index 24a847e983fb2..91cbf8992ccd5 100644 --- a/packages/@aws-cdk/aws-autoscaling/package.json +++ b/packages/@aws-cdk/aws-autoscaling/package.json @@ -82,10 +82,11 @@ "devDependencies": { "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", - "@aws-cdk/integ-runner": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", + "@aws-cdk/integ-runner": "0.0.0", + "@aws-cdk/integ-tests": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", "jest": "^27.5.1" diff --git a/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts b/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts index 553ed50b81dc4..ca1b88e2f2722 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts @@ -2,6 +2,7 @@ import { Annotations, Match, Template } from '@aws-cdk/assertions'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import { AmazonLinuxCpuType, AmazonLinuxGeneration, AmazonLinuxImage, InstanceType, LaunchTemplate } from '@aws-cdk/aws-ec2'; +import { ApplicationListener, ApplicationLoadBalancer, ApplicationTargetGroup } from '@aws-cdk/aws-elasticloadbalancingv2'; import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; import { testDeprecated } from '@aws-cdk/cdk-build-tools'; @@ -1864,6 +1865,61 @@ describe('auto scaling group', () => { })).not.toThrow(); }); + + describe('multiple target groups', () => { + let asg: autoscaling.AutoScalingGroup; + let stack: cdk.Stack; + let vpc: ec2.IVpc; + let alb: ApplicationLoadBalancer; + let listener: ApplicationListener; + + beforeEach(() => { + stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' } }); + vpc = mockVpc(stack); + alb = new ApplicationLoadBalancer(stack, 'alb', { + vpc, + internetFacing: true, + }); + + listener = alb.addListener('Listener', { + port: 80, + open: true, + }); + + asg = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage(), + vpc, + }); + }); + + test('Adding two application target groups should succeed validation', () => { + const atg1 = new ApplicationTargetGroup(stack, 'ATG1', { port: 443 }); + const atg2 = new ApplicationTargetGroup(stack, 'ATG2', { port: 443 }); + + listener.addTargetGroups('tgs', { targetGroups: [atg1, atg2] }); + + asg.attachToApplicationTargetGroup(atg1); + asg.attachToApplicationTargetGroup(atg2); + + expect(asg.node.validate()).toEqual([]); + }); + + test('Adding two application target groups should fail validation validate if `scaleOnRequestCount()` has been called', () => { + const atg1 = new ApplicationTargetGroup(stack, 'ATG1', { port: 443 }); + const atg2 = new ApplicationTargetGroup(stack, 'ATG2', { port: 443 }); + + listener.addTargetGroups('tgs', { targetGroups: [atg1, atg2] }); + + asg.attachToApplicationTargetGroup(atg1); + asg.attachToApplicationTargetGroup(atg2); + + asg.scaleOnRequestCount('requests-per-minute', { targetRequestsPerMinute: 60 }); + + expect(asg.node.validate()).toContainEqual('Cannon use multiple target groups if `scaleOnRequestCount()` is being used.'); + }); + }); + }); function mockVpc(stack: cdk.Stack) { diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json new file mode 100644 index 0000000000000..57e75754f5e88 --- /dev/null +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "LambdaTestDefaultTestDeployAssert1AF2B360.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.assets.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.assets.json new file mode 100644 index 0000000000000..2f0cf30035fc5 --- /dev/null +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "6e4ba6d1c10cb8a0be78abd30ef94d231f8913f1cd4b02c0b62b8626f3425c00": { + "source": { + "path": "aws-cdk-asg-atg-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "6e4ba6d1c10cb8a0be78abd30ef94d231f8913f1cd4b02c0b62b8626f3425c00.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.template.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.template.json new file mode 100644 index 0000000000000..e05bb77369716 --- /dev/null +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-atg-integ.template.json @@ -0,0 +1,710 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC" + ] + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet2EIP4947BC00": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2RouteTableAssociation5A808732" + ] + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "alb8A8B13C2": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "albSecurityGroup49866104", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + ], + "Type": "application" + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC", + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2RouteTableAssociation5A808732" + ] + }, + "albSecurityGroup49866104": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Automatically created Security Group for ELB awscdkasgatgintegalbAE8C693C", + "SecurityGroupIngress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow from anyone on port 80", + "FromPort": 80, + "IpProtocol": "tcp", + "ToPort": 80 + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "albSecurityGrouptoawscdkasgatgintegAsgInstanceSecurityGroupE6EC7F0C443B02D0421": { + "Type": "AWS::EC2::SecurityGroupEgress", + "Properties": { + "GroupId": { + "Fn::GetAtt": [ + "albSecurityGroup49866104", + "GroupId" + ] + }, + "IpProtocol": "tcp", + "Description": "Load balancer to target", + "DestinationSecurityGroupId": { + "Fn::GetAtt": [ + "AsgInstanceSecurityGroupC53F1492", + "GroupId" + ] + }, + "FromPort": 443, + "ToPort": 443 + } + }, + "albListener3EA0B2EF": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "ForwardConfig": { + "TargetGroups": [ + { + "TargetGroupArn": { + "Ref": "ATG17CFF5455" + }, + "Weight": 1 + }, + { + "TargetGroupArn": { + "Ref": "ATG2A54F3827" + }, + "Weight": 1 + } + ] + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "alb8A8B13C2" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "AsgInstanceSecurityGroupC53F1492": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-cdk-asg-atg-integ/Asg/InstanceSecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/Asg" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "AsgInstanceSecurityGroupfromawscdkasgatgintegalbSecurityGroup3EC708D0443E9585EF6": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "IpProtocol": "tcp", + "Description": "Load balancer to target", + "FromPort": 443, + "GroupId": { + "Fn::GetAtt": [ + "AsgInstanceSecurityGroupC53F1492", + "GroupId" + ] + }, + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "albSecurityGroup49866104", + "GroupId" + ] + }, + "ToPort": 443 + } + }, + "AsgInstanceRole7946982D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-asg-atg-integ/Asg" + } + ] + } + }, + "AsgInstanceProfileBCEDB827": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "AsgInstanceRole7946982D" + } + ] + } + }, + "AsgLaunchConfig6D4F96BB": { + "Type": "AWS::AutoScaling::LaunchConfiguration", + "Properties": { + "ImageId": { + "Ref": "SsmParameterValueawsserviceamiamazonlinuxlatestamznamihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "InstanceType": "t3.micro", + "IamInstanceProfile": { + "Ref": "AsgInstanceProfileBCEDB827" + }, + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "AsgInstanceSecurityGroupC53F1492", + "GroupId" + ] + } + ], + "UserData": { + "Fn::Base64": "#!/bin/bash" + } + }, + "DependsOn": [ + "AsgInstanceRole7946982D" + ] + }, + "AsgASGD1D7B4E2": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": "1", + "MinSize": "1", + "LaunchConfigurationName": { + "Ref": "AsgLaunchConfig6D4F96BB" + }, + "Tags": [ + { + "Key": "Name", + "PropagateAtLaunch": true, + "Value": "aws-cdk-asg-atg-integ/Asg" + } + ], + "TargetGroupARNs": [ + { + "Ref": "ATG17CFF5455" + }, + { + "Ref": "ATG2A54F3827" + } + ], + "VPCZoneIdentifier": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + }, + "UpdatePolicy": { + "AutoScalingScheduledAction": { + "IgnoreUnmodifiedGroupSizeProperties": true + } + } + }, + "ATG17CFF5455": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 443, + "Protocol": "HTTPS", + "TargetGroupAttributes": [ + { + "Key": "stickiness.enabled", + "Value": "false" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "ATG2A54F3827": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 443, + "Protocol": "HTTPS", + "TargetGroupAttributes": [ + { + "Key": "stickiness.enabled", + "Value": "false" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + } + }, + "Parameters": { + "SsmParameterValueawsserviceamiamazonlinuxlatestamznamihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2" + }, + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-integ.assets.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-integ.assets.json index 9ac85f9ce2ba2..6265dba737ebc 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-integ.assets.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/aws-cdk-asg-integ.assets.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "22.0.0", "files": { "66b1b9cec9c1b972779161099a4b8310affc4106b7e751a3032a397c09e1c9f0": { "source": { diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/cdk.out b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/cdk.out index 8ecc185e9dbee..145739f539580 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"21.0.0"} \ No newline at end of file +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/integ.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/integ.json index a5777c505cdc6..40b3938d6a745 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/integ.json @@ -1,14 +1,13 @@ { - "version": "21.0.0", + "version": "22.0.0", "testCases": { - "integ.asg-w-elbv2": { + "LambdaTest/DefaultTest": { "stacks": [ - "aws-cdk-asg-integ" + "aws-cdk-asg-integ", + "aws-cdk-asg-atg-integ" ], - "diffAssets": false, - "stackUpdateWorkflow": true + "assertionStack": "LambdaTest/DefaultTest/DeployAssert", + "assertionStackName": "LambdaTestDefaultTestDeployAssert1AF2B360" } - }, - "synthContext": {}, - "enableLookups": false + } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/manifest.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/manifest.json index 0f9edacc60c14..14f2cddea1732 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "21.0.0", + "version": "22.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-asg-integ.assets": { "type": "cdk:asset-manifest", "properties": { @@ -269,6 +263,334 @@ ] }, "displayName": "aws-cdk-asg-integ" + }, + "aws-cdk-asg-atg-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-asg-atg-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-asg-atg-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-asg-atg-integ.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6e4ba6d1c10cb8a0be78abd30ef94d231f8913f1cd4b02c0b62b8626f3425c00.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-asg-atg-integ.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-asg-atg-integ.assets" + ], + "metadata": { + "/aws-cdk-asg-atg-integ/VPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCB9E5F0B4" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1SubnetB4246D30" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableFEE4B781" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1DefaultRoute91CEF279" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1EIP6AD938E8" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1NATGatewayE0556630" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2Subnet74179F39" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTable6F1A15F1" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTableAssociation5A808732" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2DefaultRouteB7481BBA" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2EIP4947BC00" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2NATGateway3C070193" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableBE8A6027" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTable0A19E10E" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" + } + ], + "/aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" + } + ], + "/aws-cdk-asg-atg-integ/VPC/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCIGWB7E252D3" + } + ], + "/aws-cdk-asg-atg-integ/VPC/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCVPCGW99B986DC" + } + ], + "/aws-cdk-asg-atg-integ/alb/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "alb8A8B13C2" + } + ], + "/aws-cdk-asg-atg-integ/alb/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "albSecurityGroup49866104" + } + ], + "/aws-cdk-asg-atg-integ/alb/SecurityGroup/to awscdkasgatgintegAsgInstanceSecurityGroupE6EC7F0C:443": [ + { + "type": "aws:cdk:logicalId", + "data": "albSecurityGrouptoawscdkasgatgintegAsgInstanceSecurityGroupE6EC7F0C443B02D0421" + } + ], + "/aws-cdk-asg-atg-integ/alb/Listener/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "albListener3EA0B2EF" + } + ], + "/aws-cdk-asg-atg-integ/Asg/InstanceSecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AsgInstanceSecurityGroupC53F1492" + } + ], + "/aws-cdk-asg-atg-integ/Asg/InstanceSecurityGroup/from awscdkasgatgintegalbSecurityGroup3EC708D0:443": [ + { + "type": "aws:cdk:logicalId", + "data": "AsgInstanceSecurityGroupfromawscdkasgatgintegalbSecurityGroup3EC708D0443E9585EF6" + } + ], + "/aws-cdk-asg-atg-integ/Asg/InstanceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AsgInstanceRole7946982D" + } + ], + "/aws-cdk-asg-atg-integ/Asg/InstanceProfile": [ + { + "type": "aws:cdk:logicalId", + "data": "AsgInstanceProfileBCEDB827" + } + ], + "/aws-cdk-asg-atg-integ/Asg/LaunchConfig": [ + { + "type": "aws:cdk:logicalId", + "data": "AsgLaunchConfig6D4F96BB" + } + ], + "/aws-cdk-asg-atg-integ/Asg/ASG": [ + { + "type": "aws:cdk:logicalId", + "data": "AsgASGD1D7B4E2" + } + ], + "/aws-cdk-asg-atg-integ/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": [ + { + "type": "aws:cdk:logicalId", + "data": "SsmParameterValueawsserviceamiamazonlinuxlatestamznamihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter" + } + ], + "/aws-cdk-asg-atg-integ/ATG1": [ + { + "type": "aws:cdk:warning", + "data": "When creating an empty TargetGroup, you should specify a 'targetType' (this warning may become an error in the future)." + } + ], + "/aws-cdk-asg-atg-integ/ATG1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ATG17CFF5455" + } + ], + "/aws-cdk-asg-atg-integ/ATG2": [ + { + "type": "aws:cdk:warning", + "data": "When creating an empty TargetGroup, you should specify a 'targetType' (this warning may become an error in the future)." + } + ], + "/aws-cdk-asg-atg-integ/ATG2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ATG2A54F3827" + } + ], + "/aws-cdk-asg-atg-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-asg-atg-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-asg-atg-integ" + }, + "LambdaTestDefaultTestDeployAssert1AF2B360.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "LambdaTestDefaultTestDeployAssert1AF2B360.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "LambdaTestDefaultTestDeployAssert1AF2B360": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "LambdaTestDefaultTestDeployAssert1AF2B360.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "LambdaTestDefaultTestDeployAssert1AF2B360.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "LambdaTestDefaultTestDeployAssert1AF2B360.assets" + ], + "metadata": { + "/LambdaTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/LambdaTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "LambdaTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/tree.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/tree.json index 1f1936c2e188d..d9026b2de3166 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.140" - } - }, "aws-cdk-asg-integ": { "id": "aws-cdk-asg-integ", "path": "aws-cdk-asg-integ", @@ -736,6 +728,14 @@ "id": "InstanceRole", "path": "aws-cdk-asg-integ/Fleet/InstanceRole", "children": { + "ImportInstanceRole": { + "id": "ImportInstanceRole", + "path": "aws-cdk-asg-integ/Fleet/InstanceRole/ImportInstanceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-asg-integ/Fleet/InstanceRole/Resource", @@ -1152,12 +1152,1222 @@ "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationLoadBalancer", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-asg-integ/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-asg-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, "constructInfo": { "fqn": "@aws-cdk/core.Stack", "version": "0.0.0" } + }, + "aws-cdk-asg-atg-integ": { + "id": "aws-cdk-asg-atg-integ", + "path": "aws-cdk-asg-atg-integ", + "children": { + "VPC": { + "id": "VPC", + "path": "aws-cdk-asg-atg-integ/VPC", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/VPC/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-asg-atg-integ/VPC/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "aws-cdk-asg-atg-integ/VPC/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "aws-cdk-asg-atg-integ/VPC/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "internetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.Vpc", + "version": "0.0.0" + } + }, + "alb": { + "id": "alb", + "path": "aws-cdk-asg-atg-integ/alb", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/alb/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "aws:cdk:cloudformation:props": { + "loadBalancerAttributes": [ + { + "key": "deletion_protection.enabled", + "value": "false" + } + ], + "scheme": "internet-facing", + "securityGroups": [ + { + "Fn::GetAtt": [ + "albSecurityGroup49866104", + "GroupId" + ] + } + ], + "subnets": [ + { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + ], + "type": "application" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.CfnLoadBalancer", + "version": "0.0.0" + } + }, + "SecurityGroup": { + "id": "SecurityGroup", + "path": "aws-cdk-asg-atg-integ/alb/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/alb/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "Automatically created Security Group for ELB awscdkasgatgintegalbAE8C693C", + "securityGroupIngress": [ + { + "cidrIp": "0.0.0.0/0", + "ipProtocol": "tcp", + "fromPort": 80, + "toPort": 80, + "description": "Allow from anyone on port 80" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup", + "version": "0.0.0" + } + }, + "to awscdkasgatgintegAsgInstanceSecurityGroupE6EC7F0C:443": { + "id": "to awscdkasgatgintegAsgInstanceSecurityGroupE6EC7F0C:443", + "path": "aws-cdk-asg-atg-integ/alb/SecurityGroup/to awscdkasgatgintegAsgInstanceSecurityGroupE6EC7F0C:443", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroupEgress", + "aws:cdk:cloudformation:props": { + "groupId": { + "Fn::GetAtt": [ + "albSecurityGroup49866104", + "GroupId" + ] + }, + "ipProtocol": "tcp", + "description": "Load balancer to target", + "destinationSecurityGroupId": { + "Fn::GetAtt": [ + "AsgInstanceSecurityGroupC53F1492", + "GroupId" + ] + }, + "fromPort": 443, + "toPort": 443 + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroupEgress", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "Listener": { + "id": "Listener", + "path": "aws-cdk-asg-atg-integ/alb/Listener", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/alb/Listener/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener", + "aws:cdk:cloudformation:props": { + "defaultActions": [ + { + "type": "forward", + "forwardConfig": { + "targetGroups": [ + { + "targetGroupArn": { + "Ref": "ATG17CFF5455" + }, + "weight": 1 + }, + { + "targetGroupArn": { + "Ref": "ATG2A54F3827" + }, + "weight": 1 + } + ] + } + } + ], + "loadBalancerArn": { + "Ref": "alb8A8B13C2" + }, + "port": 80, + "protocol": "HTTP" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.CfnListener", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationListener", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationLoadBalancer", + "version": "0.0.0" + } + }, + "Asg": { + "id": "Asg", + "path": "aws-cdk-asg-atg-integ/Asg", + "children": { + "InstanceSecurityGroup": { + "id": "InstanceSecurityGroup", + "path": "aws-cdk-asg-atg-integ/Asg/InstanceSecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/Asg/InstanceSecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "aws-cdk-asg-atg-integ/Asg/InstanceSecurityGroup", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/Asg" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup", + "version": "0.0.0" + } + }, + "from awscdkasgatgintegalbSecurityGroup3EC708D0:443": { + "id": "from awscdkasgatgintegalbSecurityGroup3EC708D0:443", + "path": "aws-cdk-asg-atg-integ/Asg/InstanceSecurityGroup/from awscdkasgatgintegalbSecurityGroup3EC708D0:443", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroupIngress", + "aws:cdk:cloudformation:props": { + "ipProtocol": "tcp", + "description": "Load balancer to target", + "fromPort": 443, + "groupId": { + "Fn::GetAtt": [ + "AsgInstanceSecurityGroupC53F1492", + "GroupId" + ] + }, + "sourceSecurityGroupId": { + "Fn::GetAtt": [ + "albSecurityGroup49866104", + "GroupId" + ] + }, + "toPort": 443 + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroupIngress", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "InstanceRole": { + "id": "InstanceRole", + "path": "aws-cdk-asg-atg-integ/Asg/InstanceRole", + "children": { + "ImportInstanceRole": { + "id": "ImportInstanceRole", + "path": "aws-cdk-asg-atg-integ/Asg/InstanceRole/ImportInstanceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/Asg/InstanceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/Asg" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "InstanceProfile": { + "id": "InstanceProfile", + "path": "aws-cdk-asg-atg-integ/Asg/InstanceProfile", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::InstanceProfile", + "aws:cdk:cloudformation:props": { + "roles": [ + { + "Ref": "AsgInstanceRole7946982D" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnInstanceProfile", + "version": "0.0.0" + } + }, + "LaunchConfig": { + "id": "LaunchConfig", + "path": "aws-cdk-asg-atg-integ/Asg/LaunchConfig", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AutoScaling::LaunchConfiguration", + "aws:cdk:cloudformation:props": { + "imageId": { + "Ref": "SsmParameterValueawsserviceamiamazonlinuxlatestamznamihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "instanceType": "t3.micro", + "iamInstanceProfile": { + "Ref": "AsgInstanceProfileBCEDB827" + }, + "securityGroups": [ + { + "Fn::GetAtt": [ + "AsgInstanceSecurityGroupC53F1492", + "GroupId" + ] + } + ], + "userData": { + "Fn::Base64": "#!/bin/bash" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-autoscaling.CfnLaunchConfiguration", + "version": "0.0.0" + } + }, + "ASG": { + "id": "ASG", + "path": "aws-cdk-asg-atg-integ/Asg/ASG", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AutoScaling::AutoScalingGroup", + "aws:cdk:cloudformation:props": { + "maxSize": "1", + "minSize": "1", + "launchConfigurationName": { + "Ref": "AsgLaunchConfig6D4F96BB" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-asg-atg-integ/Asg", + "propagateAtLaunch": true + } + ], + "targetGroupArns": [ + { + "Ref": "ATG17CFF5455" + }, + { + "Ref": "ATG2A54F3827" + } + ], + "vpcZoneIdentifier": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-autoscaling.CfnAutoScalingGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-autoscaling.AutoScalingGroup", + "version": "0.0.0" + } + }, + "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": { + "id": "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter", + "path": "aws-cdk-asg-atg-integ/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118": { + "id": "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118", + "path": "aws-cdk-asg-atg-integ/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "ATG1": { + "id": "ATG1", + "path": "aws-cdk-asg-atg-integ/ATG1", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/ATG1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "aws:cdk:cloudformation:props": { + "port": 443, + "protocol": "HTTPS", + "targetGroupAttributes": [ + { + "key": "stickiness.enabled", + "value": "false" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.CfnTargetGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationTargetGroup", + "version": "0.0.0" + } + }, + "ATG2": { + "id": "ATG2", + "path": "aws-cdk-asg-atg-integ/ATG2", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-asg-atg-integ/ATG2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "aws:cdk:cloudformation:props": { + "port": 443, + "protocol": "HTTPS", + "targetGroupAttributes": [ + { + "key": "stickiness.enabled", + "value": "false" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.CfnTargetGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationTargetGroup", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-asg-atg-integ/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-asg-atg-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "LambdaTest": { + "id": "LambdaTest", + "path": "LambdaTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "LambdaTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "LambdaTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "LambdaTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "LambdaTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "LambdaTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts index 71f484df99b49..e949b58b17f84 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts @@ -1,40 +1,97 @@ #!/usr/bin/env node import * as ec2 from '@aws-cdk/aws-ec2'; import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; +import { ListenerAction } from '@aws-cdk/aws-elasticloadbalancingv2'; import * as cdk from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; +import { Construct } from 'constructs'; import * as autoscaling from '../lib'; -const app = new cdk.App(); -const stack = new cdk.Stack(app, 'aws-cdk-asg-integ'); +class ElbV2AsgStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); -const vpc = new ec2.Vpc(stack, 'VPC', { - maxAzs: 2, -}); + const vpc = new ec2.Vpc(this, 'VPC', { + maxAzs: 2, + }); -const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', { - vpc, - instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), - machineImage: new ec2.AmazonLinuxImage(), -}); + const asg = new autoscaling.AutoScalingGroup(this, 'Fleet', { + vpc, + instanceType: ec2.InstanceType.of( + ec2.InstanceClass.BURSTABLE2, + ec2.InstanceSize.MICRO, + ), + machineImage: new ec2.AmazonLinuxImage(), + }); -const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { - vpc, - internetFacing: true, -}); + const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', { + vpc, + internetFacing: true, + }); -const listener = lb.addListener('Listener', { - port: 80, -}); + const listener = lb.addListener('Listener', { + port: 80, + }); -listener.addTargets('Target', { - port: 80, - targets: [asg], -}); + listener.addTargets('Target', { + port: 80, + targets: [asg], + }); -listener.connections.allowDefaultPortFromAnyIpv4('Open to the world'); + listener.connections.allowDefaultPortFromAnyIpv4('Open to the world'); -asg.scaleOnRequestCount('AModestLoad', { - targetRequestsPerSecond: 1, -}); + asg.scaleOnRequestCount('AModestLoad', { + targetRequestsPerSecond: 1, + }); + } +} -app.synth(); +class ElbV2AsgAtgStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + const vpc = new ec2.Vpc(this, 'VPC', { + maxAzs: 2, + }); + const alb = new elbv2.ApplicationLoadBalancer(this, 'alb', { + vpc, + internetFacing: true, + }); + const listener = alb.addListener('Listener', { + port: 80, + open: true, + }); + + const asg = new autoscaling.AutoScalingGroup(this, 'Asg', { + vpc, + instanceType: new ec2.InstanceType('t3.micro'), + machineImage: new ec2.AmazonLinuxImage(), + }); + + const atg1 = new elbv2.ApplicationTargetGroup(this, 'ATG1', { + port: 443, + vpc, + }); + const atg2 = new elbv2.ApplicationTargetGroup(this, 'ATG2', { + port: 443, + vpc, + }); + + listener.addAction('tgs', { + action: ListenerAction.weightedForward([ + { targetGroup: atg1, weight: 1 }, + { targetGroup: atg2, weight: 1 }, + ]), + }); + + asg.attachToApplicationTargetGroup(atg1); + asg.attachToApplicationTargetGroup(atg2); + } +} +const app = new cdk.App(); + +new integ.IntegTest(app, 'LambdaTest', { + testCases: [ + new ElbV2AsgStack(app, 'aws-cdk-asg-integ'), + new ElbV2AsgAtgStack(app, 'aws-cdk-asg-atg-integ'), + ], +}); From 8d359ae35877ce066e419f7e2e7da2b0deb587e6 Mon Sep 17 00:00:00 2001 From: santanugho Date: Wed, 21 Dec 2022 01:48:56 -0800 Subject: [PATCH 11/22] feat(servicecatalogappregistry): Cross region warning and default application tag (#23412) In order to track the usage of `application-associator` L2 construct and gather metrics, we are adding a new user tag `managedBy` upon Application creation. In case of `cross-region` stack, we want to throw a warning during the synth time, which will let the customer know that AppRegistry do not natively supports cross region. ### All Submissions: * [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [X ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-servicecatalogappregistry/README.md | 2 + .../lib/aspects/stack-associator.ts | 2 +- .../lib/target-application.ts | 3 +- .../test/application-associator.test.ts | 11 +++- .../test/application.test.ts | 5 +- ...catalogappregistry-application.assets.json | 4 +- ...talogappregistry-application.template.json | 8 +-- .../manifest.json | 2 +- .../integ.application.js.snapshot/tree.json | 6 +-- .../test/integ.application.ts | 4 +- .../integ.attribute-group.js.snapshot/cdk.out | 2 +- ...logappregistry-attribute-group.assets.json | 2 +- .../integ.json | 2 +- .../manifest.json | 14 ++--- .../tree.json | 54 +++++++++++++++---- 15 files changed, 82 insertions(+), 39 deletions(-) diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/README.md b/packages/@aws-cdk/aws-servicecatalogappregistry/README.md index 10985d4839557..be09aef037fae 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/README.md +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/README.md @@ -84,6 +84,8 @@ const associatedApp = new appreg.ApplicationAssociator(app, 'AssociatedApplicati }); ``` +This will create an application `MyAssociatedApplication` with the `TagKey` as `managedBy` and `TagValue` as `CDK_Application_Associator`. + If you want to re-use an existing Application with ARN: `arn:aws:servicecatalog:us-east-1:123456789012:/applications/applicationId` and want to associate all stacks in the `App` scope to your imported application, then use as shown in the example below: diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts index 7694a519802b4..982085a6b9cf3 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts @@ -80,7 +80,7 @@ abstract class StackAssociatorBase implements IAspect { } if (node.region != this.application.env.region) { - this.error(node, 'AppRegistry does not support cross region associations. Application region ' + this.warning(node, 'AppRegistry does not support cross region associations, deployment might fail if there is cross region stacks in the app. Application region ' + this.application.env.region + ', stack region ' + node.region); } } diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts index 7745c0d99a02c..0452ea6ac4095 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts @@ -100,6 +100,7 @@ class CreateTargetApplication extends TargetApplication { applicationName: this.applicationOptions.applicationName, description: this.applicationOptions.applicationDescription || 'Application containing stacks deployed via CDK.', }); + cdk.Tags.of(appRegApplication).add('managedBy', 'CDK_Application_Associator'); return { application: appRegApplication, @@ -123,4 +124,4 @@ class ExistingTargetApplication extends TargetApplication { application: appRegApplication, }; } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts index 0d0cf74062e29..fe6bf236b28ae 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts @@ -15,13 +15,19 @@ describe('Scope based Associations with Application within Same Account', () => }); }); test('ApplicationAssociator will associate allStacks created inside cdkApp', () => { - new appreg.ApplicationAssociator(app, 'MyApplication', { + const appAssociator = new appreg.ApplicationAssociator(app, 'MyApplication', { applications: [appreg.TargetApplication.createApplicationStack({ applicationName: 'MyAssociatedApplication', stackName: 'MyAssociatedApplicationStack', })], }); + const anotherStack = new AppRegistrySampleStack(app, 'SampleStack'); + Template.fromStack(appAssociator.appRegistryApplication().stack).resourceCountIs('AWS::ServiceCatalogAppRegistry::Application', 1); + Template.fromStack(appAssociator.appRegistryApplication().stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::Application', { + Name: 'MyAssociatedApplication', + Tags: { managedBy: 'CDK_Application_Associator' }, + }); Template.fromStack(anotherStack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); Template.fromStack(anotherStack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::ResourceAssociation', { Application: 'MyAssociatedApplication', @@ -103,7 +109,8 @@ describe('Scope based Associations with Application with Cross Region/Account', const crossRegionStack = new cdk.Stack(app, 'crossRegionStack', { env: { account: 'account', region: 'region' }, }); - Annotations.fromStack(crossRegionStack).hasError('*', 'AppRegistry does not support cross region associations. Application region region2, stack region region'); + Annotations.fromStack(crossRegionStack).hasWarning('*', 'AppRegistry does not support cross region associations, deployment might fail if there is cross region stacks in the app.' + + ' Application region region2, stack region region'); }); test('Environment Agnostic ApplicationAssociator with cross region stacks inside cdkApp gives warning', () => { diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts index 7a14cda920d28..04349d3d33bd5 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts @@ -443,8 +443,9 @@ describe('Scope based Associations with Application with Cross Region/Account', }); const stageStack = new cdk.Stack(stage, 'MyStack'); application.associateAllStacksInScope(stage); - Annotations.fromStack(stageStack).hasError('*', - 'AppRegistry does not support cross region associations. Application region region, stack region region1'); + Annotations.fromStack(stageStack).hasWarning('*', + 'AppRegistry does not support cross region associations, deployment might fail if there is cross region stacks in the app.' + + ' Application region region, stack region region1'); }); }); diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.assets.json index 225ef80716295..0f728aa69a648 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.assets.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.assets.json @@ -1,7 +1,7 @@ { "version": "22.0.0", "files": { - "806ae543572346400832fe865c1bdfa243ef2c1f07c3ce10aa0bd27ed4613a42": { + "225f3d7f7d17bfb53aa17ae8a44119a756f2fc51682bfd5ee27b84ea25f994eb": { "source": { "path": "integ-servicecatalogappregistry-application.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "806ae543572346400832fe865c1bdfa243ef2c1f07c3ce10aa0bd27ed4613a42.json", + "objectKey": "225f3d7f7d17bfb53aa17ae8a44119a756f2fc51682bfd5ee27b84ea25f994eb.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.template.json index 33f4f2a1912fb..d569907291d49 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.template.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/integ-servicecatalogappregistry-application.template.json @@ -3,7 +3,7 @@ "TestApplication2FBC585F": { "Type": "AWS::ServiceCatalogAppRegistry::Application", "Properties": { - "Name": "myCdkApplication", + "Name": "myApplication", "Description": "my application description" } }, @@ -84,7 +84,7 @@ "release": "go time" } }, - "Name": "myCdkAttributeGroup", + "Name": "myAttributeGroup", "Description": "my attribute group description" } }, @@ -123,7 +123,7 @@ }, "Outputs": { "TestApplicationApplicationManagerUrlE1058321": { - "Description": "Application manager url for application myCdkApplication", + "Description": "Application manager url for application myApplication", "Value": { "Fn::Join": [ "", @@ -132,7 +132,7 @@ { "Ref": "AWS::Region" }, - ".console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-myCdkApplication" + ".console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-myApplication" ] ] } diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/manifest.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/manifest.json index a8cd9a83688d7..6a0143a97aaf2 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/manifest.json @@ -17,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/806ae543572346400832fe865c1bdfa243ef2c1f07c3ce10aa0bd27ed4613a42.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/225f3d7f7d17bfb53aa17ae8a44119a756f2fc51682bfd5ee27b84ea25f994eb.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/tree.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/tree.json index da9f344585ed2..5e4d14f15093e 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.js.snapshot/tree.json @@ -18,7 +18,7 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::Application", "aws:cdk:cloudformation:props": { - "name": "myCdkApplication", + "name": "myApplication", "description": "my application description" } }, @@ -149,7 +149,7 @@ "release": "go time" } }, - "name": "myCdkAttributeGroup", + "name": "myAttributeGroup", "description": "my attribute group description" } }, @@ -249,7 +249,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.168" + "version": "10.1.189" } } }, diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.ts index 30f5e2bb88829..06c0395e31bfa 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application.ts @@ -6,12 +6,12 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'integ-servicecatalogappregistry-application'); const application = new appreg.Application(stack, 'TestApplication', { - applicationName: 'myCdkApplication', + applicationName: 'myApplication', description: 'my application description', }); const attributeGroup = new appreg.AttributeGroup(stack, 'TestAttributeGroup', { - attributeGroupName: 'myCdkAttributeGroup', + attributeGroupName: 'myAttributeGroup', description: 'my attribute group description', attributes: { stage: 'alpha', diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/cdk.out b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/cdk.out index 8ecc185e9dbee..145739f539580 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"21.0.0"} \ No newline at end of file +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ-servicecatalogappregistry-attribute-group.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ-servicecatalogappregistry-attribute-group.assets.json index f3f8d64d86ef0..1aebd71d38d63 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ-servicecatalogappregistry-attribute-group.assets.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ-servicecatalogappregistry-attribute-group.assets.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "22.0.0", "files": { "3dece22dad73361a79cb380f2880362a20ffc5c0cc75ddc6707e26b5a88cf93f": { "source": { diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ.json index c0763c76bc8aa..a50a65615f05b 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "22.0.0", "testCases": { "integ.attribute-group": { "stacks": [ diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/manifest.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/manifest.json index 29a8ab0c7ec2a..edce9703115a8 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "22.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "integ-servicecatalogappregistry-attribute-group.assets": { "type": "cdk:asset-manifest", "properties": { @@ -77,6 +71,12 @@ ] }, "displayName": "integ-servicecatalogappregistry-attribute-group" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/tree.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/tree.json index 1bbf2fd35bb5a..83ac3d2034037 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.attribute-group.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "integ-servicecatalogappregistry-attribute-group": { "id": "integ-servicecatalogappregistry-attribute-group", "path": "integ-servicecatalogappregistry-attribute-group", @@ -97,6 +89,14 @@ "id": "MyRole", "path": "integ-servicecatalogappregistry-attribute-group/MyRole", "children": { + "ImportMyRole": { + "id": "ImportMyRole", + "path": "integ-servicecatalogappregistry-attribute-group/MyRole/ImportMyRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "integ-servicecatalogappregistry-attribute-group/MyRole/Resource", @@ -147,6 +147,14 @@ "id": "MySecondRole", "path": "integ-servicecatalogappregistry-attribute-group/MySecondRole", "children": { + "ImportMySecondRole": { + "id": "ImportMySecondRole", + "path": "integ-servicecatalogappregistry-attribute-group/MySecondRole/ImportMySecondRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "integ-servicecatalogappregistry-attribute-group/MySecondRole/Resource", @@ -192,17 +200,41 @@ "fqn": "@aws-cdk/aws-iam.Role", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-servicecatalogappregistry-attribute-group/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-servicecatalogappregistry-attribute-group/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.189" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file From b7052242fb699ba89603ae718ae2d6b0ab9efa6f Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Wed, 21 Dec 2022 10:38:04 -0800 Subject: [PATCH 12/22] fix(timestream): magneticStoreWriteProperties and retentionProperties not working as Json (#23425) Fixes #23404 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../906_TimeStream_JsonTypes_patch.json | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/906_TimeStream_JsonTypes_patch.json diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/906_TimeStream_JsonTypes_patch.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/906_TimeStream_JsonTypes_patch.json new file mode 100644 index 0000000000000..01c5d038c050c --- /dev/null +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/906_TimeStream_JsonTypes_patch.json @@ -0,0 +1,29 @@ +{ + "ResourceTypes": { + "AWS::Timestream::Table": { + "patch": { + "description": "These types were once typed as Json, and adding types now is a breaking change. Keep them as Json forever.", + "operations": [ + { + "op": "remove", + "path": "/Properties/MagneticStoreWriteProperties/Type" + }, + { + "op": "add", + "path": "/Properties/MagneticStoreWriteProperties/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/RetentionProperties/Type" + }, + { + "op": "add", + "path": "/Properties/RetentionProperties/PrimitiveType", + "value": "Json" + } + ] + } + } + } +} From 2c90783460db03ad066134372596ecf6cadfc9db Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Wed, 21 Dec 2022 19:02:28 +0000 Subject: [PATCH 13/22] chore(release): 2.56.0 --- CHANGELOG.v2.alpha.md | 8 ++++++++ CHANGELOG.v2.md | 23 +++++++++++++++++++++++ version.v2.json | 4 ++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.v2.alpha.md b/CHANGELOG.v2.alpha.md index 405ffd52e59eb..ff189964a3eb8 100644 --- a/CHANGELOG.v2.alpha.md +++ b/CHANGELOG.v2.alpha.md @@ -2,6 +2,14 @@ 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. +## [2.56.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.55.1-alpha.0...v2.56.0-alpha.0) (2022-12-21) + + +### Features + +* **integ-tests:** add serializedJson on match utility ([#23218](https://github.com/aws/aws-cdk/issues/23218)) ([1a62dc4](https://github.com/aws/aws-cdk/commit/1a62dc4590d725d3c03861af434a24789eaa0a2e)) +* **servicecatalogappregistry:** Cross region warning and default application tag ([#23412](https://github.com/aws/aws-cdk/issues/23412)) ([8d359ae](https://github.com/aws/aws-cdk/commit/8d359ae35877ce066e419f7e2e7da2b0deb587e6)) + ## [2.55.1-alpha.0](https://github.com/aws/aws-cdk/compare/v2.55.0-alpha.0...v2.55.1-alpha.0) (2022-12-16) ## [2.55.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.54.0-alpha.0...v2.55.0-alpha.0) (2022-12-14) diff --git a/CHANGELOG.v2.md b/CHANGELOG.v2.md index edce65d28bb01..2550d9751f759 100644 --- a/CHANGELOG.v2.md +++ b/CHANGELOG.v2.md @@ -2,6 +2,29 @@ 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. +## [2.56.0](https://github.com/aws/aws-cdk/compare/v2.55.1...v2.56.0) (2022-12-21) + + +### Features + +* **aws-cognito:** add AuthSessionValidity property on a UserPoolClient ([#23040](https://github.com/aws/aws-cdk/issues/23040)) ([8896fb9](https://github.com/aws/aws-cdk/commit/8896fb902ad9c8d91a5ddb63df64963186bd09e1)), closes [#22854](https://github.com/aws/aws-cdk/issues/22854) +* **cfnspec:** cloudformation spec v102.0.0 ([#23372](https://github.com/aws/aws-cdk/issues/23372)) ([480b0a5](https://github.com/aws/aws-cdk/commit/480b0a5098e51248bbf36ebf2bcec57cc791c2b0)) +* **core:** CfnResource dependency methods ([#23383](https://github.com/aws/aws-cdk/issues/23383)) ([ecedb00](https://github.com/aws/aws-cdk/commit/ecedb00ee3a3cfcaa2564a679fa635aff38f32d8)), closes [#20419](https://github.com/aws/aws-cdk/issues/20419) [#20418](https://github.com/aws/aws-cdk/issues/20418) +* **lambda:** expose all docker run options to container bundling of all lambda variants ([#23318](https://github.com/aws/aws-cdk/issues/23318)) ([02d0876](https://github.com/aws/aws-cdk/commit/02d0876bbb196e9fbeb32d977e7cf65229c8559d)), closes [#22829](https://github.com/aws/aws-cdk/issues/22829) +* **trigger:** Allow trigger to work with Lambda functions with long timeouts ([#23062](https://github.com/aws/aws-cdk/issues/23062)) ([9fd3811](https://github.com/aws/aws-cdk/commit/9fd3811b3213a227b84d79348e635a520fc537c7)), closes [#23058](https://github.com/aws/aws-cdk/issues/23058) + + +### Bug Fixes + +* **apigateway:** allow multi-level base path mapping ([#23362](https://github.com/aws/aws-cdk/issues/23362)) ([86b6c6f](https://github.com/aws/aws-cdk/commit/86b6c6f796cbd15b7c53a4c0482a2b189d45300f)), closes [#23347](https://github.com/aws/aws-cdk/issues/23347) +* **autoscaling:** Allow adding AutoScalingGroup to multiple target groups ([#23044](https://github.com/aws/aws-cdk/issues/23044)) ([07acd18](https://github.com/aws/aws-cdk/commit/07acd180d778b7084d8519234cfc3570bb8846ba)), closes [/github.com/aws/aws-cdk/issues/5667#issuecomment-636657482](https://github.com/aws//github.com/aws/aws-cdk/issues/5667/issues/issuecomment-636657482) [#5667](https://github.com/aws/aws-cdk/issues/5667) +* **aws-eks:** fail to update both logging and access at the same time ([#22957](https://github.com/aws/aws-cdk/issues/22957)) ([606837d](https://github.com/aws/aws-cdk/commit/606837d3de5d048e3fb1674c30a3048e918f680a)) +* **cognito:** quote or mime-encode `fromName` to comply RFC 5322 ([#23227](https://github.com/aws/aws-cdk/issues/23227)) ([78d474a](https://github.com/aws/aws-cdk/commit/78d474a12bce7805f88be96df926149c130bf513)), closes [#18903](https://github.com/aws/aws-cdk/issues/18903) [/www.rfc-editor.org/rfc/rfc5322#section-3](https://github.com/aws//www.rfc-editor.org/rfc/rfc5322/issues/section-3) +* **core:** cross region ssm writer update ([#23356](https://github.com/aws/aws-cdk/issues/23356)) ([87bd42d](https://github.com/aws/aws-cdk/commit/87bd42d41f11667aef673d9087c28cecedb87f66)) +* **dynamodb:** add kms permissions to grantStreamRead ([#23400](https://github.com/aws/aws-cdk/issues/23400)) ([fcf1bfa](https://github.com/aws/aws-cdk/commit/fcf1bfaab173ee57bbf64d95be62bf10cbb1b851)), closes [40aws-cdk/aws-dynamodb/lib/table.ts#L1025-L1061](https://github.com/40aws-cdk/aws-dynamodb/lib/table.ts/issues/L1025-L1061) +* **s3-deployment:** source markers missing when there are multiple sources ([#23364](https://github.com/aws/aws-cdk/issues/23364)) ([8a7ec37](https://github.com/aws/aws-cdk/commit/8a7ec37e0085e952b59bebab1ecc880167a0691f)), closes [#23321](https://github.com/aws/aws-cdk/issues/23321) [40aws-cdk/aws-s3-deployment/lib/lambda/index.py#L64](https://github.com/40aws-cdk/aws-s3-deployment/lib/lambda/index.py/issues/L64) [40aws-cdk/aws-s3-deployment/lib/lambda/index.py#L137](https://github.com/40aws-cdk/aws-s3-deployment/lib/lambda/index.py/issues/L137) +* **timestream:** magneticStoreWriteProperties and retentionProperties not working as Json ([#23425](https://github.com/aws/aws-cdk/issues/23425)) ([b705224](https://github.com/aws/aws-cdk/commit/b7052242fb699ba89603ae718ae2d6b0ab9efa6f)), closes [#23404](https://github.com/aws/aws-cdk/issues/23404) + ## [2.55.1](https://github.com/aws/aws-cdk/compare/v2.55.0...v2.55.1) (2022-12-16) diff --git a/version.v2.json b/version.v2.json index 5b85393422f62..a95bf59fb520b 100644 --- a/version.v2.json +++ b/version.v2.json @@ -1,4 +1,4 @@ { - "version": "2.55.1", - "alphaVersion": "2.55.1-alpha.0" + "version": "2.56.0", + "alphaVersion": "2.56.0-alpha.0" } \ No newline at end of file From 1b7a384c330d168d64c0cd82118e5b5473d08a67 Mon Sep 17 00:00:00 2001 From: Kyle Laker Date: Wed, 21 Dec 2022 19:00:28 -0500 Subject: [PATCH 14/22] fix(s3): buckets with SSE-KMS silently fail to receive logs (#23385) AWS S3 Server Access Logging does not support logging to buckets that use SSE-KMS, only to buckets without default encryption or to buckets that use SSE-S3. At least in some cases, this misconfiguration can be caught within the CDK (when logging to the same bucket or when the target bucket is using a KMS CMK). This will still fail to catch scenarios where the target bucket is using SSE-KMS using a KMS-managed key because the `encryptionKey` property is not set on the Bucket in that scenario. This may be a breaking change for some users; what is currently a mostly silent misconfiguration will become an error when synthesizing. ---- ### All Submissions: * [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *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/lib/bucket.ts | 11 ++++++++++ packages/@aws-cdk/aws-s3/test/bucket.test.ts | 22 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index c910d93eeff0a..0a7b7c029e63b 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -2044,6 +2044,17 @@ export class Bucket extends BucketBase { if (!props.serverAccessLogsBucket && !props.serverAccessLogsPrefix) { return undefined; } + if ( + // The current bucket is being used and is configured for default SSE-KMS + !props.serverAccessLogsBucket && ( + props.encryptionKey || + props.encryption === BucketEncryption.KMS || + props.encryption === BucketEncryption.KMS_MANAGED) || + // Another bucket is being used that is configured for default SSE-KMS + props.serverAccessLogsBucket?.encryptionKey + ) { + throw new Error('SSE-S3 is the only supported default bucket encryption for Server Access Logging target buckets'); + } return { destinationBucketName: props.serverAccessLogsBucket?.bucketName, diff --git a/packages/@aws-cdk/aws-s3/test/bucket.test.ts b/packages/@aws-cdk/aws-s3/test/bucket.test.ts index ed727d615578a..e412ceb2bc6ad 100644 --- a/packages/@aws-cdk/aws-s3/test/bucket.test.ts +++ b/packages/@aws-cdk/aws-s3/test/bucket.test.ts @@ -337,6 +337,28 @@ describe('bucket', () => { }); + test('throws error if using KMS-Managed key and server access logging to self', () => { + const stack = new cdk.Stack(); + expect(() => { + new s3.Bucket(stack, 'MyBucket', { encryption: s3.BucketEncryption.KMS_MANAGED, serverAccessLogsPrefix: 'test' }); + }).toThrow('SSE-S3 is the only supported default bucket encryption for Server Access Logging target buckets'); + }); + test('throws error if using KMS CMK and server access logging to self', () => { + const stack = new cdk.Stack(); + const key = new kms.Key(stack, 'TestKey'); + expect(() => { + new s3.Bucket(stack, 'MyBucket', { encryptionKey: key, serverAccessLogsPrefix: 'test' }); + }).toThrow('SSE-S3 is the only supported default bucket encryption for Server Access Logging target buckets'); + }); + test('throws error if enabling server access logging to bucket with SSE-KMS', () => { + const stack = new cdk.Stack(); + const key = new kms.Key(stack, 'TestKey'); + const targetBucket = new s3.Bucket(stack, 'TargetBucket', { encryptionKey: key } ); + expect(() => { + new s3.Bucket(stack, 'MyBucket', { serverAccessLogsBucket: targetBucket }); + }).toThrow('SSE-S3 is the only supported default bucket encryption for Server Access Logging target buckets'); + }); + test('bucket with versioning turned on', () => { const stack = new cdk.Stack(); new s3.Bucket(stack, 'MyBucket', { From fc70535fe699e72332d5ddb4543308e76a89594a Mon Sep 17 00:00:00 2001 From: "Huy Phan (Harry)" Date: Fri, 23 Dec 2022 02:15:21 +1100 Subject: [PATCH 15/22] feat(lambda): add support for auto-instrumentation with ADOT Lambda layer (#23027) AWS Distro for OpenTelemetry (ADOT) layers provide OpenTelemetry agent with an out-of-the-box configuration for AWS Lambda and AWS X-Ray. For the popular runtimes (Java, Python, Node), it provides automatic instrumentation without code change. This commit allows CDK users to easily add an ADOT Lambda layer to their Lambda function with the new prop `adotInstrumentationConfig`. For example: ```ts const fn = new lambda.Function(this, 'MyFunction', { ... adotInstrumentation: { layerVersion: AdotLayerVersion.fromJavaScriptSdkLayerVersion(AdotLambdaLayerJavaScriptSdkVersion.V1_7_0), execWrapper: AdotLambdaExecWrapper.REGULAR_HANDLER, } ... }); ``` To support this feature, we provides the following a new classes, enum, and helper functions to users: * `AdotLambdaExecWrapper` is the enum of all possible wrapper script that's provided by ADOT Lambda layer and must be set to the `AWS_LAMBDA_EXEC_WRAPPER` environment variable * `AdotLambdaLayer*Version` are five classes representing five different Lambda layer types offered by ADOT. * `AdotLayerVersion.from*LayerVersion` are five helper functions that return the layer ARN for the Lambda function during synthesis time. If users want to retrieve the ARN independently from enabling ADOT in the Lambda function, they can use the following pattern: ```ts declare const fn: lambda.Function; const layerArn = lambda.AdotLambdaLayerJavaSdkVersion.V1_19_0.layerArn(fn.stack, fn.architecture); ``` ---- ### All Submissions: * [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [X] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *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/README.md | 49 + .../@aws-cdk/aws-lambda/lib/adot-layers.ts | 301 +++ packages/@aws-cdk/aws-lambda/lib/function.ts | 47 +- packages/@aws-cdk/aws-lambda/lib/index.ts | 1 + .../@aws-cdk/aws-lambda/test/adot.test.ts | 89 + .../@aws-cdk/aws-lambda/test/function.test.ts | 50 + ...efaultTestDeployAssertE3E7D2A4.assets.json | 19 + ...aultTestDeployAssertE3E7D2A4.template.json | 36 + .../Stack1.assets.json | 19 + .../Stack1.template.json | 575 ++++++ .../Stack2.assets.json | 19 + .../Stack2.template.json | 526 +++++ .../integ.lambda-adot.js.snapshot/cdk.out | 1 + .../integ.lambda-adot.js.snapshot/integ.json | 13 + .../manifest.json | 338 ++++ .../integ.lambda-adot.js.snapshot/tree.json | 1768 +++++++++++++++++ .../aws-lambda/test/integ.lambda-adot.ts | 97 + .../region-info/build-tools/fact-tables.ts | 215 ++ .../build-tools/generate-static-data.ts | 14 +- packages/@aws-cdk/region-info/lib/fact.ts | 12 + .../@aws-cdk/region-info/lib/region-info.ts | 17 +- 21 files changed, 4198 insertions(+), 8 deletions(-) create mode 100644 packages/@aws-cdk/aws-lambda/lib/adot-layers.ts create mode 100644 packages/@aws-cdk/aws-lambda/test/adot.test.ts create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.assets.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.template.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.assets.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.template.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.ts diff --git a/packages/@aws-cdk/aws-lambda/README.md b/packages/@aws-cdk/aws-lambda/README.md index 419425f44f6a5..b3e118e4f1b10 100644 --- a/packages/@aws-cdk/aws-lambda/README.md +++ b/packages/@aws-cdk/aws-lambda/README.md @@ -764,6 +764,55 @@ const fn = new lambda.Function(this, 'MyFunction', { See [the AWS documentation](https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html) to learn more about AWS Lambda's X-Ray support. +## Lambda with AWS Distro for OpenTelemetry layer + +To have automatic integration with XRay without having to add dependencies or change your code, you can use the +[AWS Distro for OpenTelemetry Lambda (ADOT) layer](https://aws-otel.github.io/docs/getting-started/lambda). +Consuming the latest ADOT layer can be done with the following snippet: + +```ts +import { + AdotLambdaExecWrapper, + AdotLayerVersion, + AdotLambdaLayerJavaScriptSdkVersion, +} from 'aws-cdk-lib/aws-lambda'; + +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_18_X, + handler: 'index.handler', + code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), + adotInstrumentation: { + layerVersion: AdotLayerVersion.fromJavaScriptSdkLayerVersion(AdotLambdaLayerJavaScriptSdkVersion.LATEST), + execWrapper: AdotLambdaExecWrapper.REGULAR_HANDLER, + }, +}); +``` + +To use a different layer version, use one of the following helper functions for the `layerVersion` prop: + +* `AdotLayerVersion.fromJavaScriptSdkLayerVersion` +* `AdotLayerVersion.fromPythonSdkLayerVersion` +* `AdotLayerVersion.fromJavaSdkLayerVersion` +* `AdotLayerVersion.fromJavaAutoInstrumentationSdkLayerVersion` +* `AdotLayerVersion.fromGenericSdkLayerVersion` + +Each helper function expects a version value from a corresponding enum-like class as below: + +* `AdotLambdaLayerJavaScriptSdkVersion` +* `AdotLambdaLayerPythonSdkVersion` +* `AdotLambdaLayerJavaSdkVersion` +* `AdotLambdaLayerJavaAutoInstrumentationSdkVersion` +* `AdotLambdaLayerGenericSdkVersion` + +For more examples, see our [the integration test](test/integ.lambda-adot.ts). + +If you want to retrieve the ARN of the ADOT Lambda layer without enabling ADOT in a Lambda function: + +```ts +declare const fn: lambda.Function; +const layerArn = lambda.AdotLambdaLayerJavaSdkVersion.V1_19_0.layerArn(fn.stack, fn.architecture); +``` + ## Lambda with Profiling The following code configures the lambda function with CodeGuru profiling. By default, this creates a new CodeGuru diff --git a/packages/@aws-cdk/aws-lambda/lib/adot-layers.ts b/packages/@aws-cdk/aws-lambda/lib/adot-layers.ts new file mode 100644 index 0000000000000..401830082e4fb --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/lib/adot-layers.ts @@ -0,0 +1,301 @@ +import { RegionInfo } from '@aws-cdk/region-info'; +import { IConstruct } from 'constructs'; +import { Stack } from '../../core/lib/stack'; +import { Token } from '../../core/lib/token'; +import { FactName } from '../../region-info/lib/fact'; +import { Architecture } from './architecture'; +import { IFunction } from './function-base'; + +/** + * The type of ADOT Lambda layer + */ +enum AdotLambdaLayerType { + /** + * The Lambda layer for ADOT Java instrumentation library. This layer only auto-instruments AWS + * SDK libraries. + */ + JAVA_SDK = 'JAVA_SDK', + + /** + * The Lambda layer for ADOT Java Auto-Instrumentation Agent. This layer automatically instruments + * a large number of libraries and frameworks out of the box and has notable impact on startup + * performance. + */ + JAVA_AUTO_INSTRUMENTATION = 'JAVA_AUTO_INSTRUMENTATION', + + /** + * The Lambda layer for ADOT Collector, OpenTelemetry for JavaScript and supported libraries. + */ + JAVASCRIPT_SDK = 'JAVASCRIPT_SDK', + + /** + * The Lambda layer for ADOT Collector, OpenTelemetry for Python and supported libraries. + */ + PYTHON_SDK = 'PYTHON_SDK', + + /** + * The generic Lambda layer that contains only ADOT Collector, used for manual instrumentation + * use cases (such as Go or DotNet runtimes). + */ + GENERIC = 'GENERIC', +} + +/** + * Config returned from {@link AdotLambdaLayerVersion._bind} + */ +interface AdotLambdaLayerBindConfig { + /** + * ARN of the ADOT Lambda layer version + */ + readonly arn: string; +} + +/** + * Return the ARN of an ADOT Lambda layer given its properties. If the region name is unknown + * at synthesis time, it will generate a map in the CloudFormation template and perform the look + * up at deployment time. + * + * @param scope the parent Construct that will use the imported layer. + * @param type the type of the ADOT Lambda layer + * @param version The version of the ADOT Lambda layer + * @param architecture the architecture of the Lambda layer ('amd64' or 'arm64') + */ +function getLayerArn(scope: IConstruct, type: string, version: string, architecture: string): string { + const scopeStack = Stack.of(scope); + const region = scopeStack.region; + + // Region is defined, look up the arn, or throw an error if the version isn't supported by a region + if (region !== undefined && !Token.isUnresolved(region)) { + const arn = RegionInfo.get(region).adotLambdaLayerArn(type, version, architecture); + if (arn === undefined) { + throw new Error( + `Could not find the ARN information for the ADOT Lambda Layer of type ${type} and version ${version} in ${region}`, + ); + } + return arn; + } + + // Otherwise, need to add a mapping to be looked up at deployment time + return scopeStack.regionalFact(FactName.adotLambdaLayer(type, version, architecture)); +} + +/** + * Properties for an ADOT instrumentation in Lambda + */ +export interface AdotInstrumentationConfig { + /** + * The ADOT Lambda layer. + */ + readonly layerVersion: AdotLayerVersion; + + /** + * The startup script to run, see ADOT documentation to pick the right script for your use case: https://aws-otel.github.io/docs/getting-started/lambda + */ + readonly execWrapper: AdotLambdaExecWrapper; +} + +/** + * An ADOT Lambda layer version that's specific to a lambda layer type and an architecture. + */ +export abstract class AdotLayerVersion { + /** + * The ADOT Lambda layer for Java SDK + * + * @param version The version of the Lambda layer to use + */ + public static fromJavaSdkLayerVersion(version: AdotLambdaLayerJavaSdkVersion): AdotLayerVersion { + return AdotLayerVersion.fromAdotVersion(version); + } + + /** + * The ADOT Lambda layer for Java auto instrumentation + * + * @param version The version of the Lambda layer to use + */ + public static fromJavaAutoInstrumentationLayerVersion( + version: AdotLambdaLayerJavaAutoInstrumentationVersion, + ): AdotLayerVersion { + return AdotLayerVersion.fromAdotVersion(version); + } + + /** + * The ADOT Lambda layer for JavaScript SDK + * + * @param version The version of the Lambda layer to use + */ + public static fromJavaScriptSdkLayerVersion(version: AdotLambdaLayerJavaScriptSdkVersion): AdotLayerVersion { + return AdotLayerVersion.fromAdotVersion(version); + } + + /** + * The ADOT Lambda layer for Python SDK + * + * @param version The version of the Lambda layer to use + */ + public static fromPythonSdkLayerVersion(version: AdotLambdaLayerPythonSdkVersion): AdotLayerVersion { + return AdotLayerVersion.fromAdotVersion(version); + } + + /** + * The ADOT Lambda layer for generic use cases + * + * @param version The version of the Lambda layer to use + */ + public static fromGenericLayerVersion(version: AdotLambdaLayerGenericVersion): AdotLayerVersion { + return AdotLayerVersion.fromAdotVersion(version); + } + + private static fromAdotVersion(adotVersion: AdotLambdaLayerVersion): AdotLayerVersion { + return new (class extends AdotLayerVersion { + _bind(_function: IFunction): AdotLambdaLayerBindConfig { + return { + arn: adotVersion.layerArn(_function.stack, _function.architecture), + }; + } + })(); + } + + /** + * Produce a `AdotLambdaLayerBindConfig` instance from this `AdotLayerVersion` instance. + * + * @internal + */ + public abstract _bind(_function: IFunction): AdotLambdaLayerBindConfig; +} + +/** + * The wrapper script to be used for the Lambda function in order to enable auto instrumentation + * with ADOT. + */ +export enum AdotLambdaExecWrapper { + /** + * Wrapping regular Lambda handlers. + */ + REGULAR_HANDLER = '/opt/otel-handler', + + /** + * Wrapping regular handlers (implementing RequestHandler) proxied through API Gateway, enabling + * HTTP context propagation. + */ + PROXY_HANDLER = '/opt/otel-proxy-handler', + + /** + * Wrapping streaming handlers (implementing RequestStreamHandler), enabling HTTP context + * propagation for HTTP requests. + */ + STREAM_HANDLER = '/opt/otel-stream-handler', +} + +abstract class AdotLambdaLayerVersion { + protected constructor(protected readonly type: AdotLambdaLayerType, protected readonly version: string) {} + + /** + * The ARN of the Lambda layer + * + * @param scope The binding scope. Usually this is the stack where the Lambda layer is bound to + * @param architecture The architecture of the Lambda layer (either X86_64 or ARM_64) + */ + public layerArn(scope: IConstruct, architecture: Architecture): string { + return getLayerArn(scope, this.type, this.version, architecture.name); + } +} + +/** + * The collection of versions of the ADOT Lambda Layer for Java SDK + */ +export class AdotLambdaLayerJavaSdkVersion extends AdotLambdaLayerVersion { + /** + * The latest layer version available in this CDK version. New versions could + * introduce incompatible changes. Make sure to test them before deploying to production. + */ + public static readonly LATEST = new AdotLambdaLayerJavaSdkVersion('1.19.0'); + + /** + * Version 1.19.0 + */ + public static readonly V1_19_0 = new AdotLambdaLayerJavaSdkVersion('1.19.0'); + + private constructor(protected readonly layerVersion: string) { + super(AdotLambdaLayerType.JAVA_SDK, layerVersion); + } +} + +/** + * The collection of versions of the ADOT Lambda Layer for Java auto-instrumentation + */ +export class AdotLambdaLayerJavaAutoInstrumentationVersion extends AdotLambdaLayerVersion { + /** + * The latest layer version available in this CDK version. New versions could + * introduce incompatible changes. Make sure to test them before deploying to production. + */ + public static readonly LATEST = new AdotLambdaLayerJavaAutoInstrumentationVersion('1.19.2'); + + /** + * Version 1.19.2 + */ + public static readonly V1_19_2 = new AdotLambdaLayerJavaAutoInstrumentationVersion('1.19.2'); + + private constructor(protected readonly layerVersion: string) { + super(AdotLambdaLayerType.JAVA_AUTO_INSTRUMENTATION, layerVersion); + } +} + +/** + * The collection of versions of the ADOT Lambda Layer for Python SDK + */ +export class AdotLambdaLayerPythonSdkVersion extends AdotLambdaLayerVersion { + /** + * The latest layer version available in this CDK version. New versions could + * introduce incompatible changes. Make sure to test them before deploying to production. + */ + public static readonly LATEST = new AdotLambdaLayerPythonSdkVersion('1.13.0'); + + /** + * Version 1.13.0 + */ + public static readonly V1_13_0 = new AdotLambdaLayerPythonSdkVersion('1.13.0'); + + private constructor(protected readonly layerVersion: string) { + super(AdotLambdaLayerType.PYTHON_SDK, layerVersion); + } +} + +/** + * The collection of versions of the ADOT Lambda Layer for JavaScript SDK + */ +export class AdotLambdaLayerJavaScriptSdkVersion extends AdotLambdaLayerVersion { + /** + * The latest layer version available in this CDK version. New versions could + * introduce incompatible changes. Make sure to test them before deploying to production. + */ + public static readonly LATEST = new AdotLambdaLayerJavaScriptSdkVersion('1.7.0'); + + /** + * Version 1.7.0 + */ + public static readonly V1_7_0 = new AdotLambdaLayerJavaScriptSdkVersion('1.7.0'); + + private constructor(protected readonly layerVersion: string) { + super(AdotLambdaLayerType.JAVASCRIPT_SDK, layerVersion); + } +} + +/** + * The collection of versions of the ADOT Lambda Layer for generic purpose + */ +export class AdotLambdaLayerGenericVersion extends AdotLambdaLayerVersion { + /** + * The latest layer version available in this CDK version. New versions could + * introduce incompatible changes. Make sure to test them before deploying to production. + */ + public static readonly LATEST = new AdotLambdaLayerGenericVersion('0.62.1'); + + /** + * Version 0.62.1 + */ + public static readonly V0_62_1 = new AdotLambdaLayerGenericVersion('0.62.1'); + + private constructor(protected readonly layerVersion: string) { + super(AdotLambdaLayerType.GENERIC, layerVersion); + } +} diff --git a/packages/@aws-cdk/aws-lambda/lib/function.ts b/packages/@aws-cdk/aws-lambda/lib/function.ts index 0976b2962e7cf..a39a8fe7a9ea5 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function.ts @@ -9,6 +9,7 @@ import * as sqs from '@aws-cdk/aws-sqs'; import { Annotations, ArnFormat, CfnResource, Duration, FeatureFlags, Fn, IAspect, Lazy, Names, Size, Stack, Token } from '@aws-cdk/core'; import { LAMBDA_RECOGNIZE_LAYER_VERSION } from '@aws-cdk/cx-api'; import { Construct, IConstruct } from 'constructs'; +import { AdotInstrumentationConfig } from './adot-layers'; import { AliasOptions, Alias } from './alias'; import { Architecture } from './architecture'; import { Code, CodeConfig } from './code'; @@ -250,6 +251,14 @@ export interface FunctionOptions extends EventInvokeConfigOptions { */ readonly insightsVersion?: LambdaInsightsVersion; + /** + * Specify the configuration of AWS Distro for OpenTelemetry (ADOT) instrumentation + * @see https://aws-otel.github.io/docs/getting-started/lambda + * + * @default - No ADOT instrumentation + */ + readonly adotInstrumentation?: AdotInstrumentationConfig; + /** * A list of layers to add to the function's execution environment. You can configure your Lambda function to pull in * additional code during initialization in the form of layers. Layers are packages of libraries or other dependencies @@ -794,7 +803,6 @@ export class Function extends FunctionBase { } : undefined, vpcConfig: this.configureVpc(props), deadLetterConfig: this.buildDeadLetterConfig(dlqTopicOrQueue), - tracingConfig: this.buildTracingConfig(props), reservedConcurrentExecutions: props.reservedConcurrentExecutions, imageConfig: undefinedIfNoKeys({ command: code.image?.cmd, @@ -807,6 +815,10 @@ export class Function extends FunctionBase { architectures: this._architecture ? [this._architecture.name] : undefined, }); + if ((props.tracing !== undefined) || (props.adotInstrumentation !== undefined)) { + resource.tracingConfig = this.buildTracingConfig(props.tracing ?? Tracing.ACTIVE); + } + resource.node.addDependency(this.role); this.functionName = this.getResourceNameAttribute(resource.ref); @@ -891,6 +903,8 @@ export class Function extends FunctionBase { // Configure Lambda insights this.configureLambdaInsights(props); + + this.configureAdotInstrumentation(props); } /** @@ -1079,6 +1093,31 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett this.role?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLambdaInsightsExecutionRolePolicy')); } + /** + * Add an AWS Distro for OpenTelemetry Lambda layer. + * + * @param props properties for the ADOT instrumentation + */ + private configureAdotInstrumentation(props: FunctionProps): void { + + if (props.adotInstrumentation === undefined) { + return; + } + + if (props.runtime === Runtime.FROM_IMAGE) { + throw new Error("ADOT Lambda layer can't be configured with container image package type"); + } + + // This is not the complete list of incompatible runtimes and layer types. We are only + // checking for common mistakes on a best-effort basis. + if (this.runtime === Runtime.GO_1_X) { + throw new Error('Runtime go1.x is not supported by the ADOT Lambda Go SDK'); + } + + this.addLayers(LayerVersion.fromLayerVersionArn(this, 'AdotLayer', props.adotInstrumentation.layerVersion._bind(this).arn)); + this.addEnvironment('AWS_LAMBDA_EXEC_WRAPPER', props.adotInstrumentation.execWrapper); + } + private renderLayers() { if (!this._layers || this._layers.length === 0) { return undefined; @@ -1228,8 +1267,8 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett } } - private buildTracingConfig(props: FunctionProps) { - if (props.tracing === undefined || props.tracing === Tracing.DISABLED) { + private buildTracingConfig(tracing: Tracing) { + if (tracing === undefined || tracing === Tracing.DISABLED) { return undefined; } @@ -1239,7 +1278,7 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett })); return { - mode: props.tracing, + mode: tracing, }; } diff --git a/packages/@aws-cdk/aws-lambda/lib/index.ts b/packages/@aws-cdk/aws-lambda/lib/index.ts index 104afa76627a0..e317a58bee4bf 100644 --- a/packages/@aws-cdk/aws-lambda/lib/index.ts +++ b/packages/@aws-cdk/aws-lambda/lib/index.ts @@ -1,3 +1,4 @@ +export * from './adot-layers'; export * from './alias'; export * from './dlq'; export * from './function-base'; diff --git a/packages/@aws-cdk/aws-lambda/test/adot.test.ts b/packages/@aws-cdk/aws-lambda/test/adot.test.ts new file mode 100644 index 0000000000000..93ff30eb9cf49 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/adot.test.ts @@ -0,0 +1,89 @@ +import { Template } from '@aws-cdk/assertions'; +import * as s3 from '@aws-cdk/aws-s3'; +import * as cdk from '@aws-cdk/core'; +import * as lambda from '../lib'; + +describe('ADOT Lambda Layer', () => { + + describe('when the stack region is specified and supported', () => { + + let fn: lambda.Function; + + beforeEach(() => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack', { env: { region: 'us-west-2' } }); + const bucket = new s3.Bucket(stack, 'CodeBucket'); + fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromBucket(bucket, 'mock_key'), + handler: 'index.handler', + runtime: lambda.Runtime.JAVA_11, + }); + }); + + test('is added properly when the region information is available at synthesis time', () => { + const layerArn = lambda.AdotLambdaLayerJavaSdkVersion.V1_19_0.layerArn(fn.stack, fn.architecture); + + expect(layerArn).toEqual( + 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + ); + }); + + test('is added properly when using "LATEST" version', () => { + const layerArn = lambda.AdotLambdaLayerJavaSdkVersion.LATEST.layerArn(fn.stack, fn.architecture); + + expect(layerArn).toEqual( + 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + ); + }); + }); + + describe('when the stack region is not supported', () => { + test('throws error if the region is not supported', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack', { env: { region: 'neverland' } }); + const bucket = new s3.Bucket(stack, 'CodeBucket'); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromBucket(bucket, 'mock_key'), + handler: 'index.handler', + runtime: lambda.Runtime.JAVA_11, + }); + + expect(() => { + lambda.AdotLayerVersion.fromJavaSdkLayerVersion( + lambda.AdotLambdaLayerJavaSdkVersion.LATEST, + )._bind(fn).arn; + }).toThrow(/Could not find the ARN information for the ADOT Lambda Layer/); + }); + }); + + describe('when the stack is region agnostic', () => { + test('is added properly', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'region-agnostic-stack'); + const fn = new lambda.Function(stack, 'Function', { + code: new lambda.InlineCode('FooBar'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_14_X, + architecture: lambda.Architecture.ARM_64, + }); + + const layerArn = lambda.AdotLambdaLayerJavaSdkVersion.LATEST.layerArn(stack, fn.architecture); + fn.stack.exportValue(layerArn, { + name: 'LayerArn', + }); + + // THEN + Template.fromStack(fn.stack).hasOutput('ExportLayerArn', { + Value: { + 'Fn::FindInMap': [ + 'AdotlambdalayerMap', + { + Ref: 'AWS::Region', + }, + 'JAVAxSDKx1x19x0xarm64', + ], + }, + }); + }); + }); +}); diff --git a/packages/@aws-cdk/aws-lambda/test/function.test.ts b/packages/@aws-cdk/aws-lambda/test/function.test.ts index cd128a5050193..e16e17198bbf3 100644 --- a/packages/@aws-cdk/aws-lambda/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda/test/function.test.ts @@ -17,6 +17,7 @@ import * as cxapi from '@aws-cdk/cx-api'; import * as constructs from 'constructs'; import * as _ from 'lodash'; import * as lambda from '../lib'; +import { AdotLambdaLayerJavaSdkVersion } from '../lib/adot-layers'; import { calculateFunctionHash } from '../lib/function-hash'; describe('function', () => { @@ -3070,6 +3071,55 @@ describe('function', () => { Runtime: 'nodejs14.x', }); }); + + test('adds ADOT instrumentation to a ZIP Lambda function', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Base', { + env: { account: '111111111111', region: 'us-west-2' }, + }); + + // WHEN + new lambda.Function(stack, 'MyLambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_14_X, + adotInstrumentation: { + layerVersion: lambda.AdotLayerVersion.fromJavaSdkLayerVersion(AdotLambdaLayerJavaSdkVersion.V1_19_0), + execWrapper: lambda.AdotLambdaExecWrapper.REGULAR_HANDLER, + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + Layers: ['arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1'], + Environment: { + Variables: { + AWS_LAMBDA_EXEC_WRAPPER: '/opt/otel-handler', + }, + }, + }); + }); + + test('adds ADOT instrumentation to a container image Lambda function', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Base', { + env: { account: '111111111111', region: 'us-west-2' }, + }); + + // WHEN + expect( + () => + new lambda.DockerImageFunction(stack, 'MyLambda', { + code: lambda.DockerImageCode.fromImageAsset(path.join(__dirname, 'docker-lambda-handler')), + adotInstrumentation: { + layerVersion: lambda.AdotLayerVersion.fromJavaSdkLayerVersion(AdotLambdaLayerJavaSdkVersion.V1_19_0), + execWrapper: lambda.AdotLambdaExecWrapper.REGULAR_HANDLER, + }, + }), + ).toThrow(/ADOT Lambda layer can't be configured with container image package type/); + }); }); test('throws if ephemeral storage size is out of bound', () => { diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json new file mode 100644 index 0000000000000..ab8ca0bd4a1f2 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.assets.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.assets.json new file mode 100644 index 0000000000000..a0e1449cea6ee --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "47696196003068eea2528656bebb8f11e163f75e8635d774b801bbc06a0e57e2": { + "source": { + "path": "Stack1.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "47696196003068eea2528656bebb8f11e163f75e8635d774b801bbc06a0e57e2.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.template.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.template.json new file mode 100644 index 0000000000000..7c14bc7d09da1 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack1.template.json @@ -0,0 +1,575 @@ +{ + "Resources": { + "MyFunc1ServiceRoleF96C5B5C": { + "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" + ] + ] + } + ] + } + }, + "MyFunc1ServiceRoleDefaultPolicy3C5E9573": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc1ServiceRoleDefaultPolicy3C5E9573", + "Roles": [ + { + "Ref": "MyFunc1ServiceRoleF96C5B5C" + } + ] + } + }, + "MyFunc11BE70A62": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc1ServiceRoleF96C5B5C", + "Arn" + ] + }, + "Architectures": [ + "arm64" + ], + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::FindInMap": [ + "AdotlambdalayerMap", + { + "Ref": "AWS::Region" + }, + "JAVASCRIPTxSDKx1x7x0xarm64" + ] + } + ], + "Runtime": "nodejs14.x", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc1ServiceRoleDefaultPolicy3C5E9573", + "MyFunc1ServiceRoleF96C5B5C" + ] + }, + "MyFunc2ServiceRole68E50443": { + "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" + ] + ] + } + ] + } + }, + "MyFunc2ServiceRoleDefaultPolicyEF3319F6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc2ServiceRoleDefaultPolicyEF3319F6", + "Roles": [ + { + "Ref": "MyFunc2ServiceRole68E50443" + } + ] + } + }, + "MyFunc242557A97": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc2ServiceRole68E50443", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc2ServiceRoleDefaultPolicyEF3319F6", + "MyFunc2ServiceRole68E50443" + ] + }, + "MyFunc3ServiceRoleA69795ED": { + "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" + ] + ] + } + ] + } + }, + "MyFunc3ServiceRoleDefaultPolicy449C4CBA": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc3ServiceRoleDefaultPolicy449C4CBA", + "Roles": [ + { + "Ref": "MyFunc3ServiceRoleA69795ED" + } + ] + } + }, + "MyFunc3666B7A2F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc3ServiceRoleA69795ED", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc3ServiceRoleDefaultPolicy449C4CBA", + "MyFunc3ServiceRoleA69795ED" + ] + }, + "MyFunc4ServiceRole93C4DEFF": { + "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" + ] + ] + } + ] + } + }, + "MyFunc4ServiceRoleDefaultPolicy68C57CB2": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc4ServiceRoleDefaultPolicy68C57CB2", + "Roles": [ + { + "Ref": "MyFunc4ServiceRole93C4DEFF" + } + ] + } + }, + "MyFunc4B88F85C6": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc4ServiceRole93C4DEFF", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc4ServiceRoleDefaultPolicy68C57CB2", + "MyFunc4ServiceRole93C4DEFF" + ] + }, + "MyFunc5ServiceRoleFE4CE92B": { + "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" + ] + ] + } + ] + } + }, + "MyFunc5ServiceRoleDefaultPolicy96ABEA66": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc5ServiceRoleDefaultPolicy96ABEA66", + "Roles": [ + { + "Ref": "MyFunc5ServiceRoleFE4CE92B" + } + ] + } + }, + "MyFunc586573B53": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc5ServiceRoleFE4CE92B", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc5ServiceRoleDefaultPolicy96ABEA66", + "MyFunc5ServiceRoleFE4CE92B" + ] + } + }, + "Mappings": { + "AdotlambdalayerMap": { + "ap-northeast-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "ap-northeast-2": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1" + }, + "ap-south-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "ap-southeast-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "ap-southeast-2": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "ca-central-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1" + }, + "eu-central-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "eu-north-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1" + }, + "eu-west-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "eu-west-2": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "eu-west-3": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1" + }, + "sa-east-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1" + }, + "us-east-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "us-east-2": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + }, + "us-west-1": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1" + }, + "us-west-2": { + "JAVASCRIPTxSDKx1x7x0xarm64": "arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.assets.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.assets.json new file mode 100644 index 0000000000000..48c0af9610b9d --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "a4926065bd63dad984b7b214cd689e14b56eeec5afba89f078cd5134f8304bd8": { + "source": { + "path": "Stack2.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "a4926065bd63dad984b7b214cd689e14b56eeec5afba89f078cd5134f8304bd8.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.template.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.template.json new file mode 100644 index 0000000000000..d268d79b5f964 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/Stack2.template.json @@ -0,0 +1,526 @@ +{ + "Resources": { + "MyFunc1ServiceRoleF96C5B5C": { + "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" + ] + ] + } + ] + } + }, + "MyFunc1ServiceRoleDefaultPolicy3C5E9573": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc1ServiceRoleDefaultPolicy3C5E9573", + "Roles": [ + { + "Ref": "MyFunc1ServiceRoleF96C5B5C" + } + ] + } + }, + "MyFunc11BE70A62": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc1ServiceRoleF96C5B5C", + "Arn" + ] + }, + "Architectures": [ + "x86_64" + ], + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2" + ] + ] + } + ], + "Runtime": "nodejs14.x", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc1ServiceRoleDefaultPolicy3C5E9573", + "MyFunc1ServiceRoleF96C5B5C" + ] + }, + "MyFunc2ServiceRole68E50443": { + "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" + ] + ] + } + ] + } + }, + "MyFunc2ServiceRoleDefaultPolicyEF3319F6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc2ServiceRoleDefaultPolicyEF3319F6", + "Roles": [ + { + "Ref": "MyFunc2ServiceRole68E50443" + } + ] + } + }, + "MyFunc242557A97": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc2ServiceRole68E50443", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc2ServiceRoleDefaultPolicyEF3319F6", + "MyFunc2ServiceRole68E50443" + ] + }, + "MyFunc3ServiceRoleA69795ED": { + "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" + ] + ] + } + ] + } + }, + "MyFunc3ServiceRoleDefaultPolicy449C4CBA": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc3ServiceRoleDefaultPolicy449C4CBA", + "Roles": [ + { + "Ref": "MyFunc3ServiceRoleA69795ED" + } + ] + } + }, + "MyFunc3666B7A2F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc3ServiceRoleA69795ED", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc3ServiceRoleDefaultPolicy449C4CBA", + "MyFunc3ServiceRoleA69795ED" + ] + }, + "MyFunc4ServiceRole93C4DEFF": { + "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" + ] + ] + } + ] + } + }, + "MyFunc4ServiceRoleDefaultPolicy68C57CB2": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc4ServiceRoleDefaultPolicy68C57CB2", + "Roles": [ + { + "Ref": "MyFunc4ServiceRole93C4DEFF" + } + ] + } + }, + "MyFunc4B88F85C6": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc4ServiceRole93C4DEFF", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc4ServiceRoleDefaultPolicy68C57CB2", + "MyFunc4ServiceRole93C4DEFF" + ] + }, + "MyFunc5ServiceRoleFE4CE92B": { + "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" + ] + ] + } + ] + } + }, + "MyFunc5ServiceRoleDefaultPolicy96ABEA66": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyFunc5ServiceRoleDefaultPolicy96ABEA66", + "Roles": [ + { + "Ref": "MyFunc5ServiceRoleFE4CE92B" + } + ] + } + }, + "MyFunc586573B53": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "def handler(event, context): pass" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc5ServiceRoleFE4CE92B", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1" + ] + ] + } + ], + "Runtime": "python3.9", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "MyFunc5ServiceRoleDefaultPolicy96ABEA66", + "MyFunc5ServiceRoleFE4CE92B" + ] + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/cdk.out b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/cdk.out new file mode 100644 index 0000000000000..145739f539580 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/integ.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/integ.json new file mode 100644 index 0000000000000..48b2c710d1101 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "22.0.0", + "testCases": { + "IntegTest/DefaultTest": { + "stacks": [ + "Stack1", + "Stack2" + ], + "assertionStack": "IntegTest/DefaultTest/DeployAssert", + "assertionStackName": "IntegTestDefaultTestDeployAssertE3E7D2A4" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/manifest.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/manifest.json new file mode 100644 index 0000000000000..0c1767cb8ed9c --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/manifest.json @@ -0,0 +1,338 @@ +{ + "version": "22.0.0", + "artifacts": { + "Stack1.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "Stack1.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "Stack1": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "Stack1.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/47696196003068eea2528656bebb8f11e163f75e8635d774b801bbc06a0e57e2.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "Stack1.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "Stack1.assets" + ], + "metadata": { + "/Stack1/MyFunc1/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc1ServiceRoleF96C5B5C" + } + ], + "/Stack1/MyFunc1/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc1ServiceRoleDefaultPolicy3C5E9573" + } + ], + "/Stack1/MyFunc1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc11BE70A62" + } + ], + "/Stack1/Adot-lambda-layerMap": [ + { + "type": "aws:cdk:logicalId", + "data": "AdotlambdalayerMap" + } + ], + "/Stack1/MyFunc2/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc2ServiceRole68E50443" + } + ], + "/Stack1/MyFunc2/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc2ServiceRoleDefaultPolicyEF3319F6" + } + ], + "/Stack1/MyFunc2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc242557A97" + } + ], + "/Stack1/MyFunc3/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc3ServiceRoleA69795ED" + } + ], + "/Stack1/MyFunc3/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc3ServiceRoleDefaultPolicy449C4CBA" + } + ], + "/Stack1/MyFunc3/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc3666B7A2F" + } + ], + "/Stack1/MyFunc4/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc4ServiceRole93C4DEFF" + } + ], + "/Stack1/MyFunc4/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc4ServiceRoleDefaultPolicy68C57CB2" + } + ], + "/Stack1/MyFunc4/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc4B88F85C6" + } + ], + "/Stack1/MyFunc5/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc5ServiceRoleFE4CE92B" + } + ], + "/Stack1/MyFunc5/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc5ServiceRoleDefaultPolicy96ABEA66" + } + ], + "/Stack1/MyFunc5/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc586573B53" + } + ], + "/Stack1/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/Stack1/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "Stack1" + }, + "Stack2.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "Stack2.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "Stack2": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "Stack2.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a4926065bd63dad984b7b214cd689e14b56eeec5afba89f078cd5134f8304bd8.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "Stack2.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "Stack2.assets" + ], + "metadata": { + "/Stack2/MyFunc1/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc1ServiceRoleF96C5B5C" + } + ], + "/Stack2/MyFunc1/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc1ServiceRoleDefaultPolicy3C5E9573" + } + ], + "/Stack2/MyFunc1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc11BE70A62" + } + ], + "/Stack2/MyFunc2/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc2ServiceRole68E50443" + } + ], + "/Stack2/MyFunc2/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc2ServiceRoleDefaultPolicyEF3319F6" + } + ], + "/Stack2/MyFunc2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc242557A97" + } + ], + "/Stack2/MyFunc3/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc3ServiceRoleA69795ED" + } + ], + "/Stack2/MyFunc3/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc3ServiceRoleDefaultPolicy449C4CBA" + } + ], + "/Stack2/MyFunc3/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc3666B7A2F" + } + ], + "/Stack2/MyFunc4/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc4ServiceRole93C4DEFF" + } + ], + "/Stack2/MyFunc4/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc4ServiceRoleDefaultPolicy68C57CB2" + } + ], + "/Stack2/MyFunc4/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc4B88F85C6" + } + ], + "/Stack2/MyFunc5/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc5ServiceRoleFE4CE92B" + } + ], + "/Stack2/MyFunc5/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc5ServiceRoleDefaultPolicy96ABEA66" + } + ], + "/Stack2/MyFunc5/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunc586573B53" + } + ], + "/Stack2/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/Stack2/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "Stack2" + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "metadata": { + "/IntegTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "IntegTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/tree.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/tree.json new file mode 100644 index 0000000000000..9f2eb419a99ba --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.js.snapshot/tree.json @@ -0,0 +1,1768 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Stack1": { + "id": "Stack1", + "path": "Stack1", + "children": { + "MyFunc1": { + "id": "MyFunc1", + "path": "Stack1/MyFunc1", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack1/MyFunc1/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack1/MyFunc1/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc1/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack1/MyFunc1/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc1/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc1ServiceRoleDefaultPolicy3C5E9573", + "roles": [ + { + "Ref": "MyFunc1ServiceRoleF96C5B5C" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc1ServiceRoleF96C5B5C", + "Arn" + ] + }, + "architectures": [ + "arm64" + ], + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::FindInMap": [ + "AdotlambdalayerMap", + { + "Ref": "AWS::Region" + }, + "JAVASCRIPTxSDKx1x7x0xarm64" + ] + } + ], + "runtime": "nodejs14.x", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "Adot-lambda-layerMap": { + "id": "Adot-lambda-layerMap", + "path": "Stack1/Adot-lambda-layerMap", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnMapping", + "version": "0.0.0" + } + }, + "AdotLayer1": { + "id": "AdotLayer1", + "path": "Stack1/AdotLayer1", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc2": { + "id": "MyFunc2", + "path": "Stack1/MyFunc2", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack1/MyFunc2/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack1/MyFunc2/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc2/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack1/MyFunc2/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc2/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc2ServiceRoleDefaultPolicyEF3319F6", + "roles": [ + { + "Ref": "MyFunc2ServiceRole68E50443" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc2ServiceRole68E50443", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer2": { + "id": "AdotLayer2", + "path": "Stack1/AdotLayer2", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc3": { + "id": "MyFunc3", + "path": "Stack1/MyFunc3", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack1/MyFunc3/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack1/MyFunc3/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc3/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack1/MyFunc3/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc3/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc3ServiceRoleDefaultPolicy449C4CBA", + "roles": [ + { + "Ref": "MyFunc3ServiceRoleA69795ED" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc3/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc3ServiceRoleA69795ED", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer3": { + "id": "AdotLayer3", + "path": "Stack1/AdotLayer3", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc4": { + "id": "MyFunc4", + "path": "Stack1/MyFunc4", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack1/MyFunc4/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack1/MyFunc4/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc4/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack1/MyFunc4/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc4/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc4ServiceRoleDefaultPolicy68C57CB2", + "roles": [ + { + "Ref": "MyFunc4ServiceRole93C4DEFF" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc4/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc4ServiceRole93C4DEFF", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer4": { + "id": "AdotLayer4", + "path": "Stack1/AdotLayer4", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc5": { + "id": "MyFunc5", + "path": "Stack1/MyFunc5", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack1/MyFunc5/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack1/MyFunc5/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc5/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack1/MyFunc5/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc5/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc5ServiceRoleDefaultPolicy96ABEA66", + "roles": [ + { + "Ref": "MyFunc5ServiceRoleFE4CE92B" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack1/MyFunc5/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc5ServiceRoleFE4CE92B", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer5": { + "id": "AdotLayer5", + "path": "Stack1/AdotLayer5", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "Stack1/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "Stack1/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "Stack2": { + "id": "Stack2", + "path": "Stack2", + "children": { + "MyFunc1": { + "id": "MyFunc1", + "path": "Stack2/MyFunc1", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack2/MyFunc1/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack2/MyFunc1/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc1/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack2/MyFunc1/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc1/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc1ServiceRoleDefaultPolicy3C5E9573", + "roles": [ + { + "Ref": "MyFunc1ServiceRoleF96C5B5C" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc1ServiceRoleF96C5B5C", + "Arn" + ] + }, + "architectures": [ + "x86_64" + ], + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2" + ] + ] + } + ], + "runtime": "nodejs14.x", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer1": { + "id": "AdotLayer1", + "path": "Stack2/AdotLayer1", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc2": { + "id": "MyFunc2", + "path": "Stack2/MyFunc2", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack2/MyFunc2/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack2/MyFunc2/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc2/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack2/MyFunc2/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc2/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc2ServiceRoleDefaultPolicyEF3319F6", + "roles": [ + { + "Ref": "MyFunc2ServiceRole68E50443" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc2ServiceRole68E50443", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer2": { + "id": "AdotLayer2", + "path": "Stack2/AdotLayer2", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc3": { + "id": "MyFunc3", + "path": "Stack2/MyFunc3", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack2/MyFunc3/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack2/MyFunc3/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc3/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack2/MyFunc3/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc3/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc3ServiceRoleDefaultPolicy449C4CBA", + "roles": [ + { + "Ref": "MyFunc3ServiceRoleA69795ED" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc3/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc3ServiceRoleA69795ED", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer3": { + "id": "AdotLayer3", + "path": "Stack2/AdotLayer3", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc4": { + "id": "MyFunc4", + "path": "Stack2/MyFunc4", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack2/MyFunc4/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack2/MyFunc4/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc4/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack2/MyFunc4/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc4/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc4ServiceRoleDefaultPolicy68C57CB2", + "roles": [ + { + "Ref": "MyFunc4ServiceRole93C4DEFF" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc4/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc4ServiceRole93C4DEFF", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer4": { + "id": "AdotLayer4", + "path": "Stack2/AdotLayer4", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyFunc5": { + "id": "MyFunc5", + "path": "Stack2/MyFunc5", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "Stack2/MyFunc5/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "Stack2/MyFunc5/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc5/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "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" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "Stack2/MyFunc5/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc5/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyFunc5ServiceRoleDefaultPolicy96ABEA66", + "roles": [ + { + "Ref": "MyFunc5ServiceRoleFE4CE92B" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "Stack2/MyFunc5/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "def handler(event, context): pass" + }, + "role": { + "Fn::GetAtt": [ + "MyFunc5ServiceRoleFE4CE92B", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-handler" + } + }, + "handler": "index.handler", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1" + ] + ] + } + ], + "runtime": "python3.9", + "tracingConfig": { + "mode": "Active" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "AdotLayer5": { + "id": "AdotLayer5", + "path": "Stack2/AdotLayer5", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "Stack2/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "Stack2/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "IntegTest": { + "id": "IntegTest", + "path": "IntegTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "IntegTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "IntegTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "IntegTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.ts b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.ts new file mode 100644 index 0000000000000..0dad219ddf1d5 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-adot.ts @@ -0,0 +1,97 @@ +import * as cdk from '@aws-cdk/core'; +import { IntegTest } from '@aws-cdk/integ-tests'; +import { Construct } from 'constructs'; +import { StackProps, Stack } from '../../core/lib/stack'; +import { + AdotLambdaLayerPythonSdkVersion, + AdotLambdaLayerJavaSdkVersion, + AdotLambdaExecWrapper, + AdotLambdaLayerJavaScriptSdkVersion, + AdotLambdaLayerJavaAutoInstrumentationVersion, + AdotLambdaLayerGenericVersion, + Code, + Architecture, + Function, + Runtime, + AdotLayerVersion, +} from '../lib'; + +const app = new cdk.App(); + +interface StackUnderTestProps extends StackProps { + architecture?: Architecture; +} + +class StackUnderTest extends Stack { + constructor(scope: Construct, id: string, props: StackUnderTestProps) { + super(scope, id, props); + + new Function(this, 'MyFunc1', { + runtime: Runtime.NODEJS_14_X, + handler: 'index.handler', + code: Code.fromInline(`exports.handler = ${handler.toString()}`), + architecture: props.architecture, + adotInstrumentation: { + layerVersion: AdotLayerVersion.fromJavaScriptSdkLayerVersion(AdotLambdaLayerJavaScriptSdkVersion.LATEST), + execWrapper: AdotLambdaExecWrapper.REGULAR_HANDLER, + }, + }); + + new Function(this, 'MyFunc2', { + runtime: Runtime.PYTHON_3_9, + handler: 'index.handler', + code: Code.fromInline('def handler(event, context): pass'), + adotInstrumentation: { + layerVersion: AdotLayerVersion.fromPythonSdkLayerVersion(AdotLambdaLayerPythonSdkVersion.LATEST), + execWrapper: AdotLambdaExecWrapper.REGULAR_HANDLER, + }, + }); + + new Function(this, 'MyFunc3', { + runtime: Runtime.PYTHON_3_9, + handler: 'index.handler', + code: Code.fromInline('def handler(event, context): pass'), + adotInstrumentation: { + layerVersion: AdotLayerVersion.fromJavaSdkLayerVersion(AdotLambdaLayerJavaSdkVersion.LATEST), + execWrapper: AdotLambdaExecWrapper.REGULAR_HANDLER, + }, + }); + + new Function(this, 'MyFunc4', { + runtime: Runtime.PYTHON_3_9, + handler: 'index.handler', + code: Code.fromInline('def handler(event, context): pass'), + adotInstrumentation: { + layerVersion: AdotLayerVersion.fromJavaAutoInstrumentationLayerVersion(AdotLambdaLayerJavaAutoInstrumentationVersion.LATEST), + execWrapper: AdotLambdaExecWrapper.REGULAR_HANDLER, + }, + }); + + new Function(this, 'MyFunc5', { + runtime: Runtime.PYTHON_3_9, + handler: 'index.handler', + code: Code.fromInline('def handler(event, context): pass'), + adotInstrumentation: { + layerVersion: AdotLayerVersion.fromGenericLayerVersion(AdotLambdaLayerGenericVersion.LATEST), + execWrapper: AdotLambdaExecWrapper.REGULAR_HANDLER, + }, + }); + } +} + +/* eslint-disable no-console */ +function handler(event: any, _context: any, callback: any) { + console.log(JSON.stringify(event, undefined, 2)); + return callback(); +} + +new IntegTest(app, 'IntegTest', { + testCases: [ + new StackUnderTest(app, 'Stack1', { + architecture: Architecture.ARM_64, + }), + new StackUnderTest(app, 'Stack2', { + architecture: Architecture.X86_64, + }), + ], +}); diff --git a/packages/@aws-cdk/region-info/build-tools/fact-tables.ts b/packages/@aws-cdk/region-info/build-tools/fact-tables.ts index 8392932e8d5c2..1eb700f733e1e 100644 --- a/packages/@aws-cdk/region-info/build-tools/fact-tables.ts +++ b/packages/@aws-cdk/region-info/build-tools/fact-tables.ts @@ -505,3 +505,218 @@ export const FIREHOSE_CIDR_BLOCKS: { [region: string]: string } = { 'us-west-1': '13.57.135.192', 'us-west-2': '52.89.255.224', }; + +const ADOT_LAMBDA_LAYER_JAVA_SDK_ARNS: { [version: string]: { [arch: string]: { [region: string]: string } } } = { + '1.19.0': { + x86_64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-java-wrapper-amd64-ver-1-19-0:1', + }, + arm64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:2', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-java-wrapper-arm64-ver-1-19-0:1', + }, + }, +}; + +const ADOT_LAMBDA_LAYER_JAVA_AUTO_INSTRUMENTATION_ARNS: { + [version: string]: { [arch: string]: { [region: string]: string } }; +} = { + '1.19.2': { + x86_64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-java-agent-amd64-ver-1-19-2:1', + }, + arm64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-java-agent-arm64-ver-1-19-2:1', + }, + }, +}; + +const ADOT_LAMBDA_LAYER_JAVASCRIPT_SDK_ARNS: { [version: string]: { [arch: string]: { [region: string]: string } } } = { + '1.7.0': { + x86_64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-nodejs-amd64-ver-1-7-0:2', + }, + arm64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-nodejs-arm64-ver-1-7-0:2', + }, + }, +}; + +const ADOT_LAMBDA_LAYER_PYTHON_SDK_ARNS: { [version: string]: { [arch: string]: { [region: string]: string } } } = { + '1.13.0': { + x86_64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-python-amd64-ver-1-13-0:1', + }, + arm64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-python-arm64-ver-1-13-0:1', + }, + }, +}; + +const ADOT_LAMBDA_LAYER_GENERIC_ARNS: { [version: string]: { [arch: string]: { [region: string]: string } } } = { + '0.62.1': { + x86_64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-collector-amd64-ver-0-62-1:1', + }, + arm64: { + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'us-east-1': 'arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'us-east-2': 'arn:aws:lambda:us-east-2:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'us-west-1': 'arn:aws:lambda:us-west-1:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + 'us-west-2': 'arn:aws:lambda:us-west-2:901920570463:layer:aws-otel-collector-arm64-ver-0-62-1:1', + }, + }, +}; + +export const ADOT_LAMBDA_LAYER_ARNS: { [key: string]: any } = { + JAVA_SDK: ADOT_LAMBDA_LAYER_JAVA_SDK_ARNS, + JAVA_AUTO_INSTRUMENTATION: ADOT_LAMBDA_LAYER_JAVA_AUTO_INSTRUMENTATION_ARNS, + JAVASCRIPT_SDK: ADOT_LAMBDA_LAYER_JAVASCRIPT_SDK_ARNS, + PYTHON_SDK: ADOT_LAMBDA_LAYER_PYTHON_SDK_ARNS, + GENERIC: ADOT_LAMBDA_LAYER_GENERIC_ARNS, +}; diff --git a/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts b/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts index 042ff376796a3..3c272acf601c2 100644 --- a/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts +++ b/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts @@ -10,7 +10,7 @@ import { import { Default } from '../lib/default'; import { APPMESH_ECR_ACCOUNTS, AWS_CDK_METADATA, CLOUDWATCH_LAMBDA_INSIGHTS_ARNS, DLC_REPOSITORY_ACCOUNTS, - ELBV2_ACCOUNTS, FIREHOSE_CIDR_BLOCKS, PARTITION_MAP, ROUTE_53_BUCKET_WEBSITE_ZONE_IDS, EBS_ENV_ENDPOINT_HOSTED_ZONE_IDS, + ELBV2_ACCOUNTS, FIREHOSE_CIDR_BLOCKS, PARTITION_MAP, ROUTE_53_BUCKET_WEBSITE_ZONE_IDS, EBS_ENV_ENDPOINT_HOSTED_ZONE_IDS, ADOT_LAMBDA_LAYER_ARNS, } from './fact-tables'; async function main(): Promise { @@ -91,6 +91,18 @@ async function main(): Promise { } } + + for (const type in ADOT_LAMBDA_LAYER_ARNS) { + for (const version in ADOT_LAMBDA_LAYER_ARNS[type]) { + for (const arch in ADOT_LAMBDA_LAYER_ARNS[type][version]) { + registerFact( + region, + ['adotLambdaLayer', type, version, arch], + ADOT_LAMBDA_LAYER_ARNS[type][version][arch][region], + ); + } + } + } } lines.push(' }'); lines.push(''); diff --git a/packages/@aws-cdk/region-info/lib/fact.ts b/packages/@aws-cdk/region-info/lib/fact.ts index 4d918872ff4f0..efd9932e31908 100644 --- a/packages/@aws-cdk/region-info/lib/fact.ts +++ b/packages/@aws-cdk/region-info/lib/fact.ts @@ -191,4 +191,16 @@ export class FactName { public static servicePrincipal(service: string): string { return `service-principal:${service.replace(/\.amazonaws\.com(\.cn)?$/, '')}`; } + + /** + * The ARN of Amazon Distro for OpenTelemetry (ADOT) Lambda layer for a given lambda type, version and architecture. + * + * @param type the type of the ADOT lambda layer + * @param version the layer version. + * @param architecture the Lambda Function architecture (e.g. 'x86_64' or 'arm64') + */ + public static adotLambdaLayer(type: string, version: string, architecture: string): string { + const suffix = type + '_' + version.split('.').join('_') + '_' + architecture; + return `adot-lambda-layer:${suffix}`; + } } diff --git a/packages/@aws-cdk/region-info/lib/region-info.ts b/packages/@aws-cdk/region-info/lib/region-info.ts index 2b767c540679e..099218434c2c7 100644 --- a/packages/@aws-cdk/region-info/lib/region-info.ts +++ b/packages/@aws-cdk/region-info/lib/region-info.ts @@ -61,7 +61,7 @@ export class RegionInfo { return new RegionInfo(name); } - private constructor(public readonly name: string) { } + private constructor(public readonly name: string) {} /** * Whether the `AWS::CDK::Metadata` CloudFormation Resource is available in this region or not. @@ -106,8 +106,8 @@ export class RegionInfo { } /** - * The hosted zone ID used by Route 53 to alias a EBS environment endpoint in this region (e.g: Z2O1EMRO9K5GLX) - */ + * The hosted zone ID used by Route 53 to alias a EBS environment endpoint in this region (e.g: Z2O1EMRO9K5GLX) + */ public get ebsEnvEndpointHostedZoneId(): string | undefined { return Fact.find(this.name, FactName.EBS_ENV_ENDPOINT_HOSTED_ZONE_ID); } @@ -167,4 +167,15 @@ export class RegionInfo { public get firehoseCidrBlock(): string | undefined { return Fact.find(this.name, FactName.FIREHOSE_CIDR_BLOCK); } + + /** + * The ARN of the ADOT Lambda layer, for the given layer type, version and architecture. + * + * @param type the type of the ADOT lambda layer + * @param version the layer version. + * @param architecture the Lambda Function architecture (e.g. 'x86_64' or 'arm64') + */ + public adotLambdaLayerArn(type: string, version: string, architecture: string): string | undefined { + return Fact.find(this.name, FactName.adotLambdaLayer(type, version, architecture)); + } } From e49e57d3106f62c5d64c428cba73b4107d664cba Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Fri, 23 Dec 2022 01:47:37 -0800 Subject: [PATCH 16/22] feat(cfnspec): cloudformation spec v103.0.0 (#23452) --- packages/@aws-cdk/cfnspec/CHANGELOG.md | 133 ++++++++++++++++++ packages/@aws-cdk/cfnspec/cfn.version | 2 +- .../000_cfn/000_official/000_AWS_ACMPCA.json | 2 +- .../000_cfn/000_official/000_AWS_APS.json | 2 +- .../000_official/000_AWS_AccessAnalyzer.json | 2 +- .../000_official/000_AWS_AmazonMQ.json | 2 +- .../000_cfn/000_official/000_AWS_Amplify.json | 2 +- .../000_AWS_AmplifyUIBuilder.json | 2 +- .../000_official/000_AWS_ApiGateway.json | 6 +- .../000_official/000_AWS_ApiGatewayV2.json | 2 +- .../000_official/000_AWS_AppConfig.json | 2 +- .../000_cfn/000_official/000_AWS_AppFlow.json | 2 +- .../000_official/000_AWS_AppIntegrations.json | 2 +- .../000_cfn/000_official/000_AWS_AppMesh.json | 2 +- .../000_official/000_AWS_AppRunner.json | 2 +- .../000_official/000_AWS_AppStream.json | 2 +- .../000_cfn/000_official/000_AWS_AppSync.json | 2 +- .../000_AWS_ApplicationAutoScaling.json | 2 +- .../000_AWS_ApplicationInsights.json | 2 +- .../000_cfn/000_official/000_AWS_Athena.json | 2 +- .../000_official/000_AWS_AuditManager.json | 2 +- .../000_official/000_AWS_AutoScaling.json | 2 +- .../000_AWS_AutoScalingPlans.json | 2 +- .../000_cfn/000_official/000_AWS_Backup.json | 2 +- .../000_cfn/000_official/000_AWS_Batch.json | 2 +- .../000_AWS_BillingConductor.json | 2 +- .../000_cfn/000_official/000_AWS_Budgets.json | 2 +- .../000_cfn/000_official/000_AWS_CE.json | 2 +- .../000_cfn/000_official/000_AWS_CUR.json | 2 +- .../000_official/000_AWS_Cassandra.json | 2 +- .../000_AWS_CertificateManager.json | 2 +- .../000_cfn/000_official/000_AWS_Chatbot.json | 2 +- .../000_cfn/000_official/000_AWS_Cloud9.json | 2 +- .../000_official/000_AWS_CloudFormation.json | 2 +- .../000_official/000_AWS_CloudFront.json | 6 +- .../000_official/000_AWS_CloudTrail.json | 2 +- .../000_official/000_AWS_CloudWatch.json | 2 +- .../000_official/000_AWS_CodeArtifact.json | 2 +- .../000_official/000_AWS_CodeBuild.json | 2 +- .../000_official/000_AWS_CodeCommit.json | 2 +- .../000_official/000_AWS_CodeDeploy.json | 2 +- .../000_AWS_CodeGuruProfiler.json | 2 +- .../000_AWS_CodeGuruReviewer.json | 2 +- .../000_official/000_AWS_CodePipeline.json | 2 +- .../000_official/000_AWS_CodeStar.json | 2 +- .../000_AWS_CodeStarConnections.json | 2 +- .../000_AWS_CodeStarNotifications.json | 2 +- .../000_cfn/000_official/000_AWS_Cognito.json | 2 +- .../000_cfn/000_official/000_AWS_Config.json | 2 +- .../000_cfn/000_official/000_AWS_Connect.json | 2 +- .../000_AWS_ConnectCampaigns.json | 2 +- .../000_official/000_AWS_ControlTower.json | 2 +- .../000_AWS_CustomerProfiles.json | 2 +- .../000_cfn/000_official/000_AWS_DAX.json | 2 +- .../000_cfn/000_official/000_AWS_DLM.json | 2 +- .../000_cfn/000_official/000_AWS_DMS.json | 2 +- .../000_official/000_AWS_DataBrew.json | 2 +- .../000_official/000_AWS_DataPipeline.json | 2 +- .../000_official/000_AWS_DataSync.json | 4 +- .../000_official/000_AWS_Detective.json | 2 +- .../000_official/000_AWS_DevOpsGuru.json | 2 +- .../000_AWS_DirectoryService.json | 11 +- .../000_cfn/000_official/000_AWS_DocDB.json | 2 +- .../000_official/000_AWS_DocDBElastic.json | 2 +- .../000_official/000_AWS_DynamoDB.json | 2 +- .../000_cfn/000_official/000_AWS_EC2.json | 33 +++-- .../000_cfn/000_official/000_AWS_ECR.json | 2 +- .../000_cfn/000_official/000_AWS_ECS.json | 2 +- .../000_cfn/000_official/000_AWS_EFS.json | 2 +- .../000_cfn/000_official/000_AWS_EKS.json | 8 +- .../000_cfn/000_official/000_AWS_EMR.json | 2 +- .../000_official/000_AWS_EMRContainers.json | 2 +- .../000_official/000_AWS_EMRServerless.json | 2 +- .../000_official/000_AWS_ElastiCache.json | 2 +- .../000_AWS_ElasticBeanstalk.json | 2 +- .../000_AWS_ElasticLoadBalancing.json | 2 +- .../000_AWS_ElasticLoadBalancingV2.json | 2 +- .../000_official/000_AWS_Elasticsearch.json | 2 +- .../000_official/000_AWS_EventSchemas.json | 2 +- .../000_cfn/000_official/000_AWS_Events.json | 2 +- .../000_official/000_AWS_Evidently.json | 6 +- .../000_cfn/000_official/000_AWS_FIS.json | 2 +- .../000_cfn/000_official/000_AWS_FMS.json | 2 +- .../000_cfn/000_official/000_AWS_FSx.json | 29 +++- .../000_official/000_AWS_FinSpace.json | 2 +- .../000_official/000_AWS_Forecast.json | 2 +- .../000_official/000_AWS_FraudDetector.json | 2 +- .../000_official/000_AWS_GameLift.json | 19 ++- .../000_AWS_GlobalAccelerator.json | 2 +- .../000_cfn/000_official/000_AWS_Glue.json | 2 +- .../000_cfn/000_official/000_AWS_Grafana.json | 29 +++- .../000_official/000_AWS_Greengrass.json | 2 +- .../000_official/000_AWS_GreengrassV2.json | 2 +- .../000_official/000_AWS_GroundStation.json | 2 +- .../000_official/000_AWS_GuardDuty.json | 2 +- .../000_official/000_AWS_HealthLake.json | 2 +- .../000_cfn/000_official/000_AWS_IAM.json | 2 +- .../000_cfn/000_official/000_AWS_IVS.json | 2 +- .../000_official/000_AWS_IdentityStore.json | 2 +- .../000_official/000_AWS_ImageBuilder.json | 2 +- .../000_official/000_AWS_Inspector.json | 2 +- .../000_official/000_AWS_InspectorV2.json | 2 +- .../000_cfn/000_official/000_AWS_IoT.json | 11 +- .../000_official/000_AWS_IoT1Click.json | 2 +- .../000_official/000_AWS_IoTAnalytics.json | 2 +- .../000_AWS_IoTCoreDeviceAdvisor.json | 2 +- .../000_official/000_AWS_IoTEvents.json | 2 +- .../000_official/000_AWS_IoTFleetHub.json | 2 +- .../000_official/000_AWS_IoTFleetWise.json | 2 +- .../000_official/000_AWS_IoTSiteWise.json | 2 +- .../000_official/000_AWS_IoTThingsGraph.json | 2 +- .../000_official/000_AWS_IoTTwinMaker.json | 2 +- .../000_official/000_AWS_IoTWireless.json | 2 +- .../000_cfn/000_official/000_AWS_KMS.json | 2 +- .../000_official/000_AWS_KafkaConnect.json | 2 +- .../000_cfn/000_official/000_AWS_Kendra.json | 2 +- .../000_cfn/000_official/000_AWS_Kinesis.json | 2 +- .../000_AWS_KinesisAnalytics.json | 2 +- .../000_AWS_KinesisAnalyticsV2.json | 2 +- .../000_official/000_AWS_KinesisFirehose.json | 2 +- .../000_official/000_AWS_KinesisVideo.json | 2 +- .../000_official/000_AWS_LakeFormation.json | 2 +- .../000_cfn/000_official/000_AWS_Lambda.json | 2 +- .../000_cfn/000_official/000_AWS_Lex.json | 2 +- .../000_official/000_AWS_LicenseManager.json | 2 +- .../000_official/000_AWS_Lightsail.json | 2 +- .../000_official/000_AWS_Location.json | 2 +- .../000_cfn/000_official/000_AWS_Logs.json | 19 ++- .../000_AWS_LookoutEquipment.json | 2 +- .../000_official/000_AWS_LookoutMetrics.json | 2 +- .../000_official/000_AWS_LookoutVision.json | 2 +- .../000_cfn/000_official/000_AWS_M2.json | 2 +- .../000_cfn/000_official/000_AWS_MSK.json | 2 +- .../000_cfn/000_official/000_AWS_MWAA.json | 2 +- .../000_cfn/000_official/000_AWS_Macie.json | 2 +- .../000_AWS_ManagedBlockchain.json | 2 +- .../000_official/000_AWS_MediaConnect.json | 2 +- .../000_official/000_AWS_MediaConvert.json | 2 +- .../000_official/000_AWS_MediaLive.json | 2 +- .../000_official/000_AWS_MediaPackage.json | 2 +- .../000_official/000_AWS_MediaStore.json | 2 +- .../000_official/000_AWS_MediaTailor.json | 2 +- .../000_official/000_AWS_MemoryDB.json | 2 +- .../000_cfn/000_official/000_AWS_Neptune.json | 2 +- .../000_official/000_AWS_NetworkFirewall.json | 37 ++++- .../000_official/000_AWS_NetworkManager.json | 8 +- .../000_official/000_AWS_NimbleStudio.json | 2 +- .../000_cfn/000_official/000_AWS_Oam.json | 2 +- .../000_AWS_OpenSearchServerless.json | 2 +- .../000_AWS_OpenSearchService.json | 2 +- .../000_official/000_AWS_OpsWorks.json | 2 +- .../000_official/000_AWS_OpsWorksCM.json | 2 +- .../000_official/000_AWS_Organizations.json | 2 +- .../000_official/000_AWS_Panorama.json | 2 +- .../000_official/000_AWS_Personalize.json | 2 +- .../000_official/000_AWS_Pinpoint.json | 2 +- .../000_official/000_AWS_PinpointEmail.json | 2 +- .../000_cfn/000_official/000_AWS_Pipes.json | 2 +- .../000_cfn/000_official/000_AWS_QLDB.json | 2 +- .../000_official/000_AWS_QuickSight.json | 31 +++- .../000_cfn/000_official/000_AWS_RAM.json | 2 +- .../000_cfn/000_official/000_AWS_RDS.json | 11 +- .../000_cfn/000_official/000_AWS_RUM.json | 2 +- .../000_official/000_AWS_Redshift.json | 2 +- .../000_AWS_RedshiftServerless.json | 31 ++-- .../000_official/000_AWS_RefactorSpaces.json | 2 +- .../000_official/000_AWS_Rekognition.json | 2 +- .../000_official/000_AWS_ResilienceHub.json | 2 +- .../000_AWS_ResourceExplorer2.json | 2 +- .../000_official/000_AWS_ResourceGroups.json | 2 +- .../000_official/000_AWS_RoboMaker.json | 2 +- .../000_official/000_AWS_RolesAnywhere.json | 2 +- .../000_cfn/000_official/000_AWS_Route53.json | 2 +- .../000_AWS_Route53RecoveryControl.json | 14 +- .../000_AWS_Route53RecoveryReadiness.json | 2 +- .../000_official/000_AWS_Route53Resolver.json | 2 +- .../000_cfn/000_official/000_AWS_S3.json | 2 +- .../000_official/000_AWS_S3ObjectLambda.json | 2 +- .../000_official/000_AWS_S3Outposts.json | 2 +- .../000_cfn/000_official/000_AWS_SDB.json | 2 +- .../000_cfn/000_official/000_AWS_SES.json | 2 +- .../000_cfn/000_official/000_AWS_SNS.json | 2 +- .../000_cfn/000_official/000_AWS_SQS.json | 2 +- .../000_cfn/000_official/000_AWS_SSM.json | 2 +- .../000_official/000_AWS_SSMContacts.json | 2 +- .../000_official/000_AWS_SSMIncidents.json | 2 +- .../000_cfn/000_official/000_AWS_SSO.json | 2 +- .../000_official/000_AWS_SageMaker.json | 2 +- .../000_official/000_AWS_Scheduler.json | 2 +- .../000_official/000_AWS_SecretsManager.json | 2 +- .../000_official/000_AWS_SecurityHub.json | 2 +- .../000_official/000_AWS_ServiceCatalog.json | 2 +- .../000_AWS_ServiceCatalogAppRegistry.json | 2 +- .../000_AWS_ServiceDiscovery.json | 2 +- .../000_cfn/000_official/000_AWS_Signer.json | 2 +- .../000_official/000_AWS_StepFunctions.json | 2 +- .../000_official/000_AWS_SupportApp.json | 2 +- .../000_official/000_AWS_Synthetics.json | 2 +- .../000_official/000_AWS_Timestream.json | 2 +- .../000_official/000_AWS_Transfer.json | 2 +- .../000_cfn/000_official/000_AWS_VoiceID.json | 2 +- .../000_cfn/000_official/000_AWS_WAF.json | 2 +- .../000_official/000_AWS_WAFRegional.json | 2 +- .../000_cfn/000_official/000_AWS_WAFv2.json | 2 +- .../000_cfn/000_official/000_AWS_Wisdom.json | 2 +- .../000_official/000_AWS_WorkSpaces.json | 2 +- .../000_cfn/000_official/000_AWS_XRay.json | 2 +- .../000_cfn/000_official/000_Alexa_ASK.json | 2 +- .../000_cfn/000_official/000_Tag.json | 2 +- .../000_cfn/000_official/001_Version.json | 2 +- 210 files changed, 557 insertions(+), 271 deletions(-) diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index ad827b101d380..428bf0d218060 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,136 @@ +# CloudFormation Resource Specification v103.0.0 + +## New Resource Types + + +## Attribute Changes + +* AWS::ApiGateway::RestApi RestApiId (__deleted__) +* AWS::DirectoryService::SimpleAD DirectoryId (__added__) +* AWS::EC2::Volume Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html +* AWS::EC2::Volume VolumeId (__added__) +* AWS::FSx::FileSystem ResourceARN (__added__) +* AWS::GameLift::Build BuildId (__added__) +* AWS::IoT::Thing Arn (__added__) +* AWS::IoT::Thing Id (__added__) +* AWS::Logs::SubscriptionFilter FilterName (__deleted__) +* AWS::RDS::DBInstance DBSystemId (__added__) +* AWS::RedshiftServerless::Namespace Namespace (__deleted__) +* AWS::RedshiftServerless::Workgroup Workgroup (__deleted__) +* AWS::RedshiftServerless::Workgroup Workgroup.ConfigParameters (__deleted__) +* AWS::RedshiftServerless::Workgroup Workgroup.Endpoint (__deleted__) +* AWS::RedshiftServerless::Workgroup Workgroup.Endpoint.VpcEndpoints (__deleted__) +* AWS::Route53RecoveryControl::Cluster ClusterEndpoints (__deleted__) + +## Property Changes + +* AWS::ApiGateway::RestApi Parameters.DuplicatesAllowed (__added__) +* AWS::CloudFront::Function FunctionCode.Required (__changed__) + * Old: false + * New: true +* AWS::CloudFront::Function FunctionConfig.Required (__changed__) + * Old: false + * New: true +* AWS::DataSync::LocationEFS EfsFilesystemArn.Required (__changed__) + * Old: true + * New: false +* AWS::DirectoryService::SimpleAD Password.Required (__changed__) + * Old: true + * New: false +* AWS::EC2::Volume AutoEnableIO.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-autoenableio + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-autoenableio +* AWS::EC2::Volume AvailabilityZone.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-availabilityzone + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-availabilityzone +* AWS::EC2::Volume Encrypted.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-encrypted + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-encrypted +* AWS::EC2::Volume Iops.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-iops + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-iops +* AWS::EC2::Volume KmsKeyId.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-kmskeyid + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-kmskeyid +* AWS::EC2::Volume MultiAttachEnabled.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-multiattachenabled + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-multiattachenabled +* AWS::EC2::Volume OutpostArn.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-outpostarn + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-outpostarn +* AWS::EC2::Volume Size.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-size + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-size +* AWS::EC2::Volume SnapshotId.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-snapshotid + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-snapshotid +* AWS::EC2::Volume Tags.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-tags + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-tags +* AWS::EC2::Volume Throughput.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-throughput + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-throughput +* AWS::EC2::Volume VolumeType.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-volumetype + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-volumetype +* AWS::EKS::Nodegroup Labels.PrimitiveType (__deleted__) +* AWS::EKS::Nodegroup Labels.PrimitiveItemType (__added__) +* AWS::EKS::Nodegroup Labels.Type (__added__) +* AWS::EKS::Nodegroup Tags.PrimitiveType (__deleted__) +* AWS::EKS::Nodegroup Tags.PrimitiveItemType (__added__) +* AWS::EKS::Nodegroup Tags.Type (__added__) +* AWS::GameLift::Build StorageLocation.Type (__changed__) + * Old: S3Location + * New: StorageLocation +* AWS::Grafana::Workspace VpcConfiguration (__added__) +* AWS::Logs::SubscriptionFilter Distribution (__added__) +* AWS::Logs::SubscriptionFilter FilterName (__added__) +* AWS::RedshiftServerless::Namespace Namespace (__added__) +* AWS::RedshiftServerless::Workgroup Workgroup (__added__) +* AWS::Route53RecoveryControl::Cluster ClusterEndpoints (__added__) + +## Property Type Changes + +* AWS::GameLift::Build.S3Location (__removed__) +* AWS::GameLift::Build.StorageLocation (__added__) +* AWS::Grafana::Workspace.VpcConfiguration (__added__) +* AWS::NetworkFirewall::RuleGroup.IPSetReference (__added__) +* AWS::NetworkFirewall::RuleGroup.ReferenceSets (__added__) +* AWS::QuickSight::DataSource.DatabricksParameters (__added__) +* AWS::DirectoryService::SimpleAD.VpcSettings SubnetIds.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::DirectoryService::SimpleAD.VpcSettings VpcId.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::Evidently::Experiment.MetricGoalObject EventPattern.Required (__changed__) + * Old: true + * New: false +* AWS::Evidently::Launch.MetricDefinitionObject EventPattern.Required (__changed__) + * Old: true + * New: false +* AWS::FSx::FileSystem.OntapConfiguration RouteTableIds.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::FSx::Volume.OntapConfiguration CopyTagsToBackups (__added__) +* AWS::FSx::Volume.OntapConfiguration OntapVolumeType (__added__) +* AWS::FSx::Volume.OntapConfiguration SnapshotPolicy (__added__) +* AWS::FSx::Volume.OntapConfiguration JunctionPath.Required (__changed__) + * Old: true + * New: false +* AWS::FSx::Volume.OntapConfiguration StorageEfficiencyEnabled.Required (__changed__) + * Old: true + * New: false +* AWS::IoT::Thing.AttributePayload Attributes.DuplicatesAllowed (__deleted__) +* AWS::NetworkFirewall::FirewallPolicy.StatefulEngineOptions StreamExceptionPolicy (__added__) +* AWS::NetworkFirewall::RuleGroup.RuleGroup ReferenceSets (__added__) +* AWS::NetworkManager::VpcAttachment.VpcOptions ApplianceModeSupport (__added__) +* AWS::QuickSight::DataSource.DataSourceParameters DatabricksParameters (__added__) +* AWS::RDS::DBProxy.AuthFormat ClientPasswordAuthType (__added__) + + # CloudFormation Resource Specification v102.0.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index d4641b132dc0a..9dd4f066910f1 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -102.0.0 +103.0.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ACMPCA.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ACMPCA.json index 495198b81cce8..8aa43d81a67ea 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ACMPCA.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ACMPCA.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ACMPCA::Certificate.ApiPassthrough": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-acmpca-certificate-apipassthrough.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_APS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_APS.json index bd88dc39b958b..03a83ccffc2c1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_APS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_APS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::APS::Workspace.LoggingConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-aps-workspace-loggingconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AccessAnalyzer.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AccessAnalyzer.json index d6b46239f1555..a87eee0496f92 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AccessAnalyzer.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AccessAnalyzer.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AccessAnalyzer::Analyzer.ArchiveRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-accessanalyzer-analyzer-archiverule.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmazonMQ.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmazonMQ.json index cb11b3177ff69..28739d8ccbab6 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmazonMQ.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmazonMQ.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AmazonMQ::Broker.ConfigurationId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-amazonmq-broker-configurationid.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Amplify.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Amplify.json index 73625ed7e741c..2c29a2594777e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Amplify.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Amplify.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Amplify::App.AutoBranchCreationConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-amplify-app-autobranchcreationconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmplifyUIBuilder.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmplifyUIBuilder.json index d9696fe11b06e..8a6171ba631c6 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmplifyUIBuilder.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AmplifyUIBuilder.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AmplifyUIBuilder::Component.ActionParameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-amplifyuibuilder-component-actionparameters.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGateway.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGateway.json index fa966ec28645c..adc6240388026 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGateway.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGateway.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ApiGateway::ApiKey.StageKey": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-apikey-stagekey.html", @@ -1329,9 +1329,6 @@ }, "AWS::ApiGateway::RestApi": { "Attributes": { - "RestApiId": { - "PrimitiveType": "String" - }, "RootResourceId": { "PrimitiveType": "String" } @@ -1414,6 +1411,7 @@ }, "Parameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-parameters", + "DuplicatesAllowed": false, "PrimitiveItemType": "String", "Required": false, "Type": "Map", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGatewayV2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGatewayV2.json index e15eb6be06e30..12f43e0316869 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGatewayV2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApiGatewayV2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ApiGatewayV2::Api.BodyS3Location": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-api-bodys3location.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppConfig.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppConfig.json index 1eb502b7fd350..c94c58f59eed0 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppConfig.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppConfig.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AppConfig::Application.Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appconfig-application-tags.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppFlow.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppFlow.json index a1a66463b2082..751681ead7b24 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppFlow.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppFlow.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AppFlow::Connector.ConnectorProvisioningConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connector-connectorprovisioningconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppIntegrations.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppIntegrations.json index 027ecd1b3c764..e53efeb941a2b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppIntegrations.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppIntegrations.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AppIntegrations::DataIntegration.ScheduleConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appintegrations-dataintegration-scheduleconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppMesh.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppMesh.json index 059466450e6b9..b341dd3fbae7f 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppMesh.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppMesh.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AppMesh::GatewayRoute.GatewayRouteHostnameMatch": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutehostnamematch.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppRunner.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppRunner.json index cf506f6249348..99cc20143150b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppRunner.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppRunner.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AppRunner::ObservabilityConfiguration.TraceConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apprunner-observabilityconfiguration-traceconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppStream.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppStream.json index 72d49f0f6da5c..6e0ed270155b6 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppStream.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppStream.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AppStream::AppBlock.S3Location": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appstream-appblock-s3location.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppSync.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppSync.json index 4a331128e1b17..3004adc67e7e3 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppSync.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AppSync.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AppSync::DataSource.AuthorizationConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appsync-datasource-authorizationconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationAutoScaling.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationAutoScaling.json index 8af17fdf1fbbb..b7d7014945789 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationAutoScaling.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationAutoScaling.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ApplicationAutoScaling::ScalableTarget.ScalableTargetAction": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-applicationautoscaling-scalabletarget-scalabletargetaction.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationInsights.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationInsights.json index c824ebe11f80d..be9a65e00b777 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationInsights.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ApplicationInsights.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ApplicationInsights::Application.Alarm": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-applicationinsights-application-alarm.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Athena.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Athena.json index 8e2067e0d6b90..2aa1cdce455a8 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Athena.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Athena.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Athena::WorkGroup.EncryptionConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-athena-workgroup-encryptionconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AuditManager.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AuditManager.json index d7d52dff90a83..59beebcbcd166 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AuditManager.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AuditManager.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AuditManager::Assessment.AWSAccount": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-auditmanager-assessment-awsaccount.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScaling.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScaling.json index 43abb93cb57bc..c2715e59a84f1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScaling.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScaling.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AutoScaling::AutoScalingGroup.AcceleratorCountRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratorcountrequest.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScalingPlans.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScalingPlans.json index c0f6190243428..fde218a526415 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScalingPlans.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_AutoScalingPlans.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::AutoScalingPlans::ScalingPlan.ApplicationSource": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscalingplans-scalingplan-applicationsource.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Backup.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Backup.json index f06b394389473..8b394406e8abe 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Backup.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Backup.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Backup::BackupPlan.AdvancedBackupSettingResourceType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupplan-advancedbackupsettingresourcetype.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Batch.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Batch.json index 89a5527fa1bf6..bb97eb6806daa 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Batch.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Batch.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Batch::ComputeEnvironment.ComputeResources": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-batch-computeenvironment-computeresources.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_BillingConductor.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_BillingConductor.json index d394247ae25cd..0bb1ab2c53791 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_BillingConductor.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_BillingConductor.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::BillingConductor::BillingGroup.AccountGrouping": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-billingconductor-billinggroup-accountgrouping.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Budgets.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Budgets.json index 1ddc94074be12..2eb5108f5f1c7 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Budgets.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Budgets.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Budgets::Budget.AutoAdjustData": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-budgets-budget-autoadjustdata.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CE.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CE.json index cd2d07433642c..d888a8ed0b9e4 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CE.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CE.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CE::AnomalyMonitor.ResourceTag": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ce-anomalymonitor-resourcetag.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CUR.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CUR.json index c120e6687e736..6b16b71246739 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CUR.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CUR.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::CUR::ReportDefinition": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cassandra.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cassandra.json index 760e154313376..9e8dda6f4f67d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cassandra.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cassandra.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Cassandra::Table.BillingMode": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cassandra-table-billingmode.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CertificateManager.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CertificateManager.json index ea86972f64310..79054d722f8be 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CertificateManager.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CertificateManager.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CertificateManager::Account.ExpiryEventsConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-certificatemanager-account-expiryeventsconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Chatbot.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Chatbot.json index 3a2e09d0c4d24..b2595215db678 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Chatbot.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Chatbot.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::Chatbot::SlackChannelConfiguration": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cloud9.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cloud9.json index 2fc526c95d4bc..d078e60612ca5 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cloud9.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cloud9.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Cloud9::EnvironmentEC2.Repository": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloud9-environmentec2-repository.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFormation.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFormation.json index ed6f5c6e655e9..f4c4adc7c9940 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFormation.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFormation.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CloudFormation::HookVersion.LoggingConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudformation-hookversion-loggingconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFront.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFront.json index d168bf50c81ee..7c765f014eeda 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFront.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudFront.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CloudFront::CachePolicy.CachePolicyConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html", @@ -2007,12 +2007,12 @@ "FunctionCode": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functioncode", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "FunctionConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functionconfig", - "Required": false, + "Required": true, "Type": "FunctionConfig", "UpdateType": "Mutable" }, diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudTrail.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudTrail.json index 1d20fb37a7594..d90847e11590b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudTrail.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudTrail.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CloudTrail::EventDataStore.AdvancedEventSelector": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudtrail-eventdatastore-advancedeventselector.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudWatch.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudWatch.json index 7b2a32dc35436..d70d364a42352 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudWatch.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CloudWatch.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CloudWatch::Alarm.Dimension": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cw-dimension.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeArtifact.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeArtifact.json index ce029a74c3e6f..1e1bd521878e4 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeArtifact.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeArtifact.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::CodeArtifact::Domain": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeBuild.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeBuild.json index a03c4bfeab626..1fa1c4dc98ac9 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeBuild.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeBuild.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CodeBuild::Project.Artifacts": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-artifacts.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeCommit.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeCommit.json index 87a55fdc019f8..6d47212d5c487 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeCommit.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeCommit.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CodeCommit::Repository.Code": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codecommit-repository-code.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeDeploy.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeDeploy.json index bc7a4e35262b0..0d9623784b5ef 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeDeploy.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeDeploy.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CodeDeploy::DeploymentConfig.MinimumHealthyHosts": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codedeploy-deploymentconfig-minimumhealthyhosts.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruProfiler.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruProfiler.json index a3e3da3382ae2..ff3c0ee93927e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruProfiler.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruProfiler.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CodeGuruProfiler::ProfilingGroup.AgentPermissions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codeguruprofiler-profilinggroup-agentpermissions.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruReviewer.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruReviewer.json index 122a16b4d5acd..89520e2134c53 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruReviewer.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeGuruReviewer.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::CodeGuruReviewer::RepositoryAssociation": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodePipeline.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodePipeline.json index 488bcb0ce11df..85ac6cfc40e09 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodePipeline.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodePipeline.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CodePipeline::CustomActionType.ArtifactDetails": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codepipeline-customactiontype-artifactdetails.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStar.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStar.json index 37727ec635096..777435b7d6f62 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStar.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStar.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CodeStar::GitHubRepository.Code": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codestar-githubrepository-code.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarConnections.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarConnections.json index b1904e5e37e86..9ad68b9965457 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarConnections.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarConnections.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::CodeStarConnections::Connection": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarNotifications.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarNotifications.json index e36c0219ef4be..e173e62cbe844 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarNotifications.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CodeStarNotifications.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CodeStarNotifications::NotificationRule.Target": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codestarnotifications-notificationrule-target.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cognito.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cognito.json index c3cb24ccb6551..429b1a76a7d1b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cognito.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Cognito.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Cognito::IdentityPool.CognitoIdentityProvider": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cognito-identitypool-cognitoidentityprovider.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Config.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Config.json index 304082e86e56e..aaa204c502748 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Config.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Config.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Config::ConfigRule.CustomPolicyDetails": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-config-configrule-custompolicydetails.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Connect.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Connect.json index cd6c40693b212..f5c5eec94e9a4 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Connect.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Connect.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Connect::HoursOfOperation.HoursOfOperationConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ConnectCampaigns.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ConnectCampaigns.json index 7e6edd775683d..835f3f41542fe 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ConnectCampaigns.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ConnectCampaigns.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ConnectCampaigns::Campaign.DialerConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connectcampaigns-campaign-dialerconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ControlTower.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ControlTower.json index 793aaa010a562..e4cca6809effa 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ControlTower.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ControlTower.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::ControlTower::EnabledControl": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CustomerProfiles.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CustomerProfiles.json index 9d6570fbdf433..081ee9446bba1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CustomerProfiles.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_CustomerProfiles.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::CustomerProfiles::Integration.ConnectorOperator": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-customerprofiles-integration-connectoroperator.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DAX.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DAX.json index 206c1f5cfbd01..74da6498e2f30 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DAX.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DAX.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DAX::Cluster.SSESpecification": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dax-cluster-ssespecification.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DLM.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DLM.json index 4f759606d7022..5c48070d4ce33 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DLM.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DLM.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DLM::LifecyclePolicy.Action": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-action.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DMS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DMS.json index ceab8acf0d34e..6878b4b6d8b38 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DMS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DMS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DMS::Endpoint.DocDbSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-docdbsettings.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataBrew.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataBrew.json index 26561725875fe..70df3dd9f0bff 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataBrew.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataBrew.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DataBrew::Dataset.CsvOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-dataset-csvoptions.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataPipeline.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataPipeline.json index 85d8baf104b05..2692fbc2b59c9 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataPipeline.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataPipeline.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DataPipeline::Pipeline.Field": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datapipeline-pipeline-field.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataSync.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataSync.json index b82d37cd21920..ce74baaf863c9 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataSync.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DataSync.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DataSync::LocationEFS.Ec2Config": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationefs-ec2config.html", @@ -418,7 +418,7 @@ "EfsFilesystemArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationefs.html#cfn-datasync-locationefs-efsfilesystemarn", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Immutable" }, "FileSystemAccessRoleArn": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Detective.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Detective.json index 8838b4d066f5d..febfa9f77b824 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Detective.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Detective.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::Detective::Graph": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DevOpsGuru.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DevOpsGuru.json index d2258eafed286..c5cb4ef15592f 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DevOpsGuru.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DevOpsGuru.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DevOpsGuru::NotificationChannel.NotificationChannelConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-devopsguru-notificationchannel-notificationchannelconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DirectoryService.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DirectoryService.json index 7bc0591d605ee..e39f6437074d8 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DirectoryService.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DirectoryService.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DirectoryService::MicrosoftAD.VpcSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-directoryservice-microsoftad-vpcsettings.html", @@ -29,13 +29,13 @@ "PrimitiveItemType": "String", "Required": true, "Type": "List", - "UpdateType": "Mutable" + "UpdateType": "Immutable" }, "VpcId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-directoryservice-simplead-vpcsettings.html#cfn-directoryservice-simplead-vpcsettings-vpcid", "PrimitiveType": "String", "Required": true, - "UpdateType": "Mutable" + "UpdateType": "Immutable" } } } @@ -102,6 +102,9 @@ "Alias": { "PrimitiveType": "String" }, + "DirectoryId": { + "PrimitiveType": "String" + }, "DnsIpAddresses": { "PrimitiveItemType": "String", "Type": "List" @@ -136,7 +139,7 @@ "Password": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-directoryservice-simplead.html#cfn-directoryservice-simplead-password", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Immutable" }, "ShortName": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDB.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDB.json index 7c885cab5f378..da464ae0ff981 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDB.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDB.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::DocDB::DBCluster": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDBElastic.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDBElastic.json index 2258455b2d62a..f63a29a4f8770 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDBElastic.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DocDBElastic.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::DocDBElastic::Cluster": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DynamoDB.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DynamoDB.json index 3bef6cecb389b..a3ed76361ee71 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DynamoDB.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_DynamoDB.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::DynamoDB::GlobalTable.AttributeDefinition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-globaltable-attributedefinition.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EC2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EC2.json index 65921cacd8f1d..f5cf9c63c2377 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EC2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EC2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::EC2::CapacityReservation.TagSpecification": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservation-tagspecification.html", @@ -8567,64 +8567,69 @@ } }, "AWS::EC2::Volume": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html", + "Attributes": { + "VolumeId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html", "Properties": { "AutoEnableIO": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-autoenableio", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-autoenableio", "PrimitiveType": "Boolean", "Required": false, "UpdateType": "Mutable" }, "AvailabilityZone": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-availabilityzone", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-availabilityzone", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" }, "Encrypted": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-encrypted", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-encrypted", "PrimitiveType": "Boolean", "Required": false, "UpdateType": "Mutable" }, "Iops": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-iops", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-iops", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "KmsKeyId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-kmskeyid", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-kmskeyid", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "MultiAttachEnabled": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-multiattachenabled", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-multiattachenabled", "PrimitiveType": "Boolean", "Required": false, "UpdateType": "Mutable" }, "OutpostArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-outpostarn", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-outpostarn", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "Size": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-size", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-size", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "SnapshotId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-snapshotid", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-snapshotid", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-tags", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-tags", "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, @@ -8632,13 +8637,13 @@ "UpdateType": "Mutable" }, "Throughput": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-throughput", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-throughput", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "VolumeType": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-volumetype", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-volumetype", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECR.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECR.json index 65cc1f50de994..2b5df8a61f819 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECR.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECR.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ECR::PublicRepository.RepositoryCatalogData": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecr-publicrepository-repositorycatalogdata.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECS.json index 9cde5994e03cf..296b508c39256 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ECS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ECS::CapacityProvider.AutoScalingGroupProvider": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-autoscalinggroupprovider.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EFS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EFS.json index 4a14e2b2116bc..5857388f4b0fb 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EFS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EFS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::EFS::AccessPoint.AccessPointTag": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-efs-accesspoint-accesspointtag.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EKS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EKS.json index ea0c1c1cb1033..081eb611d2e3c 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EKS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EKS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::EKS::Cluster.ClusterLogging": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-clusterlogging.html", @@ -669,8 +669,9 @@ }, "Labels": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-labels", - "PrimitiveType": "Json", + "PrimitiveItemType": "String", "Required": false, + "Type": "Map", "UpdateType": "Mutable" }, "LaunchTemplate": { @@ -719,8 +720,9 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-tags", - "PrimitiveType": "Json", + "PrimitiveItemType": "String", "Required": false, + "Type": "Map", "UpdateType": "Mutable" }, "Taints": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMR.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMR.json index a1ac97e1b2c6c..026524bc2c549 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMR.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMR.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::EMR::Cluster.Application": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticmapreduce-cluster-application.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRContainers.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRContainers.json index 5a8353d32ba38..15d1efcd5d695 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRContainers.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRContainers.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::EMRContainers::VirtualCluster.ContainerInfo": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-emrcontainers-virtualcluster-containerinfo.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRServerless.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRServerless.json index c299ec03fda96..1d9789fccb913 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRServerless.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EMRServerless.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::EMRServerless::Application.AutoStartConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-emrserverless-application-autostartconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElastiCache.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElastiCache.json index 2c67755069dd4..394632496ef61 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElastiCache.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElastiCache.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ElastiCache::CacheCluster.CloudWatchLogsDestinationDetails": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticache-cachecluster-cloudwatchlogsdestinationdetails.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticBeanstalk.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticBeanstalk.json index 33b5947060b51..5d34ac59be6c5 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticBeanstalk.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticBeanstalk.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ElasticBeanstalk::Application.ApplicationResourceLifecycleConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticbeanstalk-application-applicationresourcelifecycleconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancing.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancing.json index 71f905d7184c5..8c8d08f06e875 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancing.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancing.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ElasticLoadBalancing::LoadBalancer.AccessLoggingPolicy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb-accessloggingpolicy.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancingV2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancingV2.json index 676fb68d33bce..ccba1f228d5d1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancingV2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ElasticLoadBalancingV2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ElasticLoadBalancingV2::Listener.Action": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticloadbalancingv2-listener-action.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Elasticsearch.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Elasticsearch.json index f8fd092855a18..cef74af2e2418 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Elasticsearch.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Elasticsearch.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Elasticsearch::Domain.AdvancedSecurityOptionsInput": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticsearch-domain-advancedsecurityoptionsinput.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EventSchemas.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EventSchemas.json index 8a1c50962794a..2597ef7747758 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EventSchemas.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_EventSchemas.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::EventSchemas::Discoverer.TagsEntry": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eventschemas-discoverer-tagsentry.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Events.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Events.json index 1f00c2794425c..7b3c7cb1da3e1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Events.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Events.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Events::Connection.ApiKeyAuthParameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-events-connection-apikeyauthparameters.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Evidently.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Evidently.json index 125bbedf94ba9..5322e4cb1c972 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Evidently.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Evidently.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Evidently::Experiment.MetricGoalObject": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-evidently-experiment-metricgoalobject.html", @@ -19,7 +19,7 @@ "EventPattern": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-evidently-experiment-metricgoalobject.html#cfn-evidently-experiment-metricgoalobject-eventpattern", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Mutable" }, "MetricName": { @@ -269,7 +269,7 @@ "EventPattern": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-evidently-launch-metricdefinitionobject.html#cfn-evidently-launch-metricdefinitionobject-eventpattern", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Mutable" }, "MetricName": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FIS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FIS.json index d9f8252c29650..be2fbc3888bb3 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FIS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FIS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::FIS::ExperimentTemplate.CloudWatchLogsConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-cloudwatchlogsconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FMS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FMS.json index 2016dde806ea3..b497d8c686d3f 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FMS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FMS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::FMS::Policy.IEMap": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fms-policy-iemap.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FSx.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FSx.json index 293ae8e34cbe1..dba25cfa81016 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FSx.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FSx.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::FSx::DataRepositoryAssociation.AutoExportPolicy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-datarepositoryassociation-autoexportpolicy.html", @@ -241,7 +241,7 @@ "PrimitiveItemType": "String", "Required": false, "Type": "List", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "ThroughputCapacity": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-ontapconfiguration.html#cfn-fsx-filesystem-ontapconfiguration-throughputcapacity", @@ -595,12 +595,24 @@ "AWS::FSx::Volume.OntapConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-volume-ontapconfiguration.html", "Properties": { + "CopyTagsToBackups": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-volume-ontapconfiguration.html#cfn-fsx-volume-ontapconfiguration-copytagstobackups", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "JunctionPath": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-volume-ontapconfiguration.html#cfn-fsx-volume-ontapconfiguration-junctionpath", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Mutable" }, + "OntapVolumeType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-volume-ontapconfiguration.html#cfn-fsx-volume-ontapconfiguration-ontapvolumetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "SecurityStyle": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-volume-ontapconfiguration.html#cfn-fsx-volume-ontapconfiguration-securitystyle", "PrimitiveType": "String", @@ -613,10 +625,16 @@ "Required": true, "UpdateType": "Mutable" }, + "SnapshotPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-volume-ontapconfiguration.html#cfn-fsx-volume-ontapconfiguration-snapshotpolicy", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "StorageEfficiencyEnabled": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-volume-ontapconfiguration.html#cfn-fsx-volume-ontapconfiguration-storageefficiencyenabled", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Mutable" }, "StorageVirtualMachineId": { @@ -831,6 +849,9 @@ "LustreMountName": { "PrimitiveType": "String" }, + "ResourceARN": { + "PrimitiveType": "String" + }, "RootVolumeId": { "PrimitiveType": "String" } diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FinSpace.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FinSpace.json index 891376dbe3458..1fc7bf4741d17 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FinSpace.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FinSpace.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::FinSpace::Environment.FederationParameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Forecast.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Forecast.json index 9e1c83ad51958..b70365fef6dfc 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Forecast.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Forecast.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Forecast::Dataset.AttributesItems": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-forecast-dataset-attributesitems.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FraudDetector.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FraudDetector.json index 23d0927b1773d..cc373cc1861ab 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FraudDetector.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_FraudDetector.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::FraudDetector::Detector.EntityType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GameLift.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GameLift.json index 6d486ca65991f..4fcb718e32fc2 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GameLift.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GameLift.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::GameLift::Alias.RoutingStrategy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-alias-routingstrategy.html", @@ -24,29 +24,29 @@ } } }, - "AWS::GameLift::Build.S3Location": { + "AWS::GameLift::Build.StorageLocation": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html", "Properties": { "Bucket": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-storage-bucket", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-storagelocation-bucket", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" }, "Key": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-storage-key", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-storagelocation-key", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" }, "ObjectVersion": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-object-verison", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-storagelocation-objectversion", "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" }, "RoleArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-storage-rolearn", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-build-storagelocation.html#cfn-gamelift-build-storagelocation-rolearn", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" @@ -413,6 +413,11 @@ } }, "AWS::GameLift::Build": { + "Attributes": { + "BuildId": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-build.html", "Properties": { "Name": { @@ -430,7 +435,7 @@ "StorageLocation": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-build.html#cfn-gamelift-build-storagelocation", "Required": false, - "Type": "S3Location", + "Type": "StorageLocation", "UpdateType": "Immutable" }, "Version": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GlobalAccelerator.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GlobalAccelerator.json index 07b2ffe939ad3..0a5de7bcbe1be 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GlobalAccelerator.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GlobalAccelerator.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::GlobalAccelerator::EndpointGroup.EndpointConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-globalaccelerator-endpointgroup-endpointconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Glue.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Glue.json index a6f9020945541..e6dae1331c246 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Glue.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Glue.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Glue::Classifier.CsvClassifier": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-glue-classifier-csvclassifier.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Grafana.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Grafana.json index 50536b043680c..3500629539aa7 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Grafana.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Grafana.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Grafana::Workspace.AssertionAttributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-grafana-workspace-assertionattributes.html", @@ -116,6 +116,27 @@ "UpdateType": "Mutable" } } + }, + "AWS::Grafana::Workspace.VpcConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-grafana-workspace-vpcconfiguration.html", + "Properties": { + "SecurityGroupIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-grafana-workspace-vpcconfiguration.html#cfn-grafana-workspace-vpcconfiguration-securitygroupids", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "SubnetIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-grafana-workspace-vpcconfiguration.html#cfn-grafana-workspace-vpcconfiguration-subnetids", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } } }, "ResourceTypes": { @@ -233,6 +254,12 @@ "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" + }, + "VpcConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-grafana-workspace.html#cfn-grafana-workspace-vpcconfiguration", + "Required": false, + "Type": "VpcConfiguration", + "UpdateType": "Mutable" } } } diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Greengrass.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Greengrass.json index 22a75783fdb6d..5e8aad77d88d6 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Greengrass.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Greengrass.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Greengrass::ConnectorDefinition.Connector": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-greengrass-connectordefinition-connector.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GreengrassV2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GreengrassV2.json index ab8871f159ab9..23e8ef567cdbf 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GreengrassV2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GreengrassV2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::GreengrassV2::ComponentVersion.ComponentDependencyRequirement": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-greengrassv2-componentversion-componentdependencyrequirement.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GroundStation.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GroundStation.json index 389771971f167..9d21141dc2bc9 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GroundStation.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GroundStation.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::GroundStation::Config.AntennaDownlinkConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-groundstation-config-antennadownlinkconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GuardDuty.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GuardDuty.json index f02d0521de78c..bdf5348f461e2 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GuardDuty.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_GuardDuty.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::GuardDuty::Detector.CFNDataSourceConfigurations": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-guardduty-detector-cfndatasourceconfigurations.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_HealthLake.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_HealthLake.json index 9480dcbfeb01a..3468a50e255b6 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_HealthLake.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_HealthLake.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::HealthLake::FHIRDatastore.CreatedAt": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-healthlake-fhirdatastore-createdat.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IAM.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IAM.json index e0e77f694ee52..9dc0e2aabe4af 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IAM.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IAM.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IAM::Group.Policy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IVS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IVS.json index 6540a7c1bdce3..6250dd07f73b7 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IVS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IVS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IVS::RecordingConfiguration.DestinationConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ivs-recordingconfiguration-destinationconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IdentityStore.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IdentityStore.json index 5449a20352e5d..c78c00d9f9121 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IdentityStore.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IdentityStore.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IdentityStore::GroupMembership.MemberId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-identitystore-groupmembership-memberid.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ImageBuilder.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ImageBuilder.json index 6888835e9eedd..b5a893e1de365 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ImageBuilder.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ImageBuilder.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ImageBuilder::ContainerRecipe.ComponentConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-containerrecipe-componentconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Inspector.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Inspector.json index 82d24c9b6c96f..1a05a96aedf8d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Inspector.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Inspector.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::Inspector::AssessmentTarget": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_InspectorV2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_InspectorV2.json index 5e4e6c31c81b1..f0b26b5c1eb76 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_InspectorV2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_InspectorV2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::InspectorV2::Filter.DateFilter": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-inspectorv2-filter-datefilter.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT.json index d55f6d12fd700..3996bc42021b2 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoT::AccountAuditConfiguration.AuditCheckConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot-accountauditconfiguration-auditcheckconfiguration.html", @@ -703,7 +703,6 @@ "Properties": { "Attributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot-thing-attributepayload.html#cfn-iot-thing-attributepayload-attributes", - "DuplicatesAllowed": false, "PrimitiveItemType": "String", "Required": false, "Type": "Map", @@ -2687,6 +2686,14 @@ } }, "AWS::IoT::Thing": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-thing.html", "Properties": { "AttributePayload": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT1Click.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT1Click.json index b9e26744addb7..a62eb420dfb7a 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT1Click.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT1Click.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoT1Click::Project.DeviceTemplate": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot1click-project-devicetemplate.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTAnalytics.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTAnalytics.json index 4b31a548c2dce..131e789238597 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTAnalytics.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTAnalytics.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTAnalytics::Channel.ChannelStorage": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-channel-channelstorage.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTCoreDeviceAdvisor.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTCoreDeviceAdvisor.json index eb30139331dc5..891c6a8253d47 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTCoreDeviceAdvisor.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTCoreDeviceAdvisor.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTCoreDeviceAdvisor::SuiteDefinition.DeviceUnderTest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotcoredeviceadvisor-suitedefinition-deviceundertest.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTEvents.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTEvents.json index cd42b586ef7cd..362598335c5b8 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTEvents.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTEvents.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTEvents::AlarmModel.AcknowledgeFlow": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotevents-alarmmodel-acknowledgeflow.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetHub.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetHub.json index 261b1f6a78e77..1b3743272db45 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetHub.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetHub.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::IoTFleetHub::Application": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetWise.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetWise.json index 73d59025c84c7..96a825a24af02 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetWise.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTFleetWise.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTFleetWise::Campaign.CollectionScheme": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotfleetwise-campaign-collectionscheme.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTSiteWise.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTSiteWise.json index 32580c8e31e07..5d835f1a8c6fe 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTSiteWise.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTSiteWise.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTSiteWise::AccessPolicy.AccessPolicyIdentity": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotsitewise-accesspolicy-accesspolicyidentity.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTThingsGraph.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTThingsGraph.json index f9310d73c0ab3..438629f38f5ec 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTThingsGraph.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTThingsGraph.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTThingsGraph::FlowTemplate.DefinitionDocument": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotthingsgraph-flowtemplate-definitiondocument.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTTwinMaker.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTTwinMaker.json index ad50b93f0fc9b..4e77cdbd21eb3 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTTwinMaker.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTTwinMaker.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTTwinMaker::ComponentType.DataConnector": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iottwinmaker-componenttype-dataconnector.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTWireless.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTWireless.json index 79c3a30a0d2f3..422aa6722f32d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTWireless.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoTWireless.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::IoTWireless::DeviceProfile.LoRaWANDeviceProfile": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotwireless-deviceprofile-lorawandeviceprofile.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KMS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KMS.json index ca50ddd35f040..cdb68780acc1b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KMS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KMS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::KMS::Alias": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KafkaConnect.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KafkaConnect.json index 4e6d336173dd3..f0a485fb5e52e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KafkaConnect.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KafkaConnect.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::KafkaConnect::Connector.ApacheKafkaCluster": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kafkaconnect-connector-apachekafkacluster.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kendra.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kendra.json index faef350628853..63653809f67fd 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kendra.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kendra.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Kendra::DataSource.AccessControlListConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kendra-datasource-accesscontrollistconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kinesis.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kinesis.json index 49f5bd99970c4..568836522e9b3 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kinesis.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Kinesis.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Kinesis::Stream.StreamEncryption": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kinesis-stream-streamencryption.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalytics.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalytics.json index 8b4cb389100c0..d334efd64d2bf 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalytics.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalytics.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::KinesisAnalytics::Application.CSVMappingParameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kinesisanalytics-application-csvmappingparameters.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalyticsV2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalyticsV2.json index 0756c17a4b45c..b58e76fb08700 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalyticsV2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisAnalyticsV2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::KinesisAnalyticsV2::Application.ApplicationCodeConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kinesisanalyticsv2-application-applicationcodeconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisFirehose.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisFirehose.json index 574f9c3f2edbf..852f462b97e75 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisFirehose.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisFirehose.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::KinesisFirehose::DeliveryStream.AmazonOpenSearchServerlessBufferingHints": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kinesisfirehose-deliverystream-amazonopensearchserverlessbufferinghints.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisVideo.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisVideo.json index f7b8297fe2580..5633a26383301 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisVideo.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_KinesisVideo.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::KinesisVideo::SignalingChannel": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LakeFormation.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LakeFormation.json index 493bf72272008..9f45f7b1bb7ee 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LakeFormation.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LakeFormation.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::LakeFormation::DataCellsFilter.ColumnWildcard": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-datacellsfilter-columnwildcard.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lambda.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lambda.json index 7b3d474e94ed0..27a87e71cdb03 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lambda.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lambda.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Lambda::Alias.AliasRoutingConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-alias-aliasroutingconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lex.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lex.json index ece003e14b3ca..76dcf2ef908a1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lex.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lex.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Lex::Bot.AdvancedRecognitionSetting": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lex-bot-advancedrecognitionsetting.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LicenseManager.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LicenseManager.json index 5dc8ff73a0041..af34d7b144808 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LicenseManager.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LicenseManager.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::LicenseManager::License.BorrowConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-licensemanager-license-borrowconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lightsail.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lightsail.json index 3a669904bf8d6..6458d7e3063e1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lightsail.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Lightsail.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Lightsail::Bucket.AccessRules": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-bucket-accessrules.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Location.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Location.json index 4af7a6252d49e..46c4282c52b6c 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Location.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Location.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Location::Map.MapConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-location-map-mapconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Logs.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Logs.json index a662921633460..61922d51fb9c4 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Logs.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Logs.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Logs::MetricFilter.Dimension": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-logs-metricfilter-dimension.html", @@ -235,11 +235,6 @@ } }, "AWS::Logs::SubscriptionFilter": { - "Attributes": { - "FilterName": { - "PrimitiveType": "String" - } - }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html", "Properties": { "DestinationArn": { @@ -248,6 +243,18 @@ "Required": true, "UpdateType": "Immutable" }, + "Distribution": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html#cfn-logs-subscriptionfilter-distribution", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "FilterName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html#cfn-logs-subscriptionfilter-filtername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "FilterPattern": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html#cfn-logs-subscriptionfilter-filterpattern", "PrimitiveType": "String", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutEquipment.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutEquipment.json index 8201b128bb0a5..d921dc4f42cda 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutEquipment.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutEquipment.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::LookoutEquipment::InferenceScheduler.DataInputConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lookoutequipment-inferencescheduler-datainputconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutMetrics.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutMetrics.json index ebc91409f3a97..07b1323e9b927 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutMetrics.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutMetrics.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::LookoutMetrics::Alert.Action": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lookoutmetrics-alert-action.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutVision.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutVision.json index 7e898ad122139..0de2f6ac97344 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutVision.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_LookoutVision.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::LookoutVision::Project": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_M2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_M2.json index 80808f3bbcc77..5a31c5893defc 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_M2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_M2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::M2::Application.Definition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-m2-application-definition.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MSK.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MSK.json index 1f7a03628cbef..f078247efee80 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MSK.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MSK.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MSK::Cluster.BrokerLogs": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-msk-cluster-brokerlogs.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MWAA.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MWAA.json index 89569d6daec84..9b5c34ec1c4e6 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MWAA.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MWAA.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MWAA::Environment.LoggingConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mwaa-environment-loggingconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Macie.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Macie.json index 031dc7eda0e1f..a11fdab015fca 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Macie.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Macie.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Macie::AllowList.Criteria": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-macie-allowlist-criteria.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ManagedBlockchain.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ManagedBlockchain.json index 3e3d842d9bc51..cb936a463cf3a 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ManagedBlockchain.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ManagedBlockchain.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ManagedBlockchain::Member.ApprovalThresholdPolicy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-managedblockchain-member-approvalthresholdpolicy.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConnect.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConnect.json index 10e5dc2bd65e2..294b2f5cc541c 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConnect.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConnect.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MediaConnect::Flow.Encryption": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediaconnect-flow-encryption.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConvert.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConvert.json index c75b342069803..3c3e9f5fd54b0 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConvert.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaConvert.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MediaConvert::JobTemplate.AccelerationSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediaconvert-jobtemplate-accelerationsettings.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaLive.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaLive.json index 73b0f96c0d74d..04ba2b5148be0 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaLive.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaLive.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MediaLive::Channel.AacSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-medialive-channel-aacsettings.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaPackage.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaPackage.json index 296728921f025..4103a3ef8674d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaPackage.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaPackage.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MediaPackage::Asset.EgressEndpoint": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediapackage-asset-egressendpoint.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaStore.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaStore.json index c931e337443fc..2105f05321b8c 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaStore.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaStore.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MediaStore::Container.CorsRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediastore-container-corsrule.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaTailor.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaTailor.json index bcfe2ec7084a8..28e7526797fca 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaTailor.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MediaTailor.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MediaTailor::PlaybackConfiguration.AdMarkerPassthrough": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediatailor-playbackconfiguration-admarkerpassthrough.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MemoryDB.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MemoryDB.json index c975e4abab5c3..4531ff12bcbd2 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MemoryDB.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_MemoryDB.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::MemoryDB::Cluster.Endpoint": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-memorydb-cluster-endpoint.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Neptune.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Neptune.json index 6cd82b8d18e66..9bc4f04c13bb7 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Neptune.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Neptune.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Neptune::DBCluster.DBClusterRole": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-neptune-dbcluster-dbclusterrole.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkFirewall.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkFirewall.json index 2161f35e64c79..b58417b40e695 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkFirewall.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkFirewall.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::NetworkFirewall::Firewall.SubnetMapping": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewall-subnetmapping.html", @@ -131,6 +131,12 @@ "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" + }, + "StreamExceptionPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulengineoptions.html#cfn-networkfirewall-firewallpolicy-statefulengineoptions-streamexceptionpolicy", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" } } }, @@ -326,6 +332,17 @@ } } }, + "AWS::NetworkFirewall::RuleGroup.IPSetReference": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-ipsetreference.html", + "Properties": { + "ReferenceArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-ipsetreference.html#cfn-networkfirewall-rulegroup-ipsetreference-referencearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::NetworkFirewall::RuleGroup.MatchAttributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-matchattributes.html", "Properties": { @@ -422,6 +439,18 @@ } } }, + "AWS::NetworkFirewall::RuleGroup.ReferenceSets": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-referencesets.html", + "Properties": { + "IPSetReferences": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-referencesets.html#cfn-networkfirewall-rulegroup-referencesets-ipsetreferences", + "ItemType": "IPSetReference", + "Required": false, + "Type": "Map", + "UpdateType": "Mutable" + } + } + }, "AWS::NetworkFirewall::RuleGroup.RuleDefinition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-ruledefinition.html", "Properties": { @@ -444,6 +473,12 @@ "AWS::NetworkFirewall::RuleGroup.RuleGroup": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-rulegroup.html", "Properties": { + "ReferenceSets": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-rulegroup.html#cfn-networkfirewall-rulegroup-rulegroup-referencesets", + "Required": false, + "Type": "ReferenceSets", + "UpdateType": "Mutable" + }, "RuleVariables": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-rulegroup.html#cfn-networkfirewall-rulegroup-rulegroup-rulevariables", "Required": false, diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkManager.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkManager.json index 73a420054d924..157a27be0adca 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkManager.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NetworkManager.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::NetworkManager::ConnectAttachment.ConnectAttachmentOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkmanager-connectattachment-connectattachmentoptions.html", @@ -284,6 +284,12 @@ "AWS::NetworkManager::VpcAttachment.VpcOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkmanager-vpcattachment-vpcoptions.html", "Properties": { + "ApplianceModeSupport": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkmanager-vpcattachment-vpcoptions.html#cfn-networkmanager-vpcattachment-vpcoptions-appliancemodesupport", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "Ipv6Support": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkmanager-vpcattachment-vpcoptions.html#cfn-networkmanager-vpcattachment-vpcoptions-ipv6support", "PrimitiveType": "Boolean", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NimbleStudio.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NimbleStudio.json index a67852cda1a5a..b3461c4b5599b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NimbleStudio.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_NimbleStudio.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::NimbleStudio::LaunchProfile.StreamConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-nimblestudio-launchprofile-streamconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Oam.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Oam.json index d40e6a1794561..f3e07e546bc9b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Oam.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Oam.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::Oam::Link": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchServerless.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchServerless.json index 0159a4d6a62a0..f9c25c584333b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchServerless.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchServerless.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::OpenSearchServerless::SecurityConfig.SamlConfigOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-opensearchserverless-securityconfig-samlconfigoptions.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchService.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchService.json index 91a43ddb9f5e9..e5f70f333f55d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchService.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpenSearchService.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::OpenSearchService::Domain.AdvancedSecurityOptionsInput": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-opensearchservice-domain-advancedsecurityoptionsinput.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorks.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorks.json index 8c1a8eba8b7d2..400e24eed4480 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorks.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorks.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::OpsWorks::App.DataSource": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-opsworks-app-datasource.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorksCM.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorksCM.json index 4f7d71e05d5ef..42db784075d72 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorksCM.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_OpsWorksCM.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::OpsWorksCM::Server.EngineAttribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-opsworkscm-server-engineattribute.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Organizations.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Organizations.json index dbe5396d4c204..6f36e7e06f647 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Organizations.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Organizations.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::Organizations::Account": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Panorama.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Panorama.json index cf3c0b36236af..684ab0405669b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Panorama.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Panorama.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Panorama::ApplicationInstance.ManifestOverridesPayload": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestoverridespayload.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Personalize.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Personalize.json index 1195b150caf9d..147e44a422ea8 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Personalize.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Personalize.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Personalize::Dataset.DataSource": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-personalize-dataset-datasource.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pinpoint.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pinpoint.json index 20585a9d520a6..5141c4336e2de 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pinpoint.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pinpoint.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Pinpoint::ApplicationSettings.CampaignHook": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-applicationsettings-campaignhook.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_PinpointEmail.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_PinpointEmail.json index 8d0a4b6eae55b..ab6770cc9d97d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_PinpointEmail.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_PinpointEmail.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::PinpointEmail::ConfigurationSet.DeliveryOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpointemail-configurationset-deliveryoptions.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pipes.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pipes.json index 9284f2cb98aa3..71c6748710811 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pipes.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Pipes.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Pipes::Pipe.AwsVpcConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pipes-pipe-awsvpcconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QLDB.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QLDB.json index 6ce461abc892d..75db3fc9b58a9 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QLDB.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QLDB.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::QLDB::Stream.KinesisConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-qldb-stream-kinesisconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QuickSight.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QuickSight.json index 2080bc64aecc7..cc57a673c4d80 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QuickSight.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_QuickSight.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::QuickSight::Analysis.AnalysisError": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-analysis-analysiserror.html", @@ -1368,6 +1368,12 @@ "Type": "AuroraPostgreSqlParameters", "UpdateType": "Mutable" }, + "DatabricksParameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-datasourceparameters.html#cfn-quicksight-datasource-datasourceparameters-databricksparameters", + "Required": false, + "Type": "DatabricksParameters", + "UpdateType": "Mutable" + }, "MariaDbParameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-datasourceparameters.html#cfn-quicksight-datasource-datasourceparameters-mariadbparameters", "Required": false, @@ -1442,6 +1448,29 @@ } } }, + "AWS::QuickSight::DataSource.DatabricksParameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-databricksparameters.html", + "Properties": { + "Host": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-databricksparameters.html#cfn-quicksight-datasource-databricksparameters-host", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Port": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-databricksparameters.html#cfn-quicksight-datasource-databricksparameters-port", + "PrimitiveType": "Double", + "Required": true, + "UpdateType": "Mutable" + }, + "SqlEndpointPath": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-databricksparameters.html#cfn-quicksight-datasource-databricksparameters-sqlendpointpath", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::QuickSight::DataSource.ManifestFileLocation": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-manifestfilelocation.html", "Properties": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RAM.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RAM.json index 8bbd32c082692..792ff30972b50 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RAM.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RAM.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::RAM::ResourceShare": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RDS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RDS.json index 3879c272803d3..55ebdce7ac47c 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RDS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RDS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::RDS::DBCluster.DBClusterRole": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-dbcluster-dbclusterrole.html", @@ -170,6 +170,12 @@ "Required": false, "UpdateType": "Mutable" }, + "ClientPasswordAuthType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-dbproxy-authformat.html#cfn-rds-dbproxy-authformat-clientpasswordauthtype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "Description": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-dbproxy-authformat.html#cfn-rds-dbproxy-authformat-description", "PrimitiveType": "String", @@ -739,6 +745,9 @@ "DBInstanceArn": { "PrimitiveType": "String" }, + "DBSystemId": { + "PrimitiveType": "String" + }, "DbiResourceId": { "PrimitiveType": "String" }, diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RUM.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RUM.json index 85f87f6a0af6e..b34a971f23311 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RUM.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RUM.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::RUM::AppMonitor.AppMonitorConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rum-appmonitor-appmonitorconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Redshift.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Redshift.json index 4e54dcf2961af..28c159860ae45 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Redshift.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Redshift.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Redshift::Cluster.Endpoint": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-cluster-endpoint.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RedshiftServerless.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RedshiftServerless.json index 8fcbc496e7683..9be1bdb8ba10e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RedshiftServerless.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RedshiftServerless.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::RedshiftServerless::Namespace.Namespace": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshiftserverless-namespace-namespace.html", @@ -265,9 +265,6 @@ "ResourceTypes": { "AWS::RedshiftServerless::Namespace": { "Attributes": { - "Namespace": { - "Type": "Namespace" - }, "Namespace.AdminUsername": { "PrimitiveType": "String" }, @@ -364,6 +361,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "Namespace": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshiftserverless-namespace.html#cfn-redshiftserverless-namespace-namespace", + "Required": false, + "Type": "Namespace", + "UpdateType": "Mutable" + }, "NamespaceName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshiftserverless-namespace.html#cfn-redshiftserverless-namespace-namespacename", "PrimitiveType": "String", @@ -382,32 +385,18 @@ }, "AWS::RedshiftServerless::Workgroup": { "Attributes": { - "Workgroup": { - "Type": "Workgroup" - }, "Workgroup.BaseCapacity": { "PrimitiveType": "Integer" }, - "Workgroup.ConfigParameters": { - "ItemType": "ConfigParameter", - "Type": "List" - }, "Workgroup.CreationDate": { "PrimitiveType": "String" }, - "Workgroup.Endpoint": { - "Type": "Endpoint" - }, "Workgroup.Endpoint.Address": { "PrimitiveType": "String" }, "Workgroup.Endpoint.Port": { "PrimitiveType": "Integer" }, - "Workgroup.Endpoint.VpcEndpoints": { - "ItemType": "VpcEndpoint", - "Type": "List" - }, "Workgroup.EnhancedVpcRouting": { "PrimitiveType": "Boolean" }, @@ -496,6 +485,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "Workgroup": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshiftserverless-workgroup.html#cfn-redshiftserverless-workgroup-workgroup", + "Required": false, + "Type": "Workgroup", + "UpdateType": "Mutable" + }, "WorkgroupName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshiftserverless-workgroup.html#cfn-redshiftserverless-workgroup-workgroupname", "PrimitiveType": "String", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RefactorSpaces.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RefactorSpaces.json index 8cb938f78da8d..e8c2d142852a8 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RefactorSpaces.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RefactorSpaces.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::RefactorSpaces::Application.ApiGatewayProxyInput": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-refactorspaces-application-apigatewayproxyinput.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Rekognition.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Rekognition.json index 12df724345cd7..412777ddb850e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Rekognition.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Rekognition.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Rekognition::StreamProcessor.BoundingBox": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rekognition-streamprocessor-boundingbox.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResilienceHub.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResilienceHub.json index d5f4d23be9c68..943ad9a298338 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResilienceHub.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResilienceHub.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ResilienceHub::App.PhysicalResourceId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resiliencehub-app-physicalresourceid.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceExplorer2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceExplorer2.json index f4af7ae6c36dc..90b1403bc5793 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceExplorer2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceExplorer2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ResourceExplorer2::View.Filters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resourceexplorer2-view-filters.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceGroups.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceGroups.json index 835032d710efb..ad009ea391660 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceGroups.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ResourceGroups.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ResourceGroups::Group.ConfigurationItem": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resourcegroups-group-configurationitem.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RoboMaker.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RoboMaker.json index 2340465891ef3..a1818371a32f2 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RoboMaker.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RoboMaker.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::RoboMaker::RobotApplication.RobotSoftwareSuite": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-robomaker-robotapplication-robotsoftwaresuite.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RolesAnywhere.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RolesAnywhere.json index b78b5159f5fde..f0c3de65b2877 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RolesAnywhere.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_RolesAnywhere.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::RolesAnywhere::TrustAnchor.Source": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rolesanywhere-trustanchor-source.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53.json index 2ec57e5dadce8..29c07d5102132 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Route53::CidrCollection.Location": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-cidrcollection-location.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryControl.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryControl.json index 783f7c0b214e4..93de509e3c9f7 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryControl.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryControl.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Route53RecoveryControl::Cluster.ClusterEndpoint": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-cluster-clusterendpoint.html", @@ -94,16 +94,20 @@ "ClusterArn": { "PrimitiveType": "String" }, - "ClusterEndpoints": { - "ItemType": "ClusterEndpoint", - "Type": "List" - }, "Status": { "PrimitiveType": "String" } }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-cluster.html", "Properties": { + "ClusterEndpoints": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-cluster.html#cfn-route53recoverycontrol-cluster-clusterendpoints", + "DuplicatesAllowed": true, + "ItemType": "ClusterEndpoint", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-cluster.html#cfn-route53recoverycontrol-cluster-name", "PrimitiveType": "String", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryReadiness.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryReadiness.json index 0e0c365e97c7a..dd2dcd3ca17e2 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryReadiness.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53RecoveryReadiness.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Route53RecoveryReadiness::ResourceSet.DNSTargetResource": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-dnstargetresource.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53Resolver.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53Resolver.json index 01fb39df3e6c2..7d703776c8eb4 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53Resolver.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Route53Resolver.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Route53Resolver::FirewallRuleGroup.FirewallRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53resolver-firewallrulegroup-firewallrule.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3.json index 335b05efb4075..1d5c96c01fc50 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::S3::AccessPoint.PolicyStatus": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-accesspoint-policystatus.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3ObjectLambda.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3ObjectLambda.json index 15f9000b09b6b..9571f5150baee 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3ObjectLambda.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3ObjectLambda.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::S3ObjectLambda::AccessPoint.AwsLambda": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3objectlambda-accesspoint-awslambda.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3Outposts.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3Outposts.json index b74bd755a1468..2dd589b04a80e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3Outposts.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_S3Outposts.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::S3Outposts::AccessPoint.VpcConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3outposts-accesspoint-vpcconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SDB.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SDB.json index d0afd28c72c59..b21be2487f72b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SDB.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SDB.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::SDB::Domain": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SES.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SES.json index babc5705f015b..37f78d23bbbd4 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SES.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SES.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SES::ConfigurationSet.DashboardOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ses-configurationset-dashboardoptions.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SNS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SNS.json index 0248453e8714a..7f4965a499f4b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SNS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SNS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SNS::Topic.Subscription": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-topic-subscription.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SQS.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SQS.json index 56e141d127bc1..71befad404eef 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SQS.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SQS.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::SQS::Queue": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSM.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSM.json index f6176a01a54d8..92743638c17a0 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSM.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSM.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SSM::Association.InstanceAssociationOutputLocation": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ssm-association-instanceassociationoutputlocation.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMContacts.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMContacts.json index a439535f4f239..cbbceb5545cd9 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMContacts.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMContacts.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SSMContacts::Contact.ChannelTargetInfo": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ssmcontacts-contact-channeltargetinfo.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMIncidents.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMIncidents.json index dffae3c29508c..828a7b816d096 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMIncidents.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSMIncidents.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SSMIncidents::ReplicationSet.RegionConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ssmincidents-replicationset-regionconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSO.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSO.json index 2b8bdb5384eea..792dd51f1a21e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSO.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SSO.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SSO::InstanceAccessControlAttributeConfiguration.AccessControlAttribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sso-instanceaccesscontrolattributeconfiguration-accesscontrolattribute.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SageMaker.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SageMaker.json index a9430ea9899ff..21b02a1b61ac0 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SageMaker.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SageMaker.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SageMaker::App.ResourceSpec": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-app-resourcespec.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Scheduler.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Scheduler.json index 044288c8564ba..943e3cd944dba 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Scheduler.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Scheduler.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Scheduler::Schedule.AwsVpcConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-scheduler-schedule-awsvpcconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecretsManager.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecretsManager.json index 08c3a9089c7ab..cf19d8bd07c98 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecretsManager.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecretsManager.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::SecretsManager::RotationSchedule.HostedRotationLambda": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-secretsmanager-rotationschedule-hostedrotationlambda.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecurityHub.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecurityHub.json index 96bca182fa484..8fd56ef627c15 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecurityHub.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SecurityHub.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::SecurityHub::Hub": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalog.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalog.json index 8dee94fe651ab..4751f02b62de4 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalog.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalog.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ServiceCatalog::CloudFormationProduct.ProvisioningArtifactProperties": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-servicecatalog-cloudformationproduct-provisioningartifactproperties.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalogAppRegistry.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalogAppRegistry.json index 21d9c1f5358ff..880fb0e979516 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalogAppRegistry.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceCatalogAppRegistry.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::ServiceCatalogAppRegistry::Application": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceDiscovery.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceDiscovery.json index c025de406f112..aeae3e3b5455b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceDiscovery.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_ServiceDiscovery.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::ServiceDiscovery::PrivateDnsNamespace.PrivateDnsPropertiesMutable": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-servicediscovery-privatednsnamespace-privatednspropertiesmutable.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Signer.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Signer.json index d95df93fd0798..8cce435fd6d6b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Signer.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Signer.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Signer::SigningProfile.SignatureValidityPeriod": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-signer-signingprofile-signaturevalidityperiod.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_StepFunctions.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_StepFunctions.json index e634f8c42f6d3..49fcc9bdcaa69 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_StepFunctions.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_StepFunctions.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::StepFunctions::Activity.TagsEntry": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stepfunctions-activity-tagsentry.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SupportApp.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SupportApp.json index eed21a95d79e0..9b79a989ab2c0 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SupportApp.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_SupportApp.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": {}, "ResourceTypes": { "AWS::SupportApp::AccountAlias": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Synthetics.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Synthetics.json index 286b06872fb4e..5926453a51c28 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Synthetics.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Synthetics.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Synthetics::Canary.ArtifactConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-artifactconfig.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Timestream.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Timestream.json index 930f438b30dd6..a1c57c7a1210e 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Timestream.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Timestream.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Timestream::ScheduledQuery.DimensionMapping": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-timestream-scheduledquery-dimensionmapping.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Transfer.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Transfer.json index c5e477066b698..71f3befd2054f 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Transfer.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Transfer.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Transfer::Connector.As2Config": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-transfer-connector-as2config.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_VoiceID.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_VoiceID.json index 28380d47ec205..104e2b2ece6da 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_VoiceID.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_VoiceID.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::VoiceID::Domain.ServerSideEncryptionConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-voiceid-domain-serversideencryptionconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAF.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAF.json index a8259a45ee9b4..4b6542f8abdcc 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAF.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAF.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::WAF::ByteMatchSet.ByteMatchTuple": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-waf-bytematchset-bytematchtuples.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFRegional.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFRegional.json index 2edfd0bc9f86f..f05b1f3520a5d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFRegional.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFRegional.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::WAFRegional::ByteMatchSet.ByteMatchTuple": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wafregional-bytematchset-bytematchtuple.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFv2.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFv2.json index 1fc22e658c3c2..395c4b64d3ab3 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFv2.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WAFv2.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::WAFv2::LoggingConfiguration.ActionCondition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wafv2-loggingconfiguration-actioncondition.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Wisdom.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Wisdom.json index 0ccf18cc965ba..08bf0ca6553ad 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Wisdom.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_Wisdom.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::Wisdom::Assistant.ServerSideEncryptionConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistant-serversideencryptionconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WorkSpaces.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WorkSpaces.json index 153a52f427cc8..c56971dddf272 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WorkSpaces.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_WorkSpaces.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::WorkSpaces::ConnectionAlias.ConnectionAliasAssociation": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-workspaces-connectionalias-connectionaliasassociation.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_XRay.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_XRay.json index 3e4a2f05b610e..9c11c2ed9beca 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_XRay.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_XRay.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "AWS::XRay::Group.InsightsConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-group-insightsconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Alexa_ASK.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Alexa_ASK.json index 85cbcac5383a3..ebe0ead3be9e1 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Alexa_ASK.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Alexa_ASK.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "Alexa::ASK::Skill.AuthenticationConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ask-skill-authenticationconfiguration.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Tag.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Tag.json index cc83f20d574dc..625b99fd72406 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Tag.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_Tag.json @@ -1,5 +1,5 @@ { - "$version": "102.0.0", + "$version": "103.0.0", "PropertyTypes": { "Tag": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resource-tags.html", diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/001_Version.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/001_Version.json index d45bd749bfcdc..15232a850766d 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/001_Version.json +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/001_Version.json @@ -1,3 +1,3 @@ { - "ResourceSpecificationVersion": "102.0.0" + "ResourceSpecificationVersion": "103.0.0" } From 4fbc1827b8978262da0b5b77b1ee9bc0ecfdcc3e Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Fri, 23 Dec 2022 08:58:54 -0800 Subject: [PATCH 17/22] fix(cfnspec): v101.0.0 introduced specific types on several types that previously were typed as json (#23448) This PR reverts all changes where a type changed from `Json` to a specific type in CfnSpec v101.0.0. See https://github.com/aws/aws-cdk/commit/3951f09fb370b74936f3fb45e7188ac6c7343b67 - [x] 000_AWS_Backup.json - [x] 000_AWS_CloudFormation.json - [x] 000_AWS_CodeGuruProfiler.json - [x] 000_AWS_Config.json - [x] 000_AWS_Connect.json - [x] 000_AWS_DataBrew.json - [x] 000_AWS_EC2.json - [x] 000_AWS_ECR.json - [x] 000_AWS_ElastiCache.json - [x] 000_AWS_FIS.json - [x] 000_AWS_Forecast.json - [x] 000_AWS_GreengrassV2.json - [x] 000_AWS_IoT.json - [ ] ~000_AWS_IoTAnalytics.json~ - [x] 000_AWS_IoTCoreDeviceAdvisor.json - [ ] ~000_AWS_IoTFleetWise.json~ - [x] 000_AWS_IoTSiteWise.json - [x] 000_AWS_IoTTwinMaker.json - [x] 000_AWS_IoTWireless.json - [ ] ~000_AWS_LakeFormation.json~ - [x] 000_AWS_Lex.json - [x] 000_AWS_LookoutEquipment.json - [ ] ~000_AWS_Macie.json~ - [x] 000_AWS_MemoryDB.json - [x] 000_AWS_Personalize.json - [x] 000_AWS_Redshift.json - [x] 000_AWS_Route53.json - [x] 000_AWS_S3.json - [x] 000_AWS_S3ObjectLambda.json - [x] 000_AWS_S3Outposts.json - [x] 000_AWS_SageMaker.json - [ ] ~000_AWS_Scheduler.json~ - [ ] ~000_AWS_StepFunctions.json~ - [ ] ~000_AWS_Timestream.json~ - [x] 000_AWS_Transfer.json - [x] 000_AWS_WAFv2.json ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts | 12 +- ...efaultTestDeployAssert6AFD1854.assets.json | 10 +- ...aultTestDeployAssert6AFD1854.template.json | 4 +- .../FlowLogsFeatureFlag.assets.json | 4 +- .../FlowLogsFeatureFlag.template.json | 14 +- .../FlowLogsTestStack.assets.json | 10 +- .../FlowLogsTestStack.template.json | 14 +- .../__entrypoint__.js | 144 --- .../__entrypoint__.js | 118 +++ .../index.d.ts | 1 + .../index.js | 0 .../index.ts | 82 ++ .../index.js | 215 +--- .../manifest.json | 23 +- .../integ.vpc-flow-logs.js.snapshot/tree.json | 112 +- .../aws-ec2/test/vpc-flow-logs.test.ts | 6 +- .../aws-s3objectlambda/lib/access-point.ts | 6 +- .../500_Revert_To_Json_Types_patch.json | 961 ++++++++++++++++++ packages/awslint/lib/rules/resource.ts | 1 - 19 files changed, 1261 insertions(+), 476 deletions(-) delete mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts rename packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/{asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c => asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26}/index.js (100%) create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts rename packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/{asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle => asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle}/index.js (75%) create mode 100644 packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts index 30cd9fe7d7e0d..d43f9f9aac26c 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts @@ -676,7 +676,7 @@ export class FlowLog extends FlowLogBase { } const flowLog = new CfnFlowLog(this, 'FlowLog', { - destinationOptions: renderDestinationOptions(destinationConfig.destinationOptions), + destinationOptions: destinationConfig.destinationOptions, deliverLogsPermissionArn: this.iamRole ? this.iamRole.roleArn : undefined, logDestinationType: destinationConfig.logDestinationType, logGroupName: this.logGroup ? this.logGroup.logGroupName : undefined, @@ -694,13 +694,3 @@ export class FlowLog extends FlowLogBase { this.node.defaultChild = flowLog; } } - -function renderDestinationOptions(opts: DestinationOptions | undefined): CfnFlowLog.DestinationOptionsProperty | undefined { - if (opts === undefined) { return undefined; } - - return { - fileFormat: opts.fileFormat ?? 'plain-text', - hiveCompatiblePartitions: opts.hiveCompatiblePartitions ?? false, - perHourPartition: opts.perHourPartition ?? false, - }; -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json index 7b8f6b3c685fc..297a68239d9a3 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json @@ -1,20 +1,20 @@ { "version": "21.0.0", "files": { - "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac": { + "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b": { "source": { - "path": "asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle", + "path": "asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.zip", + "objectKey": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd": { + "1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7": { "source": { "path": "FlowLogsDefaultTestDeployAssert6AFD1854.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd.json", + "objectKey": "1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json index d8bc055b720ef..e8cb5fe5ffe8f 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json @@ -31,7 +31,7 @@ } }, "flattenResponse": "false", - "salt": "1668693953813" + "salt": "1666810703150" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -115,7 +115,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.zip" + "S3Key": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip" }, "Timeout": 120, "Handler": "index.handler", diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json index ff70a68b4bce9..fa5105def2d15 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json @@ -1,7 +1,7 @@ { "version": "21.0.0", "files": { - "8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f": { + "2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9": { "source": { "path": "FlowLogsFeatureFlag.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f.json", + "objectKey": "2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json index 9f63324d697a3..0c55b91df3207 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json @@ -524,6 +524,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -536,8 +537,7 @@ "Key": "Name", "Value": "FlowLogsFeatureFlag/VPC" } - ], - "TrafficType": "ALL" + ] } }, "VPCFlowLogsS3WithDestinationOptionsBucket1B7AC456": { @@ -673,10 +673,11 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "DestinationOptions": { - "FileFormat": "plain-text", - "HiveCompatiblePartitions": true, - "PerHourPartition": false + "fileFormat": "plain-text", + "perHourPartition": false, + "hiveCompatiblePartitions": true }, "LogDestination": { "Fn::GetAtt": [ @@ -690,8 +691,7 @@ "Key": "Name", "Value": "FlowLogsFeatureFlag/VPC" } - ], - "TrafficType": "ALL" + ] } }, "FlowLogsInstanceInstanceSecurityGroupF61782E0": { diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json index d99b980527565..310bb5c387339 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json @@ -1,20 +1,20 @@ { "version": "21.0.0", "files": { - "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { + "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d": { "source": { - "path": "asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c", + "path": "asset.bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip", + "objectKey": "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79": { + "2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7": { "source": { "path": "FlowLogsTestStack.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79.json", + "objectKey": "2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json index c368f02a02265..43b56bfee9517 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json @@ -524,6 +524,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -536,8 +537,7 @@ "Key": "Name", "Value": "FlowLogsTestStack/VPC" } - ], - "TrafficType": "ALL" + ] } }, "VPCFlowLogsS3KeyPrefixFlowLogB57F1746": { @@ -547,6 +547,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::Join": [ "", @@ -567,8 +568,7 @@ "Key": "Name", "Value": "FlowLogsTestStack/VPC" } - ], - "TrafficType": "ALL" + ] } }, "FlowLogsCWIAMRole017AD736": { @@ -643,6 +643,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "DeliverLogsPermissionArn": { "Fn::GetAtt": [ "FlowLogsCWIAMRole017AD736", @@ -652,8 +653,7 @@ "LogDestinationType": "cloud-watch-logs", "LogGroupName": { "Ref": "FlowLogsCWLogGroup0398E8F8" - }, - "TrafficType": "ALL" + } } }, "Bucket83908E77": { @@ -888,7 +888,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip" + "S3Key": "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js deleted file mode 100644 index 1e3a3093c1706..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js +++ /dev/null @@ -1,144 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.withRetries = exports.handler = exports.external = void 0; -const https = require("https"); -const url = require("url"); -// for unit tests -exports.external = { - sendHttpRequest: defaultSendHttpRequest, - log: defaultLog, - includeStackTraces: true, - userHandlerIndex: './index', -}; -const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; -const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; -async function handler(event, context) { - const sanitizedEvent = { ...event, ResponseURL: '...' }; - exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); - // ignore DELETE event when the physical resource ID is the marker that - // indicates that this DELETE is a subsequent DELETE to a failed CREATE - // operation. - if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { - exports.external.log('ignoring DELETE event caused by a failed CREATE event'); - await submitResponse('SUCCESS', event); - return; - } - try { - // invoke the user handler. this is intentionally inside the try-catch to - // ensure that if there is an error it's reported as a failure to - // cloudformation (otherwise cfn waits). - // eslint-disable-next-line @typescript-eslint/no-require-imports - const userHandler = require(exports.external.userHandlerIndex).handler; - const result = await userHandler(sanitizedEvent, context); - // validate user response and create the combined event - const responseEvent = renderResponse(event, result); - // submit to cfn as success - await submitResponse('SUCCESS', responseEvent); - } - catch (e) { - const resp = { - ...event, - Reason: exports.external.includeStackTraces ? e.stack : e.message, - }; - if (!resp.PhysicalResourceId) { - // special case: if CREATE fails, which usually implies, we usually don't - // have a physical resource id. in this case, the subsequent DELETE - // operation does not have any meaning, and will likely fail as well. to - // address this, we use a marker so the provider framework can simply - // ignore the subsequent DELETE. - if (event.RequestType === 'Create') { - exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); - resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; - } - else { - // otherwise, if PhysicalResourceId is not specified, something is - // terribly wrong because all other events should have an ID. - exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); - } - } - // this is an actual error, fail the activity altogether and exist. - await submitResponse('FAILED', resp); - } -} -exports.handler = handler; -function renderResponse(cfnRequest, handlerResponse = {}) { - // if physical ID is not returned, we have some defaults for you based - // on the request type. - const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; - // if we are in DELETE and physical ID was changed, it's an error. - if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { - throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); - } - // merge request event and result event (result prevails). - return { - ...cfnRequest, - ...handlerResponse, - PhysicalResourceId: physicalResourceId, - }; -} -async function submitResponse(status, event) { - const json = { - Status: status, - Reason: event.Reason ?? status, - StackId: event.StackId, - RequestId: event.RequestId, - PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, - LogicalResourceId: event.LogicalResourceId, - NoEcho: event.NoEcho, - Data: event.Data, - }; - exports.external.log('submit response to cloudformation', json); - const responseBody = JSON.stringify(json); - const parsedUrl = url.parse(event.ResponseURL); - const req = { - hostname: parsedUrl.hostname, - path: parsedUrl.path, - method: 'PUT', - headers: { 'content-type': '', 'content-length': responseBody.length }, - }; - const retryOptions = { - attempts: 5, - sleep: 1000, - }; - await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); -} -async function defaultSendHttpRequest(options, responseBody) { - return new Promise((resolve, reject) => { - try { - const request = https.request(options, _ => resolve()); - request.on('error', reject); - request.write(responseBody); - request.end(); - } - catch (e) { - reject(e); - } - }); -} -function defaultLog(fmt, ...params) { - // eslint-disable-next-line no-console - console.log(fmt, ...params); -} -function withRetries(options, fn) { - return async (...xs) => { - let attempts = options.attempts; - let ms = options.sleep; - while (true) { - try { - return await fn(...xs); - } - catch (e) { - if (attempts-- <= 0) { - throw e; - } - await sleep(Math.floor(Math.random() * ms)); - ms *= 2; - } - } - }; -} -exports.withRetries = withRetries; -async function sleep(ms) { - return new Promise((ok) => setTimeout(ok, ms)); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUQsdURBQXVEO1FBQ3ZELE1BQU0sYUFBYSxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFcEQsMkJBQTJCO1FBQzNCLE1BQU0sY0FBYyxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUMsQ0FBQztLQUNoRDtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1YsTUFBTSxJQUFJLEdBQWE7WUFDckIsR0FBRyxLQUFLO1lBQ1IsTUFBTSxFQUFFLGdCQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1NBQzFELENBQUM7UUFFRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzVCLHlFQUF5RTtZQUN6RSxtRUFBbUU7WUFDbkUsd0VBQXdFO1lBQ3hFLHFFQUFxRTtZQUNyRSxnQ0FBZ0M7WUFDaEMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEMsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsNEdBQTRHLENBQUMsQ0FBQztnQkFDM0gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdDQUFnQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLGtFQUFrRTtnQkFDbEUsNkRBQTZEO2dCQUM3RCxnQkFBUSxDQUFDLEdBQUcsQ0FBQyw2REFBNkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDcEc7U0FDRjtRQUVELG1FQUFtRTtRQUNuRSxNQUFNLGNBQWMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDdEM7QUFDSCxDQUFDO0FBbkRELDBCQW1EQztBQUVELFNBQVMsY0FBYyxDQUNyQixVQUF5RixFQUN6RixrQkFBMEMsRUFBRztJQUU3QyxzRUFBc0U7SUFDdEUsdUJBQXVCO0lBQ3ZCLE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDLGtCQUFrQixJQUFJLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDO0lBRXZILGtFQUFrRTtJQUNsRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLEtBQUssUUFBUSxJQUFJLGtCQUFrQixLQUFLLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRTtRQUMvRixNQUFNLElBQUksS0FBSyxDQUFDLHdEQUF3RCxVQUFVLENBQUMsa0JBQWtCLFNBQVMsZUFBZSxDQUFDLGtCQUFrQixtQkFBbUIsQ0FBQyxDQUFDO0tBQ3RLO0lBRUQsMERBQTBEO0lBQzFELE9BQU87UUFDTCxHQUFHLFVBQVU7UUFDYixHQUFHLGVBQWU7UUFDbEIsa0JBQWtCLEVBQUUsa0JBQWtCO0tBQ3ZDLENBQUM7QUFDSixDQUFDO0FBRUQsS0FBSyxVQUFVLGNBQWMsQ0FBQyxNQUE0QixFQUFFLEtBQWU7SUFDekUsTUFBTSxJQUFJLEdBQW1EO1FBQzNELE1BQU0sRUFBRSxNQUFNO1FBQ2QsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksTUFBTTtRQUM5QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87UUFDdEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1FBQzFCLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSwwQkFBMEI7UUFDMUUsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjtRQUMxQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07UUFDcEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO0tBQ2pCLENBQUM7SUFFRixnQkFBUSxDQUFDLEdBQUcsQ0FBQyxtQ0FBbUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUV4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sR0FBRyxHQUFHO1FBQ1YsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1FBQzVCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtRQUNwQixNQUFNLEVBQUUsS0FBSztRQUNiLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRTtLQUN2RSxDQUFDO0lBRUYsTUFBTSxZQUFZLEdBQUc7UUFDbkIsUUFBUSxFQUFFLENBQUM7UUFDWCxLQUFLLEVBQUUsSUFBSTtLQUNaLENBQUM7SUFDRixNQUFNLFdBQVcsQ0FBQyxZQUFZLEVBQUUsZ0JBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVELEtBQUssVUFBVSxzQkFBc0IsQ0FBQyxPQUE2QixFQUFFLFlBQW9CO0lBQ3ZGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNmO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDWDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxHQUFHLE1BQWE7SUFDL0Msc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQVNELFNBQWdCLFdBQVcsQ0FBMEIsT0FBcUIsRUFBRSxFQUE0QjtJQUN0RyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUssRUFBRSxFQUFFO1FBQ3hCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDaEMsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUN2QixPQUFPLElBQUksRUFBRTtZQUNYLElBQUk7Z0JBQ0YsT0FBTyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2FBQ3hCO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsSUFBSSxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUU7b0JBQ25CLE1BQU0sQ0FBQyxDQUFDO2lCQUNUO2dCQUNELE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDVDtTQUNGO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQWhCRCxrQ0FnQkM7QUFFRCxLQUFLLFVBQVUsS0FBSyxDQUFDLEVBQVU7SUFDN0IsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zdCByZXNwOiBSZXNwb25zZSA9IHtcbiAgICAgIC4uLmV2ZW50LFxuICAgICAgUmVhc29uOiBleHRlcm5hbC5pbmNsdWRlU3RhY2tUcmFjZXMgPyBlLnN0YWNrIDogZS5tZXNzYWdlLFxuICAgIH07XG5cbiAgICBpZiAoIXJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICAvLyBzcGVjaWFsIGNhc2U6IGlmIENSRUFURSBmYWlscywgd2hpY2ggdXN1YWxseSBpbXBsaWVzLCB3ZSB1c3VhbGx5IGRvbid0XG4gICAgICAvLyBoYXZlIGEgcGh5c2ljYWwgcmVzb3VyY2UgaWQuIGluIHRoaXMgY2FzZSwgdGhlIHN1YnNlcXVlbnQgREVMRVRFXG4gICAgICAvLyBvcGVyYXRpb24gZG9lcyBub3QgaGF2ZSBhbnkgbWVhbmluZywgYW5kIHdpbGwgbGlrZWx5IGZhaWwgYXMgd2VsbC4gdG9cbiAgICAgIC8vIGFkZHJlc3MgdGhpcywgd2UgdXNlIGEgbWFya2VyIHNvIHRoZSBwcm92aWRlciBmcmFtZXdvcmsgY2FuIHNpbXBseVxuICAgICAgLy8gaWdub3JlIHRoZSBzdWJzZXF1ZW50IERFTEVURS5cbiAgICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICAgICAgZXh0ZXJuYWwubG9nKCdDUkVBVEUgZmFpbGVkLCByZXNwb25kaW5nIHdpdGggYSBtYXJrZXIgcGh5c2ljYWwgcmVzb3VyY2UgaWQgc28gdGhhdCB0aGUgc3Vic2VxdWVudCBERUxFVEUgd2lsbCBiZSBpZ25vcmVkJyk7XG4gICAgICAgIHJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkID0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvdGhlcndpc2UsIGlmIFBoeXNpY2FsUmVzb3VyY2VJZCBpcyBub3Qgc3BlY2lmaWVkLCBzb21ldGhpbmcgaXNcbiAgICAgICAgLy8gdGVycmlibHkgd3JvbmcgYmVjYXVzZSBhbGwgb3RoZXIgZXZlbnRzIHNob3VsZCBoYXZlIGFuIElELlxuICAgICAgICBleHRlcm5hbC5sb2coYEVSUk9SOiBNYWxmb3JtZWQgZXZlbnQuIFwiUGh5c2ljYWxSZXNvdXJjZUlkXCIgaXMgcmVxdWlyZWQ6ICR7SlNPTi5zdHJpbmdpZnkoZXZlbnQpfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoaXMgaXMgYW4gYWN0dWFsIGVycm9yLCBmYWlsIHRoZSBhY3Rpdml0eSBhbHRvZ2V0aGVyIGFuZCBleGlzdC5cbiAgICBhd2FpdCBzdWJtaXRSZXNwb25zZSgnRkFJTEVEJywgcmVzcCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyUmVzcG9uc2UoXG4gIGNmblJlcXVlc3Q6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQgJiB7IFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZyB9LFxuICBoYW5kbGVyUmVzcG9uc2U6IHZvaWQgfCBIYW5kbGVyUmVzcG9uc2UgPSB7IH0pOiBSZXNwb25zZSB7XG5cbiAgLy8gaWYgcGh5c2ljYWwgSUQgaXMgbm90IHJldHVybmVkLCB3ZSBoYXZlIHNvbWUgZGVmYXVsdHMgZm9yIHlvdSBiYXNlZFxuICAvLyBvbiB0aGUgcmVxdWVzdCB0eXBlLlxuICBjb25zdCBwaHlzaWNhbFJlc291cmNlSWQgPSBoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUmVxdWVzdElkO1xuXG4gIC8vIGlmIHdlIGFyZSBpbiBERUxFVEUgYW5kIHBoeXNpY2FsIElEIHdhcyBjaGFuZ2VkLCBpdCdzIGFuIGVycm9yLlxuICBpZiAoY2ZuUmVxdWVzdC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScgJiYgcGh5c2ljYWxSZXNvdXJjZUlkICE9PSBjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgREVMRVRFOiBjYW5ub3QgY2hhbmdlIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBmcm9tIFwiJHtjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZH1cIiB0byBcIiR7aGFuZGxlclJlc3BvbnNlLlBoeXNpY2FsUmVzb3VyY2VJZH1cIiBkdXJpbmcgZGVsZXRpb25gKTtcbiAgfVxuXG4gIC8vIG1lcmdlIHJlcXVlc3QgZXZlbnQgYW5kIHJlc3VsdCBldmVudCAocmVzdWx0IHByZXZhaWxzKS5cbiAgcmV0dXJuIHtcbiAgICAuLi5jZm5SZXF1ZXN0LFxuICAgIC4uLmhhbmRsZXJSZXNwb25zZSxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3VibWl0UmVzcG9uc2Uoc3RhdHVzOiAnU1VDQ0VTUycgfCAnRkFJTEVEJywgZXZlbnQ6IFJlc3BvbnNlKSB7XG4gIGNvbnN0IGpzb246IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2UgPSB7XG4gICAgU3RhdHVzOiBzdGF0dXMsXG4gICAgUmVhc29uOiBldmVudC5SZWFzb24gPz8gc3RhdHVzLFxuICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfHwgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIsXG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgIE5vRWNobzogZXZlbnQuTm9FY2hvLFxuICAgIERhdGE6IGV2ZW50LkRhdGEsXG4gIH07XG5cbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBqc29uKTtcblxuICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKGV2ZW50LlJlc3BvbnNlVVJMKTtcbiAgY29uc3QgcmVxID0ge1xuICAgIGhvc3RuYW1lOiBwYXJzZWRVcmwuaG9zdG5hbWUsXG4gICAgcGF0aDogcGFyc2VkVXJsLnBhdGgsXG4gICAgbWV0aG9kOiAnUFVUJyxcbiAgICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnJywgJ2NvbnRlbnQtbGVuZ3RoJzogcmVzcG9uc2VCb2R5Lmxlbmd0aCB9LFxuICB9O1xuXG4gIGNvbnN0IHJldHJ5T3B0aW9ucyA9IHtcbiAgICBhdHRlbXB0czogNSxcbiAgICBzbGVlcDogMTAwMCxcbiAgfTtcbiAgYXdhaXQgd2l0aFJldHJpZXMocmV0cnlPcHRpb25zLCBleHRlcm5hbC5zZW5kSHR0cFJlcXVlc3QpKHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59Il19 \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js new file mode 100644 index 0000000000000..9df94382cc74e --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js @@ -0,0 +1,118 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = exports.external = void 0; +const https = require("https"); +const url = require("url"); +// for unit tests +exports.external = { + sendHttpRequest: defaultSendHttpRequest, + log: defaultLog, + includeStackTraces: true, + userHandlerIndex: './index', +}; +const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; +const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; +async function handler(event, context) { + const sanitizedEvent = { ...event, ResponseURL: '...' }; + exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); + // ignore DELETE event when the physical resource ID is the marker that + // indicates that this DELETE is a subsequent DELETE to a failed CREATE + // operation. + if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { + exports.external.log('ignoring DELETE event caused by a failed CREATE event'); + await submitResponse('SUCCESS', event); + return; + } + try { + // invoke the user handler. this is intentionally inside the try-catch to + // ensure that if there is an error it's reported as a failure to + // cloudformation (otherwise cfn waits). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const userHandler = require(exports.external.userHandlerIndex).handler; + const result = await userHandler(sanitizedEvent, context); + // validate user response and create the combined event + const responseEvent = renderResponse(event, result); + // submit to cfn as success + await submitResponse('SUCCESS', responseEvent); + } + catch (e) { + const resp = { + ...event, + Reason: exports.external.includeStackTraces ? e.stack : e.message, + }; + if (!resp.PhysicalResourceId) { + // special case: if CREATE fails, which usually implies, we usually don't + // have a physical resource id. in this case, the subsequent DELETE + // operation does not have any meaning, and will likely fail as well. to + // address this, we use a marker so the provider framework can simply + // ignore the subsequent DELETE. + if (event.RequestType === 'Create') { + exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); + resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; + } + else { + // otherwise, if PhysicalResourceId is not specified, something is + // terribly wrong because all other events should have an ID. + exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); + } + } + // this is an actual error, fail the activity altogether and exist. + await submitResponse('FAILED', resp); + } +} +exports.handler = handler; +function renderResponse(cfnRequest, handlerResponse = {}) { + // if physical ID is not returned, we have some defaults for you based + // on the request type. + const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; + // if we are in DELETE and physical ID was changed, it's an error. + if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { + throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); + } + // merge request event and result event (result prevails). + return { + ...cfnRequest, + ...handlerResponse, + PhysicalResourceId: physicalResourceId, + }; +} +async function submitResponse(status, event) { + const json = { + Status: status, + Reason: event.Reason ?? status, + StackId: event.StackId, + RequestId: event.RequestId, + PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, + LogicalResourceId: event.LogicalResourceId, + NoEcho: event.NoEcho, + Data: event.Data, + }; + exports.external.log('submit response to cloudformation', json); + const responseBody = JSON.stringify(json); + const parsedUrl = url.parse(event.ResponseURL); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + await exports.external.sendHttpRequest(req, responseBody); +} +async function defaultSendHttpRequest(options, responseBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, _ => resolve()); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +function defaultLog(fmt, ...params) { + // eslint-disable-next-line no-console + console.log(fmt, ...params); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUQsdURBQXVEO1FBQ3ZELE1BQU0sYUFBYSxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFcEQsMkJBQTJCO1FBQzNCLE1BQU0sY0FBYyxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUMsQ0FBQztLQUNoRDtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1YsTUFBTSxJQUFJLEdBQWE7WUFDckIsR0FBRyxLQUFLO1lBQ1IsTUFBTSxFQUFFLGdCQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1NBQzFELENBQUM7UUFFRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzVCLHlFQUF5RTtZQUN6RSxtRUFBbUU7WUFDbkUsd0VBQXdFO1lBQ3hFLHFFQUFxRTtZQUNyRSxnQ0FBZ0M7WUFDaEMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEMsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsNEdBQTRHLENBQUMsQ0FBQztnQkFDM0gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdDQUFnQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLGtFQUFrRTtnQkFDbEUsNkRBQTZEO2dCQUM3RCxnQkFBUSxDQUFDLEdBQUcsQ0FBQyw2REFBNkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDcEc7U0FDRjtRQUVELG1FQUFtRTtRQUNuRSxNQUFNLGNBQWMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDdEM7QUFDSCxDQUFDO0FBbkRELDBCQW1EQztBQUVELFNBQVMsY0FBYyxDQUNyQixVQUF5RixFQUN6RixrQkFBMEMsRUFBRztJQUU3QyxzRUFBc0U7SUFDdEUsdUJBQXVCO0lBQ3ZCLE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDLGtCQUFrQixJQUFJLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDO0lBRXZILGtFQUFrRTtJQUNsRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLEtBQUssUUFBUSxJQUFJLGtCQUFrQixLQUFLLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRTtRQUMvRixNQUFNLElBQUksS0FBSyxDQUFDLHdEQUF3RCxVQUFVLENBQUMsa0JBQWtCLFNBQVMsZUFBZSxDQUFDLGtCQUFrQixtQkFBbUIsQ0FBQyxDQUFDO0tBQ3RLO0lBRUQsMERBQTBEO0lBQzFELE9BQU87UUFDTCxHQUFHLFVBQVU7UUFDYixHQUFHLGVBQWU7UUFDbEIsa0JBQWtCLEVBQUUsa0JBQWtCO0tBQ3ZDLENBQUM7QUFDSixDQUFDO0FBRUQsS0FBSyxVQUFVLGNBQWMsQ0FBQyxNQUE0QixFQUFFLEtBQWU7SUFDekUsTUFBTSxJQUFJLEdBQW1EO1FBQzNELE1BQU0sRUFBRSxNQUFNO1FBQ2QsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksTUFBTTtRQUM5QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87UUFDdEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1FBQzFCLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSwwQkFBMEI7UUFDMUUsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjtRQUMxQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07UUFDcEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO0tBQ2pCLENBQUM7SUFFRixnQkFBUSxDQUFDLEdBQUcsQ0FBQyxtQ0FBbUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUV4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sR0FBRyxHQUFHO1FBQ1YsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1FBQzVCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtRQUNwQixNQUFNLEVBQUUsS0FBSztRQUNiLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRTtLQUN2RSxDQUFDO0lBRUYsTUFBTSxnQkFBUSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUVELEtBQUssVUFBVSxzQkFBc0IsQ0FBQyxPQUE2QixFQUFFLFlBQW9CO0lBQ3ZGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNmO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDWDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxHQUFHLE1BQWE7SUFDL0Msc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCAqIGFzIHVybCBmcm9tICd1cmwnO1xuXG4vLyBmb3IgdW5pdCB0ZXN0c1xuZXhwb3J0IGNvbnN0IGV4dGVybmFsID0ge1xuICBzZW5kSHR0cFJlcXVlc3Q6IGRlZmF1bHRTZW5kSHR0cFJlcXVlc3QsXG4gIGxvZzogZGVmYXVsdExvZyxcbiAgaW5jbHVkZVN0YWNrVHJhY2VzOiB0cnVlLFxuICB1c2VySGFuZGxlckluZGV4OiAnLi9pbmRleCcsXG59O1xuXG5jb25zdCBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUiA9ICdBV1NDREs6OkN1c3RvbVJlc291cmNlUHJvdmlkZXJGcmFtZXdvcms6OkNSRUFURV9GQUlMRUQnO1xuY29uc3QgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpNSVNTSU5HX1BIWVNJQ0FMX0lEJztcblxuZXhwb3J0IHR5cGUgUmVzcG9uc2UgPSBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50ICYgSGFuZGxlclJlc3BvbnNlO1xuZXhwb3J0IHR5cGUgSGFuZGxlciA9IChldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpID0+IFByb21pc2U8SGFuZGxlclJlc3BvbnNlIHwgdm9pZD47XG5leHBvcnQgdHlwZSBIYW5kbGVyUmVzcG9uc2UgPSB1bmRlZmluZWQgfCB7XG4gIERhdGE/OiBhbnk7XG4gIFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZztcbiAgUmVhc29uPzogc3RyaW5nO1xuICBOb0VjaG8/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGNvbnN0IHNhbml0aXplZEV2ZW50ID0geyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH07XG4gIGV4dGVybmFsLmxvZyhKU09OLnN0cmluZ2lmeShzYW5pdGl6ZWRFdmVudCwgdW5kZWZpbmVkLCAyKSk7XG5cbiAgLy8gaWdub3JlIERFTEVURSBldmVudCB3aGVuIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBpcyB0aGUgbWFya2VyIHRoYXRcbiAgLy8gaW5kaWNhdGVzIHRoYXQgdGhpcyBERUxFVEUgaXMgYSBzdWJzZXF1ZW50IERFTEVURSB0byBhIGZhaWxlZCBDUkVBVEVcbiAgLy8gb3BlcmF0aW9uLlxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnICYmIGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCA9PT0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIpIHtcbiAgICBleHRlcm5hbC5sb2coJ2lnbm9yaW5nIERFTEVURSBldmVudCBjYXVzZWQgYnkgYSBmYWlsZWQgQ1JFQVRFIGV2ZW50Jyk7XG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCBldmVudCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBpbnZva2UgdGhlIHVzZXIgaGFuZGxlci4gdGhpcyBpcyBpbnRlbnRpb25hbGx5IGluc2lkZSB0aGUgdHJ5LWNhdGNoIHRvXG4gICAgLy8gZW5zdXJlIHRoYXQgaWYgdGhlcmUgaXMgYW4gZXJyb3IgaXQncyByZXBvcnRlZCBhcyBhIGZhaWx1cmUgdG9cbiAgICAvLyBjbG91ZGZvcm1hdGlvbiAob3RoZXJ3aXNlIGNmbiB3YWl0cykuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCB1c2VySGFuZGxlcjogSGFuZGxlciA9IHJlcXVpcmUoZXh0ZXJuYWwudXNlckhhbmRsZXJJbmRleCkuaGFuZGxlcjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB1c2VySGFuZGxlcihzYW5pdGl6ZWRFdmVudCwgY29udGV4dCk7XG5cbiAgICAvLyB2YWxpZGF0ZSB1c2VyIHJlc3BvbnNlIGFuZCBjcmVhdGUgdGhlIGNvbWJpbmVkIGV2ZW50XG4gICAgY29uc3QgcmVzcG9uc2VFdmVudCA9IHJlbmRlclJlc3BvbnNlKGV2ZW50LCByZXN1bHQpO1xuXG4gICAgLy8gc3VibWl0IHRvIGNmbiBhcyBzdWNjZXNzXG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCByZXNwb25zZUV2ZW50KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnN0IHJlc3A6IFJlc3BvbnNlID0ge1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBSZWFzb246IGV4dGVybmFsLmluY2x1ZGVTdGFja1RyYWNlcyA/IGUuc3RhY2sgOiBlLm1lc3NhZ2UsXG4gICAgfTtcblxuICAgIGlmICghcmVzcC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogaWYgQ1JFQVRFIGZhaWxzLCB3aGljaCB1c3VhbGx5IGltcGxpZXMsIHdlIHVzdWFsbHkgZG9uJ3RcbiAgICAgIC8vIGhhdmUgYSBwaHlzaWNhbCByZXNvdXJjZSBpZC4gaW4gdGhpcyBjYXNlLCB0aGUgc3Vic2VxdWVudCBERUxFVEVcbiAgICAgIC8vIG9wZXJhdGlvbiBkb2VzIG5vdCBoYXZlIGFueSBtZWFuaW5nLCBhbmQgd2lsbCBsaWtlbHkgZmFpbCBhcyB3ZWxsLiB0b1xuICAgICAgLy8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYSBtYXJrZXIgc28gdGhlIHByb3ZpZGVyIGZyYW1ld29yayBjYW4gc2ltcGx5XG4gICAgICAvLyBpZ25vcmUgdGhlIHN1YnNlcXVlbnQgREVMRVRFLlxuICAgICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgICAgICBleHRlcm5hbC5sb2coJ0NSRUFURSBmYWlsZWQsIHJlc3BvbmRpbmcgd2l0aCBhIG1hcmtlciBwaHlzaWNhbCByZXNvdXJjZSBpZCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IERFTEVURSB3aWxsIGJlIGlnbm9yZWQnKTtcbiAgICAgICAgcmVzcC5QaHlzaWNhbFJlc291cmNlSWQgPSBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG90aGVyd2lzZSwgaWYgUGh5c2ljYWxSZXNvdXJjZUlkIGlzIG5vdCBzcGVjaWZpZWQsIHNvbWV0aGluZyBpc1xuICAgICAgICAvLyB0ZXJyaWJseSB3cm9uZyBiZWNhdXNlIGFsbCBvdGhlciBldmVudHMgc2hvdWxkIGhhdmUgYW4gSUQuXG4gICAgICAgIGV4dGVybmFsLmxvZyhgRVJST1I6IE1hbGZvcm1lZCBldmVudC4gXCJQaHlzaWNhbFJlc291cmNlSWRcIiBpcyByZXF1aXJlZDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBpcyBhbiBhY3R1YWwgZXJyb3IsIGZhaWwgdGhlIGFjdGl2aXR5IGFsdG9nZXRoZXIgYW5kIGV4aXN0LlxuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdGQUlMRUQnLCByZXNwKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSZXNwb25zZShcbiAgY2ZuUmVxdWVzdDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIHsgUGh5c2ljYWxSZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gIGhhbmRsZXJSZXNwb25zZTogdm9pZCB8IEhhbmRsZXJSZXNwb25zZSA9IHsgfSk6IFJlc3BvbnNlIHtcblxuICAvLyBpZiBwaHlzaWNhbCBJRCBpcyBub3QgcmV0dXJuZWQsIHdlIGhhdmUgc29tZSBkZWZhdWx0cyBmb3IgeW91IGJhc2VkXG4gIC8vIG9uIHRoZSByZXF1ZXN0IHR5cGUuXG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGhhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5SZXF1ZXN0SWQ7XG5cbiAgLy8gaWYgd2UgYXJlIGluIERFTEVURSBhbmQgcGh5c2ljYWwgSUQgd2FzIGNoYW5nZWQsIGl0J3MgYW4gZXJyb3IuXG4gIGlmIChjZm5SZXF1ZXN0LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBwaHlzaWNhbFJlc291cmNlSWQgIT09IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBERUxFVEU6IGNhbm5vdCBjaGFuZ2UgdGhlIHBoeXNpY2FsIHJlc291cmNlIElEIGZyb20gXCIke2NmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIHRvIFwiJHtoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIGR1cmluZyBkZWxldGlvbmApO1xuICB9XG5cbiAgLy8gbWVyZ2UgcmVxdWVzdCBldmVudCBhbmQgcmVzdWx0IGV2ZW50IChyZXN1bHQgcHJldmFpbHMpLlxuICByZXR1cm4ge1xuICAgIC4uLmNmblJlcXVlc3QsXG4gICAgLi4uaGFuZGxlclJlc3BvbnNlLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdWJtaXRSZXNwb25zZShzdGF0dXM6ICdTVUNDRVNTJyB8ICdGQUlMRUQnLCBldmVudDogUmVzcG9uc2UpIHtcbiAgY29uc3QganNvbjogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSA9IHtcbiAgICBTdGF0dXM6IHN0YXR1cyxcbiAgICBSZWFzb246IGV2ZW50LlJlYXNvbiA/PyBzdGF0dXMsXG4gICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBNSVNTSU5HX1BIWVNJQ0FMX0lEX01BUktFUixcbiAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgTm9FY2hvOiBldmVudC5Ob0VjaG8sXG4gICAgRGF0YTogZXZlbnQuRGF0YSxcbiAgfTtcblxuICBleHRlcm5hbC5sb2coJ3N1Ym1pdCByZXNwb25zZSB0byBjbG91ZGZvcm1hdGlvbicsIGpzb24pO1xuXG4gIGNvbnN0IHJlc3BvbnNlQm9keSA9IEpTT04uc3RyaW5naWZ5KGpzb24pO1xuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICBjb25zdCByZXEgPSB7XG4gICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICBwYXRoOiBwYXJzZWRVcmwucGF0aCxcbiAgICBtZXRob2Q6ICdQVVQnLFxuICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gIH07XG5cbiAgYXdhaXQgZXh0ZXJuYWwuc2VuZEh0dHBSZXF1ZXN0KHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts new file mode 100644 index 0000000000000..3554dc94d4617 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts @@ -0,0 +1 @@ +export declare function handler(event: AWSLambda.CloudFormationCustomResourceEvent): Promise; diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.js similarity index 100% rename from packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js rename to packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.js diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts new file mode 100644 index 0000000000000..2459d44ab1d18 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts @@ -0,0 +1,82 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { S3 } from 'aws-sdk'; + +const AUTO_DELETE_OBJECTS_TAG = 'aws-cdk:auto-delete-objects'; + +const s3 = new S3(); + +export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent) { + switch (event.RequestType) { + case 'Create': + return; + case 'Update': + return onUpdate(event); + case 'Delete': + return onDelete(event.ResourceProperties?.BucketName); + } +} + +async function onUpdate(event: AWSLambda.CloudFormationCustomResourceEvent) { + const updateEvent = event as AWSLambda.CloudFormationCustomResourceUpdateEvent; + const oldBucketName = updateEvent.OldResourceProperties?.BucketName; + const newBucketName = updateEvent.ResourceProperties?.BucketName; + const bucketNameHasChanged = newBucketName != null && oldBucketName != null && newBucketName !== oldBucketName; + + /* If the name of the bucket has changed, CloudFormation will try to delete the bucket + and create a new one with the new name. So we have to delete the contents of the + bucket so that this operation does not fail. */ + if (bucketNameHasChanged) { + return onDelete(oldBucketName); + } +} + +/** + * Recursively delete all items in the bucket + * + * @param bucketName the bucket name + */ +async function emptyBucket(bucketName: string) { + const listedObjects = await s3.listObjectVersions({ Bucket: bucketName }).promise(); + const contents = [...listedObjects.Versions ?? [], ...listedObjects.DeleteMarkers ?? []]; + if (contents.length === 0) { + return; + } + + const records = contents.map((record: any) => ({ Key: record.Key, VersionId: record.VersionId })); + await s3.deleteObjects({ Bucket: bucketName, Delete: { Objects: records } }).promise(); + + if (listedObjects?.IsTruncated) { + await emptyBucket(bucketName); + } +} + +async function onDelete(bucketName?: string) { + if (!bucketName) { + throw new Error('No BucketName was provided.'); + } + if (!await isBucketTaggedForDeletion(bucketName)) { + process.stdout.write(`Bucket does not have '${AUTO_DELETE_OBJECTS_TAG}' tag, skipping cleaning.\n`); + return; + } + try { + await emptyBucket(bucketName); + } catch (e) { + if (e.code !== 'NoSuchBucket') { + throw e; + } + // Bucket doesn't exist. Ignoring + } +} + +/** + * The bucket will only be tagged for deletion if it's being deleted in the same + * deployment as this Custom Resource. + * + * If the Custom Resource is every deleted before the bucket, it must be because + * `autoDeleteObjects` has been switched to false, in which case the tag would have + * been removed before we get to this Delete event. + */ +async function isBucketTaggedForDeletion(bucketName: string) { + const response = await s3.getBucketTagging({ Bucket: bucketName }).promise(); + return response.TagSet.some(tag => tag.Key === AUTO_DELETE_OBJECTS_TAG && tag.Value === 'true'); +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js similarity index 75% rename from packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js rename to packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js index 6bee1ced2a9b7..ba956d47f51fe 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js @@ -1,3 +1,4 @@ +"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; @@ -25,9 +26,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru // lib/assertions/providers/lambda-handler/index.ts var lambda_handler_exports = {}; __export(lambda_handler_exports, { - handler: () => handler, - isComplete: () => isComplete, - onTimeout: () => onTimeout + handler: () => handler }); module.exports = __toCommonJS(lambda_handler_exports); @@ -387,7 +386,6 @@ var StringLikeRegexpMatch = class extends Matcher { // lib/assertions/providers/lambda-handler/base.ts var https = __toESM(require("https")); var url = __toESM(require("url")); -var AWS = __toESM(require("aws-sdk")); var CustomResourceHandler = class { constructor(event, context) { this.event = event; @@ -406,40 +404,20 @@ var CustomResourceHandler = class { } async handle() { try { - if ("stateMachineArn" in this.event.ResourceProperties) { - const req = { - stateMachineArn: this.event.ResourceProperties.stateMachineArn, - name: this.event.RequestId, - input: JSON.stringify(this.event) - }; - await this.startExecution(req); - return; - } else { - const response = await this.processEvent(this.event.ResourceProperties); - return response; - } - } catch (e) { - console.log(e); - throw e; - } finally { - clearTimeout(this.timeout); - } - } - async handleIsComplete() { - try { - const result = await this.processEvent(this.event.ResourceProperties); - return result; + console.log(`Event: ${JSON.stringify({ ...this.event, ResponseURL: "..." })}`); + const response = await this.processEvent(this.event.ResourceProperties); + console.log(`Event output : ${JSON.stringify(response)}`); + await this.respond({ + status: "SUCCESS", + reason: "OK", + data: response + }); } catch (e) { console.log(e); - return; - } finally { - clearTimeout(this.timeout); - } - } - async startExecution(req) { - try { - const sfn = new AWS.StepFunctions(); - await sfn.startExecution(req).promise(); + await this.respond({ + status: "FAILED", + reason: e.message ?? "Internal Error" + }); } finally { clearTimeout(this.timeout); } @@ -475,8 +453,6 @@ var CustomResourceHandler = class { request2.end(); } catch (e) { reject(e); - } finally { - clearTimeout(this.timeout); } }); } @@ -503,8 +479,7 @@ var AssertionHandler = class extends CustomResourceHandler { matchResult.finished(); if (matchResult.hasFailed()) { result = { - failed: true, - assertion: JSON.stringify({ + data: JSON.stringify({ status: "fail", message: [ ...matchResult.toHumanStrings(), @@ -513,11 +488,11 @@ var AssertionHandler = class extends CustomResourceHandler { }) }; if (request2.failDeployment) { - throw new Error(result.assertion); + throw new Error(result.data); } } else { result = { - assertion: JSON.stringify({ + data: JSON.stringify({ status: "success" }) }; @@ -587,10 +562,7 @@ function flatten(object) { {}, ...function _flatten(child, path = []) { return [].concat(...Object.keys(child).map((key) => { - let childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; - if (typeof childKey === "string") { - childKey = isJsonString(childKey); - } + const childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; return typeof childKey === "object" && childKey !== null ? _flatten(childKey, path.concat([key])) : { [path.concat([key]).join(".")]: childKey }; })); }(object) @@ -598,12 +570,9 @@ function flatten(object) { } var AwsApiCallHandler = class extends CustomResourceHandler { async processEvent(request2) { - const AWS2 = require("aws-sdk"); - console.log(`AWS SDK VERSION: ${AWS2.VERSION}`); - if (!Object.prototype.hasOwnProperty.call(AWS2, request2.service)) { - throw Error(`Service ${request2.service} does not exist in AWS SDK version ${AWS2.VERSION}.`); - } - const service = new AWS2[request2.service](); + const AWS = require("aws-sdk"); + console.log(`AWS SDK VERSION: ${AWS.VERSION}`); + const service = new AWS[request2.service](); const response = await service[request2.api](request2.parameters && decode(request2.parameters)).promise(); console.log(`SDK response received ${JSON.stringify(response)}`); delete response.ResponseMetadata; @@ -613,18 +582,9 @@ var AwsApiCallHandler = class extends CustomResourceHandler { const flatData = { ...flatten(respond) }; - const resp = request2.flattenResponse === "true" ? flatData : respond; - console.log(`Returning result ${JSON.stringify(resp)}`); - return resp; + return request2.flattenResponse === "true" ? flatData : respond; } }; -function isJsonString(value) { - try { - return JSON.parse(value); - } catch { - return value; - } -} // lib/assertions/providers/lambda-handler/types.ts var ASSERT_RESOURCE_TYPE = "Custom::DeployAssert@AssertEquals"; @@ -632,136 +592,21 @@ var SDK_RESOURCE_TYPE_PREFIX = "Custom::DeployAssert@SdkCall"; // lib/assertions/providers/lambda-handler/index.ts async function handler(event, context) { - console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); - const provider = createResourceHandler(event, context); - try { - if (event.RequestType === "Delete") { - await provider.respond({ - status: "SUCCESS", - reason: "OK" - }); - return; - } - const result = await provider.handle(); - if ("stateMachineArn" in event.ResourceProperties) { - console.info('Found "stateMachineArn", waiter statemachine started'); - return; - } else if ("expected" in event.ResourceProperties) { - console.info('Found "expected", testing assertions'); - const actualPath = event.ResourceProperties.actualPath; - const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; - const assertion = new AssertionHandler({ - ...event, - ResourceProperties: { - ServiceToken: event.ServiceToken, - actual, - expected: event.ResourceProperties.expected - } - }, context); - try { - const assertionResult = await assertion.handle(); - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: { - ...assertionResult, - ...result - } - }); - return; - } catch (e) { - await provider.respond({ - status: "FAILED", - reason: e.message ?? "Internal Error" - }); - return; - } - } - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: result - }); - } catch (e) { - await provider.respond({ - status: "FAILED", - reason: e.message ?? "Internal Error" - }); - return; - } - return; -} -async function onTimeout(timeoutEvent) { - const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage); - const provider = createResourceHandler(isCompleteRequest, standardContext); - await provider.respond({ - status: "FAILED", - reason: "Operation timed out: " + JSON.stringify(isCompleteRequest) - }); -} -async function isComplete(event, context) { - console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); const provider = createResourceHandler(event, context); - try { - const result = await provider.handleIsComplete(); - const actualPath = event.ResourceProperties.actualPath; - if (result) { - const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; - if ("expected" in event.ResourceProperties) { - const assertion = new AssertionHandler({ - ...event, - ResourceProperties: { - ServiceToken: event.ServiceToken, - actual, - expected: event.ResourceProperties.expected - } - }, context); - const assertionResult = await assertion.handleIsComplete(); - if (!(assertionResult == null ? void 0 : assertionResult.failed)) { - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: { - ...assertionResult, - ...result - } - }); - return; - } else { - console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`); - throw new Error(JSON.stringify(event)); - } - } - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: result - }); - } else { - console.log("No result"); - throw new Error(JSON.stringify(event)); - } - return; - } catch (e) { - console.log(e); - throw new Error(JSON.stringify(event)); - } + await provider.handle(); } function createResourceHandler(event, context) { if (event.ResourceType.startsWith(SDK_RESOURCE_TYPE_PREFIX)) { return new AwsApiCallHandler(event, context); - } else if (event.ResourceType.startsWith(ASSERT_RESOURCE_TYPE)) { - return new AssertionHandler(event, context); - } else { - throw new Error(`Unsupported resource type "${event.ResourceType}`); + } + switch (event.ResourceType) { + case ASSERT_RESOURCE_TYPE: + return new AssertionHandler(event, context); + default: + throw new Error(`Unsupported resource type "${event.ResourceType}`); } } -var standardContext = { - getRemainingTimeInMillis: () => 9e4 -}; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { - handler, - isComplete, - onTimeout + handler }); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json index 773077597be42..a114baf10c235 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json @@ -1,6 +1,12 @@ { "version": "21.0.0", "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, "FlowLogsFeatureFlag.assets": { "type": "cdk:asset-manifest", "properties": { @@ -17,7 +23,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -204,10 +210,7 @@ "/FlowLogsFeatureFlag/VPC/FlowLogsS3WithDestinationOptions/FlowLog": [ { "type": "aws:cdk:logicalId", - "data": "VPCFlowLogsS3WithDestinationOptionsFlowLog030C15B2", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "VPCFlowLogsS3WithDestinationOptionsFlowLog030C15B2" } ], "/FlowLogsFeatureFlag/Exports/Output{\"Fn::GetAtt\":[\"VPCFlowLogsS3BucketFB7DC2BE\",\"Arn\"]}": [ @@ -283,7 +286,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -546,7 +549,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -601,12 +604,6 @@ ] }, "displayName": "FlowLogs/DefaultTest/DeployAssert" - }, - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json index f6e0ef7c83ea9..9a0ff6b79a4b7 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json @@ -4,6 +4,14 @@ "id": "App", "path": "", "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.123" + } + }, "FlowLogsFeatureFlag": { "id": "FlowLogsFeatureFlag", "path": "FlowLogsFeatureFlag", @@ -819,6 +827,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -831,8 +840,7 @@ "key": "Name", "value": "FlowLogsFeatureFlag/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -1020,10 +1028,11 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "destinationOptions": { "fileFormat": "plain-text", - "hiveCompatiblePartitions": true, - "perHourPartition": false + "perHourPartition": false, + "hiveCompatiblePartitions": true }, "logDestination": { "Fn::GetAtt": [ @@ -1037,8 +1046,7 @@ "key": "Name", "value": "FlowLogsFeatureFlag/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -1081,7 +1089,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } }, "FlowLogsInstance": { @@ -1132,14 +1140,6 @@ "id": "InstanceRole", "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole", "children": { - "ImportInstanceRole": { - "id": "ImportInstanceRole", - "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole/ImportInstanceRole", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, "Resource": { "id": "Resource", "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole/Resource", @@ -1264,22 +1264,6 @@ "fqn": "@aws-cdk/core.Resource", "version": "0.0.0" } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogsFeatureFlag/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogsFeatureFlag/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" - } } }, "constructInfo": { @@ -2102,6 +2086,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -2114,8 +2099,7 @@ "key": "Name", "value": "FlowLogsTestStack/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -2143,6 +2127,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::Join": [ "", @@ -2163,8 +2148,7 @@ "key": "Name", "value": "FlowLogsTestStack/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -2192,14 +2176,6 @@ "id": "IAMRole", "path": "FlowLogsTestStack/FlowLogsCW/IAMRole", "children": { - "ImportIAMRole": { - "id": "ImportIAMRole", - "path": "FlowLogsTestStack/FlowLogsCW/IAMRole/ImportIAMRole", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, "Resource": { "id": "Resource", "path": "FlowLogsTestStack/FlowLogsCW/IAMRole/Resource", @@ -2323,6 +2299,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "deliverLogsPermissionArn": { "Fn::GetAtt": [ "FlowLogsCWIAMRole017AD736", @@ -2332,8 +2309,7 @@ "logDestinationType": "cloud-watch-logs", "logGroupName": { "Ref": "FlowLogsCWLogGroup0398E8F8" - }, - "trafficType": "ALL" + } } }, "constructInfo": { @@ -2616,22 +2592,6 @@ "fqn": "@aws-cdk/core.CustomResourceProvider", "version": "0.0.0" } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogsTestStack/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogsTestStack/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" - } } }, "constructInfo": { @@ -2652,7 +2612,7 @@ "path": "FlowLogs/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } }, "DeployAssert": { @@ -2672,7 +2632,7 @@ "path": "FlowLogs/DefaultTest/DeployAssert/AwsApiCallS3listObjectsV2/SdkProvider/AssertionsProvider", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } } }, @@ -2744,23 +2704,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" - } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogs/DefaultTest/DeployAssert/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogs/DefaultTest/DeployAssert/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" + "version": "10.1.123" } } }, @@ -2780,14 +2724,6 @@ "fqn": "@aws-cdk/integ-tests.IntegTest", "version": "0.0.0" } - }, - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.161" - } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts index 7a068377feffb..5b16d80caf50d 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts @@ -93,9 +93,9 @@ describe('vpc flow logs', () => { TrafficType: 'ALL', ResourceId: 'eni-123456', DestinationOptions: { - HiveCompatiblePartitions: true, - FileFormat: 'plain-text', - PerHourPartition: false, + hiveCompatiblePartitions: true, + fileFormat: 'plain-text', + perHourPartition: false, }, LogDestination: { 'Fn::GetAtt': [ diff --git a/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts b/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts index 7136bd3d267a7..7d0804aa3367a 100644 --- a/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts +++ b/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts @@ -232,9 +232,9 @@ export class AccessPoint extends AccessPointBase { { actions: ['GetObject'], contentTransformation: { - awsLambda: { - functionArn: props.handler.functionArn, - functionPayload: props.payload ? JSON.stringify(props.payload) : undefined, + AwsLambda: { + FunctionArn: props.handler.functionArn, + FunctionPayload: props.payload ? JSON.stringify(props.payload) : undefined, }, }, }, diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json new file mode 100644 index 0000000000000..237e302807756 --- /dev/null +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json @@ -0,0 +1,961 @@ +{ + "ResourceTypes": { + "AWS::Backup::ReportPlan": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ReportDeliveryChannel/Type" + }, + { + "op": "add", + "path": "/Properties/ReportDeliveryChannel/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/ReportSetting/Type" + }, + { + "op": "add", + "path": "/Properties/ReportSetting/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::CloudFormation::StackSet": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ManagedExecution/Type" + }, + { + "op": "add", + "path": "/Properties/ManagedExecution/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::CodeGuruProfiler::ProfilingGroup": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AgentPermissions/Type" + }, + { + "op": "add", + "path": "/Properties/AgentPermissions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Config::ConformancePack": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/TemplateSSMDocumentDetails/Type" + }, + { + "op": "add", + "path": "/Properties/TemplateSSMDocumentDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Connect::TaskTemplate": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Constraints/Type" + }, + { + "op": "add", + "path": "/Properties/Constraints/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::FlowLog": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DestinationOptions/Type" + }, + { + "op": "add", + "path": "/Properties/DestinationOptions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::Subnet": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/PrivateDnsNameOptionsOnLaunch/Type" + }, + { + "op": "add", + "path": "/Properties/PrivateDnsNameOptionsOnLaunch/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayAttachment": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayMulticastDomain": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayVpcAttachment": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::ECR::PublicRepository": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RepositoryCatalogData/Type" + }, + { + "op": "add", + "path": "/Properties/RepositoryCatalogData/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::ElastiCache::User": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AuthenticationMode/Type" + }, + { + "op": "add", + "path": "/Properties/AuthenticationMode/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Forecast::Dataset": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/EncryptionConfig/Type" + }, + { + "op": "add", + "path": "/Properties/EncryptionConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Schema/Type" + }, + { + "op": "add", + "path": "/Properties/Schema/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoT::JobTemplate": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AbortConfig/Type" + }, + { + "op": "add", + "path": "/Properties/AbortConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/JobExecutionsRolloutConfig/Type" + }, + { + "op": "add", + "path": "/Properties/JobExecutionsRolloutConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/PresignedUrlConfig/Type" + }, + { + "op": "add", + "path": "/Properties/PresignedUrlConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/TimeoutConfig/Type" + }, + { + "op": "add", + "path": "/Properties/TimeoutConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTCoreDeviceAdvisor::SuiteDefinition": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SuiteDefinitionConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/SuiteDefinitionConfiguration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTSiteWise::Portal": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Alarms/Type" + }, + { + "op": "add", + "path": "/Properties/Alarms/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTWireless::NetworkAnalyzerConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/TraceContent/Type" + }, + { + "op": "add", + "path": "/Properties/TraceContent/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::Bot": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataPrivacy/Type" + }, + { + "op": "add", + "path": "/Properties/DataPrivacy/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::BotAlias": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SentimentAnalysisSettings/Type" + }, + { + "op": "add", + "path": "/Properties/SentimentAnalysisSettings/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::LookoutEquipment::InferenceScheduler": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataInputConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/DataInputConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/DataOutputConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/DataOutputConfiguration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::MemoryDB::User": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AuthenticationMode/Type" + }, + { + "op": "add", + "path": "/Properties/AuthenticationMode/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Redshift::EndpointAccess": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/VpcEndpoint/Type" + }, + { + "op": "add", + "path": "/Properties/VpcEndpoint/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Route53::HealthCheck": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/HealthCheckConfig/Type" + }, + { + "op": "add", + "path": "/Properties/HealthCheckConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3::AccessPoint": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/PolicyStatus/Type" + }, + { + "op": "add", + "path": "/Properties/PolicyStatus/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::FeatureGroup": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/OfflineStoreConfig/Type" + }, + { + "op": "add", + "path": "/Properties/OfflineStoreConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/OnlineStoreConfig/Type" + }, + { + "op": "add", + "path": "/Properties/OnlineStoreConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::Pipeline": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ParallelismConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/ParallelismConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/PipelineDefinition/Type" + }, + { + "op": "add", + "path": "/Properties/PipelineDefinition/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::Project": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ServiceCatalogProvisioningDetails/Type" + }, + { + "op": "add", + "path": "/Properties/ServiceCatalogProvisioningDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Transfer::Connector": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/As2Config/Type" + }, + { + "op": "add", + "path": "/Properties/As2Config/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::LoggingConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/LoggingFilter/Type" + }, + { + "op": "add", + "path": "/Properties/LoggingFilter/PrimitiveType", + "value": "Json" + } + ] + } + } + }, + "PropertyTypes": { + "AWS::Backup::BackupSelection.BackupSelectionResourceType": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Conditions/Type" + }, + { + "op": "add", + "path": "/Properties/Conditions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Backup::Framework.FrameworkControl": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ControlScope/Type" + }, + { + "op": "add", + "path": "/Properties/ControlScope/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::DataBrew::Recipe.RecipeParameters": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Input/Type" + }, + { + "op": "add", + "path": "/Properties/Input/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::FIS::ExperimentTemplate.ExperimentTemplateLogConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/CloudWatchLogsConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/CloudWatchLogsConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/S3Configuration/Type" + }, + { + "op": "add", + "path": "/Properties/S3Configuration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::GreengrassV2::Deployment.IoTJobRateIncreaseCriteria": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties" + }, + { + "op": "add", + "path": "/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::ComponentType.DataValue": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RelationshipValue/Type" + }, + { + "op": "add", + "path": "/Properties/RelationshipValue/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.DataValue": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RelationshipValue/Type" + }, + { + "op": "add", + "path": "/Properties/RelationshipValue/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.Property": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Definition/Type" + }, + { + "op": "add", + "path": "/Properties/Definition/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.Status": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Error/Type" + }, + { + "op": "add", + "path": "/Properties/Error/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::Bot.TestBotAliasSettings": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SentimentAnalysisSettings/Type" + }, + { + "op": "add", + "path": "/Properties/SentimentAnalysisSettings/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Personalize::Dataset.DatasetImportJob": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataSource/Type" + }, + { + "op": "add", + "path": "/Properties/DataSource/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Personalize::Solution.SolutionConfig": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AutoMLConfig/Type" + }, + { + "op": "add", + "path": "/Properties/AutoMLConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/HpoConfig/Type" + }, + { + "op": "add", + "path": "/Properties/HpoConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3ObjectLambda::AccessPoint.TransformationConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ContentTransformation/Type" + }, + { + "op": "add", + "path": "/Properties/ContentTransformation/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3Outposts::Bucket.Rule": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Filter/Type" + }, + { + "op": "add", + "path": "/Properties/Filter/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::ModelPackage.ModelPackageContainerDefinition": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ModelInput/Type" + }, + { + "op": "add", + "path": "/Properties/ModelInput/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Transfer::Workflow.WorkflowStep": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/CopyStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/CopyStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/CustomStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/CustomStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/DeleteStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/DeleteStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/TagStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/TagStepDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::LoggingConfiguration.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/JsonBody/Type" + }, + { + "op": "add", + "path": "/Properties/JsonBody/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::RuleGroup.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SingleQueryArgument/Type" + }, + { + "op": "add", + "path": "/Properties/SingleQueryArgument/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::RuleGroup.RuleAction": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Allow/Type" + }, + { + "op": "add", + "path": "/Properties/Allow/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Block/Type" + }, + { + "op": "add", + "path": "/Properties/Block/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Captcha/Type" + }, + { + "op": "add", + "path": "/Properties/Captcha/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Count/Type" + }, + { + "op": "add", + "path": "/Properties/Count/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::WebACL.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SingleQueryArgument/Type" + }, + { + "op": "add", + "path": "/Properties/SingleQueryArgument/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + } + } +} diff --git a/packages/awslint/lib/rules/resource.ts b/packages/awslint/lib/rules/resource.ts index 95894c847f71d..e7478a811fa57 100644 --- a/packages/awslint/lib/rules/resource.ts +++ b/packages/awslint/lib/rules/resource.ts @@ -189,7 +189,6 @@ resourceLinter.add({ // This rule is the worst resourceLinter.add({ code: 'resource-attribute', - warning: true, message: 'resources must represent all cloudformation attributes as attribute properties. ' + '"@attribute ATTR[,ATTR]" can be used to tag non-standard attribute names. ' + From 1b4e3a4b503d5d08e976ccf245c20f4430bcba46 Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Fri, 23 Dec 2022 08:58:54 -0800 Subject: [PATCH 18/22] fix(cfnspec): v101.0.0 introduced specific types on several types that previously were typed as json (#23448) This PR reverts all changes where a type changed from `Json` to a specific type in CfnSpec v101.0.0. See https://github.com/aws/aws-cdk/commit/3951f09fb370b74936f3fb45e7188ac6c7343b67 - [x] 000_AWS_Backup.json - [x] 000_AWS_CloudFormation.json - [x] 000_AWS_CodeGuruProfiler.json - [x] 000_AWS_Config.json - [x] 000_AWS_Connect.json - [x] 000_AWS_DataBrew.json - [x] 000_AWS_EC2.json - [x] 000_AWS_ECR.json - [x] 000_AWS_ElastiCache.json - [x] 000_AWS_FIS.json - [x] 000_AWS_Forecast.json - [x] 000_AWS_GreengrassV2.json - [x] 000_AWS_IoT.json - [ ] ~000_AWS_IoTAnalytics.json~ - [x] 000_AWS_IoTCoreDeviceAdvisor.json - [ ] ~000_AWS_IoTFleetWise.json~ - [x] 000_AWS_IoTSiteWise.json - [x] 000_AWS_IoTTwinMaker.json - [x] 000_AWS_IoTWireless.json - [ ] ~000_AWS_LakeFormation.json~ - [x] 000_AWS_Lex.json - [x] 000_AWS_LookoutEquipment.json - [ ] ~000_AWS_Macie.json~ - [x] 000_AWS_MemoryDB.json - [x] 000_AWS_Personalize.json - [x] 000_AWS_Redshift.json - [x] 000_AWS_Route53.json - [x] 000_AWS_S3.json - [x] 000_AWS_S3ObjectLambda.json - [x] 000_AWS_S3Outposts.json - [x] 000_AWS_SageMaker.json - [ ] ~000_AWS_Scheduler.json~ - [ ] ~000_AWS_StepFunctions.json~ - [ ] ~000_AWS_Timestream.json~ - [x] 000_AWS_Transfer.json - [x] 000_AWS_WAFv2.json ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts | 12 +- ...efaultTestDeployAssert6AFD1854.assets.json | 10 +- ...aultTestDeployAssert6AFD1854.template.json | 4 +- .../FlowLogsFeatureFlag.assets.json | 4 +- .../FlowLogsFeatureFlag.template.json | 14 +- .../FlowLogsTestStack.assets.json | 10 +- .../FlowLogsTestStack.template.json | 14 +- .../__entrypoint__.js | 144 --- .../__entrypoint__.js | 118 +++ .../index.d.ts | 1 + .../index.js | 0 .../index.ts | 82 ++ .../index.js | 215 +--- .../manifest.json | 23 +- .../integ.vpc-flow-logs.js.snapshot/tree.json | 112 +- .../aws-ec2/test/vpc-flow-logs.test.ts | 6 +- .../aws-s3objectlambda/lib/access-point.ts | 6 +- .../500_Revert_To_Json_Types_patch.json | 961 ++++++++++++++++++ packages/awslint/lib/rules/resource.ts | 1 - 19 files changed, 1261 insertions(+), 476 deletions(-) delete mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts rename packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/{asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c => asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26}/index.js (100%) create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts rename packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/{asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle => asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle}/index.js (75%) create mode 100644 packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts index 30cd9fe7d7e0d..d43f9f9aac26c 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts @@ -676,7 +676,7 @@ export class FlowLog extends FlowLogBase { } const flowLog = new CfnFlowLog(this, 'FlowLog', { - destinationOptions: renderDestinationOptions(destinationConfig.destinationOptions), + destinationOptions: destinationConfig.destinationOptions, deliverLogsPermissionArn: this.iamRole ? this.iamRole.roleArn : undefined, logDestinationType: destinationConfig.logDestinationType, logGroupName: this.logGroup ? this.logGroup.logGroupName : undefined, @@ -694,13 +694,3 @@ export class FlowLog extends FlowLogBase { this.node.defaultChild = flowLog; } } - -function renderDestinationOptions(opts: DestinationOptions | undefined): CfnFlowLog.DestinationOptionsProperty | undefined { - if (opts === undefined) { return undefined; } - - return { - fileFormat: opts.fileFormat ?? 'plain-text', - hiveCompatiblePartitions: opts.hiveCompatiblePartitions ?? false, - perHourPartition: opts.perHourPartition ?? false, - }; -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json index 7b8f6b3c685fc..297a68239d9a3 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json @@ -1,20 +1,20 @@ { "version": "21.0.0", "files": { - "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac": { + "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b": { "source": { - "path": "asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle", + "path": "asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.zip", + "objectKey": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd": { + "1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7": { "source": { "path": "FlowLogsDefaultTestDeployAssert6AFD1854.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd.json", + "objectKey": "1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json index d8bc055b720ef..e8cb5fe5ffe8f 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json @@ -31,7 +31,7 @@ } }, "flattenResponse": "false", - "salt": "1668693953813" + "salt": "1666810703150" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -115,7 +115,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.zip" + "S3Key": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip" }, "Timeout": 120, "Handler": "index.handler", diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json index ff70a68b4bce9..fa5105def2d15 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json @@ -1,7 +1,7 @@ { "version": "21.0.0", "files": { - "8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f": { + "2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9": { "source": { "path": "FlowLogsFeatureFlag.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f.json", + "objectKey": "2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json index 9f63324d697a3..0c55b91df3207 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json @@ -524,6 +524,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -536,8 +537,7 @@ "Key": "Name", "Value": "FlowLogsFeatureFlag/VPC" } - ], - "TrafficType": "ALL" + ] } }, "VPCFlowLogsS3WithDestinationOptionsBucket1B7AC456": { @@ -673,10 +673,11 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "DestinationOptions": { - "FileFormat": "plain-text", - "HiveCompatiblePartitions": true, - "PerHourPartition": false + "fileFormat": "plain-text", + "perHourPartition": false, + "hiveCompatiblePartitions": true }, "LogDestination": { "Fn::GetAtt": [ @@ -690,8 +691,7 @@ "Key": "Name", "Value": "FlowLogsFeatureFlag/VPC" } - ], - "TrafficType": "ALL" + ] } }, "FlowLogsInstanceInstanceSecurityGroupF61782E0": { diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json index d99b980527565..310bb5c387339 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json @@ -1,20 +1,20 @@ { "version": "21.0.0", "files": { - "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { + "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d": { "source": { - "path": "asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c", + "path": "asset.bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip", + "objectKey": "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79": { + "2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7": { "source": { "path": "FlowLogsTestStack.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79.json", + "objectKey": "2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json index c368f02a02265..43b56bfee9517 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json @@ -524,6 +524,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -536,8 +537,7 @@ "Key": "Name", "Value": "FlowLogsTestStack/VPC" } - ], - "TrafficType": "ALL" + ] } }, "VPCFlowLogsS3KeyPrefixFlowLogB57F1746": { @@ -547,6 +547,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::Join": [ "", @@ -567,8 +568,7 @@ "Key": "Name", "Value": "FlowLogsTestStack/VPC" } - ], - "TrafficType": "ALL" + ] } }, "FlowLogsCWIAMRole017AD736": { @@ -643,6 +643,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "DeliverLogsPermissionArn": { "Fn::GetAtt": [ "FlowLogsCWIAMRole017AD736", @@ -652,8 +653,7 @@ "LogDestinationType": "cloud-watch-logs", "LogGroupName": { "Ref": "FlowLogsCWLogGroup0398E8F8" - }, - "TrafficType": "ALL" + } } }, "Bucket83908E77": { @@ -888,7 +888,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip" + "S3Key": "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js deleted file mode 100644 index 1e3a3093c1706..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js +++ /dev/null @@ -1,144 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.withRetries = exports.handler = exports.external = void 0; -const https = require("https"); -const url = require("url"); -// for unit tests -exports.external = { - sendHttpRequest: defaultSendHttpRequest, - log: defaultLog, - includeStackTraces: true, - userHandlerIndex: './index', -}; -const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; -const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; -async function handler(event, context) { - const sanitizedEvent = { ...event, ResponseURL: '...' }; - exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); - // ignore DELETE event when the physical resource ID is the marker that - // indicates that this DELETE is a subsequent DELETE to a failed CREATE - // operation. - if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { - exports.external.log('ignoring DELETE event caused by a failed CREATE event'); - await submitResponse('SUCCESS', event); - return; - } - try { - // invoke the user handler. this is intentionally inside the try-catch to - // ensure that if there is an error it's reported as a failure to - // cloudformation (otherwise cfn waits). - // eslint-disable-next-line @typescript-eslint/no-require-imports - const userHandler = require(exports.external.userHandlerIndex).handler; - const result = await userHandler(sanitizedEvent, context); - // validate user response and create the combined event - const responseEvent = renderResponse(event, result); - // submit to cfn as success - await submitResponse('SUCCESS', responseEvent); - } - catch (e) { - const resp = { - ...event, - Reason: exports.external.includeStackTraces ? e.stack : e.message, - }; - if (!resp.PhysicalResourceId) { - // special case: if CREATE fails, which usually implies, we usually don't - // have a physical resource id. in this case, the subsequent DELETE - // operation does not have any meaning, and will likely fail as well. to - // address this, we use a marker so the provider framework can simply - // ignore the subsequent DELETE. - if (event.RequestType === 'Create') { - exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); - resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; - } - else { - // otherwise, if PhysicalResourceId is not specified, something is - // terribly wrong because all other events should have an ID. - exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); - } - } - // this is an actual error, fail the activity altogether and exist. - await submitResponse('FAILED', resp); - } -} -exports.handler = handler; -function renderResponse(cfnRequest, handlerResponse = {}) { - // if physical ID is not returned, we have some defaults for you based - // on the request type. - const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; - // if we are in DELETE and physical ID was changed, it's an error. - if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { - throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); - } - // merge request event and result event (result prevails). - return { - ...cfnRequest, - ...handlerResponse, - PhysicalResourceId: physicalResourceId, - }; -} -async function submitResponse(status, event) { - const json = { - Status: status, - Reason: event.Reason ?? status, - StackId: event.StackId, - RequestId: event.RequestId, - PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, - LogicalResourceId: event.LogicalResourceId, - NoEcho: event.NoEcho, - Data: event.Data, - }; - exports.external.log('submit response to cloudformation', json); - const responseBody = JSON.stringify(json); - const parsedUrl = url.parse(event.ResponseURL); - const req = { - hostname: parsedUrl.hostname, - path: parsedUrl.path, - method: 'PUT', - headers: { 'content-type': '', 'content-length': responseBody.length }, - }; - const retryOptions = { - attempts: 5, - sleep: 1000, - }; - await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); -} -async function defaultSendHttpRequest(options, responseBody) { - return new Promise((resolve, reject) => { - try { - const request = https.request(options, _ => resolve()); - request.on('error', reject); - request.write(responseBody); - request.end(); - } - catch (e) { - reject(e); - } - }); -} -function defaultLog(fmt, ...params) { - // eslint-disable-next-line no-console - console.log(fmt, ...params); -} -function withRetries(options, fn) { - return async (...xs) => { - let attempts = options.attempts; - let ms = options.sleep; - while (true) { - try { - return await fn(...xs); - } - catch (e) { - if (attempts-- <= 0) { - throw e; - } - await sleep(Math.floor(Math.random() * ms)); - ms *= 2; - } - } - }; -} -exports.withRetries = withRetries; -async function sleep(ms) { - return new Promise((ok) => setTimeout(ok, ms)); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUQsdURBQXVEO1FBQ3ZELE1BQU0sYUFBYSxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFcEQsMkJBQTJCO1FBQzNCLE1BQU0sY0FBYyxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUMsQ0FBQztLQUNoRDtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1YsTUFBTSxJQUFJLEdBQWE7WUFDckIsR0FBRyxLQUFLO1lBQ1IsTUFBTSxFQUFFLGdCQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1NBQzFELENBQUM7UUFFRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzVCLHlFQUF5RTtZQUN6RSxtRUFBbUU7WUFDbkUsd0VBQXdFO1lBQ3hFLHFFQUFxRTtZQUNyRSxnQ0FBZ0M7WUFDaEMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEMsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsNEdBQTRHLENBQUMsQ0FBQztnQkFDM0gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdDQUFnQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLGtFQUFrRTtnQkFDbEUsNkRBQTZEO2dCQUM3RCxnQkFBUSxDQUFDLEdBQUcsQ0FBQyw2REFBNkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDcEc7U0FDRjtRQUVELG1FQUFtRTtRQUNuRSxNQUFNLGNBQWMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDdEM7QUFDSCxDQUFDO0FBbkRELDBCQW1EQztBQUVELFNBQVMsY0FBYyxDQUNyQixVQUF5RixFQUN6RixrQkFBMEMsRUFBRztJQUU3QyxzRUFBc0U7SUFDdEUsdUJBQXVCO0lBQ3ZCLE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDLGtCQUFrQixJQUFJLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDO0lBRXZILGtFQUFrRTtJQUNsRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLEtBQUssUUFBUSxJQUFJLGtCQUFrQixLQUFLLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRTtRQUMvRixNQUFNLElBQUksS0FBSyxDQUFDLHdEQUF3RCxVQUFVLENBQUMsa0JBQWtCLFNBQVMsZUFBZSxDQUFDLGtCQUFrQixtQkFBbUIsQ0FBQyxDQUFDO0tBQ3RLO0lBRUQsMERBQTBEO0lBQzFELE9BQU87UUFDTCxHQUFHLFVBQVU7UUFDYixHQUFHLGVBQWU7UUFDbEIsa0JBQWtCLEVBQUUsa0JBQWtCO0tBQ3ZDLENBQUM7QUFDSixDQUFDO0FBRUQsS0FBSyxVQUFVLGNBQWMsQ0FBQyxNQUE0QixFQUFFLEtBQWU7SUFDekUsTUFBTSxJQUFJLEdBQW1EO1FBQzNELE1BQU0sRUFBRSxNQUFNO1FBQ2QsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksTUFBTTtRQUM5QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87UUFDdEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1FBQzFCLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSwwQkFBMEI7UUFDMUUsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjtRQUMxQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07UUFDcEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO0tBQ2pCLENBQUM7SUFFRixnQkFBUSxDQUFDLEdBQUcsQ0FBQyxtQ0FBbUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUV4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sR0FBRyxHQUFHO1FBQ1YsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1FBQzVCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtRQUNwQixNQUFNLEVBQUUsS0FBSztRQUNiLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRTtLQUN2RSxDQUFDO0lBRUYsTUFBTSxZQUFZLEdBQUc7UUFDbkIsUUFBUSxFQUFFLENBQUM7UUFDWCxLQUFLLEVBQUUsSUFBSTtLQUNaLENBQUM7SUFDRixNQUFNLFdBQVcsQ0FBQyxZQUFZLEVBQUUsZ0JBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVELEtBQUssVUFBVSxzQkFBc0IsQ0FBQyxPQUE2QixFQUFFLFlBQW9CO0lBQ3ZGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNmO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDWDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxHQUFHLE1BQWE7SUFDL0Msc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQVNELFNBQWdCLFdBQVcsQ0FBMEIsT0FBcUIsRUFBRSxFQUE0QjtJQUN0RyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUssRUFBRSxFQUFFO1FBQ3hCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDaEMsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUN2QixPQUFPLElBQUksRUFBRTtZQUNYLElBQUk7Z0JBQ0YsT0FBTyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2FBQ3hCO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsSUFBSSxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUU7b0JBQ25CLE1BQU0sQ0FBQyxDQUFDO2lCQUNUO2dCQUNELE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDVDtTQUNGO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQWhCRCxrQ0FnQkM7QUFFRCxLQUFLLFVBQVUsS0FBSyxDQUFDLEVBQVU7SUFDN0IsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zdCByZXNwOiBSZXNwb25zZSA9IHtcbiAgICAgIC4uLmV2ZW50LFxuICAgICAgUmVhc29uOiBleHRlcm5hbC5pbmNsdWRlU3RhY2tUcmFjZXMgPyBlLnN0YWNrIDogZS5tZXNzYWdlLFxuICAgIH07XG5cbiAgICBpZiAoIXJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICAvLyBzcGVjaWFsIGNhc2U6IGlmIENSRUFURSBmYWlscywgd2hpY2ggdXN1YWxseSBpbXBsaWVzLCB3ZSB1c3VhbGx5IGRvbid0XG4gICAgICAvLyBoYXZlIGEgcGh5c2ljYWwgcmVzb3VyY2UgaWQuIGluIHRoaXMgY2FzZSwgdGhlIHN1YnNlcXVlbnQgREVMRVRFXG4gICAgICAvLyBvcGVyYXRpb24gZG9lcyBub3QgaGF2ZSBhbnkgbWVhbmluZywgYW5kIHdpbGwgbGlrZWx5IGZhaWwgYXMgd2VsbC4gdG9cbiAgICAgIC8vIGFkZHJlc3MgdGhpcywgd2UgdXNlIGEgbWFya2VyIHNvIHRoZSBwcm92aWRlciBmcmFtZXdvcmsgY2FuIHNpbXBseVxuICAgICAgLy8gaWdub3JlIHRoZSBzdWJzZXF1ZW50IERFTEVURS5cbiAgICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICAgICAgZXh0ZXJuYWwubG9nKCdDUkVBVEUgZmFpbGVkLCByZXNwb25kaW5nIHdpdGggYSBtYXJrZXIgcGh5c2ljYWwgcmVzb3VyY2UgaWQgc28gdGhhdCB0aGUgc3Vic2VxdWVudCBERUxFVEUgd2lsbCBiZSBpZ25vcmVkJyk7XG4gICAgICAgIHJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkID0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvdGhlcndpc2UsIGlmIFBoeXNpY2FsUmVzb3VyY2VJZCBpcyBub3Qgc3BlY2lmaWVkLCBzb21ldGhpbmcgaXNcbiAgICAgICAgLy8gdGVycmlibHkgd3JvbmcgYmVjYXVzZSBhbGwgb3RoZXIgZXZlbnRzIHNob3VsZCBoYXZlIGFuIElELlxuICAgICAgICBleHRlcm5hbC5sb2coYEVSUk9SOiBNYWxmb3JtZWQgZXZlbnQuIFwiUGh5c2ljYWxSZXNvdXJjZUlkXCIgaXMgcmVxdWlyZWQ6ICR7SlNPTi5zdHJpbmdpZnkoZXZlbnQpfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoaXMgaXMgYW4gYWN0dWFsIGVycm9yLCBmYWlsIHRoZSBhY3Rpdml0eSBhbHRvZ2V0aGVyIGFuZCBleGlzdC5cbiAgICBhd2FpdCBzdWJtaXRSZXNwb25zZSgnRkFJTEVEJywgcmVzcCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyUmVzcG9uc2UoXG4gIGNmblJlcXVlc3Q6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQgJiB7IFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZyB9LFxuICBoYW5kbGVyUmVzcG9uc2U6IHZvaWQgfCBIYW5kbGVyUmVzcG9uc2UgPSB7IH0pOiBSZXNwb25zZSB7XG5cbiAgLy8gaWYgcGh5c2ljYWwgSUQgaXMgbm90IHJldHVybmVkLCB3ZSBoYXZlIHNvbWUgZGVmYXVsdHMgZm9yIHlvdSBiYXNlZFxuICAvLyBvbiB0aGUgcmVxdWVzdCB0eXBlLlxuICBjb25zdCBwaHlzaWNhbFJlc291cmNlSWQgPSBoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUmVxdWVzdElkO1xuXG4gIC8vIGlmIHdlIGFyZSBpbiBERUxFVEUgYW5kIHBoeXNpY2FsIElEIHdhcyBjaGFuZ2VkLCBpdCdzIGFuIGVycm9yLlxuICBpZiAoY2ZuUmVxdWVzdC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScgJiYgcGh5c2ljYWxSZXNvdXJjZUlkICE9PSBjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgREVMRVRFOiBjYW5ub3QgY2hhbmdlIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBmcm9tIFwiJHtjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZH1cIiB0byBcIiR7aGFuZGxlclJlc3BvbnNlLlBoeXNpY2FsUmVzb3VyY2VJZH1cIiBkdXJpbmcgZGVsZXRpb25gKTtcbiAgfVxuXG4gIC8vIG1lcmdlIHJlcXVlc3QgZXZlbnQgYW5kIHJlc3VsdCBldmVudCAocmVzdWx0IHByZXZhaWxzKS5cbiAgcmV0dXJuIHtcbiAgICAuLi5jZm5SZXF1ZXN0LFxuICAgIC4uLmhhbmRsZXJSZXNwb25zZSxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3VibWl0UmVzcG9uc2Uoc3RhdHVzOiAnU1VDQ0VTUycgfCAnRkFJTEVEJywgZXZlbnQ6IFJlc3BvbnNlKSB7XG4gIGNvbnN0IGpzb246IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2UgPSB7XG4gICAgU3RhdHVzOiBzdGF0dXMsXG4gICAgUmVhc29uOiBldmVudC5SZWFzb24gPz8gc3RhdHVzLFxuICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfHwgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIsXG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgIE5vRWNobzogZXZlbnQuTm9FY2hvLFxuICAgIERhdGE6IGV2ZW50LkRhdGEsXG4gIH07XG5cbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBqc29uKTtcblxuICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKGV2ZW50LlJlc3BvbnNlVVJMKTtcbiAgY29uc3QgcmVxID0ge1xuICAgIGhvc3RuYW1lOiBwYXJzZWRVcmwuaG9zdG5hbWUsXG4gICAgcGF0aDogcGFyc2VkVXJsLnBhdGgsXG4gICAgbWV0aG9kOiAnUFVUJyxcbiAgICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnJywgJ2NvbnRlbnQtbGVuZ3RoJzogcmVzcG9uc2VCb2R5Lmxlbmd0aCB9LFxuICB9O1xuXG4gIGNvbnN0IHJldHJ5T3B0aW9ucyA9IHtcbiAgICBhdHRlbXB0czogNSxcbiAgICBzbGVlcDogMTAwMCxcbiAgfTtcbiAgYXdhaXQgd2l0aFJldHJpZXMocmV0cnlPcHRpb25zLCBleHRlcm5hbC5zZW5kSHR0cFJlcXVlc3QpKHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59Il19 \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js new file mode 100644 index 0000000000000..9df94382cc74e --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js @@ -0,0 +1,118 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = exports.external = void 0; +const https = require("https"); +const url = require("url"); +// for unit tests +exports.external = { + sendHttpRequest: defaultSendHttpRequest, + log: defaultLog, + includeStackTraces: true, + userHandlerIndex: './index', +}; +const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; +const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; +async function handler(event, context) { + const sanitizedEvent = { ...event, ResponseURL: '...' }; + exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); + // ignore DELETE event when the physical resource ID is the marker that + // indicates that this DELETE is a subsequent DELETE to a failed CREATE + // operation. + if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { + exports.external.log('ignoring DELETE event caused by a failed CREATE event'); + await submitResponse('SUCCESS', event); + return; + } + try { + // invoke the user handler. this is intentionally inside the try-catch to + // ensure that if there is an error it's reported as a failure to + // cloudformation (otherwise cfn waits). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const userHandler = require(exports.external.userHandlerIndex).handler; + const result = await userHandler(sanitizedEvent, context); + // validate user response and create the combined event + const responseEvent = renderResponse(event, result); + // submit to cfn as success + await submitResponse('SUCCESS', responseEvent); + } + catch (e) { + const resp = { + ...event, + Reason: exports.external.includeStackTraces ? e.stack : e.message, + }; + if (!resp.PhysicalResourceId) { + // special case: if CREATE fails, which usually implies, we usually don't + // have a physical resource id. in this case, the subsequent DELETE + // operation does not have any meaning, and will likely fail as well. to + // address this, we use a marker so the provider framework can simply + // ignore the subsequent DELETE. + if (event.RequestType === 'Create') { + exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); + resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; + } + else { + // otherwise, if PhysicalResourceId is not specified, something is + // terribly wrong because all other events should have an ID. + exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); + } + } + // this is an actual error, fail the activity altogether and exist. + await submitResponse('FAILED', resp); + } +} +exports.handler = handler; +function renderResponse(cfnRequest, handlerResponse = {}) { + // if physical ID is not returned, we have some defaults for you based + // on the request type. + const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; + // if we are in DELETE and physical ID was changed, it's an error. + if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { + throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); + } + // merge request event and result event (result prevails). + return { + ...cfnRequest, + ...handlerResponse, + PhysicalResourceId: physicalResourceId, + }; +} +async function submitResponse(status, event) { + const json = { + Status: status, + Reason: event.Reason ?? status, + StackId: event.StackId, + RequestId: event.RequestId, + PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, + LogicalResourceId: event.LogicalResourceId, + NoEcho: event.NoEcho, + Data: event.Data, + }; + exports.external.log('submit response to cloudformation', json); + const responseBody = JSON.stringify(json); + const parsedUrl = url.parse(event.ResponseURL); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + await exports.external.sendHttpRequest(req, responseBody); +} +async function defaultSendHttpRequest(options, responseBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, _ => resolve()); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +function defaultLog(fmt, ...params) { + // eslint-disable-next-line no-console + console.log(fmt, ...params); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUQsdURBQXVEO1FBQ3ZELE1BQU0sYUFBYSxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFcEQsMkJBQTJCO1FBQzNCLE1BQU0sY0FBYyxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUMsQ0FBQztLQUNoRDtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1YsTUFBTSxJQUFJLEdBQWE7WUFDckIsR0FBRyxLQUFLO1lBQ1IsTUFBTSxFQUFFLGdCQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1NBQzFELENBQUM7UUFFRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzVCLHlFQUF5RTtZQUN6RSxtRUFBbUU7WUFDbkUsd0VBQXdFO1lBQ3hFLHFFQUFxRTtZQUNyRSxnQ0FBZ0M7WUFDaEMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEMsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsNEdBQTRHLENBQUMsQ0FBQztnQkFDM0gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdDQUFnQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLGtFQUFrRTtnQkFDbEUsNkRBQTZEO2dCQUM3RCxnQkFBUSxDQUFDLEdBQUcsQ0FBQyw2REFBNkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDcEc7U0FDRjtRQUVELG1FQUFtRTtRQUNuRSxNQUFNLGNBQWMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDdEM7QUFDSCxDQUFDO0FBbkRELDBCQW1EQztBQUVELFNBQVMsY0FBYyxDQUNyQixVQUF5RixFQUN6RixrQkFBMEMsRUFBRztJQUU3QyxzRUFBc0U7SUFDdEUsdUJBQXVCO0lBQ3ZCLE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDLGtCQUFrQixJQUFJLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDO0lBRXZILGtFQUFrRTtJQUNsRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLEtBQUssUUFBUSxJQUFJLGtCQUFrQixLQUFLLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRTtRQUMvRixNQUFNLElBQUksS0FBSyxDQUFDLHdEQUF3RCxVQUFVLENBQUMsa0JBQWtCLFNBQVMsZUFBZSxDQUFDLGtCQUFrQixtQkFBbUIsQ0FBQyxDQUFDO0tBQ3RLO0lBRUQsMERBQTBEO0lBQzFELE9BQU87UUFDTCxHQUFHLFVBQVU7UUFDYixHQUFHLGVBQWU7UUFDbEIsa0JBQWtCLEVBQUUsa0JBQWtCO0tBQ3ZDLENBQUM7QUFDSixDQUFDO0FBRUQsS0FBSyxVQUFVLGNBQWMsQ0FBQyxNQUE0QixFQUFFLEtBQWU7SUFDekUsTUFBTSxJQUFJLEdBQW1EO1FBQzNELE1BQU0sRUFBRSxNQUFNO1FBQ2QsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksTUFBTTtRQUM5QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87UUFDdEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1FBQzFCLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSwwQkFBMEI7UUFDMUUsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjtRQUMxQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07UUFDcEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO0tBQ2pCLENBQUM7SUFFRixnQkFBUSxDQUFDLEdBQUcsQ0FBQyxtQ0FBbUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUV4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sR0FBRyxHQUFHO1FBQ1YsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1FBQzVCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtRQUNwQixNQUFNLEVBQUUsS0FBSztRQUNiLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRTtLQUN2RSxDQUFDO0lBRUYsTUFBTSxnQkFBUSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUVELEtBQUssVUFBVSxzQkFBc0IsQ0FBQyxPQUE2QixFQUFFLFlBQW9CO0lBQ3ZGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNmO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDWDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxHQUFHLE1BQWE7SUFDL0Msc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCAqIGFzIHVybCBmcm9tICd1cmwnO1xuXG4vLyBmb3IgdW5pdCB0ZXN0c1xuZXhwb3J0IGNvbnN0IGV4dGVybmFsID0ge1xuICBzZW5kSHR0cFJlcXVlc3Q6IGRlZmF1bHRTZW5kSHR0cFJlcXVlc3QsXG4gIGxvZzogZGVmYXVsdExvZyxcbiAgaW5jbHVkZVN0YWNrVHJhY2VzOiB0cnVlLFxuICB1c2VySGFuZGxlckluZGV4OiAnLi9pbmRleCcsXG59O1xuXG5jb25zdCBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUiA9ICdBV1NDREs6OkN1c3RvbVJlc291cmNlUHJvdmlkZXJGcmFtZXdvcms6OkNSRUFURV9GQUlMRUQnO1xuY29uc3QgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpNSVNTSU5HX1BIWVNJQ0FMX0lEJztcblxuZXhwb3J0IHR5cGUgUmVzcG9uc2UgPSBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50ICYgSGFuZGxlclJlc3BvbnNlO1xuZXhwb3J0IHR5cGUgSGFuZGxlciA9IChldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpID0+IFByb21pc2U8SGFuZGxlclJlc3BvbnNlIHwgdm9pZD47XG5leHBvcnQgdHlwZSBIYW5kbGVyUmVzcG9uc2UgPSB1bmRlZmluZWQgfCB7XG4gIERhdGE/OiBhbnk7XG4gIFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZztcbiAgUmVhc29uPzogc3RyaW5nO1xuICBOb0VjaG8/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGNvbnN0IHNhbml0aXplZEV2ZW50ID0geyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH07XG4gIGV4dGVybmFsLmxvZyhKU09OLnN0cmluZ2lmeShzYW5pdGl6ZWRFdmVudCwgdW5kZWZpbmVkLCAyKSk7XG5cbiAgLy8gaWdub3JlIERFTEVURSBldmVudCB3aGVuIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBpcyB0aGUgbWFya2VyIHRoYXRcbiAgLy8gaW5kaWNhdGVzIHRoYXQgdGhpcyBERUxFVEUgaXMgYSBzdWJzZXF1ZW50IERFTEVURSB0byBhIGZhaWxlZCBDUkVBVEVcbiAgLy8gb3BlcmF0aW9uLlxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnICYmIGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCA9PT0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIpIHtcbiAgICBleHRlcm5hbC5sb2coJ2lnbm9yaW5nIERFTEVURSBldmVudCBjYXVzZWQgYnkgYSBmYWlsZWQgQ1JFQVRFIGV2ZW50Jyk7XG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCBldmVudCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBpbnZva2UgdGhlIHVzZXIgaGFuZGxlci4gdGhpcyBpcyBpbnRlbnRpb25hbGx5IGluc2lkZSB0aGUgdHJ5LWNhdGNoIHRvXG4gICAgLy8gZW5zdXJlIHRoYXQgaWYgdGhlcmUgaXMgYW4gZXJyb3IgaXQncyByZXBvcnRlZCBhcyBhIGZhaWx1cmUgdG9cbiAgICAvLyBjbG91ZGZvcm1hdGlvbiAob3RoZXJ3aXNlIGNmbiB3YWl0cykuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCB1c2VySGFuZGxlcjogSGFuZGxlciA9IHJlcXVpcmUoZXh0ZXJuYWwudXNlckhhbmRsZXJJbmRleCkuaGFuZGxlcjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB1c2VySGFuZGxlcihzYW5pdGl6ZWRFdmVudCwgY29udGV4dCk7XG5cbiAgICAvLyB2YWxpZGF0ZSB1c2VyIHJlc3BvbnNlIGFuZCBjcmVhdGUgdGhlIGNvbWJpbmVkIGV2ZW50XG4gICAgY29uc3QgcmVzcG9uc2VFdmVudCA9IHJlbmRlclJlc3BvbnNlKGV2ZW50LCByZXN1bHQpO1xuXG4gICAgLy8gc3VibWl0IHRvIGNmbiBhcyBzdWNjZXNzXG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCByZXNwb25zZUV2ZW50KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnN0IHJlc3A6IFJlc3BvbnNlID0ge1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBSZWFzb246IGV4dGVybmFsLmluY2x1ZGVTdGFja1RyYWNlcyA/IGUuc3RhY2sgOiBlLm1lc3NhZ2UsXG4gICAgfTtcblxuICAgIGlmICghcmVzcC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogaWYgQ1JFQVRFIGZhaWxzLCB3aGljaCB1c3VhbGx5IGltcGxpZXMsIHdlIHVzdWFsbHkgZG9uJ3RcbiAgICAgIC8vIGhhdmUgYSBwaHlzaWNhbCByZXNvdXJjZSBpZC4gaW4gdGhpcyBjYXNlLCB0aGUgc3Vic2VxdWVudCBERUxFVEVcbiAgICAgIC8vIG9wZXJhdGlvbiBkb2VzIG5vdCBoYXZlIGFueSBtZWFuaW5nLCBhbmQgd2lsbCBsaWtlbHkgZmFpbCBhcyB3ZWxsLiB0b1xuICAgICAgLy8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYSBtYXJrZXIgc28gdGhlIHByb3ZpZGVyIGZyYW1ld29yayBjYW4gc2ltcGx5XG4gICAgICAvLyBpZ25vcmUgdGhlIHN1YnNlcXVlbnQgREVMRVRFLlxuICAgICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgICAgICBleHRlcm5hbC5sb2coJ0NSRUFURSBmYWlsZWQsIHJlc3BvbmRpbmcgd2l0aCBhIG1hcmtlciBwaHlzaWNhbCByZXNvdXJjZSBpZCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IERFTEVURSB3aWxsIGJlIGlnbm9yZWQnKTtcbiAgICAgICAgcmVzcC5QaHlzaWNhbFJlc291cmNlSWQgPSBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG90aGVyd2lzZSwgaWYgUGh5c2ljYWxSZXNvdXJjZUlkIGlzIG5vdCBzcGVjaWZpZWQsIHNvbWV0aGluZyBpc1xuICAgICAgICAvLyB0ZXJyaWJseSB3cm9uZyBiZWNhdXNlIGFsbCBvdGhlciBldmVudHMgc2hvdWxkIGhhdmUgYW4gSUQuXG4gICAgICAgIGV4dGVybmFsLmxvZyhgRVJST1I6IE1hbGZvcm1lZCBldmVudC4gXCJQaHlzaWNhbFJlc291cmNlSWRcIiBpcyByZXF1aXJlZDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBpcyBhbiBhY3R1YWwgZXJyb3IsIGZhaWwgdGhlIGFjdGl2aXR5IGFsdG9nZXRoZXIgYW5kIGV4aXN0LlxuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdGQUlMRUQnLCByZXNwKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSZXNwb25zZShcbiAgY2ZuUmVxdWVzdDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIHsgUGh5c2ljYWxSZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gIGhhbmRsZXJSZXNwb25zZTogdm9pZCB8IEhhbmRsZXJSZXNwb25zZSA9IHsgfSk6IFJlc3BvbnNlIHtcblxuICAvLyBpZiBwaHlzaWNhbCBJRCBpcyBub3QgcmV0dXJuZWQsIHdlIGhhdmUgc29tZSBkZWZhdWx0cyBmb3IgeW91IGJhc2VkXG4gIC8vIG9uIHRoZSByZXF1ZXN0IHR5cGUuXG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGhhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5SZXF1ZXN0SWQ7XG5cbiAgLy8gaWYgd2UgYXJlIGluIERFTEVURSBhbmQgcGh5c2ljYWwgSUQgd2FzIGNoYW5nZWQsIGl0J3MgYW4gZXJyb3IuXG4gIGlmIChjZm5SZXF1ZXN0LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBwaHlzaWNhbFJlc291cmNlSWQgIT09IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBERUxFVEU6IGNhbm5vdCBjaGFuZ2UgdGhlIHBoeXNpY2FsIHJlc291cmNlIElEIGZyb20gXCIke2NmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIHRvIFwiJHtoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIGR1cmluZyBkZWxldGlvbmApO1xuICB9XG5cbiAgLy8gbWVyZ2UgcmVxdWVzdCBldmVudCBhbmQgcmVzdWx0IGV2ZW50IChyZXN1bHQgcHJldmFpbHMpLlxuICByZXR1cm4ge1xuICAgIC4uLmNmblJlcXVlc3QsXG4gICAgLi4uaGFuZGxlclJlc3BvbnNlLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdWJtaXRSZXNwb25zZShzdGF0dXM6ICdTVUNDRVNTJyB8ICdGQUlMRUQnLCBldmVudDogUmVzcG9uc2UpIHtcbiAgY29uc3QganNvbjogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSA9IHtcbiAgICBTdGF0dXM6IHN0YXR1cyxcbiAgICBSZWFzb246IGV2ZW50LlJlYXNvbiA/PyBzdGF0dXMsXG4gICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBNSVNTSU5HX1BIWVNJQ0FMX0lEX01BUktFUixcbiAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgTm9FY2hvOiBldmVudC5Ob0VjaG8sXG4gICAgRGF0YTogZXZlbnQuRGF0YSxcbiAgfTtcblxuICBleHRlcm5hbC5sb2coJ3N1Ym1pdCByZXNwb25zZSB0byBjbG91ZGZvcm1hdGlvbicsIGpzb24pO1xuXG4gIGNvbnN0IHJlc3BvbnNlQm9keSA9IEpTT04uc3RyaW5naWZ5KGpzb24pO1xuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICBjb25zdCByZXEgPSB7XG4gICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICBwYXRoOiBwYXJzZWRVcmwucGF0aCxcbiAgICBtZXRob2Q6ICdQVVQnLFxuICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gIH07XG5cbiAgYXdhaXQgZXh0ZXJuYWwuc2VuZEh0dHBSZXF1ZXN0KHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts new file mode 100644 index 0000000000000..3554dc94d4617 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts @@ -0,0 +1 @@ +export declare function handler(event: AWSLambda.CloudFormationCustomResourceEvent): Promise; diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.js similarity index 100% rename from packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js rename to packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.js diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts new file mode 100644 index 0000000000000..2459d44ab1d18 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts @@ -0,0 +1,82 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { S3 } from 'aws-sdk'; + +const AUTO_DELETE_OBJECTS_TAG = 'aws-cdk:auto-delete-objects'; + +const s3 = new S3(); + +export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent) { + switch (event.RequestType) { + case 'Create': + return; + case 'Update': + return onUpdate(event); + case 'Delete': + return onDelete(event.ResourceProperties?.BucketName); + } +} + +async function onUpdate(event: AWSLambda.CloudFormationCustomResourceEvent) { + const updateEvent = event as AWSLambda.CloudFormationCustomResourceUpdateEvent; + const oldBucketName = updateEvent.OldResourceProperties?.BucketName; + const newBucketName = updateEvent.ResourceProperties?.BucketName; + const bucketNameHasChanged = newBucketName != null && oldBucketName != null && newBucketName !== oldBucketName; + + /* If the name of the bucket has changed, CloudFormation will try to delete the bucket + and create a new one with the new name. So we have to delete the contents of the + bucket so that this operation does not fail. */ + if (bucketNameHasChanged) { + return onDelete(oldBucketName); + } +} + +/** + * Recursively delete all items in the bucket + * + * @param bucketName the bucket name + */ +async function emptyBucket(bucketName: string) { + const listedObjects = await s3.listObjectVersions({ Bucket: bucketName }).promise(); + const contents = [...listedObjects.Versions ?? [], ...listedObjects.DeleteMarkers ?? []]; + if (contents.length === 0) { + return; + } + + const records = contents.map((record: any) => ({ Key: record.Key, VersionId: record.VersionId })); + await s3.deleteObjects({ Bucket: bucketName, Delete: { Objects: records } }).promise(); + + if (listedObjects?.IsTruncated) { + await emptyBucket(bucketName); + } +} + +async function onDelete(bucketName?: string) { + if (!bucketName) { + throw new Error('No BucketName was provided.'); + } + if (!await isBucketTaggedForDeletion(bucketName)) { + process.stdout.write(`Bucket does not have '${AUTO_DELETE_OBJECTS_TAG}' tag, skipping cleaning.\n`); + return; + } + try { + await emptyBucket(bucketName); + } catch (e) { + if (e.code !== 'NoSuchBucket') { + throw e; + } + // Bucket doesn't exist. Ignoring + } +} + +/** + * The bucket will only be tagged for deletion if it's being deleted in the same + * deployment as this Custom Resource. + * + * If the Custom Resource is every deleted before the bucket, it must be because + * `autoDeleteObjects` has been switched to false, in which case the tag would have + * been removed before we get to this Delete event. + */ +async function isBucketTaggedForDeletion(bucketName: string) { + const response = await s3.getBucketTagging({ Bucket: bucketName }).promise(); + return response.TagSet.some(tag => tag.Key === AUTO_DELETE_OBJECTS_TAG && tag.Value === 'true'); +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js similarity index 75% rename from packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js rename to packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js index 6bee1ced2a9b7..ba956d47f51fe 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js @@ -1,3 +1,4 @@ +"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; @@ -25,9 +26,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru // lib/assertions/providers/lambda-handler/index.ts var lambda_handler_exports = {}; __export(lambda_handler_exports, { - handler: () => handler, - isComplete: () => isComplete, - onTimeout: () => onTimeout + handler: () => handler }); module.exports = __toCommonJS(lambda_handler_exports); @@ -387,7 +386,6 @@ var StringLikeRegexpMatch = class extends Matcher { // lib/assertions/providers/lambda-handler/base.ts var https = __toESM(require("https")); var url = __toESM(require("url")); -var AWS = __toESM(require("aws-sdk")); var CustomResourceHandler = class { constructor(event, context) { this.event = event; @@ -406,40 +404,20 @@ var CustomResourceHandler = class { } async handle() { try { - if ("stateMachineArn" in this.event.ResourceProperties) { - const req = { - stateMachineArn: this.event.ResourceProperties.stateMachineArn, - name: this.event.RequestId, - input: JSON.stringify(this.event) - }; - await this.startExecution(req); - return; - } else { - const response = await this.processEvent(this.event.ResourceProperties); - return response; - } - } catch (e) { - console.log(e); - throw e; - } finally { - clearTimeout(this.timeout); - } - } - async handleIsComplete() { - try { - const result = await this.processEvent(this.event.ResourceProperties); - return result; + console.log(`Event: ${JSON.stringify({ ...this.event, ResponseURL: "..." })}`); + const response = await this.processEvent(this.event.ResourceProperties); + console.log(`Event output : ${JSON.stringify(response)}`); + await this.respond({ + status: "SUCCESS", + reason: "OK", + data: response + }); } catch (e) { console.log(e); - return; - } finally { - clearTimeout(this.timeout); - } - } - async startExecution(req) { - try { - const sfn = new AWS.StepFunctions(); - await sfn.startExecution(req).promise(); + await this.respond({ + status: "FAILED", + reason: e.message ?? "Internal Error" + }); } finally { clearTimeout(this.timeout); } @@ -475,8 +453,6 @@ var CustomResourceHandler = class { request2.end(); } catch (e) { reject(e); - } finally { - clearTimeout(this.timeout); } }); } @@ -503,8 +479,7 @@ var AssertionHandler = class extends CustomResourceHandler { matchResult.finished(); if (matchResult.hasFailed()) { result = { - failed: true, - assertion: JSON.stringify({ + data: JSON.stringify({ status: "fail", message: [ ...matchResult.toHumanStrings(), @@ -513,11 +488,11 @@ var AssertionHandler = class extends CustomResourceHandler { }) }; if (request2.failDeployment) { - throw new Error(result.assertion); + throw new Error(result.data); } } else { result = { - assertion: JSON.stringify({ + data: JSON.stringify({ status: "success" }) }; @@ -587,10 +562,7 @@ function flatten(object) { {}, ...function _flatten(child, path = []) { return [].concat(...Object.keys(child).map((key) => { - let childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; - if (typeof childKey === "string") { - childKey = isJsonString(childKey); - } + const childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; return typeof childKey === "object" && childKey !== null ? _flatten(childKey, path.concat([key])) : { [path.concat([key]).join(".")]: childKey }; })); }(object) @@ -598,12 +570,9 @@ function flatten(object) { } var AwsApiCallHandler = class extends CustomResourceHandler { async processEvent(request2) { - const AWS2 = require("aws-sdk"); - console.log(`AWS SDK VERSION: ${AWS2.VERSION}`); - if (!Object.prototype.hasOwnProperty.call(AWS2, request2.service)) { - throw Error(`Service ${request2.service} does not exist in AWS SDK version ${AWS2.VERSION}.`); - } - const service = new AWS2[request2.service](); + const AWS = require("aws-sdk"); + console.log(`AWS SDK VERSION: ${AWS.VERSION}`); + const service = new AWS[request2.service](); const response = await service[request2.api](request2.parameters && decode(request2.parameters)).promise(); console.log(`SDK response received ${JSON.stringify(response)}`); delete response.ResponseMetadata; @@ -613,18 +582,9 @@ var AwsApiCallHandler = class extends CustomResourceHandler { const flatData = { ...flatten(respond) }; - const resp = request2.flattenResponse === "true" ? flatData : respond; - console.log(`Returning result ${JSON.stringify(resp)}`); - return resp; + return request2.flattenResponse === "true" ? flatData : respond; } }; -function isJsonString(value) { - try { - return JSON.parse(value); - } catch { - return value; - } -} // lib/assertions/providers/lambda-handler/types.ts var ASSERT_RESOURCE_TYPE = "Custom::DeployAssert@AssertEquals"; @@ -632,136 +592,21 @@ var SDK_RESOURCE_TYPE_PREFIX = "Custom::DeployAssert@SdkCall"; // lib/assertions/providers/lambda-handler/index.ts async function handler(event, context) { - console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); - const provider = createResourceHandler(event, context); - try { - if (event.RequestType === "Delete") { - await provider.respond({ - status: "SUCCESS", - reason: "OK" - }); - return; - } - const result = await provider.handle(); - if ("stateMachineArn" in event.ResourceProperties) { - console.info('Found "stateMachineArn", waiter statemachine started'); - return; - } else if ("expected" in event.ResourceProperties) { - console.info('Found "expected", testing assertions'); - const actualPath = event.ResourceProperties.actualPath; - const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; - const assertion = new AssertionHandler({ - ...event, - ResourceProperties: { - ServiceToken: event.ServiceToken, - actual, - expected: event.ResourceProperties.expected - } - }, context); - try { - const assertionResult = await assertion.handle(); - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: { - ...assertionResult, - ...result - } - }); - return; - } catch (e) { - await provider.respond({ - status: "FAILED", - reason: e.message ?? "Internal Error" - }); - return; - } - } - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: result - }); - } catch (e) { - await provider.respond({ - status: "FAILED", - reason: e.message ?? "Internal Error" - }); - return; - } - return; -} -async function onTimeout(timeoutEvent) { - const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage); - const provider = createResourceHandler(isCompleteRequest, standardContext); - await provider.respond({ - status: "FAILED", - reason: "Operation timed out: " + JSON.stringify(isCompleteRequest) - }); -} -async function isComplete(event, context) { - console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); const provider = createResourceHandler(event, context); - try { - const result = await provider.handleIsComplete(); - const actualPath = event.ResourceProperties.actualPath; - if (result) { - const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; - if ("expected" in event.ResourceProperties) { - const assertion = new AssertionHandler({ - ...event, - ResourceProperties: { - ServiceToken: event.ServiceToken, - actual, - expected: event.ResourceProperties.expected - } - }, context); - const assertionResult = await assertion.handleIsComplete(); - if (!(assertionResult == null ? void 0 : assertionResult.failed)) { - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: { - ...assertionResult, - ...result - } - }); - return; - } else { - console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`); - throw new Error(JSON.stringify(event)); - } - } - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: result - }); - } else { - console.log("No result"); - throw new Error(JSON.stringify(event)); - } - return; - } catch (e) { - console.log(e); - throw new Error(JSON.stringify(event)); - } + await provider.handle(); } function createResourceHandler(event, context) { if (event.ResourceType.startsWith(SDK_RESOURCE_TYPE_PREFIX)) { return new AwsApiCallHandler(event, context); - } else if (event.ResourceType.startsWith(ASSERT_RESOURCE_TYPE)) { - return new AssertionHandler(event, context); - } else { - throw new Error(`Unsupported resource type "${event.ResourceType}`); + } + switch (event.ResourceType) { + case ASSERT_RESOURCE_TYPE: + return new AssertionHandler(event, context); + default: + throw new Error(`Unsupported resource type "${event.ResourceType}`); } } -var standardContext = { - getRemainingTimeInMillis: () => 9e4 -}; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { - handler, - isComplete, - onTimeout + handler }); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json index 773077597be42..a114baf10c235 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json @@ -1,6 +1,12 @@ { "version": "21.0.0", "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, "FlowLogsFeatureFlag.assets": { "type": "cdk:asset-manifest", "properties": { @@ -17,7 +23,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -204,10 +210,7 @@ "/FlowLogsFeatureFlag/VPC/FlowLogsS3WithDestinationOptions/FlowLog": [ { "type": "aws:cdk:logicalId", - "data": "VPCFlowLogsS3WithDestinationOptionsFlowLog030C15B2", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "VPCFlowLogsS3WithDestinationOptionsFlowLog030C15B2" } ], "/FlowLogsFeatureFlag/Exports/Output{\"Fn::GetAtt\":[\"VPCFlowLogsS3BucketFB7DC2BE\",\"Arn\"]}": [ @@ -283,7 +286,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -546,7 +549,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -601,12 +604,6 @@ ] }, "displayName": "FlowLogs/DefaultTest/DeployAssert" - }, - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json index f6e0ef7c83ea9..9a0ff6b79a4b7 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json @@ -4,6 +4,14 @@ "id": "App", "path": "", "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.123" + } + }, "FlowLogsFeatureFlag": { "id": "FlowLogsFeatureFlag", "path": "FlowLogsFeatureFlag", @@ -819,6 +827,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -831,8 +840,7 @@ "key": "Name", "value": "FlowLogsFeatureFlag/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -1020,10 +1028,11 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "destinationOptions": { "fileFormat": "plain-text", - "hiveCompatiblePartitions": true, - "perHourPartition": false + "perHourPartition": false, + "hiveCompatiblePartitions": true }, "logDestination": { "Fn::GetAtt": [ @@ -1037,8 +1046,7 @@ "key": "Name", "value": "FlowLogsFeatureFlag/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -1081,7 +1089,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } }, "FlowLogsInstance": { @@ -1132,14 +1140,6 @@ "id": "InstanceRole", "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole", "children": { - "ImportInstanceRole": { - "id": "ImportInstanceRole", - "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole/ImportInstanceRole", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, "Resource": { "id": "Resource", "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole/Resource", @@ -1264,22 +1264,6 @@ "fqn": "@aws-cdk/core.Resource", "version": "0.0.0" } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogsFeatureFlag/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogsFeatureFlag/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" - } } }, "constructInfo": { @@ -2102,6 +2086,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -2114,8 +2099,7 @@ "key": "Name", "value": "FlowLogsTestStack/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -2143,6 +2127,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::Join": [ "", @@ -2163,8 +2148,7 @@ "key": "Name", "value": "FlowLogsTestStack/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -2192,14 +2176,6 @@ "id": "IAMRole", "path": "FlowLogsTestStack/FlowLogsCW/IAMRole", "children": { - "ImportIAMRole": { - "id": "ImportIAMRole", - "path": "FlowLogsTestStack/FlowLogsCW/IAMRole/ImportIAMRole", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, "Resource": { "id": "Resource", "path": "FlowLogsTestStack/FlowLogsCW/IAMRole/Resource", @@ -2323,6 +2299,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "deliverLogsPermissionArn": { "Fn::GetAtt": [ "FlowLogsCWIAMRole017AD736", @@ -2332,8 +2309,7 @@ "logDestinationType": "cloud-watch-logs", "logGroupName": { "Ref": "FlowLogsCWLogGroup0398E8F8" - }, - "trafficType": "ALL" + } } }, "constructInfo": { @@ -2616,22 +2592,6 @@ "fqn": "@aws-cdk/core.CustomResourceProvider", "version": "0.0.0" } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogsTestStack/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogsTestStack/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" - } } }, "constructInfo": { @@ -2652,7 +2612,7 @@ "path": "FlowLogs/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } }, "DeployAssert": { @@ -2672,7 +2632,7 @@ "path": "FlowLogs/DefaultTest/DeployAssert/AwsApiCallS3listObjectsV2/SdkProvider/AssertionsProvider", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } } }, @@ -2744,23 +2704,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" - } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogs/DefaultTest/DeployAssert/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogs/DefaultTest/DeployAssert/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" + "version": "10.1.123" } } }, @@ -2780,14 +2724,6 @@ "fqn": "@aws-cdk/integ-tests.IntegTest", "version": "0.0.0" } - }, - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.161" - } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts index 7a068377feffb..5b16d80caf50d 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts @@ -93,9 +93,9 @@ describe('vpc flow logs', () => { TrafficType: 'ALL', ResourceId: 'eni-123456', DestinationOptions: { - HiveCompatiblePartitions: true, - FileFormat: 'plain-text', - PerHourPartition: false, + hiveCompatiblePartitions: true, + fileFormat: 'plain-text', + perHourPartition: false, }, LogDestination: { 'Fn::GetAtt': [ diff --git a/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts b/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts index 7136bd3d267a7..7d0804aa3367a 100644 --- a/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts +++ b/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts @@ -232,9 +232,9 @@ export class AccessPoint extends AccessPointBase { { actions: ['GetObject'], contentTransformation: { - awsLambda: { - functionArn: props.handler.functionArn, - functionPayload: props.payload ? JSON.stringify(props.payload) : undefined, + AwsLambda: { + FunctionArn: props.handler.functionArn, + FunctionPayload: props.payload ? JSON.stringify(props.payload) : undefined, }, }, }, diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json new file mode 100644 index 0000000000000..237e302807756 --- /dev/null +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json @@ -0,0 +1,961 @@ +{ + "ResourceTypes": { + "AWS::Backup::ReportPlan": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ReportDeliveryChannel/Type" + }, + { + "op": "add", + "path": "/Properties/ReportDeliveryChannel/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/ReportSetting/Type" + }, + { + "op": "add", + "path": "/Properties/ReportSetting/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::CloudFormation::StackSet": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ManagedExecution/Type" + }, + { + "op": "add", + "path": "/Properties/ManagedExecution/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::CodeGuruProfiler::ProfilingGroup": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AgentPermissions/Type" + }, + { + "op": "add", + "path": "/Properties/AgentPermissions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Config::ConformancePack": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/TemplateSSMDocumentDetails/Type" + }, + { + "op": "add", + "path": "/Properties/TemplateSSMDocumentDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Connect::TaskTemplate": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Constraints/Type" + }, + { + "op": "add", + "path": "/Properties/Constraints/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::FlowLog": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DestinationOptions/Type" + }, + { + "op": "add", + "path": "/Properties/DestinationOptions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::Subnet": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/PrivateDnsNameOptionsOnLaunch/Type" + }, + { + "op": "add", + "path": "/Properties/PrivateDnsNameOptionsOnLaunch/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayAttachment": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayMulticastDomain": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayVpcAttachment": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::ECR::PublicRepository": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RepositoryCatalogData/Type" + }, + { + "op": "add", + "path": "/Properties/RepositoryCatalogData/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::ElastiCache::User": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AuthenticationMode/Type" + }, + { + "op": "add", + "path": "/Properties/AuthenticationMode/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Forecast::Dataset": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/EncryptionConfig/Type" + }, + { + "op": "add", + "path": "/Properties/EncryptionConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Schema/Type" + }, + { + "op": "add", + "path": "/Properties/Schema/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoT::JobTemplate": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AbortConfig/Type" + }, + { + "op": "add", + "path": "/Properties/AbortConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/JobExecutionsRolloutConfig/Type" + }, + { + "op": "add", + "path": "/Properties/JobExecutionsRolloutConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/PresignedUrlConfig/Type" + }, + { + "op": "add", + "path": "/Properties/PresignedUrlConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/TimeoutConfig/Type" + }, + { + "op": "add", + "path": "/Properties/TimeoutConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTCoreDeviceAdvisor::SuiteDefinition": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SuiteDefinitionConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/SuiteDefinitionConfiguration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTSiteWise::Portal": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Alarms/Type" + }, + { + "op": "add", + "path": "/Properties/Alarms/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTWireless::NetworkAnalyzerConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/TraceContent/Type" + }, + { + "op": "add", + "path": "/Properties/TraceContent/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::Bot": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataPrivacy/Type" + }, + { + "op": "add", + "path": "/Properties/DataPrivacy/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::BotAlias": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SentimentAnalysisSettings/Type" + }, + { + "op": "add", + "path": "/Properties/SentimentAnalysisSettings/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::LookoutEquipment::InferenceScheduler": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataInputConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/DataInputConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/DataOutputConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/DataOutputConfiguration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::MemoryDB::User": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AuthenticationMode/Type" + }, + { + "op": "add", + "path": "/Properties/AuthenticationMode/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Redshift::EndpointAccess": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/VpcEndpoint/Type" + }, + { + "op": "add", + "path": "/Properties/VpcEndpoint/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Route53::HealthCheck": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/HealthCheckConfig/Type" + }, + { + "op": "add", + "path": "/Properties/HealthCheckConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3::AccessPoint": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/PolicyStatus/Type" + }, + { + "op": "add", + "path": "/Properties/PolicyStatus/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::FeatureGroup": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/OfflineStoreConfig/Type" + }, + { + "op": "add", + "path": "/Properties/OfflineStoreConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/OnlineStoreConfig/Type" + }, + { + "op": "add", + "path": "/Properties/OnlineStoreConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::Pipeline": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ParallelismConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/ParallelismConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/PipelineDefinition/Type" + }, + { + "op": "add", + "path": "/Properties/PipelineDefinition/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::Project": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ServiceCatalogProvisioningDetails/Type" + }, + { + "op": "add", + "path": "/Properties/ServiceCatalogProvisioningDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Transfer::Connector": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/As2Config/Type" + }, + { + "op": "add", + "path": "/Properties/As2Config/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::LoggingConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/LoggingFilter/Type" + }, + { + "op": "add", + "path": "/Properties/LoggingFilter/PrimitiveType", + "value": "Json" + } + ] + } + } + }, + "PropertyTypes": { + "AWS::Backup::BackupSelection.BackupSelectionResourceType": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Conditions/Type" + }, + { + "op": "add", + "path": "/Properties/Conditions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Backup::Framework.FrameworkControl": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ControlScope/Type" + }, + { + "op": "add", + "path": "/Properties/ControlScope/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::DataBrew::Recipe.RecipeParameters": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Input/Type" + }, + { + "op": "add", + "path": "/Properties/Input/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::FIS::ExperimentTemplate.ExperimentTemplateLogConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/CloudWatchLogsConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/CloudWatchLogsConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/S3Configuration/Type" + }, + { + "op": "add", + "path": "/Properties/S3Configuration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::GreengrassV2::Deployment.IoTJobRateIncreaseCriteria": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties" + }, + { + "op": "add", + "path": "/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::ComponentType.DataValue": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RelationshipValue/Type" + }, + { + "op": "add", + "path": "/Properties/RelationshipValue/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.DataValue": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RelationshipValue/Type" + }, + { + "op": "add", + "path": "/Properties/RelationshipValue/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.Property": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Definition/Type" + }, + { + "op": "add", + "path": "/Properties/Definition/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.Status": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Error/Type" + }, + { + "op": "add", + "path": "/Properties/Error/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::Bot.TestBotAliasSettings": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SentimentAnalysisSettings/Type" + }, + { + "op": "add", + "path": "/Properties/SentimentAnalysisSettings/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Personalize::Dataset.DatasetImportJob": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataSource/Type" + }, + { + "op": "add", + "path": "/Properties/DataSource/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Personalize::Solution.SolutionConfig": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AutoMLConfig/Type" + }, + { + "op": "add", + "path": "/Properties/AutoMLConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/HpoConfig/Type" + }, + { + "op": "add", + "path": "/Properties/HpoConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3ObjectLambda::AccessPoint.TransformationConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ContentTransformation/Type" + }, + { + "op": "add", + "path": "/Properties/ContentTransformation/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3Outposts::Bucket.Rule": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Filter/Type" + }, + { + "op": "add", + "path": "/Properties/Filter/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::ModelPackage.ModelPackageContainerDefinition": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ModelInput/Type" + }, + { + "op": "add", + "path": "/Properties/ModelInput/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Transfer::Workflow.WorkflowStep": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/CopyStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/CopyStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/CustomStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/CustomStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/DeleteStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/DeleteStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/TagStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/TagStepDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::LoggingConfiguration.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/JsonBody/Type" + }, + { + "op": "add", + "path": "/Properties/JsonBody/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::RuleGroup.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SingleQueryArgument/Type" + }, + { + "op": "add", + "path": "/Properties/SingleQueryArgument/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::RuleGroup.RuleAction": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Allow/Type" + }, + { + "op": "add", + "path": "/Properties/Allow/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Block/Type" + }, + { + "op": "add", + "path": "/Properties/Block/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Captcha/Type" + }, + { + "op": "add", + "path": "/Properties/Captcha/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Count/Type" + }, + { + "op": "add", + "path": "/Properties/Count/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::WebACL.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SingleQueryArgument/Type" + }, + { + "op": "add", + "path": "/Properties/SingleQueryArgument/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + } + } +} diff --git a/packages/awslint/lib/rules/resource.ts b/packages/awslint/lib/rules/resource.ts index 95894c847f71d..e7478a811fa57 100644 --- a/packages/awslint/lib/rules/resource.ts +++ b/packages/awslint/lib/rules/resource.ts @@ -189,7 +189,6 @@ resourceLinter.add({ // This rule is the worst resourceLinter.add({ code: 'resource-attribute', - warning: true, message: 'resources must represent all cloudformation attributes as attribute properties. ' + '"@attribute ATTR[,ATTR]" can be used to tag non-standard attribute names. ' + From dbea975fa67dc3f0cef6d988242c8c0b7059aab6 Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Fri, 23 Dec 2022 09:25:56 -0800 Subject: [PATCH 19/22] chore(release): 2.56.1 --- CHANGELOG.v2.alpha.md | 2 ++ CHANGELOG.v2.md | 7 +++++++ version.v2.json | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.v2.alpha.md b/CHANGELOG.v2.alpha.md index ff189964a3eb8..5c0234bdf43a5 100644 --- a/CHANGELOG.v2.alpha.md +++ b/CHANGELOG.v2.alpha.md @@ -2,6 +2,8 @@ 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. +## [2.56.1-alpha.0](https://github.com/aws/aws-cdk/compare/v2.56.0-alpha.0...v2.56.1-alpha.0) (2022-12-23) + ## [2.56.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.55.1-alpha.0...v2.56.0-alpha.0) (2022-12-21) diff --git a/CHANGELOG.v2.md b/CHANGELOG.v2.md index 2550d9751f759..627dbdbf84728 100644 --- a/CHANGELOG.v2.md +++ b/CHANGELOG.v2.md @@ -2,6 +2,13 @@ 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. +## [2.56.1](https://github.com/aws/aws-cdk/compare/v2.56.0...v2.56.1) (2022-12-23) + + +### Bug Fixes + +* **cfnspec:** v101.0.0 introduced specific types on several types that previously were typed as json ([#23448](https://github.com/aws/aws-cdk/issues/23448)) ([1b4e3a4](https://github.com/aws/aws-cdk/commit/1b4e3a4b503d5d08e976ccf245c20f4430bcba46)) + ## [2.56.0](https://github.com/aws/aws-cdk/compare/v2.55.1...v2.56.0) (2022-12-21) diff --git a/version.v2.json b/version.v2.json index a95bf59fb520b..1484929ef453e 100644 --- a/version.v2.json +++ b/version.v2.json @@ -1,4 +1,4 @@ { - "version": "2.56.0", - "alphaVersion": "2.56.0-alpha.0" + "version": "2.56.1", + "alphaVersion": "2.56.1-alpha.0" } \ No newline at end of file From 861774b0960ba1488d6d77461f61474f04ecc474 Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Fri, 23 Dec 2022 18:37:08 +0100 Subject: [PATCH 20/22] refactor(route53): favor `grant` method over precreated role (#23083) `PublicHostedZone` allows creating exactly one role for cross-account delegation. Because of limitations of trust policy size, some teams inside Amazon are creating a role per opt-in region, in which case the "one precreated role" feature doesn't help at all. Instead, add a `grantDelegation()` helper which works for both cases. ---- *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-iam/lib/grant.ts | 54 +++++++++++++++- packages/@aws-cdk/aws-iam/test/grant.test.ts | 34 +++++++++- packages/@aws-cdk/aws-route53/README.md | 13 +++- .../@aws-cdk/aws-route53/lib/hosted-zone.ts | 26 ++++++++ .../aws-route53/test/hosted-zone.test.ts | 62 ++++++++++++++++++- .../aws-route53/test/record-set.test.ts | 13 ++-- 6 files changed, 185 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-iam/lib/grant.ts b/packages/@aws-cdk/aws-iam/lib/grant.ts index c611fa6152255..0056f000db052 100644 --- a/packages/@aws-cdk/aws-iam/lib/grant.ts +++ b/packages/@aws-cdk/aws-iam/lib/grant.ts @@ -24,6 +24,13 @@ export interface CommonGrantOptions { * The resource ARNs to grant to */ readonly resourceArns: string[]; + + /** + * Any conditions to attach to the grant + * + * @default - No conditions + */ + readonly conditions?: Record>; } /** @@ -160,6 +167,7 @@ export class Grant implements IDependable { const statement = new PolicyStatement({ actions: options.actions, resources: options.resourceArns, + conditions: options.conditions, }); const addedToPrincipal = options.grantee.grantPrincipal.addToPrincipalPolicy(statement); @@ -224,17 +232,27 @@ export class Grant implements IDependable { /** * The statement that was added to the principal's policy * - * Can be accessed to (e.g.) add additional conditions to the statement. + * @deprecated Use `principalStatements` instead */ public readonly principalStatement?: PolicyStatement; + /** + * The statements that were added to the principal's policy + */ + public readonly principalStatements = new Array(); + /** * The statement that was added to the resource policy * - * Can be accessed to (e.g.) add additional conditions to the statement. + * @deprecated Use `resourceStatements` instead */ public readonly resourceStatement?: PolicyStatement; + /** + * The statements that were added to the principal's policy + */ + public readonly resourceStatements = new Array(); + /** * The options originally used to set this result * @@ -243,14 +261,26 @@ export class Grant implements IDependable { */ private readonly options: CommonGrantOptions; + private readonly dependables = new Array(); + private constructor(props: GrantProps) { this.options = props.options; this.principalStatement = props.principalStatement; this.resourceStatement = props.resourceStatement; + if (this.principalStatement) { + this.principalStatements.push(this.principalStatement); + } + if (this.resourceStatement) { + this.resourceStatements.push(this.resourceStatement); + } + if (props.policyDependable) { + this.dependables.push(props.policyDependable); + } + const self = this; Dependable.implement(this, { get dependencyRoots() { - return props.policyDependable ? Dependable.of(props.policyDependable).dependencyRoots : []; + return Array.from(new Set(self.dependables.flatMap(d => Dependable.of(d).dependencyRoots))); }, }); } @@ -282,6 +312,24 @@ export class Grant implements IDependable { construct.node.addDependency(this); } } + + /** + * Combine two grants into a new one + */ + public combine(rhs: Grant) { + const combinedPrinc = [...this.principalStatements, ...rhs.principalStatements]; + const combinedRes = [...this.resourceStatements, ...rhs.resourceStatements]; + + const ret = new Grant({ + options: this.options, + principalStatement: combinedPrinc[0], + resourceStatement: combinedRes[0], + }); + ret.principalStatements.splice(0, ret.principalStatements.length, ...combinedPrinc); + ret.resourceStatements.splice(0, ret.resourceStatements.length, ...combinedRes); + ret.dependables.push(...this.dependables, ...rhs.dependables); + return ret; + } } function describeGrant(options: CommonGrantOptions) { diff --git a/packages/@aws-cdk/aws-iam/test/grant.test.ts b/packages/@aws-cdk/aws-iam/test/grant.test.ts index 1a4ca30016d6c..8e02c82da8596 100644 --- a/packages/@aws-cdk/aws-iam/test/grant.test.ts +++ b/packages/@aws-cdk/aws-iam/test/grant.test.ts @@ -1,4 +1,4 @@ -import { Template } from '@aws-cdk/assertions'; +import { Template, Match } from '@aws-cdk/assertions'; import { CfnResource, Resource, Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; import * as iam from '../lib'; @@ -97,6 +97,34 @@ describe('Grant dependencies', () => { expectDependencyOn('RoleDefaultPolicy5FFB7DAB'); expectDependencyOn('BuckarooPolicy74174DA4'); }); + + test('can combine two grants', () => { + // GIVEN + const role1 = new iam.Role(stack, 'Role1', { + assumedBy: new iam.ServicePrincipal('bla.amazonaws.com'), + }); + const role2 = new iam.Role(stack, 'Role2', { + assumedBy: new iam.ServicePrincipal('bla.amazonaws.com'), + }); + + // WHEN + const g1 = iam.Grant.addToPrincipal({ + actions: ['service:DoAThing'], + grantee: role1, + resourceArns: ['*'], + }); + const g2 = iam.Grant.addToPrincipal({ + actions: ['service:DoAThing'], + grantee: role2, + resourceArns: ['*'], + }); + + (g1.combine(g2)).applyBefore(resource); + + // THEN + expectDependencyOn('Role1DefaultPolicyD3EF4D0A'); + expectDependencyOn('Role2DefaultPolicy3A7A0A1B'); + }); }); function applyGrantWithDependencyTo(principal: iam.IPrincipal) { @@ -108,8 +136,8 @@ function applyGrantWithDependencyTo(principal: iam.IPrincipal) { } function expectDependencyOn(id: string) { - Template.fromStack(stack).hasResource('CDK::Test::SomeResource', (props: any) => { - return (props?.DependsOn ?? []).includes(id); + Template.fromStack(stack).hasResource('CDK::Test::SomeResource', { + DependsOn: Match.arrayWith([id]), }); } diff --git a/packages/@aws-cdk/aws-route53/README.md b/packages/@aws-cdk/aws-route53/README.md index 44099031c986c..a98bf93f65495 100644 --- a/packages/@aws-cdk/aws-route53/README.md +++ b/packages/@aws-cdk/aws-route53/README.md @@ -152,16 +152,23 @@ new route53.ARecord(this, 'ARecord', { ### Cross Account Zone Delegation -To add a NS record to a HostedZone in different account you can do the following: +If you want to have your root domain hosted zone in one account and your subdomain hosted +zone in a diferent one, you can use `CrossAccountZoneDelegationRecord` to set up delegation +between them. In the account containing the parent hosted zone: ```ts const parentZone = new route53.PublicHostedZone(this, 'HostedZone', { zoneName: 'someexample.com', - crossAccountZoneDelegationPrincipal: new iam.AccountPrincipal('12345678901'), - crossAccountZoneDelegationRoleName: 'MyDelegationRole', }); +const crossAccountRole = new iam.Role(this, 'CrossAccountRole', { + // The role name must be predictable + roleName: 'MyDelegationRole', + // The other account + assumedBy: new iam.AccountPrincipal('12345678901'), +}); +parentZone.grantDelegation(crossAccountRole); ``` In the account containing the child zone to be delegated: diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index fc04c3f91077f..c3238dd7e3172 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -213,6 +213,7 @@ export interface PublicHostedZoneProps extends CommonHostedZoneProps { * with appropriate permissions for every opt-in region instead. * * @default - No delegation configuration + * @deprecated Create the Role yourself and call `hostedZone.grantDelegation()`. */ readonly crossAccountZoneDelegationPrincipal?: iam.IPrincipal; @@ -220,6 +221,7 @@ export interface PublicHostedZoneProps extends CommonHostedZoneProps { * The name of the role created for cross account delegation * * @default - A role name is generated automatically + * @deprecated Create the Role yourself and call `hostedZone.grantDelegation()`. */ readonly crossAccountZoneDelegationRoleName?: string; } @@ -342,6 +344,30 @@ export class PublicHostedZone extends HostedZone implements IPublicHostedZone { ttl: opts.ttl, }); } + + /** + * Grant permissions to add delegation records to this zone + */ + public grantDelegation(grantee: iam.IGrantable) { + const g1 = iam.Grant.addToPrincipal({ + grantee, + actions: ['route53:ChangeResourceRecordSets'], + resourceArns: [this.hostedZoneArn], + conditions: { + 'ForAllValues:StringEquals': { + 'route53:ChangeResourceRecordSetsRecordTypes': ['NS'], + 'route53:ChangeResourceRecordSetsActions': ['UPSERT', 'DELETE'], + }, + }, + }); + const g2 = iam.Grant.addToPrincipal({ + grantee, + actions: ['route53:ListHostedZonesByName'], + resourceArns: ['*'], + }); + + return g1.combine(g2); + } } /** diff --git a/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts b/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts index 94dddf9b0568a..8cd31471bad05 100644 --- a/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts +++ b/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts @@ -1,6 +1,7 @@ import { Match, Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; +import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import * as cdk from '@aws-cdk/core'; import { HostedZone, PrivateHostedZone, PublicHostedZone } from '../lib'; @@ -59,7 +60,7 @@ describe('hosted zone', () => { }); }); - test('with crossAccountZoneDelegationPrincipal', () => { + testDeprecated('with crossAccountZoneDelegationPrincipal', () => { // GIVEN const stack = new cdk.Stack(undefined, 'TestStack', { env: { account: '123456789012', region: 'us-east-1' }, @@ -154,7 +155,7 @@ describe('hosted zone', () => { }); }); - test('with crossAccountZoneDelegationPrincipal, throws if name provided without principal', () => { + testDeprecated('with crossAccountZoneDelegationPrincipal, throws if name provided without principal', () => { // GIVEN const stack = new cdk.Stack(undefined, 'TestStack', { env: { account: '123456789012', region: 'us-east-1' }, @@ -229,3 +230,60 @@ describe('Vpc', () => { }); }); }); + +test('grantDelegation', () => { + // GIVEN + const stack = new cdk.Stack(undefined, 'TestStack', { + env: { account: '123456789012', region: 'us-east-1' }, + }); + + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.AccountPrincipal('22222222222222'), + }); + + const zone = new PublicHostedZone(stack, 'Zone', { + zoneName: 'banana.com', + }); + + // WHEN + zone.grantDelegation(role); + + // THEN + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'route53:ChangeResourceRecordSets', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':route53:::hostedzone/', + { + Ref: 'ZoneA5DE4B68', + }, + ], + ], + }, + Condition: { + 'ForAllValues:StringEquals': { + 'route53:ChangeResourceRecordSetsRecordTypes': ['NS'], + 'route53:ChangeResourceRecordSetsActions': ['UPSERT', 'DELETE'], + }, + }, + }, + { + Action: 'route53:ListHostedZonesByName', + Effect: 'Allow', + Resource: '*', + }, + ], + }, + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53/test/record-set.test.ts b/packages/@aws-cdk/aws-route53/test/record-set.test.ts index c444cb3059e07..78c5f7884446e 100644 --- a/packages/@aws-cdk/aws-route53/test/record-set.test.ts +++ b/packages/@aws-cdk/aws-route53/test/record-set.test.ts @@ -1,5 +1,6 @@ import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; +import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import { Duration, RemovalPolicy, Stack } from '@aws-cdk/core'; import * as route53 from '../lib'; @@ -578,7 +579,7 @@ describe('record set', () => { }); }); - test('Cross account zone delegation record with parentHostedZoneId', () => { + testDeprecated('Cross account zone delegation record with parentHostedZoneId', () => { // GIVEN const stack = new Stack(); const parentZone = new route53.PublicHostedZone(stack, 'ParentHostedZone', { @@ -630,7 +631,7 @@ describe('record set', () => { }); }); - test('Cross account zone delegation record with parentHostedZoneName', () => { + testDeprecated('Cross account zone delegation record with parentHostedZoneName', () => { // GIVEN const stack = new Stack(); const parentZone = new route53.PublicHostedZone(stack, 'ParentHostedZone', { @@ -675,7 +676,7 @@ describe('record set', () => { }); }); - test('Cross account zone delegation record throws when parent id and name both/nither are supplied', () => { + testDeprecated('Cross account zone delegation record throws when parent id and name both/nither are supplied', () => { // GIVEN const stack = new Stack(); const parentZone = new route53.PublicHostedZone(stack, 'ParentHostedZone', { @@ -707,7 +708,7 @@ describe('record set', () => { }).toThrow(/Only one of parentHostedZoneName and parentHostedZoneId is supported/); }); - test('Multiple cross account zone delegation records', () => { + testDeprecated('Multiple cross account zone delegation records', () => { // GIVEN const stack = new Stack(); const parentZone = new route53.PublicHostedZone(stack, 'ParentHostedZone', { @@ -773,7 +774,7 @@ describe('record set', () => { } }); - test('Cross account zone delegation policies', () => { + testDeprecated('Cross account zone delegation policies', () => { // GIVEN const stack = new Stack(); const parentZone = new route53.PublicHostedZone(stack, 'ParentHostedZone', { @@ -845,7 +846,7 @@ describe('record set', () => { } }); - test('Cross account zone context flag', () => { + testDeprecated('Cross account zone context flag', () => { // GIVEN const stack = new Stack(); stack.node.setContext('@aws-cdk/aws-route53:useRegionalStsEndpoint', true); From 96242d73c0ae853524a567aece86f8a8a514495c Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Tue, 27 Dec 2022 12:23:27 +0100 Subject: [PATCH 21/22] fix(codedeploy): referenced Applications are not environment-aware (#23405) Applications (and associated DeploymentGroups) that were referenced using `XxxApplication.fromXxxApplicationName` always assumed they lived in the "current" stack. Add `XxxApplication.fromXxxApplicationArn` for all types, which will take account and region from the ARN, allowing cross-environment references. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/base-deployment-config.ts | 2 +- .../aws-codedeploy/lib/ecs/application.ts | 26 +++- .../lib/ecs/deployment-config.ts | 2 +- .../lib/ecs/deployment-group.ts | 44 +++--- .../aws-codedeploy/lib/lambda/application.ts | 26 +++- .../lib/lambda/custom-deployment-config.ts | 2 +- .../lib/lambda/deployment-config.ts | 2 +- .../lib/lambda/deployment-group.ts | 45 +++--- .../lib/private/base-deployment-group.ts | 138 ++++++++++++++++++ .../aws-codedeploy/lib/{ => private}/utils.ts | 32 ++-- .../aws-codedeploy/lib/server/application.ts | 25 +++- .../lib/server/deployment-config.ts | 2 +- .../lib/server/deployment-group.ts | 73 +++------ .../test/ecs/deployment-group.test.ts | 22 +++ .../test/lambda/deployment-group.test.ts | 22 +++ .../test/server/deployment-group.test.ts | 21 +++ 16 files changed, 356 insertions(+), 128 deletions(-) create mode 100644 packages/@aws-cdk/aws-codedeploy/lib/private/base-deployment-group.ts rename packages/@aws-cdk/aws-codedeploy/lib/{ => private}/utils.ts (74%) diff --git a/packages/@aws-cdk/aws-codedeploy/lib/base-deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/base-deployment-config.ts index 35c0c453cc7c2..0df406088fdb1 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/base-deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/base-deployment-config.ts @@ -2,8 +2,8 @@ import { ArnFormat, Resource, Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeploymentConfig } from './codedeploy.generated'; import { MinimumHealthyHosts } from './host-health-config'; +import { arnForDeploymentConfig, validateName } from './private/utils'; import { TrafficRouting } from './traffic-routing-config'; -import { arnForDeploymentConfig, validateName } from './utils'; /** * The base class for ServerDeploymentConfig, EcsDeploymentConfig, diff --git a/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts index 289a6660c8c4f..9b9173a7d17c0 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts @@ -1,7 +1,7 @@ -import { ArnFormat, IResource, Resource } from '@aws-cdk/core'; +import { ArnFormat, IResource, Resource, Stack, Arn } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnApplication } from '../codedeploy.generated'; -import { arnForApplication, validateName } from '../utils'; +import { arnForApplication, validateName } from '../private/utils'; /** * Represents a reference to a CodeDeploy Application deploying to Amazon ECS. @@ -42,6 +42,9 @@ export class EcsApplication extends Resource implements IEcsApplication { /** * Import an Application defined either outside the CDK, or in a different CDK Stack. * + * The Application's account and region are assumed to be the same as the stack it is being imported + * into. If not, use `fromEcsApplicationArn`. + * * @param scope the parent Construct for this new Construct * @param id the logical ID of this new Construct * @param ecsApplicationName the name of the application to import @@ -49,13 +52,28 @@ export class EcsApplication extends Resource implements IEcsApplication { */ public static fromEcsApplicationName(scope: Construct, id: string, ecsApplicationName: string): IEcsApplication { class Import extends Resource implements IEcsApplication { - public applicationArn = arnForApplication(ecsApplicationName); + public applicationArn = arnForApplication(Stack.of(scope), ecsApplicationName); public applicationName = ecsApplicationName; } return new Import(scope, id); } + /** + * Import an Application defined either outside the CDK, or in a different CDK Stack, by ARN. + * + * @param scope the parent Construct for this new Construct + * @param id the logical ID of this new Construct + * @param ecsApplicationArn the ARN of the application to import + * @returns a Construct representing a reference to an existing Application + */ + public static fromEcsApplicationArn(scope: Construct, id: string, ecsApplicationArn: string): IEcsApplication { + return new class extends Resource implements IEcsApplication { + public applicationArn = ecsApplicationArn; + public applicationName = Arn.split(ecsApplicationArn, ArnFormat.COLON_RESOURCE_NAME).resourceName ?? ''; + } (scope, id, { environmentFromArn: ecsApplicationArn }); + } + public readonly applicationArn: string; public readonly applicationName: string; @@ -70,7 +88,7 @@ export class EcsApplication extends Resource implements IEcsApplication { }); this.applicationName = this.getResourceNameAttribute(resource.ref); - this.applicationArn = this.getResourceArnAttribute(arnForApplication(resource.ref), { + this.applicationArn = this.getResourceArnAttribute(arnForApplication(Stack.of(scope), resource.ref), { service: 'codedeploy', resource: 'application', resourceName: this.physicalName, diff --git a/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-config.ts index be6204b4b10ad..32a5552834e3a 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-config.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; import { BaseDeploymentConfig, BaseDeploymentConfigOptions, ComputePlatform, IBaseDeploymentConfig } from '../base-deployment-config'; +import { deploymentConfig } from '../private/utils'; import { TrafficRouting } from '../traffic-routing-config'; -import { deploymentConfig } from '../utils'; /** * The Deployment Configuration of an ECS Deployment Group. diff --git a/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts index 762f6210e51c3..02c7e809b4275 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts @@ -5,8 +5,9 @@ import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; +import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group'; +import { renderAlarmConfiguration, renderAutoRollbackConfiguration } from '../private/utils'; import { AutoRollbackConfig } from '../rollback-config'; -import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration, validateName } from '../utils'; import { IEcsApplication, EcsApplication } from './application'; import { EcsDeploymentConfig, IEcsDeploymentConfig } from './deployment-config'; @@ -182,9 +183,11 @@ export interface EcsDeploymentGroupProps { * A CodeDeploy deployment group that orchestrates ECS blue-green deployments. * @resource AWS::CodeDeploy::DeploymentGroup */ -export class EcsDeploymentGroup extends cdk.Resource implements IEcsDeploymentGroup { +export class EcsDeploymentGroup extends DeploymentGroupBase implements IEcsDeploymentGroup { /** - * Import an ECS Deployment Group defined outside the CDK app. + * Reference an ECS Deployment Group defined outside the CDK app. + * + * Account and region for the DeploymentGroup are taken from the application. * * @param scope the parent Construct for this new Construct * @param id the logical ID of this new Construct @@ -199,8 +202,6 @@ export class EcsDeploymentGroup extends cdk.Resource implements IEcsDeploymentGr } public readonly application: IEcsApplication; - public readonly deploymentGroupName: string; - public readonly deploymentGroupArn: string; public readonly deploymentConfig: IEcsDeploymentConfig; /** * The service Role of this Deployment Group. @@ -211,16 +212,15 @@ export class EcsDeploymentGroup extends cdk.Resource implements IEcsDeploymentGr constructor(scope: Construct, id: string, props: EcsDeploymentGroupProps) { super(scope, id, { - physicalName: props.deploymentGroupName, + deploymentGroupName: props.deploymentGroupName, + role: props.role, + roleConstructId: 'ServiceRole', }); + this.role = this._role; this.application = props.application || new EcsApplication(this, 'Application'); this.alarms = props.alarms || []; - this.role = props.role || new iam.Role(this, 'ServiceRole', { - assumedBy: new iam.ServicePrincipal('codedeploy.amazonaws.com'), - }); - this.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AWSCodeDeployRoleForECS')); this.deploymentConfig = props.deploymentConfig || EcsDeploymentConfig.ALL_AT_ONCE; @@ -261,21 +261,13 @@ export class EcsDeploymentGroup extends cdk.Resource implements IEcsDeploymentGr autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }), }); - this.deploymentGroupName = this.getResourceNameAttribute(resource.ref); - this.deploymentGroupArn = this.getResourceArnAttribute(arnForDeploymentGroup(this.application.applicationName, resource.ref), { - service: 'codedeploy', - resource: 'deploymentgroup', - resourceName: `${this.application.applicationName}/${this.physicalName}`, - arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME, - }); + this._setNameAndArn(resource, this.application); // If the deployment config is a construct, add a dependency to ensure the deployment config // is created before the deployment group is. if (Construct.isConstruct(this.deploymentConfig)) { this.node.addDependency(this.deploymentConfig); } - - this.node.addValidation({ validate: () => validateName('Deployment group', this.physicalName) }); } /** @@ -355,17 +347,17 @@ export interface EcsDeploymentGroupAttributes { readonly deploymentConfig?: IEcsDeploymentConfig; } -class ImportedEcsDeploymentGroup extends cdk.Resource implements IEcsDeploymentGroup { +class ImportedEcsDeploymentGroup extends ImportedDeploymentGroupBase implements IEcsDeploymentGroup { public readonly application: IEcsApplication; - public readonly deploymentGroupName: string; - public readonly deploymentGroupArn: string; public readonly deploymentConfig: IEcsDeploymentConfig; - constructor(scope:Construct, id: string, props: EcsDeploymentGroupAttributes) { - super(scope, id); + constructor(scope: Construct, id: string, props: EcsDeploymentGroupAttributes) { + super(scope, id, { + application: props.application, + deploymentGroupName: props.deploymentGroupName, + }); + this.application = props.application; - this.deploymentGroupName = props.deploymentGroupName; - this.deploymentGroupArn = arnForDeploymentGroup(props.application.applicationName, props.deploymentGroupName); this.deploymentConfig = props.deploymentConfig || EcsDeploymentConfig.ALL_AT_ONCE; } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts index e0d27f8dabc34..c3c20a5afb2d9 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts @@ -1,7 +1,7 @@ -import { ArnFormat, IResource, Resource } from '@aws-cdk/core'; +import { ArnFormat, IResource, Resource, Stack, Arn } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnApplication } from '../codedeploy.generated'; -import { arnForApplication, validateName } from '../utils'; +import { arnForApplication, validateName } from '../private/utils'; /** * Represents a reference to a CodeDeploy Application deploying to AWS Lambda. @@ -42,6 +42,9 @@ export class LambdaApplication extends Resource implements ILambdaApplication { /** * Import an Application defined either outside the CDK, or in a different CDK Stack. * + * The Application's account and region are assumed to be the same as the stack it is being imported + * into. If not, use `fromLambdaApplicationArn`. + * * @param scope the parent Construct for this new Construct * @param id the logical ID of this new Construct * @param lambdaApplicationName the name of the application to import @@ -49,13 +52,28 @@ export class LambdaApplication extends Resource implements ILambdaApplication { */ public static fromLambdaApplicationName(scope: Construct, id: string, lambdaApplicationName: string): ILambdaApplication { class Import extends Resource implements ILambdaApplication { - public applicationArn = arnForApplication(lambdaApplicationName); + public applicationArn = arnForApplication(Stack.of(scope), lambdaApplicationName); public applicationName = lambdaApplicationName; } return new Import(scope, id); } + /** + * Import an Application defined either outside the CDK, or in a different CDK Stack, by ARN. + * + * @param scope the parent Construct for this new Construct + * @param id the logical ID of this new Construct + * @param lambdaApplicationArn the ARN of the application to import + * @returns a Construct representing a reference to an existing Application + */ + public static fromLambdaApplicationArn(scope: Construct, id: string, lambdaApplicationArn: string): ILambdaApplication { + return new class extends Resource implements ILambdaApplication { + public applicationArn = lambdaApplicationArn; + public applicationName = Arn.split(lambdaApplicationArn, ArnFormat.COLON_RESOURCE_NAME).resourceName ?? ''; + }(scope, id, { environmentFromArn: lambdaApplicationArn }); + } + public readonly applicationArn: string; public readonly applicationName: string; @@ -70,7 +88,7 @@ export class LambdaApplication extends Resource implements ILambdaApplication { }); this.applicationName = this.getResourceNameAttribute(resource.ref); - this.applicationArn = this.getResourceArnAttribute(arnForApplication(resource.ref), { + this.applicationArn = this.getResourceArnAttribute(arnForApplication(Stack.of(this), resource.ref), { service: 'codedeploy', resource: 'application', resourceName: this.physicalName, diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts index fe4ceeb249af2..4a9a6d09e426d 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts @@ -1,7 +1,7 @@ import { Duration, Names, Resource } from '@aws-cdk/core'; import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from '@aws-cdk/custom-resources'; import { Construct } from 'constructs'; -import { arnForDeploymentConfig, validateName } from '../utils'; +import { arnForDeploymentConfig, validateName } from '../private/utils'; import { ILambdaDeploymentConfig } from './deployment-config'; /** diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-config.ts index a86da3222b5f1..e049ecbe08887 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-config.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; import { BaseDeploymentConfig, BaseDeploymentConfigOptions, ComputePlatform, IBaseDeploymentConfig } from '../base-deployment-config'; +import { deploymentConfig } from '../private/utils'; import { TrafficRouting } from '../traffic-routing-config'; -import { deploymentConfig } from '../utils'; /** * The Deployment Configuration of a Lambda Deployment Group. diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts index 5968402efdd1f..44f1cd01eded7 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts @@ -4,8 +4,9 @@ import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; +import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group'; +import { renderAlarmConfiguration, renderAutoRollbackConfiguration } from '../private/utils'; import { AutoRollbackConfig } from '../rollback-config'; -import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration, validateName } from '../utils'; import { ILambdaApplication, LambdaApplication } from './application'; import { ILambdaDeploymentConfig, LambdaDeploymentConfig } from './deployment-config'; @@ -120,10 +121,12 @@ export interface LambdaDeploymentGroupProps { /** * @resource AWS::CodeDeploy::DeploymentGroup */ -export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploymentGroup { +export class LambdaDeploymentGroup extends DeploymentGroupBase implements ILambdaDeploymentGroup { /** * Import an Lambda Deployment Group defined either outside the CDK app, or in a different AWS region. * + * Account and region for the DeploymentGroup are taken from the application. + * * @param scope the parent Construct for this new Construct * @param id the logical ID of this new Construct * @param attrs the properties of the referenced Deployment Group @@ -137,9 +140,10 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy } public readonly application: ILambdaApplication; - public readonly deploymentGroupName: string; - public readonly deploymentGroupArn: string; public readonly deploymentConfig: ILambdaDeploymentConfig; + /** + * The service Role of this Deployment Group. + */ public readonly role: iam.IRole; private readonly alarms: cloudwatch.IAlarm[]; @@ -148,16 +152,15 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy constructor(scope: Construct, id: string, props: LambdaDeploymentGroupProps) { super(scope, id, { - physicalName: props.deploymentGroupName, + deploymentGroupName: props.deploymentGroupName, + role: props.role, + roleConstructId: 'ServiceRole', }); + this.role = this._role; this.application = props.application || new LambdaApplication(this, 'Application'); this.alarms = props.alarms || []; - this.role = props.role || new iam.Role(this, 'ServiceRole', { - assumedBy: new iam.ServicePrincipal('codedeploy.amazonaws.com'), - }); - this.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCodeDeployRoleForLambdaLimited')); this.deploymentConfig = props.deploymentConfig || LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES; @@ -174,13 +177,7 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }), }); - this.deploymentGroupName = this.getResourceNameAttribute(resource.ref); - this.deploymentGroupArn = this.getResourceArnAttribute(arnForDeploymentGroup(this.application.applicationName, resource.ref), { - service: 'codedeploy', - resource: 'deploymentgroup', - resourceName: `${this.application.applicationName}/${this.physicalName}`, - arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME, - }); + this._setNameAndArn(resource, this.application); if (props.preHook) { this.addPreHook(props.preHook); @@ -203,8 +200,6 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy if (this.deploymentConfig instanceof Construct) { this.node.addDependency(this.deploymentConfig); } - - this.node.addValidation({ validate: () => validateName('Deployment group', this.physicalName) }); } /** @@ -284,17 +279,17 @@ export interface LambdaDeploymentGroupAttributes { readonly deploymentConfig?: ILambdaDeploymentConfig; } -class ImportedLambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploymentGroup { +class ImportedLambdaDeploymentGroup extends ImportedDeploymentGroupBase implements ILambdaDeploymentGroup { public readonly application: ILambdaApplication; - public readonly deploymentGroupName: string; - public readonly deploymentGroupArn: string; public readonly deploymentConfig: ILambdaDeploymentConfig; - constructor(scope:Construct, id: string, props: LambdaDeploymentGroupAttributes) { - super(scope, id); + constructor(scope: Construct, id: string, props: LambdaDeploymentGroupAttributes) { + super(scope, id, { + application: props.application, + deploymentGroupName: props.deploymentGroupName, + }); + this.application = props.application; - this.deploymentGroupName = props.deploymentGroupName; - this.deploymentGroupArn = arnForDeploymentGroup(props.application.applicationName, props.deploymentGroupName); this.deploymentConfig = props.deploymentConfig || LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES; } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/private/base-deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/private/base-deployment-group.ts new file mode 100644 index 0000000000000..3ea12aa50d702 --- /dev/null +++ b/packages/@aws-cdk/aws-codedeploy/lib/private/base-deployment-group.ts @@ -0,0 +1,138 @@ +import * as iam from '@aws-cdk/aws-iam'; +import { Resource, IResource, ArnFormat, Arn, Aws } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { CfnDeploymentGroup } from '../codedeploy.generated'; +import { validateName } from './utils'; + +/** + * Structural typing, not jsii compatible but doesn't need to be + */ +interface IApplicationLike extends IResource { + readonly applicationArn: string; + readonly applicationName: string; +} + +/** + */ +export interface ImportedDeploymentGroupBaseProps { + /** + * The reference to the CodeDeploy Application that this Deployment Group belongs to. + */ + readonly application: IApplicationLike; + + /** + * The physical, human-readable name of the CodeDeploy Deployment Group + * that we are referencing. + * + * @default Either deploymentGroupName or deploymentGroupArn is required + */ + readonly deploymentGroupName: string; +} + +/** + * @internal + */ +export class ImportedDeploymentGroupBase extends Resource { + public readonly deploymentGroupName: string; + public readonly deploymentGroupArn: string; + + constructor(scope: Construct, id: string, props: ImportedDeploymentGroupBaseProps) { + const deploymentGroupName = props.deploymentGroupName; + const deploymentGroupArn = Arn.format({ + partition: Aws.PARTITION, + account: props.application.env.account, + region: props.application.env.region, + service: 'codedeploy', + resource: 'deploymentgroup', + resourceName: `${props.application.applicationName}/${deploymentGroupName}`, + arnFormat: ArnFormat.COLON_RESOURCE_NAME, + }); + + super(scope, id, { environmentFromArn: deploymentGroupArn }); + this.deploymentGroupName = deploymentGroupName; + this.deploymentGroupArn = deploymentGroupArn; + } +} + +export interface DeploymentGroupBaseProps { + /** + * The physical, human-readable name of the CodeDeploy Deployment Group. + * + * @default An auto-generated name will be used. + */ + readonly deploymentGroupName?: string; + + /** + * The service Role of this Deployment Group. + * + * @default A new Role will be created. + */ + readonly role?: iam.IRole; + + /** + * Id of the role construct, if created by this construct + * + * Exists because when we factored this out, there was a difference between the + * 3 deployment groups. + */ + readonly roleConstructId: string; +} + +/** + * @internal + */ +export class DeploymentGroupBase extends Resource { + /** + * The name of the Deployment Group. + */ + public readonly deploymentGroupName!: string; + + /** + * The ARN of the Deployment Group. + */ + public readonly deploymentGroupArn!: string; + + /** + * The service Role of this Deployment Group. + * + * (Can't make `role` properly public here, as it's typed as optional in one + * interface and typing it here as definitely set interferes with that.) + * + * @internal + */ + public readonly _role: iam.IRole; + + constructor(scope: Construct, id: string, props: DeploymentGroupBaseProps) { + super(scope, id, { + physicalName: props.deploymentGroupName, + }); + + this._role = props.role || new iam.Role(this, props.roleConstructId, { + assumedBy: new iam.ServicePrincipal('codedeploy.amazonaws.com'), + }); + + this.node.addValidation({ validate: () => validateName('Deployment group', this.physicalName) }); + } + + /** + * Set name and ARN properties. + * + * Must be called in the child constructor. + * + * @internal + */ + protected _setNameAndArn(resource: CfnDeploymentGroup, application: IApplicationLike) { + (this as any).deploymentGroupName = this.getResourceNameAttribute(resource.ref); + (this as any).deploymentGroupArn = this.getResourceArnAttribute(this.stack.formatArn({ + service: 'codedeploy', + resource: 'deploymentgroup', + resourceName: `${application.applicationName}/${resource.ref}`, + arnFormat: ArnFormat.COLON_RESOURCE_NAME, + }), { + service: 'codedeploy', + resource: 'deploymentgroup', + resourceName: `${application.applicationName}/${this.physicalName}`, + arnFormat: ArnFormat.COLON_RESOURCE_NAME, + }); + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codedeploy/lib/utils.ts b/packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts similarity index 74% rename from packages/@aws-cdk/aws-codedeploy/lib/utils.ts rename to packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts index 137998a23eb37..9dccb367d8578 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/utils.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts @@ -1,19 +1,33 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; -import { Aws, Token } from '@aws-cdk/core'; -import { IBaseDeploymentConfig } from './base-deployment-config'; -import { CfnDeploymentGroup } from './codedeploy.generated'; -import { AutoRollbackConfig } from './rollback-config'; +import { Token, Stack, ArnFormat, Arn, Fn, Aws } from '@aws-cdk/core'; +import { IBaseDeploymentConfig } from '../base-deployment-config'; +import { CfnDeploymentGroup } from '../codedeploy.generated'; +import { AutoRollbackConfig } from '../rollback-config'; -export function arnForApplication(applicationName: string): string { - return `arn:${Aws.PARTITION}:codedeploy:${Aws.REGION}:${Aws.ACCOUNT_ID}:application:${applicationName}`; +export function arnForApplication(stack: Stack, applicationName: string): string { + return stack.formatArn({ + service: 'codedeploy', + resource: 'application', + resourceName: applicationName, + arnFormat: ArnFormat.COLON_RESOURCE_NAME, + }); } -export function arnForDeploymentGroup(applicationName: string, deploymentGroupName: string): string { - return `arn:${Aws.PARTITION}:codedeploy:${Aws.REGION}:${Aws.ACCOUNT_ID}:deploymentgroup:${applicationName}/${deploymentGroupName}`; +export function nameFromDeploymentGroupArn(deploymentGroupArn: string): string { + const components = Arn.split(deploymentGroupArn, ArnFormat.COLON_RESOURCE_NAME); + return Fn.select(1, Fn.split('/', components.resourceName ?? '')); } export function arnForDeploymentConfig(name: string): string { - return `arn:${Aws.PARTITION}:codedeploy:${Aws.REGION}:${Aws.ACCOUNT_ID}:deploymentconfig:${name}`; + return Arn.format({ + partition: Aws.PARTITION, + account: Aws.ACCOUNT_ID, + region: Aws.REGION, + service: 'codedeploy', + resource: 'deploymentconfig', + resourceName: name, + arnFormat: ArnFormat.COLON_RESOURCE_NAME, + }); } export function renderAlarmConfiguration(alarms: cloudwatch.IAlarm[], ignorePollAlarmFailure?: boolean): diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts index a04d789fce566..16addfd0537ae 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts @@ -1,7 +1,7 @@ -import { ArnFormat, IResource, Resource } from '@aws-cdk/core'; +import { ArnFormat, IResource, Resource, Stack, Arn } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnApplication } from '../codedeploy.generated'; -import { arnForApplication, validateName } from '../utils'; +import { arnForApplication, validateName } from '../private/utils'; /** * Represents a reference to a CodeDeploy Application deploying to EC2/on-premise instances. @@ -42,6 +42,9 @@ export class ServerApplication extends Resource implements IServerApplication { /** * Import an Application defined either outside the CDK app, or in a different region. * + * The Application's account and region are assumed to be the same as the stack it is being imported + * into. If not, use `fromServerApplicationArn`. + * * @param scope the parent Construct for this new Construct * @param id the logical ID of this new Construct * @param serverApplicationName the name of the application to import @@ -49,12 +52,26 @@ export class ServerApplication extends Resource implements IServerApplication { */ public static fromServerApplicationName(scope: Construct, id: string, serverApplicationName: string): IServerApplication { class Import extends Resource implements IServerApplication { - public readonly applicationArn = arnForApplication(serverApplicationName); + public readonly applicationArn = arnForApplication(Stack.of(scope), serverApplicationName); public readonly applicationName = serverApplicationName; } return new Import(scope, id); + } + /** + * Import an Application defined either outside the CDK, or in a different CDK Stack, by ARN. + * + * @param scope the parent Construct for this new Construct + * @param id the logical ID of this new Construct + * @param serverApplicationArn the ARN of the application to import + * @returns a Construct representing a reference to an existing Application + */ + public static fromServerApplicationArn(scope: Construct, id: string, serverApplicationArn: string): IServerApplication { + return new class extends Resource implements IServerApplication { + public applicationArn = serverApplicationArn; + public applicationName = Arn.split(serverApplicationArn, ArnFormat.COLON_RESOURCE_NAME).resourceName ?? ''; + }(scope, id, { environmentFromArn: serverApplicationArn }); } public readonly applicationArn: string; @@ -71,7 +88,7 @@ export class ServerApplication extends Resource implements IServerApplication { }); this.applicationName = this.getResourceNameAttribute(resource.ref); - this.applicationArn = this.getResourceArnAttribute(arnForApplication(resource.ref), { + this.applicationArn = this.getResourceArnAttribute(arnForApplication(Stack.of(scope), resource.ref), { service: 'codedeploy', resource: 'application', resourceName: this.physicalName, diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts index c3ae4a75ffb59..d09af03cf2fa5 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; import { BaseDeploymentConfig, BaseDeploymentConfigOptions, IBaseDeploymentConfig } from '../base-deployment-config'; import { MinimumHealthyHosts } from '../host-health-config'; -import { deploymentConfig } from '../utils'; +import { deploymentConfig } from '../private/utils'; /** * The Deployment Configuration of an EC2/on-premise Deployment Group. diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts index afb6aee8545e0..448d4f9dde5e8 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts @@ -4,11 +4,11 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; -import { ArnFormat } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; +import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group'; +import { renderAlarmConfiguration, renderAutoRollbackConfiguration } from '../private/utils'; import { AutoRollbackConfig } from '../rollback-config'; -import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration, validateName } from '../utils'; import { IServerApplication, ServerApplication } from './application'; import { IServerDeploymentConfig, ServerDeploymentConfig } from './deployment-config'; import { LoadBalancer, LoadBalancerGeneration } from './load-balancer'; @@ -55,43 +55,20 @@ export interface ServerDeploymentGroupAttributes { readonly deploymentConfig?: IServerDeploymentConfig; } -/** - * Represents a reference to a CodeDeploy EC2/on-premise Deployment Group. - * - * If you're managing the Deployment Group alongside the rest of your CDK resources, - * use the {@link ServerDeploymentGroup} class. - * - * If you want to reference an already existing Deployment Group, - * or one defined in a different CDK Stack, - * use the {@link #import} method. - */ -abstract class ServerDeploymentGroupBase extends cdk.Resource implements IServerDeploymentGroup { - public abstract readonly application: IServerApplication; - public abstract readonly role?: iam.IRole; - public abstract readonly deploymentGroupName: string; - public abstract readonly deploymentGroupArn: string; - public readonly deploymentConfig: IServerDeploymentConfig; - public abstract readonly autoScalingGroups?: autoscaling.IAutoScalingGroup[]; - - constructor(scope: Construct, id: string, deploymentConfig?: IServerDeploymentConfig, props?: cdk.ResourceProps) { - super(scope, id, props); - this.deploymentConfig = deploymentConfig || ServerDeploymentConfig.ONE_AT_A_TIME; - } -} - -class ImportedServerDeploymentGroup extends ServerDeploymentGroupBase { +class ImportedServerDeploymentGroup extends ImportedDeploymentGroupBase implements IServerDeploymentGroup { public readonly application: IServerApplication; public readonly role?: iam.Role = undefined; - public readonly deploymentGroupName: string; - public readonly deploymentGroupArn: string; public readonly autoScalingGroups?: autoscaling.AutoScalingGroup[] = undefined; + public readonly deploymentConfig: IServerDeploymentConfig; constructor(scope: Construct, id: string, props: ServerDeploymentGroupAttributes) { - super(scope, id, props.deploymentConfig); + super(scope, id, { + application: props.application, + deploymentGroupName: props.deploymentGroupName, + }); this.application = props.application; - this.deploymentGroupName = props.deploymentGroupName; - this.deploymentGroupArn = arnForDeploymentGroup(props.application.applicationName, props.deploymentGroupName); + this.deploymentConfig = props.deploymentConfig || ServerDeploymentConfig.ONE_AT_A_TIME; } } @@ -238,7 +215,7 @@ export interface ServerDeploymentGroupProps { * A CodeDeploy Deployment Group that deploys to EC2/on-premise instances. * @resource AWS::CodeDeploy::DeploymentGroup */ -export class ServerDeploymentGroup extends ServerDeploymentGroupBase { +export class ServerDeploymentGroup extends DeploymentGroupBase implements IServerDeploymentGroup { /** * Import an EC2/on-premise Deployment Group defined either outside the CDK app, * or in a different region. @@ -256,9 +233,11 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase { } public readonly application: IServerApplication; + public readonly deploymentConfig: IServerDeploymentConfig; + /** + * The service Role of this Deployment Group. + */ public readonly role?: iam.IRole; - public readonly deploymentGroupArn: string; - public readonly deploymentGroupName: string; private readonly _autoScalingGroups: autoscaling.IAutoScalingGroup[]; private readonly installAgent: boolean; @@ -266,19 +245,19 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase { private readonly alarms: cloudwatch.IAlarm[]; constructor(scope: Construct, id: string, props: ServerDeploymentGroupProps = {}) { - super(scope, id, props.deploymentConfig, { - physicalName: props.deploymentGroupName, + super(scope, id, { + deploymentGroupName: props.deploymentGroupName, + role: props.role, + roleConstructId: 'Role', }); + this.role = this._role; this.application = props.application || new ServerApplication(this, 'Application', { applicationName: props.deploymentGroupName === cdk.PhysicalName.GENERATE_IF_NEEDED ? cdk.PhysicalName.GENERATE_IF_NEEDED : undefined, }); + this.deploymentConfig = props.deploymentConfig || ServerDeploymentConfig.ONE_AT_A_TIME; - this.role = props.role || new iam.Role(this, 'Role', { - assumedBy: new iam.ServicePrincipal('codedeploy.amazonaws.com'), - managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCodeDeployRole')], - }); - + this.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCodeDeployRole')); this._autoScalingGroups = props.autoScalingGroups || []; this.installAgent = props.installAgent ?? true; this.codeDeployBucket = s3.Bucket.fromBucketName(this, 'Bucket', `aws-codedeploy-${cdk.Stack.of(this).region}`); @@ -307,15 +286,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase { autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }), }); - this.deploymentGroupName = this.getResourceNameAttribute(resource.ref); - this.deploymentGroupArn = this.getResourceArnAttribute(arnForDeploymentGroup(this.application.applicationName, resource.ref), { - service: 'codedeploy', - resource: 'deploymentgroup', - resourceName: `${this.application.applicationName}/${this.physicalName}`, - arnFormat: ArnFormat.COLON_RESOURCE_NAME, - }); - - this.node.addValidation({ validate: () => validateName('Deployment group', this.physicalName) }); + this._setNameAndArn(resource, this.application); } /** diff --git a/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts index 62f2b4402c009..aed7b8655516e 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts @@ -848,4 +848,26 @@ describe('CodeDeploy ECS DeploymentGroup', () => { }, }); }); + + test('deploymentGroup from Arn knows its account and region', () => { + // GIVEN + const stack = new cdk.Stack(undefined, 'Stack', { env: { account: '111111111111', region: 'blabla-1' } }); + + // WHEN + const application = codedeploy.EcsApplication.fromEcsApplicationArn(stack, 'Application', 'arn:aws:codedeploy:theregion-1:222222222222:application:MyApplication'); + const group = codedeploy.EcsDeploymentGroup.fromEcsDeploymentGroupAttributes(stack, 'Group', { + application, + deploymentGroupName: 'DeploymentGroup', + }); + + // THEN + expect(application.env).toEqual(expect.objectContaining({ + account: '222222222222', + region: 'theregion-1', + })); + expect(group.env).toEqual(expect.objectContaining({ + account: '222222222222', + region: 'theregion-1', + })); + }); }); diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts index 959c98bbce139..9eae61c7a4e4f 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts @@ -615,6 +615,28 @@ describe('CodeDeploy Lambda DeploymentGroup', () => { }, }); }); + + test('deploymentGroup from Arn knows its account and region', () => { + // GIVEN + const stack = new cdk.Stack(undefined, 'Stack', { env: { account: '111111111111', region: 'blabla-1' } }); + + // WHEN + const application = codedeploy.LambdaApplication.fromLambdaApplicationArn(stack, 'Application', 'arn:aws:codedeploy:theregion-1:222222222222:application:MyApplication'); + const group = codedeploy.LambdaDeploymentGroup.fromLambdaDeploymentGroupAttributes(stack, 'Group', { + application, + deploymentGroupName: 'DeploymentGroup', + }); + + // THEN + expect(application.env).toEqual(expect.objectContaining({ + account: '222222222222', + region: 'theregion-1', + })); + expect(group.env).toEqual(expect.objectContaining({ + account: '222222222222', + region: 'theregion-1', + })); + }); }); describe('imported with fromLambdaDeploymentGroupAttributes', () => { diff --git a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts index 6b22a90cbeedb..4f360aa9cb9c2 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts @@ -494,4 +494,25 @@ describe('CodeDeploy Server Deployment Group', () => { expect(() => app.synth()).toThrow('Deployment group name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).'); }); + test('deploymentGroup from Arn knows its account and region', () => { + // GIVEN + const stack = new cdk.Stack(undefined, 'Stack', { env: { account: '111111111111', region: 'blabla-1' } }); + + // WHEN + const application = codedeploy.ServerApplication.fromServerApplicationArn(stack, 'Application', 'arn:aws:codedeploy:theregion-1:222222222222:application:MyApplication'); + const group = codedeploy.ServerDeploymentGroup.fromServerDeploymentGroupAttributes(stack, 'Group', { + application, + deploymentGroupName: 'DeploymentGroup', + }); + + // THEN + expect(application.env).toEqual(expect.objectContaining({ + account: '222222222222', + region: 'theregion-1', + })); + expect(group.env).toEqual(expect.objectContaining({ + account: '222222222222', + region: 'theregion-1', + })); + }); }); From 6bae8c99ac6a26fb04a47a3e1381addad54c428e Mon Sep 17 00:00:00 2001 From: Florian Chazal Date: Tue, 27 Dec 2022 16:19:26 +0100 Subject: [PATCH 22/22] docs(core): fix extra pound in inline doc (#23466) `Stack.exportSrtringListValue` function inline doc have an extra pound messing up with jsii-docgen generated doc for classes extending Stack. See #23465 for more detail.s ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) *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/stack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/core/lib/stack.ts b/packages/@aws-cdk/core/lib/stack.ts index 7d7997bd3d328..660f841aead19 100644 --- a/packages/@aws-cdk/core/lib/stack.ts +++ b/packages/@aws-cdk/core/lib/stack.ts @@ -1168,7 +1168,7 @@ export class Stack extends Construct implements ITaggable { * remove the reference from the consuming stack. After that, you can remove * the resource and the manual export. * - * # See `exportValue` for an example of this process. + * See `exportValue` for an example of this process. */ public exportStringListValue(exportedValue: any, options: ExportValueOptions = {}): string[] { if (options.name) {