From d7a1c34e540e12413319918a5d807060057a1a1b Mon Sep 17 00:00:00 2001 From: Harold Hunt Date: Mon, 6 Mar 2023 12:08:33 -0500 Subject: [PATCH 01/22] fix(lambda-nodejs): Required auto prefix of `handler` with `index.` breaks custom non-`index` handler settings used by layers (#24406) Using `lambda-nodejs` makes it very easy to bundle functions with `esbuild`, but the code currently *always* prefixes the `handler` value with `index.`, which makes it impossible to use some lambda extensions together with this module as they require setting `handler` to specific values and the `index.` prefixing breaks the ability to set the handler to those values. This PR avoids adding the `index.` prefix if the specified `handler` value contains a `.` already. Closes #24403 ---- *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-nodejs/README.md | 4 + .../aws-lambda-nodejs/lib/function.ts | 5 +- .../aws-lambda-nodejs/test/function.test.ts | 32 ++ .../test/integ-handlers/ts-web-handler.ts | 12 + .../test/integ-handlers/ts-web-run.sh | 11 + .../index.js | 2 + .../index.js.map | 7 + .../ts-web-run.sh | 11 + .../cdk-integ-lambda-nodejs.assets.json | 19 +- .../cdk-integ-lambda-nodejs.template.json | 130 +++++++ .../test/integ.function.js.snapshot/cdk.out | 2 +- .../integ.function.js.snapshot/integ.json | 2 +- .../integ.function.js.snapshot/manifest.json | 40 +- .../test/integ.function.js.snapshot/tree.json | 362 ++++++++++++++++-- .../aws-lambda-nodejs/test/integ.function.ts | 45 ++- 15 files changed, 643 insertions(+), 41 deletions(-) create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-handler.ts create mode 100755 packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-run.sh create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js.map create mode 100755 packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/ts-web-run.sh diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index a895188db5206..35cb80d44b9a2 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -53,6 +53,10 @@ new nodejs.NodejsFunction(this, 'MyFunction', { }); ``` +The handler value will be automatically prefixed with the bundled output file name, `index.`, +unless the handler value contains a `.` character, in which case the handler value is used as-is to +allow for values needed by some Lambda extensions. + For monorepos, the reference architecture becomes: ```plaintext diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts index 202be464b16da..0af7a63ce7d02 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts @@ -25,6 +25,9 @@ export interface NodejsFunctionProps extends lambda.FunctionOptions { /** * The name of the exported handler in the entry file. * + * The handler is prefixed with `index.` unless the specified handler value contains a `.`, + * in which case it is used as-is. + * * @default handler */ readonly handler?: string; @@ -108,7 +111,7 @@ export class NodejsFunction extends lambda.Function { depsLockFilePath, projectRoot, }), - handler: `index.${handler}`, + handler: handler.indexOf('.') !== -1 ? `${handler}` : `index.${handler}`, }); // Enable connection reuse for aws-sdk diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts index f197bb34b60da..0bc5e25917cfa 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts @@ -45,6 +45,38 @@ test('NodejsFunction with .ts handler', () => { }); }); +test('NodejsFunction with overridden handler - no dots', () => { + // WHEN + new NodejsFunction(stack, 'handler1', { + handler: 'myHandler', + }); + + expect(Bundling.bundle).toHaveBeenCalledWith(expect.objectContaining({ + entry: expect.stringContaining('function.test.handler1.ts'), // Automatically finds .ts handler file + })); + + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + Handler: 'index.myHandler', // automatic index. prefix + Runtime: 'nodejs14.x', + }); +}); + +test('NodejsFunction with overridden handler - with dots', () => { + // WHEN + new NodejsFunction(stack, 'handler1', { + handler: 'run.sh', + }); + + expect(Bundling.bundle).toHaveBeenCalledWith(expect.objectContaining({ + entry: expect.stringContaining('function.test.handler1.ts'), // Automatically finds .ts handler file + })); + + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + Handler: 'run.sh', // No index. prefix + Runtime: 'nodejs14.x', + }); +}); + test('NodejsFunction with .js handler', () => { // WHEN new NodejsFunction(stack, 'handler2'); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-handler.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-handler.ts new file mode 100644 index 0000000000000..bb0b3187a74ed --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-handler.ts @@ -0,0 +1,12 @@ +import { Server } from 'http'; +import { mult } from './util'; + +// Create simple http server +const server = new Server((_req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`${mult(3, 4)}`); + console.log(mult(3, 4)); // eslint-disable-line no-console +}); + +const port = parseInt(process.env.PORT || '3001', 10); +server.listen(port); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-run.sh b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-run.sh new file mode 100755 index 0000000000000..def03845104ba --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-web-run.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# For AWS Lambda Adapter +# https://github.com/awslabs/aws-lambda-web-adapter +export READINESS_CHECK_PATH="${READINESS_CHECK_PATH:-/health}" +export AWS_LAMBDA_EXEC_WRAPPER="${AWS_LAMBDA_EXEC_WRAPPER:-/opt/bootstrap}" +export RUST_LOG="${RUST_LOG:-info}" +export AWS_LWA_ENABLE_COMPRESSION="${AWS_LWA_ENABLE_COMPRESSION:-true}" +export PORT="${PORT:-3001}" + +exec node index.js diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js new file mode 100644 index 0000000000000..70a6e7f17eb64 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js @@ -0,0 +1,2 @@ +"use strict";var t=require("http");function r(n,e){return n*e}var o=new t.Server((n,e)=>{e.writeHead(200,{"Content-Type":"text/plain"}),e.end(`${r(3,4)}`),console.log(r(3,4))}),m=parseInt(process.env.PORT||"3001",10);o.listen(m); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vaW50ZWctaGFuZGxlcnMvdHMtd2ViLWhhbmRsZXIudHMiLCAiLi4vLi4vaW50ZWctaGFuZGxlcnMvdXRpbC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgU2VydmVyIH0gZnJvbSAnaHR0cCc7XG5pbXBvcnQgeyBtdWx0IH0gZnJvbSAnLi91dGlsJztcblxuLy8gQ3JlYXRlIHNpbXBsZSBodHRwIHNlcnZlclxuY29uc3Qgc2VydmVyID0gbmV3IFNlcnZlcigoX3JlcSwgcmVzKSA9PiB7XG4gIHJlcy53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbicgfSk7XG4gIHJlcy5lbmQoYCR7bXVsdCgzLCA0KX1gKTtcbiAgY29uc29sZS5sb2cobXVsdCgzLCA0KSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tY29uc29sZVxufSk7XG5cbmNvbnN0IHBvcnQgPSBwYXJzZUludChwcm9jZXNzLmVudi5QT1JUIHx8ICczMDAxJywgMTApO1xuc2VydmVyLmxpc3Rlbihwb3J0KTtcbiIsICJleHBvcnQgZnVuY3Rpb24gYWRkKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIGEgKyBiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbXVsdChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBhICogYjtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJhQUFBLElBQUFBLEVBQXVCLGdCQ0loQixTQUFTQyxFQUFLQyxFQUFXQyxFQUFtQixDQUNqRCxPQUFPRCxFQUFJQyxDQUNiLENERkEsSUFBTUMsRUFBUyxJQUFJLFNBQU8sQ0FBQ0MsRUFBTUMsSUFBUSxDQUN2Q0EsRUFBSSxVQUFVLElBQUssQ0FBRSxlQUFnQixZQUFhLENBQUMsRUFDbkRBLEVBQUksSUFBSSxHQUFHQyxFQUFLLEVBQUcsQ0FBQyxHQUFHLEVBQ3ZCLFFBQVEsSUFBSUEsRUFBSyxFQUFHLENBQUMsQ0FBQyxDQUN4QixDQUFDLEVBRUtDLEVBQU8sU0FBUyxRQUFRLElBQUksTUFBUSxPQUFRLEVBQUUsRUFDcERKLEVBQU8sT0FBT0ksQ0FBSSIsCiAgIm5hbWVzIjogWyJpbXBvcnRfaHR0cCIsICJtdWx0IiwgImEiLCAiYiIsICJzZXJ2ZXIiLCAiX3JlcSIsICJyZXMiLCAibXVsdCIsICJwb3J0Il0KfQo= diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js.map b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js.map new file mode 100644 index 0000000000000..1466fdadbee8c --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/index.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../integ-handlers/ts-web-handler.ts", "../../integ-handlers/util.ts"], + "sourcesContent": ["import { Server } from 'http';\nimport { mult } from './util';\n\n// Create simple http server\nconst server = new Server((_req, res) => {\n res.writeHead(200, { 'Content-Type': 'text/plain' });\n res.end(`${mult(3, 4)}`);\n console.log(mult(3, 4)); // eslint-disable-line no-console\n});\n\nconst port = parseInt(process.env.PORT || '3001', 10);\nserver.listen(port);\n", "export function add(a: number, b: number): number {\n return a + b;\n}\n\nexport function mult(a: number, b: number): number {\n return a * b;\n}\n"], + "mappings": "aAAA,IAAAA,EAAuB,gBCIhB,SAASC,EAAKC,EAAWC,EAAmB,CACjD,OAAOD,EAAIC,CACb,CDFA,IAAMC,EAAS,IAAI,SAAO,CAACC,EAAMC,IAAQ,CACvCA,EAAI,UAAU,IAAK,CAAE,eAAgB,YAAa,CAAC,EACnDA,EAAI,IAAI,GAAGC,EAAK,EAAG,CAAC,GAAG,EACvB,QAAQ,IAAIA,EAAK,EAAG,CAAC,CAAC,CACxB,CAAC,EAEKC,EAAO,SAAS,QAAQ,IAAI,MAAQ,OAAQ,EAAE,EACpDJ,EAAO,OAAOI,CAAI", + "names": ["import_http", "mult", "a", "b", "server", "_req", "res", "mult", "port"] +} diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/ts-web-run.sh b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/ts-web-run.sh new file mode 100755 index 0000000000000..def03845104ba --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce/ts-web-run.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# For AWS Lambda Adapter +# https://github.com/awslabs/aws-lambda-web-adapter +export READINESS_CHECK_PATH="${READINESS_CHECK_PATH:-/health}" +export AWS_LAMBDA_EXEC_WRAPPER="${AWS_LAMBDA_EXEC_WRAPPER:-/opt/bootstrap}" +export RUST_LOG="${RUST_LOG:-info}" +export AWS_LWA_ENABLE_COMPRESSION="${AWS_LWA_ENABLE_COMPRESSION:-true}" +export PORT="${PORT:-3001}" + +exec node index.js diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.assets.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.assets.json index 5d852f260508e..9130aa4703d05 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.assets.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.assets.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "30.1.0", "files": { "5017e4b2e278e32bc634202d075b7ed8961b0d784f75450f7918a6a4f6f7df4a": { "source": { @@ -40,7 +40,20 @@ } } }, - "90cb9162c12b37a3990ecbde27ea037907171ccb64eeb60f046f098a9ae069cd": { + "a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce": { + "source": { + "path": "asset.a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "76dea8b92881f37d669c02f0271a5aa08e02b115b3fbe57063dbb99c5acb1932": { "source": { "path": "cdk-integ-lambda-nodejs.template.json", "packaging": "file" @@ -48,7 +61,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "90cb9162c12b37a3990ecbde27ea037907171ccb64eeb60f046f098a9ae069cd.json", + "objectKey": "76dea8b92881f37d669c02f0271a5aa08e02b115b3fbe57063dbb99c5acb1932.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-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.template.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.template.json index f72cbf8df949d..eb052475e4bfd 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.template.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk-integ-lambda-nodejs.template.json @@ -626,6 +626,136 @@ "VpcPrivateSubnet2DefaultRoute060D2087", "VpcPrivateSubnet2RouteTableAssociationA89CAD56" ] + }, + "tshandlercustomhandlernodotsServiceRole1775E15E": { + "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" + ] + ] + } + ] + } + }, + "tshandlercustomhandlernodots381F62EE": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "5017e4b2e278e32bc634202d075b7ed8961b0d784f75450f7918a6a4f6f7df4a.zip" + }, + "Role": { + "Fn::GetAtt": [ + "tshandlercustomhandlernodotsServiceRole1775E15E", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "tshandlercustomhandlernodotsServiceRole1775E15E" + ] + }, + "tshandlercustomhandlerdotsServiceRole0575D3CB": { + "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" + ] + ] + } + ] + } + }, + "tshandlercustomhandlerdots2695F653": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce.zip" + }, + "Role": { + "Fn::GetAtt": [ + "tshandlercustomhandlerdotsServiceRole0575D3CB", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "ts-web.run.sh", + "Layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":753240598075:layer:LambdaAdapterLayerX86:13" + ] + ] + } + ], + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "tshandlercustomhandlerdotsServiceRole0575D3CB" + ] } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk.out b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk.out index 588d7b269d34f..b72fef144f05c 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"30.1.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/integ.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/integ.json index e9f051c1b0d53..c76a9db715ffb 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "30.1.0", "testCases": { "integ.function": { "stacks": [ diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/manifest.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/manifest.json index d868041e21916..6ba270bef70dd 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "30.1.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "cdk-integ-lambda-nodejs.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}/90cb9162c12b37a3990ecbde27ea037907171ccb64eeb60f046f098a9ae069cd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/76dea8b92881f37d669c02f0271a5aa08e02b115b3fbe57063dbb99c5acb1932.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -219,6 +213,30 @@ "data": "tshandlervpcA502E26A" } ], + "/cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "tshandlercustomhandlernodotsServiceRole1775E15E" + } + ], + "/cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "tshandlercustomhandlernodots381F62EE" + } + ], + "/cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "tshandlercustomhandlerdotsServiceRole0575D3CB" + } + ], + "/cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "tshandlercustomhandlerdots2695F653" + } + ], "/cdk-integ-lambda-nodejs/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -233,6 +251,12 @@ ] }, "displayName": "cdk-integ-lambda-nodejs" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/tree.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/tree.json index 0c03f93bc762b..56f5b3601ae24 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.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" - } - }, "cdk-integ-lambda-nodejs": { "id": "cdk-integ-lambda-nodejs", "path": "cdk-integ-lambda-nodejs", @@ -24,6 +16,14 @@ "id": "ServiceRole", "path": "cdk-integ-lambda-nodejs/ts-handler/ServiceRole", "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "cdk-integ-lambda-nodejs/ts-handler/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "cdk-integ-lambda-nodejs/ts-handler/ServiceRole/Resource", @@ -77,8 +77,8 @@ "id": "Stage", "path": "cdk-integ-lambda-nodejs/ts-handler/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -141,6 +141,14 @@ "id": "ServiceRole", "path": "cdk-integ-lambda-nodejs/js-handler/ServiceRole", "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "cdk-integ-lambda-nodejs/js-handler/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "cdk-integ-lambda-nodejs/js-handler/ServiceRole/Resource", @@ -194,8 +202,8 @@ "id": "Stage", "path": "cdk-integ-lambda-nodejs/js-handler/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -325,8 +333,8 @@ "id": "Acl", "path": "cdk-integ-lambda-nodejs/Vpc/PublicSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -492,8 +500,8 @@ "id": "Acl", "path": "cdk-integ-lambda-nodejs/Vpc/PublicSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -659,8 +667,8 @@ "id": "Acl", "path": "cdk-integ-lambda-nodejs/Vpc/PrivateSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -778,8 +786,8 @@ "id": "Acl", "path": "cdk-integ-lambda-nodejs/Vpc/PrivateSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -901,6 +909,14 @@ "id": "ServiceRole", "path": "cdk-integ-lambda-nodejs/ts-handler-vpc/ServiceRole", "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "cdk-integ-lambda-nodejs/ts-handler-vpc/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "cdk-integ-lambda-nodejs/ts-handler-vpc/ServiceRole/Resource", @@ -966,8 +982,8 @@ "id": "Stage", "path": "cdk-integ-lambda-nodejs/ts-handler-vpc/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -1073,17 +1089,313 @@ "fqn": "@aws-cdk/aws-lambda-nodejs.NodejsFunction", "version": "0.0.0" } + }, + "ts-handler-custom-handler-no-dots": { + "id": "ts-handler-custom-handler-no-dots", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/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" + } + }, + "Code": { + "id": "Code", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/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" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-no-dots/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "5017e4b2e278e32bc634202d075b7ed8961b0d784f75450f7918a6a4f6f7df4a.zip" + }, + "role": { + "Fn::GetAtt": [ + "tshandlercustomhandlernodotsServiceRole1775E15E", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda-nodejs.NodejsFunction", + "version": "0.0.0" + } + }, + "lambda-adapter-layer": { + "id": "lambda-adapter-layer", + "path": "cdk-integ-lambda-nodejs/lambda-adapter-layer", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "ts-handler-custom-handler-dots": { + "id": "ts-handler-custom-handler-dots", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/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" + } + }, + "Code": { + "id": "Code", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/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" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-integ-lambda-nodejs/ts-handler-custom-handler-dots/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "a33898f49e24c41ff9be236439c418d30e576c5f57763097162d9ec4245216ce.zip" + }, + "role": { + "Fn::GetAtt": [ + "tshandlercustomhandlerdotsServiceRole0575D3CB", + "Arn" + ] + }, + "environment": { + "variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "handler": "ts-web.run.sh", + "layers": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:lambda:", + { + "Ref": "AWS::Region" + }, + ":753240598075:layer:LambdaAdapterLayerX86:13" + ] + ] + } + ], + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda-nodejs.NodejsFunction", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-integ-lambda-nodejs/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-integ-lambda-nodejs/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.264" } } }, "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-lambda-nodejs/test/integ.function.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.ts index 2dc25ef3679dc..ba6e676e1b7fc 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.ts @@ -1,7 +1,8 @@ +import * as os from 'os'; import * as path from 'path'; import { Vpc } from '@aws-cdk/aws-ec2'; -import { Runtime } from '@aws-cdk/aws-lambda'; -import { App, Stack, StackProps } from '@aws-cdk/core'; +import { LayerVersion, Runtime } from '@aws-cdk/aws-lambda'; +import { Aws, App, Stack, StackProps } from '@aws-cdk/core'; import { Construct } from 'constructs'; import * as lambda from '../lib'; @@ -29,6 +30,46 @@ class TestStack extends Stack { runtime: Runtime.NODEJS_14_X, vpc: new Vpc(this, 'Vpc'), }); + + new lambda.NodejsFunction(this, 'ts-handler-custom-handler-no-dots', { + entry: path.join(__dirname, 'integ-handlers/ts-handler.ts'), + runtime: Runtime.NODEJS_14_X, + bundling: { + minify: true, + sourceMap: true, + sourceMapMode: lambda.SourceMapMode.BOTH, + }, + handler: 'handler', + }); + + new lambda.NodejsFunction(this, 'ts-handler-custom-handler-dots', { + entry: path.join(__dirname, 'integ-handlers/ts-web-handler.ts'), + runtime: Runtime.NODEJS_14_X, + bundling: { + minify: true, + sourceMap: true, + sourceMapMode: lambda.SourceMapMode.BOTH, + commandHooks: { + beforeBundling: () => [], + beforeInstall: () => [], + afterBundling: (_inputDir, outputDir) => [ + `${os.platform() === 'win32' ? 'copy' : 'cp'} ${path.join( + __dirname, + 'integ-handlers', + 'ts-web-run.sh', + )} ${outputDir}`, + ], + }, + }, + handler: 'ts-web.run.sh', + layers: [ + LayerVersion.fromLayerVersionArn( + this, + 'lambda-adapter-layer', + `arn:aws:lambda:${Aws.REGION}:753240598075:layer:LambdaAdapterLayerX86:13`, + ), + ], + }); } } From 6bda4e5ae4205a917a00714433f136550c59e409 Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Mon, 6 Mar 2023 17:49:27 +0000 Subject: [PATCH 02/22] fix(rds): add clusterResourceIdentifier property to database cluster (#23605) **Summary** - Exposed the [`DBClusterResourceId`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbcluster.html#aws-resource-rds-dbcluster-return-values) on the database cluster as `clusterResourceIdentifier`. - This is needed to [create an IAM policy for IAM database access](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html). --- packages/@aws-cdk/aws-rds/lib/cluster-ref.ts | 16 ++ packages/@aws-cdk/aws-rds/lib/cluster.ts | 20 +++ .../@aws-cdk/aws-rds/test/cluster.test.ts | 5 + .../aws-cdk-rds-integ.assets.json | 6 +- .../aws-cdk-rds-integ.template.json | 66 ++++++- .../test/integ.cluster.js.snapshot/cdk.out | 2 +- .../test/integ.cluster.js.snapshot/integ.json | 2 +- .../integ.cluster.js.snapshot/manifest.json | 28 ++- .../test/integ.cluster.js.snapshot/tree.json | 164 +++++++++++++++--- .../@aws-cdk/aws-rds/test/integ.cluster.ts | 17 ++ 10 files changed, 292 insertions(+), 34 deletions(-) diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts index de1f89bd3dafa..c5f5a0155dd2e 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts @@ -14,6 +14,13 @@ export interface IDatabaseCluster extends IResource, ec2.IConnectable, secretsma */ readonly clusterIdentifier: string; + /** + * The immutable identifier for the cluster; for example: cluster-ABCD1234EFGH5678IJKL90MNOP. + * + * This AWS Region-unique identifier is used in things like IAM authentication policies. + */ + readonly clusterResourceIdentifier: string; + /** * Identifiers of the replicas */ @@ -57,6 +64,15 @@ export interface DatabaseClusterAttributes { */ readonly clusterIdentifier: string; + /** + * The immutable identifier for the cluster; for example: cluster-ABCD1234EFGH5678IJKL90MNOP. + * + * This AWS Region-unique identifier is used to grant access to the cluster. + * + * @default none + */ + readonly clusterResourceIdentifier?: string; + /** * The database port * diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 16f72e6193b24..af6b42629f803 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -321,6 +321,13 @@ export abstract class DatabaseClusterBase extends Resource implements IDatabaseC */ public abstract readonly clusterIdentifier: string; + /** + * The immutable identifier for the cluster; for example: cluster-ABCD1234EFGH5678IJKL90MNOP. + * + * This AWS Region-unique identifier is used in things like IAM authentication policies. + */ + public abstract readonly clusterResourceIdentifier: string; + /** * Identifiers of the replicas */ @@ -557,6 +564,7 @@ class ImportedDatabaseCluster extends DatabaseClusterBase implements IDatabaseCl public readonly connections: ec2.Connections; public readonly engine?: IClusterEngine; + private readonly _clusterResourceIdentifier?: string; private readonly _clusterEndpoint?: Endpoint; private readonly _clusterReadEndpoint?: Endpoint; private readonly _instanceIdentifiers?: string[]; @@ -566,6 +574,7 @@ class ImportedDatabaseCluster extends DatabaseClusterBase implements IDatabaseCl super(scope, id); this.clusterIdentifier = attrs.clusterIdentifier; + this._clusterResourceIdentifier = attrs.clusterResourceIdentifier; const defaultPort = attrs.port ? ec2.Port.tcp(attrs.port) : undefined; this.connections = new ec2.Connections({ @@ -582,6 +591,13 @@ class ImportedDatabaseCluster extends DatabaseClusterBase implements IDatabaseCl : undefined; } + public get clusterResourceIdentifier() { + if (!this._clusterResourceIdentifier) { + throw new Error('Cannot access `clusterResourceIdentifier` of an imported cluster without a clusterResourceIdentifier'); + } + return this._clusterResourceIdentifier; + } + public get clusterEndpoint() { if (!this._clusterEndpoint) { throw new Error('Cannot access `clusterEndpoint` of an imported cluster without an endpoint address and port'); @@ -637,6 +653,7 @@ export class DatabaseCluster extends DatabaseClusterNew { } public readonly clusterIdentifier: string; + public readonly clusterResourceIdentifier: string; public readonly clusterEndpoint: Endpoint; public readonly clusterReadEndpoint: Endpoint; public readonly connections: ec2.Connections; @@ -662,6 +679,7 @@ export class DatabaseCluster extends DatabaseClusterNew { }); this.clusterIdentifier = cluster.ref; + this.clusterResourceIdentifier = cluster.attrDbClusterResourceId; if (secret) { this.secret = secret.attach(this); @@ -729,6 +747,7 @@ export interface DatabaseClusterFromSnapshotProps extends DatabaseClusterBasePro */ export class DatabaseClusterFromSnapshot extends DatabaseClusterNew { public readonly clusterIdentifier: string; + public readonly clusterResourceIdentifier: string; public readonly clusterEndpoint: Endpoint; public readonly clusterReadEndpoint: Endpoint; public readonly connections: ec2.Connections; @@ -774,6 +793,7 @@ export class DatabaseClusterFromSnapshot extends DatabaseClusterNew { }); this.clusterIdentifier = cluster.ref; + this.clusterResourceIdentifier = cluster.attrDbClusterResourceId; if (secret) { this.secret = secret.attach(this); diff --git a/packages/@aws-cdk/aws-rds/test/cluster.test.ts b/packages/@aws-cdk/aws-rds/test/cluster.test.ts index 880a3745efb09..fd60567e0eb44 100644 --- a/packages/@aws-cdk/aws-rds/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-rds/test/cluster.test.ts @@ -97,6 +97,7 @@ describe('cluster', () => { VpcSecurityGroupIds: [{ 'Fn::GetAtt': ['DatabaseSecurityGroup5C91FDCB', 'GroupId'] }], }); + expect(stack.resolve(cluster.clusterResourceIdentifier)).toEqual({ 'Fn::GetAtt': ['DatabaseB269D8BB', 'DBClusterResourceId'] }); expect(cluster.instanceIdentifiers).toHaveLength(1); expect(stack.resolve(cluster.instanceIdentifiers[0])).toEqual({ Ref: 'DatabaseInstance1844F58FD', @@ -738,6 +739,7 @@ describe('cluster', () => { clusterIdentifier: 'identifier', }); + expect(() => cluster.clusterResourceIdentifier).toThrow(/Cannot access `clusterResourceIdentifier` of an imported cluster/); expect(() => cluster.clusterEndpoint).toThrow(/Cannot access `clusterEndpoint` of an imported cluster/); expect(() => cluster.clusterReadEndpoint).toThrow(/Cannot access `clusterReadEndpoint` of an imported cluster/); expect(() => cluster.instanceIdentifiers).toThrow(/Cannot access `instanceIdentifiers` of an imported cluster/); @@ -750,6 +752,7 @@ describe('cluster', () => { const cluster = DatabaseCluster.fromDatabaseClusterAttributes(stack, 'Database', { clusterEndpointAddress: 'addr', clusterIdentifier: 'identifier', + clusterResourceIdentifier: 'identifier', instanceEndpointAddresses: ['instance-addr'], instanceIdentifiers: ['identifier'], port: 3306, @@ -759,6 +762,7 @@ describe('cluster', () => { })], }); + expect(cluster.clusterResourceIdentifier).toEqual('identifier'); expect(cluster.clusterEndpoint.socketAddress).toEqual('addr:3306'); expect(cluster.clusterReadEndpoint.socketAddress).toEqual('reader-address:3306'); expect(cluster.instanceIdentifiers).toEqual(['identifier']); @@ -2091,6 +2095,7 @@ describe('cluster', () => { Template.fromStack(stack).resourceCountIs('AWS::RDS::DBInstance', 2); + expect(stack.resolve(cluster.clusterResourceIdentifier)).toEqual({ 'Fn::GetAtt': ['DatabaseB269D8BB', 'DBClusterResourceId'] }); expect(cluster.instanceIdentifiers).toHaveLength(2); expect(stack.resolve(cluster.instanceIdentifiers[0])).toEqual({ Ref: 'DatabaseInstance1844F58FD', diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.assets.json b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.assets.json index 98ea3b7c06a81..4d6cbf25c5121 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.assets.json +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "29.0.0", "files": { - "0b11338b1fdbc41b36beb545451369de9d176a04762e559c87a3afbe35c7316d": { + "b62ee60990b0a14a4b10381d4d26d42ce50c164305fa81b2d9729e116480af0f": { "source": { "path": "aws-cdk-rds-integ.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "0b11338b1fdbc41b36beb545451369de9d176a04762e559c87a3afbe35c7316d.json", + "objectKey": "b62ee60990b0a14a4b10381d4d26d42ce50c164305fa81b2d9729e116480af0f.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-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.template.json b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.template.json index 5addaf6c1826d..072548b1fa549 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.template.json +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/aws-cdk-rds-integ.template.json @@ -495,7 +495,6 @@ "DatabaseB269D8BB": { "Type": "AWS::RDS::DBCluster", "Properties": { - "Engine": "aurora", "CopyTagsToSnapshot": true, "DBClusterParameterGroupName": { "Ref": "ParamsA8366201" @@ -503,6 +502,7 @@ "DBSubnetGroupName": { "Ref": "DatabaseSubnets56F17B9A" }, + "Engine": "aurora", "KmsKeyId": { "Fn::GetAtt": [ "DbSecurity381C2C15", @@ -567,6 +567,70 @@ ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "ClusterIamAccess93AC3DF3": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ClusterIamAccessDefaultPolicyA088E4DA": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "rds-db:connect", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds-db:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":dbuser:", + { + "Fn::GetAtt": [ + "DatabaseB269D8BB", + "DBClusterResourceId" + ] + }, + "/db_user" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ClusterIamAccessDefaultPolicyA088E4DA", + "Roles": [ + { + "Ref": "ClusterIamAccess93AC3DF3" + } + ] + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/cdk.out b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/cdk.out index 588d7b269d34f..d8b441d447f8a 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"29.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/integ.json b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/integ.json index b32b0de432db8..553cd276a4bd3 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "29.0.0", "testCases": { "integ.cluster": { "stacks": [ diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/manifest.json b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/manifest.json index b3f4afaedc9b0..0641f1a9bb191 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "29.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-rds-integ.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}/0b11338b1fdbc41b36beb545451369de9d176a04762e559c87a3afbe35c7316d.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b62ee60990b0a14a4b10381d4d26d42ce50c164305fa81b2d9729e116480af0f.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -225,6 +219,18 @@ "data": "DatabaseInstance2AA380DEE" } ], + "/aws-cdk-rds-integ/ClusterIamAccess/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterIamAccess93AC3DF3" + } + ], + "/aws-cdk-rds-integ/ClusterIamAccess/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterIamAccessDefaultPolicyA088E4DA" + } + ], "/aws-cdk-rds-integ/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -239,6 +245,12 @@ ] }, "displayName": "aws-cdk-rds-integ" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/tree.json b/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/tree.json index c8ebaa8dc181b..1b5a2ae9b6bec 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.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-rds-integ": { "id": "aws-cdk-rds-integ", "path": "aws-cdk-rds-integ", @@ -91,8 +83,8 @@ "id": "Acl", "path": "aws-cdk-rds-integ/VPC/PublicSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -258,8 +250,8 @@ "id": "Acl", "path": "aws-cdk-rds-integ/VPC/PublicSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -425,8 +417,8 @@ "id": "Acl", "path": "aws-cdk-rds-integ/VPC/PrivateSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -544,8 +536,8 @@ "id": "Acl", "path": "aws-cdk-rds-integ/VPC/PrivateSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -848,7 +840,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::RDS::DBCluster", "aws:cdk:cloudformation:props": { - "engine": "aurora", "copyTagsToSnapshot": true, "dbClusterParameterGroupName": { "Ref": "ParamsA8366201" @@ -856,6 +847,7 @@ "dbSubnetGroupName": { "Ref": "DatabaseSubnets56F17B9A" }, + "engine": "aurora", "kmsKeyId": { "Fn::GetAtt": [ "DbSecurity381C2C15", @@ -929,17 +921,149 @@ "fqn": "@aws-cdk/aws-rds.DatabaseCluster", "version": "0.0.0" } + }, + "ClusterIamAccess": { + "id": "ClusterIamAccess", + "path": "aws-cdk-rds-integ/ClusterIamAccess", + "children": { + "ImportClusterIamAccess": { + "id": "ImportClusterIamAccess", + "path": "aws-cdk-rds-integ/ClusterIamAccess/ImportClusterIamAccess", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-rds-integ/ClusterIamAccess/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-rds-integ/ClusterIamAccess/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-rds-integ/ClusterIamAccess/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "rds-db:connect", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds-db:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":dbuser:", + { + "Fn::GetAtt": [ + "DatabaseB269D8BB", + "DBClusterResourceId" + ] + }, + "/db_user" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "ClusterIamAccessDefaultPolicyA088E4DA", + "roles": [ + { + "Ref": "ClusterIamAccess93AC3DF3" + } + ] + } + }, + "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" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-rds-integ/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-rds-integ/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.216" } } }, "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-rds/test/integ.cluster.ts b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts index 09c74af16fecd..1b136ea59a55c 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts @@ -1,4 +1,5 @@ import * as ec2 from '@aws-cdk/aws-ec2'; +import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; import { Credentials, DatabaseCluster, DatabaseClusterEngine, ParameterGroup } from '../lib'; @@ -32,4 +33,20 @@ const cluster = new DatabaseCluster(stack, 'Database', { cluster.connections.allowDefaultPortFromAnyIpv4('Open to the world'); +const role = new iam.Role(stack, 'ClusterIamAccess', { + assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), +}); +const clusterIamAuthArn = stack.formatArn({ + service: 'rds-db', + resource: `dbuser:${cluster.clusterResourceIdentifier}`, + resourceName: 'db_user', +}); +role.addToPolicy( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: ['rds-db:connect'], + resources: [clusterIamAuthArn], + }), +); + app.synth(); From 2afad8dc208a51e1c76f383e74496f2cbf98babc Mon Sep 17 00:00:00 2001 From: bun <73948280+bun913@users.noreply.github.com> Date: Tue, 7 Mar 2023 03:30:39 +0900 Subject: [PATCH 03/22] refactor(ecs): replace instanceOf into Cluster.isCluster() method (#24455) Closes #24454 ---- *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-ecs/lib/cluster.ts | 18 ++++++++++- .../@aws-cdk/aws-ecs/test/cluster.test.ts | 32 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-ecs/lib/cluster.ts b/packages/@aws-cdk/aws-ecs/lib/cluster.ts index 8bea6de94872a..c2c886cd51431 100644 --- a/packages/@aws-cdk/aws-ecs/lib/cluster.ts +++ b/packages/@aws-cdk/aws-ecs/lib/cluster.ts @@ -13,6 +13,8 @@ import { InstanceDrainHook } from './drain-hook/instance-drain-hook'; import { ECSMetrics } from './ecs-canned-metrics.generated'; import { CfnCluster, CfnCapacityProvider, CfnClusterCapacityProviderAssociations } from './ecs.generated'; +const CLUSTER_SYMBOL = Symbol.for('@aws-cdk/aws-ecs/lib/cluster.Cluster'); + /** * The properties used to define an ECS cluster. */ @@ -94,6 +96,14 @@ export enum MachineImageType { * A regional grouping of one or more container instances on which you can run tasks and services. */ export class Cluster extends Resource implements ICluster { + + /** + * Return whether the given object is a Cluster + */ + public static isCluster(x: any) : x is Cluster { + return x !== null && typeof(x) === 'object' && CLUSTER_SYMBOL in x; + } + /** * Import an existing cluster to the stack from its attributes. */ @@ -679,6 +689,12 @@ export class Cluster extends Resource implements ICluster { } } +Object.defineProperty(Cluster.prototype, CLUSTER_SYMBOL, { + value: true, + enumerable: false, + writable: false, +}); + /** * A regional grouping of one or more container instances on which you can run tasks and services. */ @@ -1259,7 +1275,7 @@ class MaybeCreateCapacityProviderAssociations implements IAspect { } public visit(node: IConstruct): void { - if (node instanceof Cluster) { + if (Cluster.isCluster(node)) { if ((this.scope.defaultCapacityProviderStrategy.length > 0 || this.scope.capacityProviderNames.length > 0 && !this.resource)) { this.resource = new CfnClusterCapacityProviderAssociations(this.scope, this.id, { cluster: node.clusterName, diff --git a/packages/@aws-cdk/aws-ecs/test/cluster.test.ts b/packages/@aws-cdk/aws-ecs/test/cluster.test.ts index bd3d15a4c3bd2..333e709a26e7f 100644 --- a/packages/@aws-cdk/aws-ecs/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-ecs/test/cluster.test.ts @@ -11,6 +11,38 @@ import * as cxapi from '@aws-cdk/cx-api'; import * as ecs from '../lib'; describe('cluster', () => { + describe('isCluster() returns', () => { + test('true if given cluster instance', () => { + // GIVEN + const stack = new cdk.Stack(); + // WHEN + const createdCluster = new ecs.Cluster(stack, 'EcsCluster'); + // THEN + expect(ecs.Cluster.isCluster(createdCluster)).toBe(true); + }); + + test('false if given imported cluster instance', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'Vpc'); + + const importedSg = ec2.SecurityGroup.fromSecurityGroupId(stack, 'SG1', 'sg-1', { allowAllOutbound: false }); + // WHEN + const importedCluster = ecs.Cluster.fromClusterAttributes(stack, 'Cluster', { + clusterName: 'cluster-name', + securityGroups: [importedSg], + vpc, + }); + // THEN + expect(ecs.Cluster.isCluster(importedCluster)).toBe(false); + }); + + test('false if given undefined', () => { + // THEN + expect(ecs.Cluster.isCluster(undefined)).toBe(false); + }); + }); + describe('When creating an ECS Cluster', () => { testDeprecated('with no properties set, it correctly sets default properties', () => { // GIVEN From 3e2f05b578f4998c613843e4ed1bd7e2c9a38369 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Mon, 6 Mar 2023 20:12:07 +0100 Subject: [PATCH 04/22] docs(cdk): updated README with `toolkitBucket` bootstrap configuration object (#24451) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `--toolkit-bucket-name` and `--bootstrap-kms-key-id` are specified in `cdk.json` by passing a `toolkitBucket` [object](https://github.com/aws/aws-cdk/blob/3d7505b5a9c3daf5edfecdb4576b555bfe8d7553/packages/aws-cdk/lib/cli.ts#L503-L504). The [documentation on the website](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-config) should also be updated. Closes #24259 . ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md index 009dd9a192389..175adfc9e6508 100644 --- a/packages/aws-cdk/README.md +++ b/packages/aws-cdk/README.md @@ -757,8 +757,11 @@ Some of the interesting keys that can be used in the JSON configuration files: "key": "value" }, "toolkitStackName": "foo", // Customize 'bootstrap' stack name (--toolkit-stack-name=foo) - "toolkitBucketName": "fooBucket", // Customize 'bootstrap' bucket name (--toolkit-bucket-name=fooBucket) - "versionReporting": false, // Opt-out of version reporting (--no-version-reporting) + "toolkitBucket": { + "bucketName": "fooBucket", // Customize 'bootstrap' bucket name (--toolkit-bucket-name=fooBucket) + "kmsKeyId": "fooKMSKey" // Customize 'bootstrap' KMS key id (--bootstrap-kms-key-id=fooKMSKey) + }, + "versionReporting": false, // Opt-out of version reporting (--no-version-reporting) } ``` From a4856e997684f84476fe92e00afcd4da76a69b04 Mon Sep 17 00:00:00 2001 From: Markus Lindqvist Date: Mon, 6 Mar 2023 21:52:59 +0200 Subject: [PATCH 05/22] fix(core): Fix dotnet version check to allow .NET 7.0 (#24467) Fix dotnet version check to allow .NET 7.0 Closes #24466. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- scripts/check-build-prerequisites.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-build-prerequisites.sh b/scripts/check-build-prerequisites.sh index 93f9606e7c52e..49d6feef733be 100755 --- a/scripts/check-build-prerequisites.sh +++ b/scripts/check-build-prerequisites.sh @@ -127,7 +127,7 @@ app_min="6.0.100" check_which $app $app_min app_v=$(${app} --list-sdks) echo -e "Checking dotnet version... \c" -if [ $(echo $app_v | grep -c -E "6\.[0-9]+\.[0-9]+") -eq 1 ] +if [ $(echo $app_v | grep -c -E "[67]\.[0-9]+\.[0-9]+") -eq 1 ] then echo "Ok" else From 925161070a8ca943432fdd0c228105313569b257 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Mon, 6 Mar 2023 20:34:10 +0000 Subject: [PATCH 06/22] chore: fix go init template test to unblock v2 pipeline (#24472) The v2 pipeline is currently blocked due to the new go integ test failing. This change adds the correct go replacement and fixes a failing test in the sample app. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cli-integ/tests/init-go/init-go.integtest.ts | 2 +- .../lib/init-templates/sample-app/go/%name%_test.template.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/init-go/init-go.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/init-go/init-go.integtest.ts index f9772a7d80460..779078ac68739 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/init-go/init-go.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/init-go/init-go.integtest.ts @@ -8,7 +8,7 @@ import { integTest, withTemporaryDirectory, ShellHelper, withPackages } from '.. await context.packages.makeCliAvailable(); await shell.shell(['cdk', 'init', '-l', 'go', template]); - await shell.shell(['go', 'mod', 'edit', '-replace', 'github.com/aws/aws-cdk-go/awscdk=$dist_root/go/awscdk']); + await shell.shell(['go', 'mod', 'edit', '-replace', 'github.com/aws/aws-cdk-go/awscdk/v2=$CODEBUILD_SRC_DIR/go/awscdk']); await shell.shell(['go', 'mod', 'tidy']); await shell.shell(['go', 'test']); await shell.shell(['cdk', 'synth']); diff --git a/packages/aws-cdk/lib/init-templates/sample-app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/sample-app/go/%name%_test.template.go index 56181ebe4b377..d7d6ce936326d 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/go/%name%_test.template.go +++ b/packages/aws-cdk/lib/init-templates/sample-app/go/%name%_test.template.go @@ -16,7 +16,7 @@ func Test%name.PascalCased%Stack(t *testing.T) { stack := New%name.PascalCased%Stack(app, "MyStack", nil) // THEN - template := assertions.Template_FromStack(stack) + template := assertions.Template_FromStack(stack, nil) template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{ "VisibilityTimeout": 300, From 3db1a0d0bcf615871a225919eed235b78904e144 Mon Sep 17 00:00:00 2001 From: Liwei Wang <80005213+liwewang-amazon@users.noreply.github.com> Date: Tue, 7 Mar 2023 01:04:44 -0800 Subject: [PATCH 07/22] fix(servicecatalogappregistry): allow disabling automatic CfnOutput (#24483) When an application is created using `Application` construct, an output is automatically created in the customer defined stack without customer's intention to show related Application Manager URL for the application created. This can increase customer's CFN output usage without customer acknowledge and control. This commit: - emits the CFN Output in the AppRegistry managed stack where the application is created to allow all the stacks deployed in the cdk project to be associated to the application. Customers can control whether to emit the URL as CFN output by setting `emitApplicationManagerUrlAsOutput`. - changes `applicationManagerUrl` to a string type. Customers can create further create CFN output from this property. Closes #23779 BREAKING CHANGE: This commit contains destructive changes to the RAM Share. Since the application RAM share name is calculated by the application construct, where one property is removed. Integration test detects a breaking change where RAM share will be created. Integration test snapshot is updated to cater this destructive change. ---- *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 | 22 +- .../lib/application.ts | 8 +- .../lib/target-application.ts | 16 ++ .../test/application-associator.test.ts | 51 ++++ .../test/application.test.ts | 15 +- ...nAssociator-d50dd3259875-Stack.assets.json | 20 ++ ...ssociator-d50dd3259875-Stack.template.json | 64 +++++ ...efaultTestDeployAssert2A5F2DB9.assets.json | 19 ++ ...aultTestDeployAssert2A5F2DB9.template.json | 48 ++++ .../cdk.out | 1 + ...catalogappregistry-application.assets.json | 19 ++ ...talogappregistry-application.template.json | 48 ++++ .../integ.json | 12 + ...licationresourcesStack4399A149.assets.json | 19 ++ ...cationresourcesStack4399A149.template.json | 48 ++++ .../manifest.json | 250 ++++++++++++++++ .../tree.json | 266 ++++++++++++++++++ ...nteg.application-associator.disable-url.ts | 21 ++ ...catalogappregistry-application.assets.json | 4 +- ...talogappregistry-application.template.json | 21 +- .../manifest.json | 12 +- .../integ.application.js.snapshot/tree.json | 16 +- 22 files changed, 944 insertions(+), 56 deletions(-) create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.ts diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/README.md b/packages/@aws-cdk/aws-servicecatalogappregistry/README.md index 6c2ce7bf8d1d2..801f2f084b07e 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/README.md +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/README.md @@ -84,7 +84,27 @@ const associatedApp = new appreg.ApplicationAssociator(app, 'AssociatedApplicati }); ``` -This will create an application `MyAssociatedApplication` with the `TagKey` as `managedBy` and `TagValue` as `CDK_Application_Associator`. +This will create a stack `MyAssociatedApplicationStack` containing an application `MyAssociatedApplication` +with the `TagKey` as `managedBy` and `TagValue` as `CDK_Application_Associator`. + +By default, the stack will have System Managed Application Manager console URL as its output for the application created. +If you want to remove the output, then use as shown in the example below: + +```ts +const app = new App(); +const associatedApp = new appreg.ApplicationAssociator(app, 'AssociatedApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + applicationName: 'MyAssociatedApplication', + // 'Application containing stacks deployed via CDK.' is the default + applicationDescription: 'Associated Application description', + stackName: 'MyAssociatedApplicationStack', + // Disables emitting Application Manager url as output + emitApplicationManagerUrlAsOutput: false, + // AWS Account and Region that are implied by the current CLI configuration is the default + env: { account: '123456789012', region: 'us-east-1' }, + })], +}); +``` 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/application.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application.ts index 81f5584e6719f..bb5abdfed4da8 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application.ts @@ -256,7 +256,7 @@ export class Application extends ApplicationBase { * Application manager URL for the Application. * @attribute */ - public readonly applicationManagerUrl?: cdk.CfnOutput; + public readonly applicationManagerUrl?: string; public readonly applicationArn: string; public readonly applicationId: string; public readonly applicationName?: string; @@ -277,10 +277,8 @@ export class Application extends ApplicationBase { this.applicationName = props.applicationName; this.nodeAddress = cdk.Names.nodeUniqueId(application.node); - this.applicationManagerUrl = new cdk.CfnOutput(this, 'ApplicationManagerUrl', { - value: `https://${this.env.region}.console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-${this.applicationName}`, - description: 'Application manager url for the application created.', - }); + this.applicationManagerUrl = + `https://${this.env.region}.console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-${this.applicationName}`; } protected generateUniqueHash(resourceAddress: string): string { diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts index 7c13bbdf55895..2b6f13db1b0cb 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts @@ -33,6 +33,13 @@ export interface CreateTargetApplicationOptions extends TargetApplicationCommonO * @default - Application containing stacks deployed via CDK. */ readonly applicationDescription?: string; + + /** + * Whether create cloudFormation Output for application manager URL. + * + * @default - Application containing stacks deployed via CDK. + */ + readonly emitApplicationManagerUrlAsOutput?: boolean; } /** @@ -99,6 +106,8 @@ class CreateTargetApplication extends TargetApplication { this.applicationOptions.description || 'Stack to create AppRegistry application'; (this.applicationOptions.env as cdk.Environment) = this.applicationOptions.env || { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION }; + (this.applicationOptions.emitApplicationManagerUrlAsOutput as boolean) = this.applicationOptions.emitApplicationManagerUrlAsOutput ?? true; + const applicationStack = new cdk.Stack(scope, stackId, this.applicationOptions); const appRegApplication = new Application(applicationStack, 'DefaultCdkApplication', { applicationName: this.applicationOptions.applicationName, @@ -106,6 +115,13 @@ class CreateTargetApplication extends TargetApplication { }); cdk.Tags.of(appRegApplication).add('managedBy', 'CDK_Application_Associator'); + if (this.applicationOptions.emitApplicationManagerUrlAsOutput) { + new cdk.CfnOutput(appRegApplication, 'ApplicationManagerUrl', { + value: `https://${appRegApplication.env.region}.console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-${appRegApplication.applicationName}`, + description: 'System Manager Application Manager URL for the application created.', + }); + } + return { application: appRegApplication, }; 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 da882d28d06ce..c61cf4f10e6cd 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts @@ -28,6 +28,34 @@ describe('Scope based Associations with Application within Same Account', () => Name: 'MyAssociatedApplication', Tags: { managedBy: 'CDK_Application_Associator' }, }); + Template.fromStack(appAssociator.appRegistryApplication().stack).hasOutput('DefaultCdkApplicationApplicationManagerUrl27C138EF', {}); + Template.fromStack(anotherStack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); + Template.fromStack(anotherStack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::ResourceAssociation', { + Application: 'MyAssociatedApplication', + Resource: { Ref: 'AWS::StackId' }, + }); + }); + + test('ApplicationAssociator with url disabled will not create cfn output', () => { + const appAssociator = new appreg.ApplicationAssociator(app, 'MyApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + applicationName: 'MyAssociatedApplication', + stackName: 'MyAssociatedApplicationStack', + emitApplicationManagerUrlAsOutput: false, + })], + }); + + 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' }, + }); + + expect( + Template.fromStack(appAssociator.appRegistryApplication().stack) + .findOutputs('*', {}), + ).toEqual({}); Template.fromStack(anotherStack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); Template.fromStack(anotherStack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::ResourceAssociation', { Application: 'MyAssociatedApplication', @@ -93,6 +121,28 @@ describe('Scope based Associations with Application with Cross Region/Account', Template.fromStack(nestedStack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); }); + test('ApplicationAssociator disables cfn output', () => { + const appAssociator = new appreg.ApplicationAssociator(app, 'MyApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + applicationName: 'MyAssociatedApplication', + stackName: 'MyAssociatedApplicationStack', + emitApplicationManagerUrlAsOutput: false, + })], + }); + const firstStack = new cdk.Stack(app, 'testStack', { + env: { account: 'account2', region: 'region' }, + }); + const nestedStack = new cdk.Stack(firstStack, 'MyFirstStack', { + env: { account: 'account2', region: 'region' }, + }); + + expect( + Template.fromStack(appAssociator.appRegistryApplication().stack).findOutputs('*', {}), + ).toEqual({}); + Template.fromStack(firstStack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); + Template.fromStack(nestedStack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); + }); + test('ApplicationAssociator creation failed when neither Application name nor ARN is provided', () => { expect(() => { new appreg.ApplicationAssociator(app, 'MyApplication', { @@ -187,6 +237,7 @@ describe('Scope based Associations with Application with Cross Region/Account', associateStage: true, }); app.synth(); + Template.fromStack(application.appRegistryApplication().stack).hasOutput('DefaultCdkApplicationApplicationManagerUrl27C138EF', {}); Template.fromStack(pipelineStack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); }); }); diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts index 04349d3d33bd5..f78afa9d3ca3c 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts @@ -39,8 +39,7 @@ describe('Application', () => { description: description, }); - Template.fromStack(stack).hasOutput('MyApplicationApplicationManagerUrlB79EF34D', {}); - expect(application.applicationManagerUrl?.value).toContain('AWS_AppRegistry_Application-testApplication'); + expect(application.applicationManagerUrl).toContain('AWS_AppRegistry_Application-testApplication'); Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::Application', { Description: description, }); @@ -256,7 +255,7 @@ describe('Application', () => { Template.fromStack(stack).hasResourceProperties('AWS::RAM::ResourceShare', { AllowExternalPrincipals: false, - Name: 'RAMShare5bb637032063', + Name: 'RAMSharee6e0e560e6f8', Principals: ['arn:aws:organizations::123456789012:organization/o-70oi5564q1'], ResourceArns: [{ 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Arn'] }], PermissionArns: ['arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationReadOnly'], @@ -270,7 +269,7 @@ describe('Application', () => { Template.fromStack(stack).hasResourceProperties('AWS::RAM::ResourceShare', { AllowExternalPrincipals: false, - Name: 'RAMShare5bb637032063', + Name: 'RAMSharee6e0e560e6f8', Principals: ['123456789012'], ResourceArns: [{ 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Arn'] }], PermissionArns: ['arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationReadOnly'], @@ -286,7 +285,7 @@ describe('Application', () => { Template.fromStack(stack).hasResourceProperties('AWS::RAM::ResourceShare', { AllowExternalPrincipals: false, - Name: 'RAMShare5bb637032063', + Name: 'RAMSharee6e0e560e6f8', Principals: ['arn:aws:iam::123456789012:role/myRole'], ResourceArns: [{ 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Arn'] }], PermissionArns: ['arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationReadOnly'], @@ -302,7 +301,7 @@ describe('Application', () => { Template.fromStack(stack).hasResourceProperties('AWS::RAM::ResourceShare', { AllowExternalPrincipals: false, - Name: 'RAMShare5bb637032063', + Name: 'RAMSharee6e0e560e6f8', Principals: ['arn:aws:iam::123456789012:user/myUser'], ResourceArns: [{ 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Arn'] }], PermissionArns: ['arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationReadOnly'], @@ -317,7 +316,7 @@ describe('Application', () => { Template.fromStack(stack).hasResourceProperties('AWS::RAM::ResourceShare', { AllowExternalPrincipals: false, - Name: 'RAMShare5bb637032063', + Name: 'RAMSharee6e0e560e6f8', Principals: ['arn:aws:organizations::123456789012:organization/o-70oi5564q1'], ResourceArns: [{ 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Arn'] }], PermissionArns: ['arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationReadOnly'], @@ -332,7 +331,7 @@ describe('Application', () => { Template.fromStack(stack).hasResourceProperties('AWS::RAM::ResourceShare', { AllowExternalPrincipals: false, - Name: 'RAMShare5bb637032063', + Name: 'RAMSharee6e0e560e6f8', Principals: ['arn:aws:organizations::123456789012:organization/o-70oi5564q1'], ResourceArns: [{ 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Arn'] }], PermissionArns: ['arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationAllowAssociation'], diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.assets.json new file mode 100644 index 0000000000000..05f672f226537 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.assets.json @@ -0,0 +1,20 @@ +{ + "version": "30.1.0", + "files": { + "2669d20378c55153134983ffc6c70d7d39f75ab888356d2fbf04e21c11531590": { + "source": { + "path": "ApplicationAssociator-d50dd3259875-Stack.template.json", + "packaging": "file" + }, + "destinations": { + "828800149827-us-east-2": { + "bucketName": "cdk-hnb659fds-assets-828800149827-us-east-2", + "objectKey": "2669d20378c55153134983ffc6c70d7d39f75ab888356d2fbf04e21c11531590.json", + "region": "us-east-2", + "assumeRoleArn": "arn:${AWS::Partition}:iam::828800149827:role/cdk-hnb659fds-file-publishing-role-828800149827-us-east-2" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.template.json new file mode 100644 index 0000000000000..5bdc6537a2390 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociator-d50dd3259875-Stack.template.json @@ -0,0 +1,64 @@ +{ + "Description": "Stack to create AppRegistry application", + "Resources": { + "DefaultCdkApplication4573D5A3": { + "Type": "AWS::ServiceCatalogAppRegistry::Application", + "Properties": { + "Name": "AppRegistryAssociatedApplication", + "Description": "Application containing stacks deployed via CDK.", + "Tags": { + "managedBy": "CDK_Application_Associator" + } + } + }, + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": { + "Fn::GetAtt": [ + "DefaultCdkApplication4573D5A3", + "Id" + ] + }, + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "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-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json new file mode 100644 index 0000000000000..0838d8b3519fd --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json @@ -0,0 +1,19 @@ +{ + "version": "30.1.0", + "files": { + "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": { + "source": { + "path": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.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-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json new file mode 100644 index 0000000000000..ecc817b74774a --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json @@ -0,0 +1,48 @@ +{ + "Resources": { + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": "AppRegistryAssociatedApplication", + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "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-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/cdk.out b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/cdk.out new file mode 100644 index 0000000000000..b72fef144f05c --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"30.1.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.assets.json new file mode 100644 index 0000000000000..648f760e7b33c --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.assets.json @@ -0,0 +1,19 @@ +{ + "version": "30.1.0", + "files": { + "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": { + "source": { + "path": "integ-servicecatalogappregistry-application.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.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-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.template.json new file mode 100644 index 0000000000000..ecc817b74774a --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ-servicecatalogappregistry-application.template.json @@ -0,0 +1,48 @@ +{ + "Resources": { + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": "AppRegistryAssociatedApplication", + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "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-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ.json new file mode 100644 index 0000000000000..5b9d9dca1ae87 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "30.1.0", + "testCases": { + "ApplicationAssociatorTest/DefaultTest": { + "stacks": [ + "integ-servicecatalogappregistry-application" + ], + "assertionStack": "ApplicationAssociatorTest/DefaultTest/DeployAssert", + "assertionStackName": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.assets.json new file mode 100644 index 0000000000000..93889acb4f6e0 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.assets.json @@ -0,0 +1,19 @@ +{ + "version": "30.1.0", + "files": { + "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": { + "source": { + "path": "integservicecatalogappregistryapplicationresourcesStack4399A149.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.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-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.template.json new file mode 100644 index 0000000000000..ecc817b74774a --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/integservicecatalogappregistryapplicationresourcesStack4399A149.template.json @@ -0,0 +1,48 @@ +{ + "Resources": { + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": "AppRegistryAssociatedApplication", + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "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-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/manifest.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/manifest.json new file mode 100644 index 0000000000000..f12eb72323dee --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/manifest.json @@ -0,0 +1,250 @@ +{ + "version": "30.1.0", + "artifacts": { + "integservicecatalogappregistryapplicationresourcesStack4399A149.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integservicecatalogappregistryapplicationresourcesStack4399A149.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integservicecatalogappregistryapplicationresourcesStack4399A149": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integservicecatalogappregistryapplicationresourcesStack4399A149.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}/19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integservicecatalogappregistryapplicationresourcesStack4399A149.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": [ + "ApplicationAssociator-d50dd3259875-Stack", + "integservicecatalogappregistryapplicationresourcesStack4399A149.assets" + ], + "metadata": { + "/integ-servicecatalogappregistry-application/resourcesStack": [ + { + "type": "aws:cdk:warning", + "data": "Environment agnostic stack determined, AppRegistry association might not work as expected in case you deploy cross-region or cross-account stack." + } + ], + "/integ-servicecatalogappregistry-application/resourcesStack/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/integ-servicecatalogappregistry-application/resourcesStack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-servicecatalogappregistry-application/resourcesStack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-servicecatalogappregistry-application/resourcesStack" + }, + "integ-servicecatalogappregistry-application.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-servicecatalogappregistry-application.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-servicecatalogappregistry-application": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integ-servicecatalogappregistry-application.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}/19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-servicecatalogappregistry-application.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": [ + "ApplicationAssociator-d50dd3259875-Stack", + "integ-servicecatalogappregistry-application.assets" + ], + "metadata": { + "/integ-servicecatalogappregistry-application": [ + { + "type": "aws:cdk:warning", + "data": "Environment agnostic stack determined, AppRegistry association might not work as expected in case you deploy cross-region or cross-account stack." + } + ], + "/integ-servicecatalogappregistry-application/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/integ-servicecatalogappregistry-application/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-servicecatalogappregistry-application/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-servicecatalogappregistry-application" + }, + "ApplicationAssociator-d50dd3259875-Stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ApplicationAssociator-d50dd3259875-Stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ApplicationAssociator-d50dd3259875-Stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://828800149827/us-east-2", + "properties": { + "templateFile": "ApplicationAssociator-d50dd3259875-Stack.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::828800149827:role/cdk-hnb659fds-deploy-role-828800149827-us-east-2", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::828800149827:role/cdk-hnb659fds-cfn-exec-role-828800149827-us-east-2", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-828800149827-us-east-2/2669d20378c55153134983ffc6c70d7d39f75ab888356d2fbf04e21c11531590.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "ApplicationAssociator-d50dd3259875-Stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::828800149827:role/cdk-hnb659fds-lookup-role-828800149827-us-east-2", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "ApplicationAssociator-d50dd3259875-Stack.assets" + ], + "metadata": { + "/ApplicationAssociator-d50dd3259875-Stack/DefaultCdkApplication/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DefaultCdkApplication4573D5A3" + } + ], + "/ApplicationAssociator-d50dd3259875-Stack/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/ApplicationAssociator-d50dd3259875-Stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/ApplicationAssociator-d50dd3259875-Stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "ApplicationAssociator-d50dd3259875-Stack" + }, + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.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}/19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.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": [ + "ApplicationAssociator-d50dd3259875-Stack", + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets" + ], + "metadata": { + "/ApplicationAssociatorTest/DefaultTest/DeployAssert": [ + { + "type": "aws:cdk:warning", + "data": "Environment agnostic stack determined, AppRegistry association might not work as expected in case you deploy cross-region or cross-account stack." + } + ], + "/ApplicationAssociatorTest/DefaultTest/DeployAssert/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/ApplicationAssociatorTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/ApplicationAssociatorTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "ApplicationAssociatorTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/tree.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/tree.json new file mode 100644 index 0000000000000..48e6d11ac8d14 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.js.snapshot/tree.json @@ -0,0 +1,266 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-servicecatalogappregistry-application": { + "id": "integ-servicecatalogappregistry-application", + "path": "integ-servicecatalogappregistry-application", + "children": { + "resourcesStack": { + "id": "resourcesStack", + "path": "integ-servicecatalogappregistry-application/resourcesStack", + "children": { + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "integ-servicecatalogappregistry-application/resourcesStack/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": "AppRegistryAssociatedApplication", + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-servicecatalogappregistry-application/resourcesStack/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-servicecatalogappregistry-application/resourcesStack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "integ-servicecatalogappregistry-application/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": "AppRegistryAssociatedApplication", + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-servicecatalogappregistry-application/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-servicecatalogappregistry-application/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "RegisterCdkApplication": { + "id": "RegisterCdkApplication", + "path": "RegisterCdkApplication", + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.ApplicationAssociator", + "version": "0.0.0" + } + }, + "ApplicationAssociator-d50dd3259875-Stack": { + "id": "ApplicationAssociator-d50dd3259875-Stack", + "path": "ApplicationAssociator-d50dd3259875-Stack", + "children": { + "DefaultCdkApplication": { + "id": "DefaultCdkApplication", + "path": "ApplicationAssociator-d50dd3259875-Stack/DefaultCdkApplication", + "children": { + "Resource": { + "id": "Resource", + "path": "ApplicationAssociator-d50dd3259875-Stack/DefaultCdkApplication/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::Application", + "aws:cdk:cloudformation:props": { + "name": "AppRegistryAssociatedApplication", + "description": "Application containing stacks deployed via CDK.", + "tags": { + "managedBy": "CDK_Application_Associator" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnApplication", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.Application", + "version": "0.0.0" + } + }, + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "ApplicationAssociator-d50dd3259875-Stack/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": { + "Fn::GetAtt": [ + "DefaultCdkApplication4573D5A3", + "Id" + ] + }, + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "ApplicationAssociator-d50dd3259875-Stack/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "ApplicationAssociator-d50dd3259875-Stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "ApplicationAssociatorTest": { + "id": "ApplicationAssociatorTest", + "path": "ApplicationAssociatorTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "ApplicationAssociatorTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "ApplicationAssociatorTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.252" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "ApplicationAssociatorTest/DefaultTest/DeployAssert", + "children": { + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "ApplicationAssociatorTest/DefaultTest/DeployAssert/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": "AppRegistryAssociatedApplication", + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "ApplicationAssociatorTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "ApplicationAssociatorTest/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.252" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.ts new file mode 100644 index 0000000000000..67d35fe3cb2a5 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.disable-url.ts @@ -0,0 +1,21 @@ +import * as cdk from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; +import * as appreg from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'integ-servicecatalogappregistry-application'); + +new appreg.ApplicationAssociator(app, 'RegisterCdkApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + applicationName: 'AppRegistryAssociatedApplication', + emitApplicationManagerUrlAsOutput: false, + })], +}); + +new cdk.Stack(stack, 'resourcesStack'); + +new integ.IntegTest(app, 'ApplicationAssociatorTest', { + testCases: [stack], +}); + +app.synth(); \ No newline at end of file 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 d8c62f0055d75..9081ac09e1a15 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": "30.1.0", "files": { - "0d4e060fe5da6b164b9df46b0dc0cd20e7962c6cb531ffe08e6e5b99418f13de": { + "2332c6df6777cc571585060fa4888d6d3b9ef548aa00dcbfc53fbdde386d7591": { "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": "0d4e060fe5da6b164b9df46b0dc0cd20e7962c6cb531ffe08e6e5b99418f13de.json", + "objectKey": "2332c6df6777cc571585060fa4888d6d3b9ef548aa00dcbfc53fbdde386d7591.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 f6ac10354ea89..9fcf50e708a56 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 @@ -39,10 +39,10 @@ } } }, - "TestApplicationRAMShare3dc6227daec11BF3E108": { + "TestApplicationRAMSharead8ba81b8cdd40199FD1": { "Type": "AWS::RAM::ResourceShare", "Properties": { - "Name": "RAMShare3dc6227daec1", + "Name": "RAMSharead8ba81b8cdd", "AllowExternalPrincipals": false, "PermissionArns": [ "arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationReadOnly" @@ -121,23 +121,6 @@ } } }, - "Outputs": { - "TestApplicationApplicationManagerUrlE1058321": { - "Description": "Application manager url for the application created.", - "Value": { - "Fn::Join": [ - "", - [ - "https://", - { - "Ref": "AWS::Region" - }, - ".console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-TestApplication" - ] - ] - } - } - }, "Parameters": { "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", 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 982ee193a4f57..689db41c3804f 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}/0d4e060fe5da6b164b9df46b0dc0cd20e7962c6cb531ffe08e6e5b99418f13de.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2332c6df6777cc571585060fa4888d6d3b9ef548aa00dcbfc53fbdde386d7591.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -39,12 +39,6 @@ "data": "TestApplication2FBC585F" } ], - "/integ-servicecatalogappregistry-application/TestApplication/ApplicationManagerUrl": [ - { - "type": "aws:cdk:logicalId", - "data": "TestApplicationApplicationManagerUrlE1058321" - } - ], "/integ-servicecatalogappregistry-application/TestApplication/ResourceAssociationd232b63e52a8": [ { "type": "aws:cdk:logicalId", @@ -57,10 +51,10 @@ "data": "TestApplicationAttributeGroupAssociation4ba7f5842818B8EE1C6F" } ], - "/integ-servicecatalogappregistry-application/TestApplication/RAMShare3dc6227daec1": [ + "/integ-servicecatalogappregistry-application/TestApplication/RAMSharead8ba81b8cdd": [ { "type": "aws:cdk:logicalId", - "data": "TestApplicationRAMShare3dc6227daec11BF3E108" + "data": "TestApplicationRAMSharead8ba81b8cdd40199FD1" } ], "/integ-servicecatalogappregistry-application/TestAttributeGroup/Resource": [ 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 8ed129f0c0e65..ef111bc49a7b8 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 @@ -27,14 +27,6 @@ "version": "0.0.0" } }, - "ApplicationManagerUrl": { - "id": "ApplicationManagerUrl", - "path": "integ-servicecatalogappregistry-application/TestApplication/ApplicationManagerUrl", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnOutput", - "version": "0.0.0" - } - }, "ResourceAssociationd232b63e52a8": { "id": "ResourceAssociationd232b63e52a8", "path": "integ-servicecatalogappregistry-application/TestApplication/ResourceAssociationd232b63e52a8", @@ -83,13 +75,13 @@ "version": "0.0.0" } }, - "RAMShare3dc6227daec1": { - "id": "RAMShare3dc6227daec1", - "path": "integ-servicecatalogappregistry-application/TestApplication/RAMShare3dc6227daec1", + "RAMSharead8ba81b8cdd": { + "id": "RAMSharead8ba81b8cdd", + "path": "integ-servicecatalogappregistry-application/TestApplication/RAMSharead8ba81b8cdd", "attributes": { "aws:cdk:cloudformation:type": "AWS::RAM::ResourceShare", "aws:cdk:cloudformation:props": { - "name": "RAMShare3dc6227daec1", + "name": "RAMSharead8ba81b8cdd", "allowExternalPrincipals": false, "permissionArns": [ "arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationReadOnly" From c02e52ba3255ed686ca22c2c917ca72acfeb6714 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Tue, 7 Mar 2023 02:25:33 -0800 Subject: [PATCH 08/22] docs(cfnspec): update CloudFormation documentation (#24488) --- .../spec-source/cfn-docs/cfn-docs.json | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json b/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json index d0d8c99da85eb..3043bc2589cdd 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json +++ b/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json @@ -7701,9 +7701,9 @@ "Arn": "The Amazon Resource Number (ARN) of the activated extension, in this account and Region.", "Ref": "`Ref` returns the Amazon Resource Number (ARN) of the activated extension, in this account and Region.\n\n`{ \"Ref\": \"arn:aws:cloudformation:us-east-1:123456789013:type/resource/My-Example\" }`" }, - "description": "Activates a public third-party extension, making it available for use in stack templates. For more information, see [Using public extensions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry-public.html) in the *AWS CloudFormation User Guide* .\n\nOnce you have activated a public third-party extension in your account and region, use [SetTypeConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetTypeConfiguration.html) to specify configuration properties for the extension. For more information, see [Configuring extensions at the account level](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry-register.html#registry-set-configuration) in the *CloudFormation User Guide* .", + "description": "Activates a public third-party extension, making it available for use in stack templates. For more information, see [Using public extensions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry-public.html) in the *AWS CloudFormation User Guide* .\n\nOnce you have activated a public third-party extension in your account and Region, use [SetTypeConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetTypeConfiguration.html) to specify configuration properties for the extension. For more information, see [Configuring extensions at the account level](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry-register.html#registry-set-configuration) in the *CloudFormation User Guide* .", "properties": { - "AutoUpdate": "Whether to automatically update the extension in this account and region when a new *minor* version is published by the extension publisher. Major versions released by the publisher must be manually updated.\n\nThe default is `true` .", + "AutoUpdate": "Whether to automatically update the extension in this account and Region when a new *minor* version is published by the extension publisher. Major versions released by the publisher must be manually updated.\n\nThe default is `true` .", "ExecutionRoleArn": "The name of the IAM execution role to use to activate the extension.", "LoggingConfig": "Specifies logging configuration information for an extension.", "MajorVersion": "The major version of this extension you want to activate, if multiple major versions are available. The default is the latest major version. CloudFormation uses the latest available *minor* version of the major version selected.\n\nYou can specify `MajorVersion` or `VersionBump` , but not both.", @@ -7711,7 +7711,7 @@ "PublisherId": "The ID of the extension publisher.\n\nConditional: You must specify `PublicTypeArn` , or `TypeName` , `Type` , and `PublisherId` .", "Type": "The extension type.\n\nConditional: You must specify `PublicTypeArn` , or `TypeName` , `Type` , and `PublisherId` .", "TypeName": "The name of the extension.\n\nConditional: You must specify `PublicTypeArn` , or `TypeName` , `Type` , and `PublisherId` .", - "TypeNameAlias": "An alias to assign to the public extension, in this account and region. If you specify an alias for the extension, CloudFormation treats the alias as the extension type name within this account and region. You must use the alias to refer to the extension in your templates, API calls, and CloudFormation console.\n\nAn extension alias must be unique within a given account and region. You can activate the same public resource multiple times in the same account and region, using different type name aliases.", + "TypeNameAlias": "An alias to assign to the public extension, in this account and Region. If you specify an alias for the extension, CloudFormation treats the alias as the extension type name within this account and Region. You must use the alias to refer to the extension in your templates, API calls, and CloudFormation console.\n\nAn extension alias must be unique within a given account and Region. You can activate the same public resource multiple times in the same account and Region, using different type name aliases.", "VersionBump": "Manually updates a previously-activated type to a new major or minor version, if available. You can also use this parameter to update the value of `AutoUpdate` .\n\n- `MAJOR` : CloudFormation updates the extension to the newest major version, if one is available.\n- `MINOR` : CloudFormation updates the extension to the newest minor version, if one is available." } }, @@ -14647,7 +14647,7 @@ "SourceDestCheck": "Enable or disable source/destination checks, which ensure that the instance is either the source or the destination of any traffic that it receives. If the value is `true` , source/destination checks are enabled; otherwise, they are disabled. The default value is `true` . You must disable source/destination checks if the instance runs services such as network address translation, routing, or firewalls.", "SsmAssociations": "The SSM [document](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-document.html) and parameter values in AWS Systems Manager to associate with this instance. To use this property, you must specify an IAM instance profile role for the instance. For more information, see [Create an IAM instance profile for Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-configuring-access-role.html) in the *AWS Systems Manager User Guide* .\n\n> You can currently associate only one document with an instance.", "SubnetId": "[EC2-VPC] The ID of the subnet to launch the instance into.\n\nIf you specify a network interface, you must specify any subnets as part of the network interface.", - "Tags": "The tags to add to the instance. These tags are not applied to the EBS volumes, such as the root volume.", + "Tags": "The tags to add to the instance. These tags are not applied to the EBS volumes, such as the root volume, unless [PropagateTagsToVolumeOnCreation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-propagatetagstovolumeoncreation) is `true` .", "Tenancy": "The tenancy of the instance (if the instance is running in a VPC). An instance with a tenancy of `dedicated` runs on single-tenant hardware.", "UserData": "The user data script to make available to the instance. User data is limited to 16 KB. You must provide base64-encoded text. For more information, see [Fn::Base64](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-base64.html) .\n\nUser data runs only at instance launch. For more information, see [Run commands on your Linux instance at launch](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html) and [Run commands on your Windows instance at launch](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html) .", "Volumes": "The volumes to attach to the instance." @@ -15812,7 +15812,7 @@ }, "description": "Specifies a security group. To create a security group, use the [VpcId](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-vpcid) property to specify the VPC for which to create the security group.\n\nThis type supports updates. For more information about updating stacks, see [AWS CloudFormation Stacks Updates](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks.html) .\n\n> To cross-reference two security groups in the ingress and egress rules of those security groups, use the [AWS::EC2::SecurityGroupEgress](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html) and [AWS::EC2::SecurityGroupIngress](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-ingress.html) resources to define your rules. Do not use the embedded ingress and egress rules in the `AWS::EC2::SecurityGroup` . Doing so creates a circular dependency, which AWS CloudFormation doesn't allow.", "properties": { - "GroupDescription": "A description for the security group. This is informational only.\n\nConstraints: Up to 255 characters in length\n\nConstraints for EC2-Classic: ASCII characters\n\nConstraints for EC2-VPC: a-z, A-Z, 0-9, spaces, and ._-:/()#,@[]+=&;{}!$*", + "GroupDescription": "A description for the security group.\n\nConstraints: Up to 255 characters in length\n\nConstraints for EC2-Classic: ASCII characters\n\nConstraints for EC2-VPC: a-z, A-Z, 0-9, spaces, and ._-:/()#,@[]+=&;{}!$*", "GroupName": "The name of the security group.\n\nConstraints: Up to 255 characters in length. Cannot start with `sg-` .\n\nConstraints for EC2-Classic: ASCII characters\n\nConstraints for EC2-VPC: a-z, A-Z, 0-9, spaces, and ._-:/()#,@[]+=&;{}!$*", "SecurityGroupEgress": "[VPC only] The outbound rules associated with the security group. There is a short interruption during which you cannot connect to the security group.", "SecurityGroupIngress": "The inbound rules associated with the security group. There is a short interruption during which you cannot connect to the security group.", @@ -16674,7 +16674,7 @@ "AWS::EC2::VPCEndpointService": { "attributes": { "Ref": "`Ref` returns the ID of the VPC endpoint service configuration.", - "ServiceId": "" + "ServiceId": "The ID of the endpoint service." }, "description": "Creates a VPC endpoint service configuration to which service consumers ( AWS accounts, users, and IAM roles) can connect.\n\nTo create an endpoint service configuration, you must first create one of the following for your service:\n\n- A [Network Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html) . Service consumers connect to your service using an interface endpoint.\n- A [Gateway Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/gateway/introduction.html) . Service consumers connect to your service using a Gateway Load Balancer endpoint.\n\nFor more information, see the [AWS PrivateLink User Guide](https://docs.aws.amazon.com/vpc/latest/privatelink/) .", "properties": { @@ -39561,7 +39561,7 @@ }, "AWS::Pipes::Pipe.FilterCriteria": { "attributes": {}, - "description": "The collection of event patterns used to filter events. For more information, see [Events and Event Patterns](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-and-event-patterns.html) in the *Amazon EventBridge User Guide* .", + "description": "The collection of event patterns used to filter events.\n\nTo remove a filter, specify a `FilterCriteria` object with an empty array of `Filter` objects.\n\nFor more information, see [Events and Event Patterns](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-and-event-patterns.html) in the *Amazon EventBridge User Guide* .", "properties": { "Filters": "The event patterns." } @@ -39602,7 +39602,7 @@ "description": "The parameters required to set up enrichment on your pipe.", "properties": { "HttpParameters": "Contains the HTTP parameters to use when the target is a API Gateway REST endpoint or EventBridge ApiDestination.\n\nIf you specify an API Gateway REST API or EventBridge ApiDestination as a target, you can use this parameter to specify headers, path parameters, and query string keys/values as part of your target invoking request. If you're using ApiDestinations, the corresponding Connection can also have these values configured. In case of any conflicting keys, values from the Connection take precedence.", - "InputTemplate": "Valid JSON text passed to the enrichment. In this case, nothing from the event itself is passed to the enrichment. For more information, see [The JavaScript Object Notation (JSON) Data Interchange Format](https://docs.aws.amazon.com/http://www.rfc-editor.org/rfc/rfc7159.txt) ." + "InputTemplate": "Valid JSON text passed to the enrichment. In this case, nothing from the event itself is passed to the enrichment. For more information, see [The JavaScript Object Notation (JSON) Data Interchange Format](https://docs.aws.amazon.com/http://www.rfc-editor.org/rfc/rfc7159.txt) .\n\nTo remove an input template, specify an empty string." } }, "AWS::Pipes::Pipe.PipeSourceActiveMQBrokerParameters": { @@ -39662,7 +39662,7 @@ "properties": { "ActiveMQBrokerParameters": "The parameters for using an Active MQ broker as a source.", "DynamoDBStreamParameters": "The parameters for using a DynamoDB stream as a source.", - "FilterCriteria": "The collection of event patterns used to filter events. For more information, see [Events and Event Patterns](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-and-event-patterns.html) in the *Amazon EventBridge User Guide* .", + "FilterCriteria": "The collection of event patterns used to filter events.\n\nTo remove a filter, specify a `FilterCriteria` object with an empty array of `Filter` objects.\n\nFor more information, see [Events and Event Patterns](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-and-event-patterns.html) in the *Amazon EventBridge User Guide* .", "KinesisStreamParameters": "The parameters for using a Kinesis stream as a source.", "ManagedStreamingKafkaParameters": "The parameters for using an MSK stream as a source.", "RabbitMQBrokerParameters": "The parameters for using a Rabbit MQ broker as a source.", @@ -39789,7 +39789,7 @@ "EcsTaskParameters": "The parameters for using an Amazon ECS task as a target.", "EventBridgeEventBusParameters": "The parameters for using an EventBridge event bus as a target.", "HttpParameters": "These are custom parameter to be used when the target is an API Gateway REST APIs or EventBridge ApiDestinations.", - "InputTemplate": "Valid JSON text passed to the target. In this case, nothing from the event itself is passed to the target. For more information, see [The JavaScript Object Notation (JSON) Data Interchange Format](https://docs.aws.amazon.com/http://www.rfc-editor.org/rfc/rfc7159.txt) .", + "InputTemplate": "Valid JSON text passed to the target. In this case, nothing from the event itself is passed to the target. For more information, see [The JavaScript Object Notation (JSON) Data Interchange Format](https://docs.aws.amazon.com/http://www.rfc-editor.org/rfc/rfc7159.txt) .\n\nTo remove an input template, specify an empty string.", "KinesisStreamParameters": "The parameters for using a Kinesis stream as a source.", "LambdaFunctionParameters": "The parameters for using a Lambda function as a target.", "RedshiftDataParameters": "These are custom parameters to be used when the target is a Amazon Redshift cluster to invoke the Amazon Redshift Data API BatchExecuteStatement.", @@ -41837,18 +41837,18 @@ }, "AWS::RedshiftServerless::Namespace": { "attributes": { - "Namespace": "Returns the `Namespace` value.", - "Namespace.AdminUsername": "", - "Namespace.CreationDate": "", - "Namespace.DbName": "", - "Namespace.DefaultIamRoleArn": "", - "Namespace.IamRoles": "", - "Namespace.KmsKeyId": "", - "Namespace.LogExports": "", - "Namespace.NamespaceArn": "", - "Namespace.NamespaceId": "", - "Namespace.NamespaceName": "", - "Namespace.Status": "", + "Namespace": "The collection of computing resources from which an endpoint is created.", + "Namespace.AdminUsername": "The username of the administrator for the first database created in the namespace.", + "Namespace.CreationDate": "The date of when the namespace was created.", + "Namespace.DbName": "The name of the first database created in the namespace.", + "Namespace.DefaultIamRoleArn": "The Amazon Resource Name (ARN) of the IAM role to set as a default in the namespace.", + "Namespace.IamRoles": "A list of IAM roles to associate with the namespace.", + "Namespace.KmsKeyId": "The ID of the AWS Key Management Service key used to encrypt your data.", + "Namespace.LogExports": "The types of logs the namespace can export. Available export types are `User log` , `Connection log` , and `User activity log` .", + "Namespace.NamespaceArn": "The Amazon Resource Name (ARN) associated with a namespace.", + "Namespace.NamespaceId": "The unique identifier of a namespace.", + "Namespace.NamespaceName": "The name of the namespace. Must be between 3-64 alphanumeric characters in lowercase, and it cannot be a reserved word. A list of reserved words can be found in [Reserved Words](https://docs.aws.amazon.com//redshift/latest/dg/r_pg_keywords.html) in the Amazon Redshift Database Developer Guide.", + "Namespace.Status": "The status of the namespace.", "Ref": "When the logical ID of this resource is provided to the Ref intrinsic function, Ref returns the NamespaceName, such as `sample-namespace.` For more information about using the Ref function, see [Ref](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) ." }, "description": "A collection of database objects and users.", @@ -41862,7 +41862,7 @@ "IamRoles": "A list of IAM roles to associate with the namespace.", "KmsKeyId": "The ID of the AWS Key Management Service key used to encrypt your data.", "LogExports": "The types of logs the namespace can export. Available export types are `userlog` , `connectionlog` , and `useractivitylog` .", - "NamespaceName": "The name of the namespace.", + "NamespaceName": "The name of the namespace. Must be between 3-64 alphanumeric characters in lowercase, and it cannot be a reserved word. A list of reserved words can be found in [Reserved Words](https://docs.aws.amazon.com//redshift/latest/dg/r_pg_keywords.html) in the Amazon Redshift Database Developer Guide.", "Tags": "The map of the key-value pairs used to tag the namespace." } }, @@ -41887,22 +41887,22 @@ "attributes": { "Ref": "When the logical ID of this resource is provided to the Ref intrinsic function, Ref returns the WorkgroupName, such as `sample-workgroup.` For more information about using the Ref function, see [Ref](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) .", "Workgroup": "Returns the `Workgroup` value.", - "Workgroup.BaseCapacity": "", + "Workgroup.BaseCapacity": "The base data warehouse capacity of the workgroup in Redshift Processing Units (RPUs).", "Workgroup.ConfigParameters": "", - "Workgroup.CreationDate": "", + "Workgroup.CreationDate": "The creation date of the workgroup.", "Workgroup.Endpoint": "", - "Workgroup.Endpoint.Address": "", - "Workgroup.Endpoint.Port": "", + "Workgroup.Endpoint.Address": "The DNS address of the VPC endpoint.", + "Workgroup.Endpoint.Port": "The custom port to use when connecting to a workgroup. Valid port ranges are 5431-5455 and 8191-8215. The default is 5439.", "Workgroup.Endpoint.VpcEndpoints": "", - "Workgroup.EnhancedVpcRouting": "", - "Workgroup.NamespaceName": "", - "Workgroup.PubliclyAccessible": "", - "Workgroup.SecurityGroupIds": "", - "Workgroup.Status": "", - "Workgroup.SubnetIds": "", - "Workgroup.WorkgroupArn": "", - "Workgroup.WorkgroupId": "", - "Workgroup.WorkgroupName": "" + "Workgroup.EnhancedVpcRouting": "The value that specifies whether to enable enhanced virtual private cloud (VPC) routing, which forces Amazon Redshift Serverless to route traffic through your VPC.", + "Workgroup.NamespaceName": "The namespace the workgroup is associated with.", + "Workgroup.PubliclyAccessible": "A value that specifies whether the workgroup can be accessible from a public network.", + "Workgroup.SecurityGroupIds": "An array of security group IDs to associate with the workgroup.", + "Workgroup.Status": "The status of the workgroup.", + "Workgroup.SubnetIds": "An array of subnet IDs the workgroup is associated with.", + "Workgroup.WorkgroupArn": "The Amazon Resource Name (ARN) that links to the workgroup.", + "Workgroup.WorkgroupId": "The unique identifier of the workgroup.", + "Workgroup.WorkgroupName": "The name of the workgroup." }, "description": "The collection of compute resources in Amazon Redshift Serverless.", "properties": { @@ -41985,7 +41985,7 @@ "StageName": "The name of the API Gateway stage. The name defaults to `prod` .", "VpcLinkId": "The `VpcLink` ID of the API Gateway proxy." }, - "description": "Creates an AWS Migration Hub Refactor Spaces application. The account that owns the environment also owns the applications created inside the environment, regardless of the account that creates the application. Refactor Spaces provisions an Amazon API Gateway , API Gateway VPC link, and Network Load Balancer for the application proxy inside your account.", + "description": "Creates an AWS Migration Hub Refactor Spaces application. The account that owns the environment also owns the applications created inside the environment, regardless of the account that creates the application. Refactor Spaces provisions an Amazon API Gateway , API Gateway VPC link, and Network Load Balancer for the application proxy inside your account.\n\nIn environments created with a `CreateEnvironmentRequest$NetworkFabricType` of `NONE` you need to configure [VPC to VPC connectivity](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/amazon-vpc-to-amazon-vpc-connectivity-options.html) between your service VPC and the application proxy VPC to route traffic through the application proxy to a service with a private URL endpoint. For more information, see [Create an application](https://docs.aws.amazon.com/migrationhub-refactor-spaces/latest/userguide/getting-started-create-application.html) in the *Refactor Spaces User Guide* .", "properties": { "ApiGatewayProxy": "The endpoint URL of the Amazon API Gateway proxy.", "EnvironmentIdentifier": "The unique identifier of the environment.", @@ -42010,7 +42010,7 @@ "Ref": "`Ref` returns the ID of the environment, for example, `env-1234654123` .", "TransitGatewayId": "The ID of the AWS Transit Gateway set up by the environment." }, - "description": "Creates an AWS Migration Hub Refactor Spaces environment. The caller owns the environment resource, and all Refactor Spaces applications, services, and routes created within the environment. They are referred to as the *environment owner* . The environment owner has cross-account visibility and control of Refactor Spaces resources that are added to the environment by other accounts that the environment is shared with. When creating an environment, Refactor Spaces provisions a transit gateway in your account.", + "description": "Creates an AWS Migration Hub Refactor Spaces environment. The caller owns the environment resource, and all Refactor Spaces applications, services, and routes created within the environment. They are referred to as the *environment owner* . The environment owner has cross-account visibility and control of Refactor Spaces resources that are added to the environment by other accounts that the environment is shared with.\n\nWhen creating an environment with a `CreateEnvironmentRequest$NetworkFabricType` of `TRANSIT_GATEWAY` , Refactor Spaces provisions a transit gateway to enable services in VPCs to communicate directly across accounts. If `CreateEnvironmentRequest$NetworkFabricType` is `NONE` , Refactor Spaces does not create a transit gateway and you must use your network infrastructure to route traffic to services with private URL endpoints.", "properties": { "Description": "A description of the environment.", "Name": "The name of the environment.", @@ -42495,32 +42495,32 @@ "AWS::RolesAnywhere::CRL": { "attributes": { "CrlId": "The unique primary identifier of the Crl", - "Ref": "The name of the CRL." + "Ref": "`Ref` returns `CrlId` ." }, - "description": "Creates a Crl.", + "description": "Imports the certificate revocation list (CRL). A CRL is a list of certificates that have been revoked by the issuing certificate Authority (CA). IAM Roles Anywhere validates against the CRL before issuing credentials.\n\n*Required permissions:* `rolesanywhere:ImportCrl` .", "properties": { - "CrlData": "x509 v3 Certificate Revocation List to revoke auth for corresponding certificates presented in CreateSession operations", - "Enabled": "The enabled status of the resource.", - "Name": "The customer specified name of the resource.", - "Tags": "A list of Tags.", + "CrlData": "The x509 v3 specified certificate revocation list (CRL).", + "Enabled": "Specifies whether the certificate revocation list (CRL) is enabled.", + "Name": "The name of the certificate revocation list (CRL).", + "Tags": "A list of tags to attach to the certificate revocation list (CRL).", "TrustAnchorArn": "The ARN of the TrustAnchor the certificate revocation list (CRL) will provide revocation for." } }, "AWS::RolesAnywhere::Profile": { "attributes": { - "ProfileArn": "", + "ProfileArn": "The ARN of the profile.", "ProfileId": "The unique primary identifier of the Profile", - "Ref": "The name of the Profile" + "Ref": "`Ref` returns `ProfileId` ." }, - "description": "Creates a Profile.", + "description": "Creates a *profile* , a list of the roles that Roles Anywhere service is trusted to assume. You use profiles to intersect permissions with IAM managed policies.\n\n*Required permissions:* `rolesanywhere:CreateProfile` .", "properties": { - "DurationSeconds": "The number of seconds vended session credentials will be valid for", - "Enabled": "The enabled status of the resource.", - "ManagedPolicyArns": "A list of managed policy ARNs. Managed policies identified by this list will be applied to the vended session credentials.", - "Name": "The customer specified name of the resource.", - "RequireInstanceProperties": "Specifies whether instance properties are required in CreateSession requests with this profile.", - "RoleArns": "A list of IAM role ARNs that can be assumed when this profile is specified in a CreateSession request.", - "SessionPolicy": "A session policy that will applied to the trust boundary of the vended session credentials.", + "DurationSeconds": "Sets the maximum number of seconds that vended temporary credentials through [CreateSession](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/authentication-create-session.html) will be valid for, between 900 and 3600.", + "Enabled": "Indicates whether the profile is enabled.", + "ManagedPolicyArns": "A list of managed policy ARNs that apply to the vended session credentials.", + "Name": "The name of the profile.", + "RequireInstanceProperties": "Specifies whether instance properties are required in temporary credential requests with this profile.", + "RoleArns": "A list of IAM role ARNs. During `CreateSession` , if a matching role ARN is provided, the properties in this profile will be applied to the intersection session policy.", + "SessionPolicy": "A session policy that applies to the trust boundary of the vended session credentials.", "Tags": "A list of Tags." } }, @@ -42528,29 +42528,29 @@ "attributes": { "Ref": "`Ref` returns `TrustAnchorId` .", "TrustAnchorArn": "The ARN of the trust anchor.", - "TrustAnchorId": "" + "TrustAnchorId": "The unique identifier of the trust anchor." }, - "description": "Creates a TrustAnchor.", + "description": "Creates a trust anchor to establish trust between IAM Roles Anywhere and your certificate authority (CA). You can define a trust anchor as a reference to an AWS Private Certificate Authority ( AWS Private CA ) or by uploading a CA certificate. Your AWS workloads can authenticate with the trust anchor using certificates issued by the CA in exchange for temporary AWS credentials.\n\n*Required permissions:* `rolesanywhere:CreateTrustAnchor` .", "properties": { "Enabled": "Indicates whether the trust anchor is enabled.", "Name": "The name of the trust anchor.", "Source": "The trust anchor type and its related certificate data.", - "Tags": "A list of tags to attach to the trust anchor." + "Tags": "" } }, "AWS::RolesAnywhere::TrustAnchor.Source": { "attributes": {}, - "description": "Object representing the TrustAnchor type and its related certificate data.", + "description": "The trust anchor type and its related certificate data.", "properties": { - "SourceData": "A union object representing the data field of the TrustAnchor depending on its type", - "SourceType": "The type of the TrustAnchor." + "SourceData": "The data field of the trust anchor depending on its type.", + "SourceType": "The type of the TrustAnchor.\n\n> `AWS_ACM_PCA` is not an allowed value in your region." } }, "AWS::RolesAnywhere::TrustAnchor.SourceData": { "attributes": {}, - "description": "A union object representing the data field of the TrustAnchor depending on its type", + "description": "The data field of the trust anchor depending on its type.", "properties": { - "AcmPcaArn": "The root certificate of the AWS Private Certificate Authority specified by this ARN is used in trust validation for temporary credential requests. Included for trust anchors of type `AWS_ACM_PCA` .", + "AcmPcaArn": "The root certificate of the AWS Private Certificate Authority specified by this ARN is used in trust validation for temporary credential requests. Included for trust anchors of type `AWS_ACM_PCA` .\n\n> This field is not supported in your region.", "X509CertificateData": "The PEM-encoded data for the certificate anchor. Included for trust anchors of type `CERTIFICATE_BUNDLE` ." } }, From a5c8ea8eb421f9b534f96251f1956edb2c526e1f Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Tue, 7 Mar 2023 14:45:43 +0100 Subject: [PATCH 09/22] chore(cli-integ): ResourcePool will not reacquire dead processes (#24496) The ResourcePool acquires any available region from a collection of regions, each protected by a mutex. The underlying mutex supports stealing locks from processes that have died, but the ResourcePool built on top never exercises that capability, because it will only try to acquire locks from mutexes it "knows" are free (i.e., for which it has seen an "unlock" event). Try every mutex on every acquisition. This is less efficient, but it has the advantage of recovering from processes that died. There is no test for this as the test is very awkward to write (depends on subprocesses being dead). Also fix a bug in XpMutex itself where `acquire()` was supposed to call `tryAcquire()`, but that was fat-fingered into a recursive call. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cli-integ/lib/resource-pool.ts | 14 ++---- .../@aws-cdk-testing/cli-integ/lib/xpmutex.ts | 2 +- .../cli-integ/test/xpmutex.test.ts | 46 +++++++++++++++++++ 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 packages/@aws-cdk-testing/cli-integ/test/xpmutex.test.ts diff --git a/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts b/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts index 1c10f54be562d..58c39e0364797 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts @@ -44,9 +44,12 @@ export class ResourcePool { while (true) { // Start a wait on the unlock now -- if the unlock signal comes after // we try to acquire but before we start the wait, we might miss it. - const wait = this.pool.awaitUnlock(5000); + // + // (The timeout is in case the unlock signal doesn't come for whatever reason). + const wait = this.pool.awaitUnlock(10_000); - for (const res of this.unlockedResources()) { + // Try all mutexes, we might need to reacquire an expired lock + for (const res of this.resources) { const lease = await this.tryObtainLease(res); if (lease) { // Ignore the wait (count as handled) @@ -107,13 +110,6 @@ export class ResourcePool { delete this.locks[value]; await lock?.release(); } - - /** - * Return all resources that we definitely don't own the locks for - */ - private unlockedResources(): A[] { - return this.resources.filter(res => !this.locks[res]); - } } /** diff --git a/packages/@aws-cdk-testing/cli-integ/lib/xpmutex.ts b/packages/@aws-cdk-testing/cli-integ/lib/xpmutex.ts index 4687164a1b5ee..5b900b92f6e4d 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/xpmutex.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/xpmutex.ts @@ -141,7 +141,7 @@ export class XpMutex { // signal due to unfortunate timing. const wait = this.pool.awaitUnlock(5000); - const lock = await this.acquire(); + const lock = await this.tryAcquire(); if (lock) { // Ignore the wait (count as handled) wait.then(() => {}, () => {}); diff --git a/packages/@aws-cdk-testing/cli-integ/test/xpmutex.test.ts b/packages/@aws-cdk-testing/cli-integ/test/xpmutex.test.ts new file mode 100644 index 0000000000000..7adfbea8f4a4b --- /dev/null +++ b/packages/@aws-cdk-testing/cli-integ/test/xpmutex.test.ts @@ -0,0 +1,46 @@ +import { XpMutexPool } from '../lib/xpmutex'; + +const POOL = XpMutexPool.fromName('test-pool'); + +test('acquire waits', async () => { + const mux = POOL.mutex('testA'); + let secondLockAcquired = false; + + // Current "process" acquires lock + const lock = await mux.acquire(); + + // Start a second "process" that tries to acquire the lock + const secondProcess = (async () => { + const secondLock = await mux.acquire(); + try { + secondLockAcquired = true; + } finally { + await secondLock.release(); + } + })(); + + // Once we release the lock the second process is free to take it + expect(secondLockAcquired).toBe(false); + await lock.release(); + + // We expect the variable to become true + await waitFor(() => secondLockAcquired); + expect(secondLockAcquired).toBe(true); + + await secondProcess; +}); + + +/** + * Poll for some condition every 10ms + */ +function waitFor(pred: () => boolean): Promise { + return new Promise((ok) => { + const timerHandle = setInterval(() => { + if (pred()) { + clearInterval(timerHandle); + ok(); + } + }, 5); + }); +} \ No newline at end of file From e2392caf5beb85bdaa3a8b6452de8eca742ca25b Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Tue, 7 Mar 2023 16:06:30 +0100 Subject: [PATCH 10/22] chore: add extra output in CLI integ tests (#24499) Trying to diagnose what is happening in CodeBuild when the integration tests run for V2, as something appears to hang. Using `process.stderr.write` allows bypassing `jest`'s hijacking of `console.log` and `console.error`, so these traces _always_ show. --- packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts b/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts index 779df577f10bb..7c8611e45bf21 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts @@ -36,6 +36,7 @@ export function integTest( output.write('================================================================\n'); try { + process.stderr.write(`▶️ [INTEG TEST::${name}] Starting...\n`); return await callback({ output, randomString: randomString(), @@ -44,6 +45,7 @@ export function integTest( }, }); } catch (e) { + process.stderr.write(`💥 [INTEG TEST::${name}] Failed: ${e}\n`); output.write(e.message); output.write(e.stack); // Print output only if the test fails. Use 'console.log' so the output is buffered by @@ -51,6 +53,8 @@ export function integTest( // eslint-disable-next-line no-console console.log(output.buffer().toString()); throw e; + } finally { + process.stderr.write(`⏹️ [INTEG TEST::${name}] Done.\n`); } }, timeoutMillis); } From 553be48ed9bb5bdcad6a57b91ad19bb856300cc0 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Tue, 7 Mar 2023 07:47:56 -0800 Subject: [PATCH 11/22] chore: npm-check-updates && yarn upgrade (#24497) Ran npm-check-updates and yarn upgrade to keep the `yarn.lock` file up-to-date. --- package.json | 8 +- .../@aws-cdk-testing/cli-integ/package.json | 2 +- packages/@aws-cdk/aws-amplify/package.json | 2 +- .../package.json | 2 +- .../aws-cloudfront-origins/package.json | 2 +- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 8 +- .../app/package.json | 2 +- .../@aws-cdk/aws-events-targets/package.json | 2 +- .../package.json | 2 +- .../@aws-cdk/aws-lambda-nodejs/package.json | 2 +- packages/@aws-cdk/aws-logs/package.json | 2 +- packages/@aws-cdk/aws-redshift/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- packages/@aws-cdk/core/package.json | 2 +- .../@aws-cdk/custom-resources/package.json | 2 +- .../integ-runner/THIRD_PARTY_LICENSES | 2 +- packages/@aws-cdk/integ-tests/package.json | 2 +- .../@aws-cdk/lambda-layer-awscli/package.json | 2 +- .../package.json | 2 +- packages/@aws-cdk/pipelines/package.json | 2 +- packages/@aws-cdk/triggers/package.json | 2 +- packages/aws-cdk-lib/package.json | 6 +- packages/aws-cdk/THIRD_PARTY_LICENSES | 4 +- .../app/javascript/package.json | 2 +- .../app/typescript/package.json | 4 +- .../lib/typescript/package.json | 4 +- .../sample-app/javascript/package.json | 2 +- .../sample-app/typescript/package.json | 4 +- packages/aws-cdk/package.json | 4 +- packages/awslint/package.json | 4 +- packages/cdk-assets/package.json | 2 +- packages/cdk-dasm/package.json | 2 +- tools/@aws-cdk/cdk-build-tools/package.json | 6 +- tools/@aws-cdk/cfn2ts/package.json | 2 +- tools/@aws-cdk/node-bundle/package.json | 6 +- yarn.lock | 655 +++++++++--------- 42 files changed, 388 insertions(+), 385 deletions(-) diff --git a/package.json b/package.json index 02cb1f0f0ad24..90c003df8e3e3 100644 --- a/package.json +++ b/package.json @@ -19,14 +19,14 @@ "@types/node": "18.11.19", "@types/prettier": "2.6.0", "@yarnpkg/lockfile": "^1.1.0", - "cdk-generate-synthetic-examples": "^0.1.167", + "cdk-generate-synthetic-examples": "^0.1.173", "conventional-changelog-cli": "^2.2.2", "fs-extra": "^9.1.0", "graceful-fs": "^4.2.10", "jest-junit": "^13.2.0", - "jsii-diff": "1.76.0", - "jsii-pacmak": "1.76.0", - "jsii-reflect": "1.76.0", + "jsii-diff": "1.77.0", + "jsii-pacmak": "1.77.0", + "jsii-reflect": "1.77.0", "jsii-rosetta": "v4.9-next", "lerna": "^4.0.0", "patch-package": "^6.5.1", diff --git a/packages/@aws-cdk-testing/cli-integ/package.json b/packages/@aws-cdk-testing/cli-integ/package.json index c10c9e803dd9f..1112571062f33 100644 --- a/packages/@aws-cdk-testing/cli-integ/package.json +++ b/packages/@aws-cdk-testing/cli-integ/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@octokit/rest": "^18.12.0", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "axios": "^0.27.2", "fs-extra": "^9.1.0", "glob": "^7.2.3", diff --git a/packages/@aws-cdk/aws-amplify/package.json b/packages/@aws-cdk/aws-amplify/package.json index f20455b24296e..c6408fb81a4e9 100644 --- a/packages/@aws-cdk/aws-amplify/package.json +++ b/packages/@aws-cdk/aws-amplify/package.json @@ -88,7 +88,7 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jsii": "v4.9-next" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json index c3b0d3fada58a..e0722e21b085d 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json +++ b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json @@ -32,7 +32,7 @@ "@types/aws-lambda": "^8.10.111", "@types/sinon": "^9.0.11", "@aws-cdk/cdk-build-tools": "0.0.0", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "aws-sdk-mock": "5.6.0", "eslint": "^7.32.0", "eslint-config-standard": "^14.1.1", diff --git a/packages/@aws-cdk/aws-cloudfront-origins/package.json b/packages/@aws-cdk/aws-cloudfront-origins/package.json index 932b2d8481ecf..cfd2c78d0d9fc 100644 --- a/packages/@aws-cdk/aws-cloudfront-origins/package.json +++ b/packages/@aws-cdk/aws-cloudfront-origins/package.json @@ -85,7 +85,7 @@ "@aws-cdk/integ-tests": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0" + "aws-sdk": "^2.1329.0" }, "dependencies": { "@aws-cdk/aws-apigateway": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index c01da3b4a87dc..07562a41b9e53 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -88,7 +88,7 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jest": "^27.5.1" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 648268d27890b..768f1b9ff5dc4 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -87,7 +87,7 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jest": "^27.5.1" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index 85b89e6d33502..b852fc29fe572 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -93,7 +93,7 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jest": "^27.5.1" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index 90821ac3cedf1..7448d83798d16 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -93,7 +93,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jest": "^27.5.1" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index 3270864374893..473081a3bb8da 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -89,7 +89,7 @@ "@types/aws-lambda": "^8.10.111", "@types/jest": "^27.5.2", "@types/sinon": "^9.0.11", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "aws-sdk-mock": "5.6.0", "jest": "^27.5.1", "sinon": "^9.2.4", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 479e774d254a0..5a73c8f6e49d9 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -80,7 +80,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@aws-cdk/lambda-layer-kubectl-v24": "^2.0.113", + "@aws-cdk/lambda-layer-kubectl-v24": "^2.0.121", "aws-cdk-lib": "2.47.0", "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", @@ -92,9 +92,9 @@ "@types/jest": "^27.5.2", "@types/sinon": "^9.0.11", "@types/yaml": "1.9.6", - "aws-sdk": "^2.1325.0", - "cdk8s": "^2.7.15", - "cdk8s-plus-24": "2.4.40", + "aws-sdk": "^2.1329.0", + "cdk8s": "^2.7.23", + "cdk8s-plus-24": "2.4.46", "jest": "^27.5.1", "sinon": "^9.2.4" }, diff --git a/packages/@aws-cdk/aws-eks/test/sdk-call-integ-test-docker-app/app/package.json b/packages/@aws-cdk/aws-eks/test/sdk-call-integ-test-docker-app/app/package.json index e954bcb2b77e7..65e9857efb409 100644 --- a/packages/@aws-cdk/aws-eks/test/sdk-call-integ-test-docker-app/app/package.json +++ b/packages/@aws-cdk/aws-eks/test/sdk-call-integ-test-docker-app/app/package.json @@ -2,6 +2,6 @@ "name": "eks-service-account-sdk-call-integ-test", "private": "true", "dependencies": { - "aws-sdk": "^2.1325.0" + "aws-sdk": "^2.1329.0" } } diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index 3455b64b3521f..5197728a9c35e 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -89,7 +89,7 @@ "@aws-cdk/integ-runner": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "aws-sdk-mock": "5.6.0", "jest": "^27.5.1" }, diff --git a/packages/@aws-cdk/aws-globalaccelerator-endpoints/package.json b/packages/@aws-cdk/aws-globalaccelerator-endpoints/package.json index 2f1f657b94807..268c59f7ad46f 100644 --- a/packages/@aws-cdk/aws-globalaccelerator-endpoints/package.json +++ b/packages/@aws-cdk/aws-globalaccelerator-endpoints/package.json @@ -81,7 +81,7 @@ "@aws-cdk/integ-runner": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "aws-sdk-mock": "5.6.0", "jest": "^27.5.1" }, diff --git a/packages/@aws-cdk/aws-lambda-nodejs/package.json b/packages/@aws-cdk/aws-lambda-nodejs/package.json index d84acd65d1fde..bfad18cd373b4 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/package.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/package.json @@ -81,7 +81,7 @@ "@aws-cdk/triggers": "0.0.0", "@types/jest": "^27.5.2", "delay": "5.0.0", - "esbuild": "^0.17.10" + "esbuild": "^0.17.11" }, "dependencies": { "@aws-cdk/aws-lambda": "0.0.0", diff --git a/packages/@aws-cdk/aws-logs/package.json b/packages/@aws-cdk/aws-logs/package.json index 56ae9b9b1293d..695355472f6c0 100644 --- a/packages/@aws-cdk/aws-logs/package.json +++ b/packages/@aws-cdk/aws-logs/package.json @@ -89,7 +89,7 @@ "@types/aws-lambda": "^8.10.111", "@types/jest": "^27.5.2", "@types/sinon": "^9.0.11", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "aws-sdk-mock": "5.6.0", "jest": "^27.5.1", "nock": "^13.3.0", diff --git a/packages/@aws-cdk/aws-redshift/package.json b/packages/@aws-cdk/aws-redshift/package.json index e3e4f52a79eed..8e2492475ba2c 100644 --- a/packages/@aws-cdk/aws-redshift/package.json +++ b/packages/@aws-cdk/aws-redshift/package.json @@ -87,7 +87,7 @@ "@aws-cdk/pkglint": "0.0.0", "@aws-cdk/integ-tests": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jest": "^27.5.1", "jsii": "v4.9-next" }, diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index c25d2219a974a..ee825a123eb31 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -87,7 +87,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/aws-lambda": "^8.10.111", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jest": "^27.5.1" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index 1e2ebe4bbb600..956caa11e3d0e 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -88,7 +88,7 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "jest": "^27.5.1" }, "dependencies": { diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index 5a63f16d1761d..d658fde13d02a 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -191,7 +191,7 @@ "@types/jest": "^27.5.2", "@types/lodash": "^4.14.191", "@types/minimatch": "^3.0.5", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "@types/sinon": "^9.0.11", "fast-check": "^2.25.0", "jest": "^27.5.1", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 43d88f5e7a823..b34bdc5705359 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -93,7 +93,7 @@ "@types/fs-extra": "^9.0.13", "@types/jest": "^27.5.2", "@types/sinon": "^9.0.11", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "aws-sdk-mock": "5.6.0", "fs-extra": "^9.1.0", "nock": "^13.3.0", diff --git a/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES b/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES index 2df6fb89cca98..07e1b9bd0b3a4 100644 --- a/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES +++ b/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES @@ -156,7 +156,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE ---------------- -** aws-sdk@2.1325.0 - https://www.npmjs.com/package/aws-sdk/v/2.1325.0 | Apache-2.0 +** aws-sdk@2.1329.0 - https://www.npmjs.com/package/aws-sdk/v/2.1329.0 | Apache-2.0 AWS SDK for JavaScript Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/integ-tests/package.json b/packages/@aws-cdk/integ-tests/package.json index 26955f48c4e18..99d0450dd9184 100644 --- a/packages/@aws-cdk/integ-tests/package.json +++ b/packages/@aws-cdk/integ-tests/package.json @@ -67,7 +67,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/fs-extra": "^9.0.13", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "aws-sdk-mock": "5.6.0", "jest": "^27.5.1", "nock": "^13.3.0", diff --git a/packages/@aws-cdk/lambda-layer-awscli/package.json b/packages/@aws-cdk/lambda-layer-awscli/package.json index a9661d7872f3b..7e6cc5e5d7e5e 100644 --- a/packages/@aws-cdk/lambda-layer-awscli/package.json +++ b/packages/@aws-cdk/lambda-layer-awscli/package.json @@ -84,7 +84,7 @@ "dependencies": { "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/core": "0.0.0", - "@aws-cdk/asset-awscli-v1": "^2.2.85", + "@aws-cdk/asset-awscli-v1": "^2.2.97", "constructs": "^10.0.0" }, "homepage": "https://github.com/aws/aws-cdk", diff --git a/packages/@aws-cdk/lambda-layer-node-proxy-agent/package.json b/packages/@aws-cdk/lambda-layer-node-proxy-agent/package.json index 33fc33d129d07..17f369d855bfe 100644 --- a/packages/@aws-cdk/lambda-layer-node-proxy-agent/package.json +++ b/packages/@aws-cdk/lambda-layer-node-proxy-agent/package.json @@ -84,7 +84,7 @@ "dependencies": { "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/core": "0.0.0", - "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.71", + "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.77", "constructs": "^10.0.0" }, "homepage": "https://github.com/aws/aws-cdk", diff --git a/packages/@aws-cdk/pipelines/package.json b/packages/@aws-cdk/pipelines/package.json index 22003dab4cd5f..d1101c155c99b 100644 --- a/packages/@aws-cdk/pipelines/package.json +++ b/packages/@aws-cdk/pipelines/package.json @@ -51,7 +51,7 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", - "aws-sdk": "^2.1325.0" + "aws-sdk": "^2.1329.0" }, "peerDependencies": { "@aws-cdk/aws-codebuild": "0.0.0", diff --git a/packages/@aws-cdk/triggers/package.json b/packages/@aws-cdk/triggers/package.json index 0fcc8c783120a..3d4221bd14726 100644 --- a/packages/@aws-cdk/triggers/package.json +++ b/packages/@aws-cdk/triggers/package.json @@ -78,7 +78,7 @@ "@aws-cdk/integ-runner": "0.0.0", "@aws-cdk/integ-tests": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", "jest": "^27.5.1" diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 5a5c4ef436d66..ea1f95056d281 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -114,8 +114,8 @@ "punycode": "^2.3.0", "semver": "^7.3.8", "yaml": "1.10.2", - "@aws-cdk/asset-awscli-v1": "^2.2.85", - "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.71", + "@aws-cdk/asset-awscli-v1": "^2.2.97", + "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.77", "@aws-cdk/asset-kubectl-v20": "^2.1.1" }, "devDependencies": { @@ -380,7 +380,7 @@ "@aws-cdk/triggers": "0.0.0", "@aws-cdk/ubergen": "0.0.0", "constructs": "^10.0.0", - "esbuild": "^0.17.10", + "esbuild": "^0.17.11", "fs-extra": "^9.1.0", "ts-node": "^9.1.1", "typescript": "~3.8.3" diff --git a/packages/aws-cdk/THIRD_PARTY_LICENSES b/packages/aws-cdk/THIRD_PARTY_LICENSES index 144889e860f6e..db4620ad0710c 100644 --- a/packages/aws-cdk/THIRD_PARTY_LICENSES +++ b/packages/aws-cdk/THIRD_PARTY_LICENSES @@ -1,6 +1,6 @@ The aws-cdk package includes the following third-party software/licensing: -** @jsii/check-node@1.76.0 - https://www.npmjs.com/package/@jsii/check-node/v/1.76.0 | Apache-2.0 +** @jsii/check-node@1.77.0 - https://www.npmjs.com/package/@jsii/check-node/v/1.77.0 | Apache-2.0 jsii Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -268,7 +268,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE ---------------- -** aws-sdk@2.1325.0 - https://www.npmjs.com/package/aws-sdk/v/2.1325.0 | Apache-2.0 +** aws-sdk@2.1329.0 - https://www.npmjs.com/package/aws-sdk/v/2.1329.0 | Apache-2.0 AWS SDK for JavaScript Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/aws-cdk/lib/init-templates/app/javascript/package.json b/packages/aws-cdk/lib/init-templates/app/javascript/package.json index 3d4f898b31c6b..c4314e7f6c633 100644 --- a/packages/aws-cdk/lib/init-templates/app/javascript/package.json +++ b/packages/aws-cdk/lib/init-templates/app/javascript/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "aws-cdk": "%cdk-version%", - "jest": "^29.4.3" + "jest": "^29.5.0" }, "dependencies": { "aws-cdk-lib": "%cdk-version%", diff --git a/packages/aws-cdk/lib/init-templates/app/typescript/package.json b/packages/aws-cdk/lib/init-templates/app/typescript/package.json index c2d4c49eb5f5f..19242f850ad79 100644 --- a/packages/aws-cdk/lib/init-templates/app/typescript/package.json +++ b/packages/aws-cdk/lib/init-templates/app/typescript/package.json @@ -12,8 +12,8 @@ }, "devDependencies": { "@types/jest": "^29.4.0", - "@types/node": "18.14.2", - "jest": "^29.4.3", + "@types/node": "18.14.6", + "jest": "^29.5.0", "ts-jest": "^29.0.5", "aws-cdk": "%cdk-version%", "ts-node": "^10.9.1", diff --git a/packages/aws-cdk/lib/init-templates/lib/typescript/package.json b/packages/aws-cdk/lib/init-templates/lib/typescript/package.json index ddfbc0ba961ab..77bcd371c72cc 100644 --- a/packages/aws-cdk/lib/init-templates/lib/typescript/package.json +++ b/packages/aws-cdk/lib/init-templates/lib/typescript/package.json @@ -10,10 +10,10 @@ }, "devDependencies": { "@types/jest": "^29.4.0", - "@types/node": "18.14.2", + "@types/node": "18.14.6", "aws-cdk-lib": "%cdk-version%", "constructs": "%constructs-version%", - "jest": "^29.4.3", + "jest": "^29.5.0", "ts-jest": "^29.0.5", "typescript": "~4.9.5" }, diff --git a/packages/aws-cdk/lib/init-templates/sample-app/javascript/package.json b/packages/aws-cdk/lib/init-templates/sample-app/javascript/package.json index 3d4f898b31c6b..c4314e7f6c633 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/javascript/package.json +++ b/packages/aws-cdk/lib/init-templates/sample-app/javascript/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "aws-cdk": "%cdk-version%", - "jest": "^29.4.3" + "jest": "^29.5.0" }, "dependencies": { "aws-cdk-lib": "%cdk-version%", diff --git a/packages/aws-cdk/lib/init-templates/sample-app/typescript/package.json b/packages/aws-cdk/lib/init-templates/sample-app/typescript/package.json index 3c82377faa1c2..bae3f27c14704 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/typescript/package.json +++ b/packages/aws-cdk/lib/init-templates/sample-app/typescript/package.json @@ -12,8 +12,8 @@ }, "devDependencies": { "@types/jest": "^29.4.0", - "@types/node": "18.14.2", - "jest": "^29.4.3", + "@types/node": "18.14.6", + "jest": "^29.5.0", "ts-jest": "^29.0.5", "aws-cdk": "%cdk-version%", "ts-node": "^10.9.1", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 00f0dc12be4f3..192d9c433a0ce 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -98,9 +98,9 @@ "@aws-cdk/cloudformation-diff": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", - "@jsii/check-node": "1.76.0", + "@jsii/check-node": "1.77.0", "archiver": "^5.3.1", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "camelcase": "^6.3.0", "cdk-assets": "0.0.0", "chokidar": "^3.5.3", diff --git a/packages/awslint/package.json b/packages/awslint/package.json index fd31ed7b098e7..702292df72889 100644 --- a/packages/awslint/package.json +++ b/packages/awslint/package.json @@ -18,11 +18,11 @@ "awslint": "bin/awslint" }, "dependencies": { - "@jsii/spec": "1.76.0", + "@jsii/spec": "1.77.0", "camelcase": "^6.3.0", "chalk": "^4", "fs-extra": "^9.1.0", - "jsii-reflect": "1.76.0", + "jsii-reflect": "1.77.0", "yargs": "^16.2.0" }, "devDependencies": { diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index be2a4e69f3df4..558ece15e56d8 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -46,7 +46,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "archiver": "^5.3.1", - "aws-sdk": "^2.1325.0", + "aws-sdk": "^2.1329.0", "glob": "^7.2.3", "mime": "^2.6.0", "yargs": "^16.2.0" diff --git a/packages/cdk-dasm/package.json b/packages/cdk-dasm/package.json index 0b9f1def89778..a2f040d7ebf22 100644 --- a/packages/cdk-dasm/package.json +++ b/packages/cdk-dasm/package.json @@ -30,7 +30,7 @@ }, "license": "Apache-2.0", "dependencies": { - "codemaker": "1.76.0", + "codemaker": "1.77.0", "yaml": "1.10.2" }, "devDependencies": { diff --git a/tools/@aws-cdk/cdk-build-tools/package.json b/tools/@aws-cdk/cdk-build-tools/package.json index b8ed716059491..e6d86da84f9cd 100644 --- a/tools/@aws-cdk/cdk-build-tools/package.json +++ b/tools/@aws-cdk/cdk-build-tools/package.json @@ -57,9 +57,9 @@ "fs-extra": "^9.1.0", "jest": "^27.5.1", "jest-junit": "^13.2.0", - "jsii": "1.76.0", - "jsii-pacmak": "1.76.0", - "jsii-reflect": "1.76.0", + "jsii": "1.77.0", + "jsii-pacmak": "1.77.0", + "jsii-reflect": "1.77.0", "markdownlint-cli": "^0.33.0", "nyc": "^15.1.0", "semver": "^7.3.8", diff --git a/tools/@aws-cdk/cfn2ts/package.json b/tools/@aws-cdk/cfn2ts/package.json index 73eebbefafe61..f3a415c4f1202 100644 --- a/tools/@aws-cdk/cfn2ts/package.json +++ b/tools/@aws-cdk/cfn2ts/package.json @@ -32,7 +32,7 @@ "license": "Apache-2.0", "dependencies": { "@aws-cdk/cfnspec": "0.0.0", - "codemaker": "1.76.0", + "codemaker": "1.77.0", "fast-json-patch": "^3.1.1", "fs-extra": "^9.1.0", "yargs": "^16.2.0" diff --git a/tools/@aws-cdk/node-bundle/package.json b/tools/@aws-cdk/node-bundle/package.json index 4108e453a5a34..4a6159e124d2a 100644 --- a/tools/@aws-cdk/node-bundle/package.json +++ b/tools/@aws-cdk/node-bundle/package.json @@ -40,14 +40,14 @@ "jest-junit": "^13", "json-schema": "^0.4.0", "npm-check-updates": "^12", - "projen": "^0.67.69", + "projen": "^0.67.75", "standard-version": "^9", "ts-jest": "^27", "typescript": "^4.5.5" }, "dependencies": { - "cdk-generate-synthetic-examples": "^0.1.167", - "esbuild": "^0.17.10", + "cdk-generate-synthetic-examples": "^0.1.173", + "esbuild": "^0.17.11", "fs-extra": "^10.1.0", "license-checker": "^25.0.1", "madge": "^5.0.2", diff --git a/yarn.lock b/yarn.lock index a8e1c91085beb..6a8a6b63bf239 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,9 +21,9 @@ "@octokit/plugin-rest-endpoint-methods" "^5.13.0" "@actions/http-client@^2.0.1": - version "2.0.1" - resolved "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz#873f4ca98fe32f6839462a6f046332677322f99c" - integrity sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw== + version "2.1.0" + resolved "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz#b6d8c3934727d6a50d10d19f00a711a964599a9f" + integrity sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw== dependencies: tunnel "^0.0.6" @@ -35,25 +35,25 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@aws-cdk/asset-awscli-v1@^2.2.85": - version "2.2.85" - resolved "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.85.tgz#3671dc4de44f243571a806d651697bb4f49d06c1" - integrity sha512-oNX4HMupi2+/blbUNctA8WIwyqFTLOGhGDB+gginMSy7QHevLWb/duMlwa7Np4wpiHeiBDMF/ccc5Mfb352srg== +"@aws-cdk/asset-awscli-v1@^2.2.97": + version "2.2.97" + resolved "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.97.tgz#af6fcefe7b9ddecc6656691bd0b4061f5c5eabf2" + integrity sha512-bWFkQphw1U7Q8XngShvGy0S1yqDui6q72zjnLciqKQ5ucZq17/TEujLTpSv+v2K5qJU8oa8VaMDiRyYbdPD6MA== "@aws-cdk/asset-kubectl-v20@^2.1.1": version "2.1.1" resolved "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.1.tgz#d01c1efb867fb7f2cfd8c8b230b8eae16447e156" integrity sha512-U1ntiX8XiMRRRH5J1IdC+1t5CE89015cwyt5U63Cpk0GnMlN5+h9WsWMlKlPXZR4rdq/m806JRlBMRpBUB2Dhw== -"@aws-cdk/asset-node-proxy-agent-v5@^2.0.71": - version "2.0.71" - resolved "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.71.tgz#dd269f8aa160473e006633d2f0f5384f46747693" - integrity sha512-vB/KF9naAYkELP6Hi5+Oib59B4ZAz6jjtrpsKNzsIZTmcTs0IIBb4nVdAuwMpMkPcwT0mzhMg2tlsiSyjrOFBA== +"@aws-cdk/asset-node-proxy-agent-v5@^2.0.77": + version "2.0.77" + resolved "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.77.tgz#25ad8e416945c3a51881eedad3ee84516f23ecee" + integrity sha512-KKrnyIujGN38yOb0MIm0EnB3n7z83NRl9VgKvN0flOyB8C+3Ey+XKxLYfjoXJ/BulB0161eBJXXwGdP8xQrQJw== -"@aws-cdk/lambda-layer-kubectl-v24@^2.0.113": - version "2.0.113" - resolved "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl-v24/-/lambda-layer-kubectl-v24-2.0.113.tgz#7b22497eb41bd88cfdea73a34c398721514b72c6" - integrity sha512-8mn6/5s/EDxmQP1cnoIAYqGwHmUl+Jimbnut/7Jhz6MzvmkDU9olpem1W6bESmrI6RFTX/1UABz+jaYthmqlXA== +"@aws-cdk/lambda-layer-kubectl-v24@^2.0.121": + version "2.0.121" + resolved "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl-v24/-/lambda-layer-kubectl-v24-2.0.121.tgz#eddc9dca05add57bcd15301356b74a616e016630" + integrity sha512-jCoOZMzizRga6rhIkFS5xRIgJjxTPdq6L4a7oIO0fDPLqohS9KWX3XKB0vOEIafmLrZ27BDSql39s7y5xkj33w== "@babel/code-frame@7.12.11": version "7.12.11" @@ -361,115 +361,115 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@esbuild/android-arm64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.10.tgz#ad2ee47dd021035abdfb0c38848ff77a1e1918c4" - integrity sha512-ht1P9CmvrPF5yKDtyC+z43RczVs4rrHpRqrmIuoSvSdn44Fs1n6DGlpZKdK6rM83pFLbVaSUwle8IN+TPmkv7g== - -"@esbuild/android-arm@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.10.tgz#bb5a68af8adeb94b30eadee7307404dc5237d076" - integrity sha512-7YEBfZ5lSem9Tqpsz+tjbdsEshlO9j/REJrfv4DXgKTt1+/MHqGwbtlyxQuaSlMeUZLxUKBaX8wdzlTfHkmnLw== - -"@esbuild/android-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.10.tgz#751d5d8ae9ece1efa9627b689c888eb85b102360" - integrity sha512-CYzrm+hTiY5QICji64aJ/xKdN70IK8XZ6iiyq0tZkd3tfnwwSWTYH1t3m6zyaaBxkuj40kxgMyj1km/NqdjQZA== - -"@esbuild/darwin-arm64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.10.tgz#85601ee7efb2129cd3218d5bcbe8da1173bc1e8b" - integrity sha512-3HaGIowI+nMZlopqyW6+jxYr01KvNaLB5znXfbyyjuo4lE0VZfvFGcguIJapQeQMS4cX/NEispwOekJt3gr5Dg== - -"@esbuild/darwin-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.10.tgz#362c7e988c61fe72d5edef4f717e4b4fc728da98" - integrity sha512-J4MJzGchuCRG5n+B4EHpAMoJmBeAE1L3wGYDIN5oWNqX0tEr7VKOzw0ymSwpoeSpdCa030lagGUfnfhS7OvzrQ== - -"@esbuild/freebsd-arm64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.10.tgz#e8a85a46ede7c3a048a12f16b9d551d25adc8bb1" - integrity sha512-ZkX40Z7qCbugeK4U5/gbzna/UQkM9d9LNV+Fro8r7HA7sRof5Rwxc46SsqeMvB5ZaR0b1/ITQ/8Y1NmV2F0fXQ== - -"@esbuild/freebsd-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.10.tgz#cd0a1b68bffbcb5b65e65b3fd542e8c7c3edd86b" - integrity sha512-0m0YX1IWSLG9hWh7tZa3kdAugFbZFFx9XrvfpaCMMvrswSTvUZypp0NFKriUurHpBA3xsHVE9Qb/0u2Bbi/otg== - -"@esbuild/linux-arm64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.10.tgz#13b183f432512ed9d9281cc89476caeebe9e9123" - integrity sha512-g1EZJR1/c+MmCgVwpdZdKi4QAJ8DCLP5uTgLWSAVd9wlqk9GMscaNMEViG3aE1wS+cNMzXXgdWiW/VX4J+5nTA== - -"@esbuild/linux-arm@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.10.tgz#dd11e0a5faa3ea94dc80278a601c3be7b4fdf1da" - integrity sha512-whRdrrl0X+9D6o5f0sTZtDM9s86Xt4wk1bf7ltx6iQqrIIOH+sre1yjpcCdrVXntQPCNw/G+XqsD4HuxeS+2QA== - -"@esbuild/linux-ia32@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.10.tgz#4d836f87b92807d9292379963c4888270d282405" - integrity sha512-1vKYCjfv/bEwxngHERp7huYfJ4jJzldfxyfaF7hc3216xiDA62xbXJfRlradiMhGZbdNLj2WA1YwYFzs9IWNPw== - -"@esbuild/linux-loong64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.10.tgz#92eb2ee200c17ef12c7fb3b648231948699e7a4c" - integrity sha512-mvwAr75q3Fgc/qz3K6sya3gBmJIYZCgcJ0s7XshpoqIAIBszzfXsqhpRrRdVFAyV1G9VUjj7VopL2HnAS8aHFA== - -"@esbuild/linux-mips64el@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.10.tgz#14f7d50c40fe7f7ee545a9bd07c6f6e4cba5570e" - integrity sha512-XilKPgM2u1zR1YuvCsFQWl9Fc35BqSqktooumOY2zj7CSn5czJn279j9TE1JEqSqz88izJo7yE4x3LSf7oxHzg== - -"@esbuild/linux-ppc64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.10.tgz#1ab5802e93ae511ce9783e1cb95f37df0f84c4af" - integrity sha512-kM4Rmh9l670SwjlGkIe7pYWezk8uxKHX4Lnn5jBZYBNlWpKMBCVfpAgAJqp5doLobhzF3l64VZVrmGeZ8+uKmQ== - -"@esbuild/linux-riscv64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.10.tgz#4fae25201ef7ad868731d16c8b50b0e386c4774a" - integrity sha512-r1m9ZMNJBtOvYYGQVXKy+WvWd0BPvSxMsVq8Hp4GzdMBQvfZRvRr5TtX/1RdN6Va8JMVQGpxqde3O+e8+khNJQ== - -"@esbuild/linux-s390x@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.10.tgz#126254d8335bb3586918b1ca60beb4abb46e6d54" - integrity sha512-LsY7QvOLPw9WRJ+fU5pNB3qrSfA00u32ND5JVDrn/xG5hIQo3kvTxSlWFRP0NJ0+n6HmhPGG0Q4jtQsb6PFoyg== - -"@esbuild/linux-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.10.tgz#7fa4667b2df81ea0538e1b75e607cf04e526ce91" - integrity sha512-zJUfJLebCYzBdIz/Z9vqwFjIA7iSlLCFvVi7glMgnu2MK7XYigwsonXshy9wP9S7szF+nmwrelNaP3WGanstEg== - -"@esbuild/netbsd-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.10.tgz#2d24727ddc2305619685bf237a46d6087a02ee9a" - integrity sha512-lOMkailn4Ok9Vbp/q7uJfgicpDTbZFlXlnKT2DqC8uBijmm5oGtXAJy2ZZVo5hX7IOVXikV9LpCMj2U8cTguWA== - -"@esbuild/openbsd-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.10.tgz#bf3fc38ee6ecf028c1f0cfe11f61d53cc75fef12" - integrity sha512-/VE0Kx6y7eekqZ+ZLU4AjMlB80ov9tEz4H067Y0STwnGOYL8CsNg4J+cCmBznk1tMpxMoUOf0AbWlb1d2Pkbig== - -"@esbuild/sunos-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.10.tgz#8deabd6dfec6256f80bb101bc59d29dbae99c69b" - integrity sha512-ERNO0838OUm8HfUjjsEs71cLjLMu/xt6bhOlxcJ0/1MG3hNqCmbWaS+w/8nFLa0DDjbwZQuGKVtCUJliLmbVgg== - -"@esbuild/win32-arm64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.10.tgz#1ec1ee04c788c4c57a83370b6abf79587b3e4965" - integrity sha512-fXv+L+Bw2AeK+XJHwDAQ9m3NRlNemG6Z6ijLwJAAVdu4cyoFbBWbEtyZzDeL+rpG2lWI51cXeMt70HA8g2MqIg== - -"@esbuild/win32-ia32@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.10.tgz#a362528d7f3ad5d44fa8710a96764677ef92ebe9" - integrity sha512-3s+HADrOdCdGOi5lnh5DMQEzgbsFsd4w57L/eLKKjMnN0CN4AIEP0DCP3F3N14xnxh3ruNc32A0Na9zYe1Z/AQ== - -"@esbuild/win32-x64@0.17.10": - version "0.17.10" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.10.tgz#ac779220f2da96afd480fb3f3148a292f66e7fc3" - integrity sha512-oP+zFUjYNaMNmjTwlFtWep85hvwUu19cZklB3QsBOcZSs6y7hmH4LNCJ7075bsqzYaNvZFXJlAVaQ2ApITDXtw== +"@esbuild/android-arm64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.11.tgz#52c3e6cabc19c5e4c1c0c01cb58f0442338e1c14" + integrity sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg== + +"@esbuild/android-arm@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.11.tgz#f3fc768235aecbeb840d0049fdf13cd28592105f" + integrity sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw== + +"@esbuild/android-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.11.tgz#443ed47771a7e917e4282469ba350d117473550c" + integrity sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ== + +"@esbuild/darwin-arm64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.11.tgz#0e8c78d94d5759a48521dbfd83189d2ed3499a16" + integrity sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw== + +"@esbuild/darwin-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.11.tgz#2405cfdf70eb961c7cf973463ca7263dc2004c88" + integrity sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw== + +"@esbuild/freebsd-arm64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.11.tgz#d5138e873e15f87bd4564c024dfa00ef37e623fd" + integrity sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q== + +"@esbuild/freebsd-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.11.tgz#e850b58b8fabf8e9ef0e125af3c25229ad2d6c38" + integrity sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g== + +"@esbuild/linux-arm64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.11.tgz#2bfb93d0809ec2357c12ebb27736b750c9ae0aa5" + integrity sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg== + +"@esbuild/linux-arm@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.11.tgz#e56fb3b76828317a704f4a167c5bd790fe5314e7" + integrity sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg== + +"@esbuild/linux-ia32@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.11.tgz#59fa1c49b271793d14eb5effc757e8c0d0cb2cab" + integrity sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA== + +"@esbuild/linux-loong64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.11.tgz#89575bc189099c03a36daa54f3f481780c7fd502" + integrity sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g== + +"@esbuild/linux-mips64el@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.11.tgz#0e18ca039dc7e4645efd8edc1b10952933eb6b1b" + integrity sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw== + +"@esbuild/linux-ppc64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.11.tgz#2d152cb3a253afb8c100a165ad132dc96f36cb11" + integrity sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA== + +"@esbuild/linux-riscv64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.11.tgz#c6ac494a81221d53d65b33e665c7df1747952d3c" + integrity sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA== + +"@esbuild/linux-s390x@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.11.tgz#4bad33894bc7415cea4be8fa90fe456226a424ad" + integrity sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ== + +"@esbuild/linux-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.11.tgz#903fda743459f530a16a6c6ee8d2c0f6c1a12fc7" + integrity sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw== + +"@esbuild/netbsd-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.11.tgz#b589239fe7d9b16ee03c5e191f3f5b640f1518a1" + integrity sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag== + +"@esbuild/openbsd-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.11.tgz#b355019754116bef39ec688f8fd2fe6471b9779b" + integrity sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w== + +"@esbuild/sunos-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.11.tgz#2ea47fb592e68406e5025a7696dc714fc6a115dc" + integrity sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg== + +"@esbuild/win32-arm64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.11.tgz#47e6fdab17c4c52e6e0d606dd9cb843b29826325" + integrity sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ== + +"@esbuild/win32-ia32@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.11.tgz#a97273aa3164c8d8f501899f55cc75a4a79599a3" + integrity sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw== + +"@esbuild/win32-x64@0.17.11": + version "0.17.11" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.11.tgz#9be796d93ae27b636da32d960899a4912bca27a1" + integrity sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ== "@eslint/eslintrc@^0.4.3": version "0.4.3" @@ -795,10 +795,18 @@ chalk "^4.1.2" semver "^7.3.8" -"@jsii/spec@1.76.0", "@jsii/spec@^1.76.0": - version "1.76.0" - resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.76.0.tgz#9323aec77f4e0a3ec7c68a5c257b0841f5ad0731" - integrity sha512-7L8KeG44ECq0ulKYWaOr0FQvnFW7RavjxEGvMAdKfIOXb5mZyGERnj5pKl5kmq2m1lWE2VBZELoTfM7dDlAPtg== +"@jsii/check-node@1.77.0": + version "1.77.0" + resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.77.0.tgz#46e0e4201f5006cef0c5d11a1ce4b00b6ce27801" + integrity sha512-kgq4h5SrpIuM9CZ6uZVZ9KrJCPSn6zwz4y60ZEIFMA5aqkBN1n7MhTJglG6I8IaL2uYm7P5kZf6+eGNI+n3tig== + dependencies: + chalk "^4.1.2" + semver "^7.3.8" + +"@jsii/spec@1.77.0", "@jsii/spec@^1.76.0", "@jsii/spec@^1.77.0": + version "1.77.0" + resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.77.0.tgz#2ee31c32e26d61880e422a546a62296c6543bff9" + integrity sha512-QmwXRREX8W1YOdKHbfu+Tw0rygdCJ2AYcKt7iu56Is2giQ9doyRLKvzywXoKxJjZtj9E7Sp0GdDob8pl8cwmlg== dependencies: ajv "^8.12.0" @@ -2157,9 +2165,9 @@ integrity sha512-uv53RrNdhbkV/3VmVCtfImfYCWC3GTTRn3R11Whni3EJ+gb178tkZBVNj2edLY5CMrB749dQi+SJkg87jsN8UQ== "@types/node@*": - version "18.14.2" - resolved "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz#c076ed1d7b6095078ad3cf21dfeea951842778b1" - integrity sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA== + version "18.14.6" + resolved "https://registry.npmjs.org/@types/node/-/node-18.14.6.tgz#ae1973dd2b1eeb1825695bb11ebfb746d27e3e93" + integrity sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA== "@types/node@18.11.19": version "18.11.19" @@ -2167,9 +2175,9 @@ integrity sha512-YUgMWAQBWLObABqrvx8qKO1enAvBUdjZOAWQ5grBAkp5LQv45jBvYKZ3oFS9iKRCQyFjqw6iuEa1vmFqtxYLZw== "@types/node@^16.9.2": - version "16.18.13" - resolved "https://registry.npmjs.org/@types/node/-/node-16.18.13.tgz#c572f8837094c6e3b73918a68674c784f6877fc0" - integrity sha512-l0/3XZ153UTlNOnZK8xSNoJlQda9/WnYgiTdcKKPJSZjdjI9MU+A9oMXOesAWLSnqAaaJhj3qfQsU07Dr8OUwg== + version "16.18.14" + resolved "https://registry.npmjs.org/@types/node/-/node-16.18.14.tgz#5465ce598486a703caddbefe8603f8a2cffa3461" + integrity sha512-wvzClDGQXOCVNU4APPopC2KtMYukaF1MN/W3xAmslx22Z4/IF1/izDMekuyoUlwfnDHYCIZGaj7jMwnJKBTxKw== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -2328,13 +2336,13 @@ tsutils "^3.21.0" "@typescript-eslint/eslint-plugin@^5": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz#2c821ad81b2c786d142279a8292090f77d1881f4" - integrity sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw== + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.1.tgz#0c5091289ce28372e38ab8d28e861d2dbe1ab29e" + integrity sha512-a2RQAkosH3d3ZIV08s3DcL/mcGc2M/UC528VkPULFxR9VnVPT8pBu0IyBAJJmVsCmhVfwQX1v6q+QGnmSe1bew== dependencies: - "@typescript-eslint/scope-manager" "5.54.0" - "@typescript-eslint/type-utils" "5.54.0" - "@typescript-eslint/utils" "5.54.0" + "@typescript-eslint/scope-manager" "5.54.1" + "@typescript-eslint/type-utils" "5.54.1" + "@typescript-eslint/utils" "5.54.1" debug "^4.3.4" grapheme-splitter "^1.0.4" ignore "^5.2.0" @@ -2366,13 +2374,13 @@ debug "^4.3.1" "@typescript-eslint/parser@^5": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz#def186eb1b1dbd0439df0dacc44fb6d8d5c417fe" - integrity sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ== + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.1.tgz#05761d7f777ef1c37c971d3af6631715099b084c" + integrity sha512-8zaIXJp/nG9Ff9vQNh7TI+C3nA6q6iIsGJ4B4L6MhZ7mHnTMR4YP5vp2xydmFXIy8rpyIVbNAG44871LMt6ujg== dependencies: - "@typescript-eslint/scope-manager" "5.54.0" - "@typescript-eslint/types" "5.54.0" - "@typescript-eslint/typescript-estree" "5.54.0" + "@typescript-eslint/scope-manager" "5.54.1" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/typescript-estree" "5.54.1" debug "^4.3.4" "@typescript-eslint/scope-manager@4.33.0": @@ -2383,21 +2391,21 @@ "@typescript-eslint/types" "4.33.0" "@typescript-eslint/visitor-keys" "4.33.0" -"@typescript-eslint/scope-manager@5.54.0": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz#74b28ac9a3fc8166f04e806c957adb8c1fd00536" - integrity sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg== +"@typescript-eslint/scope-manager@5.54.1": + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.1.tgz#6d864b4915741c608a58ce9912edf5a02bb58735" + integrity sha512-zWKuGliXxvuxyM71UA/EcPxaviw39dB2504LqAmFDjmkpO8qNLHcmzlh6pbHs1h/7YQ9bnsO8CCcYCSA8sykUg== dependencies: - "@typescript-eslint/types" "5.54.0" - "@typescript-eslint/visitor-keys" "5.54.0" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/visitor-keys" "5.54.1" -"@typescript-eslint/type-utils@5.54.0": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.0.tgz#390717216eb61393a0cad2995da154b613ba7b26" - integrity sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ== +"@typescript-eslint/type-utils@5.54.1": + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.1.tgz#4825918ec27e55da8bb99cd07ec2a8e5f50ab748" + integrity sha512-WREHsTz0GqVYLIbzIZYbmUUr95DKEKIXZNH57W3s+4bVnuF1TKe2jH8ZNH8rO1CeMY3U4j4UQeqPNkHMiGem3g== dependencies: - "@typescript-eslint/typescript-estree" "5.54.0" - "@typescript-eslint/utils" "5.54.0" + "@typescript-eslint/typescript-estree" "5.54.1" + "@typescript-eslint/utils" "5.54.1" debug "^4.3.4" tsutils "^3.21.0" @@ -2406,10 +2414,10 @@ resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== -"@typescript-eslint/types@5.54.0": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.0.tgz#7d519df01f50739254d89378e0dcac504cab2740" - integrity sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ== +"@typescript-eslint/types@5.54.1": + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.1.tgz#29fbac29a716d0f08c62fe5de70c9b6735de215c" + integrity sha512-G9+1vVazrfAfbtmCapJX8jRo2E4MDXxgm/IMOF4oGh3kq7XuK3JRkOg6y2Qu1VsTRmWETyTkWt1wxy7X7/yLkw== "@typescript-eslint/typescript-estree@4.33.0", "@typescript-eslint/typescript-estree@^4.33.0": version "4.33.0" @@ -2424,29 +2432,29 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.54.0": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz#f6f3440cabee8a43a0b25fa498213ebb61fdfe99" - integrity sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ== +"@typescript-eslint/typescript-estree@5.54.1": + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.1.tgz#df7b6ae05fd8fef724a87afa7e2f57fa4a599be1" + integrity sha512-bjK5t+S6ffHnVwA0qRPTZrxKSaFYocwFIkZx5k7pvWfsB1I57pO/0M0Skatzzw1sCkjJ83AfGTL0oFIFiDX3bg== dependencies: - "@typescript-eslint/types" "5.54.0" - "@typescript-eslint/visitor-keys" "5.54.0" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/visitor-keys" "5.54.1" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.54.0": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.0.tgz#3db758aae078be7b54b8ea8ea4537ff6cd3fbc21" - integrity sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw== +"@typescript-eslint/utils@5.54.1": + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.1.tgz#7a3ee47409285387b9d4609ea7e1020d1797ec34" + integrity sha512-IY5dyQM8XD1zfDe5X8jegX6r2EVU5o/WJnLu/znLPWCBF7KNGC+adacXnt5jEYS9JixDcoccI6CvE4RCjHMzCQ== dependencies: "@types/json-schema" "^7.0.9" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.54.0" - "@typescript-eslint/types" "5.54.0" - "@typescript-eslint/typescript-estree" "5.54.0" + "@typescript-eslint/scope-manager" "5.54.1" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/typescript-estree" "5.54.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" semver "^7.3.7" @@ -2459,12 +2467,12 @@ "@typescript-eslint/types" "4.33.0" eslint-visitor-keys "^2.0.0" -"@typescript-eslint/visitor-keys@5.54.0": - version "5.54.0" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz#846878afbf0cd67c19cfa8d75947383d4490db8f" - integrity sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA== +"@typescript-eslint/visitor-keys@5.54.1": + version "5.54.1" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.1.tgz#d7a8a0f7181d6ac748f4d47b2306e0513b98bf8b" + integrity sha512-q8iSoHTgwCfgcRJ2l2x+xCbu8nBlRAlsQ33k24Adj8eoVBE0f8dUeI+bAa8F84Mv05UGbAx57g2zrRsYIooqQg== dependencies: - "@typescript-eslint/types" "5.54.0" + "@typescript-eslint/types" "5.54.1" eslint-visitor-keys "^3.3.0" "@xmldom/xmldom@^0.8.6": @@ -2541,12 +2549,12 @@ agent-base@6, agent-base@^6.0.0, agent-base@^6.0.2: debug "4" agentkeepalive@^4.1.3, agentkeepalive@^4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" - integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== + version "4.3.0" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" + integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== dependencies: debug "^4.1.0" - depd "^1.1.2" + depd "^2.0.0" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -2887,10 +2895,10 @@ aws-sdk-mock@5.6.0: sinon "^11.1.1" traverse "^0.6.6" -aws-sdk@^2.1325.0, aws-sdk@^2.928.0: - version "2.1325.0" - resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1325.0.tgz#4529ede089ee8db79d6eb04ab46a211bfddbbe5b" - integrity sha512-ztg9HG5aoUHTprY+/eqjqb25E4joCgz+8ToxsP4OSKFQCtaBcF6my03j4e/J2j3fmpPifJnZSPMu4kV7DBj8WA== +aws-sdk@^2.1329.0, aws-sdk@^2.928.0: + version "2.1329.0" + resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1329.0.tgz#6a83a1f7f8e1b3cdc8f8bdc3b7db7bfd43812b78" + integrity sha512-F5M9x/T+PanPiYGiL95atFE6QiwzJWwgPahaEgUdq+qvVAgruiNy5t6nw2B5tBB/yWDPPavHFip3UsXeO0qU3Q== dependencies: buffer "4.9.2" events "1.1.1" @@ -3258,9 +3266,9 @@ camelcase@^6.2.0, camelcase@^6.3.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001449: - version "1.0.30001458" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz#871e35866b4654a7d25eccca86864f411825540c" - integrity sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w== + version "1.0.30001462" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001462.tgz#b2e801e37536d453731286857c8520d3dcee15fe" + integrity sha512-PDd20WuOBPiasZ7KbFnmQRyuLE7cFXW2PVd7dmALzbkUXEP46upAuCDm9eY9vho8fgNMGmbAX92QBZHzcnWIqw== case@1.6.3, case@^1.6.3: version "1.6.3" @@ -3272,29 +3280,29 @@ caseless@~0.12.0: resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -cdk-generate-synthetic-examples@^0.1.167: - version "0.1.167" - resolved "https://registry.npmjs.org/cdk-generate-synthetic-examples/-/cdk-generate-synthetic-examples-0.1.167.tgz#1fba547e4cab09b914c0cf36e72d618cedbf8df3" - integrity sha512-rjSRrw1fzalETc1tI5pm8aytdnuaqa6/oDD/r2fsSPzWzoOtV8W+TCNx4/BkPgZxaKJwwURpUAx7Jl8R12eZWg== +cdk-generate-synthetic-examples@^0.1.173: + version "0.1.173" + resolved "https://registry.npmjs.org/cdk-generate-synthetic-examples/-/cdk-generate-synthetic-examples-0.1.173.tgz#2792893986c57e9859e23a178c146736845bf51f" + integrity sha512-BTf4tAWfmGZ2nZgQmFZuCpU2o/Ay8YvizYhDTKmqFlipm12luewZkSBP9U52QQZRRiC+Wnn5YFAetJF4Ho4IEg== dependencies: - "@jsii/spec" "^1.76.0" + "@jsii/spec" "^1.77.0" fs-extra "^10.1.0" - jsii "^1.76.0" - jsii-reflect "^1.76.0" - jsii-rosetta "^1.76.0" + jsii "^1.77.0" + jsii-reflect "^1.77.0" + jsii-rosetta "^1.77.0" yargs "^17.7.1" -cdk8s-plus-24@2.4.40: - version "2.4.40" - resolved "https://registry.npmjs.org/cdk8s-plus-24/-/cdk8s-plus-24-2.4.40.tgz#f27c4c5f0adf20ec58294ac7452fdbe3bcb64a9a" - integrity sha512-vDs1Q1XJ1cVg9ap/onOPEC4QRhuCMIHod7TeeQqO8v6I1bB2W9sZc52aLBEc4u9yEuI7/pP2t1rL9m+obcITvw== +cdk8s-plus-24@2.4.46: + version "2.4.46" + resolved "https://registry.npmjs.org/cdk8s-plus-24/-/cdk8s-plus-24-2.4.46.tgz#4168a1cda18daa828494384f6866a7c35bb3578c" + integrity sha512-GMkCQ5NpKxFgbSy8eKCGWr3Eu5QeL2cmNQ1tcQYE7VELhoJfGVxOESRmdN8W6f9eik50mHql2V0Np/kKpNQhtA== dependencies: minimatch "^3.1.2" -cdk8s@^2.7.15: - version "2.7.15" - resolved "https://registry.npmjs.org/cdk8s/-/cdk8s-2.7.15.tgz#f7d40a17e5ce662208d2713e02a1902593d1caa0" - integrity sha512-bQIYHUas23SnjSso1ajZdzs0uKY76jisv41KhdL0RMaG+kvHZ5U6WqbKgwMfocPB9DDKxl+k00emn/g5Eh+Nvg== +cdk8s@^2.7.23: + version "2.7.23" + resolved "https://registry.npmjs.org/cdk8s/-/cdk8s-2.7.23.tgz#d9be5e0ec64ac2f4e8427b5c6710e716117cd85b" + integrity sha512-mofg+0B6VkIXMbW6yWNW6fxAiiMZMUllRm5MDtWby+WuNEKVVHNmtRXD2CtJrrdZ1HVOUJwF9C5+/h2yJC/XYA== dependencies: fast-json-patch "^3.1.1" follow-redirects "^1.15.2" @@ -3526,10 +3534,10 @@ co@^4.6.0: resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== -codemaker@1.76.0, codemaker@^1.76.0: - version "1.76.0" - resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.76.0.tgz#28a2c517ee53bdcfb02030c82520f669db6e5286" - integrity sha512-EqnBOOiEV+kjyRghA5Z0TX22VnVH2Mgo2diOSYelcmntlTSiQkZimGof6jxE5j1buzjEVBK1d1W7bhRKYGegUg== +codemaker@1.77.0, codemaker@^1.77.0: + version "1.77.0" + resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.77.0.tgz#8fa150ab21c8fcb0f6ee557bbc3160529c03499c" + integrity sha512-XSHAqkXMn5OtcebJLVMFEW9puB+4ZmmChBFspEf62ZeYzs+ggSXEHW9GrjC/ZyX+sfxql6ciJP3z25sSp4VsVQ== dependencies: camelcase "^6.3.0" decamelize "^5.0.1" @@ -3699,9 +3707,9 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control- integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== constructs@^10.0.0: - version "10.1.264" - resolved "https://registry.npmjs.org/constructs/-/constructs-10.1.264.tgz#84d418b582e6938b998d67e493a6db49011277bc" - integrity sha512-f9db+zgEV9xiIhmHxBuxNU2DjmnIQkM5M4IyLvjP+pBtS3r+PflQFwdZlDuy3K84NMnSaI4J/Sz5i5aNgwmDAg== + version "10.1.270" + resolved "https://registry.npmjs.org/constructs/-/constructs-10.1.270.tgz#a9e55f33504b14561fe3dc971b9075b864610272" + integrity sha512-EuPb/VI9q0pOy/deaddOIO0RKdJXpBv+qTo7AbYK2dcEq6Kd7PJ8TnDQ5XwotWgB7YaXuTPddIgFDyyIstHcsA== conventional-changelog-angular@^5.0.12: version "5.0.13" @@ -4159,16 +4167,11 @@ delegates@^1.0.0: resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -depd@2.0.0: +depd@2.0.0, depd@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -depd@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - dependency-tree@^8.1.1: version "8.1.2" resolved "https://registry.npmjs.org/dependency-tree/-/dependency-tree-8.1.2.tgz#c9e652984f53bd0239bc8a3e50cbd52f05b2e770" @@ -4414,9 +4417,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.4.284: - version "1.4.314" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.314.tgz#33e4ad7a2ca2ddbe2e113874cc0c0e2a00cb46bf" - integrity sha512-+3RmNVx9hZLlc0gW//4yep0K5SYKmIvB5DXg1Yg6varsuAHlHwTeqeygfS8DWwLCsNOWrgj+p9qgM5WYjw1lXQ== + version "1.4.322" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.322.tgz#e0afa1d115b66c1d47869db40d8f2f3729cecc16" + integrity sha512-KovjizNC9XB7dno/2GjxX8VS0SlfPpCjtyoKft+bCO+UfD8bFy16hY4Sh9s0h9BDxbRH2U0zX5VBjpM1LTcNlg== emittery@^0.8.1: version "0.8.1" @@ -4599,33 +4602,33 @@ es6-weak-map@^2.0.3: es6-iterator "^2.0.3" es6-symbol "^3.1.1" -esbuild@^0.17.10: - version "0.17.10" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.10.tgz#3be050561b34c5dc05b46978f4e1f326d5cc9437" - integrity sha512-n7V3v29IuZy5qgxx25TKJrEm0FHghAlS6QweUcyIgh/U0zYmQcvogWROitrTyZId1mHSkuhhuyEXtI9OXioq7A== +esbuild@^0.17.11: + version "0.17.11" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.11.tgz#9f3122643b21d7e7731e42f18576c10bfa28152b" + integrity sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg== optionalDependencies: - "@esbuild/android-arm" "0.17.10" - "@esbuild/android-arm64" "0.17.10" - "@esbuild/android-x64" "0.17.10" - "@esbuild/darwin-arm64" "0.17.10" - "@esbuild/darwin-x64" "0.17.10" - "@esbuild/freebsd-arm64" "0.17.10" - "@esbuild/freebsd-x64" "0.17.10" - "@esbuild/linux-arm" "0.17.10" - "@esbuild/linux-arm64" "0.17.10" - "@esbuild/linux-ia32" "0.17.10" - "@esbuild/linux-loong64" "0.17.10" - "@esbuild/linux-mips64el" "0.17.10" - "@esbuild/linux-ppc64" "0.17.10" - "@esbuild/linux-riscv64" "0.17.10" - "@esbuild/linux-s390x" "0.17.10" - "@esbuild/linux-x64" "0.17.10" - "@esbuild/netbsd-x64" "0.17.10" - "@esbuild/openbsd-x64" "0.17.10" - "@esbuild/sunos-x64" "0.17.10" - "@esbuild/win32-arm64" "0.17.10" - "@esbuild/win32-ia32" "0.17.10" - "@esbuild/win32-x64" "0.17.10" + "@esbuild/android-arm" "0.17.11" + "@esbuild/android-arm64" "0.17.11" + "@esbuild/android-x64" "0.17.11" + "@esbuild/darwin-arm64" "0.17.11" + "@esbuild/darwin-x64" "0.17.11" + "@esbuild/freebsd-arm64" "0.17.11" + "@esbuild/freebsd-x64" "0.17.11" + "@esbuild/linux-arm" "0.17.11" + "@esbuild/linux-arm64" "0.17.11" + "@esbuild/linux-ia32" "0.17.11" + "@esbuild/linux-loong64" "0.17.11" + "@esbuild/linux-mips64el" "0.17.11" + "@esbuild/linux-ppc64" "0.17.11" + "@esbuild/linux-riscv64" "0.17.11" + "@esbuild/linux-s390x" "0.17.11" + "@esbuild/linux-x64" "0.17.11" + "@esbuild/netbsd-x64" "0.17.11" + "@esbuild/openbsd-x64" "0.17.11" + "@esbuild/sunos-x64" "0.17.11" + "@esbuild/win32-arm64" "0.17.11" + "@esbuild/win32-ia32" "0.17.11" + "@esbuild/win32-x64" "0.17.11" escalade@^3.1.1: version "3.1.1" @@ -4927,9 +4930,9 @@ esprima@^4.0.0, esprima@^4.0.1: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.0, esquery@^1.4.2: - version "1.4.2" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz#c6d3fee05dd665808e2ad870631f221f5617b1d1" - integrity sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng== + version "1.5.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -6097,12 +6100,12 @@ is-arguments@^1.0.4: has-tostringtag "^1.0.0" is-array-buffer@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a" - integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== + version "3.0.2" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== dependencies: call-bind "^1.0.2" - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.0" is-typed-array "^1.1.10" is-arrayish@^0.2.1: @@ -7016,64 +7019,64 @@ jsesc@^2.5.1: resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsii-diff@1.76.0: - version "1.76.0" - resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.76.0.tgz#8aba54481e1ac7dcd7e2c592d1ef11defe244b2a" - integrity sha512-i3U753ae5WzaiGLJV8ZFTu9rlGQGVuSJADCHxteP2UuHuFSWRSPY2iMhtyg7tEoQmdNYjPznM7fesqrDHLxBOg== +jsii-diff@1.77.0: + version "1.77.0" + resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.77.0.tgz#f56c72ff22918dbcf2dcdfd10ad3c15815833aa0" + integrity sha512-H/ujCkMXM1VrZJQJVOfkz+t1S9CAVTut0HSENuXrDdxdIUgIIIT7gnap7LNFVxKwOU9E54Ya+hEnSwjO3sw1FQ== dependencies: - "@jsii/check-node" "1.76.0" - "@jsii/spec" "^1.76.0" + "@jsii/check-node" "1.77.0" + "@jsii/spec" "^1.77.0" fs-extra "^10.1.0" - jsii-reflect "^1.76.0" - log4js "^6.7.1" + jsii-reflect "^1.77.0" + log4js "^6.8.0" yargs "^16.2.0" -jsii-pacmak@1.76.0: - version "1.76.0" - resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.76.0.tgz#e0d95bc20f757f7b067dc545587bc38795611b09" - integrity sha512-70h0puIRpDeDyYk/jLxQk7vPbg3w3ppJRATlF0qPntMk/WnSo4uvr8hlz1BmRzOOvQ7JqXBuNOaVd+bp7Xolbw== +jsii-pacmak@1.77.0: + version "1.77.0" + resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.77.0.tgz#f6253a871bccc8a0617a032235a8cdbf33bffd03" + integrity sha512-mYrITqM/fTiS1rzGFYeIK90/Ab7S39/4wFlBlhVYqqxbeAwiOFS1+zfx2m5RBYGvJMw5rd6S4zoWg6CnK2kpPg== dependencies: - "@jsii/check-node" "1.76.0" - "@jsii/spec" "^1.76.0" + "@jsii/check-node" "1.77.0" + "@jsii/spec" "^1.77.0" clone "^2.1.2" - codemaker "^1.76.0" + codemaker "^1.77.0" commonmark "^0.30.0" escape-string-regexp "^4.0.0" fs-extra "^10.1.0" - jsii-reflect "^1.76.0" - jsii-rosetta "^1.76.0" + jsii-reflect "^1.77.0" + jsii-rosetta "^1.77.0" semver "^7.3.8" spdx-license-list "^6.6.0" xmlbuilder "^15.1.1" yargs "^16.2.0" -jsii-reflect@1.76.0, jsii-reflect@^1.76.0: - version "1.76.0" - resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.76.0.tgz#a80ab48f9bea9f1ad4212e8b2057eb0ae325e1e0" - integrity sha512-voS5WyeitP3o0knus00v00NlxVLbaU9ykvEDamFw5KPEc4z4wvAwDG9wBfNmdO1OulXgID41WhMzJOEJFKle6A== +jsii-reflect@1.77.0, jsii-reflect@^1.77.0: + version "1.77.0" + resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.77.0.tgz#f4fa0c43f550f6af065b118427763dc00f861a7c" + integrity sha512-wSEkBxdEjuZHp2qLPpUPFamhppvDBW+vUJi8/VnQlAYJMCOIvQPdj8GVfiMllc+6tir9xIHl8q30PZaanbQpXA== dependencies: - "@jsii/check-node" "1.76.0" - "@jsii/spec" "^1.76.0" + "@jsii/check-node" "1.77.0" + "@jsii/spec" "^1.77.0" chalk "^4" fs-extra "^10.1.0" - oo-ascii-tree "^1.76.0" + oo-ascii-tree "^1.77.0" yargs "^16.2.0" -jsii-rosetta@^1.76.0: - version "1.76.0" - resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.76.0.tgz#450256361bdbb0d6d5524c4817a7b345d9647a57" - integrity sha512-y3OcYebjMdK/4Yxt8P9tMalK9Szmq8Xc4VXD3kGDIEulMjUxo3TpEUZc9WEfzVu6A+lSl/WRAwV50ZgzQyVWZg== +jsii-rosetta@^1.77.0: + version "1.77.0" + resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.77.0.tgz#12e99f0e43c5028456883f46d3ac92bd8c77a22e" + integrity sha512-gOpK7YxGb64Fwy6zvEpRV3umC3u77HAmltP3kSF/eGPmM04ggTQ17UEfN+XsEO4NXJh1LDniMDyMjOIa3QViBw== dependencies: - "@jsii/check-node" "1.76.0" - "@jsii/spec" "1.76.0" + "@jsii/check-node" "1.77.0" + "@jsii/spec" "1.77.0" "@xmldom/xmldom" "^0.8.6" commonmark "^0.30.0" fast-glob "^3.2.12" - jsii "1.76.0" + jsii "1.77.0" semver "^7.3.8" semver-intersect "^1.4.0" typescript "~3.9.10" - workerpool "^6.3.1" + workerpool "^6.4.0" yargs "^16.2.0" jsii-rosetta@v4.9-next: @@ -7093,18 +7096,18 @@ jsii-rosetta@v4.9-next: workerpool "^6.4.0" yargs "^17.7.1" -jsii@1.76.0, jsii@^1.76.0: - version "1.76.0" - resolved "https://registry.npmjs.org/jsii/-/jsii-1.76.0.tgz#b40c98108b1cac2cb86a5eb2b3f201ba52a316b6" - integrity sha512-IlQmxPPnscn2Va/cnnXRnQ7bnxEkO8ImKW0MBlEr66oqxhFQ9jy9+FWzOp/5kfHzhyyyM5mcqitB8O6fr1moIw== +jsii@1.77.0, jsii@^1.77.0: + version "1.77.0" + resolved "https://registry.npmjs.org/jsii/-/jsii-1.77.0.tgz#bc3f4e3c475045f5d8d49c3c6fe202b33a1d0705" + integrity sha512-3VODnWUhljro1+PmWlTWAEUPxWGWwCOmzOS6EG7l5E1KthurCgQDzhpTySlw80U85mGU9XvDJMcpvwuj3ESrKA== dependencies: - "@jsii/check-node" "1.76.0" - "@jsii/spec" "^1.76.0" + "@jsii/check-node" "1.77.0" + "@jsii/spec" "^1.77.0" case "^1.6.3" chalk "^4" fast-deep-equal "^3.1.3" fs-extra "^10.1.0" - log4js "^6.7.1" + log4js "^6.8.0" semver "^7.3.8" semver-intersect "^1.4.0" sort-json "^2.0.1" @@ -7113,9 +7116,9 @@ jsii@1.76.0, jsii@^1.76.0: yargs "^16.2.0" jsii@v4.9-next: - version "4.9.0-dev.1" - resolved "https://registry.npmjs.org/jsii/-/jsii-4.9.0-dev.1.tgz#3fcc0001a425f7cf933260b9b9dd999ca71739b6" - integrity sha512-1neCv7G/y9Ihku5ZEz2cDMuSNXpZYxNuTS1ycVXZ0ZhOVGn0+s0ghkOLj+Xecei3M0fBfZxlLiHSpw3xrJT/Mg== + version "4.9.0-dev.2" + resolved "https://registry.npmjs.org/jsii/-/jsii-4.9.0-dev.2.tgz#6b193a8a1ce6078741ce4f40bf1b5cf01c9a6f41" + integrity sha512-5VIj4HVTYuXJwv+UnEG9KIZ1Kwx4S7fws0y6XwMf6U7Qr4QbOwW59HM7mn28B0GJgj83y/CezcJTTqpuEES+5Q== dependencies: "@jsii/check-node" "1.76.0" "@jsii/spec" "^1.76.0" @@ -7697,10 +7700,10 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log4js@^6.7.1, log4js@^6.8.0: - version "6.8.0" - resolved "https://registry.npmjs.org/log4js/-/log4js-6.8.0.tgz#f0fe9b2b82725aaf97f20692e23381a5c5722448" - integrity sha512-g+V8gZyurIexrOvWQ+AcZsIvuK/lBnx2argejZxL4gVZ4Hq02kUYH6WZOnqxgBml+zzQZYdaEoTN84B6Hzm8Fg== +log4js@^6.8.0: + version "6.9.0" + resolved "https://registry.npmjs.org/log4js/-/log4js-6.9.0.tgz#2687c08b330f610054e79c492b35c677c9b183eb" + integrity sha512-sAGxJKqxXFlK+05OlMH6SIDAdvgQHj95EfSDOfkHW6BQUlkz+fZw8PWhydfRHq+0UuWYWR55mVnR+KTnWE2JDA== dependencies: date-format "^4.0.14" debug "^4.3.4" @@ -7733,9 +7736,9 @@ lru-cache@^6.0.0: yallist "^4.0.0" lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: - version "7.18.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.1.tgz#4716408dec51d5d0104732647f584d1f6738b109" - integrity sha512-8/HcIENyQnfUTCDizRu9rrDyG6XG/21M4X7/YEGZeD76ZJilFPAUVb/2zysFf7VVO1LEjCDFyHp8pMMvozIrvg== + version "7.18.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== lru-queue@^0.1.0: version "0.1.0" @@ -8016,9 +8019,9 @@ min-indent@^1.0.0: integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== minimatch@>=3.1: - version "7.4.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-7.4.1.tgz#166705f9417985ba5149f2dbf2fa50c29832913b" - integrity sha512-Oz1iPEP+MGl7KS3SciLsLLcuZ7VsBfb7Qrz/jYt/s/sYAv272P26HSLz2f77Y6hzTKXiBi6g765fqpEDNc5fJw== + version "7.4.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz#157e847d79ca671054253b840656720cb733f10f" + integrity sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA== dependencies: brace-expansion "^2.0.1" @@ -8860,10 +8863,10 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -oo-ascii-tree@^1.76.0: - version "1.76.0" - resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.76.0.tgz#776630f3e3df43a3a5082cbf23fa40e3ada808ab" - integrity sha512-I/me4GK6Dybc9lsPYZJdnd1OOFbbnZtfEIIizrbTuFx/v1if375Y59w9ol/TJ75MlSAKs4aHj7Xm+A4E0JitSw== +oo-ascii-tree@^1.77.0: + version "1.77.0" + resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.77.0.tgz#8205a3b2df0bd6f085764092ed93b0cd61218f67" + integrity sha512-UQXPEVtecK9FDQxlp5WQ9nVBgS0sq96R9LWE1HBmlS3ZLJRqXh3+kdU7Bxs+qqF+cdWmE9uOggwihBffTpqLrA== open@^7.4.2: version "7.4.2" @@ -9458,10 +9461,10 @@ progress@^2.0.0, progress@^2.0.3: resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -projen@^0.67.69: - version "0.67.69" - resolved "https://registry.npmjs.org/projen/-/projen-0.67.69.tgz#ec666e340395a3b429581a91733b6856d0602e86" - integrity sha512-F28eW4CZFQwsb93omeVfzAoK9hEajqrzBzKZCwIfKaEupAjqJ8KJkc29FW4MnI7tbZ0DzHg75u0yzzNtotaEXg== +projen@^0.67.75: + version "0.67.75" + resolved "https://registry.npmjs.org/projen/-/projen-0.67.75.tgz#64fc75d9e8aaea7ad56424bf78ba0c5d59a8f27e" + integrity sha512-cdCRjhyIumTPOlKIaNSl4FtJUV5QC6C11FqbdEXhOBsnLleppo62NoS/renS4IGkruyHyqliX0bXakBCskYiaQ== dependencies: "@iarna/toml" "^2.2.5" case "^1.6.3" @@ -9618,9 +9621,9 @@ qrcode-terminal@^0.12.0: integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== qs@^6.9.4: - version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + version "6.11.1" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f" + integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ== dependencies: side-channel "^1.0.4" @@ -10449,9 +10452,9 @@ spdx-compare@^1.0.0: spdx-ranges "^2.0.0" spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + version "3.2.0" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -11201,9 +11204,9 @@ typescript@^4.5.5, typescript@~4.9.5: integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== typescript@next: - version "5.1.0-dev.20230301" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.0-dev.20230301.tgz#3250b647dfd19942326bf904211350cdbbfdfe79" - integrity sha512-aJ0PIgQ00zlf9npD2tri7MWDAooMoh3iIn4v0hAMSRCSKqJjTzt7fVopvdtbvWPKripipxeXnX5mhkBZcGrEKQ== + version "5.1.0-dev.20230307" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.0-dev.20230307.tgz#64cde6497b61b894af9b9a0547ee273f11bd34ce" + integrity sha512-QoA4rJ5koT+JJk69FBwAF4vx446c5xPWlvgMrlz0E0SaGDpveCbK8DTpRmdxrZR4oVQ0VxMag1BGtZPtQtU+Jg== typescript@~3.8.3: version "3.8.3" @@ -11627,7 +11630,7 @@ wordwrap@>=0.0.2, wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -workerpool@^6.3.1, workerpool@^6.4.0: +workerpool@^6.4.0: version "6.4.0" resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.4.0.tgz#f8d5cfb45fde32fa3b7af72ad617c3369567a462" integrity sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A== From 1b2014eef9e3f2190b2cce79c55f635cc1f167e3 Mon Sep 17 00:00:00 2001 From: Stefan Freitag Date: Tue, 7 Mar 2023 18:15:56 +0100 Subject: [PATCH 12/22] feat(msk): add Kafka version 3.3.2 (#24440) Add support for the MSK Kafka version 3.3.2. The new version was announced on Mar 02 2023, the link to the announcement is in the linked issue. Closes #24432 . ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-msk/lib/cluster-version.ts | 4 + .../@aws-cdk/aws-msk/test/cluster.test.ts | 1 + ...efaultTestDeployAssertC2F074AF.assets.json | 12 +- ...aultTestDeployAssertC2F074AF.template.json | 4 +- .../index.js | 1 + .../index.js | 253 ------------------ .../aws-cdk-msk-integ.assets.json | 6 +- .../aws-cdk-msk-integ.template.json | 144 ++++++++++ .../test/integ.cluster.js.snapshot/cdk.out | 2 +- .../test/integ.cluster.js.snapshot/integ.json | 2 +- .../integ.cluster.js.snapshot/manifest.json | 36 ++- .../test/integ.cluster.js.snapshot/tree.json | 201 +++++++++++++- .../@aws-cdk/aws-msk/test/integ.cluster.ts | 14 + 13 files changed, 406 insertions(+), 274 deletions(-) rename packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/{asset.1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28.bundle => asset.73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.bundle}/index.js (99%) delete mode 100644 packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js diff --git a/packages/@aws-cdk/aws-msk/lib/cluster-version.ts b/packages/@aws-cdk/aws-msk/lib/cluster-version.ts index e3cdf502caf4b..ba370f8c04885 100644 --- a/packages/@aws-cdk/aws-msk/lib/cluster-version.ts +++ b/packages/@aws-cdk/aws-msk/lib/cluster-version.ts @@ -87,6 +87,10 @@ export class KafkaVersion { */ public static readonly V3_3_1 = KafkaVersion.of('3.3.1'); + /** + * Kafka version 3.3.2 + */ + public static readonly V3_3_2 = KafkaVersion.of('3.3.2'); /** * Custom cluster version * @param version custom version number diff --git a/packages/@aws-cdk/aws-msk/test/cluster.test.ts b/packages/@aws-cdk/aws-msk/test/cluster.test.ts index e6443cd4762c2..be4f6e92679ca 100644 --- a/packages/@aws-cdk/aws-msk/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-msk/test/cluster.test.ts @@ -40,6 +40,7 @@ describe('MSK Cluster', () => { [msk.KafkaVersion.V3_1_1, '3.1.1'], [msk.KafkaVersion.V3_2_0, '3.2.0'], [msk.KafkaVersion.V3_3_1, '3.3.1'], + [msk.KafkaVersion.V3_3_2, '3.3.2'], ], )('created with expected Kafka version %j', (parameter, result) => { new msk.Cluster(stack, 'Cluster', { diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.assets.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.assets.json index e504429e84b40..2d32efad89dbf 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.assets.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.assets.json @@ -1,20 +1,20 @@ { - "version": "30.0.0", + "version": "30.1.0", "files": { - "1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28": { + "73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4": { "source": { - "path": "asset.1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28.bundle", + "path": "asset.73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.bundle", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28.zip", + "objectKey": "73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "e05a31925a856f753d012d462f51a3f4b884235b0fe9c3cea1b63e4c95fcd2c4": { + "26ebb083b5aa4c4938dd01e52996de45327a2629e9d6d262659c6f011a7b21a1": { "source": { "path": "MskLoggingDefaultTestDeployAssertC2F074AF.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "e05a31925a856f753d012d462f51a3f4b884235b0fe9c3cea1b63e4c95fcd2c4.json", + "objectKey": "26ebb083b5aa4c4938dd01e52996de45327a2629e9d6d262659c6f011a7b21a1.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-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.template.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.template.json index af795cd591edf..8ab6331d020e2 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.template.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/MskLoggingDefaultTestDeployAssertC2F074AF.template.json @@ -31,7 +31,7 @@ } }, "flattenResponse": "false", - "salt": "1677027448917" + "salt": "1677835197710" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -124,7 +124,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28.zip" + "S3Key": "73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.zip" }, "Timeout": 120, "Handler": "index.handler", diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28.bundle/index.js b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.bundle/index.js similarity index 99% rename from packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28.bundle/index.js rename to packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.bundle/index.js index 4264087b9aab2..58bcb1ef7f38e 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.1f3c2cfb18e102edc713fe4c4b4d87572f4297ee4a5e80a5960adf526ee9ea28.bundle/index.js +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.bundle/index.js @@ -1,3 +1,4 @@ +"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js deleted file mode 100644 index d913ab9defaa1..0000000000000 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/asset.a268caa53756f51bda8ad5f499be4ed8484a81b314811806fbb66f874837c476/index.js +++ /dev/null @@ -1,253 +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, - 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsaURBQXlDO0FBQ3pDLHlCQUF5QjtBQUN6QiwrQkFBNEI7QUFTNUI7O0dBRUc7QUFDVSxRQUFBLDhCQUE4QixHQUFHLHNCQUFzQixDQUFDO0FBRXJFOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLE1BQWM7SUFDcEMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQixFQUFFLEVBQ0YsR0FBRyxTQUFTLFFBQVEsQ0FBQyxLQUFVLEVBQUUsT0FBaUIsRUFBRTtRQUNsRCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEYsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksUUFBUSxLQUFLLElBQUk7Z0JBQ3RELENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUNWLENBQUM7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LE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUNmO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ1g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDO0FBbEpELDBCQWtKQztBQUVELFNBQVMsVUFBVSxDQUFDLElBQXdCO0lBQzFDLElBQUksQ0FBQyxJQUFJLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQztLQUFFO0lBQ2hDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsYUFBdUI7SUFDOUMsT0FBTyxVQUFTLE1BQWM7UUFDNUIsS0FBSyxNQUFNLFlBQVksSUFBSSxhQUFhLEVBQUU7WUFDeEMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNuQyxPQUFPLElBQUksQ0FBQzthQUNiO1NBQ0Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyBleGVjU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuLy8gaW1wb3J0IHRoZSBBV1NMYW1iZGEgcGFja2FnZSBleHBsaWNpdGx5LFxuLy8gd2hpY2ggaXMgZ2xvYmFsbHkgYXZhaWxhYmxlIGluIHRoZSBMYW1iZGEgcnVudGltZSxcbi8vIGFzIG90aGVyd2lzZSBsaW5raW5nIHRoaXMgcmVwb3NpdG9yeSB3aXRoIGxpbmstYWxsLnNoXG4vLyBmYWlscyBpbiB0aGUgQ0RLIGFwcCBleGVjdXRlZCB3aXRoIHRzLW5vZGVcbi8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMsaW1wb3J0L25vLXVucmVzb2x2ZWQgKi9cbmltcG9ydCAqIGFzIEFXU0xhbWJkYSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7IEF3c1Nka0NhbGwgfSBmcm9tICcuLi9hd3MtY3VzdG9tLXJlc291cmNlJztcblxuLyoqXG4gKiBTZXJpYWxpemVkIGZvcm0gb2YgdGhlIHBoeXNpY2FsIHJlc291cmNlIGlkIGZvciB1c2UgaW4gdGhlIG9wZXJhdGlvbiBwYXJhbWV0ZXJzXG4gKi9cbmV4cG9ydCBjb25zdCBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0UgPSAnUEhZU0lDQUw6UkVTT1VSQ0VJRDonO1xuXG4vKipcbiAqIEZsYXR0ZW5zIGEgbmVzdGVkIG9iamVjdFxuICpcbiAqIEBwYXJhbSBvYmplY3QgdGhlIG9iamVjdCB0byBiZSBmbGF0dGVuZWRcbiAqIEByZXR1cm5zIGEgZmxhdCBvYmplY3Qgd2l0aCBwYXRoIGFzIGtleXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4ob2JqZWN0OiBvYmplY3QpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oXG4gICAge30sXG4gICAgLi4uZnVuY3Rpb24gX2ZsYXR0ZW4oY2hpbGQ6IGFueSwgcGF0aDogc3RyaW5nW10gPSBbXSk6IGFueSB7XG4gICAgICByZXR1cm4gW10uY29uY2F0KC4uLk9iamVjdC5rZXlzKGNoaWxkKVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgY2hpbGRLZXkgPSBCdWZmZXIuaXNCdWZmZXIoY2hpbGRba2V5XSkgPyBjaGlsZFtrZXldLnRvU3RyaW5nKCd1dGY4JykgOiBjaGlsZFtrZXldO1xuICAgICAgICAgIHJldHVybiB0eXBlb2YgY2hpbGRLZXkgPT09ICdvYmplY3QnICYmIGNoaWxkS2V5ICE9PSBudWxsXG4gICAgICAgICAgICA/IF9mbGF0dGVuKGNoaWxkS2V5LCBwYXRoLmNvbmNhdChba2V5XSkpXG4gICAgICAgICAgICA6ICh7IFtwYXRoLmNvbmNhdChba2V5XSkuam9pbignLicpXTogY2hpbGRLZXkgfSk7XG4gICAgICAgIH0pKTtcbiAgICB9KG9iamVjdCksXG4gICk7XG59XG5cbi8qKlxuICogRGVjb2RlcyBlbmNvZGVkIHNwZWNpYWwgdmFsdWVzIChwaHlzaWNhbFJlc291cmNlSWQpXG4gKi9cbmZ1bmN0aW9uIGRlY29kZVNwZWNpYWxWYWx1ZXMob2JqZWN0OiBvYmplY3QsIHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iamVjdCksIChfaywgdikgPT4ge1xuICAgIHN3aXRjaCAodikge1xuICAgICAgY2FzZSBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0U6XG4gICAgICAgIHJldHVybiBwaHlzaWNhbFJlc291cmNlSWQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdjtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIEZpbHRlcnMgdGhlIGtleXMgb2YgYW4gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBmaWx0ZXJLZXlzKG9iamVjdDogb2JqZWN0LCBwcmVkOiAoa2V5OiBzdHJpbmcpID0+IGJvb2xlYW4pIHtcbiAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iamVjdClcbiAgICAucmVkdWNlKFxuICAgICAgKGFjYywgW2ssIHZdKSA9PiBwcmVkKGspXG4gICAgICAgID8geyAuLi5hY2MsIFtrXTogdiB9XG4gICAgICAgIDogYWNjLFxuICAgICAge30sXG4gICAgKTtcbn1cblxubGV0IGxhdGVzdFNka0luc3RhbGxlZCA9IGZhbHNlO1xuXG5leHBvcnQgZnVuY3Rpb24gZm9yY2VTZGtJbnN0YWxsYXRpb24oKSB7XG4gIGxhdGVzdFNka0luc3RhbGxlZCA9IGZhbHNlO1xufVxuXG4vKipcbiAqIEluc3RhbGxzIGxhdGVzdCBBV1MgU0RLIHYyXG4gKi9cbmZ1bmN0aW9uIGluc3RhbGxMYXRlc3RTZGsoKTogdm9pZCB7XG4gIGNvbnNvbGUubG9nKCdJbnN0YWxsaW5nIGxhdGVzdCBBV1MgU0RLIHYyJyk7XG4gIC8vIEJvdGggSE9NRSBhbmQgLS1wcmVmaXggYXJlIG5lZWRlZCBoZXJlIGJlY2F1c2UgL3RtcCBpcyB0aGUgb25seSB3cml0YWJsZSBsb2NhdGlvblxuICBleGVjU3luYygnSE9NRT0vdG1wIG5wbSBpbnN0YWxsIGF3cy1zZGtAMiAtLXByb2R1Y3Rpb24gLS1uby1wYWNrYWdlLWxvY2sgLS1uby1zYXZlIC0tcHJlZml4IC90bXAnKTtcbiAgbGF0ZXN0U2RrSW5zdGFsbGVkID0gdHJ1ZTtcbn1cblxuLy8gbm8gY3VycmVudGx5IHBhdGNoZWQgc2VydmljZXNcbmNvbnN0IHBhdGNoZWRTZXJ2aWNlczogeyBzZXJ2aWNlTmFtZTogc3RyaW5nOyBhcGlWZXJzaW9uczogc3RyaW5nW10gfVtdID0gW107XG4vKipcbiAqIFBhdGNoZXMgdGhlIEFXUyBTREsgYnkgbG9hZGluZyBzZXJ2aWNlIG1vZGVscyBpbiB0aGUgc2FtZSBtYW5uZXIgYXMgdGhlIGFjdHVhbCBTREtcbiAqL1xuZnVuY3Rpb24gcGF0Y2hTZGsoYXdzU2RrOiBhbnkpOiBhbnkge1xuICBjb25zdCBhcGlMb2FkZXIgPSBhd3NTZGsuYXBpTG9hZGVyO1xuICBwYXRjaGVkU2VydmljZXMuZm9yRWFjaCgoeyBzZXJ2aWNlTmFtZSwgYXBpVmVyc2lvbnMgfSkgPT4ge1xuICAgIGNvbnN0IGxvd2VyU2VydmljZU5hbWUgPSBzZXJ2aWNlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICghYXdzU2RrLlNlcnZpY2UuaGFzU2VydmljZShsb3dlclNlcnZpY2VOYW1lKSkge1xuICAgICAgYXBpTG9hZGVyLnNlcnZpY2VzW2xvd2VyU2VydmljZU5hbWVdID0ge307XG4gICAgICBhd3NTZGtbc2VydmljZU5hbWVdID0gYXdzU2RrLlNlcnZpY2UuZGVmaW5lU2VydmljZShsb3dlclNlcnZpY2VOYW1lLCBhcGlWZXJzaW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3c1Nkay5TZXJ2aWNlLmFkZFZlcnNpb25zKGF3c1Nka1tzZXJ2aWNlTmFtZV0sIGFwaVZlcnNpb25zKTtcbiAgICB9XG4gICAgYXBpVmVyc2lvbnMuZm9yRWFjaChhcGlWZXJzaW9uID0+IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcGlMb2FkZXIuc2VydmljZXNbbG93ZXJTZXJ2aWNlTmFtZV0sIGFwaVZlcnNpb24sIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgICAgY29uc3QgbW9kZWxGaWxlUHJlZml4ID0gYGF3cy1zZGstcGF0Y2gvJHtsb3dlclNlcnZpY2VOYW1lfS0ke2FwaVZlcnNpb259YDtcbiAgICAgICAgICBjb25zdCBtb2RlbCA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGpvaW4oX19kaXJuYW1lLCBgJHttb2RlbEZpbGVQcmVmaXh9LnNlcnZpY2UuanNvbmApLCAndXRmLTgnKSk7XG4gICAgICAgICAgbW9kZWwucGFnaW5hdG9ycyA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGpvaW4oX19kaXJuYW1lLCBgJHttb2RlbEZpbGVQcmVmaXh9LnBhZ2luYXRvcnMuanNvbmApLCAndXRmLTgnKSkucGFnaW5hdGlvbjtcbiAgICAgICAgICByZXR1cm4gbW9kZWw7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIGF3c1Nkaztcbn1cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cywgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpIHtcbiAgdHJ5IHtcbiAgICBsZXQgQVdTOiBhbnk7XG4gICAgaWYgKCFsYXRlc3RTZGtJbnN0YWxsZWQgJiYgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkluc3RhbGxMYXRlc3RBd3NTZGsgPT09ICd0cnVlJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW5zdGFsbExhdGVzdFNkaygpO1xuICAgICAgICBBV1MgPSByZXF1aXJlKCcvdG1wL25vZGVfbW9kdWxlcy9hd3Mtc2RrJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBGYWlsZWQgdG8gaW5zdGFsbCBsYXRlc3QgQVdTIFNESyB2MjogJHtlfWApO1xuICAgICAgICBBV1MgPSByZXF1aXJlKCdhd3Mtc2RrJyk7IC8vIEZhbGxiYWNrIHRvIHByZS1pbnN0YWxsZWQgdmVyc2lvblxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobGF0ZXN0U2RrSW5zdGFsbGVkKSB7XG4gICAgICBBV1MgPSByZXF1aXJlKCcvdG1wL25vZGVfbW9kdWxlcy9hd3Mtc2RrJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIEFXUyA9IHJlcXVpcmUoJ2F3cy1zZGsnKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIEFXUyA9IHBhdGNoU2RrKEFXUyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5sb2coYEZhaWxlZCB0byBwYXRjaCBBV1MgU0RLOiAke2V9LiBQcm9jZWVkaW5nIHdpdGggdGhlIGluc3RhbGxlZCBjb3B5LmApO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9KSk7XG4gICAgY29uc29sZS5sb2coJ0FXUyBTREsgVkVSU0lPTjogJyArIEFXUy5WRVJTSU9OKTtcblxuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGUpO1xuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5VcGRhdGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5VcGRhdGUpO1xuICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGUgPSBkZWNvZGVDYWxsKGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGUpO1xuICAgIC8vIERlZmF1bHQgcGh5c2ljYWwgcmVzb3VyY2UgaWRcbiAgICBsZXQgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmc7XG4gICAgc3dpdGNoIChldmVudC5SZXF1ZXN0VHlwZSkge1xuICAgICAgY2FzZSAnQ3JlYXRlJzpcbiAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkNyZWF0ZT8ucGh5c2ljYWxSZXNvdXJjZUlkPy5pZCA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWxldGU/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuTG9naWNhbFJlc291cmNlSWQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnVXBkYXRlJzpcbiAgICAgIGNhc2UgJ0RlbGV0ZSc6XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllc1tldmVudC5SZXF1ZXN0VHlwZV0/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz8gZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBsZXQgZmxhdERhdGE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBsZXQgZGF0YTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIGNvbnN0IGNhbGw6IEF3c1Nka0NhbGwgfCB1bmRlZmluZWQgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXNbZXZlbnQuUmVxdWVzdFR5cGVdO1xuXG4gICAgaWYgKGNhbGwpIHtcblxuICAgICAgbGV0IGNyZWRlbnRpYWxzO1xuICAgICAgaWYgKGNhbGwuYXNzdW1lZFJvbGVBcm4pIHtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgUm9sZUFybjogY2FsbC5hc3N1bWVkUm9sZUFybixcbiAgICAgICAgICBSb2xlU2Vzc2lvbk5hbWU6IGAke3RpbWVzdGFtcH0tJHtwaHlzaWNhbFJlc291cmNlSWR9YC5zdWJzdHJpbmcoMCwgNjQpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNyZWRlbnRpYWxzID0gbmV3IEFXUy5DaGFpbmFibGVUZW1wb3JhcnlDcmVkZW50aWFscyh7XG4gICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgICAgc3RzQ29uZmlnOiB7IHN0c1JlZ2lvbmFsRW5kcG9pbnRzOiAncmVnaW9uYWwnIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChBV1MsIGNhbGwuc2VydmljZSkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoYFNlcnZpY2UgJHtjYWxsLnNlcnZpY2V9IGRvZXMgbm90IGV4aXN0IGluIEFXUyBTREsgdmVyc2lvbiAke0FXUy5WRVJTSU9OfS5gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGF3c1NlcnZpY2UgPSBuZXcgKEFXUyBhcyBhbnkpW2NhbGwuc2VydmljZV0oe1xuICAgICAgICBhcGlWZXJzaW9uOiBjYWxsLmFwaVZlcnNpb24sXG4gICAgICAgIGNyZWRlbnRpYWxzOiBjcmVkZW50aWFscyxcbiAgICAgICAgcmVnaW9uOiBjYWxsLnJlZ2lvbixcbiAgICAgIH0pO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF3c1NlcnZpY2VbY2FsbC5hY3Rpb25dKFxuICAgICAgICAgIGNhbGwucGFyYW1ldGVycyAmJiBkZWNvZGVTcGVjaWFsVmFsdWVzKGNhbGwucGFyYW1ldGVycywgcGh5c2ljYWxSZXNvdXJjZUlkKSkucHJvbWlzZSgpO1xuICAgICAgICBmbGF0RGF0YSA9IHtcbiAgICAgICAgICBhcGlWZXJzaW9uOiBhd3NTZXJ2aWNlLmNvbmZpZy5hcGlWZXJzaW9uLCAvLyBGb3IgdGVzdCBwdXJwb3NlczogY2hlY2sgaWYgYXBpVmVyc2lvbiB3YXMgY29ycmVjdGx5IHBhc3NlZC5cbiAgICAgICAgICByZWdpb246IGF3c1NlcnZpY2UuY29uZmlnLnJlZ2lvbiwgLy8gRm9yIHRlc3QgcHVycG9zZXM6IGNoZWNrIGlmIHJlZ2lvbiB3YXMgY29ycmVjdGx5IHBhc3NlZC5cbiAgICAgICAgICAuLi5mbGF0dGVuKHJlc3BvbnNlKSxcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgb3V0cHV0UGF0aHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoY2FsbC5vdXRwdXRQYXRoKSB7XG4gICAgICAgICAgb3V0cHV0UGF0aHMgPSBbY2FsbC5vdXRwdXRQYXRoXTtcbiAgICAgICAgfSBlbHNlIGlmIChjYWxsLm91dHB1dFBhdGhzKSB7XG4gICAgICAgICAgb3V0cHV0UGF0aHMgPSBjYWxsLm91dHB1dFBhdGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG91dHB1dFBhdGhzKSB7XG4gICAgICAgICAgZGF0YSA9IGZpbHRlcktleXMoZmxhdERhdGEsIHN0YXJ0c1dpdGhPbmVPZihvdXRwdXRQYXRocykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGEgPSBmbGF0RGF0YTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIWNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nIHx8ICFuZXcgUmVnRXhwKGNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nKS50ZXN0KGUuY29kZSkpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjYWxsLnBoeXNpY2FsUmVzb3VyY2VJZD8ucmVzcG9uc2VQYXRoKSB7XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGZsYXREYXRhW2NhbGwucGh5c2ljYWxSZXNvdXJjZUlkLnJlc3BvbnNlUGF0aF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgcmVzcG9uZCgnU1VDQ0VTUycsICdPSycsIHBoeXNpY2FsUmVzb3VyY2VJZCwgZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmxvZyhlKTtcbiAgICBhd2FpdCByZXNwb25kKCdGQUlMRUQnLCBlLm1lc3NhZ2UgfHwgJ0ludGVybmFsIEVycm9yJywgY29udGV4dC5sb2dTdHJlYW1OYW1lLCB7fSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNwb25kKHJlc3BvbnNlU3RhdHVzOiBzdHJpbmcsIHJlYXNvbjogc3RyaW5nLCBwaHlzaWNhbFJlc291cmNlSWQ6IHN0cmluZywgZGF0YTogYW55KSB7XG4gICAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgU3RhdHVzOiByZXNwb25zZVN0YXR1cyxcbiAgICAgIFJlYXNvbjogcmVhc29uLFxuICAgICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBwaHlzaWNhbFJlc291cmNlSWQsXG4gICAgICBTdGFja0lkOiBldmVudC5TdGFja0lkLFxuICAgICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgICBOb0VjaG86IGZhbHNlLFxuICAgICAgRGF0YTogZGF0YSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKCdSZXNwb25kaW5nJywgcmVzcG9uc2VCb2R5KTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgcGFyc2VkVXJsID0gcmVxdWlyZSgndXJsJykucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgICAgbWV0aG9kOiAnUFVUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnaHR0cHMnKS5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCByZXNvbHZlKTtcbiAgICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWNvZGVDYWxsKGNhbGw6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICBpZiAoIWNhbGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICByZXR1cm4gSlNPTi5wYXJzZShjYWxsKTtcbn1cblxuZnVuY3Rpb24gc3RhcnRzV2l0aE9uZU9mKHNlYXJjaFN0cmluZ3M6IHN0cmluZ1tdKTogKHN0cmluZzogc3RyaW5nKSA9PiBib29sZWFuIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBzZWFyY2hTdHJpbmcgb2Ygc2VhcmNoU3RyaW5ncykge1xuICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKHNlYXJjaFN0cmluZykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.assets.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.assets.json index 44941b12cf3c6..989f097f194b0 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.assets.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.assets.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "30.1.0", "files": { "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { "source": { @@ -27,7 +27,7 @@ } } }, - "5c5b94db03f045cf89b28c56612a2b112fa3d83037d4f96122b61ebcfaaa1383": { + "a9b33d873aac9026db60e46ffd1764d09d46440f81b1ffd7fdb395e54501d620": { "source": { "path": "aws-cdk-msk-integ.template.json", "packaging": "file" @@ -35,7 +35,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "5c5b94db03f045cf89b28c56612a2b112fa3d83037d4f96122b61ebcfaaa1383.json", + "objectKey": "a9b33d873aac9026db60e46ffd1764d09d46440f81b1ffd7fdb395e54501d620.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-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.template.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.template.json index 945483ee06744..8458d0b53265a 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.template.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/aws-cdk-msk-integ.template.json @@ -1592,6 +1592,142 @@ } ] } + }, + "ClusterV332SecurityGroupDDA33760": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "MSK security group", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "ClusterV332929A761F": { + "Type": "AWS::MSK::Cluster", + "Properties": { + "BrokerNodeGroupInfo": { + "ClientSubnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "InstanceType": "kafka.m5.large", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "ClusterV332SecurityGroupDDA33760", + "GroupId" + ] + } + ], + "StorageInfo": { + "EBSStorageInfo": { + "VolumeSize": 1000 + } + } + }, + "ClusterName": "integ-test-v3-3-2", + "KafkaVersion": "3.3.2", + "NumberOfBrokerNodes": 2, + "EncryptionInfo": { + "EncryptionInTransit": { + "ClientBroker": "TLS", + "InCluster": true + } + }, + "LoggingInfo": { + "BrokerLogs": { + "CloudWatchLogs": { + "Enabled": false + }, + "Firehose": { + "Enabled": false + }, + "S3": { + "Bucket": { + "Ref": "LoggingBucket1E5A6F3B" + }, + "Enabled": true + } + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterV332BootstrapBrokersBootstrapBrokerStringTls06A03A3A": { + "Type": "Custom::AWS", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd22872D164C4C", + "Arn" + ] + }, + "Create": { + "Fn::Join": [ + "", + [ + "{\"service\":\"Kafka\",\"action\":\"getBootstrapBrokers\",\"parameters\":{\"ClusterArn\":\"", + { + "Ref": "ClusterV332929A761F" + }, + "\"},\"physicalResourceId\":{\"id\":\"BootstrapBrokers\"}}" + ] + ] + }, + "Update": { + "Fn::Join": [ + "", + [ + "{\"service\":\"Kafka\",\"action\":\"getBootstrapBrokers\",\"parameters\":{\"ClusterArn\":\"", + { + "Ref": "ClusterV332929A761F" + }, + "\"},\"physicalResourceId\":{\"id\":\"BootstrapBrokers\"}}" + ] + ] + }, + "InstallLatestAwsSdk": false + }, + "DependsOn": [ + "ClusterV332BootstrapBrokersBootstrapBrokerStringTlsCustomResourcePolicy2EA79A00" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterV332BootstrapBrokersBootstrapBrokerStringTlsCustomResourcePolicy2EA79A00": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "kafka:GetBootstrapBrokers", + "Effect": "Allow", + "Resource": { + "Ref": "ClusterV332929A761F" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ClusterV332BootstrapBrokersBootstrapBrokerStringTlsCustomResourcePolicy2EA79A00", + "Roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } } }, "Outputs": { @@ -1677,6 +1813,14 @@ "BootstrapBrokerStringTls" ] } + }, + "BootstrapBrokers9": { + "Value": { + "Fn::GetAtt": [ + "ClusterV332BootstrapBrokersBootstrapBrokerStringTls06A03A3A", + "BootstrapBrokerStringTls" + ] + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/cdk.out b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/cdk.out index ae4b03c54e770..b72fef144f05c 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"30.0.0"} \ No newline at end of file +{"version":"30.1.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/integ.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/integ.json index 395b83f733032..95562c41ec5e1 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "30.1.0", "testCases": { "MskLogging/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/manifest.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/manifest.json index 451908b83a3d8..2bd8d5d957e8f 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "30.1.0", "artifacts": { "aws-cdk-msk-integ.assets": { "type": "cdk:asset-manifest", @@ -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}/5c5b94db03f045cf89b28c56612a2b112fa3d83037d4f96122b61ebcfaaa1383.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a9b33d873aac9026db60e46ffd1764d09d46440f81b1ffd7fdb395e54501d620.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -443,6 +443,36 @@ "data": "BootstrapBrokers8" } ], + "/aws-cdk-msk-integ/Cluster_V3_3_2/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterV332SecurityGroupDDA33760" + } + ], + "/aws-cdk-msk-integ/Cluster_V3_3_2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterV332929A761F" + } + ], + "/aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls/Resource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterV332BootstrapBrokersBootstrapBrokerStringTls06A03A3A" + } + ], + "/aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls/CustomResourcePolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterV332BootstrapBrokersBootstrapBrokerStringTlsCustomResourcePolicy2EA79A00" + } + ], + "/aws-cdk-msk-integ/BootstrapBrokers9": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapBrokers9" + } + ], "/aws-cdk-msk-integ/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -474,7 +504,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}/e05a31925a856f753d012d462f51a3f4b884235b0fe9c3cea1b63e4c95fcd2c4.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/26ebb083b5aa4c4938dd01e52996de45327a2629e9d6d262659c6f011a7b21a1.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/tree.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/tree.json index e9c8f93dd919c..b18f350eb1a83 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.js.snapshot/tree.json @@ -1107,7 +1107,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.249" + "version": "10.1.264" } }, "AWS679f53fac002430cb0da5b7982bd2287": { @@ -2323,6 +2323,197 @@ "version": "0.0.0" } }, + "Cluster_V3_3_2": { + "id": "Cluster_V3_3_2", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2", + "children": { + "SecurityGroup": { + "id": "SecurityGroup", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "MSK security group", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::MSK::Cluster", + "aws:cdk:cloudformation:props": { + "brokerNodeGroupInfo": { + "instanceType": "kafka.m5.large", + "clientSubnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "securityGroups": [ + { + "Fn::GetAtt": [ + "ClusterV332SecurityGroupDDA33760", + "GroupId" + ] + } + ], + "storageInfo": { + "ebsStorageInfo": { + "volumeSize": 1000 + } + } + }, + "clusterName": "integ-test-v3-3-2", + "kafkaVersion": "3.3.2", + "numberOfBrokerNodes": 2, + "encryptionInfo": { + "encryptionInTransit": { + "clientBroker": "TLS", + "inCluster": true + } + }, + "loggingInfo": { + "brokerLogs": { + "cloudWatchLogs": { + "enabled": false + }, + "firehose": { + "enabled": false + }, + "s3": { + "enabled": true, + "bucket": { + "Ref": "LoggingBucket1E5A6F3B" + } + } + } + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-msk.CfnCluster", + "version": "0.0.0" + } + }, + "BootstrapBrokersBootstrapBrokerStringTls": { + "id": "BootstrapBrokersBootstrapBrokerStringTls", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls", + "children": { + "Provider": { + "id": "Provider", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls/Provider", + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.SingletonFunction", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls/Resource", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls/Resource/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + }, + "CustomResourcePolicy": { + "id": "CustomResourcePolicy", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls/CustomResourcePolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-msk-integ/Cluster_V3_3_2/BootstrapBrokersBootstrapBrokerStringTls/CustomResourcePolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "kafka:GetBootstrapBrokers", + "Effect": "Allow", + "Resource": { + "Ref": "ClusterV332929A761F" + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "ClusterV332BootstrapBrokersBootstrapBrokerStringTlsCustomResourcePolicy2EA79A00", + "roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } + }, + "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/custom-resources.AwsCustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-msk.Cluster", + "version": "0.0.0" + } + }, + "BootstrapBrokers9": { + "id": "BootstrapBrokers9", + "path": "aws-cdk-msk-integ/BootstrapBrokers9", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "aws-cdk-msk-integ/BootstrapVersion", @@ -2358,7 +2549,7 @@ "path": "MskLogging/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.249" + "version": "10.1.264" } }, "DeployAssert": { @@ -2378,7 +2569,7 @@ "path": "MskLogging/DefaultTest/DeployAssert/AwsApiCallS3listObjectsV2/SdkProvider/AssertionsProvider", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.249" + "version": "10.1.264" } } }, @@ -2450,7 +2641,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.249" + "version": "10.1.264" } }, "BootstrapVersion": { @@ -2492,7 +2683,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.249" + "version": "10.1.264" } } }, diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.ts b/packages/@aws-cdk/aws-msk/test/integ.cluster.ts index 53e29e86d6754..af0e9ddd8677c 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.ts +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.ts @@ -182,6 +182,20 @@ class FeatureFlagStack extends cdk.Stack { removalPolicy: cdk.RemovalPolicy.DESTROY, }); new cdk.CfnOutput(this, 'BootstrapBrokers8', { value: cluster6.bootstrapBrokersTls }); + + const cluster7 = new msk.Cluster(this, 'Cluster_V3_3_2', { + clusterName: 'integ-test-v3-3-2', + kafkaVersion: msk.KafkaVersion.V3_3_2, + vpc, + logging: { + s3: { + bucket: this.bucket, + }, + }, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + new cdk.CfnOutput(this, 'BootstrapBrokers9', { value: cluster7.bootstrapBrokersTls }); + } } From 1ca3e0027323e84aacade4d9bd058bbc5687a7ab Mon Sep 17 00:00:00 2001 From: Rizxcviii Date: Wed, 8 Mar 2023 00:01:08 +0000 Subject: [PATCH 13/22] feat(redshift): column compression encodings and comments can now be customised (#24177) In accordance with #24165, I'm opening the same pull request as before. Not sure if my previous PR #23597 will automatically be "re-merged" in, but if not, then you can review this pull request Will AGAIN close #22506 ---- *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-redshift/README.md | 37 +- .../private/database-query-provider/table.ts | 28 +- packages/@aws-cdk/aws-redshift/lib/table.ts | 123 + .../database-query-provider/table.test.ts | 100 +- .../tree.json | 4 +- ...-cdk-redshift-cluster-database.assets.json | 2 +- ...efaultTestDeployAssertEAC4B798.assets.json | 2 +- .../cdk.out | 2 +- .../integ.json | 5 +- .../manifest.json | 14 +- .../tree.json | 80 +- ...efaultTestDeployAssert10B513A1.assets.json | 2 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 14 +- ...shift-enhancedvpcrouting-integ.assets.json | 2 +- .../tree.json | 52 +- .../index.js | 4 +- .../types.js | 24 - .../handler-name.js | 10 + .../index.js | 23 + .../privileges.js | 58 + .../redshift-data.js | 37 + .../table.js | 148 ++ .../types.js | 120 + .../user.js | 70 + .../util.js | 34 + ...-cdk-redshift-cluster-database.assets.json | 2 +- ...dk-redshift-cluster-database.template.json | 2362 ++++++++--------- .../test/integ.database.js.snapshot/cdk.out | 2 +- .../integ.database.js.snapshot/integ.json | 6 +- .../integ.database.js.snapshot/manifest.json | 10 +- ...efaultTestDeployAssert4339FB48.assets.json | 2 +- .../test/integ.database.js.snapshot/tree.json | 2 +- .../aws-redshift/test/integ.database.ts | 6 +- 35 files changed, 2085 insertions(+), 1306 deletions(-) delete mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/types.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/handler-name.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/index.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/privileges.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/redshift-data.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/table.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/types.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/user.js create mode 100644 packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/util.js diff --git a/packages/@aws-cdk/aws-redshift/README.md b/packages/@aws-cdk/aws-redshift/README.md index 9eb79a46b8b7a..ba8680aaade4d 100644 --- a/packages/@aws-cdk/aws-redshift/README.md +++ b/packages/@aws-cdk/aws-redshift/README.md @@ -200,17 +200,32 @@ new Table(this, 'Table', { }); ``` -Tables can also be configured with a comment: +Tables and their respective columns can be configured to contain comments: ```ts fixture=cluster new Table(this, 'Table', { tableColumns: [ - { name: 'col1', dataType: 'varchar(4)' }, - { name: 'col2', dataType: 'float' } + { name: 'col1', dataType: 'varchar(4)', comment: 'This is a column comment' }, + { name: 'col2', dataType: 'float', comment: 'This is a another column comment' } + ], + cluster: cluster, + databaseName: 'databaseName', + tableComment: 'This is a table comment', +}); +``` + +Table columns can be configured to use a specific compression encoding: + +```ts fixture=cluster +import { ColumnEncoding } from '@aws-cdk/aws-redshift'; + +new Table(this, 'Table', { + tableColumns: [ + { name: 'col1', dataType: 'varchar(4)', encoding: ColumnEncoding.TEXT32K }, + { name: 'col2', dataType: 'float', encoding: ColumnEncoding.DELTA32K }, ], cluster: cluster, databaseName: 'databaseName', - comment: 'This is a comment', }); ``` @@ -369,6 +384,8 @@ cluster.addToParameterGroup('enable_user_activity_logging', 'true'); In most cases, existing clusters [must be manually rebooted](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-parameter-groups.html) to apply parameter changes. You can automate parameter related reboots by setting the cluster's `rebootForParameterChanges` property to `true` , or by using `Cluster.enableRebootForParameterChanges()`. ```ts +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as cdk from '@aws-cdk/core'; declare const vpc: ec2.Vpc; const cluster = new Cluster(this, 'Cluster', { @@ -451,6 +468,8 @@ Some Amazon Redshift features require Amazon Redshift to access other AWS servic When you create an IAM role and set it as the default for the cluster using console, you don't have to provide the IAM role's Amazon Resource Name (ARN) to perform authentication and authorization. ```ts +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as iam from '@aws-cdk/aws-iam'; declare const vpc: ec2.Vpc; const defaultRole = new iam.Role(this, 'DefaultRole', { @@ -458,7 +477,7 @@ const defaultRole = new iam.Role(this, 'DefaultRole', { }, ); -new Cluster(stack, 'Redshift', { +new Cluster(this, 'Redshift', { masterUser: { masterUsername: 'admin', }, @@ -471,6 +490,8 @@ new Cluster(stack, 'Redshift', { A default role can also be added to a cluster using the `addDefaultIamRole` method. ```ts +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as iam from '@aws-cdk/aws-iam'; declare const vpc: ec2.Vpc; const defaultRole = new iam.Role(this, 'DefaultRole', { @@ -478,7 +499,7 @@ const defaultRole = new iam.Role(this, 'DefaultRole', { }, ); -const redshiftCluster = new Cluster(stack, 'Redshift', { +const redshiftCluster = new Cluster(this, 'Redshift', { masterUser: { masterUsername: 'admin', }, @@ -494,6 +515,8 @@ redshiftCluster.addDefaultIamRole(defaultRole); Attaching IAM roles to a Redshift Cluster grants permissions to the Redshift service to perform actions on your behalf. ```ts +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as iam from '@aws-cdk/aws-iam'; declare const vpc: ec2.Vpc const role = new iam.Role(this, 'Role', { @@ -511,6 +534,8 @@ const cluster = new Cluster(this, 'Redshift', { Additional IAM roles can be attached to a cluster using the `addIamRole` method. ```ts +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as iam from '@aws-cdk/aws-iam'; declare const vpc: ec2.Vpc const role = new iam.Role(this, 'Role', { diff --git a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts index bb6274f107681..ba4e71aeca843 100644 --- a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts +++ b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts @@ -42,7 +42,7 @@ async function createTable( tableAndClusterProps: TableAndClusterProps, ): Promise { const tableName = tableNamePrefix + tableNameSuffix; - const tableColumnsString = tableColumns.map(column => `${column.name} ${column.dataType}`).join(); + const tableColumnsString = tableColumns.map(column => `${column.name} ${column.dataType}${getEncodingColumnString(column)}`).join(); let statement = `CREATE TABLE ${tableName} (${tableColumnsString})`; @@ -63,6 +63,11 @@ async function createTable( await executeStatement(statement, tableAndClusterProps); + for (const column of tableColumns) { + if (column.comment) { + await executeStatement(`COMMENT ON COLUMN ${tableName}.${column.name} IS '${column.comment}'`, tableAndClusterProps); + } + } if (tableAndClusterProps.tableComment) { await executeStatement(`COMMENT ON TABLE ${tableName} IS '${tableAndClusterProps.tableComment}'`, tableAndClusterProps); } @@ -120,6 +125,20 @@ async function updateTable( alterationStatements.push(...columnAdditions.map(addition => `ALTER TABLE ${tableName} ${addition}`)); } + const columnEncoding = tableColumns.filter(column => { + return oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.encoding !== oldColumn.encoding); + }).map(column => `ALTER COLUMN ${column.name} ENCODE ${column.encoding || 'AUTO'}`); + if (columnEncoding.length > 0) { + alterationStatements.push(`ALTER TABLE ${tableName} ${columnEncoding.join(', ')}`); + } + + const columnComments = tableColumns.filter(column => { + return oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.comment !== oldColumn.comment); + }).map(column => `COMMENT ON COLUMN ${tableName}.${column.name} IS ${column.comment ? `'${column.comment}'` : 'NULL'}`); + if (columnComments.length > 0) { + alterationStatements.push(...columnComments); + } + if (useColumnIds) { const columnNameUpdates = tableColumns.reduce((updates, column) => { const oldColumn = oldTableColumns.find(oldCol => oldCol.id && oldCol.id === column.id); @@ -190,3 +209,10 @@ async function updateTable( function getSortKeyColumnsString(sortKeyColumns: Column[]) { return sortKeyColumns.map(column => column.name).join(); } + +function getEncodingColumnString(column: Column): string { + if (column.encoding) { + return ` ENCODE ${column.encoding}`; + } + return ''; +} diff --git a/packages/@aws-cdk/aws-redshift/lib/table.ts b/packages/@aws-cdk/aws-redshift/lib/table.ts index 2f3f095a39110..92587ca745efa 100644 --- a/packages/@aws-cdk/aws-redshift/lib/table.ts +++ b/packages/@aws-cdk/aws-redshift/lib/table.ts @@ -90,6 +90,20 @@ export interface Column { * @default - column is not a SORTKEY */ readonly sortKey?: boolean; + + /** + * The encoding to use for the column. + * + * @default - Amazon Redshift determines the encoding based on the data type. + */ + readonly encoding?: ColumnEncoding; + + /** + * A comment to attach to the column. + * + * @default - no comment + */ + readonly comment?: string; } /** @@ -371,3 +385,112 @@ export enum TableSortStyle { */ INTERLEAVED = 'INTERLEAVED', } + +/** + * The compression encoding of a column. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Compression_encodings.html + */ +export enum ColumnEncoding { + /** + * Amazon Redshift assigns an optimal encoding based on the column data. + * This is the default. + */ + AUTO = 'AUTO', + + /** + * The column is not compressed. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Raw_encoding.html + */ + RAW = 'RAW', + + /** + * The column is compressed using the AZ64 algorithm. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/az64-encoding.html + */ + AZ64 = 'AZ64', + + /** + * The column is compressed using a separate dictionary for each block column value on disk. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Byte_dictionary_encoding.html + */ + BYTEDICT = 'BYTEDICT', + + /** + * The column is compressed based on the difference between values in the column. + * This records differences as 1-byte values. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Delta_encoding.html + */ + DELTA = 'DELTA', + + /** + * The column is compressed based on the difference between values in the column. + * This records differences as 2-byte values. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Delta_encoding.html + */ + DELTA32K = 'DELTA32K', + + /** + * The column is compressed using the LZO algorithm. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/lzo-encoding.html + */ + LZO = 'LZO', + + /** + * The column is compressed to a smaller storage size than the original data type. + * The compressed storage size is 1 byte. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_MostlyN_encoding.html + */ + MOSTLY8 = 'MOSTLY8', + + /** + * The column is compressed to a smaller storage size than the original data type. + * The compressed storage size is 2 bytes. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_MostlyN_encoding.html + */ + MOSTLY16 = 'MOSTLY16', + + /** + * The column is compressed to a smaller storage size than the original data type. + * The compressed storage size is 4 bytes. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_MostlyN_encoding.html + */ + MOSTLY32 = 'MOSTLY32', + + /** + * The column is compressed by recording the number of occurrences of each value in the column. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Runlength_encoding.html + */ + RUNLENGTH = 'RUNLENGTH', + + /** + * The column is compressed by recording the first 245 unique words and then using a 1-byte index to represent each word. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Text255_encoding.html + */ + TEXT255 = 'TEXT255', + + /** + * The column is compressed by recording the first 32K unique words and then using a 2-byte index to represent each word. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Text255_encoding.html + */ + TEXT32K = 'TEXT32K', + + /** + * The column is compressed using the ZSTD algorithm. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/zstd-encoding.html + */ + ZSTD = 'ZSTD', +} diff --git a/packages/@aws-cdk/aws-redshift/test/database-query-provider/table.test.ts b/packages/@aws-cdk/aws-redshift/test/database-query-provider/table.test.ts index 0999f20826fd7..94981b23692eb 100644 --- a/packages/@aws-cdk/aws-redshift/test/database-query-provider/table.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/database-query-provider/table.test.ts @@ -6,7 +6,7 @@ jest.mock('aws-sdk/clients/redshiftdata', () => class { executeStatement = mockExecuteStatement; describeStatement = () => ({ promise: jest.fn(() => ({ Status: 'FINISHED' })) }); }); -import { Column, TableDistStyle, TableSortStyle } from '../../lib'; +import { Column, ColumnEncoding, TableDistStyle, TableSortStyle } from '../../lib'; import { handler as manageTable } from '../../lib/private/database-query-provider/table'; import { TableAndClusterProps } from '../../lib/private/database-query-provider/types'; @@ -477,7 +477,7 @@ describe('update', () => { })); }); - test('replaces when differnt sortStyle: INTERLEAVED', async () => { + test('replaces when different sortStyle: INTERLEAVED', async () => { const newEvent: AWSLambda.CloudFormationCustomResourceEvent = { ...event, OldResourceProperties: { @@ -523,7 +523,7 @@ describe('update', () => { })); }); - test('does not replace when differnt sortStyle: COMPOUND', async () => { + test('does not replace when different sortStyle: COMPOUND', async () => { const newEvent: AWSLambda.CloudFormationCustomResourceEvent = { ...event, OldResourceProperties: { @@ -546,7 +546,7 @@ describe('update', () => { })); }); - test('does not replace when differnt sortStyle: AUTO', async () => { + test('does not replace when different sortStyle: AUTO', async () => { const newEvent: AWSLambda.CloudFormationCustomResourceEvent = { ...event, OldResourceProperties: { @@ -606,4 +606,96 @@ describe('update', () => { })); }); }); + + describe('column comment', () => { + test('does not replace if comment added on column', async () => { + const newComment = 'newComment'; + const newResourceProperties = { + ...resourceProperties, + tableColumns: [{ name: 'col1', dataType: 'varchar(1)', comment: newComment }], + }; + + await expect(manageTable(newResourceProperties, event)).resolves.toMatchObject({ + PhysicalResourceId: physicalResourceId, + }); + expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({ + Sql: `COMMENT ON COLUMN ${physicalResourceId}.col1 IS '${newComment}'`, + })); + }); + + test('does not replace if comment removed on column', async () => { + const newEvent = { + ...event, + OldResourceProperties: { + ...event.OldResourceProperties, + tableColumns: [{ name: 'col1', dataType: 'varchar(1)', comment: 'oldComment' }], + }, + }; + + await expect(manageTable(resourceProperties, newEvent)).resolves.toMatchObject({ + PhysicalResourceId: physicalResourceId, + }); + expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({ + Sql: `COMMENT ON COLUMN ${physicalResourceId}.col1 IS NULL`, + })); + }); + }); + + describe('column encoding', () => { + test('does not replace if encoding added on column', async () => { + const newResourceProperties = { + ...resourceProperties, + tableColumns: [{ name: 'col1', dataType: 'varchar(1)', encoding: ColumnEncoding.RAW }], + }; + + await expect(manageTable(newResourceProperties, event)).resolves.toMatchObject({ + PhysicalResourceId: physicalResourceId, + }); + expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({ + Sql: `ALTER TABLE ${physicalResourceId} ALTER COLUMN col1 ENCODE RAW`, + })); + }); + + test('does not replace if encoding removed on column', async () => { + const newEvent = { + ...event, + OldResourceProperties: { + ...event.OldResourceProperties, + tableColumns: [{ name: 'col1', dataType: 'varchar(1)', encoding: ColumnEncoding.RAW }], + }, + }; + const newResourceProperties = { + ...resourceProperties, + }; + + await expect(manageTable(newResourceProperties, newEvent)).resolves.toMatchObject({ + PhysicalResourceId: physicalResourceId, + }); + expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({ + Sql: `ALTER TABLE ${physicalResourceId} ALTER COLUMN col1 ENCODE AUTO`, + })); + }); + + test('adds a comma between multiple statements', async () => { + const newEvent = { + ...event, + OldResourceProperties: { + ...event.OldResourceProperties, + tableColumns: [{ name: 'col1', dataType: 'varchar(1)' }, { name: 'col2', dataType: 'varchar(1)' }], + }, + }; + + const newResourceProperties = { + ...resourceProperties, + tableColumns: [{ name: 'col1', dataType: 'varchar(1)', encoding: ColumnEncoding.RAW }, { name: 'col2', dataType: 'varchar(1)', encoding: ColumnEncoding.RAW }], + }; + + await expect(manageTable(newResourceProperties, newEvent)).resolves.toMatchObject({ + PhysicalResourceId: physicalResourceId, + }); + expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({ + Sql: `ALTER TABLE ${physicalResourceId} ALTER COLUMN col1 ENCODE RAW, ALTER COLUMN col2 ENCODE RAW`, + })); + }); + }); }); diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/tree.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/tree.json index 8f43d13c0da06..fc2f90bd8896c 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/tree.json @@ -1442,7 +1442,7 @@ "path": "DefaultIamRoleInteg/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.209" + "version": "10.1.235" } }, "DeployAssert": { @@ -1488,7 +1488,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.209" + "version": "10.1.235" } } }, diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/aws-cdk-redshift-cluster-database.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/aws-cdk-redshift-cluster-database.assets.json index caaeb45bb105b..10aa2697f70f7 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/aws-cdk-redshift-cluster-database.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/aws-cdk-redshift-cluster-database.assets.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "29.0.0", "files": { "df6d8dd1b5d25c8d69910f850500b42f43ae98b5dfe06f5f0d1843148539d7f3": { "source": { diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/awscdkredshiftelasticiptestDefaultTestDeployAssertEAC4B798.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/awscdkredshiftelasticiptestDefaultTestDeployAssertEAC4B798.assets.json index 064832a9333cf..a3b98377b3ccb 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/awscdkredshiftelasticiptestDefaultTestDeployAssertEAC4B798.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/awscdkredshiftelasticiptestDefaultTestDeployAssertEAC4B798.assets.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "29.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/cdk.out b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/cdk.out index 8ecc185e9dbee..d8b441d447f8a 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"21.0.0"} \ No newline at end of file +{"version":"29.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/integ.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/integ.json index 880550223b63c..3a506f7fa9f7b 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/integ.json @@ -1,11 +1,12 @@ { - "version": "20.0.0", + "version": "29.0.0", "testCases": { "aws-cdk-redshift-elastic-ip-test/DefaultTest": { "stacks": [ "aws-cdk-redshift-cluster-database" ], - "assertionStack": "aws-cdk-redshift-elastic-ip-test/DefaultTest/DeployAssert" + "assertionStack": "aws-cdk-redshift-elastic-ip-test/DefaultTest/DeployAssert", + "assertionStackName": "awscdkredshiftelasticiptestDefaultTestDeployAssertEAC4B798" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/manifest.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/manifest.json index ff7f0c20bd19b..f34589ba81960 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "29.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-redshift-cluster-database.assets": { "type": "cdk:asset-manifest", "properties": { @@ -274,6 +268,12 @@ ] }, "displayName": "aws-cdk-redshift-elastic-ip-test/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/tree.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/tree.json index 5705868482891..64d523ec1e681 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-elasticip.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-redshift-cluster-database": { "id": "aws-cdk-redshift-cluster-database", "path": "aws-cdk-redshift-cluster-database", @@ -103,8 +95,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -270,8 +262,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -437,8 +429,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -556,8 +548,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -864,11 +856,27 @@ "fqn": "@aws-cdk/aws-redshift.Cluster", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-redshift-cluster-database/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-redshift-cluster-database/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" } }, "aws-cdk-redshift-elastic-ip-test": { @@ -884,15 +892,33 @@ "path": "aws-cdk-redshift-elastic-ip-test/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.235" } }, "DeployAssert": { "id": "DeployAssert", "path": "aws-cdk-redshift-elastic-ip-test/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-redshift-elastic-ip-test/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-redshift-elastic-ip-test/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" } } }, @@ -906,11 +932,19 @@ "fqn": "@aws-cdk/integ-tests.IntegTest", "version": "0.0.0" } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.235" + } } }, "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-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/EnhancedVpcRoutingDefaultTestDeployAssert10B513A1.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/EnhancedVpcRoutingDefaultTestDeployAssert10B513A1.assets.json index 00fd66f1b4bc2..dba684834eca7 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/EnhancedVpcRoutingDefaultTestDeployAssert10B513A1.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/EnhancedVpcRoutingDefaultTestDeployAssert10B513A1.assets.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "29.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/cdk.out b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/cdk.out index 8ecc185e9dbee..d8b441d447f8a 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"21.0.0"} \ No newline at end of file +{"version":"29.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/integ.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/integ.json index dd54e06e8a6f1..28ad1346532c3 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "29.0.0", "testCases": { "EnhancedVpcRouting/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/manifest.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/manifest.json index 88ff20370e7aa..a0fb6e711b75e 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "21.0.0", + "version": "29.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "redshift-enhancedvpcrouting-integ.assets": { "type": "cdk:asset-manifest", "properties": { @@ -268,6 +262,12 @@ ] }, "displayName": "EnhancedVpcRouting/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/redshift-enhancedvpcrouting-integ.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/redshift-enhancedvpcrouting-integ.assets.json index 02aab1b89f83b..f281b06ac61ea 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/redshift-enhancedvpcrouting-integ.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/redshift-enhancedvpcrouting-integ.assets.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "29.0.0", "files": { "88e2010a08d484eca3203f7e1bcffce43eaa10faedbd092b56c3d70967765b7a": { "source": { diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/tree.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/tree.json index ebc0d8772046a..7997ed915c513 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-enhancedvpcrouting.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.129" - } - }, "redshift-enhancedvpcrouting-integ": { "id": "redshift-enhancedvpcrouting-integ", "path": "redshift-enhancedvpcrouting-integ", @@ -850,6 +842,22 @@ "fqn": "@aws-cdk/aws-redshift.Cluster", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "redshift-enhancedvpcrouting-integ/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "redshift-enhancedvpcrouting-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, "constructInfo": { @@ -870,12 +878,30 @@ "path": "EnhancedVpcRouting/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.129" + "version": "10.1.235" } }, "DeployAssert": { "id": "DeployAssert", "path": "EnhancedVpcRouting/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "EnhancedVpcRouting/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "EnhancedVpcRouting/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, "constructInfo": { "fqn": "@aws-cdk/core.Stack", "version": "0.0.0" @@ -892,6 +918,14 @@ "fqn": "@aws-cdk/integ-tests.IntegTest", "version": "0.0.0" } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.235" + } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/index.js b/packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/index.js index d7a8b52f2944c..d91935764b9bf 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/index.js +++ b/packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/index.js @@ -18,4 +18,6 @@ async function handler(event) { return subHandler(event.ResourceProperties, event); } exports.handler = handler; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpREFBNkM7QUFDN0MsNkNBQTJEO0FBQzNELG1DQUFpRDtBQUNqRCxpQ0FBK0M7QUFFL0MsTUFBTSxRQUFRLEdBQWlIO0lBQzdILENBQUMsMEJBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFXO0lBQ2hDLENBQUMsMEJBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFVO0lBQzlCLENBQUMsMEJBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLG9CQUFnQjtDQUNwRCxDQUFDO0FBRUssS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrRDtJQUM5RSxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQXNCLENBQUMsQ0FBQztJQUM3RSxJQUFJLENBQUMsVUFBVSxFQUFFO1FBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sNkJBQTZCLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUM1STtJQUNELE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBTkQsMEJBTUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVucmVzb2x2ZWQgKi9cbmltcG9ydCAqIGFzIEFXU0xhbWJkYSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7IEhhbmRsZXJOYW1lIH0gZnJvbSAnLi9oYW5kbGVyLW5hbWUnO1xuaW1wb3J0IHsgaGFuZGxlciBhcyBtYW5hZ2VQcml2aWxlZ2VzIH0gZnJvbSAnLi9wcml2aWxlZ2VzJztcbmltcG9ydCB7IGhhbmRsZXIgYXMgbWFuYWdlVGFibGUgfSBmcm9tICcuL3RhYmxlJztcbmltcG9ydCB7IGhhbmRsZXIgYXMgbWFuYWdlVXNlciB9IGZyb20gJy4vdXNlcic7XG5cbmNvbnN0IEhBTkRMRVJTOiB7IFtrZXkgaW4gSGFuZGxlck5hbWVdOiAoKHByb3BzOiBhbnksIGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSA9PiBQcm9taXNlPGFueT4pIH0gPSB7XG4gIFtIYW5kbGVyTmFtZS5UYWJsZV06IG1hbmFnZVRhYmxlLFxuICBbSGFuZGxlck5hbWUuVXNlcl06IG1hbmFnZVVzZXIsXG4gIFtIYW5kbGVyTmFtZS5Vc2VyVGFibGVQcml2aWxlZ2VzXTogbWFuYWdlUHJpdmlsZWdlcyxcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSB7XG4gIGNvbnN0IHN1YkhhbmRsZXIgPSBIQU5ETEVSU1tldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuaGFuZGxlciBhcyBIYW5kbGVyTmFtZV07XG4gIGlmICghc3ViSGFuZGxlcikge1xuICAgIHRocm93IG5ldyBFcnJvcihgUmVxdWVzdGVkIGhhbmRsZXIgJHtldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuaGFuZGxlcn0gaXMgbm90IGluIHN1cHBvcnRlZCBzZXQ6ICR7SlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXMoSEFORExFUlMpKX1gKTtcbiAgfVxuICByZXR1cm4gc3ViSGFuZGxlcihldmVudC5SZXNvdXJjZVByb3BlcnRpZXMsIGV2ZW50KTtcbn1cbiJdfQ== \ No newline at end of file +var types_1 = require("./types"); +Object.defineProperty(exports, "ColumnEncoding", { enumerable: true, get: function () { return types_1.ColumnEncoding; } }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpREFBNkM7QUFDN0MsNkNBQTJEO0FBQzNELG1DQUFpRDtBQUNqRCxpQ0FBK0M7QUFFL0MsTUFBTSxRQUFRLEdBQWlIO0lBQzdILENBQUMsMEJBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFXO0lBQ2hDLENBQUMsMEJBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFVO0lBQzlCLENBQUMsMEJBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLG9CQUFnQjtDQUNwRCxDQUFDO0FBRUssS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrRDtJQUM5RSxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQXNCLENBQUMsQ0FBQztJQUM3RSxJQUFJLENBQUMsVUFBVSxFQUFFO1FBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sNkJBQTZCLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUM1STtJQUNELE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBTkQsMEJBTUM7QUFFRCxpQ0FBeUM7QUFBaEMsdUdBQUEsY0FBYyxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnJlc29sdmVkICovXG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBIYW5kbGVyTmFtZSB9IGZyb20gJy4vaGFuZGxlci1uYW1lJztcbmltcG9ydCB7IGhhbmRsZXIgYXMgbWFuYWdlUHJpdmlsZWdlcyB9IGZyb20gJy4vcHJpdmlsZWdlcyc7XG5pbXBvcnQgeyBoYW5kbGVyIGFzIG1hbmFnZVRhYmxlIH0gZnJvbSAnLi90YWJsZSc7XG5pbXBvcnQgeyBoYW5kbGVyIGFzIG1hbmFnZVVzZXIgfSBmcm9tICcuL3VzZXInO1xuXG5jb25zdCBIQU5ETEVSUzogeyBba2V5IGluIEhhbmRsZXJOYW1lXTogKChwcm9wczogYW55LCBldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCkgPT4gUHJvbWlzZTxhbnk+KSB9ID0ge1xuICBbSGFuZGxlck5hbWUuVGFibGVdOiBtYW5hZ2VUYWJsZSxcbiAgW0hhbmRsZXJOYW1lLlVzZXJdOiBtYW5hZ2VVc2VyLFxuICBbSGFuZGxlck5hbWUuVXNlclRhYmxlUHJpdmlsZWdlc106IG1hbmFnZVByaXZpbGVnZXMsXG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCkge1xuICBjb25zdCBzdWJIYW5kbGVyID0gSEFORExFUlNbZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmhhbmRsZXIgYXMgSGFuZGxlck5hbWVdO1xuICBpZiAoIXN1YkhhbmRsZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVlc3RlZCBoYW5kbGVyICR7ZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmhhbmRsZXJ9IGlzIG5vdCBpbiBzdXBwb3J0ZWQgc2V0OiAke0pTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKEhBTkRMRVJTKSl9YCk7XG4gIH1cbiAgcmV0dXJuIHN1YkhhbmRsZXIoZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLCBldmVudCk7XG59XG5cbmV4cG9ydCB7IENvbHVtbkVuY29kaW5nIH0gZnJvbSAnLi90eXBlcyc7XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/types.js b/packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/types.js deleted file mode 100644 index 070bb11c1600e..0000000000000 --- a/packages/@aws-cdk/aws-redshift/test/integ.database-columnid.js.snapshot/asset.169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338/types.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.TableSortStyle = void 0; -/** - * The sort style of a table. - * This has been duplicated here to exporting private types. - */ -var TableSortStyle; -(function (TableSortStyle) { - /** - * Amazon Redshift assigns an optimal sort key based on the table data. - */ - TableSortStyle["AUTO"] = "AUTO"; - /** - * Specifies that the data is sorted using a compound key made up of all of the listed columns, - * in the order they are listed. - */ - TableSortStyle["COMPOUND"] = "COMPOUND"; - /** - * Specifies that the data is sorted using an interleaved sort key. - */ - TableSortStyle["INTERLEAVED"] = "INTERLEAVED"; -})(TableSortStyle = exports.TableSortStyle || (exports.TableSortStyle = {})); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFLQTs7O0dBR0c7QUFDSCxJQUFZLGNBZ0JYO0FBaEJELFdBQVksY0FBYztJQUN4Qjs7T0FFRztJQUNILCtCQUFhLENBQUE7SUFFYjs7O09BR0c7SUFDSCx1Q0FBcUIsQ0FBQTtJQUVyQjs7T0FFRztJQUNILDZDQUEyQixDQUFBO0FBQzdCLENBQUMsRUFoQlcsY0FBYyxHQUFkLHNCQUFjLEtBQWQsc0JBQWMsUUFnQnpCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGF0YWJhc2VRdWVyeUhhbmRsZXJQcm9wcywgVGFibGVIYW5kbGVyUHJvcHMgfSBmcm9tICcuLi9oYW5kbGVyLXByb3BzJztcblxuZXhwb3J0IHR5cGUgQ2x1c3RlclByb3BzID0gT21pdDxEYXRhYmFzZVF1ZXJ5SGFuZGxlclByb3BzLCAnaGFuZGxlcic+O1xuZXhwb3J0IHR5cGUgVGFibGVBbmRDbHVzdGVyUHJvcHMgPSBUYWJsZUhhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcztcblxuLyoqXG4gKiBUaGUgc29ydCBzdHlsZSBvZiBhIHRhYmxlLlxuICogVGhpcyBoYXMgYmVlbiBkdXBsaWNhdGVkIGhlcmUgdG8gZXhwb3J0aW5nIHByaXZhdGUgdHlwZXMuXG4gKi9cbmV4cG9ydCBlbnVtIFRhYmxlU29ydFN0eWxlIHtcbiAgLyoqXG4gICAqIEFtYXpvbiBSZWRzaGlmdCBhc3NpZ25zIGFuIG9wdGltYWwgc29ydCBrZXkgYmFzZWQgb24gdGhlIHRhYmxlIGRhdGEuXG4gICAqL1xuICBBVVRPID0gJ0FVVE8nLFxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgZGF0YSBpcyBzb3J0ZWQgdXNpbmcgYSBjb21wb3VuZCBrZXkgbWFkZSB1cCBvZiBhbGwgb2YgdGhlIGxpc3RlZCBjb2x1bW5zLFxuICAgKiBpbiB0aGUgb3JkZXIgdGhleSBhcmUgbGlzdGVkLlxuICAgKi9cbiAgQ09NUE9VTkQgPSAnQ09NUE9VTkQnLFxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgZGF0YSBpcyBzb3J0ZWQgdXNpbmcgYW4gaW50ZXJsZWF2ZWQgc29ydCBrZXkuXG4gICAqL1xuICBJTlRFUkxFQVZFRCA9ICdJTlRFUkxFQVZFRCcsXG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/handler-name.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/handler-name.js new file mode 100644 index 0000000000000..4983115a93834 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/handler-name.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HandlerName = void 0; +var HandlerName; +(function (HandlerName) { + HandlerName["User"] = "user"; + HandlerName["Table"] = "table"; + HandlerName["UserTablePrivileges"] = "user-table-privileges"; +})(HandlerName = exports.HandlerName || (exports.HandlerName = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci1uYW1lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaGFuZGxlci1uYW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLElBQVksV0FJWDtBQUpELFdBQVksV0FBVztJQUNyQiw0QkFBYSxDQUFBO0lBQ2IsOEJBQWUsQ0FBQTtJQUNmLDREQUE2QyxDQUFBO0FBQy9DLENBQUMsRUFKVyxXQUFXLEdBQVgsbUJBQVcsS0FBWCxtQkFBVyxRQUl0QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIEhhbmRsZXJOYW1lIHtcbiAgVXNlciA9ICd1c2VyJyxcbiAgVGFibGUgPSAndGFibGUnLFxuICBVc2VyVGFibGVQcml2aWxlZ2VzID0gJ3VzZXItdGFibGUtcHJpdmlsZWdlcycsXG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/index.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/index.js new file mode 100644 index 0000000000000..d91935764b9bf --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/index.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +const handler_name_1 = require("./handler-name"); +const privileges_1 = require("./privileges"); +const table_1 = require("./table"); +const user_1 = require("./user"); +const HANDLERS = { + [handler_name_1.HandlerName.Table]: table_1.handler, + [handler_name_1.HandlerName.User]: user_1.handler, + [handler_name_1.HandlerName.UserTablePrivileges]: privileges_1.handler, +}; +async function handler(event) { + const subHandler = HANDLERS[event.ResourceProperties.handler]; + if (!subHandler) { + throw new Error(`Requested handler ${event.ResourceProperties.handler} is not in supported set: ${JSON.stringify(Object.keys(HANDLERS))}`); + } + return subHandler(event.ResourceProperties, event); +} +exports.handler = handler; +var types_1 = require("./types"); +Object.defineProperty(exports, "ColumnEncoding", { enumerable: true, get: function () { return types_1.ColumnEncoding; } }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpREFBNkM7QUFDN0MsNkNBQTJEO0FBQzNELG1DQUFpRDtBQUNqRCxpQ0FBK0M7QUFFL0MsTUFBTSxRQUFRLEdBQWlIO0lBQzdILENBQUMsMEJBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFXO0lBQ2hDLENBQUMsMEJBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFVO0lBQzlCLENBQUMsMEJBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLG9CQUFnQjtDQUNwRCxDQUFDO0FBRUssS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrRDtJQUM5RSxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQXNCLENBQUMsQ0FBQztJQUM3RSxJQUFJLENBQUMsVUFBVSxFQUFFO1FBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sNkJBQTZCLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUM1STtJQUNELE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBTkQsMEJBTUM7QUFFRCxpQ0FBeUM7QUFBaEMsdUdBQUEsY0FBYyxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnJlc29sdmVkICovXG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBIYW5kbGVyTmFtZSB9IGZyb20gJy4vaGFuZGxlci1uYW1lJztcbmltcG9ydCB7IGhhbmRsZXIgYXMgbWFuYWdlUHJpdmlsZWdlcyB9IGZyb20gJy4vcHJpdmlsZWdlcyc7XG5pbXBvcnQgeyBoYW5kbGVyIGFzIG1hbmFnZVRhYmxlIH0gZnJvbSAnLi90YWJsZSc7XG5pbXBvcnQgeyBoYW5kbGVyIGFzIG1hbmFnZVVzZXIgfSBmcm9tICcuL3VzZXInO1xuXG5jb25zdCBIQU5ETEVSUzogeyBba2V5IGluIEhhbmRsZXJOYW1lXTogKChwcm9wczogYW55LCBldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCkgPT4gUHJvbWlzZTxhbnk+KSB9ID0ge1xuICBbSGFuZGxlck5hbWUuVGFibGVdOiBtYW5hZ2VUYWJsZSxcbiAgW0hhbmRsZXJOYW1lLlVzZXJdOiBtYW5hZ2VVc2VyLFxuICBbSGFuZGxlck5hbWUuVXNlclRhYmxlUHJpdmlsZWdlc106IG1hbmFnZVByaXZpbGVnZXMsXG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCkge1xuICBjb25zdCBzdWJIYW5kbGVyID0gSEFORExFUlNbZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmhhbmRsZXIgYXMgSGFuZGxlck5hbWVdO1xuICBpZiAoIXN1YkhhbmRsZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVlc3RlZCBoYW5kbGVyICR7ZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmhhbmRsZXJ9IGlzIG5vdCBpbiBzdXBwb3J0ZWQgc2V0OiAke0pTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKEhBTkRMRVJTKSl9YCk7XG4gIH1cbiAgcmV0dXJuIHN1YkhhbmRsZXIoZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLCBldmVudCk7XG59XG5cbmV4cG9ydCB7IENvbHVtbkVuY29kaW5nIH0gZnJvbSAnLi90eXBlcyc7XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/privileges.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/privileges.js new file mode 100644 index 0000000000000..8770142deb498 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/privileges.js @@ -0,0 +1,58 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +const redshift_data_1 = require("./redshift-data"); +const util_1 = require("./util"); +async function handler(props, event) { + const username = props.username; + const tablePrivileges = props.tablePrivileges; + const clusterProps = props; + if (event.RequestType === 'Create') { + await grantPrivileges(username, tablePrivileges, clusterProps); + return { PhysicalResourceId: util_1.makePhysicalId(username, clusterProps, event.RequestId) }; + } + else if (event.RequestType === 'Delete') { + await revokePrivileges(username, tablePrivileges, clusterProps); + return; + } + else if (event.RequestType === 'Update') { + const { replace } = await updatePrivileges(username, tablePrivileges, clusterProps, event.OldResourceProperties); + const physicalId = replace ? util_1.makePhysicalId(username, clusterProps, event.RequestId) : event.PhysicalResourceId; + return { PhysicalResourceId: physicalId }; + } + else { + /* eslint-disable-next-line dot-notation */ + throw new Error(`Unrecognized event type: ${event['RequestType']}`); + } +} +exports.handler = handler; +async function revokePrivileges(username, tablePrivileges, clusterProps) { + await Promise.all(tablePrivileges.map(({ tableName, actions }) => { + return redshift_data_1.executeStatement(`REVOKE ${actions.join(', ')} ON ${tableName} FROM ${username}`, clusterProps); + })); +} +async function grantPrivileges(username, tablePrivileges, clusterProps) { + await Promise.all(tablePrivileges.map(({ tableName, actions }) => { + return redshift_data_1.executeStatement(`GRANT ${actions.join(', ')} ON ${tableName} TO ${username}`, clusterProps); + })); +} +async function updatePrivileges(username, tablePrivileges, clusterProps, oldResourceProperties) { + const oldClusterProps = oldResourceProperties; + if (clusterProps.clusterName !== oldClusterProps.clusterName || clusterProps.databaseName !== oldClusterProps.databaseName) { + await grantPrivileges(username, tablePrivileges, clusterProps); + return { replace: true }; + } + const oldUsername = oldResourceProperties.username; + if (oldUsername !== username) { + await grantPrivileges(username, tablePrivileges, clusterProps); + return { replace: true }; + } + const oldTablePrivileges = oldResourceProperties.tablePrivileges; + if (oldTablePrivileges !== tablePrivileges) { + await revokePrivileges(username, oldTablePrivileges, clusterProps); + await grantPrivileges(username, tablePrivileges, clusterProps); + return { replace: false }; + } + return { replace: false }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmlsZWdlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByaXZpbGVnZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsbURBQW1EO0FBRW5ELGlDQUF3QztBQUdqQyxLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQXFELEVBQUUsS0FBa0Q7SUFDckksTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztJQUNoQyxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsZUFBZSxDQUFDO0lBQzlDLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQztJQUUzQixJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQ2xDLE1BQU0sZUFBZSxDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDL0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLHFCQUFjLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztLQUN4RjtTQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUU7UUFDekMsTUFBTSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ2hFLE9BQU87S0FDUjtTQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUU7UUFDekMsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sZ0JBQWdCLENBQ3hDLFFBQVEsRUFDUixlQUFlLEVBQ2YsWUFBWSxFQUNaLEtBQUssQ0FBQyxxQkFBdUUsQ0FDOUUsQ0FBQztRQUNGLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMscUJBQWMsQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQ2hILE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsQ0FBQztLQUMzQztTQUFNO1FBQ0wsMkNBQTJDO1FBQzNDLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLEtBQUssQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7S0FDckU7QUFDSCxDQUFDO0FBeEJELDBCQXdCQztBQUVELEtBQUssVUFBVSxnQkFBZ0IsQ0FBQyxRQUFnQixFQUFFLGVBQWlDLEVBQUUsWUFBMEI7SUFDN0csTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFO1FBQy9ELE9BQU8sZ0NBQWdCLENBQUMsVUFBVSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLFNBQVMsU0FBUyxRQUFRLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN6RyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVELEtBQUssVUFBVSxlQUFlLENBQUMsUUFBZ0IsRUFBRSxlQUFpQyxFQUFFLFlBQTBCO0lBQzVHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRTtRQUMvRCxPQUFPLGdDQUFnQixDQUFDLFNBQVMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxTQUFTLE9BQU8sUUFBUSxFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDdEcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFRCxLQUFLLFVBQVUsZ0JBQWdCLENBQzdCLFFBQWdCLEVBQ2hCLGVBQWlDLEVBQ2pDLFlBQTBCLEVBQzFCLHFCQUFxRTtJQUVyRSxNQUFNLGVBQWUsR0FBRyxxQkFBcUIsQ0FBQztJQUM5QyxJQUFJLFlBQVksQ0FBQyxXQUFXLEtBQUssZUFBZSxDQUFDLFdBQVcsSUFBSSxZQUFZLENBQUMsWUFBWSxLQUFLLGVBQWUsQ0FBQyxZQUFZLEVBQUU7UUFDMUgsTUFBTSxlQUFlLENBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUMvRCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO0tBQzFCO0lBRUQsTUFBTSxXQUFXLEdBQUcscUJBQXFCLENBQUMsUUFBUSxDQUFDO0lBQ25ELElBQUksV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUM1QixNQUFNLGVBQWUsQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQy9ELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7S0FDMUI7SUFFRCxNQUFNLGtCQUFrQixHQUFHLHFCQUFxQixDQUFDLGVBQWUsQ0FBQztJQUNqRSxJQUFJLGtCQUFrQixLQUFLLGVBQWUsRUFBRTtRQUMxQyxNQUFNLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxrQkFBa0IsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNuRSxNQUFNLGVBQWUsQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQy9ELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7S0FDM0I7SUFFRCxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVucmVzb2x2ZWQgKi9cbmltcG9ydCAqIGFzIEFXU0xhbWJkYSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7IGV4ZWN1dGVTdGF0ZW1lbnQgfSBmcm9tICcuL3JlZHNoaWZ0LWRhdGEnO1xuaW1wb3J0IHsgQ2x1c3RlclByb3BzIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBtYWtlUGh5c2ljYWxJZCB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyBUYWJsZVByaXZpbGVnZSwgVXNlclRhYmxlUHJpdmlsZWdlc0hhbmRsZXJQcm9wcyB9IGZyb20gJy4uL2hhbmRsZXItcHJvcHMnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihwcm9wczogVXNlclRhYmxlUHJpdmlsZWdlc0hhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcywgZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgY29uc3QgdXNlcm5hbWUgPSBwcm9wcy51c2VybmFtZTtcbiAgY29uc3QgdGFibGVQcml2aWxlZ2VzID0gcHJvcHMudGFibGVQcml2aWxlZ2VzO1xuICBjb25zdCBjbHVzdGVyUHJvcHMgPSBwcm9wcztcblxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdDcmVhdGUnKSB7XG4gICAgYXdhaXQgZ3JhbnRQcml2aWxlZ2VzKHVzZXJuYW1lLCB0YWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiBtYWtlUGh5c2ljYWxJZCh1c2VybmFtZSwgY2x1c3RlclByb3BzLCBldmVudC5SZXF1ZXN0SWQpIH07XG4gIH0gZWxzZSBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnKSB7XG4gICAgYXdhaXQgcmV2b2tlUHJpdmlsZWdlcyh1c2VybmFtZSwgdGFibGVQcml2aWxlZ2VzLCBjbHVzdGVyUHJvcHMpO1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ1VwZGF0ZScpIHtcbiAgICBjb25zdCB7IHJlcGxhY2UgfSA9IGF3YWl0IHVwZGF0ZVByaXZpbGVnZXMoXG4gICAgICB1c2VybmFtZSxcbiAgICAgIHRhYmxlUHJpdmlsZWdlcyxcbiAgICAgIGNsdXN0ZXJQcm9wcyxcbiAgICAgIGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcyBhcyBVc2VyVGFibGVQcml2aWxlZ2VzSGFuZGxlclByb3BzICYgQ2x1c3RlclByb3BzLFxuICAgICk7XG4gICAgY29uc3QgcGh5c2ljYWxJZCA9IHJlcGxhY2UgPyBtYWtlUGh5c2ljYWxJZCh1c2VybmFtZSwgY2x1c3RlclByb3BzLCBldmVudC5SZXF1ZXN0SWQpIDogZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxJZCB9O1xuICB9IGVsc2Uge1xuICAgIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkb3Qtbm90YXRpb24gKi9cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBldmVudCB0eXBlOiAke2V2ZW50WydSZXF1ZXN0VHlwZSddfWApO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJldm9rZVByaXZpbGVnZXModXNlcm5hbWU6IHN0cmluZywgdGFibGVQcml2aWxlZ2VzOiBUYWJsZVByaXZpbGVnZVtdLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcykge1xuICBhd2FpdCBQcm9taXNlLmFsbCh0YWJsZVByaXZpbGVnZXMubWFwKCh7IHRhYmxlTmFtZSwgYWN0aW9ucyB9KSA9PiB7XG4gICAgcmV0dXJuIGV4ZWN1dGVTdGF0ZW1lbnQoYFJFVk9LRSAke2FjdGlvbnMuam9pbignLCAnKX0gT04gJHt0YWJsZU5hbWV9IEZST00gJHt1c2VybmFtZX1gLCBjbHVzdGVyUHJvcHMpO1xuICB9KSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdyYW50UHJpdmlsZWdlcyh1c2VybmFtZTogc3RyaW5nLCB0YWJsZVByaXZpbGVnZXM6IFRhYmxlUHJpdmlsZWdlW10sIGNsdXN0ZXJQcm9wczogQ2x1c3RlclByb3BzKSB7XG4gIGF3YWl0IFByb21pc2UuYWxsKHRhYmxlUHJpdmlsZWdlcy5tYXAoKHsgdGFibGVOYW1lLCBhY3Rpb25zIH0pID0+IHtcbiAgICByZXR1cm4gZXhlY3V0ZVN0YXRlbWVudChgR1JBTlQgJHthY3Rpb25zLmpvaW4oJywgJyl9IE9OICR7dGFibGVOYW1lfSBUTyAke3VzZXJuYW1lfWAsIGNsdXN0ZXJQcm9wcyk7XG4gIH0pKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXBkYXRlUHJpdmlsZWdlcyhcbiAgdXNlcm5hbWU6IHN0cmluZyxcbiAgdGFibGVQcml2aWxlZ2VzOiBUYWJsZVByaXZpbGVnZVtdLFxuICBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcyxcbiAgb2xkUmVzb3VyY2VQcm9wZXJ0aWVzOiBVc2VyVGFibGVQcml2aWxlZ2VzSGFuZGxlclByb3BzICYgQ2x1c3RlclByb3BzLFxuKTogUHJvbWlzZTx7IHJlcGxhY2U6IGJvb2xlYW4gfT4ge1xuICBjb25zdCBvbGRDbHVzdGVyUHJvcHMgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXM7XG4gIGlmIChjbHVzdGVyUHJvcHMuY2x1c3Rlck5hbWUgIT09IG9sZENsdXN0ZXJQcm9wcy5jbHVzdGVyTmFtZSB8fCBjbHVzdGVyUHJvcHMuZGF0YWJhc2VOYW1lICE9PSBvbGRDbHVzdGVyUHJvcHMuZGF0YWJhc2VOYW1lKSB7XG4gICAgYXdhaXQgZ3JhbnRQcml2aWxlZ2VzKHVzZXJuYW1lLCB0YWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgcmVwbGFjZTogdHJ1ZSB9O1xuICB9XG5cbiAgY29uc3Qgb2xkVXNlcm5hbWUgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudXNlcm5hbWU7XG4gIGlmIChvbGRVc2VybmFtZSAhPT0gdXNlcm5hbWUpIHtcbiAgICBhd2FpdCBncmFudFByaXZpbGVnZXModXNlcm5hbWUsIHRhYmxlUHJpdmlsZWdlcywgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiB0cnVlIH07XG4gIH1cblxuICBjb25zdCBvbGRUYWJsZVByaXZpbGVnZXMgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudGFibGVQcml2aWxlZ2VzO1xuICBpZiAob2xkVGFibGVQcml2aWxlZ2VzICE9PSB0YWJsZVByaXZpbGVnZXMpIHtcbiAgICBhd2FpdCByZXZva2VQcml2aWxlZ2VzKHVzZXJuYW1lLCBvbGRUYWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgYXdhaXQgZ3JhbnRQcml2aWxlZ2VzKHVzZXJuYW1lLCB0YWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgcmVwbGFjZTogZmFsc2UgfTtcbiAgfVxuXG4gIHJldHVybiB7IHJlcGxhY2U6IGZhbHNlIH07XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/redshift-data.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/redshift-data.js new file mode 100644 index 0000000000000..e65374f4ab7e0 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/redshift-data.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.executeStatement = void 0; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +const RedshiftData = require("aws-sdk/clients/redshiftdata"); +const redshiftData = new RedshiftData(); +async function executeStatement(statement, clusterProps) { + const executeStatementProps = { + ClusterIdentifier: clusterProps.clusterName, + Database: clusterProps.databaseName, + SecretArn: clusterProps.adminUserArn, + Sql: statement, + }; + const executedStatement = await redshiftData.executeStatement(executeStatementProps).promise(); + if (!executedStatement.Id) { + throw new Error('Service error: Statement execution did not return a statement ID'); + } + await waitForStatementComplete(executedStatement.Id); +} +exports.executeStatement = executeStatement; +const waitTimeout = 100; +async function waitForStatementComplete(statementId) { + await new Promise((resolve) => { + setTimeout(() => resolve(), waitTimeout); + }); + const statement = await redshiftData.describeStatement({ Id: statementId }).promise(); + if (statement.Status !== 'FINISHED' && statement.Status !== 'FAILED' && statement.Status !== 'ABORTED') { + return waitForStatementComplete(statementId); + } + else if (statement.Status === 'FINISHED') { + return; + } + else { + throw new Error(`Statement status was ${statement.Status}: ${statement.Error}`); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkc2hpZnQtZGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInJlZHNoaWZ0LWRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQWdFO0FBQ2hFLDZEQUE2RDtBQUc3RCxNQUFNLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0FBRWpDLEtBQUssVUFBVSxnQkFBZ0IsQ0FBQyxTQUFpQixFQUFFLFlBQTBCO0lBQ2xGLE1BQU0scUJBQXFCLEdBQUc7UUFDNUIsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLFdBQVc7UUFDM0MsUUFBUSxFQUFFLFlBQVksQ0FBQyxZQUFZO1FBQ25DLFNBQVMsRUFBRSxZQUFZLENBQUMsWUFBWTtRQUNwQyxHQUFHLEVBQUUsU0FBUztLQUNmLENBQUM7SUFDRixNQUFNLGlCQUFpQixHQUFHLE1BQU0sWUFBWSxDQUFDLGdCQUFnQixDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDL0YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsRUFBRTtRQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLGtFQUFrRSxDQUFDLENBQUM7S0FDckY7SUFDRCxNQUFNLHdCQUF3QixDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZELENBQUM7QUFaRCw0Q0FZQztBQUVELE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQUN4QixLQUFLLFVBQVUsd0JBQXdCLENBQUMsV0FBbUI7SUFDekQsTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQThCLEVBQUUsRUFBRTtRQUNuRCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLFNBQVMsR0FBRyxNQUFNLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3RGLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxVQUFVLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxRQUFRLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUU7UUFDdEcsT0FBTyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztLQUM5QztTQUFNLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUU7UUFDMUMsT0FBTztLQUNSO1NBQU07UUFDTCxNQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixTQUFTLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0tBQ2pGO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmltcG9ydCAqIGFzIFJlZHNoaWZ0RGF0YSBmcm9tICdhd3Mtc2RrL2NsaWVudHMvcmVkc2hpZnRkYXRhJztcbmltcG9ydCB7IENsdXN0ZXJQcm9wcyB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCByZWRzaGlmdERhdGEgPSBuZXcgUmVkc2hpZnREYXRhKCk7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleGVjdXRlU3RhdGVtZW50KHN0YXRlbWVudDogc3RyaW5nLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBleGVjdXRlU3RhdGVtZW50UHJvcHMgPSB7XG4gICAgQ2x1c3RlcklkZW50aWZpZXI6IGNsdXN0ZXJQcm9wcy5jbHVzdGVyTmFtZSxcbiAgICBEYXRhYmFzZTogY2x1c3RlclByb3BzLmRhdGFiYXNlTmFtZSxcbiAgICBTZWNyZXRBcm46IGNsdXN0ZXJQcm9wcy5hZG1pblVzZXJBcm4sXG4gICAgU3FsOiBzdGF0ZW1lbnQsXG4gIH07XG4gIGNvbnN0IGV4ZWN1dGVkU3RhdGVtZW50ID0gYXdhaXQgcmVkc2hpZnREYXRhLmV4ZWN1dGVTdGF0ZW1lbnQoZXhlY3V0ZVN0YXRlbWVudFByb3BzKS5wcm9taXNlKCk7XG4gIGlmICghZXhlY3V0ZWRTdGF0ZW1lbnQuSWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZpY2UgZXJyb3I6IFN0YXRlbWVudCBleGVjdXRpb24gZGlkIG5vdCByZXR1cm4gYSBzdGF0ZW1lbnQgSUQnKTtcbiAgfVxuICBhd2FpdCB3YWl0Rm9yU3RhdGVtZW50Q29tcGxldGUoZXhlY3V0ZWRTdGF0ZW1lbnQuSWQpO1xufVxuXG5jb25zdCB3YWl0VGltZW91dCA9IDEwMDtcbmFzeW5jIGZ1bmN0aW9uIHdhaXRGb3JTdGF0ZW1lbnRDb21wbGV0ZShzdGF0ZW1lbnRJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlOiAodmFsdWU6IHZvaWQpID0+IHZvaWQpID0+IHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoKSwgd2FpdFRpbWVvdXQpO1xuICB9KTtcbiAgY29uc3Qgc3RhdGVtZW50ID0gYXdhaXQgcmVkc2hpZnREYXRhLmRlc2NyaWJlU3RhdGVtZW50KHsgSWQ6IHN0YXRlbWVudElkIH0pLnByb21pc2UoKTtcbiAgaWYgKHN0YXRlbWVudC5TdGF0dXMgIT09ICdGSU5JU0hFRCcgJiYgc3RhdGVtZW50LlN0YXR1cyAhPT0gJ0ZBSUxFRCcgJiYgc3RhdGVtZW50LlN0YXR1cyAhPT0gJ0FCT1JURUQnKSB7XG4gICAgcmV0dXJuIHdhaXRGb3JTdGF0ZW1lbnRDb21wbGV0ZShzdGF0ZW1lbnRJZCk7XG4gIH0gZWxzZSBpZiAoc3RhdGVtZW50LlN0YXR1cyA9PT0gJ0ZJTklTSEVEJykge1xuICAgIHJldHVybjtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFN0YXRlbWVudCBzdGF0dXMgd2FzICR7c3RhdGVtZW50LlN0YXR1c306ICR7c3RhdGVtZW50LkVycm9yfWApO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/table.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/table.js new file mode 100644 index 0000000000000..1294ed3cd80c4 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/table.js @@ -0,0 +1,148 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +const redshift_data_1 = require("./redshift-data"); +const types_1 = require("./types"); +const util_1 = require("./util"); +async function handler(props, event) { + const tableNamePrefix = props.tableName.prefix; + const tableNameSuffix = props.tableName.generateSuffix === 'true' ? `${event.RequestId.substring(0, 8)}` : ''; + const tableColumns = props.tableColumns; + const tableAndClusterProps = props; + if (event.RequestType === 'Create') { + const tableName = await createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps); + return { PhysicalResourceId: tableName }; + } + else if (event.RequestType === 'Delete') { + await dropTable(event.PhysicalResourceId, tableAndClusterProps); + return; + } + else if (event.RequestType === 'Update') { + const tableName = await updateTable(event.PhysicalResourceId, tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps, event.OldResourceProperties); + return { PhysicalResourceId: tableName }; + } + else { + /* eslint-disable-next-line dot-notation */ + throw new Error(`Unrecognized event type: ${event['RequestType']}`); + } +} +exports.handler = handler; +async function createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps) { + const tableName = tableNamePrefix + tableNameSuffix; + const tableColumnsString = tableColumns.map(column => `${column.name} ${column.dataType}${getEncodingColumnString(column)}`).join(); + let statement = `CREATE TABLE ${tableName} (${tableColumnsString})`; + if (tableAndClusterProps.distStyle) { + statement += ` DISTSTYLE ${tableAndClusterProps.distStyle}`; + } + const distKeyColumn = util_1.getDistKeyColumn(tableColumns); + if (distKeyColumn) { + statement += ` DISTKEY(${distKeyColumn.name})`; + } + const sortKeyColumns = util_1.getSortKeyColumns(tableColumns); + if (sortKeyColumns.length > 0) { + const sortKeyColumnsString = getSortKeyColumnsString(sortKeyColumns); + statement += ` ${tableAndClusterProps.sortStyle} SORTKEY(${sortKeyColumnsString})`; + } + await redshift_data_1.executeStatement(statement, tableAndClusterProps); + for (const column of tableColumns) { + if (column.comment) { + await redshift_data_1.executeStatement(`COMMENT ON COLUMN ${tableName}.${column.name} IS '${column.comment}'`, tableAndClusterProps); + } + } + if (tableAndClusterProps.tableComment) { + await redshift_data_1.executeStatement(`COMMENT ON TABLE ${tableName} IS '${tableAndClusterProps.tableComment}'`, tableAndClusterProps); + } + return tableName; +} +async function dropTable(tableName, clusterProps) { + await redshift_data_1.executeStatement(`DROP TABLE ${tableName}`, clusterProps); +} +async function updateTable(tableName, tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps, oldResourceProperties) { + const alterationStatements = []; + const oldClusterProps = oldResourceProperties; + if (tableAndClusterProps.clusterName !== oldClusterProps.clusterName || tableAndClusterProps.databaseName !== oldClusterProps.databaseName) { + return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps); + } + const oldTableNamePrefix = oldResourceProperties.tableName.prefix; + if (tableNamePrefix !== oldTableNamePrefix) { + return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps); + } + const oldTableColumns = oldResourceProperties.tableColumns; + const columnDeletions = oldTableColumns.filter(oldColumn => (tableColumns.every(column => oldColumn.name !== column.name))); + if (columnDeletions.length > 0) { + alterationStatements.push(...columnDeletions.map(column => `ALTER TABLE ${tableName} DROP COLUMN ${column.name}`)); + } + const columnAdditions = tableColumns.filter(column => { + return !oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.dataType === oldColumn.dataType); + }).map(column => `ADD ${column.name} ${column.dataType}`); + if (columnAdditions.length > 0) { + alterationStatements.push(...columnAdditions.map(addition => `ALTER TABLE ${tableName} ${addition}`)); + } + const columnEncoding = tableColumns.filter(column => { + return oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.encoding !== oldColumn.encoding); + }).map(column => `ALTER COLUMN ${column.name} ENCODE ${column.encoding || types_1.ColumnEncoding.AUTO}`); + if (columnEncoding.length > 0) { + alterationStatements.push(`ALTER TABLE ${tableName} ${columnEncoding.join(', ')}`); + } + const columnComments = tableColumns.filter(column => { + return oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.comment !== oldColumn.comment); + }).map(column => `COMMENT ON COLUMN ${tableName}.${column.name} IS ${column.comment ? `'${column.comment}'` : 'NULL'}`); + if (columnComments.length > 0) { + alterationStatements.push(...columnComments); + } + const oldDistStyle = oldResourceProperties.distStyle; + if ((!oldDistStyle && tableAndClusterProps.distStyle) || + (oldDistStyle && !tableAndClusterProps.distStyle)) { + return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps); + } + else if (oldDistStyle !== tableAndClusterProps.distStyle) { + alterationStatements.push(`ALTER TABLE ${tableName} ALTER DISTSTYLE ${tableAndClusterProps.distStyle}`); + } + const oldDistKey = util_1.getDistKeyColumn(oldTableColumns)?.name; + const newDistKey = util_1.getDistKeyColumn(tableColumns)?.name; + if ((!oldDistKey && newDistKey) || (oldDistKey && !newDistKey)) { + return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps); + } + else if (oldDistKey !== newDistKey) { + alterationStatements.push(`ALTER TABLE ${tableName} ALTER DISTKEY ${newDistKey}`); + } + const oldSortKeyColumns = util_1.getSortKeyColumns(oldTableColumns); + const newSortKeyColumns = util_1.getSortKeyColumns(tableColumns); + const oldSortStyle = oldResourceProperties.sortStyle; + const newSortStyle = tableAndClusterProps.sortStyle; + if ((oldSortStyle === newSortStyle && !util_1.areColumnsEqual(oldSortKeyColumns, newSortKeyColumns)) + || (oldSortStyle !== newSortStyle)) { + switch (newSortStyle) { + case types_1.TableSortStyle.INTERLEAVED: + // INTERLEAVED sort key addition requires replacement. + // https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html + return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps); + case types_1.TableSortStyle.COMPOUND: { + const sortKeyColumnsString = getSortKeyColumnsString(newSortKeyColumns); + alterationStatements.push(`ALTER TABLE ${tableName} ALTER ${newSortStyle} SORTKEY(${sortKeyColumnsString})`); + break; + } + case types_1.TableSortStyle.AUTO: { + alterationStatements.push(`ALTER TABLE ${tableName} ALTER SORTKEY ${newSortStyle}`); + break; + } + } + } + const oldComment = oldResourceProperties.tableComment; + const newComment = tableAndClusterProps.tableComment; + if (oldComment !== newComment) { + alterationStatements.push(`COMMENT ON TABLE ${tableName} IS ${newComment ? `'${newComment}'` : 'NULL'}`); + } + await Promise.all(alterationStatements.map(statement => redshift_data_1.executeStatement(statement, tableAndClusterProps))); + return tableName; +} +function getSortKeyColumnsString(sortKeyColumns) { + return sortKeyColumns.map(column => column.name).join(); +} +function getEncodingColumnString(column) { + if (column.encoding) { + return ` ENCODE ${column.encoding}`; + } + return ''; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0YWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxtREFBbUQ7QUFDbkQsbUNBQTZGO0FBQzdGLGlDQUE4RTtBQUd2RSxLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQTJCLEVBQUUsS0FBa0Q7SUFDM0csTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDL0MsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDOUcsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUN4QyxNQUFNLG9CQUFvQixHQUFHLEtBQUssQ0FBQztJQUVuQyxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQ2xDLE1BQU0sU0FBUyxHQUFHLE1BQU0sV0FBVyxDQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFDMUcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxDQUFDO0tBQzFDO1NBQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUN6QyxNQUFNLFNBQVMsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztRQUNoRSxPQUFPO0tBQ1I7U0FBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQ3pDLE1BQU0sU0FBUyxHQUFHLE1BQU0sV0FBVyxDQUNqQyxLQUFLLENBQUMsa0JBQWtCLEVBQ3hCLGVBQWUsRUFDZixlQUFlLEVBQ2YsWUFBWSxFQUNaLG9CQUFvQixFQUNwQixLQUFLLENBQUMs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b0JBQW9CLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsZ0NBQWdCLENBQUMsU0FBUyxFQUFFLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRTVHLE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxTQUFTLHVCQUF1QixDQUFDLGNBQXdCO0lBQ3ZELE9BQU8sY0FBYyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUMxRCxDQUFDO0FBRUQsU0FBUyx1QkFBdUIsQ0FBQyxNQUFjO0lBQzdDLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRTtRQUNuQixPQUFPLFdBQVcsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO0tBQ3JDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnJlc29sdmVkICovXG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBleGVjdXRlU3RhdGVtZW50IH0gZnJvbSAnLi9yZWRzaGlmdC1kYXRhJztcbmltcG9ydCB7IENsdXN0ZXJQcm9wcywgQ29sdW1uRW5jb2RpbmcsIFRhYmxlQW5kQ2x1c3RlclByb3BzLCBUYWJsZVNvcnRTdHlsZSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgYXJlQ29sdW1uc0VxdWFsLCBnZXREaXN0S2V5Q29sdW1uLCBnZXRTb3J0S2V5Q29sdW1ucyB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyBDb2x1bW4gfSBmcm9tICcuLi8uLi90YWJsZSc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKHByb3BzOiBUYWJsZUFuZENsdXN0ZXJQcm9wcywgZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgY29uc3QgdGFibGVOYW1lUHJlZml4ID0gcHJvcHMudGFibGVOYW1lLnByZWZpeDtcbiAgY29uc3QgdGFibGVOYW1lU3VmZml4ID0gcHJvcHMudGFibGVOYW1lLmdlbmVyYXRlU3VmZml4ID09PSAndHJ1ZScgPyBgJHtldmVudC5SZXF1ZXN0SWQuc3Vic3RyaW5nKDAsIDgpfWAgOiAnJztcbiAgY29uc3QgdGFibGVDb2x1bW5zID0gcHJvcHMudGFibGVDb2x1bW5zO1xuICBjb25zdCB0YWJsZUFuZENsdXN0ZXJQcm9wcyA9IHByb3BzO1xuXG4gIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICBjb25zdCB0YWJsZU5hbWUgPSBhd2FpdCBjcmVhdGVUYWJsZSh0YWJsZU5hbWVQcmVmaXgsIHRhYmxlTmFtZVN1ZmZpeCwgdGFibGVDb2x1bW5zLCB0YWJsZUFuZENsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiB0YWJsZU5hbWUgfTtcbiAgfSBlbHNlIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScpIHtcbiAgICBhd2FpdCBkcm9wVGFibGUoZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkLCB0YWJsZUFuZENsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuO1xuICB9IGVsc2UgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnVXBkYXRlJykge1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IGF3YWl0IHVwZGF0ZVRhYmxlKFxuICAgICAgZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkLFxuICAgICAgdGFibGVOYW1lUHJlZml4LFxuICAgICAgdGFibGVOYW1lU3VmZml4LFxuICAgICAgdGFibGVDb2x1bW5zLFxuICAgICAgdGFibGVBbmRDbHVzdGVyUHJvcHMsXG4gICAgICBldmVudC5PbGRSZXNvdXJjZVByb3BlcnRpZXMgYXMgVGFibGVBbmRDbHVzdGVyUHJvcHMsXG4gICAgKTtcbiAgICByZXR1cm4geyBQaHlzaWNhbFJlc291cmNlSWQ6IHRhYmxlTmFtZSB9O1xuICB9IGVsc2Uge1xuICAgIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkb3Qtbm90YXRpb24gKi9cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBldmVudCB0eXBlOiAke2V2ZW50WydSZXF1ZXN0VHlwZSddfWApO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKFxuICB0YWJsZU5hbWVQcmVmaXg6IHN0cmluZyxcbiAgdGFibGVOYW1lU3VmZml4OiBzdHJpbmcsXG4gIHRhYmxlQ29sdW1uczogQ29sdW1uW10sXG4gIHRhYmxlQW5kQ2x1c3RlclByb3BzOiBUYWJsZUFuZENsdXN0ZXJQcm9wcyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHRhYmxlTmFtZSA9IHRhYmxlTmFtZVByZWZpeCArIHRhYmxlTmFtZVN1ZmZpeDtcbiAgY29uc3QgdGFibGVDb2x1bW5zU3RyaW5nID0gdGFibGVDb2x1bW5zLm1hcChjb2x1bW4gPT4gYCR7Y29sdW1uLm5hbWV9ICR7Y29sdW1uLmRhdGFUeXBlfSR7Z2V0RW5jb2RpbmdDb2x1bW5TdHJpbmcoY29sdW1uKX1gKS5qb2luKCk7XG5cbiAgbGV0IHN0YXRlbWVudCA9IGBDUkVBVEUgVEFCTEUgJHt0YWJsZU5hbWV9ICgke3RhYmxlQ29sdW1uc1N0cmluZ30pYDtcblxuICBpZiAodGFibGVBbmRDbHVzdGVyUHJvcHMuZGlzdFN0eWxlKSB7XG4gICAgc3RhdGVtZW50ICs9IGAgRElTVFNUWUxFICR7dGFibGVBbmRDbHVzdGVyUHJvcHMuZGlzdFN0eWxlfWA7XG4gIH1cblxuICBjb25zdCBkaXN0S2V5Q29sdW1uID0gZ2V0RGlzdEtleUNvbHVtbih0YWJsZUNvbHVtbnMpO1xuICBpZiAoZGlzdEtleUNvbHVtbikge1xuICAgIHN0YXRlbWVudCArPSBgIERJU1RLRVkoJHtkaXN0S2V5Q29sdW1uLm5hbWV9KWA7XG4gIH1cblxuICBjb25zdCBzb3J0S2V5Q29sdW1ucyA9IGdldFNvcnRLZXlDb2x1bW5zKHRhYmxlQ29sdW1ucyk7XG4gIGlmIChzb3J0S2V5Q29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qgc29ydEtleUNvbHVtbnNTdHJpbmcgPSBnZXRTb3J0S2V5Q29sdW1uc1N0cmluZyhzb3J0S2V5Q29sdW1ucyk7XG4gICAgc3RhdGVtZW50ICs9IGAgJHt0YWJsZUFuZENsdXN0ZXJQcm9wcy5zb3J0U3R5bGV9IFNPUlRLRVkoJHtzb3J0S2V5Q29sdW1uc1N0cmluZ30pYDtcbiAgfVxuXG4gIGF3YWl0IGV4ZWN1dGVTdGF0ZW1lbnQoc3RhdGVtZW50LCB0YWJsZUFuZENsdXN0ZXJQcm9wcyk7XG5cbiAgZm9yIChjb25zdCBjb2x1bW4gb2YgdGFibGVDb2x1bW5zKSB7XG4gICAgaWYgKGNvbHVtbi5jb21tZW50KSB7XG4gICAgICBhd2FpdCBleGVjdXRlU3RhdGVtZW50KGBDT01NRU5UIE9OIENPTFVNTiAke3RhYmxlTmFtZX0uJHtjb2x1bW4ubmFtZX0gSVMgJyR7Y29sdW1uLmNvbW1lbnR9J2AsIHRhYmxlQW5kQ2x1c3RlclByb3BzKTtcbiAgICB9XG4gIH1cbiAgaWYgKHRhYmxlQW5kQ2x1c3RlclByb3BzLnRhYmxlQ29tbWVudCkge1xuICAgIGF3YWl0IGV4ZWN1dGVTdGF0ZW1lbnQoYENPTU1FTlQgT04gVEFCTEUgJHt0YWJsZU5hbWV9IElTICcke3RhYmxlQW5kQ2x1c3RlclByb3BzLnRhYmxlQ29tbWVudH0nYCwgdGFibGVBbmRDbHVzdGVyUHJvcHMpO1xuICB9XG5cbiAgcmV0dXJuIHRhYmxlTmFtZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZHJvcFRhYmxlKHRhYmxlTmFtZTogc3RyaW5nLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcykge1xuICBhd2FpdCBleGVjdXRlU3RhdGVtZW50KGBEUk9QIFRBQkxFICR7dGFibGVOYW1lfWAsIGNsdXN0ZXJQcm9wcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVRhYmxlKFxuICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgdGFibGVOYW1lUHJlZml4OiBzdHJpbmcsXG4gIHRhYmxlTmFtZVN1ZmZpeDogc3RyaW5nLFxuICB0YWJsZUNvbHVtbnM6IENvbHVtbltdLFxuICB0YWJsZUFuZENsdXN0ZXJQcm9wczogVGFibGVBbmRDbHVzdGVyUHJvcHMsXG4gIG9sZFJlc291cmNlUHJvcGVydGllczogVGFibGVBbmRDbHVzdGVyUHJvcHMsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBhbHRlcmF0aW9uU3RhdGVtZW50czogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdCBvbGRDbHVzdGVyUHJvcHMgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXM7XG4gIGlmICh0YWJsZUFuZENsdXN0ZXJQcm9wcy5jbHVzdGVyTmFtZSAhPT0gb2xkQ2x1c3RlclByb3BzLmNsdXN0ZXJOYW1lIHx8IHRhYmxlQW5kQ2x1c3RlclByb3BzLmRhdGFiYXNlTmFtZSAhPT0gb2xkQ2x1c3RlclByb3BzLmRhdGFiYXNlTmFtZSkge1xuICAgIHJldHVybiBjcmVhdGVUYWJsZSh0YWJsZU5hbWVQcmVmaXgsIHRhYmxlTmFtZVN1ZmZpeCwgdGFibGVDb2x1bW5zLCB0YWJsZUFuZENsdXN0ZXJQcm9wcyk7XG4gIH1cblxuICBjb25zdCBvbGRUYWJsZU5hbWVQcmVmaXggPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudGFibGVOYW1lLnByZWZpeDtcbiAgaWYgKHRhYmxlTmFtZVByZWZpeCAhPT0gb2xkVGFibGVOYW1lUHJlZml4KSB7XG4gICAgcmV0dXJuIGNyZWF0ZVRhYmxlKHRhYmxlTmFtZVByZWZpeCwgdGFibGVOYW1lU3VmZml4LCB0YWJsZUNvbHVtbnMsIHRhYmxlQW5kQ2x1c3RlclByb3BzKTtcbiAgfVxuXG4gIGNvbnN0IG9sZFRhYmxlQ29sdW1ucyA9IG9sZFJlc291cmNlUHJvcGVydGllcy50YWJsZUNvbHVtbnM7XG4gIGNvbnN0IGNvbHVtbkRlbGV0aW9ucyA9IG9sZFRhYmxlQ29sdW1ucy5maWx0ZXIob2xkQ29sdW1uID0+IChcbiAgICB0YWJsZUNvbHVtbnMuZXZlcnkoY29sdW1uID0+IG9sZENvbHVtbi5uYW1lICE9PSBjb2x1bW4ubmFtZSlcbiAgKSk7XG4gIGlmIChjb2x1bW5EZWxldGlvbnMubGVuZ3RoID4gMCkge1xuICAgIGFsdGVyYXRpb25TdGF0ZW1lbnRzLnB1c2goLi4uY29sdW1uRGVsZXRpb25zLm1hcChjb2x1bW4gPT4gYEFMVEVSIFRBQkxFICR7dGFibGVOYW1lfSBEUk9QIENPTFVNTiAke2NvbHVtbi5uYW1lfWApKTtcbiAgfVxuXG4gIGNvbnN0IGNvbHVtbkFkZGl0aW9ucyA9IHRhYmxlQ29sdW1ucy5maWx0ZXIoY29sdW1uID0+IHtcbiAgICByZXR1cm4gIW9sZFRhYmxlQ29sdW1ucy5zb21lKG9sZENvbHVtbiA9PiBjb2x1bW4ubmFtZSA9PT0gb2xkQ29sdW1uLm5hbWUgJiYgY29sdW1uLmRhdGFUeXBlID09PSBvbGRDb2x1bW4uZGF0YVR5cGUpO1xuICB9KS5tYXAoY29sdW1uID0+IGBBREQgJHtjb2x1bW4ubmFtZX0gJHtjb2x1bW4uZGF0YVR5cGV9YCk7XG4gIGlmIChjb2x1bW5BZGRpdGlvbnMubGVuZ3RoID4gMCkge1xuICAgIGFsdGVyYXRpb25TdGF0ZW1lbnRzLnB1c2goLi4uY29sdW1uQWRkaXRpb25zLm1hcChhZGRpdGlvbiA9PiBgQUxURVIgVEFCTEUgJHt0YWJsZU5hbWV9ICR7YWRkaXRpb259YCkpO1xuICB9XG5cbiAgY29uc3QgY29sdW1uRW5jb2RpbmcgPSB0YWJsZUNvbHVtbnMuZmlsdGVyKGNvbHVtbiA9PiB7XG4gICAgcmV0dXJuIG9sZFRhYmxlQ29sdW1ucy5zb21lKG9sZENvbHVtbiA9PiBjb2x1bW4ubmFtZSA9PT0gb2xkQ29sdW1uLm5hbWUgJiYgY29sdW1uLmVuY29kaW5nICE9PSBvbGRDb2x1bW4uZW5jb2RpbmcpO1xuICB9KS5tYXAoY29sdW1uID0+IGBBTFRFUiBDT0xVTU4gJHtjb2x1bW4ubmFtZX0gRU5DT0RFICR7Y29sdW1uLmVuY29kaW5nIHx8IENvbHVtbkVuY29kaW5nLkFVVE99YCk7XG4gIGlmIChjb2x1bW5FbmNvZGluZy5sZW5ndGggPiAwKSB7XG4gICAgYWx0ZXJhdGlvblN0YXRlbWVudHMucHVzaChgQUxURVIgVEFCTEUgJHt0YWJsZU5hbWV9ICR7Y29sdW1uRW5jb2Rpbmcuam9pbignLCAnKX1gKTtcbiAgfVxuXG4gIGNvbnN0IGNvbHVtbkNvbW1lbnRzID0gdGFibGVDb2x1bW5zLmZpbHRlcihjb2x1bW4gPT4ge1xuICAgIHJldHVybiBvbGRUYWJsZUNvbHVtbnMuc29tZShvbGRDb2x1bW4gPT4gY29sdW1uLm5hbWUgPT09IG9sZENvbHVtbi5uYW1lICYmIGNvbHVtbi5jb21tZW50ICE9PSBvbGRDb2x1bW4uY29tbWVudCk7XG4gIH0pLm1hcChjb2x1bW4gPT4gYENPTU1FTlQgT04gQ09MVU1OICR7dGFibGVOYW1lfS4ke2NvbHVtbi5uYW1lfSBJUyAke2NvbHVtbi5jb21tZW50ID8gYCcke2NvbHVtbi5jb21tZW50fSdgIDogJ05VTEwnfWApO1xuICBpZiAoY29sdW1uQ29tbWVudHMubGVuZ3RoID4gMCkge1xuICAgIGFsdGVyYXRpb25TdGF0ZW1lbnRzLnB1c2goLi4uY29sdW1uQ29tbWVudHMpO1xuICB9XG5cbiAgY29uc3Qgb2xkRGlzdFN0eWxlID0gb2xkUmVzb3VyY2VQcm9wZXJ0aWVzLmRpc3RTdHlsZTtcbiAgaWYgKCghb2xkRGlzdFN0eWxlICYmIHRhYmxlQW5kQ2x1c3RlclByb3BzLmRpc3RTdHlsZSkgfHxcbiAgICAob2xkRGlzdFN0eWxlICYmICF0YWJsZUFuZENsdXN0ZXJQcm9wcy5kaXN0U3R5bGUpKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVRhYmxlKHRhYmxlTmFtZVByZWZpeCwgdGFibGVOYW1lU3VmZml4LCB0YWJsZUNvbHVtbnMsIHRhYmxlQW5kQ2x1c3RlclByb3BzKTtcbiAgfSBlbHNlIGlmIChvbGREaXN0U3R5bGUgIT09IHRhYmxlQW5kQ2x1c3RlclByb3BzLmRpc3RTdHlsZSkge1xuICAgIGFsdGVyYXRpb25TdGF0ZW1lbnRzLnB1c2goYEFMVEVSIFRBQkxFICR7dGFibGVOYW1lfSBBTFRFUiBESVNUU1RZTEUgJHt0YWJsZUFuZENsdXN0ZXJQcm9wcy5kaXN0U3R5bGV9YCk7XG4gIH1cblxuICBjb25zdCBvbGREaXN0S2V5ID0gZ2V0RGlzdEtleUNvbHVtbihvbGRUYWJsZUNvbHVtbnMpPy5uYW1lO1xuICBjb25zdCBuZXdEaXN0S2V5ID0gZ2V0RGlzdEtleUNvbHVtbih0YWJsZUNvbHVtbnMpPy5uYW1lO1xuICBpZiAoKCFvbGREaXN0S2V5ICYmIG5ld0Rpc3RLZXkgKSB8fCAob2xkRGlzdEtleSAmJiAhbmV3RGlzdEtleSkpIHtcbiAgICByZXR1cm4gY3JlYXRlVGFibGUodGFibGVOYW1lUHJlZml4LCB0YWJsZU5hbWVTdWZmaXgsIHRhYmxlQ29sdW1ucywgdGFibGVBbmRDbHVzdGVyUHJvcHMpO1xuICB9IGVsc2UgaWYgKG9sZERpc3RLZXkgIT09IG5ld0Rpc3RLZXkpIHtcbiAgICBhbHRlcmF0aW9uU3RhdGVtZW50cy5wdXNoKGBBTFRFUiBUQUJMRSAke3RhYmxlTmFtZX0gQUxURVIgRElTVEtFWSAke25ld0Rpc3RLZXl9YCk7XG4gIH1cblxuICBjb25zdCBvbGRTb3J0S2V5Q29sdW1ucyA9IGdldFNvcnRLZXlDb2x1bW5zKG9sZFRhYmxlQ29sdW1ucyk7XG4gIGNvbnN0IG5ld1NvcnRLZXlDb2x1bW5zID0gZ2V0U29ydEtleUNvbHVtbnModGFibGVDb2x1bW5zKTtcbiAgY29uc3Qgb2xkU29ydFN0eWxlID0gb2xkUmVzb3VyY2VQcm9wZXJ0aWVzLnNvcnRTdHlsZTtcbiAgY29uc3QgbmV3U29ydFN0eWxlID0gdGFibGVBbmRDbHVzdGVyUHJvcHMuc29ydFN0eWxlO1xuICBpZiAoKG9sZFNvcnRTdHlsZSA9PT0gbmV3U29ydFN0eWxlICYmICFhcmVDb2x1bW5zRXF1YWwob2xkU29ydEtleUNvbHVtbnMsIG5ld1NvcnRLZXlDb2x1bW5zKSlcbiAgICB8fCAob2xkU29ydFN0eWxlICE9PSBuZXdTb3J0U3R5bGUpKSB7XG4gICAgc3dpdGNoIChuZXdTb3J0U3R5bGUpIHtcbiAgICAgIGNhc2UgVGFibGVTb3J0U3R5bGUuSU5URVJMRUFWRUQ6XG4gICAgICAgIC8vIElOVEVSTEVBVkVEIHNvcnQga2V5IGFkZGl0aW9uIHJlcXVpcmVzIHJlcGxhY2VtZW50LlxuICAgICAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L2RnL3JfQUxURVJfVEFCTEUuaHRtbFxuICAgICAgICByZXR1cm4gY3JlYXRlVGFibGUodGFibGVOYW1lUHJlZml4LCB0YWJsZU5hbWVTdWZmaXgsIHRhYmxlQ29sdW1ucywgdGFibGVBbmRDbHVzdGVyUHJvcHMpO1xuXG4gICAgICBjYXNlIFRhYmxlU29ydFN0eWxlLkNPTVBPVU5EOiB7XG4gICAgICAgIGNvbnN0IHNvcnRLZXlDb2x1bW5zU3RyaW5nID0gZ2V0U29ydEtleUNvbHVtbnNTdHJpbmcobmV3U29ydEtleUNvbHVtbnMpO1xuICAgICAgICBhbHRlcmF0aW9uU3RhdGVtZW50cy5wdXNoKGBBTFRFUiBUQUJMRSAke3RhYmxlTmFtZX0gQUxURVIgJHtuZXdTb3J0U3R5bGV9IFNPUlRLRVkoJHtzb3J0S2V5Q29sdW1uc1N0cmluZ30pYCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlIFRhYmxlU29ydFN0eWxlLkFVVE86IHtcbiAgICAgICAgYWx0ZXJhdGlvblN0YXRlbWVudHMucHVzaChgQUxURVIgVEFCTEUgJHt0YWJsZU5hbWV9IEFMVEVSIFNPUlRLRVkgJHtuZXdTb3J0U3R5bGV9YCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG9sZENvbW1lbnQgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudGFibGVDb21tZW50O1xuICBjb25zdCBuZXdDb21tZW50ID0gdGFibGVBbmRDbHVzdGVyUHJvcHMudGFibGVDb21tZW50O1xuICBpZiAob2xkQ29tbWVudCAhPT0gbmV3Q29tbWVudCkge1xuICAgIGFsdGVyYXRpb25TdGF0ZW1lbnRzLnB1c2goYENPTU1FTlQgT04gVEFCTEUgJHt0YWJsZU5hbWV9IElTICR7bmV3Q29tbWVudCA/IGAnJHtuZXdDb21tZW50fSdgIDogJ05VTEwnfWApO1xuICB9XG5cbiAgYXdhaXQgUHJvbWlzZS5hbGwoYWx0ZXJhdGlvblN0YXRlbWVudHMubWFwKHN0YXRlbWVudCA9PiBleGVjdXRlU3RhdGVtZW50KHN0YXRlbWVudCwgdGFibGVBbmRDbHVzdGVyUHJvcHMpKSk7XG5cbiAgcmV0dXJuIHRhYmxlTmFtZTtcbn1cblxuZnVuY3Rpb24gZ2V0U29ydEtleUNvbHVtbnNTdHJpbmcoc29ydEtleUNvbHVtbnM6IENvbHVtbltdKSB7XG4gIHJldHVybiBzb3J0S2V5Q29sdW1ucy5tYXAoY29sdW1uID0+IGNvbHVtbi5uYW1lKS5qb2luKCk7XG59XG5cbmZ1bmN0aW9uIGdldEVuY29kaW5nQ29sdW1uU3RyaW5nKGNvbHVtbjogQ29sdW1uKTogc3RyaW5nIHtcbiAgaWYgKGNvbHVtbi5lbmNvZGluZykge1xuICAgIHJldHVybiBgIEVOQ09ERSAke2NvbHVtbi5lbmNvZGluZ31gO1xuICB9XG4gIHJldHVybiAnJztcbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/types.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/types.js new file mode 100644 index 0000000000000..c19cbf576b891 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/types.js @@ -0,0 +1,120 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ColumnEncoding = exports.TableSortStyle = void 0; +/** + * The sort style of a table. + * This has been duplicated here to exporting private types. + */ +var TableSortStyle; +(function (TableSortStyle) { + /** + * Amazon Redshift assigns an optimal sort key based on the table data. + */ + TableSortStyle["AUTO"] = "AUTO"; + /** + * Specifies that the data is sorted using a compound key made up of all of the listed columns, + * in the order they are listed. + */ + TableSortStyle["COMPOUND"] = "COMPOUND"; + /** + * Specifies that the data is sorted using an interleaved sort key. + */ + TableSortStyle["INTERLEAVED"] = "INTERLEAVED"; +})(TableSortStyle = exports.TableSortStyle || (exports.TableSortStyle = {})); +/** + * The compression encoding of a column. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Compression_encodings.html + */ +var ColumnEncoding; +(function (ColumnEncoding) { + /** + * Amazon Redshift assigns an optimal encoding based on the column data. + * This is the default. + */ + ColumnEncoding["AUTO"] = "AUTO"; + /** + * The column is not compressed. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Raw_encoding.html + */ + ColumnEncoding["RAW"] = "RAW"; + /** + * The column is compressed using the AZ64 algorithm. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/az64-encoding.html + */ + ColumnEncoding["AZ64"] = "AZ64"; + /** + * The column is compressed using a separate dictionary for each block column value on disk. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Byte_dictionary_encoding.html + */ + ColumnEncoding["BYTEDICT"] = "BYTEDICT"; + /** + * The column is compressed based on the difference between values in the column. + * This records differences as 1-byte values. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Delta_encoding.html + */ + ColumnEncoding["DELTA"] = "DELTA"; + /** + * The column is compressed based on the difference between values in the column. + * This records differences as 2-byte values. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Delta_encoding.html + */ + ColumnEncoding["DELTA32K"] = "DELTA32K"; + /** + * The column is compressed using the LZO algorithm. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/lzo-encoding.html + */ + ColumnEncoding["LZO"] = "LZO"; + /** + * The column is compressed to a smaller storage size than the original data type. + * The compressed storage size is 1 byte. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_MostlyN_encoding.html + */ + ColumnEncoding["MOSTLY8"] = "MOSTLY8"; + /** + * The column is compressed to a smaller storage size than the original data type. + * The compressed storage size is 2 bytes. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_MostlyN_encoding.html + */ + ColumnEncoding["MOSTLY16"] = "MOSTLY16"; + /** + * The column is compressed to a smaller storage size than the original data type. + * The compressed storage size is 4 bytes. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_MostlyN_encoding.html + */ + ColumnEncoding["MOSTLY32"] = "MOSTLY32"; + /** + * The column is compressed by recording the number of occurrences of each value in the column. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Runlength_encoding.html + */ + ColumnEncoding["RUNLENGTH"] = "RUNLENGTH"; + /** + * The column is compressed by recording the first 245 unique words and then using a 1-byte index to represent each word. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Text255_encoding.html + */ + ColumnEncoding["TEXT255"] = "TEXT255"; + /** + * The column is compressed by recording the first 32K unique words and then using a 2-byte index to represent each word. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/c_Text255_encoding.html + */ + ColumnEncoding["TEXT32K"] = "TEXT32K"; + /** + * The column is compressed using the ZSTD algorithm. + * + * @see https://docs.aws.amazon.com/redshift/latest/dg/zstd-encoding.html + */ + ColumnEncoding["ZSTD"] = "ZSTD"; +})(ColumnEncoding = exports.ColumnEncoding || (exports.ColumnEncoding = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFLQTs7O0dBR0c7QUFDSCxJQUFZLGNBZ0JYO0FBaEJELFdBQVksY0FBYztJQUN4Qjs7T0FFRztJQUNILCtCQUFhLENBQUE7SUFFYjs7O09BR0c7SUFDSCx1Q0FBcUIsQ0FBQTtJQUVyQjs7T0FFRztJQUNILDZDQUEyQixDQUFBO0FBQzdCLENBQUMsRUFoQlcsY0FBYyxHQUFkLHNCQUFjLEtBQWQsc0JBQWMsUUFnQnpCO0FBRUQ7Ozs7R0FJRztBQUNILElBQVksY0FzR1g7QUF0R0QsV0FBWSxjQUFjO0lBQ3hCOzs7T0FHRztJQUNILCtCQUFhLENBQUE7SUFFYjs7OztPQUlHO0lBQ0gsNkJBQVcsQ0FBQTtJQUVYOzs7O09BSUc7SUFDSCwrQkFBYSxDQUFBO0lBRWI7Ozs7T0FJRztJQUNILHVDQUFxQixDQUFBO0lBRXJCOzs7OztPQUtHO0lBQ0gsaUNBQWUsQ0FBQTtJQUVmOzs7OztPQUtHO0lBQ0gsdUNBQXFCLENBQUE7SUFFckI7Ozs7T0FJRztJQUNILDZCQUFXLENBQUE7SUFFWDs7Ozs7T0FLRztJQUNILHFDQUFtQixDQUFBO0lBRW5COzs7OztPQUtHO0lBQ0gsdUNBQXFCLENBQUE7SUFFckI7Ozs7O09BS0c7SUFDSCx1Q0FBcUIsQ0FBQTtJQUVyQjs7OztPQUlHO0lBQ0gseUNBQXVCLENBQUE7SUFFdkI7Ozs7T0FJRztJQUNILHFDQUFtQixDQUFBO0lBRW5COzs7O09BSUc7SUFDSCxxQ0FBbUIsQ0FBQTtJQUVuQjs7OztPQUlHO0lBQ0gsK0JBQWEsQ0FBQTtBQUNmLENBQUMsRUF0R1csY0FBYyxHQUFkLHNCQUFjLEtBQWQsc0JBQWMsUUFzR3pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGF0YWJhc2VRdWVyeUhhbmRsZXJQcm9wcywgVGFibGVIYW5kbGVyUHJvcHMgfSBmcm9tICcuLi9oYW5kbGVyLXByb3BzJztcblxuZXhwb3J0IHR5cGUgQ2x1c3RlclByb3BzID0gT21pdDxEYXRhYmFzZVF1ZXJ5SGFuZGxlclByb3BzLCAnaGFuZGxlcic+O1xuZXhwb3J0IHR5cGUgVGFibGVBbmRDbHVzdGVyUHJvcHMgPSBUYWJsZUhhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcztcblxuLyoqXG4gKiBUaGUgc29ydCBzdHlsZSBvZiBhIHRhYmxlLlxuICogVGhpcyBoYXMgYmVlbiBkdXBsaWNhdGVkIGhlcmUgdG8gZXhwb3J0aW5nIHByaXZhdGUgdHlwZXMuXG4gKi9cbmV4cG9ydCBlbnVtIFRhYmxlU29ydFN0eWxlIHtcbiAgLyoqXG4gICAqIEFtYXpvbiBSZWRzaGlmdCBhc3NpZ25zIGFuIG9wdGltYWwgc29ydCBrZXkgYmFzZWQgb24gdGhlIHRhYmxlIGRhdGEuXG4gICAqL1xuICBBVVRPID0gJ0FVVE8nLFxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgZGF0YSBpcyBzb3J0ZWQgdXNpbmcgYSBjb21wb3VuZCBrZXkgbWFkZSB1cCBvZiBhbGwgb2YgdGhlIGxpc3RlZCBjb2x1bW5zLFxuICAgKiBpbiB0aGUgb3JkZXIgdGhleSBhcmUgbGlzdGVkLlxuICAgKi9cbiAgQ09NUE9VTkQgPSAnQ09NUE9VTkQnLFxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgZGF0YSBpcyBzb3J0ZWQgdXNpbmcgYW4gaW50ZXJsZWF2ZWQgc29ydCBrZXkuXG4gICAqL1xuICBJTlRFUkxFQVZFRCA9ICdJTlRFUkxFQVZFRCcsXG59XG5cbi8qKlxuICogVGhlIGNvbXByZXNzaW9uIGVuY29kaW5nIG9mIGEgY29sdW1uLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9kZy9jX0NvbXByZXNzaW9uX2VuY29kaW5ncy5odG1sXG4gKi9cbmV4cG9ydCBlbnVtIENvbHVtbkVuY29kaW5nIHtcbiAgLyoqXG4gICAqIEFtYXpvbiBSZWRzaGlmdCBhc3NpZ25zIGFuIG9wdGltYWwgZW5jb2RpbmcgYmFzZWQgb24gdGhlIGNvbHVtbiBkYXRhLlxuICAgKiBUaGlzIGlzIHRoZSBkZWZhdWx0LlxuICAgKi9cbiAgQVVUTyA9ICdBVVRPJyxcblxuICAvKipcbiAgICogVGhlIGNvbHVtbiBpcyBub3QgY29tcHJlc3NlZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L2RnL2NfUmF3X2VuY29kaW5nLmh0bWxcbiAgICovXG4gIFJBVyA9ICdSQVcnLFxuXG4gIC8qKlxuICAgKiBUaGUgY29sdW1uIGlzIGNvbXByZXNzZWQgdXNpbmcgdGhlIEFaNjQgYWxnb3JpdGhtLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvZGcvYXo2NC1lbmNvZGluZy5odG1sXG4gICAqL1xuICBBWjY0ID0gJ0FaNjQnLFxuXG4gIC8qKlxuICAgKiBUaGUgY29sdW1uIGlzIGNvbXByZXNzZWQgdXNpbmcgYSBzZXBhcmF0ZSBkaWN0aW9uYXJ5IGZvciBlYWNoIGJsb2NrIGNvbHVtbiB2YWx1ZSBvbiBkaXNrLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvZGcvY19CeXRlX2RpY3Rpb25hcnlfZW5jb2RpbmcuaHRtbFxuICAgKi9cbiAgQllURURJQ1QgPSAnQllURURJQ1QnLFxuXG4gIC8qKlxuICAgKiBUaGUgY29sdW1uIGlzIGNvbXByZXNzZWQgYmFzZWQgb24gdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB2YWx1ZXMgaW4gdGhlIGNvbHVtbi5cbiAgICogVGhpcyByZWNvcmRzIGRpZmZlcmVuY2VzIGFzIDEtYnl0ZSB2YWx1ZXMuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9kZy9jX0RlbHRhX2VuY29kaW5nLmh0bWxcbiAgICovXG4gIERFTFRBID0gJ0RFTFRBJyxcblxuICAvKipcbiAgICogVGhlIGNvbHVtbiBpcyBjb21wcmVzc2VkIGJhc2VkIG9uIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdmFsdWVzIGluIHRoZSBjb2x1bW4uXG4gICAqIFRoaXMgcmVjb3JkcyBkaWZmZXJlbmNlcyBhcyAyLWJ5dGUgdmFsdWVzLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvZGcvY19EZWx0YV9lbmNvZGluZy5odG1sXG4gICAqL1xuICBERUxUQTMySyA9ICdERUxUQTMySycsXG5cbiAgLyoqXG4gICAqIFRoZSBjb2x1bW4gaXMgY29tcHJlc3NlZCB1c2luZyB0aGUgTFpPIGFsZ29yaXRobS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L2RnL2x6by1lbmNvZGluZy5odG1sXG4gICAqL1xuICBMWk8gPSAnTFpPJyxcblxuICAvKipcbiAgICogVGhlIGNvbHVtbiBpcyBjb21wcmVzc2VkIHRvIGEgc21hbGxlciBzdG9yYWdlIHNpemUgdGhhbiB0aGUgb3JpZ2luYWwgZGF0YSB0eXBlLlxuICAgKiBUaGUgY29tcHJlc3NlZCBzdG9yYWdlIHNpemUgaXMgMSBieXRlLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvZGcvY19Nb3N0bHlOX2VuY29kaW5nLmh0bWxcbiAgICovXG4gIE1PU1RMWTggPSAnTU9TVExZOCcsXG5cbiAgLyoqXG4gICAqIFRoZSBjb2x1bW4gaXMgY29tcHJlc3NlZCB0byBhIHNtYWxsZXIgc3RvcmFnZSBzaXplIHRoYW4gdGhlIG9yaWdpbmFsIGRhdGEgdHlwZS5cbiAgICogVGhlIGNvbXByZXNzZWQgc3RvcmFnZSBzaXplIGlzIDIgYnl0ZXMuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9kZy9jX01vc3RseU5fZW5jb2RpbmcuaHRtbFxuICAgKi9cbiAgTU9TVExZMTYgPSAnTU9TVExZMTYnLFxuXG4gIC8qKlxuICAgKiBUaGUgY29sdW1uIGlzIGNvbXByZXNzZWQgdG8gYSBzbWFsbGVyIHN0b3JhZ2Ugc2l6ZSB0aGFuIHRoZSBvcmlnaW5hbCBkYXRhIHR5cGUuXG4gICAqIFRoZSBjb21wcmVzc2VkIHN0b3JhZ2Ugc2l6ZSBpcyA0IGJ5dGVzLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvZGcvY19Nb3N0bHlOX2VuY29kaW5nLmh0bWxcbiAgICovXG4gIE1PU1RMWTMyID0gJ01PU1RMWTMyJyxcblxuICAvKipcbiAgICogVGhlIGNvbHVtbiBpcyBjb21wcmVzc2VkIGJ5IHJlY29yZGluZyB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIG9mIGVhY2ggdmFsdWUgaW4gdGhlIGNvbHVtbi5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L2RnL2NfUnVubGVuZ3RoX2VuY29kaW5nLmh0bWxcbiAgICovXG4gIFJVTkxFTkdUSCA9ICdSVU5MRU5HVEgnLFxuXG4gIC8qKlxuICAgKiBUaGUgY29sdW1uIGlzIGNvbXByZXNzZWQgYnkgcmVjb3JkaW5nIHRoZSBmaXJzdCAyNDUgdW5pcXVlIHdvcmRzIGFuZCB0aGVuIHVzaW5nIGEgMS1ieXRlIGluZGV4IHRvIHJlcHJlc2VudCBlYWNoIHdvcmQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9kZy9jX1RleHQyNTVfZW5jb2RpbmcuaHRtbFxuICAgKi9cbiAgVEVYVDI1NSA9ICdURVhUMjU1JyxcblxuICAvKipcbiAgICogVGhlIGNvbHVtbiBpcyBjb21wcmVzc2VkIGJ5IHJlY29yZGluZyB0aGUgZmlyc3QgMzJLIHVuaXF1ZSB3b3JkcyBhbmQgdGhlbiB1c2luZyBhIDItYnl0ZSBpbmRleCB0byByZXByZXNlbnQgZWFjaCB3b3JkLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvZGcvY19UZXh0MjU1X2VuY29kaW5nLmh0bWxcbiAgICovXG4gIFRFWFQzMksgPSAnVEVYVDMySycsXG5cbiAgLyoqXG4gICAqIFRoZSBjb2x1bW4gaXMgY29tcHJlc3NlZCB1c2luZyB0aGUgWlNURCBhbGdvcml0aG0uXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9kZy96c3RkLWVuY29kaW5nLmh0bWxcbiAgICovXG4gIFpTVEQgPSAnWlNURCcsXG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/user.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/user.js new file mode 100644 index 0000000000000..f097ae1836462 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/user.js @@ -0,0 +1,70 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +const SecretsManager = require("aws-sdk/clients/secretsmanager"); +const redshift_data_1 = require("./redshift-data"); +const util_1 = require("./util"); +const secretsManager = new SecretsManager(); +async function handler(props, event) { + const username = props.username; + const passwordSecretArn = props.passwordSecretArn; + const clusterProps = props; + if (event.RequestType === 'Create') { + await createUser(username, passwordSecretArn, clusterProps); + return { PhysicalResourceId: util_1.makePhysicalId(username, clusterProps, event.RequestId), Data: { username: username } }; + } + else if (event.RequestType === 'Delete') { + await dropUser(username, clusterProps); + return; + } + else if (event.RequestType === 'Update') { + const { replace } = await updateUser(username, passwordSecretArn, clusterProps, event.OldResourceProperties); + const physicalId = replace ? util_1.makePhysicalId(username, clusterProps, event.RequestId) : event.PhysicalResourceId; + return { PhysicalResourceId: physicalId, Data: { username: username } }; + } + else { + /* eslint-disable-next-line dot-notation */ + throw new Error(`Unrecognized event type: ${event['RequestType']}`); + } +} +exports.handler = handler; +async function dropUser(username, clusterProps) { + await redshift_data_1.executeStatement(`DROP USER ${username}`, clusterProps); +} +async function createUser(username, passwordSecretArn, clusterProps) { + const password = await getPasswordFromSecret(passwordSecretArn); + await redshift_data_1.executeStatement(`CREATE USER ${username} PASSWORD '${password}'`, clusterProps); +} +async function updateUser(username, passwordSecretArn, clusterProps, oldResourceProperties) { + const oldClusterProps = oldResourceProperties; + if (clusterProps.clusterName !== oldClusterProps.clusterName || clusterProps.databaseName !== oldClusterProps.databaseName) { + await createUser(username, passwordSecretArn, clusterProps); + return { replace: true }; + } + const oldUsername = oldResourceProperties.username; + const oldPasswordSecretArn = oldResourceProperties.passwordSecretArn; + const oldPassword = await getPasswordFromSecret(oldPasswordSecretArn); + const password = await getPasswordFromSecret(passwordSecretArn); + if (username !== oldUsername) { + await createUser(username, passwordSecretArn, clusterProps); + return { replace: true }; + } + if (password !== oldPassword) { + await redshift_data_1.executeStatement(`ALTER USER ${username} PASSWORD '${password}'`, clusterProps); + return { replace: false }; + } + return { replace: false }; +} +async function getPasswordFromSecret(passwordSecretArn) { + const secretValue = await secretsManager.getSecretValue({ + SecretId: passwordSecretArn, + }).promise(); + const secretString = secretValue.SecretString; + if (!secretString) { + throw new Error(`Secret string for ${passwordSecretArn} was empty`); + } + const { password } = JSON.parse(secretString); + return password; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsZ0VBQWdFO0FBQ2hFLGlFQUFpRTtBQUNqRSxtREFBbUQ7QUFFbkQsaUNBQXdDO0FBR3hDLE1BQU0sY0FBYyxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7QUFFckMsS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFzQyxFQUFFLEtBQWtEO0lBQ3RILE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7SUFDaEMsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUM7SUFDbEQsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBRTNCLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUU7UUFDbEMsTUFBTSxVQUFVLENBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxxQkFBYyxDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDO0tBQ3RIO1NBQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUN6QyxNQUFNLFFBQVEsQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO1NBQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUN6QyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxVQUFVLENBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMscUJBQXdELENBQUMsQ0FBQztRQUNoSixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLHFCQUFjLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxL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L25vLXVucmVzb2x2ZWQgKi9cbmltcG9ydCAqIGFzIEFXU0xhbWJkYSBmcm9tICdhd3MtbGFtYmRhJztcbi8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmltcG9ydCAqIGFzIFNlY3JldHNNYW5hZ2VyIGZyb20gJ2F3cy1zZGsvY2xpZW50cy9zZWNyZXRzbWFuYWdlcic7XG5pbXBvcnQgeyBleGVjdXRlU3RhdGVtZW50IH0gZnJvbSAnLi9yZWRzaGlmdC1kYXRhJztcbmltcG9ydCB7IENsdXN0ZXJQcm9wcyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgbWFrZVBoeXNpY2FsSWQgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHsgVXNlckhhbmRsZXJQcm9wcyB9IGZyb20gJy4uL2hhbmRsZXItcHJvcHMnO1xuXG5jb25zdCBzZWNyZXRzTWFuYWdlciA9IG5ldyBTZWNyZXRzTWFuYWdlcigpO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihwcm9wczogVXNlckhhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcywgZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgY29uc3QgdXNlcm5hbWUgPSBwcm9wcy51c2VybmFtZTtcbiAgY29uc3QgcGFzc3dvcmRTZWNyZXRBcm4gPSBwcm9wcy5wYXNzd29yZFNlY3JldEFybjtcbiAgY29uc3QgY2x1c3RlclByb3BzID0gcHJvcHM7XG5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgIGF3YWl0IGNyZWF0ZVVzZXIodXNlcm5hbWUsIHBhc3N3b3JkU2VjcmV0QXJuLCBjbHVzdGVyUHJvcHMpO1xuICAgIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogbWFrZVBoeXNpY2FsSWQodXNlcm5hbWUsIGNsdXN0ZXJQcm9wcywgZXZlbnQuUmVxdWVzdElkKSwgRGF0YTogeyB1c2VybmFtZTogdXNlcm5hbWUgfSB9O1xuICB9IGVsc2UgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJykge1xuICAgIGF3YWl0IGRyb3BVc2VyKHVzZXJuYW1lLCBjbHVzdGVyUHJvcHMpO1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ1VwZGF0ZScpIHtcbiAgICBjb25zdCB7IHJlcGxhY2UgfSA9IGF3YWl0IHVwZGF0ZVVzZXIodXNlcm5hbWUsIHBhc3N3b3JkU2VjcmV0QXJuLCBjbHVzdGVyUHJvcHMsIGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcyBhcyBVc2VySGFuZGxlclByb3BzICYgQ2x1c3RlclByb3BzKTtcbiAgICBjb25zdCBwaHlzaWNhbElkID0gcmVwbGFjZSA/IG1ha2VQaHlzaWNhbElkKHVzZXJuYW1lLCBjbHVzdGVyUHJvcHMsIGV2ZW50LlJlcXVlc3RJZCkgOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQ7XG4gICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiBwaHlzaWNhbElkLCBEYXRhOiB7IHVzZXJuYW1lOiB1c2VybmFtZSB9IH07XG4gIH0gZWxzZSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRvdC1ub3RhdGlvbiAqL1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pemVkIGV2ZW50IHR5cGU6ICR7ZXZlbnRbJ1JlcXVlc3RUeXBlJ119YCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZHJvcFVzZXIodXNlcm5hbWU6IHN0cmluZywgY2x1c3RlclByb3BzOiBDbHVzdGVyUHJvcHMpIHtcbiAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgRFJPUCBVU0VSICR7dXNlcm5hbWV9YCwgY2x1c3RlclByb3BzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlVXNlcih1c2VybmFtZTogc3RyaW5nLCBwYXNzd29yZFNlY3JldEFybjogc3RyaW5nLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcykge1xuICBjb25zdCBwYXNzd29yZCA9IGF3YWl0IGdldFBhc3N3b3JkRnJvbVNlY3JldChwYXNzd29yZFNlY3JldEFybik7XG5cbiAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgQ1JFQVRFIFVTRVIgJHt1c2VybmFtZX0gUEFTU1dPUkQgJyR7cGFzc3dvcmR9J2AsIGNsdXN0ZXJQcm9wcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVVzZXIoXG4gIHVzZXJuYW1lOiBzdHJpbmcsXG4gIHBhc3N3b3JkU2VjcmV0QXJuOiBzdHJpbmcsXG4gIGNsdXN0ZXJQcm9wczogQ2x1c3RlclByb3BzLFxuICBvbGRSZXNvdXJjZVByb3BlcnRpZXM6IFVzZXJIYW5kbGVyUHJvcHMgJiBDbHVzdGVyUHJvcHMsXG4pOiBQcm9taXNlPHsgcmVwbGFjZTogYm9vbGVhbiB9PiB7XG4gIGNvbnN0IG9sZENsdXN0ZXJQcm9wcyA9IG9sZFJlc291cmNlUHJvcGVydGllcztcbiAgaWYgKGNsdXN0ZXJQcm9wcy5jbHVzdGVyTmFtZSAhPT0gb2xkQ2x1c3RlclByb3BzLmNsdXN0ZXJOYW1lIHx8IGNsdXN0ZXJQcm9wcy5kYXRhYmFzZU5hbWUgIT09IG9sZENsdXN0ZXJQcm9wcy5kYXRhYmFzZU5hbWUpIHtcbiAgICBhd2FpdCBjcmVhdGVVc2VyKHVzZXJuYW1lLCBwYXNzd29yZFNlY3JldEFybiwgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiB0cnVlIH07XG4gIH1cblxuICBjb25zdCBvbGRVc2VybmFtZSA9IG9sZFJlc291cmNlUHJvcGVydGllcy51c2VybmFtZTtcbiAgY29uc3Qgb2xkUGFzc3dvcmRTZWNyZXRBcm4gPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMucGFzc3dvcmRTZWNyZXRBcm47XG4gIGNvbnN0IG9sZFBhc3N3b3JkID0gYXdhaXQgZ2V0UGFzc3dvcmRGcm9tU2VjcmV0KG9sZFBhc3N3b3JkU2VjcmV0QXJuKTtcbiAgY29uc3QgcGFzc3dvcmQgPSBhd2FpdCBnZXRQYXNzd29yZEZyb21TZWNyZXQocGFzc3dvcmRTZWNyZXRBcm4pO1xuXG4gIGlmICh1c2VybmFtZSAhPT0gb2xkVXNlcm5hbWUpIHtcbiAgICBhd2FpdCBjcmVhdGVVc2VyKHVzZXJuYW1lLCBwYXNzd29yZFNlY3JldEFybiwgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiB0cnVlIH07XG4gIH1cblxuICBpZiAocGFzc3dvcmQgIT09IG9sZFBhc3N3b3JkKSB7XG4gICAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgQUxURVIgVVNFUiAke3VzZXJuYW1lfSBQQVNTV09SRCAnJHtwYXNzd29yZH0nYCwgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiBmYWxzZSB9O1xuICB9XG5cbiAgcmV0dXJuIHsgcmVwbGFjZTogZmFsc2UgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0UGFzc3dvcmRGcm9tU2VjcmV0KHBhc3N3b3JkU2VjcmV0QXJuOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBzZWNyZXRWYWx1ZSA9IGF3YWl0IHNlY3JldHNNYW5hZ2VyLmdldFNlY3JldFZhbHVlKHtcbiAgICBTZWNyZXRJZDogcGFzc3dvcmRTZWNyZXRBcm4sXG4gIH0pLnByb21pc2UoKTtcbiAgY29uc3Qgc2VjcmV0U3RyaW5nID0gc2VjcmV0VmFsdWUuU2VjcmV0U3RyaW5nO1xuICBpZiAoIXNlY3JldFN0cmluZykge1xuICAgIHRocm93IG5ldyBFcnJvcihgU2VjcmV0IHN0cmluZyBmb3IgJHtwYXNzd29yZFNlY3JldEFybn0gd2FzIGVtcHR5YCk7XG4gIH1cbiAgY29uc3QgeyBwYXNzd29yZCB9ID0gSlNPTi5wYXJzZShzZWNyZXRTdHJpbmcpO1xuXG4gIHJldHVybiBwYXNzd29yZDtcbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/util.js b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/util.js new file mode 100644 index 0000000000000..d8dc8cad799c9 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/asset.847e15feeb180b356ab9a8094d8b9459ea8ec26fc27957794d583ed9eb3a79d8/util.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.areColumnsEqual = exports.getSortKeyColumns = exports.getDistKeyColumn = exports.makePhysicalId = void 0; +function makePhysicalId(resourceName, clusterProps, requestId) { + return `${clusterProps.clusterName}:${clusterProps.databaseName}:${resourceName}:${requestId}`; +} +exports.makePhysicalId = makePhysicalId; +function getDistKeyColumn(columns) { + // string comparison is required for custom resource since everything is passed as string + const distKeyColumns = columns.filter(column => column.distKey === true || column.distKey === 'true'); + if (distKeyColumns.length === 0) { + return undefined; + } + else if (distKeyColumns.length > 1) { + throw new Error('Multiple dist key columns found'); + } + return distKeyColumns[0]; +} +exports.getDistKeyColumn = getDistKeyColumn; +function getSortKeyColumns(columns) { + // string comparison is required for custom resource since everything is passed as string + return columns.filter(column => column.sortKey === true || column.sortKey === 'true'); +} +exports.getSortKeyColumns = getSortKeyColumns; +function areColumnsEqual(columnsA, columnsB) { + if (columnsA.length !== columnsB.length) { + return false; + } + return columnsA.every(columnA => { + return columnsB.find(column => column.name === columnA.name && column.dataType === columnA.dataType); + }); +} +exports.areColumnsEqual = areColumnsEqual; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsU0FBZ0IsY0FBYyxDQUFDLFlBQW9CLEVBQUUsWUFBMEIsRUFBRSxTQUFpQjtJQUNoRyxPQUFPLEdBQUcsWUFBWSxDQUFDLFdBQVcsSUFBSSxZQUFZLENBQUMsWUFBWSxJQUFJLFlBQVksSUFBSSxTQUFTLEVBQUUsQ0FBQztBQUNqRyxDQUFDO0FBRkQsd0NBRUM7QUFFRCxTQUFnQixnQkFBZ0IsQ0FBQyxPQUFpQjtJQUNoRCx5RkFBeUY7SUFDekYsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEtBQUssSUFBSSxJQUFLLE1BQU0sQ0FBQyxPQUE2QixLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBRTdILElBQUksY0FBYyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDL0IsT0FBTyxTQUFTLENBQUM7S0FDbEI7U0FBTSxJQUFJLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztLQUNwRDtJQUVELE9BQU8sY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFYRCw0Q0FXQztBQUVELFNBQWdCLGlCQUFpQixDQUFDLE9BQWlCO0lBQ2pELHlGQUF5RjtJQUN6RixPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxLQUFLLElBQUksSUFBSyxNQUFNLENBQUMsT0FBNkIsS0FBSyxNQUFNLENBQUMsQ0FBQztBQUMvRyxDQUFDO0FBSEQsOENBR0M7QUFFRCxTQUFnQixlQUFlLENBQUMsUUFBa0IsRUFBRSxRQUFrQjtJQUNwRSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLE1BQU0sRUFBRTtRQUN2QyxPQUFPLEtBQUssQ0FBQztLQUNkO0lBQ0QsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQzlCLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN2RyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFQRCwwQ0FPQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENsdXN0ZXJQcm9wcyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgQ29sdW1uIH0gZnJvbSAnLi4vLi4vdGFibGUnO1xuXG5leHBvcnQgZnVuY3Rpb24gbWFrZVBoeXNpY2FsSWQocmVzb3VyY2VOYW1lOiBzdHJpbmcsIGNsdXN0ZXJQcm9wczogQ2x1c3RlclByb3BzLCByZXF1ZXN0SWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtjbHVzdGVyUHJvcHMuY2x1c3Rlck5hbWV9OiR7Y2x1c3RlclByb3BzLmRhdGFiYXNlTmFtZX06JHtyZXNvdXJjZU5hbWV9OiR7cmVxdWVzdElkfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREaXN0S2V5Q29sdW1uKGNvbHVtbnM6IENvbHVtbltdKTogQ29sdW1uIHwgdW5kZWZpbmVkIHtcbiAgLy8gc3RyaW5nIGNvbXBhcmlzb24gaXMgcmVxdWlyZWQgZm9yIGN1c3RvbSByZXNvdXJjZSBzaW5jZSBldmVyeXRoaW5nIGlzIHBhc3NlZCBhcyBzdHJpbmdcbiAgY29uc3QgZGlzdEtleUNvbHVtbnMgPSBjb2x1bW5zLmZpbHRlcihjb2x1bW4gPT4gY29sdW1uLmRpc3RLZXkgPT09IHRydWUgfHwgKGNvbHVtbi5kaXN0S2V5IGFzIHVua25vd24gYXMgc3RyaW5nKSA9PT0gJ3RydWUnKTtcblxuICBpZiAoZGlzdEtleUNvbHVtbnMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBlbHNlIGlmIChkaXN0S2V5Q29sdW1ucy5sZW5ndGggPiAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNdWx0aXBsZSBkaXN0IGtleSBjb2x1bW5zIGZvdW5kJyk7XG4gIH1cblxuICByZXR1cm4gZGlzdEtleUNvbHVtbnNbMF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTb3J0S2V5Q29sdW1ucyhjb2x1bW5zOiBDb2x1bW5bXSk6IENvbHVtbltdIHtcbiAgLy8gc3RyaW5nIGNvbXBhcmlzb24gaXMgcmVxdWlyZWQgZm9yIGN1c3RvbSByZXNvdXJjZSBzaW5jZSBldmVyeXRoaW5nIGlzIHBhc3NlZCBhcyBzdHJpbmdcbiAgcmV0dXJuIGNvbHVtbnMuZmlsdGVyKGNvbHVtbiA9PiBjb2x1bW4uc29ydEtleSA9PT0gdHJ1ZSB8fCAoY29sdW1uLnNvcnRLZXkgYXMgdW5rbm93biBhcyBzdHJpbmcpID09PSAndHJ1ZScpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJlQ29sdW1uc0VxdWFsKGNvbHVtbnNBOiBDb2x1bW5bXSwgY29sdW1uc0I6IENvbHVtbltdKTogYm9vbGVhbiB7XG4gIGlmIChjb2x1bW5zQS5sZW5ndGggIT09IGNvbHVtbnNCLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gY29sdW1uc0EuZXZlcnkoY29sdW1uQSA9PiB7XG4gICAgcmV0dXJuIGNvbHVtbnNCLmZpbmQoY29sdW1uID0+IGNvbHVtbi5uYW1lID09PSBjb2x1bW5BLm5hbWUgJiYgY29sdW1uLmRhdGFUeXBlID09PSBjb2x1bW5BLmRhdGFUeXBlKTtcbiAgfSk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.assets.json index 863fe6c1960ce..ae34a00d79aa9 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.assets.json @@ -42,4 +42,4 @@ } }, "dockerImages": {} -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.template.json b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.template.json index c3a7bfa330492..4e234633a945a 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.template.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/aws-cdk-redshift-cluster-database.template.json @@ -1,1221 +1,1193 @@ { - "Resources": { - "customkmskey377C6F9A": { - "Type": "AWS::KMS::Key", - "Properties": { - "KeyPolicy": { - "Statement": [ - { - "Action": "kms:*", - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" + "Resources": { + "customkmskey377C6F9A": { + "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" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "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-redshift-cluster-database/Vpc/PublicSubnet1" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } - }, - "Resource": "*" - } - ], - "Version": "2012-10-17" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "Vpc8378EB38": { - "Type": "AWS::EC2::VPC", - "Properties": { - "CidrBlock": "10.0.0.0/16", - "EnableDnsHostnames": true, - "EnableDnsSupport": true, - "InstanceTenancy": "default", - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet1Subnet5C2D37C4": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "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-redshift-cluster-database/Vpc/PublicSubnet1" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet1RouteTable6C95E38E": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet1RouteTableAssociation97140677": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "VpcPublicSubnet1RouteTable6C95E38E" - }, - "SubnetId": { - "Ref": "VpcPublicSubnet1Subnet5C2D37C4" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet1DefaultRoute3DA9E72A": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "VpcPublicSubnet1RouteTable6C95E38E" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "GatewayId": { - "Ref": "VpcIGWD7BA715C" - } - }, - "DependsOn": [ - "VpcVPCGWBF912B6E" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet1EIPD7E02669": { - "Type": "AWS::EC2::EIP", - "Properties": { - "Domain": "vpc", - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet1NATGateway4D7517AA": { - "Type": "AWS::EC2::NatGateway", - "Properties": { - "SubnetId": { - "Ref": "VpcPublicSubnet1Subnet5C2D37C4" - }, - "AllocationId": { - "Fn::GetAtt": [ - "VpcPublicSubnet1EIPD7E02669", - "AllocationId" - ] - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1" - } - ] - }, - "DependsOn": [ - "VpcPublicSubnet1DefaultRoute3DA9E72A", - "VpcPublicSubnet1RouteTableAssociation97140677" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet2Subnet691E08A3": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "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-redshift-cluster-database/Vpc/PublicSubnet2" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet2RouteTable94F7E489": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet2RouteTableAssociationDD5762D8": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "VpcPublicSubnet2RouteTable94F7E489" - }, - "SubnetId": { - "Ref": "VpcPublicSubnet2Subnet691E08A3" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet2DefaultRoute97F91067": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "VpcPublicSubnet2RouteTable94F7E489" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "GatewayId": { - "Ref": "VpcIGWD7BA715C" - } - }, - "DependsOn": [ - "VpcVPCGWBF912B6E" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet2EIP3C605A87": { - "Type": "AWS::EC2::EIP", - "Properties": { - "Domain": "vpc", - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPublicSubnet2NATGateway9182C01D": { - "Type": "AWS::EC2::NatGateway", - "Properties": { - "SubnetId": { - "Ref": "VpcPublicSubnet2Subnet691E08A3" - }, - "AllocationId": { - "Fn::GetAtt": [ - "VpcPublicSubnet2EIP3C605A87", - "AllocationId" - ] - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2" - } - ] - }, - "DependsOn": [ - "VpcPublicSubnet2DefaultRoute97F91067", - "VpcPublicSubnet2RouteTableAssociationDD5762D8" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet1Subnet536B997A": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "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-redshift-cluster-database/Vpc/PrivateSubnet1" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet1RouteTableB2C5B500": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet1" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" - }, - "SubnetId": { - "Ref": "VpcPrivateSubnet1Subnet536B997A" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet1DefaultRouteBE02A9ED": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "NatGatewayId": { - "Ref": "VpcPublicSubnet1NATGateway4D7517AA" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet2Subnet3788AAA1": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "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-redshift-cluster-database/Vpc/PrivateSubnet2" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet2RouteTableA678073B": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet2" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "VpcPrivateSubnet2RouteTableA678073B" - }, - "SubnetId": { - "Ref": "VpcPrivateSubnet2Subnet3788AAA1" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcPrivateSubnet2DefaultRoute060D2087": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "VpcPrivateSubnet2RouteTableA678073B" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "NatGatewayId": { - "Ref": "VpcPublicSubnet2NATGateway9182C01D" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcIGWD7BA715C": { - "Type": "AWS::EC2::InternetGateway", - "Properties": { - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-redshift-cluster-database/Vpc" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VpcVPCGWBF912B6E": { - "Type": "AWS::EC2::VPCGatewayAttachment", - "Properties": { - "VpcId": { - "Ref": "Vpc8378EB38" - }, - "InternetGatewayId": { - "Ref": "VpcIGWD7BA715C" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "ClusterSubnetsDCFA5CB7": { - "Type": "AWS::Redshift::ClusterSubnetGroup", - "Properties": { - "Description": "Subnets for Cluster Redshift cluster", - "SubnetIds": [ - { - "Ref": "VpcPublicSubnet1Subnet5C2D37C4" - }, - { - "Ref": "VpcPublicSubnet2Subnet691E08A3" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "ClusterSecurityGroup0921994B": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Redshift security group", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "ClusterSecret6368BD0F": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": { - "ExcludeCharacters": "\"@/\\ '", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{\"username\":\"admin\"}" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "ClusterSecretAttachment769E6258": { - "Type": "AWS::SecretsManager::SecretTargetAttachment", - "Properties": { - "SecretId": { - "Ref": "ClusterSecret6368BD0F" - }, - "TargetId": { - "Ref": "ClusterEB0386A7" - }, - "TargetType": "AWS::Redshift::Cluster" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "ClusterEB0386A7": { - "Type": "AWS::Redshift::Cluster", - "Properties": { - "ClusterType": "multi-node", - "DBName": "my_db", - "MasterUsername": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "ClusterSecret6368BD0F" - }, - ":SecretString:username::}}" - ] - ] - }, - "MasterUserPassword": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "ClusterSecret6368BD0F" - }, - ":SecretString:password::}}" - ] - ] - }, - "NodeType": "dc2.large", - "AllowVersionUpgrade": true, - "AutomatedSnapshotRetentionPeriod": 1, - "ClusterParameterGroupName": { - "Ref": "ClusterParameterGroup879806FD" - }, - "ClusterSubnetGroupName": { - "Ref": "ClusterSubnetsDCFA5CB7" - }, - "Encrypted": true, - "KmsKeyId": { - "Ref": "customkmskey377C6F9A" - }, - "NumberOfNodes": 2, - "PubliclyAccessible": true, - "VpcSecurityGroupIds": [ - { - "Fn::GetAtt": [ - "ClusterSecurityGroup0921994B", - "GroupId" - ] - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "ClusterParameterGroup879806FD": { - "Type": "AWS::Redshift::ClusterParameterGroup", - "Properties": { - "Description": "Cluster parameter group for family redshift-1.0", - "ParameterGroupFamily": "redshift-1.0", - "Parameters": [ - { - "ParameterName": "enable_user_activity_logging", - "ParameterValue": "true" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserSecretE2C04A69": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": { - "ExcludeCharacters": "\"@/\\ '", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{\"username\":\"awscdkredshiftclusterdatabaseuserc17d5ebd\"}" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserSecretAttachment02022609": { - "Type": "AWS::SecretsManager::SecretTargetAttachment", - "Properties": { - "SecretId": { - "Ref": "UserSecretE2C04A69" - }, - "TargetId": { - "Ref": "ClusterEB0386A7" - }, - "TargetType": "AWS::Redshift::Cluster" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserProviderframeworkonEventServiceRole8FBA2FBD": { - "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" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserProviderframeworkonEventServiceRoleDefaultPolicy9A9E044F": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "lambda:InvokeFunction", - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": ["VpcVPCGWBF912B6E"], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet1EIPD7E02669": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] - }, - ":*" + "AllocationId": { + "Fn::GetAtt": ["VpcPublicSubnet1EIPD7E02669", "AllocationId"] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet1RouteTableAssociation97140677" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet2Subnet691E08A3": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "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-redshift-cluster-database/Vpc/PublicSubnet2" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" } - ] - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "UserProviderframeworkonEventServiceRoleDefaultPolicy9A9E044F", - "Roles": [ - { - "Ref": "UserProviderframeworkonEventServiceRole8FBA2FBD" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserProviderframeworkonEvent4EC32885": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "a8a62b989c7866e3ad5b24f3eb6228f8ca91ebff5f5c76f1da466f6c805c0585.zip" - }, - "Role": { - "Fn::GetAtt": [ - "UserProviderframeworkonEventServiceRole8FBA2FBD", - "Arn" - ] - }, - "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-redshift-cluster-database/User/Resource/Provider)", - "Environment": { - "Variables": { - "USER_ON_EVENT_FUNCTION_ARN": { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] - } - } - }, - "Handler": "framework.onEvent", - "Runtime": "nodejs14.x", - "Timeout": 900 - }, - "DependsOn": [ - "UserProviderframeworkonEventServiceRoleDefaultPolicy9A9E044F", - "UserProviderframeworkonEventServiceRole8FBA2FBD" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserFDDCDD17": { - "Type": "Custom::RedshiftDatabaseQuery", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "UserProviderframeworkonEvent4EC32885", - "Arn" - ] - }, - "handler": "user", - "clusterName": { - "Ref": "ClusterEB0386A7" - }, - "adminUserArn": { - "Ref": "ClusterSecretAttachment769E6258" - }, - "databaseName": "my_db", - "username": "awscdkredshiftclusterdatabaseuserc17d5ebd", - "passwordSecretArn": { - "Ref": "UserSecretAttachment02022609" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A": { - "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" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet2DefaultRoute97F91067": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserTablePrivilegesProviderframeworkonEventServiceRoleDefaultPolicy3B6EF50C": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "lambda:InvokeFunction", - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": ["VpcVPCGWBF912B6E"], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet2EIP3C605A87": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPublicSubnet2NATGateway9182C01D": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] - }, - ":*" + "AllocationId": { + "Fn::GetAtt": ["VpcPublicSubnet2EIP3C605A87", "AllocationId"] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "VpcPublicSubnet2DefaultRoute97F91067", + "VpcPublicSubnet2RouteTableAssociationDD5762D8" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet1Subnet536B997A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "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-redshift-cluster-database/Vpc/PrivateSubnet1" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet1" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet2Subnet3788AAA1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "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-redshift-cluster-database/Vpc/PrivateSubnet2" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet2RouteTableA678073B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet2" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" } - ] - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "UserTablePrivilegesProviderframeworkonEventServiceRoleDefaultPolicy3B6EF50C", - "Roles": [ - { - "Ref": "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserTablePrivilegesProviderframeworkonEvent3F5C1851": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "a8a62b989c7866e3ad5b24f3eb6228f8ca91ebff5f5c76f1da466f6c805c0585.zip" - }, - "Role": { - "Fn::GetAtt": [ - "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A", - "Arn" - ] - }, - "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-redshift-cluster-database/User/TablePrivileges/Resource/Provider)", - "Environment": { - "Variables": { - "USER_ON_EVENT_FUNCTION_ARN": { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] - } - } - }, - "Handler": "framework.onEvent", - "Runtime": "nodejs14.x", - "Timeout": 900 - }, - "DependsOn": [ - "UserTablePrivilegesProviderframeworkonEventServiceRoleDefaultPolicy3B6EF50C", - "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "UserTablePrivileges3829D614": { - "Type": "Custom::RedshiftDatabaseQuery", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "UserTablePrivilegesProviderframeworkonEvent3F5C1851", - "Arn" - ] - }, - "handler": "user-table-privileges", - "clusterName": { - "Ref": "ClusterEB0386A7" - }, - "adminUserArn": { - "Ref": "ClusterSecretAttachment769E6258" - }, - "databaseName": "my_db", - "username": { - "Fn::GetAtt": [ - "UserFDDCDD17", - "username" - ] - }, - "tablePrivileges": [ - { - "tableName": { - "Ref": "Table7ABB320E" }, - "actions": [ - "INSERT", - "DELETE", - "SELECT" - ] - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717": { - "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" + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcPrivateSubnet2DefaultRoute060D2087": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRoleDefaultPolicyDDD1388D": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "redshift-data:DescribeStatement", - "redshift-data:ExecuteStatement" - ], - "Effect": "Allow", - "Resource": "*" + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet2NATGateway9182C01D" + } }, - { - "Action": [ - "secretsmanager:DescribeSecret", - "secretsmanager:GetSecretValue" - ], - "Effect": "Allow", - "Resource": [ - { - "Ref": "ClusterSecretAttachment769E6258" + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-redshift-cluster-database/Vpc" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" }, - { - "Ref": "UserSecretAttachment02022609" + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" } - ] - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRoleDefaultPolicyDDD1388D", - "Roles": [ - { - "Ref": "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338.zip" - }, - "Role": { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717", - "Arn" - ] - }, - "Handler": "index.handler", - "Runtime": "nodejs14.x", - "Timeout": 60 - }, - "DependsOn": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRoleDefaultPolicyDDD1388D", - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TableProviderframeworkonEventServiceRoleC3128F67": { - "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" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterSubnetsDCFA5CB7": { + "Type": "AWS::Redshift::ClusterSubnetGroup", + "Properties": { + "Description": "Subnets for Cluster Redshift cluster", + "SubnetIds": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterSecurityGroup0921994B": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Redshift security group", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterSecret6368BD0F": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": { + "ExcludeCharacters": "\"@/\\ '", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{\"username\":\"admin\"}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterSecretAttachment769E6258": { + "Type": "AWS::SecretsManager::SecretTargetAttachment", + "Properties": { + "SecretId": { + "Ref": "ClusterSecret6368BD0F" }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TableProviderframeworkonEventServiceRoleDefaultPolicyAD08715D": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "lambda:InvokeFunction", - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] + "TargetId": { + "Ref": "ClusterEB0386A7" }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" + "TargetType": "AWS::Redshift::Cluster" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterEB0386A7": { + "Type": "AWS::Redshift::Cluster", + "Properties": { + "ClusterType": "multi-node", + "DBName": "my_db", + "MasterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "ClusterSecret6368BD0F" + }, + ":SecretString:username::}}" ] - }, - ":*" ] - ] + }, + "MasterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "ClusterSecret6368BD0F" + }, + ":SecretString:password::}}" + ] + ] + }, + "NodeType": "dc2.large", + "AllowVersionUpgrade": true, + "AutomatedSnapshotRetentionPeriod": 1, + "ClusterParameterGroupName": { + "Ref": "ClusterParameterGroup879806FD" + }, + "ClusterSubnetGroupName": { + "Ref": "ClusterSubnetsDCFA5CB7" + }, + "Encrypted": true, + "KmsKeyId": { + "Ref": "customkmskey377C6F9A" + }, + "NumberOfNodes": 2, + "PubliclyAccessible": true, + "VpcSecurityGroupIds": [ + { + "Fn::GetAtt": ["ClusterSecurityGroup0921994B", "GroupId"] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterParameterGroup879806FD": { + "Type": "AWS::Redshift::ClusterParameterGroup", + "Properties": { + "Description": "Cluster parameter group for family redshift-1.0", + "ParameterGroupFamily": "redshift-1.0", + "Parameters": [ + { + "ParameterName": "enable_user_activity_logging", + "ParameterValue": "true" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserSecretE2C04A69": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": { + "ExcludeCharacters": "\"@/\\ '", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{\"username\":\"awscdkredshiftclusterdatabaseuserc17d5ebd\"}" } - ] - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "TableProviderframeworkonEventServiceRoleDefaultPolicyAD08715D", - "Roles": [ - { - "Ref": "TableProviderframeworkonEventServiceRoleC3128F67" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserSecretAttachment02022609": { + "Type": "AWS::SecretsManager::SecretTargetAttachment", + "Properties": { + "SecretId": { + "Ref": "UserSecretE2C04A69" + }, + "TargetId": { + "Ref": "ClusterEB0386A7" + }, + "TargetType": "AWS::Redshift::Cluster" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserProviderframeworkonEventServiceRole8FBA2FBD": { + "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" + ] + ] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserProviderframeworkonEventServiceRoleDefaultPolicy9A9E044F": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + }, + ":*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "UserProviderframeworkonEventServiceRoleDefaultPolicy9A9E044F", + "Roles": [ + { + "Ref": "UserProviderframeworkonEventServiceRole8FBA2FBD" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserProviderframeworkonEvent4EC32885": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "a8a62b989c7866e3ad5b24f3eb6228f8ca91ebff5f5c76f1da466f6c805c0585.zip" + }, + "Role": { + "Fn::GetAtt": [ + "UserProviderframeworkonEventServiceRole8FBA2FBD", + "Arn" + ] + }, + "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-redshift-cluster-database/User/Resource/Provider)", + "Environment": { + "Variables": { + "USER_ON_EVENT_FUNCTION_ARN": { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + } + } + }, + "Handler": "framework.onEvent", + "Runtime": "nodejs14.x", + "Timeout": 900 + }, + "DependsOn": [ + "UserProviderframeworkonEventServiceRoleDefaultPolicy9A9E044F", + "UserProviderframeworkonEventServiceRole8FBA2FBD" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserFDDCDD17": { + "Type": "Custom::RedshiftDatabaseQuery", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": ["UserProviderframeworkonEvent4EC32885", "Arn"] + }, + "handler": "user", + "clusterName": { + "Ref": "ClusterEB0386A7" + }, + "adminUserArn": { + "Ref": "ClusterSecretAttachment769E6258" + }, + "databaseName": "my_db", + "username": "awscdkredshiftclusterdatabaseuserc17d5ebd", + "passwordSecretArn": { + "Ref": "UserSecretAttachment02022609" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A": { + "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" + ] + ] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserTablePrivilegesProviderframeworkonEventServiceRoleDefaultPolicy3B6EF50C": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + }, + ":*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "UserTablePrivilegesProviderframeworkonEventServiceRoleDefaultPolicy3B6EF50C", + "Roles": [ + { + "Ref": "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserTablePrivilegesProviderframeworkonEvent3F5C1851": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "a8a62b989c7866e3ad5b24f3eb6228f8ca91ebff5f5c76f1da466f6c805c0585.zip" + }, + "Role": { + "Fn::GetAtt": [ + "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A", + "Arn" + ] + }, + "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-redshift-cluster-database/User/TablePrivileges/Resource/Provider)", + "Environment": { + "Variables": { + "USER_ON_EVENT_FUNCTION_ARN": { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + } + } + }, + "Handler": "framework.onEvent", + "Runtime": "nodejs14.x", + "Timeout": 900 + }, + "DependsOn": [ + "UserTablePrivilegesProviderframeworkonEventServiceRoleDefaultPolicy3B6EF50C", + "UserTablePrivilegesProviderframeworkonEventServiceRole56BAEC9A" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "UserTablePrivileges3829D614": { + "Type": "Custom::RedshiftDatabaseQuery", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "UserTablePrivilegesProviderframeworkonEvent3F5C1851", + "Arn" + ] + }, + "handler": "user-table-privileges", + "clusterName": { + "Ref": "ClusterEB0386A7" + }, + "adminUserArn": { + "Ref": "ClusterSecretAttachment769E6258" + }, + "databaseName": "my_db", + "username": { + "Fn::GetAtt": ["UserFDDCDD17", "username"] + }, + "tablePrivileges": [ + { + "tableName": { + "Ref": "Table7ABB320E" + }, + "actions": ["INSERT", "DELETE", "SELECT"] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717": { + "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" + ] + ] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRoleDefaultPolicyDDD1388D": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "redshift-data:DescribeStatement", + "redshift-data:ExecuteStatement" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:GetSecretValue" + ], + "Effect": "Allow", + "Resource": [ + { + "Ref": "ClusterSecretAttachment769E6258" + }, + { + "Ref": "UserSecretAttachment02022609" + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRoleDefaultPolicyDDD1388D", + "Roles": [ + { + "Ref": "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "169a8c0beb97c903ee155ea9653e39b0884c9e3b860ac72ffbe906b3c1f4e338.zip" + }, + "Role": { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x", + "Timeout": 60 + }, + "DependsOn": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRoleDefaultPolicyDDD1388D", + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5fServiceRole0A90D717" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "TableProviderframeworkonEventServiceRoleC3128F67": { + "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" + ] + ] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "TableProviderframeworkonEventServiceRoleDefaultPolicyAD08715D": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + }, + ":*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TableProviderframeworkonEventServiceRoleDefaultPolicyAD08715D", + "Roles": [ + { + "Ref": "TableProviderframeworkonEventServiceRoleC3128F67" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "TableProviderframeworkonEvent97F3951A": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "a8a62b989c7866e3ad5b24f3eb6228f8ca91ebff5f5c76f1da466f6c805c0585.zip" + }, + "Role": { + "Fn::GetAtt": [ + "TableProviderframeworkonEventServiceRoleC3128F67", + "Arn" + ] + }, + "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-redshift-cluster-database/Table/Resource/Provider)", + "Environment": { + "Variables": { + "USER_ON_EVENT_FUNCTION_ARN": { + "Fn::GetAtt": [ + "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", + "Arn" + ] + } + } + }, + "Handler": "framework.onEvent", + "Runtime": "nodejs14.x", + "Timeout": 900 + }, + "DependsOn": [ + "TableProviderframeworkonEventServiceRoleDefaultPolicyAD08715D", + "TableProviderframeworkonEventServiceRoleC3128F67" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Table7ABB320E": { + "Type": "Custom::RedshiftDatabaseQuery", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": ["TableProviderframeworkonEvent97F3951A", "Arn"] + }, + "handler": "table", + "clusterName": { + "Ref": "ClusterEB0386A7" + }, + "adminUserArn": { + "Ref": "ClusterSecretAttachment769E6258" + }, + "databaseName": "my_db", + "tableName": { + "prefix": "awscdkredshiftclusterdatabaseTable24923533", + "generateSuffix": "true" + }, + "tableColumns": [ + { + "name": "col1", + "dataType": "varchar(4)", + "distKey": true, + "comment": "A test column", + "encoding": "LZO" + }, + { + "name": "col2", + "dataType": "float", + "sortKey": true, + "comment": "A test column" + }, + { + "name": "col3", + "dataType": "float", + "comment": "A test column", + "encoding": "RAW" + } + ], + "distStyle": "KEY", + "sortStyle": "INTERLEAVED", + "tableComment": "A test table", + "useColumnIds": true + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } }, - "TableProviderframeworkonEvent97F3951A": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "a8a62b989c7866e3ad5b24f3eb6228f8ca91ebff5f5c76f1da466f6c805c0585.zip" - }, - "Role": { - "Fn::GetAtt": [ - "TableProviderframeworkonEventServiceRoleC3128F67", - "Arn" - ] - }, - "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-redshift-cluster-database/Table/Resource/Provider)", - "Environment": { - "Variables": { - "USER_ON_EVENT_FUNCTION_ARN": { - "Fn::GetAtt": [ - "QueryRedshiftDatabase3de5bea727da479686625efb56431b5f3DF81997", - "Arn" - ] - } - } - }, - "Handler": "framework.onEvent", - "Runtime": "nodejs14.x", - "Timeout": 900 - }, - "DependsOn": [ - "TableProviderframeworkonEventServiceRoleDefaultPolicyAD08715D", - "TableProviderframeworkonEventServiceRoleC3128F67" - ], - "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]" + } }, - "Table7ABB320E": { - "Type": "Custom::RedshiftDatabaseQuery", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "TableProviderframeworkonEvent97F3951A", - "Arn" - ] - }, - "handler": "table", - "clusterName": { - "Ref": "ClusterEB0386A7" - }, - "adminUserArn": { - "Ref": "ClusterSecretAttachment769E6258" - }, - "databaseName": "my_db", - "tableName": { - "prefix": "awscdkredshiftclusterdatabaseTable24923533", - "generateSuffix": "true" - }, - "tableColumns": [ - { - "name": "col1", - "dataType": "varchar(4)", - "distKey": true - }, - { - "name": "col2", - "dataType": "float", - "sortKey": true - }, - { - "name": "col3", - "dataType": "float", - "sortKey": true - } - ], - "distStyle": "KEY", - "sortStyle": "INTERLEAVED", - "tableComment": "A test table", - "useColumnIds": true - }, - "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" - } - ] - } + "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." + } ] - }, - "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-redshift/test/integ.database.js.snapshot/cdk.out b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/cdk.out index b72fef144f05c..22aff0ee1a3eb 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"30.1.0"} \ No newline at end of file +{"version":"30.1.0"} diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/integ.json b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/integ.json index 43c7d308e429c..f38ac471f573e 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/integ.json @@ -2,11 +2,9 @@ "version": "30.1.0", "testCases": { "redshift-cluster-database-integ/DefaultTest": { - "stacks": [ - "aws-cdk-redshift-cluster-database" - ], + "stacks": ["aws-cdk-redshift-cluster-database"], "assertionStack": "redshift-cluster-database-integ/DefaultTest/DeployAssert", "assertionStackName": "redshiftclusterdatabaseintegDefaultTestDeployAssert4339FB48" } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/manifest.json b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/manifest.json index 839bb7d0a2ea1..371f1970d61c0 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/manifest.json @@ -20,18 +20,14 @@ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/297bfa1758edc6b71a084153702165132d111eb7914b4bf8ed951da4b98faede.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", - "additionalDependencies": [ - "aws-cdk-redshift-cluster-database.assets" - ], + "additionalDependencies": ["aws-cdk-redshift-cluster-database.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-redshift-cluster-database.assets" - ], + "dependencies": ["aws-cdk-redshift-cluster-database.assets"], "metadata": { "/aws-cdk-redshift-cluster-database/custom-kms-key/Resource": [ { @@ -384,4 +380,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/redshiftclusterdatabaseintegDefaultTestDeployAssert4339FB48.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/redshiftclusterdatabaseintegDefaultTestDeployAssert4339FB48.assets.json index a21d912bf150e..76d14311f460d 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/redshiftclusterdatabaseintegDefaultTestDeployAssert4339FB48.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/redshiftclusterdatabaseintegDefaultTestDeployAssert4339FB48.assets.json @@ -16,4 +16,4 @@ } }, "dockerImages": {} -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/tree.json b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/tree.json index 0b2213b1b8f64..1a18995b967cc 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.js.snapshot/tree.json @@ -2001,4 +2001,4 @@ "version": "0.0.0" } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.ts b/packages/@aws-cdk/aws-redshift/test/integ.database.ts index be9ce4b65a60f..1474e8811d459 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.ts +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.ts @@ -48,9 +48,9 @@ const user = new redshift.User(stack, 'User', databaseOptions); const table = new redshift.Table(stack, 'Table', { ...databaseOptions, tableColumns: [ - { name: 'col1', dataType: 'varchar(4)', distKey: true }, - { name: 'col2', dataType: 'float', sortKey: true }, - { name: 'col3', dataType: 'float', sortKey: true }, + { name: 'col1', dataType: 'varchar(4)', distKey: true, comment: 'A test column', encoding: redshift.ColumnEncoding.LZO }, + { name: 'col2', dataType: 'float', sortKey: true, comment: 'A test column' }, + { name: 'col3', dataType: 'float', comment: 'A test column', encoding: redshift.ColumnEncoding.RAW }, ], distStyle: redshift.TableDistStyle.KEY, sortStyle: redshift.TableSortStyle.INTERLEAVED, From e39bdea5c820e377ebb5760ec2b15e187939f4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=A7=91=F0=9F=8F=BB=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier?= Date: Wed, 8 Mar 2023 10:06:56 +0100 Subject: [PATCH 14/22] chore: further increase logging in CLI integ test --- packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts | 8 +++++--- packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts | 5 +++-- packages/aws-cdk/test/integ/cli/test.sh | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts b/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts index 7c8611e45bf21..1eb8a78242db0 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts @@ -35,8 +35,9 @@ export function integTest( output.write(`${name}\n`); output.write('================================================================\n'); + const now = Date.now(); + process.stderr.write(`[INTEG TEST::${name}] Starting (pid ${process.pid})...\n`); try { - process.stderr.write(`▶️ [INTEG TEST::${name}] Starting...\n`); return await callback({ output, randomString: randomString(), @@ -45,7 +46,7 @@ export function integTest( }, }); } catch (e) { - process.stderr.write(`💥 [INTEG TEST::${name}] Failed: ${e}\n`); + process.stderr.write(`[INTEG TEST::${name}] Failed: ${e}\n`); output.write(e.message); output.write(e.stack); // Print output only if the test fails. Use 'console.log' so the output is buffered by @@ -54,7 +55,8 @@ export function integTest( console.log(output.buffer().toString()); throw e; } finally { - process.stderr.write(`⏹️ [INTEG TEST::${name}] Done.\n`); + const duration = Date.now() - now; + process.stderr.write(`[INTEG TEST::${name}] Done (${duration} ms).\n`); } }, timeoutMillis); } diff --git a/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts b/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts index 58c39e0364797..43214cc88acd5 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts @@ -87,14 +87,15 @@ export class ResourcePool { private makeLease(value: A): ILease { let disposed = false; + process.stderr.write(`Lease acquired by ${process.pid}: ${value}`); return { value, - dispose: () => { + dispose: async () => { if (disposed) { throw new Error('Calling dispose() on an already-disposed lease.'); } disposed = true; - return this.returnValue(value); + return this.returnValue(value).finally(() => process.stderr.write(`Lease returned by ${process.pid}: ${value}`)); }, }; } diff --git a/packages/aws-cdk/test/integ/cli/test.sh b/packages/aws-cdk/test/integ/cli/test.sh index 1d33ee1502bbd..0f435e3439c77 100755 --- a/packages/aws-cdk/test/integ/cli/test.sh +++ b/packages/aws-cdk/test/integ/cli/test.sh @@ -3,4 +3,4 @@ set -eu # This is a backwards compatibility script. All logic has moved to '@aws-cdk-testing/cli-integ' # and should be called from there directly. -exec ${INTEG_TOOLS}/bin/run-suite --use-cli-release=$VERSION cli-integ-tests +exec ${INTEG_TOOLS}/bin/run-suite --use-cli-release=$VERSION --verbose cli-integ-tests From 9237a7a26180eca0caba5887f05456557b4b595b Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Wed, 8 Mar 2023 11:44:07 +0100 Subject: [PATCH 15/22] chore(cli-integ): add per-test timeouts (#24504) We couldn't use the jest timeout feature for our integration tests, and ended up running without timeouts. This made it EXTREMELY hard to debug an issue where the tests ended up not finishing, and not producing any output to indicate why. Re-add the ability to have timeouts on test, and set a timeout of 10 minutes on all of them. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cli-integ/lib/resource-pool.ts | 3 +- .../cli-integ/lib/with-cdk-app.ts | 5 ++- .../cli-integ/lib/with-sam.ts | 5 +-- .../cli-integ/lib/with-timeout.ts | 33 +++++++++++++++++++ .../cli-integ/test/resource-pool.test.ts | 2 +- 5 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 packages/@aws-cdk-testing/cli-integ/lib/with-timeout.ts diff --git a/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts b/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts index 43214cc88acd5..677500226b6d2 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/resource-pool.ts @@ -87,7 +87,6 @@ export class ResourcePool { private makeLease(value: A): ILease { let disposed = false; - process.stderr.write(`Lease acquired by ${process.pid}: ${value}`); return { value, dispose: async () => { @@ -95,7 +94,7 @@ export class ResourcePool { throw new Error('Calling dispose() on an already-disposed lease.'); } disposed = true; - return this.returnValue(value).finally(() => process.stderr.write(`Lease returned by ${process.pid}: ${value}`)); + return this.returnValue(value); }, }; } diff --git a/packages/@aws-cdk-testing/cli-integ/lib/with-cdk-app.ts b/packages/@aws-cdk-testing/cli-integ/lib/with-cdk-app.ts index 8561a87915546..38bcbea166c2b 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/with-cdk-app.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/with-cdk-app.ts @@ -9,6 +9,9 @@ import { packageSourceInSubprocess } from './package-sources/subprocess'; import { RESOURCES_DIR } from './resources'; import { shell, ShellOptions, ShellHelper, rimraf } from './shell'; import { AwsContext, withAws } from './with-aws'; +import { withTimeout } from './with-timeout'; + +export const DEFAULT_TEST_TIMEOUT_S = 10 * 60; /** * Higher order function to execute a block with a CDK app fixture @@ -135,7 +138,7 @@ export function withMonolithicCfnIncludeCdkApp(block: (co * test declaration but centralizing it is going to make it convenient to modify in the future. */ export function withDefaultFixture(block: (context: TestFixture) => Promise) { - return withAws(withCdkApp(block)); + return withAws(withTimeout(DEFAULT_TEST_TIMEOUT_S, withCdkApp(block))); } export interface DisableBootstrapContext { diff --git a/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts b/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts index c2419cc69f832..fe77b9499b8af 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts @@ -7,7 +7,8 @@ import { TestContext } from './integ-test'; import { RESOURCES_DIR } from './resources'; import { ShellOptions, rimraf } from './shell'; import { AwsContext, withAws } from './with-aws'; -import { cloneDirectory, installNpmPackages, TestFixture } from './with-cdk-app'; +import { cloneDirectory, installNpmPackages, TestFixture, DEFAULT_TEST_TIMEOUT_S } from './with-cdk-app'; +import { withTimeout } from './with-timeout'; export interface ActionOutput { @@ -113,7 +114,7 @@ function errorCausedByGoPkg(error: string) { * SAM Integration test fixture for CDK - SAM integration test cases */ export function withSamIntegrationFixture(block: (context: SamIntegrationTestFixture) => Promise) { - return withAws(withSamIntegrationCdkApp(block)); + return withAws(withTimeout(DEFAULT_TEST_TIMEOUT_S, withSamIntegrationCdkApp(block))); } export class SamIntegrationTestFixture extends TestFixture { diff --git a/packages/@aws-cdk-testing/cli-integ/lib/with-timeout.ts b/packages/@aws-cdk-testing/cli-integ/lib/with-timeout.ts new file mode 100644 index 0000000000000..1ffb1eced188f --- /dev/null +++ b/packages/@aws-cdk-testing/cli-integ/lib/with-timeout.ts @@ -0,0 +1,33 @@ +/** + * Run a block with a timeout + * + * We can't use the jest timeout feature: + * + * - `jest.concurrent()` does not do any concurrency management. It starts all + * tests at the same time. + * - Our tests use locking to make sure only one test is running at a time per + * region. + * + * The wait time for the locks is included in the jest test timeout. We therefore + * need to set it unreasonably high (as long as the last test may need to wait + * if all tests are executed using only 1 region, and they effectively execute + * sequentially), which makes it not useful to detect stuck tests. + * + * The `withTimeout()` modifier makes it possible to measure only a specific + * block of code. In our case: the effective test code, excluding the wait time. + */ +export function withTimeout(seconds: number, block: (x: A) => Promise) { + return (x: A) => { + const timeOut = new Promise((_ok, ko) => { + const timerHandle = setTimeout( + () => ko(new Error(`Timeout: test took more than ${seconds}s to complete`)), + seconds * 1000); + timerHandle.unref(); + }); + + return Promise.race([ + block(x), + timeOut, + ]); + }; +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/cli-integ/test/resource-pool.test.ts b/packages/@aws-cdk-testing/cli-integ/test/resource-pool.test.ts index 18f153778bb5f..02a2c3d6c4feb 100644 --- a/packages/@aws-cdk-testing/cli-integ/test/resource-pool.test.ts +++ b/packages/@aws-cdk-testing/cli-integ/test/resource-pool.test.ts @@ -32,7 +32,7 @@ test('double dispose throws', async () => { const lease = await pool.take(); await lease.dispose(); - expect(() => lease.dispose()).toThrow(); + await expect(() => lease.dispose()).rejects.toThrow(); }); test('somewhat balance', async () => { From 7be906867da224d595be956f6a7b7e099db7a1fb Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Wed, 8 Mar 2023 13:04:50 +0100 Subject: [PATCH 16/22] chore: remove parentheses in 'sam local start-api' filter (#24508) The dependencies in v1.76.0+ of the SAM CLI no longer contain parenthesis in the output, making the trigger wait forever --- .../cli-integ/lib/with-sam.ts | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts b/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts index fe77b9499b8af..125777a7c24ee 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/with-sam.ts @@ -140,7 +140,7 @@ export class SamIntegrationTestFixture extends TestFixture { args.push('--port'); args.push(port.toString()); - return this.samShell(['sam', 'local', 'start-api', ...args], '(Press CTRL+C to quit)', ()=>{ + return this.samShell(['sam', 'local', 'start-api', ...args], 'Press CTRL+C to quit', ()=>{ return new Promise((resolve, reject) => { axios.get(`http://127.0.0.1:${port}${apiPath}`).then( resp => { resolve(resp.data); @@ -173,7 +173,12 @@ export function randomInteger(min: number, max: number) { * Is platform-aware, handles errors nicely. */ export async function shellWithAction( - command: string[], filter?: string, action?: () => Promise, options: ShellOptions = {}): Promise { + command: string[], + filter?: string, + action?: () => Promise, + options: ShellOptions = {}, + actionTimeoutSeconds: number = 600, +): Promise { if (options.modEnv && options.env) { throw new Error('Use either env or modEnv but not both'); } @@ -199,8 +204,8 @@ export async function shellWithAction( let actionExecuted = false; function executeAction(chunk: any) { - out.push(chunk); - if (!actionExecuted && typeof filter === 'string' && out.toString().includes(filter) && typeof action === 'function') { + out.push(Buffer.from(chunk)); + if (!actionExecuted && typeof filter === 'string' && Buffer.concat(out).toString('utf-8').includes(filter) && typeof action === 'function') { actionExecuted = true; options.output?.write('before executing action'); action().then((output) => { @@ -218,6 +223,18 @@ export async function shellWithAction( } } + if (typeof filter === 'string' && typeof action === 'function') { + // Reject with an error if an action is configured, but the filter failed + // to show up in the output before the timeout occurred. + setTimeout( + () => { + if (!actionExecuted) { + reject(new Error(`Timed out waiting for filter ${JSON.stringify(filter)} to appear in command output after ${actionTimeoutSeconds} seconds\nOutput so far:\n${Buffer.concat(out).toString('utf-8')}`)); + } + }, actionTimeoutSeconds * 1_000, + ).unref(); + } + child.stdout!.on('data', chunk => { options.output?.write(chunk); stdout.push(chunk); From 21aa42144548099cac9b9dcd03ea842c01cddb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=A7=91=F0=9F=8F=BB=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier?= Date: Wed, 8 Mar 2023 14:21:37 +0100 Subject: [PATCH 17/22] chore: print message if tests run concurrently --- packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts b/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts index 1eb8a78242db0..0b0b5130d7041 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts @@ -10,6 +10,10 @@ export interface TestContext { log(s: string): void; }; +if (process.env.JEST_TEST_CONCURRENT === 'true') { + process.stderr.write('ℹ️ JEST_TEST_CONCURRENT is true: tests will run concurrently and filters have no effect!'); +} + /** * A wrapper for jest's 'test' which takes regression-disabled tests into account and prints a banner */ @@ -18,7 +22,6 @@ export function integTest( callback: (context: TestContext) => Promise, timeoutMillis?: number, ): void { - // Integ tests can run concurrently, and are responsible for blocking // themselves if they cannot. Because `test.concurrent` executes the test // code immediately, regardles of any `--testNamePattern`, this cannot be the From 527dcbba725c7e3dc6f2aafdf3384576e7c7175d Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Wed, 8 Mar 2023 14:09:43 +0000 Subject: [PATCH 18/22] chore(release): 2.68.0 --- CHANGELOG.v2.alpha.md | 20 ++++++++++++++++++++ CHANGELOG.v2.md | 12 ++++++++++++ packages/@aws-cdk/cx-api/FEATURE_FLAGS.md | 4 ++-- packages/@aws-cdk/cx-api/lib/features.ts | 2 +- version.v2.json | 4 ++-- 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.v2.alpha.md b/CHANGELOG.v2.alpha.md index 904d905436fab..e4df9ed280b0b 100644 --- a/CHANGELOG.v2.alpha.md +++ b/CHANGELOG.v2.alpha.md @@ -2,6 +2,26 @@ 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.68.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.67.0-alpha.0...v2.68.0-alpha.0) (2023-03-08) + + +### ⚠ BREAKING CHANGES TO EXPERIMENTAL FEATURES + +* **servicecatalogappregistry:** This commit contains destructive changes to the RAM Share. +Since the application RAM share name is calculated by the application construct, where one property is removed. Integration test detects a breaking change where RAM share will be created. Integration test snapshot is updated to cater this destructive change. + +### Features + +* **msk:** add Kafka version 3.3.2 ([#24440](https://github.com/aws/aws-cdk/issues/24440)) ([1b2014e](https://github.com/aws/aws-cdk/commit/1b2014eef9e3f2190b2cce79c55f635cc1f167e3)), closes [#24432](https://github.com/aws/aws-cdk/issues/24432) +* **redshift:** column compression encodings and comments can now be customised ([#24177](https://github.com/aws/aws-cdk/issues/24177)) ([1ca3e00](https://github.com/aws/aws-cdk/commit/1ca3e0027323e84aacade4d9bd058bbc5687a7ab)), closes [#24165](https://github.com/aws/aws-cdk/issues/24165) [#23597](https://github.com/aws/aws-cdk/issues/23597) [#22506](https://github.com/aws/aws-cdk/issues/22506) +* **redshift:** columns require an id attribute (under feature flag) ([#24272](https://github.com/aws/aws-cdk/issues/24272)) ([9a07ab0](https://github.com/aws/aws-cdk/commit/9a07ab008d1b6d23e9a302921f1a5165a21fb128)), closes [#24234](https://github.com/aws/aws-cdk/issues/24234) + + +### Bug Fixes + +* **servicecatalogappregistry:** allow disabling automatic CfnOutput ([#24483](https://github.com/aws/aws-cdk/issues/24483)) ([3db1a0d](https://github.com/aws/aws-cdk/commit/3db1a0d0bcf615871a225919eed235b78904e144)), closes [#23779](https://github.com/aws/aws-cdk/issues/23779) +* **servicecatalogappregistry:** Associate an application with attribute group ([#24378](https://github.com/aws/aws-cdk/issues/24378)) ([d1264c1](https://github.com/aws/aws-cdk/commit/d1264c1c414257fb8dd5288fdc24cfe9605cdf90)) + ## [2.67.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.66.1-alpha.0...v2.67.0-alpha.0) (2023-03-02) diff --git a/CHANGELOG.v2.md b/CHANGELOG.v2.md index 31967bb1f4ebf..c82c84244e08b 100644 --- a/CHANGELOG.v2.md +++ b/CHANGELOG.v2.md @@ -2,6 +2,18 @@ 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.68.0](https://github.com/aws/aws-cdk/compare/v2.67.0...v2.68.0) (2023-03-08) + + +### Bug Fixes + +* **apprunner-alpha:** env vars and secrets can't solely be added via .add*() methods ([#24346](https://github.com/aws/aws-cdk/issues/24346)) ([45195b6](https://github.com/aws/aws-cdk/commit/45195b6f2e5162eaa795d3a412d89dd09680aa8b)), closes [#24345](https://github.com/aws/aws-cdk/issues/24345) +* **cli:** cannot `cdk import` resources with multiple identifiers ([#24439](https://github.com/aws/aws-cdk/issues/24439)) ([a70ff1a](https://github.com/aws/aws-cdk/commit/a70ff1ad332af780c052e3117b73df060deee7ae)), closes [#20895](https://github.com/aws/aws-cdk/issues/20895) +* **core:** Fix dotnet version check to allow .NET 7.0 ([#24467](https://github.com/aws/aws-cdk/issues/24467)) ([a4856e9](https://github.com/aws/aws-cdk/commit/a4856e997684f84476fe92e00afcd4da76a69b04)), closes [#24466](https://github.com/aws/aws-cdk/issues/24466) +* **lambda-nodejs:** esbuild preCompilation tsconfig precedence is wrong ([#23871](https://github.com/aws/aws-cdk/issues/23871)) ([790a709](https://github.com/aws/aws-cdk/commit/790a709d758333f4622c5fb860d9bbb48dee7106)) +* **lambda-nodejs:** Required auto prefix of `handler` with `index.` breaks custom non-`index` handler settings used by layers ([#24406](https://github.com/aws/aws-cdk/issues/24406)) ([d7a1c34](https://github.com/aws/aws-cdk/commit/d7a1c34e540e12413319918a5d807060057a1a1b)), closes [#24403](https://github.com/aws/aws-cdk/issues/24403) +* **rds:** add clusterResourceIdentifier property to database cluster ([#23605](https://github.com/aws/aws-cdk/issues/23605)) ([6bda4e5](https://github.com/aws/aws-cdk/commit/6bda4e5ae4205a917a00714433f136550c59e409)) + ## [2.67.0](https://github.com/aws/aws-cdk/compare/v2.66.1...v2.67.0) (2023-03-02) diff --git a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md index 7e95b2872ed35..8506abc1ca20d 100644 --- a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md +++ b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md @@ -48,7 +48,7 @@ Flags come in three types: | [@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId](#aws-cdkaws-apigatewayauthorizerchangedeploymentlogicalid) | Include authorizer configuration in the calculation of the API deployment logical ID. | 2.66.0 | (fix) | | [@aws-cdk/aws-ec2:launchTemplateDefaultUserData](#aws-cdkaws-ec2launchtemplatedefaultuserdata) | Define user data for a launch template by default when a machine image is provided. | 2.67.0 | (fix) | | [@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments](#aws-cdkaws-secretsmanageruseattachedsecretresourcepolicyforsecrettargetattachments) | SecretTargetAttachments uses the ResourcePolicy of the attached Secret. | 2.67.0 | (fix) | -| [@aws-cdk/aws-redshift:columnId](#aws-cdkaws-redshiftcolumnid) | Whether to use an ID to track Redshift column changes | V2NEXT | (fix) | +| [@aws-cdk/aws-redshift:columnId](#aws-cdkaws-redshiftcolumnid) | Whether to use an ID to track Redshift column changes | 2.68.0 | (fix) | @@ -897,7 +897,7 @@ of the `id`s, the `name`s of the columns can be changed without data loss. | Since | Default | Recommended | | ----- | ----- | ----- | | (not in v1) | | | -| V2NEXT | `false` | `true` | +| 2.68.0 | `false` | `true` | diff --git a/packages/@aws-cdk/cx-api/lib/features.ts b/packages/@aws-cdk/cx-api/lib/features.ts index 5eec1c99b1ad3..504abaff3e682 100644 --- a/packages/@aws-cdk/cx-api/lib/features.ts +++ b/packages/@aws-cdk/cx-api/lib/features.ts @@ -728,7 +728,7 @@ export const FLAGS: Record = { initial deployment, the columns will be dropped and recreated, causing data loss. After the initial deployment of the \`id\`s, the \`name\`s of the columns can be changed without data loss. `, - introducedIn: { v2: 'V2NEXT' }, + introducedIn: { v2: '2.68.0' }, recommendedValue: true, }, }; diff --git a/version.v2.json b/version.v2.json index c447441e598b2..06ff472538194 100644 --- a/version.v2.json +++ b/version.v2.json @@ -1,4 +1,4 @@ { - "version": "2.67.0", - "alphaVersion": "2.67.0-alpha.0" + "version": "2.68.0", + "alphaVersion": "2.68.0-alpha.0" } \ No newline at end of file From 4e02566fab0f6c6708c9ee766e2805adbb329f18 Mon Sep 17 00:00:00 2001 From: Richard Simpson Date: Wed, 8 Mar 2023 13:59:56 -0600 Subject: [PATCH 19/22] feat(ecr-assets): Support cache-from and cache-to flags (#24024) This adds the `--cache-from` and `--cache-to` flag options. --- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md?rgh-link-date=2022-12-09T23%3A48%3A14Z) ### 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/?rgh-link-date=2022-12-09T23%3A48%3A14Z#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?rgh-link-date=2022-12-09T23%3A48%3A14Z)? * [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-ecr-assets/README.md | 12 +++ .../aws-ecr-assets/lib/image-asset.ts | 54 ++++++++++++ .../test/build-image-cache.test.ts | 88 +++++++++++++++++++ .../integ-assets-docker.template.json | 5 ++ .../integ.assets-docker.js.snapshot/tree.json | 4 +- .../test/integ.assets-docker.ts | 7 ++ .../lib/assets/docker-image-asset.ts | 38 ++++++++ .../lib/cloud-assembly/metadata-schema.ts | 38 ++++++++ .../schema/assets.schema.json | 31 +++++++ .../schema/cloud-assembly.schema.json | 31 +++++++ .../schema/cloud-assembly.version.json | 4 +- packages/@aws-cdk/core/lib/assets.ts | 34 +++++++ .../asset-manifest-builder.ts | 2 + .../core/lib/stack-synthesizers/legacy.ts | 2 + packages/@aws-cdk/cx-api/lib/assets.ts | 2 + packages/cdk-assets/lib/private/docker.ts | 17 ++++ .../lib/private/handlers/container-images.ts | 2 + 17 files changed, 366 insertions(+), 5 deletions(-) create mode 100644 packages/@aws-cdk/aws-ecr-assets/test/build-image-cache.test.ts diff --git a/packages/@aws-cdk/aws-ecr-assets/README.md b/packages/@aws-cdk/aws-ecr-assets/README.md index 32059529f1ee1..26c3963afbe05 100644 --- a/packages/@aws-cdk/aws-ecr-assets/README.md +++ b/packages/@aws-cdk/aws-ecr-assets/README.md @@ -121,6 +121,18 @@ const asset = new DockerImageAsset(this, 'MyBuildImage', { }) ``` +You can optionally pass cache from and cache to options to cache images: + +```ts +import { DockerImageAsset, Platform } from '@aws-cdk/aws-ecr-assets'; + +const asset = new DockerImageAsset(this, 'MyBuildImage', { + directory: path.join(__dirname, 'my-image'), + cacheFrom: [{ type: 'registry', params: { ref: 'ghcr.io/myorg/myimage:cache' }}], + cacheTo: { type: 'registry', params: { ref: 'ghcr.io/myorg/myimage:cache', mode: 'max', compression: 'zstd' }} +}) +``` + ## Images from Tarball Images are loaded from a local tarball, uploaded to ECR by the CDK toolkit and/or your app's CI-CD pipeline, and can be diff --git a/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts b/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts index da03e18f80046..49e93ff47bbfb 100644 --- a/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts +++ b/packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts @@ -148,6 +148,28 @@ export interface DockerImageAssetInvalidationOptions { readonly outputs?: boolean; } +/** + * Options for configuring the Docker cache backend + */ +export interface DockerCacheOption { + /** + * The type of cache to use. + * Refer to https://docs.docker.com/build/cache/backends/ for full list of backends. + * @default - unspecified + * + * @example 'registry' + */ + readonly type: string; + /** + * Any parameters to pass into the docker cache backend configuration. + * Refer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. + * @default {} No options provided + * + * @example { ref: `12345678.dkr.ecr.us-west-2.amazonaws.com/cache:${branch}`, mode: "max" } + */ + readonly params?: { [key: string]: string }; +} + /** * Options for DockerImageAsset */ @@ -236,6 +258,22 @@ export interface DockerImageAssetOptions extends FingerprintOptions, FileFingerp * @see https://docs.docker.com/engine/reference/commandline/build/#custom-build-outputs */ readonly outputs?: string[]; + + /** + * Cache from options to pass to the `docker build` command. + * + * @default - no cache from options are passed to the build command + * @see https://docs.docker.com/build/cache/backends/ + */ + readonly cacheFrom?: DockerCacheOption[]; + + /** + * Cache to options to pass to the `docker build` command. + * + * @default - no cache to options are passed to the build command + * @see https://docs.docker.com/build/cache/backends/ + */ + readonly cacheTo?: DockerCacheOption; } /** @@ -316,6 +354,16 @@ export class DockerImageAsset extends Construct implements IAsset { */ private readonly dockerOutputs?: string[]; + /** + * Cache from options to pass to the `docker build` command. + */ + private readonly dockerCacheFrom?: DockerCacheOption[]; + + /** + * Cache to options to pass to the `docker build` command. + */ + private readonly dockerCacheTo?: DockerCacheOption; + /** * Docker target to build to */ @@ -407,6 +455,8 @@ export class DockerImageAsset extends Construct implements IAsset { this.dockerBuildSecrets = props.buildSecrets; this.dockerBuildTarget = props.target; this.dockerOutputs = props.outputs; + this.dockerCacheFrom = props.cacheFrom; + this.dockerCacheTo = props.cacheTo; const location = stack.synthesizer.addDockerImageAsset({ directoryName: this.assetPath, @@ -418,6 +468,8 @@ export class DockerImageAsset extends Construct implements IAsset { networkMode: props.networkMode?.mode, platform: props.platform?.platform, dockerOutputs: this.dockerOutputs, + dockerCacheFrom: this.dockerCacheFrom, + dockerCacheTo: this.dockerCacheTo, }); this.repository = ecr.Repository.fromRepositoryName(this, 'Repository', location.repositoryName); @@ -456,6 +508,8 @@ export class DockerImageAsset extends Construct implements IAsset { resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_BUILD_TARGET_KEY] = this.dockerBuildTarget; resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY] = resourceProperty; resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_OUTPUTS_KEY] = this.dockerOutputs; + resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_CACHE_FROM_KEY] = this.dockerCacheFrom; + resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_CACHE_TO_KEY] = this.dockerCacheTo; } } diff --git a/packages/@aws-cdk/aws-ecr-assets/test/build-image-cache.test.ts b/packages/@aws-cdk/aws-ecr-assets/test/build-image-cache.test.ts new file mode 100644 index 0000000000000..e50c41c4c6f95 --- /dev/null +++ b/packages/@aws-cdk/aws-ecr-assets/test/build-image-cache.test.ts @@ -0,0 +1,88 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { AssetManifest } from '@aws-cdk/cloud-assembly-schema'; +import { App, Stack } from '@aws-cdk/core'; +import { AssetManifestArtifact, CloudArtifact, CloudAssembly } from '@aws-cdk/cx-api'; +import { DockerImageAsset } from '../lib'; + +describe('build cache', () => { + test('manifest contains cache from options ', () => { + // GIVEN + const app = new App(); + const stack = new Stack(app); + const asset = new DockerImageAsset(stack, 'DockerImage6', { + directory: path.join(__dirname, 'demo-image'), + cacheFrom: [{ type: 'registry', params: { image: 'foo' } }], + }); + + // WHEN + const asm = app.synth(); + + // THEN + const manifestArtifact = getAssetManifest(asm); + const manifest = readAssetManifest(manifestArtifact); + + expect(Object.keys(manifest.dockerImages ?? {}).length).toBe(1); + expect(manifest.dockerImages?.[asset.assetHash]?.source.cacheFrom?.length).toBe(1); + expect(manifest.dockerImages?.[asset.assetHash]?.source.cacheFrom?.[0]).toStrictEqual({ + type: 'registry', + params: { image: 'foo' }, + }); + }); + test('manifest contains cache to options ', () => { + // GIVEN + const app = new App(); + const stack = new Stack(app); + const asset = new DockerImageAsset(stack, 'DockerImage6', { + directory: path.join(__dirname, 'demo-image'), + cacheTo: { type: 'inline' }, + }); + + // WHEN + const asm = app.synth(); + + // THEN + const manifestArtifact = getAssetManifest(asm); + const manifest = readAssetManifest(manifestArtifact); + + expect(Object.keys(manifest.dockerImages ?? {}).length).toBe(1); + expect(manifest.dockerImages?.[asset.assetHash]?.source.cacheTo).toStrictEqual({ + type: 'inline', + }); + }); + + test('manifest does not contain options when not specified', () => { + // GIVEN + const app = new App(); + const stack = new Stack(app); + const asset = new DockerImageAsset(stack, 'DockerImage6', { + directory: path.join(__dirname, 'demo-image'), + }); + + // WHEN + const asm = app.synth(); + + // THEN + const manifestArtifact = getAssetManifest(asm); + const manifest = readAssetManifest(manifestArtifact); + expect(Object.keys(manifest.dockerImages ?? {}).length).toBe(1); + expect(manifest.dockerImages?.[asset.assetHash]?.source.cacheFrom).toBeUndefined(); + expect(manifest.dockerImages?.[asset.assetHash]?.source.cacheTo).toBeUndefined(); + }); +}); + +function isAssetManifest(x: CloudArtifact): x is AssetManifestArtifact { + return x instanceof AssetManifestArtifact; +} + +function getAssetManifest(asm: CloudAssembly): AssetManifestArtifact { + const manifestArtifact = asm.artifacts.filter(isAssetManifest)[0]; + if (!manifestArtifact) { + throw new Error('no asset manifest in assembly'); + } + return manifestArtifact; +} + +function readAssetManifest(manifestArtifact: AssetManifestArtifact): AssetManifest { + return JSON.parse(fs.readFileSync(manifestArtifact.file, { encoding: 'utf-8' })); +} diff --git a/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json b/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json index 8c7c033450117..ac306d4d02d70 100644 --- a/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json +++ b/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json @@ -81,6 +81,11 @@ "Value": { "Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:60dea2e16e94d1977b92fe03fa7085fea446233f1fe499702b69593438baa59f" } + }, + "ImageUri6": { + "Value": { + "Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:0a3355be12051c9984bf2b0b2bba4e6ea535968e5b6e7396449701732fe5ed14" + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json b/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json index 32988bdc52723..06c8f34bf353e 100644 --- a/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json @@ -262,8 +262,8 @@ "version": "0.0.0" } }, - "ImageUri5": { - "id": "ImageUri5", + "ImageUri4": { + "id": "ImageUri4", "path": "integ-assets-docker/ImageUri5", "constructInfo": { "fqn": "@aws-cdk/core.CfnOutput", diff --git a/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.ts b/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.ts index 702b83fe011a5..65a6f266d5a35 100644 --- a/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.ts +++ b/packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.ts @@ -31,17 +31,24 @@ const asset5 = new assets.DockerImageAsset(stack, 'DockerImage5', { }, }); +const asset6 = new assets.DockerImageAsset(stack, 'DockerImage6', { + directory: path.join(__dirname, 'demo-image'), + cacheTo: { type: 'inline' }, +}); + const user = new iam.User(stack, 'MyUser'); asset.repository.grantPull(user); asset2.repository.grantPull(user); asset3.repository.grantPull(user); asset4.repository.grantPull(user); asset5.repository.grantPull(user); +asset6.repository.grantPull(user); new cdk.CfnOutput(stack, 'ImageUri', { value: asset.imageUri }); new cdk.CfnOutput(stack, 'ImageUri2', { value: asset2.imageUri }); new cdk.CfnOutput(stack, 'ImageUri3', { value: asset3.imageUri }); new cdk.CfnOutput(stack, 'ImageUri4', { value: asset4.imageUri }); new cdk.CfnOutput(stack, 'ImageUri5', { value: asset5.imageUri }); +new cdk.CfnOutput(stack, 'ImageUri6', { value: asset6.imageUri }); app.synth(); diff --git a/packages/@aws-cdk/cloud-assembly-schema/lib/assets/docker-image-asset.ts b/packages/@aws-cdk/cloud-assembly-schema/lib/assets/docker-image-asset.ts index 809ef1c9f91f4..6224af4fb6c77 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/lib/assets/docker-image-asset.ts +++ b/packages/@aws-cdk/cloud-assembly-schema/lib/assets/docker-image-asset.ts @@ -97,6 +97,22 @@ export interface DockerImageSource { * @see https://docs.docker.com/engine/reference/commandline/build/#custom-build-outputs */ readonly dockerOutputs?: string[]; + + /** + * Cache from options to pass to the `docker build` command. + * + * @default - no cache from options are passed to the build command + * @see https://docs.docker.com/build/cache/backends/ + */ + readonly cacheFrom?: DockerCacheOption[]; + + /** + * Cache to options to pass to the `docker build` command. + * + * @default - no cache to options are passed to the build command + * @see https://docs.docker.com/build/cache/backends/ + */ + readonly cacheTo?: DockerCacheOption; } /** @@ -113,3 +129,25 @@ export interface DockerImageDestination extends AwsDestination { */ readonly imageTag: string; } + +/** + * Options for configuring the Docker cache backend + */ +export interface DockerCacheOption { + /** + * The type of cache to use. + * Refer to https://docs.docker.com/build/cache/backends/ for full list of backends. + * @default - unspecified + * + * @example 'registry' + */ + readonly type: string; + /** + * Any parameters to pass into the docker cache backend configuration. + * Refer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. + * @default {} No options provided + * + * @example { ref: `12345678.dkr.ecr.us-west-2.amazonaws.com/cache:${branch}`, mode: "max" } + */ + readonly params?: { [key: string]: string }; +} \ No newline at end of file diff --git a/packages/@aws-cdk/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts b/packages/@aws-cdk/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts index c3d4ac127a46f..bcc67298ff308 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts +++ b/packages/@aws-cdk/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts @@ -71,6 +71,28 @@ export interface Tag { readonly value: string } +/** + * Options for configuring the Docker cache backend + */ +export interface ContainerImageAssetCacheOption { + /** + * The type of cache to use. + * Refer to https://docs.docker.com/build/cache/backends/ for full list of backends. + * @default - unspecified + * + * @example 'registry' + */ + readonly type: string; + /** + * Any parameters to pass into the docker cache backend configuration. + * Refer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. + * @default {} No options provided + * + * @example { ref: `12345678.dkr.ecr.us-west-2.amazonaws.com/cache:${branch}`, mode: "max" } + */ + readonly params?: { [key: string]: string }; +} + /** * Metadata Entry spec for container images. */ @@ -160,6 +182,22 @@ export interface ContainerImageAssetMetadataEntry extends BaseAssetMetadataEntry * @see https://docs.docker.com/engine/reference/commandline/build/#custom-build-outputs */ readonly outputs?: string[]; + + /** + * Cache from options to pass to the `docker build` command. + * + * @default - no cache from options are passed to the build command + * @see https://docs.docker.com/build/cache/backends/ + */ + readonly cacheFrom?: ContainerImageAssetCacheOption[]; + + /** + * Cache to options to pass to the `docker build` command. + * + * @default - no cache to options are passed to the build command + * @see https://docs.docker.com/build/cache/backends/ + */ + readonly cacheTo?: ContainerImageAssetCacheOption; } /** diff --git a/packages/@aws-cdk/cloud-assembly-schema/schema/assets.schema.json b/packages/@aws-cdk/cloud-assembly-schema/schema/assets.schema.json index 28dea7efbf357..6e7f02037f744 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/schema/assets.schema.json +++ b/packages/@aws-cdk/cloud-assembly-schema/schema/assets.schema.json @@ -176,9 +176,40 @@ "items": { "type": "string" } + }, + "cacheFrom": { + "description": "Cache from options to pass to the `docker build` command. (Default - no cache from options are passed to the build command)", + "type": "array", + "items": { + "$ref": "#/definitions/DockerCacheOption" + } + }, + "cacheTo": { + "description": "Cache to options to pass to the `docker build` command. (Default - no cache to options are passed to the build command)", + "$ref": "#/definitions/DockerCacheOption" } } }, + "DockerCacheOption": { + "description": "Options for configuring the Docker cache backend", + "type": "object", + "properties": { + "type": { + "description": "The type of cache to use.\nRefer to https://docs.docker.com/build/cache/backends/ for full list of backends. (Default - unspecified)", + "type": "string" + }, + "params": { + "description": "Any parameters to pass into the docker cache backend configuration.\nRefer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. (Default {} No options provided)", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "type" + ] + }, "DockerImageDestination": { "description": "Where to publish docker images", "type": "object", diff --git a/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.schema.json b/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.schema.json index 92eb946bc9149..12d263bfdea2f 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.schema.json +++ b/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.schema.json @@ -248,6 +248,17 @@ "type": "string" } }, + "cacheFrom": { + "description": "Cache from options to pass to the `docker build` command. (Default - no cache from options are passed to the build command)", + "type": "array", + "items": { + "$ref": "#/definitions/ContainerImageAssetCacheOption" + } + }, + "cacheTo": { + "description": "Cache to options to pass to the `docker build` command. (Default - no cache to options are passed to the build command)", + "$ref": "#/definitions/ContainerImageAssetCacheOption" + }, "id": { "description": "Logical identifier for the asset", "type": "string" @@ -268,6 +279,26 @@ "sourceHash" ] }, + "ContainerImageAssetCacheOption": { + "description": "Options for configuring the Docker cache backend", + "type": "object", + "properties": { + "type": { + "description": "The type of cache to use.\nRefer to https://docs.docker.com/build/cache/backends/ for full list of backends. (Default - unspecified)", + "type": "string" + }, + "params": { + "description": "Any parameters to pass into the docker cache backend configuration.\nRefer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. (Default {} No options provided)", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "type" + ] + }, "Tag": { "description": "Metadata Entry spec for stack tag.", "type": "object", diff --git a/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.version.json b/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.version.json index 7233abc4c3527..0d5aff521d3a2 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.version.json +++ b/packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.version.json @@ -1,3 +1 @@ -{ - "version": "30.1.0" -} +{"version":"31.0.0"} diff --git a/packages/@aws-cdk/core/lib/assets.ts b/packages/@aws-cdk/core/lib/assets.ts index 10e1a61e7e5d0..72f9429f2afdb 100644 --- a/packages/@aws-cdk/core/lib/assets.ts +++ b/packages/@aws-cdk/core/lib/assets.ts @@ -242,6 +242,18 @@ export interface DockerImageAssetSource { */ readonly dockerOutputs?: string[]; + /** + * Cache from options to pass to the `docker build` command. + * @default - no cache from args are passed + */ + readonly dockerCacheFrom?: DockerCacheOption[]; + + /** + * Cache to options to pass to the `docker build` command. + * @default - no cache to args are passed + */ + readonly dockerCacheTo?: DockerCacheOption; + } /** @@ -347,3 +359,25 @@ export interface DockerImageAssetLocation { */ readonly imageTag?: string; } + +/** + * Options for configuring the Docker cache backend + */ +export interface DockerCacheOption { + /** + * The type of cache to use. + * Refer to https://docs.docker.com/build/cache/backends/ for full list of backends. + * @default - unspecified + * + * @example 'registry' + */ + readonly type: string; + /** + * Any parameters to pass into the docker cache backend configuration. + * Refer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. + * @default {} No options provided + * + * @example { ref: `12345678.dkr.ecr.us-west-2.amazonaws.com/cache:${branch}`, mode: "max" } + */ + readonly params?: { [key: string]: string }; +} \ No newline at end of file diff --git a/packages/@aws-cdk/core/lib/stack-synthesizers/asset-manifest-builder.ts b/packages/@aws-cdk/core/lib/stack-synthesizers/asset-manifest-builder.ts index 0f923dfaef659..109ddc4c00c1f 100644 --- a/packages/@aws-cdk/core/lib/stack-synthesizers/asset-manifest-builder.ts +++ b/packages/@aws-cdk/core/lib/stack-synthesizers/asset-manifest-builder.ts @@ -71,6 +71,8 @@ export class AssetManifestBuilder { networkMode: asset.networkMode, platform: asset.platform, dockerOutputs: asset.dockerOutputs, + cacheFrom: asset.dockerCacheFrom, + cacheTo: asset.dockerCacheTo, }, { repositoryName: target.repositoryName, imageTag, diff --git a/packages/@aws-cdk/core/lib/stack-synthesizers/legacy.ts b/packages/@aws-cdk/core/lib/stack-synthesizers/legacy.ts index bce9dac8ced65..70dc22333bf84 100644 --- a/packages/@aws-cdk/core/lib/stack-synthesizers/legacy.ts +++ b/packages/@aws-cdk/core/lib/stack-synthesizers/legacy.ts @@ -148,6 +148,8 @@ export class LegacyStackSynthesizer extends StackSynthesizer implements IReusabl networkMode: asset.networkMode, platform: asset.platform, outputs: asset.dockerOutputs, + cacheFrom: asset.dockerCacheFrom, + cacheTo: asset.dockerCacheTo, }; this.boundStack.node.addMetadata(cxschema.ArtifactMetadataEntryType.ASSET, metadata); diff --git a/packages/@aws-cdk/cx-api/lib/assets.ts b/packages/@aws-cdk/cx-api/lib/assets.ts index 3cc8312f646d4..42461895828be 100644 --- a/packages/@aws-cdk/cx-api/lib/assets.ts +++ b/packages/@aws-cdk/cx-api/lib/assets.ts @@ -17,6 +17,8 @@ export const ASSET_RESOURCE_METADATA_DOCKER_BUILD_TARGET_KEY = 'aws:asset:docker export const ASSET_RESOURCE_METADATA_PROPERTY_KEY = 'aws:asset:property'; export const ASSET_RESOURCE_METADATA_IS_BUNDLED_KEY = 'aws:asset:is-bundled'; export const ASSET_RESOURCE_METADATA_DOCKER_OUTPUTS_KEY = 'aws:asset:docker-outputs'; +export const ASSET_RESOURCE_METADATA_DOCKER_CACHE_FROM_KEY = 'aws:asset:docker-cache-from'; +export const ASSET_RESOURCE_METADATA_DOCKER_CACHE_TO_KEY = 'aws:asset:docker-cache-to'; /** * Separator string that separates the prefix separator from the object key separator. diff --git a/packages/cdk-assets/lib/private/docker.ts b/packages/cdk-assets/lib/private/docker.ts index 509e15cbed22f..f5a6d675aa634 100644 --- a/packages/cdk-assets/lib/private/docker.ts +++ b/packages/cdk-assets/lib/private/docker.ts @@ -19,6 +19,8 @@ interface BuildOptions { readonly networkMode?: string; readonly platform?: string; readonly outputs?: string[]; + readonly cacheFrom?: DockerCacheOption[]; + readonly cacheTo?: DockerCacheOption; } export interface DockerCredentialsConfig { @@ -36,6 +38,11 @@ enum InspectImageErrorCode { Podman = 125 } +export interface DockerCacheOption { + readonly type: string; + readonly params?: { [key: string]: string }; +} + export class Docker { private configDir: string | undefined = undefined; @@ -90,6 +97,8 @@ export class Docker { ...options.networkMode ? ['--network', options.networkMode] : [], ...options.platform ? ['--platform', options.platform] : [], ...options.outputs ? options.outputs.map(output => [`--output=${output}`]) : [], + ...options.cacheFrom ? options.cacheFrom.map(cacheFrom => this.cacheOptionToFlag(cacheFrom)) : [], + ...options.cacheTo ? [this.cacheOptionToFlag(options.cacheTo)] : [], '.', ]; await this.execute(buildCommand, { cwd: options.directory }); @@ -179,6 +188,14 @@ export class Docker { throw e; } } + + private cacheOptionToFlag(option: DockerCacheOption): string { + let flag = `type=${option.type}`; + if (option.params) { + flag += ',' + Object.entries(option.params).map(([k, v]) => `${k}=${v}`).join(','); + } + return flag; + } } export interface DockerFactoryOptions { diff --git a/packages/cdk-assets/lib/private/handlers/container-images.ts b/packages/cdk-assets/lib/private/handlers/container-images.ts index 811d02e1a8d01..e25b12d368a01 100644 --- a/packages/cdk-assets/lib/private/handlers/container-images.ts +++ b/packages/cdk-assets/lib/private/handlers/container-images.ts @@ -173,6 +173,8 @@ class ContainerImageBuilder { networkMode: source.networkMode, platform: source.platform, outputs: source.dockerOutputs, + cacheFrom: source.cacheFrom, + cacheTo: source.cacheTo, }); } From d451b3014a1d39e0a6ea18c2ec79a547b187adc5 Mon Sep 17 00:00:00 2001 From: Richard Simpson Date: Wed, 8 Mar 2023 15:04:04 -0600 Subject: [PATCH 20/22] fix(ecr-assets): prefix cache arguments correctly (#24524) Follow up to #24024, fixes an issue where cache args were not correctly prefixed and adds additional testing. Apologies for the second PR, I realized there was an issue literally as the auto-merge happened! ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/cdk-assets/lib/private/docker.ts | 4 +- .../cdk-assets/test/docker-images.test.ts | 139 ++++++++++++++++++ 2 files changed, 141 insertions(+), 2 deletions(-) diff --git a/packages/cdk-assets/lib/private/docker.ts b/packages/cdk-assets/lib/private/docker.ts index f5a6d675aa634..eea1bb7b3a093 100644 --- a/packages/cdk-assets/lib/private/docker.ts +++ b/packages/cdk-assets/lib/private/docker.ts @@ -97,8 +97,8 @@ export class Docker { ...options.networkMode ? ['--network', options.networkMode] : [], ...options.platform ? ['--platform', options.platform] : [], ...options.outputs ? options.outputs.map(output => [`--output=${output}`]) : [], - ...options.cacheFrom ? options.cacheFrom.map(cacheFrom => this.cacheOptionToFlag(cacheFrom)) : [], - ...options.cacheTo ? [this.cacheOptionToFlag(options.cacheTo)] : [], + ...options.cacheFrom ? [...options.cacheFrom.map(cacheFrom => ['--cache-from', this.cacheOptionToFlag(cacheFrom)]).flat()] : [], + ...options.cacheTo ? ['--cache-to', this.cacheOptionToFlag(options.cacheTo)] : [], '.', ]; await this.execute(buildCommand, { cwd: options.directory }); diff --git a/packages/cdk-assets/test/docker-images.test.ts b/packages/cdk-assets/test/docker-images.test.ts index 7b7d94b54362f..688828a68c021 100644 --- a/packages/cdk-assets/test/docker-images.test.ts +++ b/packages/cdk-assets/test/docker-images.test.ts @@ -144,6 +144,68 @@ beforeEach(() => { }, }, }), + '/cache/cdk.out/assets.json': JSON.stringify({ + version: Manifest.version(), + dockerImages: { + theAsset: { + source: { + directory: 'dockerdir', + cacheFrom: [{ type: 'registry', params: { ref: 'abcdef' } }], + cacheTo: { type: 'inline' }, + }, + destinations: { + theDestination: { + region: 'us-north-50', + assumeRoleArn: 'arn:aws:role', + repositoryName: 'repo', + imageTag: 'nopqr', + }, + }, + }, + }, + }), + '/cache-from-multiple/cdk.out/assets.json': JSON.stringify({ + version: Manifest.version(), + dockerImages: { + theAsset: { + source: { + directory: 'dockerdir', + cacheFrom: [ + { type: 'registry', params: { ref: 'cache:ref' } }, + { type: 'registry', params: { ref: 'cache:main' } }, + { type: 'gha' }, + ], + }, + destinations: { + theDestination: { + region: 'us-north-50', + assumeRoleArn: 'arn:aws:role', + repositoryName: 'repo', + imageTag: 'nopqr', + }, + }, + }, + }, + }), + '/cache-to-complex/cdk.out/assets.json': JSON.stringify({ + version: Manifest.version(), + dockerImages: { + theAsset: { + source: { + directory: 'dockerdir', + cacheTo: { type: 'registry', params: { ref: 'cache:main', mode: 'max', compression: 'zstd' } }, + }, + destinations: { + theDestination: { + region: 'us-north-50', + assumeRoleArn: 'arn:aws:role', + repositoryName: 'repo', + imageTag: 'nopqr', + }, + }, + }, + }, + }), '/platform-arm64/cdk.out/dockerdir/Dockerfile': 'FROM scratch', }); @@ -284,6 +346,83 @@ describe('with a complete manifest', () => { expectAllSpawns(); expect(true).toBeTruthy(); // Expect no exception, satisfy linter }); + + test('build with cache option', async () => { + pub = new AssetPublishing(AssetManifest.fromPath('/cache/cdk.out'), { aws }); + const defaultNetworkDockerpath = '/cache/cdk.out/dockerdir'; + aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); + aws.mockEcr.getAuthorizationToken = mockedApiResult({ + authorizationData: [ + { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, + ], + }); + + const expectAllSpawns = mockSpawn( + { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, + { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, + { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '--cache-from', 'type=registry,ref=abcdef', '--cache-to', 'type=inline', '.'], cwd: defaultNetworkDockerpath }, + { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, + { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, + ); + + await pub.publish(); + + expectAllSpawns(); + expect(true).toBeTruthy(); // Expect no exception, satisfy linter + }); + + test('build with multiple cache from option', async () => { + pub = new AssetPublishing(AssetManifest.fromPath('/cache-from-multiple/cdk.out'), { aws }); + const defaultNetworkDockerpath = '/cache-from-multiple/cdk.out/dockerdir'; + aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); + aws.mockEcr.getAuthorizationToken = mockedApiResult({ + authorizationData: [ + { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, + ], + }); + + const expectAllSpawns = mockSpawn( + { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, + { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, + { + commandLine: [ + 'docker', 'build', '--tag', 'cdkasset-theasset', '--cache-from', 'type=registry,ref=cache:ref', '--cache-from', 'type=registry,ref=cache:main', '--cache-from', 'type=gha', '.', + ], + cwd: defaultNetworkDockerpath, + }, + { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, + { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, + ); + + await pub.publish(); + + expectAllSpawns(); + expect(true).toBeTruthy(); // Expect no exception, satisfy linter + }); + + test('build with cache to complex option', async () => { + pub = new AssetPublishing(AssetManifest.fromPath('/cache-to-complex/cdk.out'), { aws }); + const defaultNetworkDockerpath = '/cache-to-complex/cdk.out/dockerdir'; + aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); + aws.mockEcr.getAuthorizationToken = mockedApiResult({ + authorizationData: [ + { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, + ], + }); + + const expectAllSpawns = mockSpawn( + { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, + { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, + { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '--cache-to', 'type=registry,ref=cache:main,mode=max,compression=zstd', '.'], cwd: defaultNetworkDockerpath }, + { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, + { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, + ); + + await pub.publish(); + + expectAllSpawns(); + expect(true).toBeTruthy(); // Expect no exception, satisfy linter + }); }); describe('external assets', () => { From 7c7ad6d18bd0d48a30858c1964d27d8a02b274ae Mon Sep 17 00:00:00 2001 From: Mitch Lloyd Date: Wed, 8 Mar 2023 17:02:50 -0500 Subject: [PATCH 21/22] feat(kinesisanalytics-flink): VPC support for Flink applications (#24442) The Kinesis Data Analytics team added support for [deploying Flink applications in a VPC](https://docs.aws.amazon.com/kinesisanalytics/latest/java/vpc.html). This feature is also available in CloudFormation. Deploying Flink in a VPC allows the application to reach services like Redis and other databases. This PR adds support for configuring `VpcConfigurations` with `vpcSubets` (subnetSelection) and securityGroups following similar patterns for resources like `lambda.Function` that support optional deployment in a VPC. Some design decisions: - Name the subnet selection prop `vpcSubnets`. Some resources call the subnet selection property `subnetSelection` but `vpcSubnets` seemed more popular and is used by the Lambda and ECS modules. - Only support passing an array of security groups. Some resources support adding a single SecurityGroup or SecurityGroupId properties but it appears this [usage is deprecated](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-lambda/lib/function.ts#L170) in favor of always passing an array of SecurityGroups. - I added a `fromApplicationAttributes` factory that includes `securityGroups`. This seemed like an appropriate time to add this method given there was another property to pass besides ARN and name. However I didn't go down the path of including a role in `fromApplicationAttributes` yet in order to keep this PR focused. - ~~I thought about adding a section to the readme about using VPCs, but I didn't notice a section like that in the [Lambda readme](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-lambda/README.md) for instance. My current thinking is that the conventions for VPC-bound resources are so consistent it probably doesn't warrant more documentation~~ @aws-cdk-automation did not buy this rational. I'd like to follow-up with a PR to move code into more files as the > 1K lines of code in `application.ts` is getting a little unweildy. I wanted to avoid moving code around in this PR to make it easier to review. Closes #21104. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-kinesisanalytics-flink/README.md | 16 +- .../lib/application.ts | 231 +++- .../lib/private/validation.ts | 17 + .../aws-kinesisanalytics-flink/package.json | 3 + .../rosetta/default.ts-fixture | 3 +- .../test/application.test.ts | 220 ++- .../FlinkAppTest.assets.json | 32 + .../FlinkAppTest.template.json | 720 ++++++++++ ...efaultTestDeployAssert06A9965C.assets.json | 19 + ...aultTestDeployAssert06A9965C.template.json | 36 + .../WordCount.jar | Bin 0 -> 15192 bytes .../integ.vpc-application.js.snapshot/cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 285 ++++ .../tree.json | 1175 +++++++++++++++++ .../test/integ.vpc-application.ts | 19 + 16 files changed, 2722 insertions(+), 67 deletions(-) create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.assets.json create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.template.json create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.assets.json create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.template.json create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/asset.8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577/WordCount.jar create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.ts diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md b/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md index 8e91fcd78b6ac..2e99aeb3ba0d0 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md @@ -46,7 +46,7 @@ const flinkApp = new flink.Application(this, 'Application', { }, }, // ... - runtime: flink.Runtime.FLINK_1_13, + runtime: flink.Runtime.FLINK_1_15, code: flink.ApplicationCode.fromBucket(bucket, 'my-app.jar'), }); ``` @@ -59,7 +59,7 @@ snapshotting, monitoring, and parallelism. declare const bucket: s3.Bucket; const flinkApp = new flink.Application(this, 'Application', { code: flink.ApplicationCode.fromBucket(bucket, 'my-app.jar'), - runtime: flink.Runtime.FLINK_1_13, + runtime: flink.Runtime.FLINK_1_15, checkpointingEnabled: true, // default is true checkpointInterval: Duration.seconds(30), // default is 1 minute minPauseBetweenCheckpoints: Duration.seconds(10), // default is 5 seconds @@ -72,3 +72,15 @@ const flinkApp = new flink.Application(this, 'Application', { logGroup: new logs.LogGroup(this, 'LogGroup'), // by default, a new LogGroup will be created }); ``` + +Flink applications can optionally be deployed in a VPC: + +```ts +declare const bucket: s3.Bucket; +declare const vpc: ec2.Vpc; +const flinkApp = new flink.Application(this, 'Application', { + code: flink.ApplicationCode.fromBucket(bucket, 'my-app.jar'), + runtime: flink.Runtime.FLINK_1_15, + vpc, +}); +``` diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/application.ts b/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/application.ts index 312c55eb9ac22..a7cee60ffa496 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/application.ts +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/application.ts @@ -1,4 +1,5 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; +import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import { CfnApplicationCloudWatchLoggingOptionV2, CfnApplicationV2 } from '@aws-cdk/aws-kinesisanalytics'; import * as logs from '@aws-cdk/aws-logs'; @@ -14,7 +15,7 @@ import { LogLevel, MetricsLevel, PropertyGroups, Runtime } from './types'; * An interface expressing the public properties on both an imported and * CDK-created Flink application. */ -export interface IApplication extends core.IResource, iam.IGrantable { +export interface IApplication extends core.IResource, ec2.IConnectable, iam.IGrantable { /** * The application ARN. * @@ -56,7 +57,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricKpus(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -67,7 +68,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricDowntime(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -78,7 +79,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default sample count over 5 minutes + * @default - sample count over 5 minutes */ metricUptime(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -90,7 +91,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricFullRestarts(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -101,7 +102,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricNumberOfFailedCheckpoints(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -112,7 +113,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricLastCheckpointDuration(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -123,7 +124,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricLastCheckpointSize(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -136,7 +137,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricCpuUtilization(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -149,7 +150,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricHeapMemoryUtilization(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -160,7 +161,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricOldGenerationGCTime(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -172,7 +173,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricOldGenerationGCCount(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -183,7 +184,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricThreadsCount(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -195,7 +196,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsIn(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -207,7 +208,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsInPerSecond(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -218,7 +219,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsOut(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -230,7 +231,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsOutPerSecond(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -241,7 +242,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricNumLateRecordsDropped(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -252,7 +253,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricCurrentInputWatermark(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -263,7 +264,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricCurrentOutputWatermark(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -274,7 +275,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricManagedMemoryUsed(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -285,7 +286,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricManagedMemoryTotal(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -296,7 +297,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricManagedMemoryUtilization(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -309,7 +310,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricIdleTimeMsPerSecond(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -321,7 +322,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricBackPressuredTimeMsPerSecond(props?: cloudwatch.MetricOptions): cloudwatch.Metric; @@ -334,7 +335,7 @@ export interface IApplication extends core.IResource, iam.IGrantable { * * Reporting Level: Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricBusyTimePerMsPerSecond(props?: cloudwatch.MetricOptions): cloudwatch.Metric; } @@ -351,6 +352,13 @@ abstract class ApplicationBase extends core.Resource implements IApplication { // Implement iam.IGrantable interface public abstract readonly grantPrincipal: iam.IPrincipal; + /** + * The underlying connections object for the connections getter. + * + * @internal + */ + protected _connections?: ec2.Connections; + /** Implement the convenience `IApplication.addToPrincipalPolicy` method. */ public addToRolePolicy(policyStatement: iam.PolicyStatement): boolean { if (this.role) { @@ -361,6 +369,13 @@ abstract class ApplicationBase extends core.Resource implements IApplication { return false; } + public get connections() { + if (!this._connections) { + throw new Error('This Application isn\'t associated with a VPC. Provide a "vpc" prop when creating the Application or "securityGroups" when importing it.'); + } + return this._connections; + } + /** * Return a CloudWatch metric associated with this Flink application. * @@ -385,7 +400,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricKpus(props?: cloudwatch.MetricOptions) { return this.metric('KPUs', { statistic: 'Average', ...props }); @@ -399,7 +414,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricDowntime(props?: cloudwatch.MetricOptions) { return this.metric('downtime', { statistic: 'Average', ...props }); @@ -412,7 +427,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricUptime(props?: cloudwatch.MetricOptions) { return this.metric('uptime', { statistic: 'Average', ...props }); @@ -426,7 +441,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricFullRestarts(props?: cloudwatch.MetricOptions) { return this.metric('fullRestarts', { statistic: 'Sum', ...props }); @@ -439,7 +454,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricNumberOfFailedCheckpoints(props?: cloudwatch.MetricOptions) { return this.metric('numberOfFailedCheckpoints', { statistic: 'Sum', ...props }); @@ -452,7 +467,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricLastCheckpointDuration(props?: cloudwatch.MetricOptions) { return this.metric('lastCheckpointDuration', { statistic: 'Maximum', ...props }); @@ -465,7 +480,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricLastCheckpointSize(props?: cloudwatch.MetricOptions) { return this.metric('lastCheckpointSize', { statistic: 'Maximum', ...props }); @@ -480,7 +495,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricCpuUtilization(props?: cloudwatch.MetricOptions) { return this.metric('cpuUtilization', { statistic: 'Average', ...props }); @@ -495,7 +510,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricHeapMemoryUtilization(props?: cloudwatch.MetricOptions) { return this.metric('heapMemoryUtilization', { statistic: 'Average', ...props }); @@ -508,7 +523,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricOldGenerationGCTime(props?: cloudwatch.MetricOptions) { return this.metric('oldGenerationGCTime', { statistic: 'Sum', ...props }); @@ -522,7 +537,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricOldGenerationGCCount(props?: cloudwatch.MetricOptions) { return this.metric('oldGenerationGCCount', { statistic: 'Sum', ...props }); @@ -535,7 +550,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricThreadsCount(props?: cloudwatch.MetricOptions) { return this.metric('threadsCount', { statistic: 'Average', ...props }); @@ -549,7 +564,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsIn(props?: cloudwatch.MetricOptions) { return this.metric('numRecordsIn', { statistic: 'Average', ...props }); @@ -563,7 +578,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsInPerSecond(props?: cloudwatch.MetricOptions) { return this.metric('numRecordsInPerSecond', { statistic: 'Average', ...props }); @@ -576,7 +591,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsOut(props?: cloudwatch.MetricOptions) { return this.metric('numRecordsOut', { statistic: 'Average', ...props }); @@ -590,7 +605,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricNumRecordsOutPerSecond(props?: cloudwatch.MetricOptions) { return this.metric('numRecordsOutPerSecond', { statistic: 'Average', ...props }); @@ -604,7 +619,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default sum over 5 minutes + * @default - sum over 5 minutes */ metricNumLateRecordsDropped(props?: cloudwatch.MetricOptions) { return this.metric('numLateRecordsDropped', { statistic: 'Sum', ...props }); @@ -617,7 +632,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricCurrentInputWatermark(props?: cloudwatch.MetricOptions) { return this.metric('currentInputWatermark', { statistic: 'Maximum', ...props }); @@ -630,7 +645,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default maximum over 5 minutes + * @default - maximum over 5 minutes */ metricCurrentOutputWatermark(props?: cloudwatch.MetricOptions) { return this.metric('currentOutputWatermark', { statistic: 'Maximum', ...props }); @@ -643,7 +658,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricManagedMemoryUsed(props?: cloudwatch.MetricOptions) { return this.metric('managedMemoryUsed', { statistic: 'Average', ...props }); @@ -656,7 +671,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricManagedMemoryTotal(props?: cloudwatch.MetricOptions) { return this.metric('managedMemoryTotal', { statistic: 'Average', ...props }); @@ -669,7 +684,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Application, Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricManagedMemoryUtilization(props?: cloudwatch.MetricOptions) { return this.metric('managedMemoryUtilization', { statistic: 'Average', ...props }); @@ -684,7 +699,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricIdleTimeMsPerSecond(props?: cloudwatch.MetricOptions) { return this.metric('idleTimeMsPerSecond', { statistic: 'Average', ...props }); @@ -698,7 +713,7 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricBackPressuredTimeMsPerSecond(props?: cloudwatch.MetricOptions) { return this.metric('backPressuredTimeMsPerSecond', { statistic: 'Average', ...props }); @@ -713,13 +728,32 @@ abstract class ApplicationBase extends core.Resource implements IApplication { * * Reporting Level: Operator, Task, Parallelism * - * @default average over 5 minutes + * @default - average over 5 minutes */ metricBusyTimePerMsPerSecond(props?: cloudwatch.MetricOptions) { return this.metric('busyTimePerMsPerSecond', { statistic: 'Average', ...props }); } } +/** + * Attributes used for importing an Application with Application.fromApplicationAttributes. + */ +export interface ApplicationAttributes { + /** + * The ARN of the Flink application. + * + * Format: arn::kinesisanalytics:::application/ + */ + readonly applicationArn: string; + + /** + * The security groups for this Flink application if deployed in a VPC. + * + * @default - no security groups + */ + readonly securityGroups?: ec2.ISecurityGroup[]; +} + /** * Props for creating an Application construct. */ @@ -751,7 +785,7 @@ export interface ApplicationProps { /** * The interval between checkpoints. * - * @default 1 minute + * @default - 1 minute */ readonly checkpointInterval?: core.Duration; @@ -759,7 +793,7 @@ export interface ApplicationProps { * The minimum amount of time in to wait after a checkpoint finishes to start * a new checkpoint. * - * @default 5 seconds + * @default - 5 seconds */ readonly minPauseBetweenCheckpoints?: core.Duration; @@ -815,7 +849,7 @@ export interface ApplicationProps { * Configuration PropertyGroups. You can use these property groups to pass * arbitrary runtime configuration values to your Flink app. * - * @default No property group configuration provided to the Flink app + * @default - No property group configuration provided to the Flink app */ readonly propertyGroups?: PropertyGroups; @@ -837,9 +871,30 @@ export interface ApplicationProps { /** * The log group to send log entries to. * - * @default CDK's default LogGroup + * @default - CDK's default LogGroup */ readonly logGroup?: logs.ILogGroup; + + /** + * Deploy the Flink application in a VPC. + * + * @default - no VPC + */ + readonly vpc?: ec2.IVpc; + + /** + * Choose which VPC subnets to use. + * + * @default - SubnetType.PRIVATE_WITH_EGRESS subnets + */ + readonly vpcSubnets?: ec2.SubnetSelection; + + /** + * Security groups to use with a provided VPC. + * + * @default - a new security group is created for this application. + */ + readonly securityGroups?: ec2.ISecurityGroup[]; } /** @@ -851,7 +906,7 @@ class Import extends ApplicationBase { public readonly applicationName: string; public readonly applicationArn: string; - constructor(scope: Construct, id: string, attrs: { applicationArn: string, applicationName: string }) { + constructor(scope: Construct, id: string, attrs: { applicationArn: string, securityGroups?: ec2.ISecurityGroup[] }) { super(scope, id); // Imported applications have no associated role or grantPrincipal @@ -859,7 +914,16 @@ class Import extends ApplicationBase { this.role = undefined; this.applicationArn = attrs.applicationArn; - this.applicationName = attrs.applicationName; + const applicationName = core.Stack.of(scope).splitArn(attrs.applicationArn, core.ArnFormat.SLASH_RESOURCE_NAME).resourceName; + if (!applicationName) { + throw new Error(`applicationArn for fromApplicationArn (${attrs.applicationArn}) must include resource name`); + } + this.applicationName = applicationName; + + const securityGroups = attrs.securityGroups ?? []; + if (securityGroups.length > 0) { + this._connections = new ec2.Connections({ securityGroups }); + } } } @@ -877,7 +941,7 @@ export class Application extends ApplicationBase { public static fromApplicationName(scope: Construct, id: string, applicationName: string): IApplication { const applicationArn = core.Stack.of(scope).formatArn(applicationArnComponents(applicationName)); - return new Import(scope, id, { applicationArn, applicationName }); + return new Import(scope, id, { applicationArn }); } /** @@ -885,12 +949,17 @@ export class Application extends ApplicationBase { * applicationArn. */ public static fromApplicationArn(scope: Construct, id: string, applicationArn: string): IApplication { - const applicationName = core.Stack.of(scope).splitArn(applicationArn, core.ArnFormat.SLASH_RESOURCE_NAME).resourceName; - if (!applicationName) { - throw new Error(`applicationArn for fromApplicationArn (${applicationArn}) must include resource name`); - } + return new Import(scope, id, { applicationArn }); + } - return new Import(scope, id, { applicationArn, applicationName }); + /** + * Import an existing application defined outside of CDK code. + */ + public static fromApplicationAttributes(scope: Construct, id: string, attrs: ApplicationAttributes): IApplication { + return new Import(scope, id, { + applicationArn: attrs.applicationArn, + securityGroups: attrs.securityGroups, + }); } public readonly applicationArn: string; @@ -919,6 +988,23 @@ export class Application extends ApplicationBase { const code = props.code.bind(this); code.bucket.grantRead(this); + let vpcConfigurations; + if (props.vpc) { + const securityGroups = props.securityGroups ?? [ + new ec2.SecurityGroup(this, 'SecurityGroup', { + vpc: props.vpc, + }), + ]; + this._connections = new ec2.Connections({ securityGroups }); + const subnetSelection = props.vpcSubnets ?? { + subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, + }; + vpcConfigurations = [{ + securityGroupIds: securityGroups.map(sg => sg.securityGroupId), + subnetIds: props.vpc.selectSubnets(subnetSelection).subnetIds, + }]; + } + const resource = new CfnApplicationV2(this, 'Resource', { applicationName: props.applicationName, runtimeEnvironment: props.runtime.value, @@ -939,6 +1025,7 @@ export class Application extends ApplicationBase { applicationSnapshotConfiguration: { snapshotsEnabled: props.snapshotsEnabled ?? true, }, + vpcConfigurations, }, }); resource.node.addDependency(this.role); @@ -978,6 +1065,24 @@ export class Application extends ApplicationBase { }, }); + // Permissions required for VPC usage per: + // https://docs.aws.amazon.com/kinesisanalytics/latest/java/vpc-permissions.html + if (props.vpc) { + this.role.addToPrincipalPolicy(new iam.PolicyStatement({ + actions: [ + 'ec2:DescribeVpcs', + 'ec2:DescribeSubnets', + 'ec2:DescribeSecurityGroups', + 'ec2:DescribeDhcpOptions', + 'ec2:CreateNetworkInterface', + 'ec2:CreateNetworkInterfacePermission', + 'ec2:DescribeNetworkInterfaces', + 'ec2:DeleteNetworkInterface', + ], + resources: ['*'], + })); + } + this.applicationName = this.getResourceNameAttribute(resource.ref); this.applicationArn = this.getResourceArnAttribute( core.Stack.of(this).formatArn(applicationArnComponents(resource.ref)), diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/private/validation.ts b/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/private/validation.ts index b0f94f56daf77..739956e926f3f 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/private/validation.ts +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/private/validation.ts @@ -1,9 +1,13 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; import * as core from '@aws-cdk/core'; interface ValidatedProps { applicationName?: string; parallelism?: number; parallelismPerKpu?: number; + vpc?: ec2.IVpc; + vpcSubnets?: ec2.SubnetSelection; + securityGroups?: ec2.ISecurityGroup[]; } /** @@ -13,6 +17,7 @@ export function validateFlinkApplicationProps(props: ValidatedProps) { validateApplicationName(props.applicationName); validateParallelism(props.parallelism); validateParallelismPerKpu(props.parallelismPerKpu); + validateVpcProps(props); } function validateApplicationName(applicationName?: string) { @@ -52,3 +57,15 @@ function validateParallelismPerKpu(parallelismPerKpu?: number) { throw new Error('parallelismPerKpu must be at least 1'); } } + +function validateVpcProps({ vpc, securityGroups = [], vpcSubnets }: ValidatedProps) { + if (!vpc) { + if (vpcSubnets) { + throw new Error('vpc prop required when passing vpcSubnets'); + } + + if (securityGroups.length > 0) { + throw new Error('vpc prop required when passing securityGroups'); + } + } +} diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json b/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json index 103eb37da9387..b0aeedbafabfe 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json @@ -76,6 +76,7 @@ "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cdk-build-tools": "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", @@ -84,6 +85,7 @@ "dependencies": { "@aws-cdk/assets": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", + "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kinesisanalytics": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", @@ -98,6 +100,7 @@ "peerDependencies": { "@aws-cdk/assets": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", + "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kinesisanalytics": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-kinesisanalytics-flink/rosetta/default.ts-fixture index a9f46e29f793b..69cf40a794c9a 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/rosetta/default.ts-fixture @@ -1,6 +1,7 @@ // Fixture with packages imported, but nothing else import { Construct } from 'constructs'; import { Duration, Stack } from '@aws-cdk/core'; +import * as ec2 from '@aws-cdk/aws-ec2'; import * as flink from '@aws-cdk/aws-kinesisanalytics-flink'; import * as logs from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; @@ -11,4 +12,4 @@ class Fixture extends Stack { /// here } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts index f663c2b4cc0e7..3b83c039452b4 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts @@ -1,6 +1,7 @@ import * as path from 'path'; import { Match, Template } from '@aws-cdk/assertions'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; +import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as logs from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; @@ -76,8 +77,14 @@ describe('Application', () => { Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { - Statement: Match.arrayWith([ + Statement: Match.arrayEquals([ { Action: 'cloudwatch:PutMetricData', Effect: 'Allow', Resource: '*' }, + // Access to read from the code bucket + { + Action: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'], + Effect: 'Allow', + Resource: Match.anyValue(), + }, { Action: 'logs:DescribeLogGroups', Effect: 'Allow', @@ -504,6 +511,206 @@ describe('Application', () => { }); }); + test('using a VPC with default vpcSubnets and securityGroups', () => { + new flink.Application(stack, 'FlinkApplication', { + ...requiredProps, + vpc: new ec2.Vpc(stack, 'VPC'), + }); + + const template = Template.fromStack(stack); + template.hasResourceProperties( + 'AWS::KinesisAnalyticsV2::Application', + { + ApplicationConfiguration: { + VpcConfigurations: [ + { + SecurityGroupIds: [ + { + 'Fn::GetAtt': ['FlinkApplicationSecurityGroup1FD816EE', 'GroupId'], + }, + ], + SubnetIds: [ + { + Ref: 'VPCPrivateSubnet1Subnet8BCA10E0', + }, + { + Ref: 'VPCPrivateSubnet2SubnetCFCDAA7A', + }, + ], + }, + ], + }, + }, + ); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: Match.arrayWith([ + { + Action: [ + 'ec2:DescribeVpcs', + 'ec2:DescribeSubnets', + 'ec2:DescribeSecurityGroups', + 'ec2:DescribeDhcpOptions', + 'ec2:CreateNetworkInterface', + 'ec2:CreateNetworkInterfacePermission', + 'ec2:DescribeNetworkInterfaces', + 'ec2:DeleteNetworkInterface', + ], + Effect: 'Allow', + Resource: '*', + }, + ]), + }, + }); + }); + + test('providing securityGroups', () => { + const vpc = new ec2.Vpc(stack, 'VPC'); + new flink.Application(stack, 'FlinkApplication', { + ...requiredProps, + vpc, + securityGroups: [ + new ec2.SecurityGroup(stack, 'ProvidedSecurityGroup', { vpc }), + ], + }); + + Template.fromStack(stack).hasResourceProperties( + 'AWS::KinesisAnalyticsV2::Application', + { + ApplicationConfiguration: { + VpcConfigurations: [ + { + SecurityGroupIds: [ + { + 'Fn::GetAtt': ['ProvidedSecurityGroup3C7655DD', 'GroupId'], + }, + ], + }, + ], + }, + }, + ); + }); + + test('providing a subnetSelection', () => { + new flink.Application(stack, 'FlinkApplication', { + ...requiredProps, + vpc: new ec2.Vpc(stack, 'VPC'), + vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, + }); + + Template.fromStack(stack).hasResourceProperties( + 'AWS::KinesisAnalyticsV2::Application', + { + ApplicationConfiguration: { + VpcConfigurations: [ + { + SubnetIds: [ + { + Ref: 'VPCPublicSubnet1SubnetB4246D30', + }, + { + Ref: 'VPCPublicSubnet2Subnet74179F39', + }, + ], + }, + ], + }, + }, + ); + }); + + test('using connections on a created Application', () => { + const app = new flink.Application(stack, 'FlinkApplication', { + ...requiredProps, + vpc: new ec2.Vpc(stack, 'VPC'), + }); + + app.connections.allowFromAnyIpv4(ec2.Port.tcp(443)); + + Template.fromStack(stack).hasResourceProperties( + 'AWS::EC2::SecurityGroup', + { + SecurityGroupEgress: [{ + Description: 'Allow all outbound traffic by default', + IpProtocol: '-1', + }], + SecurityGroupIngress: [{ + Description: 'from 0.0.0.0/0:443', + FromPort: 443, + IpProtocol: 'tcp', + ToPort: 443, + }], + }, + ); + }); + + test('using connections on an imported Application', () => { + const app = flink.Application.fromApplicationAttributes(stack, 'FlinkApplication', { + applicationArn: 'arn:aws:kinesisanalytics:us-west-2:012345678901:application/my-app', + securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(stack, 'ImportedSG', 'sg-123456789')], + }); + + app.connections.allowFromAnyIpv4(ec2.Port.tcp(443)); + + Template.fromStack(stack).hasResourceProperties( + 'AWS::EC2::SecurityGroupIngress', + { + FromPort: 443, + GroupId: 'sg-123456789', + IpProtocol: 'tcp', + ToPort: 443, + }, + ); + }); + + test('validating vpnSubnets prop requires vpc prop', () => { + expect(() => { + new flink.Application(stack, 'FlinkApplication', { + ...requiredProps, + vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, + }); + }).toThrow(/vpc prop required when passing vpcSubnets/); + }); + + test('validating securityGroups prop requires vpc prop', () => { + expect(() => { + const vpc = new ec2.Vpc(stack, 'VPC'); + const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { + vpc, + }); + new flink.Application(stack, 'Error', { + ...requiredProps, + securityGroups: [securityGroup], + }); + }).toThrow(/vpc prop required when passing securityGroups/); + + // empty array for securityGroups is treated the same as undefined + expect(() => { + new flink.Application(stack, 'OK', { + ...requiredProps, + securityGroups: [], + }); + }).not.toThrow(); + }); + + test('validating vpc provided when using connections for created App', () => { + let app = new flink.Application(stack, 'FlinkApplication', { + ...requiredProps, + }); + expect(() => { + app.connections; + }).toThrow(/This Application isn\'t associated with a VPC/); + }); + + test('validating vpc provided when using connections for imported App', () => { + let app = flink.Application.fromApplicationName(stack, 'FlinkApplication', 'Name'); + expect(() => { + app.connections; + }).toThrow(/This Application isn\'t associated with a VPC/); + }); + test('validating applicationName', () => { // Expect no error with valid name new flink.Application(stack, 'ValidString', { @@ -612,6 +819,17 @@ describe('Application', () => { expect(flinkApp.addToRolePolicy(new iam.PolicyStatement())).toBe(false); }); + test('fromFlinkApplicationAttributes', () => { + const arn = 'arn:aws:kinesisanalytics:us-west-2:012345678901:application/my-app'; + const flinkApp = flink.Application.fromApplicationAttributes(stack, 'Imported', { + applicationArn: arn, + }); + + expect(flinkApp.applicationName).toEqual('my-app'); + expect(flinkApp.applicationArn).toEqual(arn); + expect(flinkApp.addToRolePolicy(new iam.PolicyStatement())).toBe(false); + }); + test('get metric', () => { const flinkApp = new flink.Application(stack, 'Application', { ...requiredProps }); expect(flinkApp.metric('KPUs', { statistic: 'Sum' })) diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.assets.json b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.assets.json new file mode 100644 index 0000000000000..705074e025672 --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.assets.json @@ -0,0 +1,32 @@ +{ + "version": "30.1.0", + "files": { + "8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577": { + "source": { + "path": "asset.8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "e6269b086e65eaed552c57d90811a297037300cdaf9403468e748cc1d22dc668": { + "source": { + "path": "FlinkAppTest.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e6269b086e65eaed552c57d90811a297037300cdaf9403468e748cc1d22dc668.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-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.template.json b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.template.json new file mode 100644 index 0000000000000..b2ab7859cf42a --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/FlinkAppTest.template.json @@ -0,0 +1,720 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "FlinkAppTest/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": "FlinkAppTest/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "FlinkAppTest/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": "FlinkAppTest/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "FlinkAppTest/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": "FlinkAppTest/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "FlinkAppTest/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": "FlinkAppTest/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "FlinkAppTest/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": "FlinkAppTest/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "FlinkAppTest/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": "FlinkAppTest/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "FlinkAppTest/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": "FlinkAppTest/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "AppRole1AF9B530": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "kinesisanalytics.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "AppRoleDefaultPolicy9CADBAA1": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "cloudwatch:PutMetricData", + "ec2:CreateNetworkInterface", + "ec2:CreateNetworkInterfacePermission", + "ec2:DeleteNetworkInterface", + "ec2:DescribeDhcpOptions", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeVpcs" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/*" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + } + ] + ] + } + ] + }, + { + "Action": "logs:DescribeLogGroups", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:*" + ] + ] + } + }, + { + "Action": "logs:DescribeLogStreams", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "AppLogGroupC72EEC8C", + "Arn" + ] + } + }, + { + "Action": "logs:PutLogEvents", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:", + { + "Ref": "AppLogGroupC72EEC8C" + }, + ":log-stream:", + { + "Ref": "AppLogStream3CAF66A7" + } + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "AppRoleDefaultPolicy9CADBAA1", + "Roles": [ + { + "Ref": "AppRole1AF9B530" + } + ] + } + }, + "AppSecurityGroupC292657D": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "FlinkAppTest/App/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "AppF1B96344": { + "Type": "AWS::KinesisAnalyticsV2::Application", + "Properties": { + "RuntimeEnvironment": "FLINK-1_15", + "ServiceExecutionRole": { + "Fn::GetAtt": [ + "AppRole1AF9B530", + "Arn" + ] + }, + "ApplicationConfiguration": { + "ApplicationCodeConfiguration": { + "CodeContent": { + "S3ContentLocation": { + "BucketARN": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":s3:::", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + } + ] + ] + }, + "FileKey": "8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577.zip" + } + }, + "CodeContentType": "ZIPFILE" + }, + "ApplicationSnapshotConfiguration": { + "SnapshotsEnabled": true + }, + "VpcConfigurations": [ + { + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "AppSecurityGroupC292657D", + "GroupId" + ] + } + ], + "SubnetIds": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + } + ] + } + }, + "DependsOn": [ + "AppRoleDefaultPolicy9CADBAA1", + "AppRole1AF9B530" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "AppLogGroupC72EEC8C": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "AppLogStream3CAF66A7": { + "Type": "AWS::Logs::LogStream", + "Properties": { + "LogGroupName": { + "Ref": "AppLogGroupC72EEC8C" + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "AppLoggingOption75BE995E": { + "Type": "AWS::KinesisAnalyticsV2::ApplicationCloudWatchLoggingOption", + "Properties": { + "ApplicationName": { + "Ref": "AppF1B96344" + }, + "CloudWatchLoggingOption": { + "LogStreamARN": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:", + { + "Ref": "AppLogGroupC72EEC8C" + }, + ":log-stream:", + { + "Ref": "AppLogStream3CAF66A7" + } + ] + ] + } + } + } + } + }, + "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-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.assets.json b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.assets.json new file mode 100644 index 0000000000000..e03abd70970a9 --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.assets.json @@ -0,0 +1,19 @@ +{ + "version": "30.1.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "VpcTestDefaultTestDeployAssert06A9965C.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-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.template.json b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/VpcTestDefaultTestDeployAssert06A9965C.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-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/asset.8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577/WordCount.jar b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/integ.vpc-application.js.snapshot/asset.8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577/WordCount.jar new file mode 100644 index 0000000000000000000000000000000000000000..9c533e6fea60771f319c0f4923cdbf728bdc72e0 GIT binary patch literal 15192 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 Date: Wed, 8 Mar 2023 16:42:31 -0600 Subject: [PATCH 22/22] feat(docdb): added ability to enable performance insights (#24039) Added the ability to enable performance insights in the L2 construct for DocumentDB Cluster so it can be enabled programmatically in all instances inside the cluster. > [CONTRIBUTING GUIDE]: https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md > [DESIGN GUIDELINES]: https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md Closes #24036. ---- *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-docdb/README.md | 20 +++++++ packages/@aws-cdk/aws-docdb/lib/cluster.ts | 8 +++ packages/@aws-cdk/aws-docdb/lib/instance.ts | 8 +++ .../@aws-cdk/aws-docdb/test/cluster.test.ts | 23 ++++++++ .../@aws-cdk/aws-docdb/test/instance.test.ts | 19 +++++++ .../aws-cdk-docdb-integ.assets.json | 6 +- .../aws-cdk-docdb-integ.template.json | 3 +- .../test/integ.cluster.js.snapshot/cdk.out | 2 +- .../test/integ.cluster.js.snapshot/integ.json | 2 +- .../integ.cluster.js.snapshot/manifest.json | 16 +++--- .../test/integ.cluster.js.snapshot/tree.json | 57 ++++++++++++------- .../@aws-cdk/aws-docdb/test/integ.cluster.ts | 1 + 12 files changed, 131 insertions(+), 34 deletions(-) diff --git a/packages/@aws-cdk/aws-docdb/README.md b/packages/@aws-cdk/aws-docdb/README.md index a86bfe5b77460..509959c8b186d 100644 --- a/packages/@aws-cdk/aws-docdb/README.md +++ b/packages/@aws-cdk/aws-docdb/README.md @@ -161,3 +161,23 @@ const cluster = new docdb.DatabaseCluster(this, 'Database', { cloudWatchLogsRetentionRole: myLogsPublishingRole, // Optional - a role will be created if not provided }); ``` + +## Enable Performance Insights + +By enabling this feature it will be cascaded and enabled in all instances inside the cluster: + +```ts +declare const vpc: ec2.Vpc; + +const cluster = new docdb.DatabaseCluster(this, 'Database', { + masterUser: { + username: 'myuser', + }, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.MEMORY5, ec2.InstanceSize.LARGE), + vpcSubnets: { + subnetType: ec2.SubnetType.PUBLIC, + }, + vpc, + enablePerformanceInsights: true, // Enable Performance Insights in all instances under this cluster +}); +``` diff --git a/packages/@aws-cdk/aws-docdb/lib/cluster.ts b/packages/@aws-cdk/aws-docdb/lib/cluster.ts index 03c4801d3977d..c26a8a63cbae5 100644 --- a/packages/@aws-cdk/aws-docdb/lib/cluster.ts +++ b/packages/@aws-cdk/aws-docdb/lib/cluster.ts @@ -183,6 +183,13 @@ export interface DatabaseClusterProps { * @default - a new role is created. */ readonly cloudWatchLogsRetentionRole?: IRole; + + /** + * A value that indicates whether to enable Performance Insights for the instances in the DB Cluster. + * + * @default - false + */ + readonly enablePerformanceInsights?: boolean; } /** @@ -509,6 +516,7 @@ export class DatabaseCluster extends DatabaseClusterBase { dbInstanceIdentifier: instanceIdentifier, // Instance properties dbInstanceClass: databaseInstanceType(props.instanceType), + enablePerformanceInsights: props.enablePerformanceInsights, }); instance.applyRemovalPolicy(props.removalPolicy, { diff --git a/packages/@aws-cdk/aws-docdb/lib/instance.ts b/packages/@aws-cdk/aws-docdb/lib/instance.ts index 9611235077389..2acf386893b4a 100644 --- a/packages/@aws-cdk/aws-docdb/lib/instance.ts +++ b/packages/@aws-cdk/aws-docdb/lib/instance.ts @@ -165,6 +165,13 @@ export interface DatabaseInstanceProps { * @default RemovalPolicy.Retain */ readonly removalPolicy?: cdk.RemovalPolicy + + /** + * A value that indicates whether to enable Performance Insights for the DB Instance. + * + * @default - false + */ + readonly enablePerformanceInsights?: boolean; } /** @@ -208,6 +215,7 @@ export class DatabaseInstance extends DatabaseInstanceBase implements IDatabaseI availabilityZone: props.availabilityZone, dbInstanceIdentifier: props.dbInstanceName, preferredMaintenanceWindow: props.preferredMaintenanceWindow, + enablePerformanceInsights: props.enablePerformanceInsights, }); this.cluster = props.cluster; diff --git a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts index 9b2ba729a7934..7e07f33f7d39f 100644 --- a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts @@ -706,6 +706,29 @@ describe('DatabaseCluster', () => { }); }); + test('can enable Performance Insights on instances', () => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + + // WHEN + new DatabaseCluster(stack, 'Database', { + masterUser: { + username: 'admin', + }, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + enablePerformanceInsights: true, + }); + + // THEN + Template.fromStack(stack).hasResource('AWS::DocDB::DBInstance', { + Properties: { + EnablePerformanceInsights: true, + }, + }); + }); + test('single user rotation', () => { // GIVEN const stack = testStack(); diff --git a/packages/@aws-cdk/aws-docdb/test/instance.test.ts b/packages/@aws-cdk/aws-docdb/test/instance.test.ts index 5c3fdb9e1f036..761c842efce56 100644 --- a/packages/@aws-cdk/aws-docdb/test/instance.test.ts +++ b/packages/@aws-cdk/aws-docdb/test/instance.test.ts @@ -172,6 +172,25 @@ describe('DatabaseInstance', () => { Value: `${instanceEndpointAddress}:${port}`, }); }); + + test('can enable performance insights on instances', () => { + // GIVEN + const stack = testStack(); + + // WHEN + new DatabaseInstance(stack, 'Instance', { + cluster: stack.cluster, + instanceType: SINGLE_INSTANCE_TYPE, + enablePerformanceInsights: true, + }); + + // THEN + Template.fromStack(stack).hasResource('AWS::DocDB::DBInstance', { + Properties: { + EnablePerformanceInsights: true, + }, + }); + }); }); class TestStack extends cdk.Stack { diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.assets.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.assets.json index d9f99b3ff0cac..bb7c2c7f22afd 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.assets.json +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "30.1.0", "files": { - "811c147f8ed74c3803d8df4f44e3f6a7e7779b21e729fc8cb3b66a685054a393": { + "f7cbfe0c634dda7840ec3c05f938c0badf4e3f4f4b183a058b1245d482d019bd": { "source": { "path": "aws-cdk-docdb-integ.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "811c147f8ed74c3803d8df4f44e3f6a7e7779b21e729fc8cb3b66a685054a393.json", + "objectKey": "f7cbfe0c634dda7840ec3c05f938c0badf4e3f4f4b183a058b1245d482d019bd.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-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.template.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.template.json index c810d3a1e6c3e..00e8e0ad2734e 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.template.json +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/aws-cdk-docdb-integ.template.json @@ -533,7 +533,8 @@ "DBClusterIdentifier": { "Ref": "DatabaseB269D8BB" }, - "DBInstanceClass": "db.r5.large" + "DBInstanceClass": "db.r5.large", + "EnablePerformanceInsights": true }, "DependsOn": [ "VPCPublicSubnet1DefaultRoute91CEF279", diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/cdk.out b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/cdk.out index 588d7b269d34f..b72fef144f05c 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"30.1.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/integ.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/integ.json index b26125fa26b7a..aa6bd7ed54c18 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "30.1.0", "testCases": { "integ.cluster": { "stacks": [ diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/manifest.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/manifest.json index 5acfb39cb3cc7..441cbfdd1f1b3 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "30.1.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-docdb-integ.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}/811c147f8ed74c3803d8df4f44e3f6a7e7779b21e729fc8cb3b66a685054a393.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/f7cbfe0c634dda7840ec3c05f938c0badf4e3f4f4b183a058b1245d482d019bd.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -233,6 +227,12 @@ ] }, "displayName": "aws-cdk-docdb-integ" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/tree.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/tree.json index e8252c13c9841..18a9822e08393 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.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-docdb-integ": { "id": "aws-cdk-docdb-integ", "path": "aws-cdk-docdb-integ", @@ -91,8 +83,8 @@ "id": "Acl", "path": "aws-cdk-docdb-integ/VPC/PublicSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -258,8 +250,8 @@ "id": "Acl", "path": "aws-cdk-docdb-integ/VPC/PublicSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -425,8 +417,8 @@ "id": "Acl", "path": "aws-cdk-docdb-integ/VPC/PrivateSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -544,8 +536,8 @@ "id": "Acl", "path": "aws-cdk-docdb-integ/VPC/PrivateSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -880,7 +872,8 @@ "dbClusterIdentifier": { "Ref": "DatabaseB269D8BB" }, - "dbInstanceClass": "db.r5.large" + "dbInstanceClass": "db.r5.large", + "enablePerformanceInsights": true } }, "constructInfo": { @@ -893,17 +886,41 @@ "fqn": "@aws-cdk/aws-docdb.DatabaseCluster", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-docdb-integ/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-docdb-integ/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.270" } } }, "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-docdb/test/integ.cluster.ts b/packages/@aws-cdk/aws-docdb/test/integ.cluster.ts index 1922febe59a98..f97ff065c7eb4 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.ts +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.ts @@ -41,6 +41,7 @@ class TestStack extends cdk.Stack { parameterGroup: params, kmsKey, removalPolicy: cdk.RemovalPolicy.DESTROY, + enablePerformanceInsights: true, }); cluster.connections.allowDefaultPortFromAnyIpv4('Open to the world');