From 919880793fdf79be460d87cfe633b05d37bcaa87 Mon Sep 17 00:00:00 2001 From: Parker Scanlon <69879391+scanlonp@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:22:23 -0700 Subject: [PATCH 01/14] fix(cloudwatch): setting gauge widget annotations caused deployment failures (#27720) A badly formed annotation was being added when annotations were set for gauge widgets (`yAxis: 'annotations'`). This caused errors on deployment. This change removes that extra annotation. Closes #25496. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...efaultTestDeployAssert1AF2B360.assets.json | 19 +++ ...aultTestDeployAssert1AF2B360.template.json | 36 +++++ .../integ.gauge-widget.js.snapshot/cdk.out | 1 + .../gauge-alarm.assets.json | 19 +++ .../gauge-alarm.template.json | 55 +++++++ .../integ.gauge-widget.js.snapshot/integ.json | 12 ++ .../manifest.json | 113 +++++++++++++++ .../integ.gauge-widget.js.snapshot/tree.json | 136 ++++++++++++++++++ .../aws-cloudwatch/test/integ.gauge-widget.ts | 41 ++++++ .../aws-cdk-lib/aws-cloudwatch/lib/graph.ts | 5 +- .../aws-cloudwatch/test/graphs.test.ts | 46 ++++++ 11 files changed, 479 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json new file mode 100644 index 0000000000000..85285ed67b8d5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "LambdaTestDefaultTestDeployAssert1AF2B360.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.assets.json new file mode 100644 index 0000000000000..b8071b6e7cfe9 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "767c8028870d07c3b106a2563078e7f26c3e63b6f4edae22b663db45fa6e84c5": { + "source": { + "path": "gauge-alarm.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "767c8028870d07c3b106a2563078e7f26c3e63b6f4edae22b663db45fa6e84c5.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-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.template.json new file mode 100644 index 0000000000000..3806af309571f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/gauge-alarm.template.json @@ -0,0 +1,55 @@ +{ + "Resources": { + "Dashboard9E4231ED": { + "Type": "AWS::CloudWatch::Dashboard", + "Properties": { + "DashboardBody": { + "Fn::Join": [ + "", + [ + "{\"widgets\":[{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":0,\"properties\":{\"view\":\"gauge\",\"title\":\"My gauge widget\",\"region\":\"", + { + "Ref": "AWS::Region" + }, + "\",\"metrics\":[[\"AWS/VPN\",\"TunnelState\",\"TunnelIpAddress\",\"123.123.123.123\",{\"stat\":\"Minimum\"}]],\"annotations\":{\"horizontal\":[{\"color\":\"#b2df8d\",\"label\":\"Up\",\"value\":5,\"fill\":\"above\"}]},\"yAxis\":{\"left\":{\"min\":0,\"max\":10}},\"period\":60,\"stat\":\"Minimum\"}}]}" + ] + ] + } + } + } + }, + "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-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/integ.json new file mode 100644 index 0000000000000..0284c558bff12 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "LambdaTest/DefaultTest": { + "stacks": [ + "gauge-alarm" + ], + "assertionStack": "LambdaTest/DefaultTest/DeployAssert", + "assertionStackName": "LambdaTestDefaultTestDeployAssert1AF2B360" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/manifest.json new file mode 100644 index 0000000000000..af348b5b6a7ae --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/manifest.json @@ -0,0 +1,113 @@ +{ + "version": "34.0.0", + "artifacts": { + "gauge-alarm.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "gauge-alarm.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "gauge-alarm": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "gauge-alarm.template.json", + "terminationProtection": false, + "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}/767c8028870d07c3b106a2563078e7f26c3e63b6f4edae22b663db45fa6e84c5.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "gauge-alarm.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": [ + "gauge-alarm.assets" + ], + "metadata": { + "/gauge-alarm/Dashboard/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Dashboard9E4231ED" + } + ], + "/gauge-alarm/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/gauge-alarm/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "gauge-alarm" + }, + "LambdaTestDefaultTestDeployAssert1AF2B360.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "LambdaTestDefaultTestDeployAssert1AF2B360.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "LambdaTestDefaultTestDeployAssert1AF2B360": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "LambdaTestDefaultTestDeployAssert1AF2B360.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "LambdaTestDefaultTestDeployAssert1AF2B360.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "LambdaTestDefaultTestDeployAssert1AF2B360.assets" + ], + "metadata": { + "/LambdaTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/LambdaTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "LambdaTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/tree.json new file mode 100644 index 0000000000000..9ac02e8b640b0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.js.snapshot/tree.json @@ -0,0 +1,136 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "gauge-alarm": { + "id": "gauge-alarm", + "path": "gauge-alarm", + "children": { + "Dashboard": { + "id": "Dashboard", + "path": "gauge-alarm/Dashboard", + "children": { + "Resource": { + "id": "Resource", + "path": "gauge-alarm/Dashboard/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudWatch::Dashboard", + "aws:cdk:cloudformation:props": { + "dashboardBody": { + "Fn::Join": [ + "", + [ + "{\"widgets\":[{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":0,\"properties\":{\"view\":\"gauge\",\"title\":\"My gauge widget\",\"region\":\"", + { + "Ref": "AWS::Region" + }, + "\",\"metrics\":[[\"AWS/VPN\",\"TunnelState\",\"TunnelIpAddress\",\"123.123.123.123\",{\"stat\":\"Minimum\"}]],\"annotations\":{\"horizontal\":[{\"color\":\"#b2df8d\",\"label\":\"Up\",\"value\":5,\"fill\":\"above\"}]},\"yAxis\":{\"left\":{\"min\":0,\"max\":10}},\"period\":60,\"stat\":\"Minimum\"}}]}" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudwatch.CfnDashboard", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudwatch.Dashboard", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "gauge-alarm/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "gauge-alarm/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "LambdaTest": { + "id": "LambdaTest", + "path": "LambdaTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "LambdaTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "LambdaTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "LambdaTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "LambdaTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "LambdaTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.ts new file mode 100644 index 0000000000000..04cf0b3fdd1d9 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.gauge-widget.ts @@ -0,0 +1,41 @@ +import * as cdk from 'aws-cdk-lib/core'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'gauge-alarm'); + +const dashboard = new cloudwatch.Dashboard(stack, 'Dashboard'); + +const widget = new cloudwatch.GaugeWidget({ + title: 'My gauge widget', + metrics: [new cloudwatch.Metric({ + namespace: 'AWS/VPN', + metricName: 'TunnelState', + dimensionsMap: { + TunnelIpAddress: '123.123.123.123', + }, + statistic: 'Minimum', + })], + leftYAxis: { + min: 0, + max: 10, + }, + annotations: [ + { + color: '#b2df8d', + label: 'Up', + value: 5, + fill: cloudwatch.Shading.ABOVE, + }, + ], + statistic: 'Minimum', + period: cdk.Duration.minutes(1), +}); + +dashboard.addWidgets(widget); + +new integ.IntegTest(app, 'LambdaTest', { + testCases: [stack], +}); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts b/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts index 91c2ffc54cce9..4d1071481c881 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts @@ -258,9 +258,6 @@ export class GaugeWidget extends ConcreteWidget { } public toJson(): any[] { - const horizontalAnnotations = [ - ...(this.props.annotations || []).map(mapAnnotation('annotations')), - ]; const metrics = allMetricsGraphJson(this.metrics, []); const leftYAxis = { @@ -279,7 +276,7 @@ export class GaugeWidget extends ConcreteWidget { title: this.props.title, region: this.props.region || cdk.Aws.REGION, metrics: metrics.length > 0 ? metrics : undefined, - annotations: horizontalAnnotations.length > 0 ? { horizontal: horizontalAnnotations } : undefined, + annotations: (this.props.annotations ?? []).length > 0 ? { horizontal: this.props.annotations } : undefined, yAxis: { left: leftYAxis ?? undefined, }, diff --git a/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts b/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts index 797ee88d88b2c..72ff2cca8a0ac 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts @@ -1040,4 +1040,50 @@ describe('Graphs', () => { }); }).toThrow(/If you specify a value for end, you must also specify a value for start./); }); + + test('add annotations to gauge widget', () => { + // GIVEN + const stack = new Stack(); + const widget = new GaugeWidget({ + metrics: [new Metric({ namespace: 'CDK', metricName: 'Test' })], + annotations: [ + { + color: '#b2df8d', + label: 'Up', + value: 1, + fill: Shading.ABOVE, + }, + ], + }); + + // THEN + expect(stack.resolve(widget.toJson())).toEqual([{ + type: 'metric', + width: 6, + height: 6, + properties: { + view: 'gauge', + region: { Ref: 'AWS::Region' }, + metrics: [ + ['CDK', 'Test'], + ], + yAxis: { + left: { + min: 0, + max: 100, + }, + }, + annotations: { + horizontal: [ + { + color: '#b2df8d', + label: 'Up', + value: 1, + fill: 'above', + }, + ], + }, + }, + }]); + }); }); From 292eec6cd17bdc5226225a7aea2e4cf6745fda11 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Mon, 30 Oct 2023 18:39:51 -0400 Subject: [PATCH 02/14] chore(apigatewayv2): turn on awslint (#27767) We've been bad and turned off awslint for a while. This turns it back on so future commits to this module will have to play nice with the linter. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-apigatewayv2-alpha/awslint.json | 10 +++++++++- .../@aws-cdk/aws-apigatewayv2-alpha/lib/http/api.ts | 12 ++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-apigatewayv2-alpha/awslint.json b/packages/@aws-cdk/aws-apigatewayv2-alpha/awslint.json index 3dab73aef9027..f3c891320b8a8 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-alpha/awslint.json +++ b/packages/@aws-cdk/aws-apigatewayv2-alpha/awslint.json @@ -1,5 +1,13 @@ { "exclude": [ - "*:*" + "props-physical-name:@aws-cdk/aws-apigatewayv2-alpha.ApiMappingProps", + "props-physical-name:@aws-cdk/aws-apigatewayv2-alpha.HttpIntegrationProps", + "props-physical-name:@aws-cdk/aws-apigatewayv2-alpha.HttpRouteProps", + "props-physical-name:@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegrationProps", + "props-physical-name:@aws-cdk/aws-apigatewayv2-alpha.WebSocketRouteProps", + "from-method:@aws-cdk/aws-apigatewayv2-alpha.HttpIntegration", + "from-method:@aws-cdk/aws-apigatewayv2-alpha.HttpRoute", + "from-method:@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", + "from-method:@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute" ] } diff --git a/packages/@aws-cdk/aws-apigatewayv2-alpha/lib/http/api.ts b/packages/@aws-cdk/aws-apigatewayv2-alpha/lib/http/api.ts index b6d2f6cef2dc8..51363ac2096c6 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-alpha/lib/http/api.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-alpha/lib/http/api.ts @@ -357,11 +357,19 @@ export class HttpApi extends HttpApiBase { */ public readonly defaultStage: IHttpStage | undefined; - private readonly _apiEndpoint: string; - + /** + * Default Authorizer applied to all routes in the gateway. + */ public readonly defaultAuthorizer?: IHttpRouteAuthorizer; + + /** + * Default OIDC scopes attached to all routes in the gateway, unless explicitly configured on the route. + * The scopes are used with a COGNITO_USER_POOLS authorizer to authorize the method invocation. + */ public readonly defaultAuthorizationScopes?: string[]; + private readonly _apiEndpoint: string; + constructor(scope: Construct, id: string, props?: HttpApiProps) { super(scope, id); From b545448b5f79659ed6e713f4a36df731549e9b7d Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Mon, 30 Oct 2023 19:10:52 -0400 Subject: [PATCH 03/14] chore(amplify): turn on awslint (#27766) We've been bad and turned off awslint for a while. This turns it back on so future commits to this module will have to play nice with the linter. ---- *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-amplify-alpha/awslint.json | 2 +- packages/@aws-cdk/aws-amplify-alpha/lib/app.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-amplify-alpha/awslint.json b/packages/@aws-cdk/aws-amplify-alpha/awslint.json index 3dab73aef9027..9c9d991ce2207 100644 --- a/packages/@aws-cdk/aws-amplify-alpha/awslint.json +++ b/packages/@aws-cdk/aws-amplify-alpha/awslint.json @@ -1,5 +1,5 @@ { "exclude": [ - "*:*" + "construct-ctor-props-optional:@aws-cdk/aws-amplify-alpha.App" ] } diff --git a/packages/@aws-cdk/aws-amplify-alpha/lib/app.ts b/packages/@aws-cdk/aws-amplify-alpha/lib/app.ts index 1398a1edf2c0d..622f74bd1817a 100644 --- a/packages/@aws-cdk/aws-amplify-alpha/lib/app.ts +++ b/packages/@aws-cdk/aws-amplify-alpha/lib/app.ts @@ -164,7 +164,7 @@ export interface AppProps { * generated (SSG) apps (i.e. a Create React App or Gatsby) and WEB_COMPUTE * for server side rendered (SSR) apps (i.e. NextJS). * - * @default - WEB + * @default Platform.WEB */ readonly platform?: Platform; } @@ -539,6 +539,9 @@ function renderCustomResponseHeaders(customHeaders: CustomResponseHeader[]): str return `${yaml.join('\n')}\n`; } +/** + * Available hosting platforms to use on the App. + */ export enum Platform { /** * WEB - Used to indicate that the app is hosted using only static assets. From c096aa7e9083fbb0a395acd6d0c8891960570827 Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Tue, 31 Oct 2023 06:35:23 -0700 Subject: [PATCH 04/14] chore: check region-info completeness (#27771) During the compatibility check, also check that no facts have disappeared from the `region-info` database. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk-lib/region-info/lib/fact.ts | 19 +++++++ scripts/check-api-compatibility.sh | 13 +++++ scripts/check-region-info-compatibility.ts | 59 ++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 scripts/check-region-info-compatibility.ts diff --git a/packages/aws-cdk-lib/region-info/lib/fact.ts b/packages/aws-cdk-lib/region-info/lib/fact.ts index 67bbe9ce42d52..4b1ecc6574a25 100644 --- a/packages/aws-cdk-lib/region-info/lib/fact.ts +++ b/packages/aws-cdk-lib/region-info/lib/fact.ts @@ -13,6 +13,25 @@ export class Fact { return [...new Set([...AWS_REGIONS, ...Object.keys(this.database)])]; } + /** + * Returns the list of names of registered facts. + * + * All facts will be present in at least one region. + */ + public static get names(): string[] { + return [...new Set(Object.values(this.database).flatMap(regionFacts => Object.keys(regionFacts)))]; + } + + /** + * Return all pairs of (region, factName) that are defined + */ + public static definedFacts(): Array { + return Object.entries(this.database) + .flatMap(([regionName, regionFacts]) => + Object.keys(regionFacts).map((factName) => + [regionName, factName] satisfies [string, string])); + } + /** * Retrieves a fact from this Fact database. * diff --git a/scripts/check-api-compatibility.sh b/scripts/check-api-compatibility.sh index 7311d0a74ce90..df9358485bb6c 100755 --- a/scripts/check-api-compatibility.sh +++ b/scripts/check-api-compatibility.sh @@ -3,6 +3,7 @@ set -eu repo_root="$(cd $(dirname $0)/.. && pwd)" +scriptdir="$repo_root/scripts" tmpdir=/tmp/compat-check package_name() { @@ -105,6 +106,18 @@ for dir in $jsii_package_dirs; do fi done +#---------------------------------------------------------------------- +# Do a special region-info check independently +echo -n "Checking region info facts... " +if npx ts-node $scriptdir/check-region-info-compatibility.ts $tmpdir/node_modules/aws-cdk-lib $repo_root/packages/aws-cdk-lib; then + echo "OK." +else + echo "MISSING." + success=false +fi + +#---------------------------------------------------------------------- + if $success; then echo "All OK." >&2 else diff --git a/scripts/check-region-info-compatibility.ts b/scripts/check-region-info-compatibility.ts new file mode 100644 index 0000000000000..175c82b8e215a --- /dev/null +++ b/scripts/check-region-info-compatibility.ts @@ -0,0 +1,59 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +/** + * Given two copies of the @aws-cdk/region-info database, check that no facts have disappeared between them + */ + +type AwsCdkLib = typeof import('aws-cdk-lib'); +type RegionInfoPackage = AwsCdkLib['region_info']; + +function main(oldPackage: string, newPackage: string) { + const breaksFile = path.join(__dirname, '..', 'allowed-breaking-changes.txt'); + const allowedBreaks = new Set(fs.readFileSync(breaksFile, { encoding: 'utf-8' }).split('\n')); + + const oldPkg: RegionInfoPackage = (require(oldPackage) as AwsCdkLib).region_info; + const newPkg: RegionInfoPackage = (require(newPackage) as AwsCdkLib).region_info; + + const oldFacts = definedFacts(oldPkg.Fact); + const newFacts = definedFacts(newPkg.Fact); + + const disappearedFacts = oldFacts + .filter((oldFact) => !newFacts.some((newFact) => factEq(oldFact, newFact))) + .map((fact) => ({ fact, key: `${fact[0]}:${fact[1]}` })) + .filter(({ key }) => !allowedBreaks.has(key)); + + if (disappearedFacts.length > 0) { + console.log('Facts have disappeared from region fact database (add to allowed-breaking-changes.txt to ignore):'); + for (const { key } of disappearedFacts) { + console.log(`- ${key}`); + process.exitCode = 1; + } + } +} + +/** + * Call Fact.definedFacts() on the given object, emulating it with hacks for versions of `region-info` that don't support it. + */ +function definedFacts(fact: RegionInfoPackage['Fact']): Array<[string, string]> { + if ((fact as any).definedFacts) { + return (fact as any).definedFacts(); + } + + // Access private member through trickery + const db: Record> = (fact as any).database; + return Object.entries(db) + .flatMap(([regionName, regionFacts]) => + Object.keys(regionFacts).map((factName) => + [regionName, factName] satisfies [string, string])); +} + +function factEq(a: [string, string], b: [string, string]) { + return a[0] === b[0] && a[1] === b[1]; +} + + +if (process.argv.length < 4) { + throw new Error('Usage: check-region-info-compatibility '); +} +main(process.argv[2], process.argv[3]); \ No newline at end of file From f9ee5e651a461fa7995823b556aa3b7c69c59a72 Mon Sep 17 00:00:00 2001 From: Kip <134538209+kishiel@users.noreply.github.com> Date: Tue, 31 Oct 2023 09:05:09 -0500 Subject: [PATCH 05/14] feat(eks): support updateConfig properties for managed node groups (#27593) This is a duplicate of [PR 27320](https://github.com/aws/aws-cdk/pull/27320) but on a new branch in my repo. This change enables nodegroups to configure updateConfig properties which will allow nodegroups to upgrade more than 1 instance at a time. The default value of 1 results in slow deployment times which prevented my service pipelines from quickly delivering fixes to my customers. This change allows each nodegroup to specify a maximum count of instances, or percent, which can be upgraded in parallel. --- .../apply/__init__.py | 0 .../get/__init__.py | 0 .../helm/__init__.py | 10 +- .../index.py | 0 .../patch/__init__.py | 0 .../cluster.d.ts | 0 .../cluster.js | 277 +++++++++++++++++ .../cluster.ts | 5 +- .../common.d.ts | 0 .../common.js | 0 .../common.ts | 0 .../compareLogging.d.ts | 0 .../compareLogging.js | 0 .../compareLogging.ts | 0 .../consts.d.ts | 0 .../consts.js | 0 .../consts.ts | 0 .../fargate.d.ts | 0 .../fargate.js | 102 +++++++ .../fargate.ts | 2 +- .../index.d.ts | 0 .../index.js | 2 +- .../index.ts | 2 +- .../cluster.js | 280 ------------------ .../fargate.js | 104 ------- .../cfn-response.js | 0 .../consts.js | 0 .../framework.js | 0 .../outbound.js | 75 +++++ .../util.js | 0 .../aws-cdk-eks-cluster-test.assets.json | 30 +- .../aws-cdk-eks-cluster-test.template.json | 16 +- ...ourceProvider5F388D1A.nested.template.json | 10 +- ...bectlProviderE05943BF.nested.template.json | 4 +- .../manifest.json | 4 +- .../integ.eks-cluster.js.snapshot/tree.json | 30 +- .../test/aws-eks/test/integ.eks-cluster.ts | 3 + packages/aws-cdk-lib/aws-eks/README.md | 21 ++ .../aws-eks/lib/managed-nodegroup.ts | 46 +++ .../aws-eks/test/nodegroup.test.ts | 119 ++++++++ 40 files changed, 707 insertions(+), 435 deletions(-) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779 => asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3}/apply/__init__.py (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779 => asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3}/get/__init__.py (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779 => asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3}/helm/__init__.py (97%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779 => asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3}/index.py (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779 => asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3}/patch/__init__.py (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/cluster.d.ts (100%) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.js rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/cluster.ts (98%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/common.d.ts (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/common.js (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/common.ts (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/compareLogging.d.ts (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/compareLogging.js (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/compareLogging.ts (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/consts.d.ts (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/consts.js (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/consts.ts (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/fargate.d.ts (100%) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.js rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/fargate.ts (97%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/index.d.ts (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/index.js (72%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934 => asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49}/index.ts (99%) delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.js delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.js rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db => asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef}/cfn-response.js (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db => asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef}/consts.js (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db => asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef}/framework.js (100%) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/outbound.js rename packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/{asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db => asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef}/util.js (100%) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/apply/__init__.py b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/apply/__init__.py similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/apply/__init__.py rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/apply/__init__.py diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/get/__init__.py b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/get/__init__.py similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/get/__init__.py rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/get/__init__.py diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/helm/__init__.py b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/helm/__init__.py similarity index 97% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/helm/__init__.py rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/helm/__init__.py index ce5fe63925637..3a5656f46db91 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/helm/__init__.py +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/helm/__init__.py @@ -100,8 +100,8 @@ def helm_handler(event, context): def get_oci_cmd(repository, version): # Generates OCI command based on pattern. Public ECR vs Private ECR are treated differently. - private_ecr_pattern = 'oci://(?P\d+.dkr.ecr.(?P[a-z0-9\-]+).amazonaws.com)*' - public_ecr_pattern = 'oci://(?Ppublic.ecr.aws)*' + private_ecr_pattern = 'oci://(?P\d+\.dkr\.ecr\.(?P[a-z0-9\-]+)\.amazonaws\.com)*' + public_ecr_pattern = 'oci://(?Ppublic\.ecr\.aws)*' private_registry = re.match(private_ecr_pattern, repository).groupdict() public_registry = re.match(public_ecr_pattern, repository).groupdict() @@ -115,7 +115,7 @@ def get_oci_cmd(repository, version): elif public_registry['registry'] is not None: logger.info("Found AWS public repository, will use default region as deployment") region = os.environ.get('AWS_REGION', 'us-east-1') - + if is_ecr_public_available(region): cmnd = [ f"aws ecr-public get-login-password --region us-east-1 | " \ @@ -124,7 +124,7 @@ def get_oci_cmd(repository, version): else: # `aws ecr-public get-login-password` and `helm registry login` not required as ecr public is not available in current region # see https://helm.sh/docs/helm/helm_registry_login/ - cmnd = [f"helm pull {repository} --version {version} --untar"] + cmnd = [f"helm pull {repository} --version {version} --untar"] else: logger.error("OCI repository format not recognized, falling back to helm pull") cmnd = [f"helm pull {repository} --version {version} --untar"] @@ -144,7 +144,7 @@ def get_chart_from_oci(tmpdir, repository = None, version = None): output = subprocess.check_output(cmnd, stderr=subprocess.STDOUT, cwd=tmpdir, shell=True) logger.info(output) - # effectively returns "$tmpDir/$lastPartOfOCIUrl", because this is how helm pull saves OCI artifact. + # effectively returns "$tmpDir/$lastPartOfOCIUrl", because this is how helm pull saves OCI artifact. # Eg. if we have oci://9999999999.dkr.ecr.us-east-1.amazonaws.com/foo/bar/pet-service repository, helm saves artifact under $tmpDir/pet-service return os.path.join(tmpdir, repository.rpartition('/')[-1]) except subprocess.CalledProcessError as exc: diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/index.py b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/index.py similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/index.py rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/index.py diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/patch/__init__.py b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/patch/__init__.py similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779/patch/__init__.py rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3/patch/__init__.py diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.d.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.d.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.d.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.js new file mode 100644 index 0000000000000..37f410e998666 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.js @@ -0,0 +1,277 @@ +"use strict"; +/* eslint-disable no-console */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ClusterResourceHandler = void 0; +const common_1 = require("./common"); +const compareLogging_1 = require("./compareLogging"); +const MAX_CLUSTER_NAME_LEN = 100; +class ClusterResourceHandler extends common_1.ResourceHandler { + get clusterName() { + if (!this.physicalResourceId) { + throw new Error('Cannot determine cluster name without physical resource ID'); + } + return this.physicalResourceId; + } + constructor(eks, event) { + super(eks, event); + this.newProps = parseProps(this.event.ResourceProperties); + this.oldProps = event.RequestType === 'Update' ? parseProps(event.OldResourceProperties) : {}; + // compare newProps and oldProps and update the newProps by appending disabled LogSetup if any + const compared = (0, compareLogging_1.compareLoggingProps)(this.oldProps, this.newProps); + this.newProps.logging = compared.logging; + } + // ------ + // CREATE + // ------ + async onCreate() { + console.log('onCreate: creating cluster with options:', JSON.stringify(this.newProps, undefined, 2)); + if (!this.newProps.roleArn) { + throw new Error('"roleArn" is required'); + } + const clusterName = this.newProps.name || this.generateClusterName(); + const resp = await this.eks.createCluster({ + ...this.newProps, + name: clusterName, + }); + if (!resp.cluster) { + throw new Error(`Error when trying to create cluster ${clusterName}: CreateCluster returned without cluster information`); + } + return { + PhysicalResourceId: resp.cluster.name, + }; + } + async isCreateComplete() { + return this.isActive(); + } + // ------ + // DELETE + // ------ + async onDelete() { + console.log(`onDelete: deleting cluster ${this.clusterName}`); + try { + await this.eks.deleteCluster({ name: this.clusterName }); + } + catch (e) { + if (e.name !== 'ResourceNotFoundException') { + throw e; + } + else { + console.log(`cluster ${this.clusterName} not found, idempotently succeeded`); + } + } + return { + PhysicalResourceId: this.clusterName, + }; + } + async isDeleteComplete() { + console.log(`isDeleteComplete: waiting for cluster ${this.clusterName} to be deleted`); + try { + const resp = await this.eks.describeCluster({ name: this.clusterName }); + console.log('describeCluster returned:', JSON.stringify(resp, undefined, 2)); + } + catch (e) { + if (e.name === 'ResourceNotFoundException') { + console.log('received ResourceNotFoundException, this means the cluster has been deleted (or never existed)'); + return { IsComplete: true }; + } + console.log('describeCluster error:', e); + throw e; + } + return { + IsComplete: false, + }; + } + // ------ + // UPDATE + // ------ + async onUpdate() { + const updates = analyzeUpdate(this.oldProps, this.newProps); + console.log('onUpdate:', JSON.stringify({ updates }, undefined, 2)); + // updates to encryption config is not supported + if (updates.updateEncryption) { + throw new Error('Cannot update cluster encryption configuration'); + } + // if there is an update that requires replacement, go ahead and just create + // a new cluster with the new config. The old cluster will automatically be + // deleted by cloudformation upon success. + if (updates.replaceName || updates.replaceRole || updates.replaceVpc) { + // if we are replacing this cluster and the cluster has an explicit + // physical name, the creation of the new cluster will fail with "there is + // already a cluster with that name". this is a common behavior for + // CloudFormation resources that support specifying a physical name. + if (this.oldProps.name === this.newProps.name && this.oldProps.name) { + throw new Error(`Cannot replace cluster "${this.oldProps.name}" since it has an explicit physical name. Either rename the cluster or remove the "name" configuration`); + } + return this.onCreate(); + } + // if a version update is required, issue the version update + if (updates.updateVersion) { + if (!this.newProps.version) { + throw new Error(`Cannot remove cluster version configuration. Current version is ${this.oldProps.version}`); + } + return this.updateClusterVersion(this.newProps.version); + } + if (updates.updateLogging && updates.updateAccess) { + throw new Error('Cannot update logging and access at the same time'); + } + if (updates.updateLogging || updates.updateAccess) { + const config = { + name: this.clusterName, + }; + if (updates.updateLogging) { + config.logging = this.newProps.logging; + } + ; + if (updates.updateAccess) { + // Updating the cluster with securityGroupIds and subnetIds (as specified in the warning here: + // https://awscli.amazonaws.com/v2/documentation/api/latest/reference/eks/update-cluster-config.html) + // will fail, therefore we take only the access fields explicitly + config.resourcesVpcConfig = { + endpointPrivateAccess: this.newProps.resourcesVpcConfig?.endpointPrivateAccess, + endpointPublicAccess: this.newProps.resourcesVpcConfig?.endpointPublicAccess, + publicAccessCidrs: this.newProps.resourcesVpcConfig?.publicAccessCidrs, + }; + } + const updateResponse = await this.eks.updateClusterConfig(config); + return { EksUpdateId: updateResponse.update?.id }; + } + // no updates + return; + } + async isUpdateComplete() { + console.log('isUpdateComplete'); + // if this is an EKS update, we will monitor the update event itself + if (this.event.EksUpdateId) { + const complete = await this.isEksUpdateComplete(this.event.EksUpdateId); + if (!complete) { + return { IsComplete: false }; + } + // fall through: if the update is done, we simply delegate to isActive() + // in order to extract attributes and state from the cluster itself, which + // is supposed to be in an ACTIVE state after the update is complete. + } + return this.isActive(); + } + async updateClusterVersion(newVersion) { + console.log(`updating cluster version to ${newVersion}`); + // update-cluster-version will fail if we try to update to the same version, + // so skip in this case. + const cluster = (await this.eks.describeCluster({ name: this.clusterName })).cluster; + if (cluster?.version === newVersion) { + console.log(`cluster already at version ${cluster.version}, skipping version update`); + return; + } + const updateResponse = await this.eks.updateClusterVersion({ name: this.clusterName, version: newVersion }); + return { EksUpdateId: updateResponse.update?.id }; + } + async isActive() { + console.log('waiting for cluster to become ACTIVE'); + const resp = await this.eks.describeCluster({ name: this.clusterName }); + console.log('describeCluster result:', JSON.stringify(resp, undefined, 2)); + const cluster = resp.cluster; + // if cluster is undefined (shouldnt happen) or status is not ACTIVE, we are + // not complete. note that the custom resource provider framework forbids + // returning attributes (Data) if isComplete is false. + if (cluster?.status === 'FAILED') { + // not very informative, unfortunately the response doesn't contain any error + // information :\ + throw new Error('Cluster is in a FAILED status'); + } + else if (cluster?.status !== 'ACTIVE') { + return { + IsComplete: false, + }; + } + else { + return { + IsComplete: true, + Data: { + Name: cluster.name, + Endpoint: cluster.endpoint, + Arn: cluster.arn, + // IMPORTANT: CFN expects that attributes will *always* have values, + // so return an empty string in case the value is not defined. + // Otherwise, CFN will throw with `Vendor response doesn't contain + // XXXX key`. + CertificateAuthorityData: cluster.certificateAuthority?.data ?? '', + ClusterSecurityGroupId: cluster.resourcesVpcConfig?.clusterSecurityGroupId ?? '', + OpenIdConnectIssuerUrl: cluster.identity?.oidc?.issuer ?? '', + OpenIdConnectIssuer: cluster.identity?.oidc?.issuer?.substring(8) ?? '', + // We can safely return the first item from encryption configuration array, because it has a limit of 1 item + // https://docs.amazon.com/eks/latest/APIReference/API_CreateCluster.html#AmazonEKS-CreateCluster-request-encryptionConfig + EncryptionConfigKeyArn: cluster.encryptionConfig?.shift()?.provider?.keyArn ?? '', + }, + }; + } + } + async isEksUpdateComplete(eksUpdateId) { + this.log({ isEksUpdateComplete: eksUpdateId }); + const describeUpdateResponse = await this.eks.describeUpdate({ + name: this.clusterName, + updateId: eksUpdateId, + }); + this.log({ describeUpdateResponse }); + if (!describeUpdateResponse.update) { + throw new Error(`unable to describe update with id "${eksUpdateId}"`); + } + switch (describeUpdateResponse.update.status) { + case 'InProgress': + return false; + case 'Successful': + return true; + case 'Failed': + case 'Cancelled': + throw new Error(`cluster update id "${eksUpdateId}" failed with errors: ${JSON.stringify(describeUpdateResponse.update.errors)}`); + default: + throw new Error(`unknown status "${describeUpdateResponse.update.status}" for update id "${eksUpdateId}"`); + } + } + generateClusterName() { + const suffix = this.requestId.replace(/-/g, ''); // 32 chars + const offset = MAX_CLUSTER_NAME_LEN - suffix.length - 1; + const prefix = this.logicalResourceId.slice(0, offset > 0 ? offset : 0); + return `${prefix}-${suffix}`; + } +} +exports.ClusterResourceHandler = ClusterResourceHandler; +function parseProps(props) { + const parsed = props?.Config ?? {}; + // this is weird but these boolean properties are passed by CFN as a string, and we need them to be booleanic for the SDK. + // Otherwise it fails with 'Unexpected Parameter: params.resourcesVpcConfig.endpointPrivateAccess is expected to be a boolean' + if (typeof (parsed.resourcesVpcConfig?.endpointPrivateAccess) === 'string') { + parsed.resourcesVpcConfig.endpointPrivateAccess = parsed.resourcesVpcConfig.endpointPrivateAccess === 'true'; + } + if (typeof (parsed.resourcesVpcConfig?.endpointPublicAccess) === 'string') { + parsed.resourcesVpcConfig.endpointPublicAccess = parsed.resourcesVpcConfig.endpointPublicAccess === 'true'; + } + if (typeof (parsed.logging?.clusterLogging[0].enabled) === 'string') { + parsed.logging.clusterLogging[0].enabled = parsed.logging.clusterLogging[0].enabled === 'true'; + } + return parsed; +} +function analyzeUpdate(oldProps, newProps) { + console.log('old props: ', JSON.stringify(oldProps)); + console.log('new props: ', JSON.stringify(newProps)); + const newVpcProps = newProps.resourcesVpcConfig || {}; + const oldVpcProps = oldProps.resourcesVpcConfig || {}; + const oldPublicAccessCidrs = new Set(oldVpcProps.publicAccessCidrs ?? []); + const newPublicAccessCidrs = new Set(newVpcProps.publicAccessCidrs ?? []); + const newEnc = newProps.encryptionConfig || {}; + const oldEnc = oldProps.encryptionConfig || {}; + return { + replaceName: newProps.name !== oldProps.name, + replaceVpc: JSON.stringify(newVpcProps.subnetIds?.sort()) !== JSON.stringify(oldVpcProps.subnetIds?.sort()) || + JSON.stringify(newVpcProps.securityGroupIds?.sort()) !== JSON.stringify(oldVpcProps.securityGroupIds?.sort()), + updateAccess: newVpcProps.endpointPrivateAccess !== oldVpcProps.endpointPrivateAccess || + newVpcProps.endpointPublicAccess !== oldVpcProps.endpointPublicAccess || + !setsEqual(newPublicAccessCidrs, oldPublicAccessCidrs), + replaceRole: newProps.roleArn !== oldProps.roleArn, + updateVersion: newProps.version !== oldProps.version, + updateEncryption: JSON.stringify(newEnc) !== JSON.stringify(oldEnc), + updateLogging: JSON.stringify(newProps.logging) !== JSON.stringify(oldProps.logging), + }; +} +function setsEqual(first, second) { + return first.size === second.size && [...first].every((e) => second.has(e)); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2x1c3Rlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsdXN0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtCQUErQjs7O0FBSS9CLHFDQUFxRTtBQUNyRSxxREFBdUQ7QUFHdkQsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLENBQUM7QUFFakMsTUFBYSxzQkFBdUIsU0FBUSx3QkFBZTtJQUN6RCxJQUFXLFdBQVc7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDREQUE0RCxDQUFDLENBQUM7U0FDL0U7UUFFRCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztLQUNoQztJQUtELFlBQVksR0FBYyxFQUFFLEtBQW9CO1FBQzlDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlGLDhGQUE4RjtRQUM5RixNQUFNLFFBQVEsR0FBMkMsSUFBQSxvQ0FBbUIsRUFBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzRyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDO0tBQzFDO0lBRUQsU0FBUztJQUNULFNBQVM7SUFDVCxTQUFTO0lBRUMsS0FBSyxDQUFDLFFBQVE7UUFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFF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QW9CLEVBQUUsb0JBQW9CLENBQUM7UUFDeEQsV0FBVyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLE9BQU87UUFDbEQsYUFBYSxFQUFFLFFBQVEsQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLE9BQU87UUFDcEQsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUNuRSxhQUFhLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO0tBQ3JGLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsS0FBa0IsRUFBRSxNQUFtQjtJQUN4RCxPQUFPLEtBQUssQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0ICogYXMgRUtTIGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1la3MnO1xuaW1wb3J0IHsgRWtzQ2xpZW50LCBSZXNvdXJjZUV2ZW50LCBSZXNvdXJjZUhhbmRsZXIgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgeyBjb21wYXJlTG9nZ2luZ1Byb3BzIH0gZnJvbSAnLi9jb21wYXJlTG9nZ2luZyc7XG5pbXBvcnQgeyBJc0NvbXBsZXRlUmVzcG9uc2UsIE9uRXZlbnRSZXNwb25zZSB9IGZyb20gJy4uLy4uLy4uL2N1c3RvbS1yZXNvdXJjZXMvbGliL3Byb3ZpZGVyLWZyYW1ld29yay90eXBlcyc7XG5cbmNvbnN0IE1BWF9DTFVTVEVSX05BTUVfTEVOID0gMTAwO1xuXG5leHBvcnQgY2xhc3MgQ2x1c3RlclJlc291cmNlSGFuZGxlciBleHRlbmRzIFJlc291cmNlSGFuZGxlciB7XG4gIHB1YmxpYyBnZXQgY2x1c3Rlck5hbWUoKSB7XG4gICAgaWYgKCF0aGlzLnBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZGV0ZXJtaW5lIGNsdXN0ZXIgbmFtZSB3aXRob3V0IHBoeXNpY2FsIHJlc291cmNlIElEJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucGh5c2ljYWxSZXNvdXJjZUlkO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBuZXdQcm9wczogRUtTLkNyZWF0ZUNsdXN0ZXJDb21tYW5kSW5wdXQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgb2xkUHJvcHM6IFBhcnRpYWw8RUtTLkNyZWF0ZUNsdXN0ZXJDb21tYW5kSW5wdXQ+O1xuXG4gIGNvbnN0cnVjdG9yKGVrczogRWtzQ2xpZW50LCBldmVudDogUmVzb3VyY2VFdmVudCkge1xuICAgIHN1cGVyKGVrcywgZXZlbnQpO1xuXG4gICAgdGhpcy5uZXdQcm9wcyA9IHBhcnNlUHJvcHModGhpcy5ldmVudC5SZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgIHRoaXMub2xkUHJvcHMgPSBldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ1VwZGF0ZScgPyBwYXJzZVByb3BzKGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcykgOiB7fTtcbiAgICAvLyBjb21wYXJlIG5ld1Byb3BzIGFuZCBvbGRQcm9wcyBhbmQgdXBkYXRlIHRoZSBuZXdQcm9wcyBieSBhcHBlbmRpbmcgZGlzYWJsZWQgTG9nU2V0dXAgaWYgYW55XG4gICAgY29uc3QgY29tcGFyZWQ6IFBhcnRpYWw8RUtTLkNyZWF0ZUNsdXN0ZXJDb21tYW5kSW5wdXQ+ID0gY29tcGFyZUxvZ2dpbmdQcm9wcyh0aGlzLm9sZFByb3BzLCB0aGlzLm5ld1Byb3BzKTtcbiAgICB0aGlzLm5ld1Byb3BzLmxvZ2dpbmcgPSBjb21wYXJlZC5sb2dnaW5nO1xuICB9XG5cbiAgLy8gLS0tLS0tXG4gIC8vIENSRUFURVxuICAvLyAtLS0tLS1cblxuICBwcm90ZWN0ZWQgYXN5bmMgb25DcmVhdGUoKTogUHJvbWlzZTxPbkV2ZW50UmVzcG9uc2U+IHtcbiAgICBjb25zb2xlLmxvZygnb25DcmVhdGU6IGNyZWF0aW5nIGNsdXN0ZXIgd2l0aCBvcHRpb25zOicsIEpTT04uc3RyaW5naWZ5KHRoaXMubmV3UHJvcHMsIHVuZGVmaW5lZCwgMikpO1xuICAgIGlmICghdGhpcy5uZXdQcm9wcy5yb2xlQXJuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1wicm9sZUFyblwiIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgY2x1c3Rlck5hbWUgPSB0aGlzLm5ld1Byb3BzLm5hbWUgfHwgdGhpcy5nZW5lcmF0ZUNsdXN0ZXJOYW1lKCk7XG5cbiAgICBjb25zdCByZXNwID0gYXdhaXQgdGhpcy5la3MuY3JlYXRlQ2x1c3Rlcih7XG4gICAgICAuLi50aGlzLm5ld1Byb3BzLFxuICAgICAgbmFtZTogY2x1c3Rlck5hbWUsXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3AuY2x1c3Rlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciB3aGVuIHRyeWluZyB0byBjcmVhdGUgY2x1c3RlciAke2NsdXN0ZXJOYW1lfTogQ3JlYXRlQ2x1c3RlciByZXR1cm5lZCB3aXRob3V0IGNsdXN0ZXIgaW5mb3JtYXRpb25gKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgUGh5c2ljYWxSZXNvdXJjZUlkOiByZXNwLmNsdXN0ZXIubmFtZSxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlzQ3JlYXRlQ29tcGxldGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNBY3RpdmUoKTtcbiAgfVxuXG4gIC8vIC0tLS0tLVxuICAvLyBERUxFVEVcbiAgLy8gLS0tLS0tXG5cbiAgcHJvdGVjdGVkIGFzeW5jIG9uRGVsZXRlKCk6IFByb21pc2U8T25FdmVudFJlc3BvbnNlPiB7XG4gICAgY29uc29sZS5sb2coYG9uRGVsZXRlOiBkZWxldGluZyBjbHVzdGVyICR7dGhpcy5jbHVzdGVyTmFtZX1gKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5la3MuZGVsZXRlQ2x1c3Rlcih7IG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUgfSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoZS5uYW1lICE9PSAnUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBjbHVzdGVyICR7dGhpcy5jbHVzdGVyTmFtZX0gbm90IGZvdW5kLCBpZGVtcG90ZW50bHkgc3VjY2VlZGVkYCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHRoaXMuY2x1c3Rlck5hbWUsXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpc0RlbGV0ZUNvbXBsZXRlKCk6IFByb21pc2U8SXNDb21wbGV0ZVJlc3BvbnNlPiB7XG4gICAgY29uc29sZS5sb2coYGlzRGVsZXRlQ29tcGxldGU6IHdhaXRpbmcgZm9yIGNsdXN0ZXIgJHt0aGlzLmNsdXN0ZXJOYW1lfSB0byBiZSBkZWxldGVkYCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHRoaXMuZWtzLmRlc2NyaWJlQ2x1c3Rlcih7IG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUgfSk7XG4gICAgICBjb25zb2xlLmxvZygnZGVzY3JpYmVDbHVzdGVyIHJldHVybmVkOicsIEpTT04uc3RyaW5naWZ5KHJlc3AsIHVuZGVmaW5lZCwgMikpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKGUubmFtZSA9PT0gJ1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24nKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdyZWNlaXZlZCBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uLCB0aGlzIG1lYW5zIHRoZSBjbHVzdGVyIGhhcyBiZWVuIGRlbGV0ZWQgKG9yIG5ldmVyIGV4aXN0ZWQpJyk7XG4gICAgICAgIHJldHVybiB7IElzQ29tcGxldGU6IHRydWUgfTtcbiAgICAgIH1cblxuICAgICAgY29uc29sZS5sb2coJ2Rlc2NyaWJlQ2x1c3RlciBlcnJvcjonLCBlKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIElzQ29tcGxldGU6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICAvLyAtLS0tLS1cbiAgLy8gVVBEQVRFXG4gIC8vIC0tLS0tLVxuXG4gIHByb3RlY3RlZCBhc3luYyBvblVwZGF0ZSgpIHtcbiAgICBjb25zdCB1cGRhdGVzID0gYW5hbHl6ZVVwZGF0ZSh0aGlzLm9sZFByb3BzLCB0aGlzLm5ld1Byb3BzKTtcbiAgICBjb25zb2xlLmxvZygnb25VcGRhdGU6JywgSlNPTi5zdHJpbmdpZnkoeyB1cGRhdGVzIH0sIHVuZGVmaW5lZCwgMikpO1xuXG4gICAgLy8gdXBkYXRlcyB0byBlbmNyeXB0aW9uIGNvbmZpZyBpcyBub3Qgc3VwcG9ydGVkXG4gICAgaWYgKHVwZGF0ZXMudXBkYXRlRW5jcnlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgdXBkYXRlIGNsdXN0ZXIgZW5jcnlwdGlvbiBjb25maWd1cmF0aW9uJyk7XG4gICAgfVxuXG4gICAgLy8gaWYgdGhlcmUgaXMgYW4gdXBkYXRlIHRoYXQgcmVxdWlyZXMgcmVwbGFjZW1lbnQsIGdvIGFoZWFkIGFuZCBqdXN0IGNyZWF0ZVxuICAgIC8vIGEgbmV3IGNsdXN0ZXIgd2l0aCB0aGUgbmV3IGNvbmZpZy4gVGhlIG9sZCBjbHVzdGVyIHdpbGwgYXV0b21hdGljYWxseSBiZVxuICAgIC8vIGRlbGV0ZWQgYnkgY2xvdWRmb3JtYXRpb24gdXBvbiBzdWNjZXNzLlxuICAgIGlmICh1cGRhdGVzLnJlcGxhY2VOYW1lIHx8IHVwZGF0ZXMucmVwbGFjZVJvbGUgfHwgdXBkYXRlcy5yZXBsYWNlVnBjKSB7XG5cbiAgICAgIC8vIGlmIHdlIGFyZSByZXBsYWNpbmcgdGhpcyBjbHVzdGVyIGFuZCB0aGUgY2x1c3RlciBoYXMgYW4gZXhwbGljaXRcbiAgICAgIC8vIHBoeXNpY2FsIG5hbWUsIHRoZSBjcmVhdGlvbiBvZiB0aGUgbmV3IGNsdXN0ZXIgd2lsbCBmYWlsIHdpdGggXCJ0aGVyZSBpc1xuICAgICAgLy8gYWxyZWFkeSBhIGNsdXN0ZXIgd2l0aCB0aGF0IG5hbWVcIi4gdGhpcyBpcyBhIGNvbW1vbiBiZWhhdmlvciBmb3JcbiAgICAgIC8vIENsb3VkRm9ybWF0aW9uIHJlc291cmNlcyB0aGF0IHN1cHBvcnQgc3BlY2lmeWluZyBhIHBoeXNpY2FsIG5hbWUuXG4gICAgICBpZiAodGhpcy5vbGRQcm9wcy5uYW1lID09PSB0aGlzLm5ld1Byb3BzLm5hbWUgJiYgdGhpcy5vbGRQcm9wcy5uYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlcGxhY2UgY2x1c3RlciBcIiR7dGhpcy5vbGRQcm9wcy5uYW1lfVwiIHNpbmNlIGl0IGhhcyBhbiBleHBsaWNpdCBwaHlzaWNhbCBuYW1lLiBFaXRoZXIgcmVuYW1lIHRoZSBjbHVzdGVyIG9yIHJlbW92ZSB0aGUgXCJuYW1lXCIgY29uZmlndXJhdGlvbmApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5vbkNyZWF0ZSgpO1xuICAgIH1cblxuICAgIC8vIGlmIGEgdmVyc2lvbiB1cGRhdGUgaXMgcmVxdWlyZWQsIGlzc3VlIHRoZSB2ZXJzaW9uIHVwZGF0ZVxuICAgIGlmICh1cGRhdGVzLnVwZGF0ZVZlcnNpb24pIHtcbiAgICAgIGlmICghdGhpcy5uZXdQcm9wcy52ZXJzaW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlbW92ZSBjbHVzdGVyIHZlcnNpb24gY29uZmlndXJhdGlvbi4gQ3VycmVudCB2ZXJzaW9uIGlzICR7dGhpcy5vbGRQcm9wcy52ZXJzaW9ufWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy51cGRhdGVDbHVzdGVyVmVyc2lvbih0aGlzLm5ld1Byb3BzLnZlcnNpb24pO1xuICAgIH1cblxuICAgIGlmICh1cGRhdGVzLnVwZGF0ZUxvZ2dpbmcgJiYgdXBkYXRlcy51cGRhdGVBY2Nlc3MpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHVwZGF0ZSBsb2dnaW5nIGFuZCBhY2Nlc3MgYXQgdGhlIHNhbWUgdGltZScpO1xuICAgIH1cblxuICAgIGlmICh1cGRhdGVzLnVwZGF0ZUxvZ2dpbmcgfHwgdXBkYXRlcy51cGRhdGVBY2Nlc3MpIHtcbiAgICAgIGNvbnN0IGNvbmZpZzogRUtTLlVwZGF0ZUNsdXN0ZXJDb25maWdDb21tYW5kSW5wdXQgPSB7XG4gICAgICAgIG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUsXG4gICAgICB9O1xuICAgICAgaWYgKHVwZGF0ZXMudXBkYXRlTG9nZ2luZykge1xuICAgICAgICBjb25maWcubG9nZ2luZyA9IHRoaXMubmV3UHJvcHMubG9nZ2luZztcbiAgICAgIH07XG4gICAgICBpZiAodXBkYXRlcy51cGRhdGVBY2Nlc3MpIHtcbiAgICAgICAgLy8gVXBkYXRpbmcgdGhlIGNsdXN0ZXIgd2l0aCBzZWN1cml0eUdyb3VwSWRzIGFuZCBzdWJuZXRJZHMgKGFzIHNwZWNpZmllZCBpbiB0aGUgd2FybmluZyBoZXJlOlxuICAgICAgICAvLyBodHRwczovL2F3c2NsaS5hbWF6b25hd3MuY29tL3YyL2RvY3VtZW50YXRpb24vYXBpL2xhdGVzdC9yZWZlcmVuY2UvZWtzL3VwZGF0ZS1jbHVzdGVyLWNvbmZpZy5odG1sKVxuICAgICAgICAvLyB3aWxsIGZhaWwsIHRoZXJlZm9yZSB3ZSB0YWtlIG9ubHkgdGhlIGFjY2VzcyBmaWVsZHMgZXhwbGljaXRseVxuICAgICAgICBjb25maWcucmVzb3VyY2VzVnBjQ29uZmlnID0ge1xuICAgICAgICAgIGVuZHBvaW50UHJpdmF0ZUFjY2VzczogdGhpcy5uZXdQcm9wcy5yZXNvdXJjZXNWcGNDb25maWc/LmVuZHBvaW50UHJpdmF0ZUFjY2VzcyxcbiAgICAgICAgICBlbmRwb2ludFB1YmxpY0FjY2VzczogdGhpcy5uZXdQcm9wcy5yZXNvdXJjZXNWcGNDb25maWc/LmVuZHBvaW50UHVibGljQWNjZXNzLFxuICAgICAgICAgIHB1YmxpY0FjY2Vzc0NpZHJzOiB0aGlzLm5ld1Byb3BzLnJlc291cmNlc1ZwY0NvbmZpZz8ucHVibGljQWNjZXNzQ2lkcnMsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBjb25zdCB1cGRhdGVSZXNwb25zZSA9IGF3YWl0IHRoaXMuZWtzLnVwZGF0ZUNsdXN0ZXJDb25maWcoY29uZmlnKTtcblxuICAgICAgcmV0dXJuIHsgRWtzVXBkYXRlSWQ6IHVwZGF0ZVJlc3BvbnNlLnVwZGF0ZT8uaWQgfTtcbiAgICB9XG5cbiAgICAvLyBubyB1cGRhdGVzXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlzVXBkYXRlQ29tcGxldGUoKSB7XG4gICAgY29uc29sZS5sb2coJ2lzVXBkYXRlQ29tcGxldGUnKTtcblxuICAgIC8vIGlmIHRoaXMgaXMgYW4gRUtTIHVwZGF0ZSwgd2Ugd2lsbCBtb25pdG9yIHRoZSB1cGRhdGUgZXZlbnQgaXRzZWxmXG4gICAgaWYgKHRoaXMuZXZlbnQuRWtzVXBkYXRlSWQpIHtcbiAgICAgIGNvbnN0IGNvbXBsZXRlID0gYXdhaXQgdGhpcy5pc0Vrc1VwZGF0ZUNvbXBsZXRlKHRoaXMuZXZlbnQuRWtzVXBkYXRlSWQpO1xuICAgICAgaWYgKCFjb21wbGV0ZSkge1xuICAgICAgICByZXR1cm4geyBJc0NvbXBsZXRlOiBmYWxzZSB9O1xuICAgICAgfVxuXG4gICAgICAvLyBmYWxsIHRocm91Z2g6IGlmIHRoZSB1cGRhdGUgaXMgZG9uZSwgd2Ugc2ltcGx5IGRlbGVnYXRlIHRvIGlzQWN0aXZlKClcbiAgICAgIC8vIGluIG9yZGVyIHRvIGV4dHJhY3QgYXR0cmlidXRlcyBhbmQgc3RhdGUgZnJvbSB0aGUgY2x1c3RlciBpdHNlbGYsIHdoaWNoXG4gICAgICAvLyBpcyBzdXBwb3NlZCB0byBiZSBpbiBhbiBBQ1RJVkUgc3RhdGUgYWZ0ZXIgdGhlIHVwZGF0ZSBpcyBjb21wbGV0ZS5cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5pc0FjdGl2ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVDbHVzdGVyVmVyc2lvbihuZXdWZXJzaW9uOiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZyhgdXBkYXRpbmcgY2x1c3RlciB2ZXJzaW9uIHRvICR7bmV3VmVyc2lvbn1gKTtcblxuICAgIC8vIHVwZGF0ZS1jbHVzdGVyLXZlcnNpb24gd2lsbCBmYWlsIGlmIHdlIHRyeSB0byB1cGRhdGUgdG8gdGhlIHNhbWUgdmVyc2lvbixcbiAgICAvLyBzbyBza2lwIGluIHRoaXMgY2FzZS5cbiAgICBjb25zdCBjbHVzdGVyID0gKGF3YWl0IHRoaXMuZWtzLmRlc2NyaWJlQ2x1c3Rlcih7IG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUgfSkpLmNsdXN0ZXI7XG4gICAgaWYgKGNsdXN0ZXI/LnZlcnNpb24gPT09IG5ld1ZlcnNpb24pIHtcbiAgICAgIGNvbnNvbGUubG9nKGBjbHVzdGVyIGFscmVhZHkgYXQgdmVyc2lvbiAke2NsdXN0ZXIudmVyc2lvbn0sIHNraXBwaW5nIHZlcnNpb24gdXBkYXRlYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdXBkYXRlUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmVrcy51cGRhdGVDbHVzdGVyVmVyc2lvbih7IG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUsIHZlcnNpb246IG5ld1ZlcnNpb24gfSk7XG4gICAgcmV0dXJuIHsgRWtzVXBkYXRlSWQ6IHVwZGF0ZVJlc3BvbnNlLnVwZGF0ZT8uaWQgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaXNBY3RpdmUoKTogUHJvbWlzZTxJc0NvbXBsZXRlUmVzcG9uc2U+IHtcbiAgICBjb25zb2xlLmxvZygnd2FpdGluZyBmb3IgY2x1c3RlciB0byBiZWNvbWUgQUNUSVZFJyk7XG4gICAgY29uc3QgcmVzcCA9IGF3YWl0IHRoaXMuZWtzLmRlc2NyaWJlQ2x1c3Rlcih7IG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUgfSk7XG4gICAgY29uc29sZS5sb2coJ2Rlc2NyaWJlQ2x1c3RlciByZXN1bHQ6JywgSlNPTi5zdHJpbmdpZnkocmVzcCwgdW5kZWZpbmVkLCAyKSk7XG4gICAgY29uc3QgY2x1c3RlciA9IHJlc3AuY2x1c3RlcjtcblxuICAgIC8vIGlmIGNsdXN0ZXIgaXMgdW5kZWZpbmVkIChzaG91bGRudCBoYXBwZW4pIG9yIHN0YXR1cyBpcyBub3QgQUNUSVZFLCB3ZSBhcmVcbiAgICAvLyBub3QgY29tcGxldGUuIG5vdGUgdGhhdCB0aGUgY3VzdG9tIHJlc291cmNlIHByb3ZpZGVyIGZyYW1ld29yayBmb3JiaWRzXG4gICAgLy8gcmV0dXJuaW5nIGF0dHJpYnV0ZXMgKERhdGEpIGlmIGlzQ29tcGxldGUgaXMgZmFsc2UuXG4gICAgaWYgKGNsdXN0ZXI/LnN0YXR1cyA9PT0gJ0ZBSUxFRCcpIHtcbiAgICAgIC8vIG5vdCB2ZXJ5IGluZm9ybWF0aXZlLCB1bmZvcnR1bmF0ZWx5IHRoZSByZXNwb25zZSBkb2Vzbid0IGNvbnRhaW4gYW55IGVycm9yXG4gICAgICAvLyBpbmZvcm1hdGlvbiA6XFxcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2x1c3RlciBpcyBpbiBhIEZBSUxFRCBzdGF0dXMnKTtcbiAgICB9IGVsc2UgaWYgKGNsdXN0ZXI/LnN0YXR1cyAhPT0gJ0FDVElWRScpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIElzQ29tcGxldGU6IGZhbHNlLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgSXNDb21wbGV0ZTogdHJ1ZSxcbiAgICAgICAgRGF0YToge1xuICAgICAgICAgIE5hbWU6IGNsdXN0ZXIubmFtZSxcbiAgICAgICAgICBFbmRwb2ludDogY2x1c3Rlci5lbmRwb2ludCxcbiAgICAgICAgICBBcm46IGNsdXN0ZXIuYXJuLFxuXG4gICAgICAgICAgLy8gSU1QT1JUQU5UOiBDRk4gZXhwZWN0cyB0aGF0IGF0dHJpYnV0ZXMgd2lsbCAqYWx3YXlzKiBoYXZlIHZhbHVlcyxcbiAgICAgICAgICAvLyBzbyByZXR1cm4gYW4gZW1wdHkgc3RyaW5nIGluIGNhc2UgdGhlIHZhbHVlIGlzIG5vdCBkZWZpbmVkLlxuICAgICAgICAgIC8vIE90aGVyd2lzZSwgQ0ZOIHdpbGwgdGhyb3cgd2l0aCBgVmVuZG9yIHJlc3BvbnNlIGRvZXNuJ3QgY29udGFpblxuICAgICAgICAgIC8vIFhYWFgga2V5YC5cblxuICAgICAgICAgIENlcnRpZmljYXRlQXV0aG9yaXR5RGF0YTogY2x1c3Rlci5jZXJ0aWZpY2F0ZUF1dGhvcml0eT8uZGF0YSA/PyAnJyxcbiAgICAgICAgICBDbHVzdGVyU2VjdXJpdHlHcm91cElkOiBjbHVzdGVyLnJlc291cmNlc1ZwY0NvbmZpZz8uY2x1c3RlclNlY3VyaXR5R3JvdXBJZCA/PyAnJyxcbiAgICAgICAgICBPcGVuSWRDb25uZWN0SXNzdWVyVXJsOiBjbHVzdGVyLmlkZW50aXR5Py5vaWRjPy5pc3N1ZXIgPz8gJycsXG4gICAgICAgICAgT3BlbklkQ29ubmVjdElzc3VlcjogY2x1c3Rlci5pZGVudGl0eT8ub2lkYz8uaXNzdWVyPy5zdWJzdHJpbmcoOCkgPz8gJycsIC8vIFN0cmlwcyBvZmYgaHR0cHM6Ly8gZnJvbSB0aGUgaXNzdWVyIHVybFxuXG4gICAgICAgICAgLy8gV2UgY2FuIHNhZmVseSByZXR1cm4gdGhlIGZpcnN0IGl0ZW0gZnJvbSBlbmNyeXB0aW9uIGNvbmZpZ3VyYXRpb24gYXJyYXksIGJlY2F1c2UgaXQgaGFzIGEgbGltaXQgb2YgMSBpdGVtXG4gICAgICAgICAgLy8gaHR0cHM6Ly9kb2NzLmFtYXpvbi5jb20vZWtzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUNsdXN0ZXIuaHRtbCNBbWF6b25FS1MtQ3JlYXRlQ2x1c3Rlci1yZXF1ZXN0LWVuY3J5cHRpb25Db25maWdcbiAgICAgICAgICBFbmNyeXB0aW9uQ29uZmlnS2V5QXJuOiBjbHVzdGVyLmVuY3J5cHRpb25Db25maWc/LnNoaWZ0KCk/LnByb3ZpZGVyPy5rZXlBcm4gPz8gJycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaXNFa3NVcGRhdGVDb21wbGV0ZShla3NVcGRhdGVJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5sb2coeyBpc0Vrc1VwZGF0ZUNvbXBsZXRlOiBla3NVcGRhdGVJZCB9KTtcblxuICAgIGNvbnN0IGRlc2NyaWJlVXBkYXRlUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmVrcy5kZXNjcmliZVVwZGF0ZSh7XG4gICAgICBuYW1lOiB0aGlzLmNsdXN0ZXJOYW1lLFxuICAgICAgdXBkYXRlSWQ6IGVrc1VwZGF0ZUlkLFxuICAgIH0pO1xuXG4gICAgdGhpcy5sb2coeyBkZXNjcmliZVVwZGF0ZVJlc3BvbnNlIH0pO1xuXG4gICAgaWYgKCFkZXNjcmliZVVwZGF0ZVJlc3BvbnNlLnVwZGF0ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmFibGUgdG8gZGVzY3JpYmUgdXBkYXRlIHdpdGggaWQgXCIke2Vrc1VwZGF0ZUlkfVwiYCk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChkZXNjcmliZVVwZGF0ZVJlc3BvbnNlLnVwZGF0ZS5zdGF0dXMpIHtcbiAgICAgIGNhc2UgJ0luUHJvZ3Jlc3MnOlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBjYXNlICdTdWNjZXNzZnVsJzpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBjYXNlICdGYWlsZWQnOlxuICAgICAgY2FzZSAnQ2FuY2VsbGVkJzpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjbHVzdGVyIHVwZGF0ZSBpZCBcIiR7ZWtzVXBkYXRlSWR9XCIgZmFpbGVkIHdpdGggZXJyb3JzOiAke0pTT04uc3RyaW5naWZ5KGRlc2NyaWJlVXBkYXRlUmVzcG9uc2UudXBkYXRlLmVycm9ycyl9YCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vd24gc3RhdHVzIFwiJHtkZXNjcmliZVVwZGF0ZVJlc3BvbnNlLnVwZGF0ZS5zdGF0dXN9XCIgZm9yIHVwZGF0ZSBpZCBcIiR7ZWtzVXBkYXRlSWR9XCJgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdlbmVyYXRlQ2x1c3Rlck5hbWUoKSB7XG4gICAgY29uc3Qgc3VmZml4ID0gdGhpcy5yZXF1ZXN0SWQucmVwbGFjZSgvLS9nLCAnJyk7IC8vIDMyIGNoYXJzXG4gICAgY29uc3Qgb2Zmc2V0ID0gTUFYX0NMVVNURVJfTkFNRV9MRU4gLSBzdWZmaXgubGVuZ3RoIC0gMTtcbiAgICBjb25zdCBwcmVmaXggPSB0aGlzLmxvZ2ljYWxSZXNvdXJjZUlkLnNsaWNlKDAsIG9mZnNldCA+IDAgPyBvZmZzZXQgOiAwKTtcbiAgICByZXR1cm4gYCR7cHJlZml4fS0ke3N1ZmZpeH1gO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlUHJvcHMocHJvcHM6IGFueSk6IEVLUy5DcmVhdGVDbHVzdGVyQ29tbWFuZElucHV0IHtcblxuICBjb25zdCBwYXJzZWQgPSBwcm9wcz8uQ29uZmlnID8/IHt9O1xuXG4gIC8vIHRoaXMgaXMgd2VpcmQgYnV0IHRoZXNlIGJvb2xlYW4gcHJvcGVydGllcyBhcmUgcGFzc2VkIGJ5IENGTiBhcyBhIHN0cmluZywgYW5kIHdlIG5lZWQgdGhlbSB0byBiZSBib29sZWFuaWMgZm9yIHRoZSBTREsuXG4gIC8vIE90aGVyd2lzZSBpdCBmYWlscyB3aXRoICdVbmV4cGVjdGVkIFBhcmFtZXRlcjogcGFyYW1zLnJlc291cmNlc1ZwY0NvbmZpZy5lbmRwb2ludFByaXZhdGVBY2Nlc3MgaXMgZXhwZWN0ZWQgdG8gYmUgYSBib29sZWFuJ1xuXG4gIGlmICh0eXBlb2YgKHBhcnNlZC5yZXNvdXJjZXNWcGNDb25maWc/LmVuZHBvaW50UHJpdmF0ZUFjY2VzcykgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFyc2VkLnJlc291cmNlc1ZwY0NvbmZpZy5lbmRwb2ludFByaXZhdGVBY2Nlc3MgPSBwYXJzZWQucmVzb3VyY2VzVnBjQ29uZmlnLmVuZHBvaW50UHJpdmF0ZUFjY2VzcyA9PT0gJ3RydWUnO1xuICB9XG5cbiAgaWYgKHR5cGVvZiAocGFyc2VkLnJlc291cmNlc1ZwY0NvbmZpZz8uZW5kcG9pbnRQdWJsaWNBY2Nlc3MpID09PSAnc3RyaW5nJykge1xuICAgIHBhcnNlZC5yZXNvdXJjZXNWcGNDb25maWcuZW5kcG9pbnRQdWJsaWNBY2Nlc3MgPSBwYXJzZWQucmVzb3VyY2VzVnBjQ29uZmlnLmVuZHBvaW50UHVibGljQWNjZXNzID09PSAndHJ1ZSc7XG4gIH1cblxuICBpZiAodHlwZW9mIChwYXJzZWQubG9nZ2luZz8uY2x1c3RlckxvZ2dpbmdbMF0uZW5hYmxlZCkgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFyc2VkLmxvZ2dpbmcuY2x1c3RlckxvZ2dpbmdbMF0uZW5hYmxlZCA9IHBhcnNlZC5sb2dnaW5nLmNsdXN0ZXJMb2dnaW5nWzBdLmVuYWJsZWQgPT09ICd0cnVlJztcbiAgfVxuXG4gIHJldHVybiBwYXJzZWQ7XG5cbn1cblxuaW50ZXJmYWNlIFVwZGF0ZU1hcCB7XG4gIHJlcGxhY2VOYW1lOiBib29sZWFuOyAvLyBuYW1lXG4gIHJlcGxhY2VWcGM6IGJvb2xlYW47IC8vIHJlc291cmNlc1ZwY0NvbmZpZy5zdWJuZXRJZHMgYW5kIHNlY3VyaXR5R3JvdXBJZHNcbiAgcmVwbGFjZVJvbGU6IGJvb2xlYW47IC8vIHJvbGVBcm5cblxuICB1cGRhdGVWZXJzaW9uOiBib29sZWFuOyAvLyB2ZXJzaW9uXG4gIHVwZGF0ZUxvZ2dpbmc6IGJvb2xlYW47IC8vIGxvZ2dpbmdcbiAgdXBkYXRlRW5jcnlwdGlvbjogYm9vbGVhbjsgLy8gZW5jcnlwdGlvbiAoY2Fubm90IGJlIHVwZGF0ZWQpXG4gIHVwZGF0ZUFjY2VzczogYm9vbGVhbjsgLy8gcmVzb3VyY2VzVnBjQ29uZmlnLmVuZHBvaW50UHJpdmF0ZUFjY2VzcyBhbmQgZW5kcG9pbnRQdWJsaWNBY2Nlc3Ncbn1cblxuZnVuY3Rpb24gYW5hbHl6ZVVwZGF0ZShvbGRQcm9wczogUGFydGlhbDxFS1MuQ3JlYXRlQ2x1c3RlckNvbW1hbmRJbnB1dD4sIG5ld1Byb3BzOiBFS1MuQ3JlYXRlQ2x1c3RlckNvbW1hbmRJbnB1dCk6IFVwZGF0ZU1hcCB7XG4gIGNvbnNvbGUubG9nKCdvbGQgcHJvcHM6ICcsIEpTT04uc3RyaW5naWZ5KG9sZFByb3BzKSk7XG4gIGNvbnNvbGUubG9nKCduZXcgcHJvcHM6ICcsIEpTT04uc3RyaW5naWZ5KG5ld1Byb3BzKSk7XG5cbiAgY29uc3QgbmV3VnBjUHJvcHMgPSBuZXdQcm9wcy5yZXNvdXJjZXNWcGNDb25maWcgfHwge307XG4gIGNvbnN0IG9sZFZwY1Byb3BzID0gb2xkUHJvcHMucmVzb3VyY2VzVnBjQ29uZmlnIHx8IHt9O1xuXG4gIGNvbnN0IG9sZFB1YmxpY0FjY2Vzc0NpZHJzID0gbmV3IFNldChvbGRWcGNQcm9wcy5wdWJsaWNBY2Nlc3NDaWRycyA/PyBbXSk7XG4gIGNvbnN0IG5ld1B1YmxpY0FjY2Vzc0NpZHJzID0gbmV3IFNldChuZXdWcGNQcm9wcy5wdWJsaWNBY2Nlc3NDaWRycyA/PyBbXSk7XG4gIGNvbnN0IG5ld0VuYyA9IG5ld1Byb3BzLmVuY3J5cHRpb25Db25maWcgfHwge307XG4gIGNvbnN0IG9sZEVuYyA9IG9sZFByb3BzLmVuY3J5cHRpb25Db25maWcgfHwge307XG5cbiAgcmV0dXJuIHtcbiAgICByZXBsYWNlTmFtZTogbmV3UHJvcHMubmFtZSAhPT0gb2xkUHJvcHMubmFtZSxcbiAgICByZXBsYWNlVnBjOlxuICAgICAgSlNPTi5zdHJpbmdpZnkobmV3VnBjUHJvcHMuc3VibmV0SWRzPy5zb3J0KCkpICE9PSBKU09OLnN0cmluZ2lmeShvbGRWcGNQcm9wcy5zdWJuZXRJZHM/LnNvcnQoKSkgfHxcbiAgICAgIEpTT04uc3RyaW5naWZ5KG5ld1ZwY1Byb3BzLnNlY3VyaXR5R3JvdXBJZHM/LnNvcnQoKSkgIT09IEpTT04uc3RyaW5naWZ5KG9sZFZwY1Byb3BzLnNlY3VyaXR5R3JvdXBJZHM/LnNvcnQoKSksXG4gICAgdXBkYXRlQWNjZXNzOlxuICAgICAgbmV3VnBjUHJvcHMuZW5kcG9pbnRQcml2YXRlQWNjZXNzICE9PSBvbGRWcGNQcm9wcy5lbmRwb2ludFByaXZhdGVBY2Nlc3MgfHxcbiAgICAgIG5ld1ZwY1Byb3BzLmVuZHBvaW50UHVibGljQWNjZXNzICE9PSBvbGRWcGNQcm9wcy5lbmRwb2ludFB1YmxpY0FjY2VzcyB8fFxuICAgICAgIXNldHNFcXVhbChuZXdQdWJsaWNBY2Nlc3NDaWRycywgb2xkUHVibGljQWNjZXNzQ2lkcnMpLFxuICAgIHJlcGxhY2VSb2xlOiBuZXdQcm9wcy5yb2xlQXJuICE9PSBvbGRQcm9wcy5yb2xlQXJuLFxuICAgIHVwZGF0ZVZlcnNpb246IG5ld1Byb3BzLnZlcnNpb24gIT09IG9sZFByb3BzLnZlcnNpb24sXG4gICAgdXBkYXRlRW5jcnlwdGlvbjogSlNPTi5zdHJpbmdpZnkobmV3RW5jKSAhPT0gSlNPTi5zdHJpbmdpZnkob2xkRW5jKSxcbiAgICB1cGRhdGVMb2dnaW5nOiBKU09OLnN0cmluZ2lmeShuZXdQcm9wcy5sb2dnaW5nKSAhPT0gSlNPTi5zdHJpbmdpZnkob2xkUHJvcHMubG9nZ2luZyksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHNldHNFcXVhbChmaXJzdDogU2V0PHN0cmluZz4sIHNlY29uZDogU2V0PHN0cmluZz4pIHtcbiAgcmV0dXJuIGZpcnN0LnNpemUgPT09IHNlY29uZC5zaXplICYmIFsuLi5maXJzdF0uZXZlcnkoKGU6IHN0cmluZykgPT4gc2Vjb25kLmhhcyhlKSk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.ts similarity index 98% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.ts index 433de220b6c83..4b70abab4588e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/cluster.ts @@ -69,7 +69,7 @@ export class ClusterResourceHandler extends ResourceHandler { try { await this.eks.deleteCluster({ name: this.clusterName }); } catch (e: any) { - if (!(e instanceof EKS.ResourceNotFoundException)) { + if (e.name !== 'ResourceNotFoundException') { throw e; } else { console.log(`cluster ${this.clusterName} not found, idempotently succeeded`); @@ -87,8 +87,7 @@ export class ClusterResourceHandler extends ResourceHandler { const resp = await this.eks.describeCluster({ name: this.clusterName }); console.log('describeCluster returned:', JSON.stringify(resp, undefined, 2)); } catch (e: any) { - // see https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/ - if (e instanceof EKS.ResourceNotFoundException) { + if (e.name === 'ResourceNotFoundException') { console.log('received ResourceNotFoundException, this means the cluster has been deleted (or never existed)'); return { IsComplete: true }; } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/common.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/common.d.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/common.d.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/common.d.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/common.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/common.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/common.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/common.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/common.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/common.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/common.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/common.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/compareLogging.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/compareLogging.d.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/compareLogging.d.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/compareLogging.d.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/compareLogging.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/compareLogging.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/compareLogging.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/compareLogging.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/compareLogging.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/compareLogging.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/compareLogging.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/compareLogging.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/consts.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/consts.d.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/consts.d.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/consts.d.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/consts.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/consts.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/consts.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/consts.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/consts.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/consts.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/consts.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/consts.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.d.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.d.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.d.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.js new file mode 100644 index 0000000000000..e946d9384b98f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.js @@ -0,0 +1,102 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.FargateProfileResourceHandler = void 0; +const common_1 = require("./common"); +const MAX_NAME_LEN = 63; +class FargateProfileResourceHandler extends common_1.ResourceHandler { + async onCreate() { + const fargateProfileName = this.event.ResourceProperties.Config.fargateProfileName ?? this.generateProfileName(); + const createFargateProfile = { + fargateProfileName, + ...this.event.ResourceProperties.Config, + }; + this.log({ createFargateProfile }); + const createFargateProfileResponse = await this.eks.createFargateProfile(createFargateProfile); + this.log({ createFargateProfileResponse }); + if (!createFargateProfileResponse.fargateProfile) { + throw new Error('invalid CreateFargateProfile response'); + } + return { + PhysicalResourceId: createFargateProfileResponse.fargateProfile.fargateProfileName, + Data: { + fargateProfileArn: createFargateProfileResponse.fargateProfile.fargateProfileArn, + }, + }; + } + async onDelete() { + if (!this.physicalResourceId) { + throw new Error('Cannot delete a profile without a physical id'); + } + const deleteFargateProfile = { + clusterName: this.event.ResourceProperties.Config.clusterName, + fargateProfileName: this.physicalResourceId, + }; + this.log({ deleteFargateProfile }); + const deleteFargateProfileResponse = await this.eks.deleteFargateProfile(deleteFargateProfile); + this.log({ deleteFargateProfileResponse }); + return; + } + async onUpdate() { + // all updates require a replacement. as long as name is generated, we are + // good. if name is explicit, update will fail, which is common when trying + // to replace cfn resources with explicit physical names + return this.onCreate(); + } + async isCreateComplete() { + return this.isUpdateComplete(); + } + async isUpdateComplete() { + const status = await this.queryStatus(); + return { + IsComplete: status === 'ACTIVE', + }; + } + async isDeleteComplete() { + const status = await this.queryStatus(); + return { + IsComplete: status === 'NOT_FOUND', + }; + } + /** + * Generates a fargate profile name. + */ + generateProfileName() { + const suffix = this.requestId.replace(/-/g, ''); // 32 chars + const offset = MAX_NAME_LEN - suffix.length - 1; + const prefix = this.logicalResourceId.slice(0, offset > 0 ? offset : 0); + return `${prefix}-${suffix}`; + } + /** + * Queries the Fargate profile's current status and returns the status or + * NOT_FOUND if the profile doesn't exist (i.e. it has been deleted). + */ + async queryStatus() { + if (!this.physicalResourceId) { + throw new Error('Unable to determine status for fargate profile without a resource name'); + } + const describeFargateProfile = { + clusterName: this.event.ResourceProperties.Config.clusterName, + fargateProfileName: this.physicalResourceId, + }; + try { + this.log({ describeFargateProfile }); + const describeFargateProfileResponse = await this.eks.describeFargateProfile(describeFargateProfile); + this.log({ describeFargateProfileResponse }); + const status = describeFargateProfileResponse.fargateProfile?.status; + if (status === 'CREATE_FAILED' || status === 'DELETE_FAILED') { + throw new Error(status); + } + return status; + } + catch (describeFargateProfileError) { + if (describeFargateProfileError.name === 'ResourceNotFoundException') { + this.log('received ResourceNotFoundException, this means the profile has been deleted (or never existed)'); + return 'NOT_FOUND'; + } + this.log({ describeFargateProfileError }); + throw describeFargateProfileError; + } + } +} +exports.FargateProfileResourceHandler = FargateProfileResourceHandler; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFyZ2F0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImZhcmdhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEscUNBQTJDO0FBRTNDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztBQUV4QixNQUFhLDZCQUE4QixTQUFRLHdCQUFlO0lBQ3RELEtBQUssQ0FBQyxRQUFRO1FBQ3RCLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFFakgsTUFBTSxvQkFBb0IsR0FBeUM7WUFDakUsa0JBQWtCO1lBQ2xCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNO1NBQ3hDLENBQUM7UUFFRixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sNEJBQTRCLEdBQUcsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDL0YsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLDRCQUE0QixFQUFFLENBQUMsQ0FBQztRQUUzQyxJQUFJLENBQUMsNEJBQTRCLENBQUMsY0FBYyxFQUFFO1lBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztTQUMxRDtRQUVELE9BQU87WUFDTCxrQkFBa0IsRUFBRSw0QkFBNEIsQ0FBQyxjQUFjLENBQUMsa0JBQWtCO1lBQ2xGLElBQUksRUFBRTtnQkFDSixpQkFBaUIsRUFBRSw0QkFBNEIsQ0FBQyxjQUFjLENBQUMsaUJBQWlCO2FBQ2pGO1NBQ0YsQ0FBQztLQUNIO0lBRVMsS0FBSyxDQUFDLFFBQVE7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENB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QUNwRSxJQUFJLENBQUMsR0FBRyxDQUFDLGdHQUFnRyxDQUFDLENBQUM7Z0JBQzNHLE9BQU8sV0FBVyxDQUFDO2FBQ3BCO1lBRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLDJCQUEyQixFQUFFLENBQUMsQ0FBQztZQUMxQyxNQUFNLDJCQUEyQixDQUFDO1NBQ25DO0tBQ0Y7Q0FDRjtBQWpIRCxzRUFpSEMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgKiBhcyBFS1MgZnJvbSAnQGF3cy1zZGsvY2xpZW50LWVrcyc7XG5pbXBvcnQgeyBSZXNvdXJjZUhhbmRsZXIgfSBmcm9tICcuL2NvbW1vbic7XG5cbmNvbnN0IE1BWF9OQU1FX0xFTiA9IDYzO1xuXG5leHBvcnQgY2xhc3MgRmFyZ2F0ZVByb2ZpbGVSZXNvdXJjZUhhbmRsZXIgZXh0ZW5kcyBSZXNvdXJjZUhhbmRsZXIge1xuICBwcm90ZWN0ZWQgYXN5bmMgb25DcmVhdGUoKSB7XG4gICAgY29uc3QgZmFyZ2F0ZVByb2ZpbGVOYW1lID0gdGhpcy5ldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ29uZmlnLmZhcmdhdGVQcm9maWxlTmFtZSA/PyB0aGlzLmdlbmVyYXRlUHJvZmlsZU5hbWUoKTtcblxuICAgIGNvbnN0IGNyZWF0ZUZhcmdhdGVQcm9maWxlOiBFS1MuQ3JlYXRlRmFyZ2F0ZVByb2ZpbGVDb21tYW5kSW5wdXQgPSB7XG4gICAgICBmYXJnYXRlUHJvZmlsZU5hbWUsXG4gICAgICAuLi50aGlzLmV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Db25maWcsXG4gICAgfTtcblxuICAgIHRoaXMubG9nKHsgY3JlYXRlRmFyZ2F0ZVByb2ZpbGUgfSk7XG4gICAgY29uc3QgY3JlYXRlRmFyZ2F0ZVByb2ZpbGVSZXNwb25zZSA9IGF3YWl0IHRoaXMuZWtzLmNyZWF0ZUZhcmdhdGVQcm9maWxlKGNyZWF0ZUZhcmdhdGVQcm9maWxlKTtcbiAgICB0aGlzLmxvZyh7IGNyZWF0ZUZhcmdhdGVQcm9maWxlUmVzcG9uc2UgfSk7XG5cbiAgICBpZiAoIWNyZWF0ZUZhcmdhdGVQcm9maWxlUmVzcG9uc2UuZmFyZ2F0ZVByb2ZpbGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBDcmVhdGVGYXJnYXRlUHJvZmlsZSByZXNwb25zZScpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGNyZWF0ZUZhcmdhdGVQcm9maWxlUmVzcG9uc2UuZmFyZ2F0ZVByb2ZpbGUuZmFyZ2F0ZVByb2ZpbGVOYW1lLFxuICAgICAgRGF0YToge1xuICAgICAgICBmYXJnYXRlUHJvZmlsZUFybjogY3JlYXRlRmFyZ2F0ZVByb2ZpbGVSZXNwb25zZS5mYXJnYXRlUHJvZmlsZS5mYXJnYXRlUHJvZmlsZUFybixcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBvbkRlbGV0ZSgpIHtcbiAgICBpZiAoIXRoaXMucGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBkZWxldGUgYSBwcm9maWxlIHdpdGhvdXQgYSBwaHlzaWNhbCBpZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlbGV0ZUZhcmdhdGVQcm9maWxlOiBFS1MuRGVsZXRlRmFyZ2F0ZVByb2ZpbGVDb21tYW5kSW5wdXQgPSB7XG4gICAgICBjbHVzdGVyTmFtZTogdGhpcy5ldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ29uZmlnLmNsdXN0ZXJOYW1lLFxuICAgICAgZmFyZ2F0ZVByb2ZpbGVOYW1lOiB0aGlzLnBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICB9O1xuXG4gICAgdGhpcy5sb2coeyBkZWxldGVGYXJnYXRlUHJvZmlsZSB9KTtcbiAgICBjb25zdCBkZWxldGVGYXJnYXRlUHJvZmlsZVJlc3BvbnNlID0gYXdhaXQgdGhpcy5la3MuZGVsZXRlRmFyZ2F0ZVByb2ZpbGUoZGVsZXRlRmFyZ2F0ZVByb2ZpbGUpO1xuICAgIHRoaXMubG9nKHsgZGVsZXRlRmFyZ2F0ZVByb2ZpbGVSZXNwb25zZSB9KTtcblxuICAgIHJldHVybjtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBvblVwZGF0ZSgpIHtcbiAgICAvLyBhbGwgdXBkYXRlcyByZXF1aXJlIGEgcmVwbGFjZW1lbnQuIGFzIGxvbmcgYXMgbmFtZSBpcyBnZW5lcmF0ZWQsIHdlIGFyZVxuICAgIC8vIGdvb2QuIGlmIG5hbWUgaXMgZXhwbGljaXQsIHVwZGF0ZSB3aWxsIGZhaWwsIHdoaWNoIGlzIGNvbW1vbiB3aGVuIHRyeWluZ1xuICAgIC8vIHRvIHJlcGxhY2UgY2ZuIHJlc291cmNlcyB3aXRoIGV4cGxpY2l0IHBoeXNpY2FsIG5hbWVzXG4gICAgcmV0dXJuIHRoaXMub25DcmVhdGUoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpc0NyZWF0ZUNvbXBsZXRlKCkge1xuICAgIHJldHVybiB0aGlzLmlzVXBkYXRlQ29tcGxldGUoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpc1VwZGF0ZUNvbXBsZXRlKCkge1xuICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IHRoaXMucXVlcnlTdGF0dXMoKTtcbiAgICByZXR1cm4ge1xuICAgICAgSXNDb21wbGV0ZTogc3RhdHVzID09PSAnQUNUSVZFJyxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlzRGVsZXRlQ29tcGxldGUoKSB7XG4gICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgdGhpcy5xdWVyeVN0YXR1cygpO1xuICAgIHJldHVybiB7XG4gICAgICBJc0NvbXBsZXRlOiBzdGF0dXMgPT09ICdOT1RfRk9VTkQnLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGEgZmFyZ2F0ZSBwcm9maWxlIG5hbWUuXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlUHJvZmlsZU5hbWUoKSB7XG4gICAgY29uc3Qgc3VmZml4ID0gdGhpcy5yZXF1ZXN0SWQucmVwbGFjZSgvLS9nLCAnJyk7IC8vIDMyIGNoYXJzXG4gICAgY29uc3Qgb2Zmc2V0ID0gTUFYX05BTUVfTEVOIC0gc3VmZml4Lmxlbmd0aCAtIDE7XG4gICAgY29uc3QgcHJlZml4ID0gdGhpcy5sb2dpY2FsUmVzb3VyY2VJZC5zbGljZSgwLCBvZmZzZXQgPiAwID8gb2Zmc2V0IDogMCk7XG4gICAgcmV0dXJuIGAke3ByZWZpeH0tJHtzdWZmaXh9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyaWVzIHRoZSBGYXJnYXRlIHByb2ZpbGUncyBjdXJyZW50IHN0YXR1cyBhbmQgcmV0dXJucyB0aGUgc3RhdHVzIG9yXG4gICAqIE5PVF9GT1VORCBpZiB0aGUgcHJvZmlsZSBkb2Vzbid0IGV4aXN0IChpLmUuIGl0IGhhcyBiZWVuIGRlbGV0ZWQpLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBxdWVyeVN0YXR1cygpOiBQcm9taXNlPEVLUy5GYXJnYXRlUHJvZmlsZVN0YXR1cyB8ICdOT1RfRk9VTkQnIHwgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKCF0aGlzLnBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGV0ZXJtaW5lIHN0YXR1cyBmb3IgZmFyZ2F0ZSBwcm9maWxlIHdpdGhvdXQgYSByZXNvdXJjZSBuYW1lJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVzY3JpYmVGYXJnYXRlUHJvZmlsZTogRUtTLkRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGVDb21tYW5kSW5wdXQgPSB7XG4gICAgICBjbHVzdGVyTmFtZTogdGhpcy5ldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ29uZmlnLmNsdXN0ZXJOYW1lLFxuICAgICAgZmFyZ2F0ZVByb2ZpbGVOYW1lOiB0aGlzLnBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICB9O1xuXG4gICAgdHJ5IHtcblxuICAgICAgdGhpcy5sb2coeyBkZXNjcmliZUZhcmdhdGVQcm9maWxlIH0pO1xuICAgICAgY29uc3QgZGVzY3JpYmVGYXJnYXRlUHJvZmlsZVJlc3BvbnNlID0gYXdhaXQgdGhpcy5la3MuZGVzY3JpYmVGYXJnYXRlUHJvZmlsZShkZXNjcmliZUZhcmdhdGVQcm9maWxlKTtcbiAgICAgIHRoaXMubG9nKHsgZGVzY3JpYmVGYXJnYXRlUHJvZmlsZVJlc3BvbnNlIH0pO1xuICAgICAgY29uc3Qgc3RhdHVzID0gZGVzY3JpYmVGYXJnYXRlUHJvZmlsZVJlc3BvbnNlLmZhcmdhdGVQcm9maWxlPy5zdGF0dXM7XG5cbiAgICAgIGlmIChzdGF0dXMgPT09ICdDUkVBVEVfRkFJTEVEJyB8fCBzdGF0dXMgPT09ICdERUxFVEVfRkFJTEVEJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc3RhdHVzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0YXR1cztcbiAgICB9IGNhdGNoIChkZXNjcmliZUZhcmdhdGVQcm9maWxlRXJyb3I6IGFueSkge1xuICAgICAgaWYgKGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGVFcnJvci5uYW1lID09PSAnUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgdGhpcy5sb2coJ3JlY2VpdmVkIFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24sIHRoaXMgbWVhbnMgdGhlIHByb2ZpbGUgaGFzIGJlZW4gZGVsZXRlZCAob3IgbmV2ZXIgZXhpc3RlZCknKTtcbiAgICAgICAgcmV0dXJuICdOT1RfRk9VTkQnO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZyh7IGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGVFcnJvciB9KTtcbiAgICAgIHRocm93IGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGVFcnJvcjtcbiAgICB9XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.ts similarity index 97% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.ts index a47a17cbec0a7..0e292277ebc65 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/fargate.ts @@ -108,7 +108,7 @@ export class FargateProfileResourceHandler extends ResourceHandler { return status; } catch (describeFargateProfileError: any) { - if (describeFargateProfileError instanceof EKS.ResourceNotFoundException) { + if (describeFargateProfileError.name === 'ResourceNotFoundException') { this.log('received ResourceNotFoundException, this means the profile has been deleted (or never existed)'); return 'NOT_FOUND'; } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.d.ts similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.d.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.d.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.js similarity index 72% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.js index a53ec4c9cde7a..24b8c9f16aab1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.js +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.js @@ -65,4 +65,4 @@ function createResourceHandler(event) { throw new Error(`Unsupported resource type "${event.ResourceType}`); } } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsNkRBQTZEO0FBQzdELG9EQUEwQztBQUMxQyw2REFBNkQ7QUFDN0Qsd0VBQXlFO0FBQ3pFLDZEQUE2RDtBQUM3RCxrRUFBNkQ7QUFDN0QsNkRBQTZEO0FBQzdELDZDQUF5QztBQUN6Qyx1Q0FBbUQ7QUFFbkQsbUNBQW1DO0FBQ25DLHVDQUEwRDtBQUcxRCxNQUFNLFVBQVUsR0FBRyxJQUFJLHdCQUFVLEVBQUUsQ0FBQztBQUNwQyxNQUFNLFNBQVMsR0FBRztJQUNoQixNQUFNLEVBQUUsT0FBTztJQUNmLGNBQWMsRUFBRSxJQUFJLG1DQUFlLENBQUM7UUFDbEMsU0FBUyxFQUFFLFVBQVU7UUFDckIsVUFBVSxFQUFFLFVBQVU7S0FDdkIsQ0FBQztDQUNILENBQUM7QUFFRixJQUFJLEdBQW9CLENBQUM7QUFFekIsTUFBTSxnQkFBZ0IsR0FBYztJQUNsQyxhQUFhLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDO0lBQ3ZELGFBQWEsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUM7SUFDdkQsZUFBZSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQztJQUMzRCxjQUFjLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDO0lBQ3pELG1CQUFtQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDO0lBQ25FLG9CQUFvQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDO0lBQ3JFLG9CQUFvQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDO0lBQ3JFLG9CQUFvQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDO0lBQ3JFLHNCQUFzQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUFDO0lBQ3pFLG1CQUFtQixFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7UUFDM0IsR0FBRyxHQUFHLElBQUksZ0JBQUcsQ0FBQztZQUNaLEdBQUcsU0FBUztZQUNaLFdBQVcsRUFBRSxJQUFBLCtDQUF3QixFQUFDO2dCQUNwQyxNQUFNLEVBQUUsR0FBRzthQUNaLENBQUM7U0FDSCxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YsQ0FBQztBQUVGLFNBQVMsWUFBWTtJQUNuQixJQUFJLENBQUMsR0FBRyxFQUFFO1FBQ1IsTUFBTSxJQUFJLEtBQUssQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO0tBQzVFO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRU0sS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrRDtJQUM5RSxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxPQUFPLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUM1QixDQUFDO0FBSEQsMEJBR0M7QUFFTSxLQUFLLFVBQVUsVUFBVSxDQUFDLEtBQWtEO0lBQ2pGLE1BQU0sUUFBUSxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlDLE9BQU8sUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQy9CLENBQUM7QUFIRCxnQ0FHQztBQUVELFNBQVMscUJBQXFCLENBQUMsS0FBa0Q7SUFDL0UsUUFBUSxLQUFLLENBQUMsWUFBWSxFQUFFO1FBQzFCLEtBQUssTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxJQUFJLGdDQUFzQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzlGLEtBQUssTUFBTSxDQUFDLDZCQUE2QixDQUFDLENBQUMsT0FBTyxJQUFJLHVDQUE2QixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzdHO1lBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7S0FDdkU7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0IHsgRUtTIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWVrcyc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBmcm9tVGVtcG9yYXJ5Q3JlZGVudGlhbHMgfSBmcm9tICdAYXdzLXNkay9jcmVkZW50aWFsLXByb3ZpZGVycyc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBOb2RlSHR0cEhhbmRsZXIgfSBmcm9tICdAYXdzLXNkay9ub2RlLWh0dHAtaGFuZGxlcic7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBQcm94eUFnZW50IH0gZnJvbSAncHJveHktYWdlbnQnO1xuaW1wb3J0IHsgQ2x1c3RlclJlc291cmNlSGFuZGxlciB9IGZyb20gJy4vY2x1c3Rlcic7XG5pbXBvcnQgeyBFa3NDbGllbnQgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgKiBhcyBjb25zdHMgZnJvbSAnLi9jb25zdHMnO1xuaW1wb3J0IHsgRmFyZ2F0ZVByb2ZpbGVSZXNvdXJjZUhhbmRsZXIgfSBmcm9tICcuL2ZhcmdhdGUnO1xuaW1wb3J0IHsgSXNDb21wbGV0ZVJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vLi4vY3VzdG9tLXJlc291cmNlcy9saWIvcHJvdmlkZXItZnJhbWV3b3JrL3R5cGVzJztcblxuY29uc3QgcHJveHlBZ2VudCA9IG5ldyBQcm94eUFnZW50KCk7XG5jb25zdCBhd3NDb25maWcgPSB7XG4gIGxvZ2dlcjogY29uc29sZSxcbiAgcmVxdWVzdEhhbmRsZXI6IG5ldyBOb2RlSHR0cEhhbmRsZXIoe1xuICAgIGh0dHBBZ2VudDogcHJveHlBZ2VudCxcbiAgICBodHRwc0FnZW50OiBwcm94eUFnZW50LFxuICB9KSxcbn07XG5cbmxldCBla3M6IEVLUyB8IHVuZGVmaW5lZDtcblxuY29uc3QgZGVmYXVsdEVrc0NsaWVudDogRWtzQ2xpZW50ID0ge1xuICBjcmVhdGVDbHVzdGVyOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkuY3JlYXRlQ2x1c3RlcihyZXEpLFxuICBkZWxldGVDbHVzdGVyOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkuZGVsZXRlQ2x1c3RlcihyZXEpLFxuICBkZXNjcmliZUNsdXN0ZXI6IHJlcSA9PiBnZXRFa3NDbGllbnQoKS5kZXNjcmliZUNsdXN0ZXIocmVxKSxcbiAgZGVzY3JpYmVVcGRhdGU6IHJlcSA9PiBnZXRFa3NDbGllbnQoKS5kZXNjcmliZVVwZGF0ZShyZXEpLFxuICB1cGRhdGVDbHVzdGVyQ29uZmlnOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkudXBkYXRlQ2x1c3RlckNvbmZpZyhyZXEpLFxuICB1cGRhdGVDbHVzdGVyVmVyc2lvbjogcmVxID0+IGdldEVrc0NsaWVudCgpLnVwZGF0ZUNsdXN0ZXJWZXJzaW9uKHJlcSksXG4gIGNyZWF0ZUZhcmdhdGVQcm9maWxlOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkuY3JlYXRlRmFyZ2F0ZVByb2ZpbGUocmVxKSxcbiAgZGVsZXRlRmFyZ2F0ZVByb2ZpbGU6IHJlcSA9PiBnZXRFa3NDbGllbnQoKS5kZWxldGVGYXJnYXRlUHJvZmlsZShyZXEpLFxuICBkZXNjcmliZUZhcmdhdGVQcm9maWxlOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkuZGVzY3JpYmVGYXJnYXRlUHJvZmlsZShyZXEpLFxuICBjb25maWd1cmVBc3N1bWVSb2xlOiAocmVxKSA9PiB7XG4gICAgZWtzID0gbmV3IEVLUyh7XG4gICAgICAuLi5hd3NDb25maWcsXG4gICAgICBjcmVkZW50aWFsczogZnJvbVRlbXBvcmFyeUNyZWRlbnRpYWxzKHtcbiAgICAgICAgcGFyYW1zOiByZXEsXG4gICAgICB9KSxcbiAgICB9KTtcbiAgfSxcbn07XG5cbmZ1bmN0aW9uIGdldEVrc0NsaWVudCgpIHtcbiAgaWYgKCFla3MpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0VLUyBjbGllbnQgbm90IGluaXRpYWxpemVkIChjYWxsIFwiY29uZmlndXJlQXNzdW1lUm9sZVwiKScpO1xuICB9XG5cbiAgcmV0dXJuIGVrcztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uRXZlbnQoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgY29uc3QgcHJvdmlkZXIgPSBjcmVhdGVSZXNvdXJjZUhhbmRsZXIoZXZlbnQpO1xuICByZXR1cm4gcHJvdmlkZXIub25FdmVudCgpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNDb21wbGV0ZShldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCk6IFByb21pc2U8SXNDb21wbGV0ZVJlc3BvbnNlPiB7XG4gIGNvbnN0IHByb3ZpZGVyID0gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGV2ZW50KTtcbiAgcmV0dXJuIHByb3ZpZGVyLmlzQ29tcGxldGUoKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSB7XG4gIHN3aXRjaCAoZXZlbnQuUmVzb3VyY2VUeXBlKSB7XG4gICAgY2FzZSBjb25zdHMuQ0xVU1RFUl9SRVNPVVJDRV9UWVBFOiByZXR1cm4gbmV3IENsdXN0ZXJSZXNvdXJjZUhhbmRsZXIoZGVmYXVsdEVrc0NsaWVudCwgZXZlbnQpO1xuICAgIGNhc2UgY29uc3RzLkZBUkdBVEVfUFJPRklMRV9SRVNPVVJDRV9UWVBFOiByZXR1cm4gbmV3IEZhcmdhdGVQcm9maWxlUmVzb3VyY2VIYW5kbGVyKGRlZmF1bHRFa3NDbGllbnQsIGV2ZW50KTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCByZXNvdXJjZSB0eXBlIFwiJHtldmVudC5SZXNvdXJjZVR5cGV9YCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsNkRBQTZEO0FBQzdELG9EQUEwQztBQUMxQyw2REFBNkQ7QUFDN0Qsd0VBQXlFO0FBQ3pFLDZEQUE2RDtBQUM3RCxrRUFBNkQ7QUFDN0QsNkRBQTZEO0FBQzdELDZDQUF5QztBQUN6Qyx1Q0FBbUQ7QUFFbkQsbUNBQW1DO0FBQ25DLHVDQUEwRDtBQUcxRCxNQUFNLFVBQVUsR0FBRyxJQUFJLHdCQUFVLEVBQUUsQ0FBQztBQUNwQyxNQUFNLFNBQVMsR0FBRztJQUNoQixNQUFNLEVBQUUsT0FBTztJQUNmLGNBQWMsRUFBRSxJQUFJLG1DQUFlLENBQUM7UUFDbEMsU0FBUyxFQUFFLFVBQVU7UUFDckIsVUFBVSxFQUFFLFVBQVU7S0FDdkIsQ0FBUTtDQUNWLENBQUM7QUFFRixJQUFJLEdBQW9CLENBQUM7QUFFekIsTUFBTSxnQkFBZ0IsR0FBYztJQUNsQyxhQUFhLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDO0lBQ3ZELGFBQWEsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUM7SUFDdkQsZUFBZSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQztJQUMzRCxjQUFjLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDO0lBQ3pELG1CQUFtQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDO0lBQ25FLG9CQUFvQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDO0lBQ3JFLG9CQUFvQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDO0lBQ3JFLG9CQUFvQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDO0lBQ3JFLHNCQUFzQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUFDO0lBQ3pFLG1CQUFtQixFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7UUFDM0IsR0FBRyxHQUFHLElBQUksZ0JBQUcsQ0FBQztZQUNaLEdBQUcsU0FBUztZQUNaLFdBQVcsRUFBRSxJQUFBLCtDQUF3QixFQUFDO2dCQUNwQyxNQUFNLEVBQUUsR0FBRzthQUNaLENBQUM7U0FDSCxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YsQ0FBQztBQUVGLFNBQVMsWUFBWTtJQUNuQixJQUFJLENBQUMsR0FBRyxFQUFFO1FBQ1IsTUFBTSxJQUFJLEtBQUssQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO0tBQzVFO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRU0sS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrRDtJQUM5RSxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxPQUFPLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUM1QixDQUFDO0FBSEQsMEJBR0M7QUFFTSxLQUFLLFVBQVUsVUFBVSxDQUFDLEtBQWtEO0lBQ2pGLE1BQU0sUUFBUSxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlDLE9BQU8sUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQy9CLENBQUM7QUFIRCxnQ0FHQztBQUVELFNBQVMscUJBQXFCLENBQUMsS0FBa0Q7SUFDL0UsUUFBUSxLQUFLLENBQUMsWUFBWSxFQUFFO1FBQzFCLEtBQUssTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxJQUFJLGdDQUFzQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzlGLEtBQUssTUFBTSxDQUFDLDZCQUE2QixDQUFDLENBQUMsT0FBTyxJQUFJLHVDQUE2QixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzdHO1lBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7S0FDdkU7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0IHsgRUtTIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWVrcyc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBmcm9tVGVtcG9yYXJ5Q3JlZGVudGlhbHMgfSBmcm9tICdAYXdzLXNkay9jcmVkZW50aWFsLXByb3ZpZGVycyc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBOb2RlSHR0cEhhbmRsZXIgfSBmcm9tICdAYXdzLXNkay9ub2RlLWh0dHAtaGFuZGxlcic7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBQcm94eUFnZW50IH0gZnJvbSAncHJveHktYWdlbnQnO1xuaW1wb3J0IHsgQ2x1c3RlclJlc291cmNlSGFuZGxlciB9IGZyb20gJy4vY2x1c3Rlcic7XG5pbXBvcnQgeyBFa3NDbGllbnQgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgKiBhcyBjb25zdHMgZnJvbSAnLi9jb25zdHMnO1xuaW1wb3J0IHsgRmFyZ2F0ZVByb2ZpbGVSZXNvdXJjZUhhbmRsZXIgfSBmcm9tICcuL2ZhcmdhdGUnO1xuaW1wb3J0IHsgSXNDb21wbGV0ZVJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vLi4vY3VzdG9tLXJlc291cmNlcy9saWIvcHJvdmlkZXItZnJhbWV3b3JrL3R5cGVzJztcblxuY29uc3QgcHJveHlBZ2VudCA9IG5ldyBQcm94eUFnZW50KCk7XG5jb25zdCBhd3NDb25maWcgPSB7XG4gIGxvZ2dlcjogY29uc29sZSxcbiAgcmVxdWVzdEhhbmRsZXI6IG5ldyBOb2RlSHR0cEhhbmRsZXIoe1xuICAgIGh0dHBBZ2VudDogcHJveHlBZ2VudCxcbiAgICBodHRwc0FnZW50OiBwcm94eUFnZW50LFxuICB9KSBhcyBhbnksXG59O1xuXG5sZXQgZWtzOiBFS1MgfCB1bmRlZmluZWQ7XG5cbmNvbnN0IGRlZmF1bHRFa3NDbGllbnQ6IEVrc0NsaWVudCA9IHtcbiAgY3JlYXRlQ2x1c3RlcjogcmVxID0+IGdldEVrc0NsaWVudCgpLmNyZWF0ZUNsdXN0ZXIocmVxKSxcbiAgZGVsZXRlQ2x1c3RlcjogcmVxID0+IGdldEVrc0NsaWVudCgpLmRlbGV0ZUNsdXN0ZXIocmVxKSxcbiAgZGVzY3JpYmVDbHVzdGVyOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkuZGVzY3JpYmVDbHVzdGVyKHJlcSksXG4gIGRlc2NyaWJlVXBkYXRlOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkuZGVzY3JpYmVVcGRhdGUocmVxKSxcbiAgdXBkYXRlQ2x1c3RlckNvbmZpZzogcmVxID0+IGdldEVrc0NsaWVudCgpLnVwZGF0ZUNsdXN0ZXJDb25maWcocmVxKSxcbiAgdXBkYXRlQ2x1c3RlclZlcnNpb246IHJlcSA9PiBnZXRFa3NDbGllbnQoKS51cGRhdGVDbHVzdGVyVmVyc2lvbihyZXEpLFxuICBjcmVhdGVGYXJnYXRlUHJvZmlsZTogcmVxID0+IGdldEVrc0NsaWVudCgpLmNyZWF0ZUZhcmdhdGVQcm9maWxlKHJlcSksXG4gIGRlbGV0ZUZhcmdhdGVQcm9maWxlOiByZXEgPT4gZ2V0RWtzQ2xpZW50KCkuZGVsZXRlRmFyZ2F0ZVByb2ZpbGUocmVxKSxcbiAgZGVzY3JpYmVGYXJnYXRlUHJvZmlsZTogcmVxID0+IGdldEVrc0NsaWVudCgpLmRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGUocmVxKSxcbiAgY29uZmlndXJlQXNzdW1lUm9sZTogKHJlcSkgPT4ge1xuICAgIGVrcyA9IG5ldyBFS1Moe1xuICAgICAgLi4uYXdzQ29uZmlnLFxuICAgICAgY3JlZGVudGlhbHM6IGZyb21UZW1wb3JhcnlDcmVkZW50aWFscyh7XG4gICAgICAgIHBhcmFtczogcmVxLFxuICAgICAgfSksXG4gICAgfSk7XG4gIH0sXG59O1xuXG5mdW5jdGlvbiBnZXRFa3NDbGllbnQoKSB7XG4gIGlmICghZWtzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFS1MgY2xpZW50IG5vdCBpbml0aWFsaXplZCAoY2FsbCBcImNvbmZpZ3VyZUFzc3VtZVJvbGVcIiknKTtcbiAgfVxuXG4gIHJldHVybiBla3M7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbkV2ZW50KGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSB7XG4gIGNvbnN0IHByb3ZpZGVyID0gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGV2ZW50KTtcbiAgcmV0dXJuIHByb3ZpZGVyLm9uRXZlbnQoKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlzQ29tcGxldGUoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpOiBQcm9taXNlPElzQ29tcGxldGVSZXNwb25zZT4ge1xuICBjb25zdCBwcm92aWRlciA9IGNyZWF0ZVJlc291cmNlSGFuZGxlcihldmVudCk7XG4gIHJldHVybiBwcm92aWRlci5pc0NvbXBsZXRlKCk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlc291cmNlSGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCkge1xuICBzd2l0Y2ggKGV2ZW50LlJlc291cmNlVHlwZSkge1xuICAgIGNhc2UgY29uc3RzLkNMVVNURVJfUkVTT1VSQ0VfVFlQRTogcmV0dXJuIG5ldyBDbHVzdGVyUmVzb3VyY2VIYW5kbGVyKGRlZmF1bHRFa3NDbGllbnQsIGV2ZW50KTtcbiAgICBjYXNlIGNvbnN0cy5GQVJHQVRFX1BST0ZJTEVfUkVTT1VSQ0VfVFlQRTogcmV0dXJuIG5ldyBGYXJnYXRlUHJvZmlsZVJlc291cmNlSGFuZGxlcihkZWZhdWx0RWtzQ2xpZW50LCBldmVudCk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgcmVzb3VyY2UgdHlwZSBcIiR7ZXZlbnQuUmVzb3VyY2VUeXBlfWApO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.ts similarity index 99% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.ts index 4004ddf5cd22e..8ab163c37ac93 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/index.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49/index.ts @@ -19,7 +19,7 @@ const awsConfig = { requestHandler: new NodeHttpHandler({ httpAgent: proxyAgent, httpsAgent: proxyAgent, - }), + }) as any, }; let eks: EKS | undefined; diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.js deleted file mode 100644 index 50571d01a66a5..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/cluster.js +++ /dev/null @@ -1,280 +0,0 @@ -"use strict"; -/* eslint-disable no-console */ -Object.defineProperty(exports, "__esModule", { value: true }); -exports.ClusterResourceHandler = void 0; -// eslint-disable-next-line import/no-extraneous-dependencies -const EKS = require("@aws-sdk/client-eks"); -const common_1 = require("./common"); -const compareLogging_1 = require("./compareLogging"); -const MAX_CLUSTER_NAME_LEN = 100; -class ClusterResourceHandler extends common_1.ResourceHandler { - get clusterName() { - if (!this.physicalResourceId) { - throw new Error('Cannot determine cluster name without physical resource ID'); - } - return this.physicalResourceId; - } - constructor(eks, event) { - super(eks, event); - this.newProps = parseProps(this.event.ResourceProperties); - this.oldProps = event.RequestType === 'Update' ? parseProps(event.OldResourceProperties) : {}; - // compare newProps and oldProps and update the newProps by appending disabled LogSetup if any - const compared = (0, compareLogging_1.compareLoggingProps)(this.oldProps, this.newProps); - this.newProps.logging = compared.logging; - } - // ------ - // CREATE - // ------ - async onCreate() { - console.log('onCreate: creating cluster with options:', JSON.stringify(this.newProps, undefined, 2)); - if (!this.newProps.roleArn) { - throw new Error('"roleArn" is required'); - } - const clusterName = this.newProps.name || this.generateClusterName(); - const resp = await this.eks.createCluster({ - ...this.newProps, - name: clusterName, - }); - if (!resp.cluster) { - throw new Error(`Error when trying to create cluster ${clusterName}: CreateCluster returned without cluster information`); - } - return { - PhysicalResourceId: resp.cluster.name, - }; - } - async isCreateComplete() { - return this.isActive(); - } - // ------ - // DELETE - // ------ - async onDelete() { - console.log(`onDelete: deleting cluster ${this.clusterName}`); - try { - await this.eks.deleteCluster({ name: this.clusterName }); - } - catch (e) { - if (!(e instanceof EKS.ResourceNotFoundException)) { - throw e; - } - else { - console.log(`cluster ${this.clusterName} not found, idempotently succeeded`); - } - } - return { - PhysicalResourceId: this.clusterName, - }; - } - async isDeleteComplete() { - console.log(`isDeleteComplete: waiting for cluster ${this.clusterName} to be deleted`); - try { - const resp = await this.eks.describeCluster({ name: this.clusterName }); - console.log('describeCluster returned:', JSON.stringify(resp, undefined, 2)); - } - catch (e) { - // see https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/ - if (e instanceof EKS.ResourceNotFoundException) { - console.log('received ResourceNotFoundException, this means the cluster has been deleted (or never existed)'); - return { IsComplete: true }; - } - console.log('describeCluster error:', e); - throw e; - } - return { - IsComplete: false, - }; - } - // ------ - // UPDATE - // ------ - async onUpdate() { - const updates = analyzeUpdate(this.oldProps, this.newProps); - console.log('onUpdate:', JSON.stringify({ updates }, undefined, 2)); - // updates to encryption config is not supported - if (updates.updateEncryption) { - throw new Error('Cannot update cluster encryption configuration'); - } - // if there is an update that requires replacement, go ahead and just create - // a new cluster with the new config. The old cluster will automatically be - // deleted by cloudformation upon success. - if (updates.replaceName || updates.replaceRole || updates.replaceVpc) { - // if we are replacing this cluster and the cluster has an explicit - // physical name, the creation of the new cluster will fail with "there is - // already a cluster with that name". this is a common behavior for - // CloudFormation resources that support specifying a physical name. - if (this.oldProps.name === this.newProps.name && this.oldProps.name) { - throw new Error(`Cannot replace cluster "${this.oldProps.name}" since it has an explicit physical name. Either rename the cluster or remove the "name" configuration`); - } - return this.onCreate(); - } - // if a version update is required, issue the version update - if (updates.updateVersion) { - if (!this.newProps.version) { - throw new Error(`Cannot remove cluster version configuration. Current version is ${this.oldProps.version}`); - } - return this.updateClusterVersion(this.newProps.version); - } - if (updates.updateLogging && updates.updateAccess) { - throw new Error('Cannot update logging and access at the same time'); - } - if (updates.updateLogging || updates.updateAccess) { - const config = { - name: this.clusterName, - }; - if (updates.updateLogging) { - config.logging = this.newProps.logging; - } - ; - if (updates.updateAccess) { - // Updating the cluster with securityGroupIds and subnetIds (as specified in the warning here: - // https://awscli.amazonaws.com/v2/documentation/api/latest/reference/eks/update-cluster-config.html) - // will fail, therefore we take only the access fields explicitly - config.resourcesVpcConfig = { - endpointPrivateAccess: this.newProps.resourcesVpcConfig?.endpointPrivateAccess, - endpointPublicAccess: this.newProps.resourcesVpcConfig?.endpointPublicAccess, - publicAccessCidrs: this.newProps.resourcesVpcConfig?.publicAccessCidrs, - }; - } - const updateResponse = await this.eks.updateClusterConfig(config); - return { EksUpdateId: updateResponse.update?.id }; - } - // no updates - return; - } - async isUpdateComplete() { - console.log('isUpdateComplete'); - // if this is an EKS update, we will monitor the update event itself - if (this.event.EksUpdateId) { - const complete = await this.isEksUpdateComplete(this.event.EksUpdateId); - if (!complete) { - return { IsComplete: false }; - } - // fall through: if the update is done, we simply delegate to isActive() - // in order to extract attributes and state from the cluster itself, which - // is supposed to be in an ACTIVE state after the update is complete. - } - return this.isActive(); - } - async updateClusterVersion(newVersion) { - console.log(`updating cluster version to ${newVersion}`); - // update-cluster-version will fail if we try to update to the same version, - // so skip in this case. - const cluster = (await this.eks.describeCluster({ name: this.clusterName })).cluster; - if (cluster?.version === newVersion) { - console.log(`cluster already at version ${cluster.version}, skipping version update`); - return; - } - const updateResponse = await this.eks.updateClusterVersion({ name: this.clusterName, version: newVersion }); - return { EksUpdateId: updateResponse.update?.id }; - } - async isActive() { - console.log('waiting for cluster to become ACTIVE'); - const resp = await this.eks.describeCluster({ name: this.clusterName }); - console.log('describeCluster result:', JSON.stringify(resp, undefined, 2)); - const cluster = resp.cluster; - // if cluster is undefined (shouldnt happen) or status is not ACTIVE, we are - // not complete. note that the custom resource provider framework forbids - // returning attributes (Data) if isComplete is false. - if (cluster?.status === 'FAILED') { - // not very informative, unfortunately the response doesn't contain any error - // information :\ - throw new Error('Cluster is in a FAILED status'); - } - else if (cluster?.status !== 'ACTIVE') { - return { - IsComplete: false, - }; - } - else { - return { - IsComplete: true, - Data: { - Name: cluster.name, - Endpoint: cluster.endpoint, - Arn: cluster.arn, - // IMPORTANT: CFN expects that attributes will *always* have values, - // so return an empty string in case the value is not defined. - // Otherwise, CFN will throw with `Vendor response doesn't contain - // XXXX key`. - CertificateAuthorityData: cluster.certificateAuthority?.data ?? '', - ClusterSecurityGroupId: cluster.resourcesVpcConfig?.clusterSecurityGroupId ?? '', - OpenIdConnectIssuerUrl: cluster.identity?.oidc?.issuer ?? '', - OpenIdConnectIssuer: cluster.identity?.oidc?.issuer?.substring(8) ?? '', - // We can safely return the first item from encryption configuration array, because it has a limit of 1 item - // https://docs.amazon.com/eks/latest/APIReference/API_CreateCluster.html#AmazonEKS-CreateCluster-request-encryptionConfig - EncryptionConfigKeyArn: cluster.encryptionConfig?.shift()?.provider?.keyArn ?? '', - }, - }; - } - } - async isEksUpdateComplete(eksUpdateId) { - this.log({ isEksUpdateComplete: eksUpdateId }); - const describeUpdateResponse = await this.eks.describeUpdate({ - name: this.clusterName, - updateId: eksUpdateId, - }); - this.log({ describeUpdateResponse }); - if (!describeUpdateResponse.update) { - throw new Error(`unable to describe update with id "${eksUpdateId}"`); - } - switch (describeUpdateResponse.update.status) { - case 'InProgress': - return false; - case 'Successful': - return true; - case 'Failed': - case 'Cancelled': - throw new Error(`cluster update id "${eksUpdateId}" failed with errors: ${JSON.stringify(describeUpdateResponse.update.errors)}`); - default: - throw new Error(`unknown status "${describeUpdateResponse.update.status}" for update id "${eksUpdateId}"`); - } - } - generateClusterName() { - const suffix = this.requestId.replace(/-/g, ''); // 32 chars - const offset = MAX_CLUSTER_NAME_LEN - suffix.length - 1; - const prefix = this.logicalResourceId.slice(0, offset > 0 ? offset : 0); - return `${prefix}-${suffix}`; - } -} -exports.ClusterResourceHandler = ClusterResourceHandler; -function parseProps(props) { - const parsed = props?.Config ?? {}; - // this is weird but these boolean properties are passed by CFN as a string, and we need them to be booleanic for the SDK. - // Otherwise it fails with 'Unexpected Parameter: params.resourcesVpcConfig.endpointPrivateAccess is expected to be a boolean' - if (typeof (parsed.resourcesVpcConfig?.endpointPrivateAccess) === 'string') { - parsed.resourcesVpcConfig.endpointPrivateAccess = parsed.resourcesVpcConfig.endpointPrivateAccess === 'true'; - } - if (typeof (parsed.resourcesVpcConfig?.endpointPublicAccess) === 'string') { - parsed.resourcesVpcConfig.endpointPublicAccess = parsed.resourcesVpcConfig.endpointPublicAccess === 'true'; - } - if (typeof (parsed.logging?.clusterLogging[0].enabled) === 'string') { - parsed.logging.clusterLogging[0].enabled = parsed.logging.clusterLogging[0].enabled === 'true'; - } - return parsed; -} -function analyzeUpdate(oldProps, newProps) { - console.log('old props: ', JSON.stringify(oldProps)); - console.log('new props: ', JSON.stringify(newProps)); - const newVpcProps = newProps.resourcesVpcConfig || {}; - const oldVpcProps = oldProps.resourcesVpcConfig || {}; - const oldPublicAccessCidrs = new Set(oldVpcProps.publicAccessCidrs ?? []); - const newPublicAccessCidrs = new Set(newVpcProps.publicAccessCidrs ?? []); - const newEnc = newProps.encryptionConfig || {}; - const oldEnc = oldProps.encryptionConfig || {}; - return { - replaceName: newProps.name !== oldProps.name, - replaceVpc: JSON.stringify(newVpcProps.subnetIds?.sort()) !== JSON.stringify(oldVpcProps.subnetIds?.sort()) || - JSON.stringify(newVpcProps.securityGroupIds?.sort()) !== JSON.stringify(oldVpcProps.securityGroupIds?.sort()), - updateAccess: newVpcProps.endpointPrivateAccess !== oldVpcProps.endpointPrivateAccess || - newVpcProps.endpointPublicAccess !== oldVpcProps.endpointPublicAccess || - !setsEqual(newPublicAccessCidrs, oldPublicAccessCidrs), - replaceRole: newProps.roleArn !== oldProps.roleArn, - updateVersion: newProps.version !== oldProps.version, - updateEncryption: JSON.stringify(newEnc) !== JSON.stringify(oldEnc), - updateLogging: JSON.stringify(newProps.logging) !== JSON.stringify(oldProps.logging), - }; -} -function setsEqual(first, second) { - return first.size === second.size && [...first].every((e) => second.has(e)); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2x1c3Rlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsdXN0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtCQUErQjs7O0FBRS9CLDZEQUE2RDtBQUM3RCwyQ0FBMkM7QUFDM0MscUNBQXFFO0FBQ3JFLHFEQUF1RDtBQUd2RCxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQztBQUVqQyxNQUFhLHNCQUF1QixTQUFRLHdCQUFlO0lBQ3pELElBQVcsV0FBVztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsNERBQTRELENBQUMsQ0FBQztTQUMvRTtRQUVELE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDO0tBQ2hDO0lBS0QsWUFBWSxHQUFjLEVBQUUsS0FBb0I7UUFDOUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVsQixJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDOUYsOEZBQThGO1FBQzlGLE1BQU0sUUFBUSxHQUEyQyxJQUFBLG9DQUFtQixFQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzNHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7S0FDMUM7SUFFRCxTQUFTO0lBQ1QsU0FBUztJQUNULFNBQVM7SUFFQyxLQUFLLENBQUMsUUFBUTtRQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFB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LG9CQUFvQixLQUFLLFdBQVcsQ0FBQyxvQkFBb0I7WUFDckUsQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsb0JBQW9CLENBQUM7UUFDeEQsV0FBVyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLE9BQU87UUFDbEQsYUFBYSxFQUFFLFFBQVEsQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLE9BQU87UUFDcEQsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUNuRSxhQUFhLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO0tBQ3JGLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsS0FBa0IsRUFBRSxNQUFtQjtJQUN4RCxPQUFPLEtBQUssQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0ICogYXMgRUtTIGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1la3MnO1xuaW1wb3J0IHsgRWtzQ2xpZW50LCBSZXNvdXJjZUV2ZW50LCBSZXNvdXJjZUhhbmRsZXIgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgeyBjb21wYXJlTG9nZ2luZ1Byb3BzIH0gZnJvbSAnLi9jb21wYXJlTG9nZ2luZyc7XG5pbXBvcnQgeyBJc0NvbXBsZXRlUmVzcG9uc2UsIE9uRXZlbnRSZXNwb25zZSB9IGZyb20gJy4uLy4uLy4uL2N1c3RvbS1yZXNvdXJjZXMvbGliL3Byb3ZpZGVyLWZyYW1ld29yay90eXBlcyc7XG5cbmNvbnN0IE1BWF9DTFVTVEVSX05BTUVfTEVOID0gMTAwO1xuXG5leHBvcnQgY2xhc3MgQ2x1c3RlclJlc291cmNlSGFuZGxlciBleHRlbmRzIFJlc291cmNlSGFuZGxlciB7XG4gIHB1YmxpYyBnZXQgY2x1c3Rlck5hbWUoKSB7XG4gICAgaWYgKCF0aGlzLnBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZGV0ZXJtaW5lIGNsdXN0ZXIgbmFtZSB3aXRob3V0IHBoeXNpY2FsIHJlc291cmNlIElEJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucGh5c2ljYWxSZXNvdXJjZUlkO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBuZXdQcm9wczogRUtTLkNyZWF0ZUNsdXN0ZXJDb21tYW5kSW5wdXQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgb2xkUHJvcHM6IFBhcnRpYWw8RUtTLkNyZWF0ZUNsdXN0ZXJDb21tYW5kSW5wdXQ+O1xuXG4gIGNvbnN0cnVjdG9yKGVrczogRWtzQ2xpZW50LCBldmVudDogUmVzb3VyY2VFdmVudCkge1xuICAgIHN1cGVyKGVrcywgZXZlbnQpO1xuXG4gICAgdGhpcy5uZXdQcm9wcyA9IHBhcnNlUHJvcHModGhpcy5ldmVudC5SZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgIHRoaXMub2xkUHJvcHMgPSBldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ1VwZGF0ZScgPyBwYXJzZVByb3BzKGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcykgOiB7fTtcbiAgICAvLyBjb21wYXJlIG5ld1Byb3BzIGFuZCBvbGRQcm9wcyBhbmQgdXBkYXRlIHRoZSBuZXdQcm9wcyBieSBhcHBlbmRpbmcgZGlzYWJsZWQgTG9nU2V0dXAgaWYgYW55XG4gICAgY29uc3QgY29tcGFyZWQ6IFBhcnRpYWw8RUtTLkNyZWF0ZUNsdXN0ZXJDb21tYW5kSW5wdXQ+ID0gY29tcGFyZUxvZ2dpbmdQcm9wcyh0aGlzLm9sZFByb3BzLCB0aGlzLm5ld1Byb3BzKTtcbiAgICB0aGlzLm5ld1Byb3BzLmxvZ2dpbmcgPSBjb21wYXJlZC5sb2dnaW5nO1xuICB9XG5cbiAgLy8gLS0tLS0tXG4gIC8vIENSRUFURVxuICAvLyAtLS0tLS1cblxuICBwcm90ZWN0ZWQgYXN5bmMgb25DcmVhdGUoKTogUHJvbWlzZTxPbkV2ZW50UmVzcG9uc2U+IHtcbiAgICBjb25zb2xlLmxvZygnb25DcmVhdGU6IGNyZWF0aW5nIGNsdXN0ZXIgd2l0aCBvcHRpb25zOicsIEpTT04uc3RyaW5naWZ5KHRoaXMubmV3UHJvcHMsIHVuZGVmaW5lZCwgMikpO1xuICAgIGlmICghdGhpcy5uZXdQcm9wcy5yb2xlQXJuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1wicm9sZUFyblwiIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgY2x1c3Rlck5hbWUgPSB0aGlzLm5ld1Byb3BzLm5hbWUgfHwgdGhpcy5nZW5lcmF0ZUNsdXN0ZXJOYW1lKCk7XG5cbiAgICBjb25zdCByZXNwID0gYXdhaXQgdGhpcy5la3MuY3JlYXRlQ2x1c3Rlcih7XG4gICAgICAuLi50aGlzLm5ld1Byb3BzLFxuICAgICAgbmFtZTogY2x1c3Rlck5hbWUsXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3AuY2x1c3Rlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciB3aGVuIHRyeWluZyB0byBjcmVhdGUgY2x1c3RlciAke2NsdXN0ZXJOYW1lfTogQ3JlYXRlQ2x1c3RlciByZXR1cm5lZCB3aXRob3V0IGNsdXN0ZXIgaW5mb3JtYXRpb25gKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgUGh5c2ljYWxSZXNvdXJjZUlkOiByZXNwLmNsdXN0ZXIubmFtZSxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlzQ3JlYXRlQ29tcGxldGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNBY3RpdmUoKTtcbiAgfVxuXG4gIC8vIC0tLS0tLVxuICAvLyBERUxFVEVcbiAgLy8gLS0tLS0tXG5cbiAgcHJvdGVjdGVkIGFzeW5jIG9uRGVsZXRlKCk6IFByb21pc2U8T25FdmVudFJlc3BvbnNlPiB7XG4gICAgY29uc29sZS5sb2coYG9uRGVsZXRlOiBkZWxldGluZyBjbHVzdGVyICR7dGhpcy5jbHVzdGVyTmFtZX1gKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5la3MuZGVsZXRlQ2x1c3Rlcih7IG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUgfSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgRUtTLlJlc291cmNlTm90Rm91bmRFeGNlcHRpb24pKSB7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhgY2x1c3RlciAke3RoaXMuY2x1c3Rlck5hbWV9IG5vdCBmb3VuZCwgaWRlbXBvdGVudGx5IHN1Y2NlZWRlZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgUGh5c2ljYWxSZXNvdXJjZUlkOiB0aGlzLmNsdXN0ZXJOYW1lLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaXNEZWxldGVDb21wbGV0ZSgpOiBQcm9taXNlPElzQ29tcGxldGVSZXNwb25zZT4ge1xuICAgIGNvbnNvbGUubG9nKGBpc0RlbGV0ZUNvbXBsZXRlOiB3YWl0aW5nIGZvciBjbHVzdGVyICR7dGhpcy5jbHVzdGVyTmFtZX0gdG8gYmUgZGVsZXRlZGApO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCB0aGlzLmVrcy5kZXNjcmliZUNsdXN0ZXIoeyBuYW1lOiB0aGlzLmNsdXN0ZXJOYW1lIH0pO1xuICAgICAgY29uc29sZS5sb2coJ2Rlc2NyaWJlQ2x1c3RlciByZXR1cm5lZDonLCBKU09OLnN0cmluZ2lmeShyZXNwLCB1bmRlZmluZWQsIDIpKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIC8vIHNlZSBodHRwczovL2F3cy5hbWF6b24uY29tL2Jsb2dzL2RldmVsb3Blci9zZXJ2aWNlLWVycm9yLWhhbmRsaW5nLW1vZHVsYXItYXdzLXNkay1qcy9cbiAgICAgIGlmIChlIGluc3RhbmNlb2YgRUtTLlJlc291cmNlTm90Rm91bmRFeGNlcHRpb24pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3JlY2VpdmVkIFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24sIHRoaXMgbWVhbnMgdGhlIGNsdXN0ZXIgaGFzIGJlZW4gZGVsZXRlZCAob3IgbmV2ZXIgZXhpc3RlZCknKTtcbiAgICAgICAgcmV0dXJuIHsgSXNDb21wbGV0ZTogdHJ1ZSB9O1xuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmxvZygnZGVzY3JpYmVDbHVzdGVyIGVycm9yOicsIGUpO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgSXNDb21wbGV0ZTogZmFsc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8vIC0tLS0tLVxuICAvLyBVUERBVEVcbiAgLy8gLS0tLS0tXG5cbiAgcHJvdGVjdGVkIGFzeW5jIG9uVXBkYXRlKCkge1xuICAgIGNvbnN0IHVwZGF0ZXMgPSBhbmFseXplVXBkYXRlKHRoaXMub2xkUHJvcHMsIHRoaXMubmV3UHJvcHMpO1xuICAgIGNvbnNvbGUubG9nKCdvblVwZGF0ZTonLCBKU09OLnN0cmluZ2lmeSh7IHVwZGF0ZXMgfSwgdW5kZWZpbmVkLCAyKSk7XG5cbiAgICAvLyB1cGRhdGVzIHRvIGVuY3J5cHRpb24gY29uZmlnIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICBpZiAodXBkYXRlcy51cGRhdGVFbmNyeXB0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCB1cGRhdGUgY2x1c3RlciBlbmNyeXB0aW9uIGNvbmZpZ3VyYXRpb24nKTtcbiAgICB9XG5cbiAgICAvLyBpZiB0aGVyZSBpcyBhbiB1cGRhdGUgdGhhdCByZXF1aXJlcyByZXBsYWNlbWVudCwgZ28gYWhlYWQgYW5kIGp1c3QgY3JlYXRlXG4gICAgLy8gYSBuZXcgY2x1c3RlciB3aXRoIHRoZSBuZXcgY29uZmlnLiBUaGUgb2xkIGNsdXN0ZXIgd2lsbCBhdXRvbWF0aWNhbGx5IGJlXG4gICAgLy8gZGVsZXRlZCBieSBjbG91ZGZvcm1hdGlvbiB1cG9uIHN1Y2Nlc3MuXG4gICAgaWYgKHVwZGF0ZXMucmVwbGFjZU5hbWUgfHwgdXBkYXRlcy5yZXBsYWNlUm9sZSB8fCB1cGRhdGVzLnJlcGxhY2VWcGMpIHtcblxuICAgICAgLy8gaWYgd2UgYXJlIHJlcGxhY2luZyB0aGlzIGNsdXN0ZXIgYW5kIHRoZSBjbHVzdGVyIGhhcyBhbiBleHBsaWNpdFxuICAgICAgLy8gcGh5c2ljYWwgbmFtZSwgdGhlIGNyZWF0aW9uIG9mIHRoZSBuZXcgY2x1c3RlciB3aWxsIGZhaWwgd2l0aCBcInRoZXJlIGlzXG4gICAgICAvLyBhbHJlYWR5IGEgY2x1c3RlciB3aXRoIHRoYXQgbmFtZVwiLiB0aGlzIGlzIGEgY29tbW9uIGJlaGF2aW9yIGZvclxuICAgICAgLy8gQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2VzIHRoYXQgc3VwcG9ydCBzcGVjaWZ5aW5nIGEgcGh5c2ljYWwgbmFtZS5cbiAgICAgIGlmICh0aGlzLm9sZFByb3BzLm5hbWUgPT09IHRoaXMubmV3UHJvcHMubmFtZSAmJiB0aGlzLm9sZFByb3BzLm5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcmVwbGFjZSBjbHVzdGVyIFwiJHt0aGlzLm9sZFByb3BzLm5hbWV9XCIgc2luY2UgaXQgaGFzIGFuIGV4cGxpY2l0IHBoeXNpY2FsIG5hbWUuIEVpdGhlciByZW5hbWUgdGhlIGNsdXN0ZXIgb3IgcmVtb3ZlIHRoZSBcIm5hbWVcIiBjb25maWd1cmF0aW9uYCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLm9uQ3JlYXRlKCk7XG4gICAgfVxuXG4gICAgLy8gaWYgYSB2ZXJzaW9uIHVwZGF0ZSBpcyByZXF1aXJlZCwgaXNzdWUgdGhlIHZlcnNpb24gdXBkYXRlXG4gICAgaWYgKHVwZGF0ZXMudXBkYXRlVmVyc2lvbikge1xuICAgICAgaWYgKCF0aGlzLm5ld1Byb3BzLnZlcnNpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcmVtb3ZlIGNsdXN0ZXIgdmVyc2lvbiBjb25maWd1cmF0aW9uLiBDdXJyZW50IHZlcnNpb24gaXMgJHt0aGlzLm9sZFByb3BzLnZlcnNpb259YCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnVwZGF0ZUNsdXN0ZXJWZXJzaW9uKHRoaXMubmV3UHJvcHMudmVyc2lvbik7XG4gICAgfVxuXG4gICAgaWYgKHVwZGF0ZXMudXBkYXRlTG9nZ2luZyAmJiB1cGRhdGVzLnVwZGF0ZUFjY2Vzcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgdXBkYXRlIGxvZ2dpbmcgYW5kIGFjY2VzcyBhdCB0aGUgc2FtZSB0aW1lJyk7XG4gICAgfVxuXG4gICAgaWYgKHVwZGF0ZXMudXBkYXRlTG9nZ2luZyB8fCB1cGRhdGVzLnVwZGF0ZUFjY2Vzcykge1xuICAgICAgY29uc3QgY29uZmlnOiBFS1MuVXBkYXRlQ2x1c3RlckNvbmZpZ0NvbW1hbmRJbnB1dCA9IHtcbiAgICAgICAgbmFtZTogdGhpcy5jbHVzdGVyTmFtZSxcbiAgICAgIH07XG4gICAgICBpZiAodXBkYXRlcy51cGRhdGVMb2dnaW5nKSB7XG4gICAgICAgIGNvbmZpZy5sb2dnaW5nID0gdGhpcy5uZXdQcm9wcy5sb2dnaW5nO1xuICAgICAgfTtcbiAgICAgIGlmICh1cGRhdGVzLnVwZGF0ZUFjY2Vzcykge1xuICAgICAgICAvLyBVcGRhdGluZyB0aGUgY2x1c3RlciB3aXRoIHNlY3VyaXR5R3JvdXBJZHMgYW5kIHN1Ym5ldElkcyAoYXMgc3BlY2lmaWVkIGluIHRoZSB3YXJuaW5nIGhlcmU6XG4gICAgICAgIC8vIGh0dHBzOi8vYXdzY2xpLmFtYXpvbmF3cy5jb20vdjIvZG9jdW1lbnRhdGlvbi9hcGkvbGF0ZXN0L3JlZmVyZW5jZS9la3MvdXBkYXRlLWNsdXN0ZXItY29uZmlnLmh0bWwpXG4gICAgICAgIC8vIHdpbGwgZmFpbCwgdGhlcmVmb3JlIHdlIHRha2Ugb25seSB0aGUgYWNjZXNzIGZpZWxkcyBleHBsaWNpdGx5XG4gICAgICAgIGNvbmZpZy5yZXNvdXJjZXNWcGNDb25maWcgPSB7XG4gICAgICAgICAgZW5kcG9pbnRQcml2YXRlQWNjZXNzOiB0aGlzLm5ld1Byb3BzLnJlc291cmNlc1ZwY0NvbmZpZz8uZW5kcG9pbnRQcml2YXRlQWNjZXNzLFxuICAgICAgICAgIGVuZHBvaW50UHVibGljQWNjZXNzOiB0aGlzLm5ld1Byb3BzLnJlc291cmNlc1ZwY0NvbmZpZz8uZW5kcG9pbnRQdWJsaWNBY2Nlc3MsXG4gICAgICAgICAgcHVibGljQWNjZXNzQ2lkcnM6IHRoaXMubmV3UHJvcHMucmVzb3VyY2VzVnBjQ29uZmlnPy5wdWJsaWNBY2Nlc3NDaWRycyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVwZGF0ZVJlc3BvbnNlID0gYXdhaXQgdGhpcy5la3MudXBkYXRlQ2x1c3RlckNvbmZpZyhjb25maWcpO1xuXG4gICAgICByZXR1cm4geyBFa3NVcGRhdGVJZDogdXBkYXRlUmVzcG9uc2UudXBkYXRlPy5pZCB9O1xuICAgIH1cblxuICAgIC8vIG5vIHVwZGF0ZXNcbiAgICByZXR1cm47XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaXNVcGRhdGVDb21wbGV0ZSgpIHtcbiAgICBjb25zb2xlLmxvZygnaXNVcGRhdGVDb21wbGV0ZScpO1xuXG4gICAgLy8gaWYgdGhpcyBpcyBhbiBFS1MgdXBkYXRlLCB3ZSB3aWxsIG1vbml0b3IgdGhlIHVwZGF0ZSBldmVudCBpdHNlbGZcbiAgICBpZiAodGhpcy5ldmVudC5Fa3NVcGRhdGVJZCkge1xuICAgICAgY29uc3QgY29tcGxldGUgPSBhd2FpdCB0aGlzLmlzRWtzVXBkYXRlQ29tcGxldGUodGhpcy5ldmVudC5Fa3NVcGRhdGVJZCk7XG4gICAgICBpZiAoIWNvbXBsZXRlKSB7XG4gICAgICAgIHJldHVybiB7IElzQ29tcGxldGU6IGZhbHNlIH07XG4gICAgICB9XG5cbiAgICAgIC8vIGZhbGwgdGhyb3VnaDogaWYgdGhlIHVwZGF0ZSBpcyBkb25lLCB3ZSBzaW1wbHkgZGVsZWdhdGUgdG8gaXNBY3RpdmUoKVxuICAgICAgLy8gaW4gb3JkZXIgdG8gZXh0cmFjdCBhdHRyaWJ1dGVzIGFuZCBzdGF0ZSBmcm9tIHRoZSBjbHVzdGVyIGl0c2VsZiwgd2hpY2hcbiAgICAgIC8vIGlzIHN1cHBvc2VkIHRvIGJlIGluIGFuIEFDVElWRSBzdGF0ZSBhZnRlciB0aGUgdXBkYXRlIGlzIGNvbXBsZXRlLlxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmlzQWN0aXZlKCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUNsdXN0ZXJWZXJzaW9uKG5ld1ZlcnNpb246IHN0cmluZykge1xuICAgIGNvbnNvbGUubG9nKGB1cGRhdGluZyBjbHVzdGVyIHZlcnNpb24gdG8gJHtuZXdWZXJzaW9ufWApO1xuXG4gICAgLy8gdXBkYXRlLWNsdXN0ZXItdmVyc2lvbiB3aWxsIGZhaWwgaWYgd2UgdHJ5IHRvIHVwZGF0ZSB0byB0aGUgc2FtZSB2ZXJzaW9uLFxuICAgIC8vIHNvIHNraXAgaW4gdGhpcyBjYXNlLlxuICAgIGNvbnN0IGNsdXN0ZXIgPSAoYXdhaXQgdGhpcy5la3MuZGVzY3JpYmVDbHVzdGVyKHsgbmFtZTogdGhpcy5jbHVzdGVyTmFtZSB9KSkuY2x1c3RlcjtcbiAgICBpZiAoY2x1c3Rlcj8udmVyc2lvbiA9PT0gbmV3VmVyc2lvbikge1xuICAgICAgY29uc29sZS5sb2coYGNsdXN0ZXIgYWxyZWFkeSBhdCB2ZXJzaW9uICR7Y2x1c3Rlci52ZXJzaW9ufSwgc2tpcHBpbmcgdmVyc2lvbiB1cGRhdGVgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB1cGRhdGVSZXNwb25zZSA9IGF3YWl0IHRoaXMuZWtzLnVwZGF0ZUNsdXN0ZXJWZXJzaW9uKHsgbmFtZTogdGhpcy5jbHVzdGVyTmFtZSwgdmVyc2lvbjogbmV3VmVyc2lvbiB9KTtcbiAgICByZXR1cm4geyBFa3NVcGRhdGVJZDogdXBkYXRlUmVzcG9uc2UudXBkYXRlPy5pZCB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpc0FjdGl2ZSgpOiBQcm9taXNlPElzQ29tcGxldGVSZXNwb25zZT4ge1xuICAgIGNvbnNvbGUubG9nKCd3YWl0aW5nIGZvciBjbHVzdGVyIHRvIGJlY29tZSBBQ1RJVkUnKTtcbiAgICBjb25zdCByZXNwID0gYXdhaXQgdGhpcy5la3MuZGVzY3JpYmVDbHVzdGVyKHsgbmFtZTogdGhpcy5jbHVzdGVyTmFtZSB9KTtcbiAgICBjb25zb2xlLmxvZygnZGVzY3JpYmVDbHVzdGVyIHJlc3VsdDonLCBKU09OLnN0cmluZ2lmeShyZXNwLCB1bmRlZmluZWQsIDIpKTtcbiAgICBjb25zdCBjbHVzdGVyID0gcmVzcC5jbHVzdGVyO1xuXG4gICAgLy8gaWYgY2x1c3RlciBpcyB1bmRlZmluZWQgKHNob3VsZG50IGhhcHBlbikgb3Igc3RhdHVzIGlzIG5vdCBBQ1RJVkUsIHdlIGFyZVxuICAgIC8vIG5vdCBjb21wbGV0ZS4gbm90ZSB0aGF0IHRoZSBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXIgZnJhbWV3b3JrIGZvcmJpZHNcbiAgICAvLyByZXR1cm5pbmcgYXR0cmlidXRlcyAoRGF0YSkgaWYgaXNDb21wbGV0ZSBpcyBmYWxzZS5cbiAgICBpZiAoY2x1c3Rlcj8uc3RhdHVzID09PSAnRkFJTEVEJykge1xuICAgICAgLy8gbm90IHZlcnkgaW5mb3JtYXRpdmUsIHVuZm9ydHVuYXRlbHkgdGhlIHJlc3BvbnNlIGRvZXNuJ3QgY29udGFpbiBhbnkgZXJyb3JcbiAgICAgIC8vIGluZm9ybWF0aW9uIDpcXFxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDbHVzdGVyIGlzIGluIGEgRkFJTEVEIHN0YXR1cycpO1xuICAgIH0gZWxzZSBpZiAoY2x1c3Rlcj8uc3RhdHVzICE9PSAnQUNUSVZFJykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgSXNDb21wbGV0ZTogZmFsc2UsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBJc0NvbXBsZXRlOiB0cnVlLFxuICAgICAgICBEYXRhOiB7XG4gICAgICAgICAgTmFtZTogY2x1c3Rlci5uYW1lLFxuICAgICAgICAgIEVuZHBvaW50OiBjbHVzdGVyLmVuZHBvaW50LFxuICAgICAgICAgIEFybjogY2x1c3Rlci5hcm4sXG5cbiAgICAgICAgICAvLyBJTVBPUlRBTlQ6IENGTiBleHBlY3RzIHRoYXQgYXR0cmlidXRlcyB3aWxsICphbHdheXMqIGhhdmUgdmFsdWVzLFxuICAgICAgICAgIC8vIHNvIHJldHVybiBhbiBlbXB0eSBzdHJpbmcgaW4gY2FzZSB0aGUgdmFsdWUgaXMgbm90IGRlZmluZWQuXG4gICAgICAgICAgLy8gT3RoZXJ3aXNlLCBDRk4gd2lsbCB0aHJvdyB3aXRoIGBWZW5kb3IgcmVzcG9uc2UgZG9lc24ndCBjb250YWluXG4gICAgICAgICAgLy8gWFhYWCBrZXlgLlxuXG4gICAgICAgICAgQ2VydGlmaWNhdGVBdXRob3JpdHlEYXRhOiBjbHVzdGVyLmNlcnRpZmljYXRlQXV0aG9yaXR5Py5kYXRhID8/ICcnLFxuICAgICAgICAgIENsdXN0ZXJTZWN1cml0eUdyb3VwSWQ6IGNsdXN0ZXIucmVzb3VyY2VzVnBjQ29uZmlnPy5jbHVzdGVyU2VjdXJpdHlHcm91cElkID8/ICcnLFxuICAgICAgICAgIE9wZW5JZENvbm5lY3RJc3N1ZXJVcmw6IGNsdXN0ZXIuaWRlbnRpdHk/Lm9pZGM/Lmlzc3VlciA/PyAnJyxcbiAgICAgICAgICBPcGVuSWRDb25uZWN0SXNzdWVyOiBjbHVzdGVyLmlkZW50aXR5Py5vaWRjPy5pc3N1ZXI/LnN1YnN0cmluZyg4KSA/PyAnJywgLy8gU3RyaXBzIG9mZiBodHRwczovLyBmcm9tIHRoZSBpc3N1ZXIgdXJsXG5cbiAgICAgICAgICAvLyBXZSBjYW4gc2FmZWx5IHJldHVybiB0aGUgZmlyc3QgaXRlbSBmcm9tIGVuY3J5cHRpb24gY29uZmlndXJhdGlvbiBhcnJheSwgYmVjYXVzZSBpdCBoYXMgYSBsaW1pdCBvZiAxIGl0ZW1cbiAgICAgICAgICAvLyBodHRwczovL2RvY3MuYW1hem9uLmNvbS9la3MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlQ2x1c3Rlci5odG1sI0FtYXpvbkVLUy1DcmVhdGVDbHVzdGVyLXJlcXVlc3QtZW5jcnlwdGlvbkNvbmZpZ1xuICAgICAgICAgIEVuY3J5cHRpb25Db25maWdLZXlBcm46IGNsdXN0ZXIuZW5jcnlwdGlvbkNvbmZpZz8uc2hpZnQoKT8ucHJvdmlkZXI/LmtleUFybiA/PyAnJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpc0Vrc1VwZGF0ZUNvbXBsZXRlKGVrc1VwZGF0ZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmxvZyh7IGlzRWtzVXBkYXRlQ29tcGxldGU6IGVrc1VwZGF0ZUlkIH0pO1xuXG4gICAgY29uc3QgZGVzY3JpYmVVcGRhdGVSZXNwb25zZSA9IGF3YWl0IHRoaXMuZWtzLmRlc2NyaWJlVXBkYXRlKHtcbiAgICAgIG5hbWU6IHRoaXMuY2x1c3Rlck5hbWUsXG4gICAgICB1cGRhdGVJZDogZWtzVXBkYXRlSWQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmxvZyh7IGRlc2NyaWJlVXBkYXRlUmVzcG9uc2UgfSk7XG5cbiAgICBpZiAoIWRlc2NyaWJlVXBkYXRlUmVzcG9uc2UudXBkYXRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuYWJsZSB0byBkZXNjcmliZSB1cGRhdGUgd2l0aCBpZCBcIiR7ZWtzVXBkYXRlSWR9XCJgKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRlc2NyaWJlVXBkYXRlUmVzcG9uc2UudXBkYXRlLnN0YXR1cykge1xuICAgICAgY2FzZSAnSW5Qcm9ncmVzcyc6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGNhc2UgJ1N1Y2Nlc3NmdWwnOlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGNhc2UgJ0ZhaWxlZCc6XG4gICAgICBjYXNlICdDYW5jZWxsZWQnOlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNsdXN0ZXIgdXBkYXRlIGlkIFwiJHtla3NVcGRhdGVJZH1cIiBmYWlsZWQgd2l0aCBlcnJvcnM6ICR7SlNPTi5zdHJpbmdpZnkoZGVzY3JpYmVVcGRhdGVSZXNwb25zZS51cGRhdGUuZXJyb3JzKX1gKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5rbm93biBzdGF0dXMgXCIke2Rlc2NyaWJlVXBkYXRlUmVzcG9uc2UudXBkYXRlLnN0YXR1c31cIiBmb3IgdXBkYXRlIGlkIFwiJHtla3NVcGRhdGVJZH1cImApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2VuZXJhdGVDbHVzdGVyTmFtZSgpIHtcbiAgICBjb25zdCBzdWZmaXggPSB0aGlzLnJlcXVlc3RJZC5yZXBsYWNlKC8tL2csICcnKTsgLy8gMzIgY2hhcnNcbiAgICBjb25zdCBvZmZzZXQgPSBNQVhfQ0xVU1RFUl9OQU1FX0xFTiAtIHN1ZmZpeC5sZW5ndGggLSAxO1xuICAgIGNvbnN0IHByZWZpeCA9IHRoaXMubG9naWNhbFJlc291cmNlSWQuc2xpY2UoMCwgb2Zmc2V0ID4gMCA/IG9mZnNldCA6IDApO1xuICAgIHJldHVybiBgJHtwcmVmaXh9LSR7c3VmZml4fWA7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VQcm9wcyhwcm9wczogYW55KTogRUtTLkNyZWF0ZUNsdXN0ZXJDb21tYW5kSW5wdXQge1xuXG4gIGNvbnN0IHBhcnNlZCA9IHByb3BzPy5Db25maWcgPz8ge307XG5cbiAgLy8gdGhpcyBpcyB3ZWlyZCBidXQgdGhlc2UgYm9vbGVhbiBwcm9wZXJ0aWVzIGFyZSBwYXNzZWQgYnkgQ0ZOIGFzIGEgc3RyaW5nLCBhbmQgd2UgbmVlZCB0aGVtIHRvIGJlIGJvb2xlYW5pYyBmb3IgdGhlIFNESy5cbiAgLy8gT3RoZXJ3aXNlIGl0IGZhaWxzIHdpdGggJ1VuZXhwZWN0ZWQgUGFyYW1ldGVyOiBwYXJhbXMucmVzb3VyY2VzVnBjQ29uZmlnLmVuZHBvaW50UHJpdmF0ZUFjY2VzcyBpcyBleHBlY3RlZCB0byBiZSBhIGJvb2xlYW4nXG5cbiAgaWYgKHR5cGVvZiAocGFyc2VkLnJlc291cmNlc1ZwY0NvbmZpZz8uZW5kcG9pbnRQcml2YXRlQWNjZXNzKSA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJzZWQucmVzb3VyY2VzVnBjQ29uZmlnLmVuZHBvaW50UHJpdmF0ZUFjY2VzcyA9IHBhcnNlZC5yZXNvdXJjZXNWcGNDb25maWcuZW5kcG9pbnRQcml2YXRlQWNjZXNzID09PSAndHJ1ZSc7XG4gIH1cblxuICBpZiAodHlwZW9mIChwYXJzZWQucmVzb3VyY2VzVnBjQ29uZmlnPy5lbmRwb2ludFB1YmxpY0FjY2VzcykgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFyc2VkLnJlc291cmNlc1ZwY0NvbmZpZy5lbmRwb2ludFB1YmxpY0FjY2VzcyA9IHBhcnNlZC5yZXNvdXJjZXNWcGNDb25maWcuZW5kcG9pbnRQdWJsaWNBY2Nlc3MgPT09ICd0cnVlJztcbiAgfVxuXG4gIGlmICh0eXBlb2YgKHBhcnNlZC5sb2dnaW5nPy5jbHVzdGVyTG9nZ2luZ1swXS5lbmFibGVkKSA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJzZWQubG9nZ2luZy5jbHVzdGVyTG9nZ2luZ1swXS5lbmFibGVkID0gcGFyc2VkLmxvZ2dpbmcuY2x1c3RlckxvZ2dpbmdbMF0uZW5hYmxlZCA9PT0gJ3RydWUnO1xuICB9XG5cbiAgcmV0dXJuIHBhcnNlZDtcblxufVxuXG5pbnRlcmZhY2UgVXBkYXRlTWFwIHtcbiAgcmVwbGFjZU5hbWU6IGJvb2xlYW47IC8vIG5hbWVcbiAgcmVwbGFjZVZwYzogYm9vbGVhbjsgLy8gcmVzb3VyY2VzVnBjQ29uZmlnLnN1Ym5ldElkcyBhbmQgc2VjdXJpdHlHcm91cElkc1xuICByZXBsYWNlUm9sZTogYm9vbGVhbjsgLy8gcm9sZUFyblxuXG4gIHVwZGF0ZVZlcnNpb246IGJvb2xlYW47IC8vIHZlcnNpb25cbiAgdXBkYXRlTG9nZ2luZzogYm9vbGVhbjsgLy8gbG9nZ2luZ1xuICB1cGRhdGVFbmNyeXB0aW9uOiBib29sZWFuOyAvLyBlbmNyeXB0aW9uIChjYW5ub3QgYmUgdXBkYXRlZClcbiAgdXBkYXRlQWNjZXNzOiBib29sZWFuOyAvLyByZXNvdXJjZXNWcGNDb25maWcuZW5kcG9pbnRQcml2YXRlQWNjZXNzIGFuZCBlbmRwb2ludFB1YmxpY0FjY2Vzc1xufVxuXG5mdW5jdGlvbiBhbmFseXplVXBkYXRlKG9sZFByb3BzOiBQYXJ0aWFsPEVLUy5DcmVhdGVDbHVzdGVyQ29tbWFuZElucHV0PiwgbmV3UHJvcHM6IEVLUy5DcmVhdGVDbHVzdGVyQ29tbWFuZElucHV0KTogVXBkYXRlTWFwIHtcbiAgY29uc29sZS5sb2coJ29sZCBwcm9wczogJywgSlNPTi5zdHJpbmdpZnkob2xkUHJvcHMpKTtcbiAgY29uc29sZS5sb2coJ25ldyBwcm9wczogJywgSlNPTi5zdHJpbmdpZnkobmV3UHJvcHMpKTtcblxuICBjb25zdCBuZXdWcGNQcm9wcyA9IG5ld1Byb3BzLnJlc291cmNlc1ZwY0NvbmZpZyB8fCB7fTtcbiAgY29uc3Qgb2xkVnBjUHJvcHMgPSBvbGRQcm9wcy5yZXNvdXJjZXNWcGNDb25maWcgfHwge307XG5cbiAgY29uc3Qgb2xkUHVibGljQWNjZXNzQ2lkcnMgPSBuZXcgU2V0KG9sZFZwY1Byb3BzLnB1YmxpY0FjY2Vzc0NpZHJzID8/IFtdKTtcbiAgY29uc3QgbmV3UHVibGljQWNjZXNzQ2lkcnMgPSBuZXcgU2V0KG5ld1ZwY1Byb3BzLnB1YmxpY0FjY2Vzc0NpZHJzID8/IFtdKTtcbiAgY29uc3QgbmV3RW5jID0gbmV3UHJvcHMuZW5jcnlwdGlvbkNvbmZpZyB8fCB7fTtcbiAgY29uc3Qgb2xkRW5jID0gb2xkUHJvcHMuZW5jcnlwdGlvbkNvbmZpZyB8fCB7fTtcblxuICByZXR1cm4ge1xuICAgIHJlcGxhY2VOYW1lOiBuZXdQcm9wcy5uYW1lICE9PSBvbGRQcm9wcy5uYW1lLFxuICAgIHJlcGxhY2VWcGM6XG4gICAgICBKU09OLnN0cmluZ2lmeShuZXdWcGNQcm9wcy5zdWJuZXRJZHM/LnNvcnQoKSkgIT09IEpTT04uc3RyaW5naWZ5KG9sZFZwY1Byb3BzLnN1Ym5ldElkcz8uc29ydCgpKSB8fFxuICAgICAgSlNPTi5zdHJpbmdpZnkobmV3VnBjUHJvcHMuc2VjdXJpdHlHcm91cElkcz8uc29ydCgpKSAhPT0gSlNPTi5zdHJpbmdpZnkob2xkVnBjUHJvcHMuc2VjdXJpdHlHcm91cElkcz8uc29ydCgpKSxcbiAgICB1cGRhdGVBY2Nlc3M6XG4gICAgICBuZXdWcGNQcm9wcy5lbmRwb2ludFByaXZhdGVBY2Nlc3MgIT09IG9sZFZwY1Byb3BzLmVuZHBvaW50UHJpdmF0ZUFjY2VzcyB8fFxuICAgICAgbmV3VnBjUHJvcHMuZW5kcG9pbnRQdWJsaWNBY2Nlc3MgIT09IG9sZFZwY1Byb3BzLmVuZHBvaW50UHVibGljQWNjZXNzIHx8XG4gICAgICAhc2V0c0VxdWFsKG5ld1B1YmxpY0FjY2Vzc0NpZHJzLCBvbGRQdWJsaWNBY2Nlc3NDaWRycyksXG4gICAgcmVwbGFjZVJvbGU6IG5ld1Byb3BzLnJvbGVBcm4gIT09IG9sZFByb3BzLnJvbGVBcm4sXG4gICAgdXBkYXRlVmVyc2lvbjogbmV3UHJvcHMudmVyc2lvbiAhPT0gb2xkUHJvcHMudmVyc2lvbixcbiAgICB1cGRhdGVFbmNyeXB0aW9uOiBKU09OLnN0cmluZ2lmeShuZXdFbmMpICE9PSBKU09OLnN0cmluZ2lmeShvbGRFbmMpLFxuICAgIHVwZGF0ZUxvZ2dpbmc6IEpTT04uc3RyaW5naWZ5KG5ld1Byb3BzLmxvZ2dpbmcpICE9PSBKU09OLnN0cmluZ2lmeShvbGRQcm9wcy5sb2dnaW5nKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2V0c0VxdWFsKGZpcnN0OiBTZXQ8c3RyaW5nPiwgc2Vjb25kOiBTZXQ8c3RyaW5nPikge1xuICByZXR1cm4gZmlyc3Quc2l6ZSA9PT0gc2Vjb25kLnNpemUgJiYgWy4uLmZpcnN0XS5ldmVyeSgoZTogc3RyaW5nKSA9PiBzZWNvbmQuaGFzKGUpKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.js deleted file mode 100644 index ed25b1b728f1b..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934/fargate.js +++ /dev/null @@ -1,104 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.FargateProfileResourceHandler = void 0; -// eslint-disable-next-line import/no-extraneous-dependencies -const EKS = require("@aws-sdk/client-eks"); -const common_1 = require("./common"); -const MAX_NAME_LEN = 63; -class FargateProfileResourceHandler extends common_1.ResourceHandler { - async onCreate() { - const fargateProfileName = this.event.ResourceProperties.Config.fargateProfileName ?? this.generateProfileName(); - const createFargateProfile = { - fargateProfileName, - ...this.event.ResourceProperties.Config, - }; - this.log({ createFargateProfile }); - const createFargateProfileResponse = await this.eks.createFargateProfile(createFargateProfile); - this.log({ createFargateProfileResponse }); - if (!createFargateProfileResponse.fargateProfile) { - throw new Error('invalid CreateFargateProfile response'); - } - return { - PhysicalResourceId: createFargateProfileResponse.fargateProfile.fargateProfileName, - Data: { - fargateProfileArn: createFargateProfileResponse.fargateProfile.fargateProfileArn, - }, - }; - } - async onDelete() { - if (!this.physicalResourceId) { - throw new Error('Cannot delete a profile without a physical id'); - } - const deleteFargateProfile = { - clusterName: this.event.ResourceProperties.Config.clusterName, - fargateProfileName: this.physicalResourceId, - }; - this.log({ deleteFargateProfile }); - const deleteFargateProfileResponse = await this.eks.deleteFargateProfile(deleteFargateProfile); - this.log({ deleteFargateProfileResponse }); - return; - } - async onUpdate() { - // all updates require a replacement. as long as name is generated, we are - // good. if name is explicit, update will fail, which is common when trying - // to replace cfn resources with explicit physical names - return this.onCreate(); - } - async isCreateComplete() { - return this.isUpdateComplete(); - } - async isUpdateComplete() { - const status = await this.queryStatus(); - return { - IsComplete: status === 'ACTIVE', - }; - } - async isDeleteComplete() { - const status = await this.queryStatus(); - return { - IsComplete: status === 'NOT_FOUND', - }; - } - /** - * Generates a fargate profile name. - */ - generateProfileName() { - const suffix = this.requestId.replace(/-/g, ''); // 32 chars - const offset = MAX_NAME_LEN - suffix.length - 1; - const prefix = this.logicalResourceId.slice(0, offset > 0 ? offset : 0); - return `${prefix}-${suffix}`; - } - /** - * Queries the Fargate profile's current status and returns the status or - * NOT_FOUND if the profile doesn't exist (i.e. it has been deleted). - */ - async queryStatus() { - if (!this.physicalResourceId) { - throw new Error('Unable to determine status for fargate profile without a resource name'); - } - const describeFargateProfile = { - clusterName: this.event.ResourceProperties.Config.clusterName, - fargateProfileName: this.physicalResourceId, - }; - try { - this.log({ describeFargateProfile }); - const describeFargateProfileResponse = await this.eks.describeFargateProfile(describeFargateProfile); - this.log({ describeFargateProfileResponse }); - const status = describeFargateProfileResponse.fargateProfile?.status; - if (status === 'CREATE_FAILED' || status === 'DELETE_FAILED') { - throw new Error(status); - } - return status; - } - catch (describeFargateProfileError) { - if (describeFargateProfileError instanceof EKS.ResourceNotFoundException) { - this.log('received ResourceNotFoundException, this means the profile has been deleted (or never existed)'); - return 'NOT_FOUND'; - } - this.log({ describeFargateProfileError }); - throw describeFargateProfileError; - } - } -} -exports.FargateProfileResourceHandler = FargateProfileResourceHandler; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFyZ2F0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImZhcmdhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkRBQTZEO0FBQzdELDJDQUEyQztBQUMzQyxxQ0FBMkM7QUFFM0MsTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDO0FBRXhCLE1BQWEsNkJBQThCLFNBQVEsd0JBQWU7SUFDdEQsS0FBSyxDQUFDLFFBQVE7UUFDdEIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUVqSCxNQUFNLG9CQUFvQixHQUF5QztZQUNqRSxrQkFBa0I7WUFDbEIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU07U0FDeEMsQ0FBQztRQUVGLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDbkMsTUFBTSw0QkFBNEIsR0FBRyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUMvRixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsNEJBQTRCLEVBQUUsQ0FBQyxDQUFDO1FBRTNDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxjQUFjLEVBQUU7WUFDaEQsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1NBQzFEO1FBRUQsT0FBTztZQUNMLGtCQUFrQixFQUFFLDRCQUE0QixDQUFDLGNBQWMsQ0FBQyxrQkFBa0I7WUFDbEYsSUFBSSxFQUFFO2dCQUNKLGlCQUFpQixFQUFFLDRCQUE0QixDQUFDLGNBQWMsQ0FBQyxpQkFBaUI7YUFDakY7U0FDRixDQUFDO0tBQ0g7SUFFUyxLQUFLLENBQUMsUUFBUTtRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzVCLE1BQU0sSUFB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WSxHQUFHLENBQUMseUJBQXlCLEVBQUU7Z0JBQ3hFLElBQUksQ0FBQyxHQUFHLENBQUMsZ0dBQWdHLENBQUMsQ0FBQztnQkFDM0csT0FBTyxXQUFXLENBQUM7YUFDcEI7WUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsMkJBQTJCLEVBQUUsQ0FBQyxDQUFDO1lBQzFDLE1BQU0sMkJBQTJCLENBQUM7U0FDbkM7S0FDRjtDQUNGO0FBakhELHNFQWlIQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcbmltcG9ydCAqIGFzIEVLUyBmcm9tICdAYXdzLXNkay9jbGllbnQtZWtzJztcbmltcG9ydCB7IFJlc291cmNlSGFuZGxlciB9IGZyb20gJy4vY29tbW9uJztcblxuY29uc3QgTUFYX05BTUVfTEVOID0gNjM7XG5cbmV4cG9ydCBjbGFzcyBGYXJnYXRlUHJvZmlsZVJlc291cmNlSGFuZGxlciBleHRlbmRzIFJlc291cmNlSGFuZGxlciB7XG4gIHByb3RlY3RlZCBhc3luYyBvbkNyZWF0ZSgpIHtcbiAgICBjb25zdCBmYXJnYXRlUHJvZmlsZU5hbWUgPSB0aGlzLmV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Db25maWcuZmFyZ2F0ZVByb2ZpbGVOYW1lID8/IHRoaXMuZ2VuZXJhdGVQcm9maWxlTmFtZSgpO1xuXG4gICAgY29uc3QgY3JlYXRlRmFyZ2F0ZVByb2ZpbGU6IEVLUy5DcmVhdGVGYXJnYXRlUHJvZmlsZUNvbW1hbmRJbnB1dCA9IHtcbiAgICAgIGZhcmdhdGVQcm9maWxlTmFtZSxcbiAgICAgIC4uLnRoaXMuZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkNvbmZpZyxcbiAgICB9O1xuXG4gICAgdGhpcy5sb2coeyBjcmVhdGVGYXJnYXRlUHJvZmlsZSB9KTtcbiAgICBjb25zdCBjcmVhdGVGYXJnYXRlUHJvZmlsZVJlc3BvbnNlID0gYXdhaXQgdGhpcy5la3MuY3JlYXRlRmFyZ2F0ZVByb2ZpbGUoY3JlYXRlRmFyZ2F0ZVByb2ZpbGUpO1xuICAgIHRoaXMubG9nKHsgY3JlYXRlRmFyZ2F0ZVByb2ZpbGVSZXNwb25zZSB9KTtcblxuICAgIGlmICghY3JlYXRlRmFyZ2F0ZVByb2ZpbGVSZXNwb25zZS5mYXJnYXRlUHJvZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIENyZWF0ZUZhcmdhdGVQcm9maWxlIHJlc3BvbnNlJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogY3JlYXRlRmFyZ2F0ZVByb2ZpbGVSZXNwb25zZS5mYXJnYXRlUHJvZmlsZS5mYXJnYXRlUHJvZmlsZU5hbWUsXG4gICAgICBEYXRhOiB7XG4gICAgICAgIGZhcmdhdGVQcm9maWxlQXJuOiBjcmVhdGVGYXJnYXRlUHJvZmlsZVJlc3BvbnNlLmZhcmdhdGVQcm9maWxlLmZhcmdhdGVQcm9maWxlQXJuLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIG9uRGVsZXRlKCkge1xuICAgIGlmICghdGhpcy5waHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGRlbGV0ZSBhIHByb2ZpbGUgd2l0aG91dCBhIHBoeXNpY2FsIGlkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVsZXRlRmFyZ2F0ZVByb2ZpbGU6IEVLUy5EZWxldGVGYXJnYXRlUHJvZmlsZUNvbW1hbmRJbnB1dCA9IHtcbiAgICAgIGNsdXN0ZXJOYW1lOiB0aGlzLmV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Db25maWcuY2x1c3Rlck5hbWUsXG4gICAgICBmYXJnYXRlUHJvZmlsZU5hbWU6IHRoaXMucGh5c2ljYWxSZXNvdXJjZUlkLFxuICAgIH07XG5cbiAgICB0aGlzLmxvZyh7IGRlbGV0ZUZhcmdhdGVQcm9maWxlIH0pO1xuICAgIGNvbnN0IGRlbGV0ZUZhcmdhdGVQcm9maWxlUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmVrcy5kZWxldGVGYXJnYXRlUHJvZmlsZShkZWxldGVGYXJnYXRlUHJvZmlsZSk7XG4gICAgdGhpcy5sb2coeyBkZWxldGVGYXJnYXRlUHJvZmlsZVJlc3BvbnNlIH0pO1xuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIG9uVXBkYXRlKCkge1xuICAgIC8vIGFsbCB1cGRhdGVzIHJlcXVpcmUgYSByZXBsYWNlbWVudC4gYXMgbG9uZyBhcyBuYW1lIGlzIGdlbmVyYXRlZCwgd2UgYXJlXG4gICAgLy8gZ29vZC4gaWYgbmFtZSBpcyBleHBsaWNpdCwgdXBkYXRlIHdpbGwgZmFpbCwgd2hpY2ggaXMgY29tbW9uIHdoZW4gdHJ5aW5nXG4gICAgLy8gdG8gcmVwbGFjZSBjZm4gcmVzb3VyY2VzIHdpdGggZXhwbGljaXQgcGh5c2ljYWwgbmFtZXNcbiAgICByZXR1cm4gdGhpcy5vbkNyZWF0ZSgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlzQ3JlYXRlQ29tcGxldGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNVcGRhdGVDb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlzVXBkYXRlQ29tcGxldGUoKSB7XG4gICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgdGhpcy5xdWVyeVN0YXR1cygpO1xuICAgIHJldHVybiB7XG4gICAgICBJc0NvbXBsZXRlOiBzdGF0dXMgPT09ICdBQ1RJVkUnLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaXNEZWxldGVDb21wbGV0ZSgpIHtcbiAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCB0aGlzLnF1ZXJ5U3RhdHVzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIElzQ29tcGxldGU6IHN0YXR1cyA9PT0gJ05PVF9GT1VORCcsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYSBmYXJnYXRlIHByb2ZpbGUgbmFtZS5cbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVQcm9maWxlTmFtZSgpIHtcbiAgICBjb25zdCBzdWZmaXggPSB0aGlzLnJlcXVlc3RJZC5yZXBsYWNlKC8tL2csICcnKTsgLy8gMzIgY2hhcnNcbiAgICBjb25zdCBvZmZzZXQgPSBNQVhfTkFNRV9MRU4gLSBzdWZmaXgubGVuZ3RoIC0gMTtcbiAgICBjb25zdCBwcmVmaXggPSB0aGlzLmxvZ2ljYWxSZXNvdXJjZUlkLnNsaWNlKDAsIG9mZnNldCA+IDAgPyBvZmZzZXQgOiAwKTtcbiAgICByZXR1cm4gYCR7cHJlZml4fS0ke3N1ZmZpeH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1ZXJpZXMgdGhlIEZhcmdhdGUgcHJvZmlsZSdzIGN1cnJlbnQgc3RhdHVzIGFuZCByZXR1cm5zIHRoZSBzdGF0dXMgb3JcbiAgICogTk9UX0ZPVU5EIGlmIHRoZSBwcm9maWxlIGRvZXNuJ3QgZXhpc3QgKGkuZS4gaXQgaGFzIGJlZW4gZGVsZXRlZCkuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHF1ZXJ5U3RhdHVzKCk6IFByb21pc2U8RUtTLkZhcmdhdGVQcm9maWxlU3RhdHVzIHwgJ05PVF9GT1VORCcgfCBzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoIXRoaXMucGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZXRlcm1pbmUgc3RhdHVzIGZvciBmYXJnYXRlIHByb2ZpbGUgd2l0aG91dCBhIHJlc291cmNlIG5hbWUnKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXNjcmliZUZhcmdhdGVQcm9maWxlOiBFS1MuRGVzY3JpYmVGYXJnYXRlUHJvZmlsZUNvbW1hbmRJbnB1dCA9IHtcbiAgICAgIGNsdXN0ZXJOYW1lOiB0aGlzLmV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Db25maWcuY2x1c3Rlck5hbWUsXG4gICAgICBmYXJnYXRlUHJvZmlsZU5hbWU6IHRoaXMucGh5c2ljYWxSZXNvdXJjZUlkLFxuICAgIH07XG5cbiAgICB0cnkge1xuXG4gICAgICB0aGlzLmxvZyh7IGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGUgfSk7XG4gICAgICBjb25zdCBkZXNjcmliZUZhcmdhdGVQcm9maWxlUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmVrcy5kZXNjcmliZUZhcmdhdGVQcm9maWxlKGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGUpO1xuICAgICAgdGhpcy5sb2coeyBkZXNjcmliZUZhcmdhdGVQcm9maWxlUmVzcG9uc2UgfSk7XG4gICAgICBjb25zdCBzdGF0dXMgPSBkZXNjcmliZUZhcmdhdGVQcm9maWxlUmVzcG9uc2UuZmFyZ2F0ZVByb2ZpbGU/LnN0YXR1cztcblxuICAgICAgaWYgKHN0YXR1cyA9PT0gJ0NSRUFURV9GQUlMRUQnIHx8IHN0YXR1cyA9PT0gJ0RFTEVURV9GQUlMRUQnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihzdGF0dXMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3RhdHVzO1xuICAgIH0gY2F0Y2ggKGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGVFcnJvcjogYW55KSB7XG4gICAgICBpZiAoZGVzY3JpYmVGYXJnYXRlUHJvZmlsZUVycm9yIGluc3RhbmNlb2YgRUtTLlJlc291cmNlTm90Rm91bmRFeGNlcHRpb24pIHtcbiAgICAgICAgdGhpcy5sb2coJ3JlY2VpdmVkIFJlc291cmNlTm90Rm91bmRFeGNlcHRpb24sIHRoaXMgbWVhbnMgdGhlIHByb2ZpbGUgaGFzIGJlZW4gZGVsZXRlZCAob3IgbmV2ZXIgZXhpc3RlZCknKTtcbiAgICAgICAgcmV0dXJuICdOT1RfRk9VTkQnO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZyh7IGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGVFcnJvciB9KTtcbiAgICAgIHRocm93IGRlc2NyaWJlRmFyZ2F0ZVByb2ZpbGVFcnJvcjtcbiAgICB9XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/cfn-response.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/cfn-response.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/cfn-response.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/cfn-response.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/consts.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/consts.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/consts.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/consts.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/framework.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/framework.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/framework.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/framework.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/outbound.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/outbound.js new file mode 100644 index 0000000000000..8ade7c5c96c6e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/outbound.js @@ -0,0 +1,75 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.httpRequest = exports.invokeFunction = exports.startExecution = void 0; +/* istanbul ignore file */ +const https = require("https"); +// eslint-disable-next-line import/no-extraneous-dependencies +const client_lambda_1 = require("@aws-sdk/client-lambda"); +// eslint-disable-next-line import/no-extraneous-dependencies +const client_sfn_1 = require("@aws-sdk/client-sfn"); +// eslint-disable-next-line import/no-extraneous-dependencies +const FRAMEWORK_HANDLER_TIMEOUT = 900000; // 15 minutes +// In order to honor the overall maximum timeout set for the target process, +// the default 2 minutes from AWS SDK has to be overriden: +// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html#httpOptions-property +const awsSdkConfig = { + httpOptions: { timeout: FRAMEWORK_HANDLER_TIMEOUT }, +}; +async function defaultHttpRequest(options, responseBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, resolve); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +let sfn; +let lambda; +async function defaultStartExecution(req) { + if (!sfn) { + sfn = new client_sfn_1.SFN(awsSdkConfig); + } + return sfn.startExecution(req); +} +async function defaultInvokeFunction(req) { + if (!lambda) { + lambda = new client_lambda_1.Lambda(awsSdkConfig); + } + try { + /** + * Try an initial invoke. + * + * When you try to invoke a function that is inactive, the invocation fails and Lambda sets + * the function to pending state until the function resources are recreated. + * If Lambda fails to recreate the resources, the function is set to the inactive state. + * + * We're using invoke first because `waitFor` doesn't trigger an inactive function to do anything, + * it just runs `getFunction` and checks the state. + */ + return await lambda.invoke(req); + } + catch { + /** + * The status of the Lambda function is checked every second for up to 300 seconds. + * Exits the loop on 'Active' state and throws an error on 'Inactive' or 'Failed'. + * + * And now we wait. + */ + await (0, client_lambda_1.waitUntilFunctionActiveV2)({ + client: lambda, + maxWaitTime: 300, + }, { + FunctionName: req.FunctionName, + }); + return await lambda.invoke(req); + } +} +exports.startExecution = defaultStartExecution; +exports.invokeFunction = defaultInvokeFunction; +exports.httpRequest = defaultHttpRequest; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0Ym91bmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJvdXRib3VuZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwwQkFBMEI7QUFDMUIsK0JBQStCO0FBQy9CLDZEQUE2RDtBQUM3RCwwREFBbUg7QUFDbkgsNkRBQTZEO0FBQzdELG9EQUFxRjtBQUNyRiw2REFBNkQ7QUFFN0QsTUFBTSx5QkFBeUIsR0FBRyxNQUFNLENBQUMsQ0FBQyxhQUFhO0FBRXZELDRFQUE0RTtBQUM1RSwwREFBMEQ7QUFDMUQsMkZBQTJGO0FBQzNGLE1BQU0sWUFBWSxHQUFHO0lBQ25CLFdBQVcsRUFBRSxFQUFFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRTtDQUNwRCxDQUFDO0FBRUYsS0FBSyxVQUFVLGtCQUFrQixDQUFDLE9BQTZCLEVBQUUsWUFBb0I7SUFDbkYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxJQUFJO1lBQ0YsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDaEQsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDZjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ1g7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxJQUFJLEdBQVEsQ0FBQztBQUNiLElBQUksTUFBYyxDQUFDO0FBRW5CLEtBQUssVUFBVSxxQkFBcUIsQ0FBQyxHQUF3QjtJQUMzRCxJQUFJLENBQUMsR0FBRyxFQUFFO1FBQ1IsR0FBRyxHQUFHLElBQUksZ0JBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztLQUM3QjtJQUVELE9BQU8sR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQyxDQUFDO0FBRUQsS0FBSyxVQUFVLHFCQUFxQixDQUFDLEdBQXVCO0lBQzFELElBQUksQ0FBQyxNQUFNLEVBQUU7UUFDWCxNQUFNLEdBQUcsSUFBSSxzQkFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0tBQ25DO0lBRUQsSUFBSTtRQUNGOzs7Ozs7Ozs7V0FTRztRQUNILE9BQU8sTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0tBQ2pDO0lBQUMsTUFBTTtRQUNOOzs7OztXQUtHO1FBQ0gsTUFBTSxJQUFBLHlDQUF5QixFQUFDO1lBQzlCLE1BQU0sRUFBRSxNQUFNO1lBQ2QsV0FBVyxFQUFFLEdBQUc7U0FDakIsRUFBRTtZQUNELFlBQVksRUFBRSxHQUFHLENBQUMsWUFBWTtTQUMvQixDQUFDLENBQUM7UUFDSCxPQUFPLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztLQUNqQztBQUNILENBQUM7QUFFVSxRQUFBLGNBQWMsR0FBRyxxQkFBcUIsQ0FBQztBQUN2QyxRQUFBLGNBQWMsR0FBRyxxQkFBcUIsQ0FBQztBQUN2QyxRQUFBLFdBQVcsR0FBRyxrQkFBa0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGlzdGFuYnVsIGlnbm9yZSBmaWxlICovXG5pbXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBMYW1iZGEsIHdhaXRVbnRpbEZ1bmN0aW9uQWN0aXZlVjIsIEludm9jYXRpb25SZXNwb25zZSwgSW52b2tlQ29tbWFuZElucHV0IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWxhbWJkYSc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBTRk4sIFN0YXJ0RXhlY3V0aW9uSW5wdXQsIFN0YXJ0RXhlY3V0aW9uT3V0cHV0IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNmbic7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5cbmNvbnN0IEZSQU1FV09SS19IQU5ETEVSX1RJTUVPVVQgPSA5MDAwMDA7IC8vIDE1IG1pbnV0ZXNcblxuLy8gSW4gb3JkZXIgdG8gaG9ub3IgdGhlIG92ZXJhbGwgbWF4aW11bSB0aW1lb3V0IHNldCBmb3IgdGhlIHRhcmdldCBwcm9jZXNzLFxuLy8gdGhlIGRlZmF1bHQgMiBtaW51dGVzIGZyb20gQVdTIFNESyBoYXMgdG8gYmUgb3ZlcnJpZGVuOlxuLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0phdmFTY3JpcHRTREsvbGF0ZXN0L0FXUy9Db25maWcuaHRtbCNodHRwT3B0aW9ucy1wcm9wZXJ0eVxuY29uc3QgYXdzU2RrQ29uZmlnID0ge1xuICBodHRwT3B0aW9uczogeyB0aW1lb3V0OiBGUkFNRVdPUktfSEFORExFUl9USU1FT1VUIH0sXG59O1xuXG5hc3luYyBmdW5jdGlvbiBkZWZhdWx0SHR0cFJlcXVlc3Qob3B0aW9uczogaHR0cHMuUmVxdWVzdE9wdGlvbnMsIHJlc3BvbnNlQm9keTogc3RyaW5nKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KG9wdGlvbnMsIHJlc29sdmUpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxubGV0IHNmbjogU0ZOO1xubGV0IGxhbWJkYTogTGFtYmRhO1xuXG5hc3luYyBmdW5jdGlvbiBkZWZhdWx0U3RhcnRFeGVjdXRpb24ocmVxOiBTdGFydEV4ZWN1dGlvbklucHV0KTogUHJvbWlzZTxTdGFydEV4ZWN1dGlvbk91dHB1dD4ge1xuICBpZiAoIXNmbikge1xuICAgIHNmbiA9IG5ldyBTRk4oYXdzU2RrQ29uZmlnKTtcbiAgfVxuXG4gIHJldHVybiBzZm4uc3RhcnRFeGVjdXRpb24ocmVxKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdEludm9rZUZ1bmN0aW9uKHJlcTogSW52b2tlQ29tbWFuZElucHV0KTogUHJvbWlzZTxJbnZvY2F0aW9uUmVzcG9uc2U+IHtcbiAgaWYgKCFsYW1iZGEpIHtcbiAgICBsYW1iZGEgPSBuZXcgTGFtYmRhKGF3c1Nka0NvbmZpZyk7XG4gIH1cblxuICB0cnkge1xuICAgIC8qKlxuICAgICAqIFRyeSBhbiBpbml0aWFsIGludm9rZS5cbiAgICAgKlxuICAgICAqIFdoZW4geW91IHRyeSB0byBpbnZva2UgYSBmdW5jdGlvbiB0aGF0IGlzIGluYWN0aXZlLCB0aGUgaW52b2NhdGlvbiBmYWlscyBhbmQgTGFtYmRhIHNldHNcbiAgICAgKiB0aGUgZnVuY3Rpb24gdG8gcGVuZGluZyBzdGF0ZSB1bnRpbCB0aGUgZnVuY3Rpb24gcmVzb3VyY2VzIGFyZSByZWNyZWF0ZWQuXG4gICAgICogSWYgTGFtYmRhIGZhaWxzIHRvIHJlY3JlYXRlIHRoZSByZXNvdXJjZXMsIHRoZSBmdW5jdGlvbiBpcyBzZXQgdG8gdGhlIGluYWN0aXZlIHN0YXRlLlxuICAgICAqXG4gICAgICogV2UncmUgdXNpbmcgaW52b2tlIGZpcnN0IGJlY2F1c2UgYHdhaXRGb3JgIGRvZXNuJ3QgdHJpZ2dlciBhbiBpbmFjdGl2ZSBmdW5jdGlvbiB0byBkbyBhbnl0aGluZyxcbiAgICAgKiBpdCBqdXN0IHJ1bnMgYGdldEZ1bmN0aW9uYCBhbmQgY2hlY2tzIHRoZSBzdGF0ZS5cbiAgICAgKi9cbiAgICByZXR1cm4gYXdhaXQgbGFtYmRhLmludm9rZShyZXEpO1xuICB9IGNhdGNoIHtcbiAgICAvKipcbiAgICAgKiBUaGUgc3RhdHVzIG9mIHRoZSBMYW1iZGEgZnVuY3Rpb24gaXMgY2hlY2tlZCBldmVyeSBzZWNvbmQgZm9yIHVwIHRvIDMwMCBzZWNvbmRzLlxuICAgICAqIEV4aXRzIHRoZSBsb29wIG9uICdBY3RpdmUnIHN0YXRlIGFuZCB0aHJvd3MgYW4gZXJyb3Igb24gJ0luYWN0aXZlJyBvciAnRmFpbGVkJy5cbiAgICAgKlxuICAgICAqIEFuZCBub3cgd2Ugd2FpdC5cbiAgICAgKi9cbiAgICBhd2FpdCB3YWl0VW50aWxGdW5jdGlvbkFjdGl2ZVYyKHtcbiAgICAgIGNsaWVudDogbGFtYmRhLFxuICAgICAgbWF4V2FpdFRpbWU6IDMwMCxcbiAgICB9LCB7XG4gICAgICBGdW5jdGlvbk5hbWU6IHJlcS5GdW5jdGlvbk5hbWUsXG4gICAgfSk7XG4gICAgcmV0dXJuIGF3YWl0IGxhbWJkYS5pbnZva2UocmVxKTtcbiAgfVxufVxuXG5leHBvcnQgbGV0IHN0YXJ0RXhlY3V0aW9uID0gZGVmYXVsdFN0YXJ0RXhlY3V0aW9uO1xuZXhwb3J0IGxldCBpbnZva2VGdW5jdGlvbiA9IGRlZmF1bHRJbnZva2VGdW5jdGlvbjtcbmV4cG9ydCBsZXQgaHR0cFJlcXVlc3QgPSBkZWZhdWx0SHR0cFJlcXVlc3Q7XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/util.js b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/util.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db/util.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef/util.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.assets.json index d81d268dd9c91..d6c203cde1cc1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.assets.json @@ -29,43 +29,43 @@ } } }, - "968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934": { + "0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49": { "source": { - "path": "asset.968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934", + "path": "asset.0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49", "packaging": "zip" }, "destinations": { "current_account-us-east-1": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", - "objectKey": "968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934.zip", + "objectKey": "0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49.zip", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" } } }, - "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db": { + "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef": { "source": { - "path": "asset.81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db", + "path": "asset.d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef", "packaging": "zip" }, "destinations": { "current_account-us-east-1": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", - "objectKey": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip", + "objectKey": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" } } }, - "7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779": { + "0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3": { "source": { - "path": "asset.7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779", + "path": "asset.0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3", "packaging": "zip" }, "destinations": { "current_account-us-east-1": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", - "objectKey": "7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779.zip", + "objectKey": "0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3.zip", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" } @@ -127,7 +127,7 @@ } } }, - "ce59f1e5d36e583edfcdecf9caf7d8b3c0abe7ee6fd28a0c69854ea0a67c66b0": { + "589d6efd6364827e3aa6473cecef5ff51c2428794c20f9b36bf4cb3db32020d2": { "source": { "path": "awscdkeksclustertestawscdkawseksClusterResourceProvider5F388D1A.nested.template.json", "packaging": "file" @@ -135,13 +135,13 @@ "destinations": { "current_account-us-east-1": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", - "objectKey": "ce59f1e5d36e583edfcdecf9caf7d8b3c0abe7ee6fd28a0c69854ea0a67c66b0.json", + "objectKey": "589d6efd6364827e3aa6473cecef5ff51c2428794c20f9b36bf4cb3db32020d2.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" } } }, - "039c7b09e181385a0fc36563c9c63f2b2437e3a618033d00bb31a556a4fd47aa": { + "d5c3999a77f79f8d8503a926c732fbd124d326cee9cb2914f9dc82ac7d1293a1": { "source": { "path": "awscdkeksclustertestawscdkawseksKubectlProviderE05943BF.nested.template.json", "packaging": "file" @@ -149,13 +149,13 @@ "destinations": { "current_account-us-east-1": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", - "objectKey": "039c7b09e181385a0fc36563c9c63f2b2437e3a618033d00bb31a556a4fd47aa.json", + "objectKey": "d5c3999a77f79f8d8503a926c732fbd124d326cee9cb2914f9dc82ac7d1293a1.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" } } }, - "051427e862ae2aa3e816f8d026f6246d7e57fb86b9b033d6e2bf64be99fab9e8": { + "36279b628b72020624e83f28ba846d3e055efe80c13e6747787de74a2e5265c3": { "source": { "path": "aws-cdk-eks-cluster-test.template.json", "packaging": "file" @@ -163,7 +163,7 @@ "destinations": { "current_account-us-east-1": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", - "objectKey": "051427e862ae2aa3e816f8d026f6246d7e57fb86b9b033d6e2bf64be99fab9e8.json", + "objectKey": "36279b628b72020624e83f28ba846d3e055efe80c13e6747787de74a2e5265c3.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.template.json index 48cbdeacf1e9f..597312c101852 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/aws-cdk-eks-cluster-test.template.json @@ -3402,7 +3402,7 @@ }, "ScalingConfig": { "DesiredSize": 1, - "MaxSize": 1, + "MaxSize": 4, "MinSize": 1 }, "Subnets": [ @@ -3412,7 +3412,10 @@ { "Ref": "VpcPrivateSubnet2Subnet3788AAA1" } - ] + ], + "UpdateConfig": { + "MaxUnavailable": 3 + } } }, "ClusterNodegroupextrangspotNodeGroupRoleB53B4857": { @@ -3589,7 +3592,10 @@ { "Ref": "VpcPrivateSubnet2Subnet3788AAA1" } - ] + ], + "UpdateConfig": { + "MaxUnavailablePercentage": 33 + } } }, "ClusterNodegroupextrangarm3NodeGroupRole3A6AB3EC": { @@ -4178,7 +4184,7 @@ { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "/ce59f1e5d36e583edfcdecf9caf7d8b3c0abe7ee6fd28a0c69854ea0a67c66b0.json" + "/589d6efd6364827e3aa6473cecef5ff51c2428794c20f9b36bf4cb3db32020d2.json" ] ] } @@ -4224,7 +4230,7 @@ { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "/039c7b09e181385a0fc36563c9c63f2b2437e3a618033d00bb31a556a4fd47aa.json" + "/d5c3999a77f79f8d8503a926c732fbd124d326cee9cb2914f9dc82ac7d1293a1.json" ] ] } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksClusterResourceProvider5F388D1A.nested.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksClusterResourceProvider5F388D1A.nested.template.json index 9661a90af5e04..7d54fd310d586 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksClusterResourceProvider5F388D1A.nested.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksClusterResourceProvider5F388D1A.nested.template.json @@ -50,7 +50,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934.zip" + "S3Key": "0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49.zip" }, "Description": "onEvent handler for EKS cluster resource provider", "Environment": { @@ -115,7 +115,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934.zip" + "S3Key": "0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49.zip" }, "Description": "isComplete handler for EKS cluster resource provider", "Environment": { @@ -249,7 +249,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "S3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.ClusterResourceProvider/Provider)", "Environment": { @@ -386,7 +386,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "S3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "Description": "AWS CDK resource provider framework - isComplete (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.ClusterResourceProvider/Provider)", "Environment": { @@ -520,7 +520,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "S3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "Description": "AWS CDK resource provider framework - onTimeout (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.ClusterResourceProvider/Provider)", "Environment": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksKubectlProviderE05943BF.nested.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksKubectlProviderE05943BF.nested.template.json index 710560a0bb9c4..d1baac7f975a9 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksKubectlProviderE05943BF.nested.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/awscdkeksclustertestawscdkawseksKubectlProviderE05943BF.nested.template.json @@ -7,7 +7,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779.zip" + "S3Key": "0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3.zip" }, "Description": "onEvent handler for EKS kubectl resource provider", "Handler": "index.handler", @@ -146,7 +146,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "S3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "Description": "AWS CDK resource provider framework - onEvent (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.KubectlProvider/Provider)", "Environment": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/manifest.json index 6f430a73ad71a..a61b8bbcdffd9 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/manifest.json @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/us-east-1", "properties": { "templateFile": "aws-cdk-eks-cluster-test.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-us-east-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1/051427e862ae2aa3e816f8d026f6246d7e57fb86b9b033d6e2bf64be99fab9e8.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1/36279b628b72020624e83f28ba846d3e055efe80c13e6747787de74a2e5265c3.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -1129,6 +1130,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "awscdkeksclusterDefaultTestDeployAssertFBF4B356.template.json", + "terminationProtection": false, "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}", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/tree.json index 751a61563d636..c76b1312bc602 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.js.snapshot/tree.json @@ -4461,7 +4461,7 @@ }, "scalingConfig": { "desiredSize": 1, - "maxSize": 1, + "maxSize": 4, "minSize": 1 }, "subnets": [ @@ -4471,7 +4471,10 @@ { "Ref": "VpcPrivateSubnet2Subnet3788AAA1" } - ] + ], + "updateConfig": { + "maxUnavailable": 3 + } } }, "constructInfo": { @@ -4736,7 +4739,10 @@ { "Ref": "VpcPrivateSubnet2Subnet3788AAA1" } - ] + ], + "updateConfig": { + "maxUnavailablePercentage": 33 + } } }, "constructInfo": { @@ -5535,7 +5541,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "s3Key": "968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934.zip" + "s3Key": "0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49.zip" }, "description": "onEvent handler for EKS cluster resource provider", "environment": { @@ -5667,7 +5673,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "s3Key": "968f385a33c07678c81a74fa6d36baf4a5efe934fe6d178d5585ecaafe89b934.zip" + "s3Key": "0f3b39df2b09547f11665065c82a6bb6324e27671974665b429e4ea692645b49.zip" }, "description": "isComplete handler for EKS cluster resource provider", "environment": { @@ -5890,7 +5896,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "s3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "s3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "description": "AWS CDK resource provider framework - onEvent (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.ClusterResourceProvider/Provider)", "environment": { @@ -6111,7 +6117,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "s3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "s3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "description": "AWS CDK resource provider framework - isComplete (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.ClusterResourceProvider/Provider)", "environment": { @@ -6329,7 +6335,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "s3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "s3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "description": "AWS CDK resource provider framework - onTimeout (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.ClusterResourceProvider/Provider)", "environment": { @@ -6569,7 +6575,7 @@ { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "/ce59f1e5d36e583edfcdecf9caf7d8b3c0abe7ee6fd28a0c69854ea0a67c66b0.json" + "/589d6efd6364827e3aa6473cecef5ff51c2428794c20f9b36bf4cb3db32020d2.json" ] ] } @@ -6630,7 +6636,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "s3Key": "7ee709fdaf72d4a95dabe6f431ed4176b1dbcb78127986bf956f0ed8cad04779.zip" + "s3Key": "0f19e51d1e47290d7a33e0b67405e4722942dee4b92b9d29425fccf0d99017c3.zip" }, "description": "onEvent handler for EKS kubectl resource provider", "handler": "index.handler", @@ -6921,7 +6927,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "s3Key": "81328426dba578d9ff57b0b54146bc81395a478131b0b61e40236fcc8395c2db.zip" + "s3Key": "d002370061965c69bc4caf15dddb5eccc9df318933ade6e4fa57cddb81c5abef.zip" }, "description": "AWS CDK resource provider framework - onEvent (aws-cdk-eks-cluster-test/@aws-cdk--aws-eks.KubectlProvider/Provider)", "environment": { @@ -7076,7 +7082,7 @@ { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "/039c7b09e181385a0fc36563c9c63f2b2437e3a618033d00bb31a556a4fd47aa.json" + "/d5c3999a77f79f8d8503a926c732fbd124d326cee9cb2914f9dc82ac7d1293a1.json" ] ] } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.ts index 161e066a26819..79550cb0917d6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-eks/test/integ.eks-cluster.ts @@ -211,6 +211,8 @@ class EksClusterStack extends Stack { this.cluster.addNodegroupCapacity('extra-ng', { instanceTypes: [new ec2.InstanceType('t3.small')], minSize: 1, + maxSize: 4, + maxUnavailable: 3, // reusing the default capacity nodegroup instance role when available nodeRole: this.cluster.defaultCapacity ? this.cluster.defaultCapacity.role : undefined, }); @@ -260,6 +262,7 @@ class EksClusterStack extends Stack { this.cluster.addNodegroupCapacity('extra-ng-arm', { instanceTypes: [new ec2.InstanceType('m6g.medium')], minSize: 1, + maxUnavailablePercentage: 33, // reusing the default capacity nodegroup instance role when available nodeRole: this.cluster.defaultCapacity ? this.cluster.defaultCapacity.role : undefined, }); diff --git a/packages/aws-cdk-lib/aws-eks/README.md b/packages/aws-cdk-lib/aws-eks/README.md index a46ceb88dfb1a..4cbad3b2c12ce 100644 --- a/packages/aws-cdk-lib/aws-eks/README.md +++ b/packages/aws-cdk-lib/aws-eks/README.md @@ -206,6 +206,27 @@ cluster.addNodegroupCapacity('custom-node-group', { }); ``` +To define the maximum number of instances which can be simultaneously replaced in a node group during a version update you can set `maxUnavailable` or `maxUnavailablePercentage` options. + +> For more details visit [Updating a managed node group](https://docs.aws.amazon.com/eks/latest/userguide/update-managed-node-group.html) + +```ts +declare const cluster: eks.Cluster; +cluster.addNodegroupCapacity('custom-node-group', { + instanceTypes: [new ec2.InstanceType('m5.large')], + maxSize: 5, + maxUnavailable: 2, +}); +``` + +```ts +declare const cluster: eks.Cluster; +cluster.addNodegroupCapacity('custom-node-group', { + instanceTypes: [new ec2.InstanceType('m5.large')], + maxUnavailablePercentage: 33, +}); +``` + #### Node Groups with IPv6 Support Node groups are available with IPv6 configured networks. For custom roles assigned to node groups additional permissions are necessary in order for pods to obtain an IPv6 address. The default node role will include these permissions. diff --git a/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts b/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts index f328e3a661661..b59b941318323 100644 --- a/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts +++ b/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts @@ -282,6 +282,28 @@ export interface NodegroupOptions { * @default - ON_DEMAND */ readonly capacityType?: CapacityType; + + /** + * The maximum number of nodes unavailable at once during a version update. + * Nodes will be updated in parallel. The maximum number is 100. + * + * This value or `maxUnavailablePercentage` is required to have a value for custom update configurations to be applied. + * + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-nodegroup-updateconfig.html#cfn-eks-nodegroup-updateconfig-maxunavailable + * @default 1 + */ + readonly maxUnavailable?: number; + + /** + * The maximum percentage of nodes unavailable during a version update. + * This percentage of nodes will be updated in parallel, up to 100 nodes at once. + * + * This value or `maxUnavailable` is required to have a value for custom update configurations to be applied. + * + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-nodegroup-updateconfig.html#cfn-eks-nodegroup-updateconfig-maxunavailablepercentage + * @default undefined - node groups will update instances one at a time + */ + readonly maxUnavailablePercentage?: number; } /** @@ -425,6 +447,8 @@ export class Nodegroup extends Resource implements INodegroup { this.role = props.nodeRole; } + this.validateUpdateConfig(props.maxUnavailable, props.maxUnavailablePercentage); + const resource = new CfnNodegroup(this, 'Resource', { clusterName: this.cluster.clusterName, nodegroupName: props.nodegroupName, @@ -463,6 +487,10 @@ export class Nodegroup extends Resource implements INodegroup { minSize: this.minSize, }, tags: props.tags, + updateConfig: props.maxUnavailable || props.maxUnavailablePercentage ? { + maxUnavailable: props.maxUnavailable, + maxUnavailablePercentage: props.maxUnavailablePercentage, + } : undefined, }); // managed nodegroups update the `aws-auth` on creation, but we still need to track @@ -491,6 +519,24 @@ export class Nodegroup extends Resource implements INodegroup { }); this.nodegroupName = this.getResourceNameAttribute(resource.ref); } + + private validateUpdateConfig(maxUnavailable?: number, maxUnavailablePercentage?: number) { + if (!maxUnavailable && !maxUnavailablePercentage) return; + if (maxUnavailable && maxUnavailablePercentage) { + throw new Error('maxUnavailable and maxUnavailablePercentage are not allowed to be defined together'); + } + if (maxUnavailablePercentage && (maxUnavailablePercentage < 1 || maxUnavailablePercentage > 100)) { + throw new Error(`maxUnavailablePercentage must be between 1 and 100, got ${maxUnavailablePercentage}`); + } + if (maxUnavailable) { + if (maxUnavailable > this.maxSize) { + throw new Error(`maxUnavailable must be lower than maxSize (${this.maxSize}), got ${maxUnavailable}`); + } + if (maxUnavailable < 1 || maxUnavailable > 100) { + throw new Error(`maxUnavailable must be between 1 and 100, got ${maxUnavailable}`); + } + } + } } /** diff --git a/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts b/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts index 4f154ea5dc2ca..585c682b60958 100644 --- a/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts +++ b/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts @@ -1425,4 +1425,123 @@ describe('node group', () => { }, })).toThrow(/diskSize must be specified within the launch template/); }); + + test('create updateConfig for maxUnavailable correctly', () => { + // GIVEN + const { stack, vpc } = testFixture(); + + // WHEN + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + new eks.Nodegroup(stack, 'Nodegroup', { + cluster, + maxUnavailable: 3, + maxSize: 5, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EKS::Nodegroup', { + UpdateConfig: { + MaxUnavailable: 3, + }, + }); + }); + + test('create updateConfig for maxUnavailablePercentage correctly', () => { + // GIVEN + const { stack, vpc } = testFixture(); + + // WHEN + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + new eks.Nodegroup(stack, 'Nodegroup', { + cluster, + maxUnavailablePercentage: 33, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EKS::Nodegroup', { + UpdateConfig: { + MaxUnavailablePercentage: 33, + }, + }); + }); + + test('throws when maxUnavailable and maxUnavailablePercentage are set', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { maxUnavailable: 3, maxUnavailablePercentage: 2 })).toThrow(/maxUnavailable and maxUnavailablePercentage are not allowed to be defined together/); + }); + + test('throws when maxUnavailable is greater than maxSize', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { maxUnavailable: 5, maxSize: 4 })).toThrow(/maxUnavailable must be lower than maxSize/); + }); + + test('throws when maxUnavailable is less than 1', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { maxUnavailable: -3, maxSize: 10 })).toThrow(/maxUnavailable must be between 1 and 100/); + }); + + test('throws when maxUnavailable is greater than 100', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { maxUnavailable: 101, maxSize: 200 })).toThrow(/maxUnavailable must be between 1 and 100/); + }); + + test('throws when maxUnavailablePercentage is less than 1', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { maxUnavailablePercentage: -3, maxSize: 10 })).toThrow(/maxUnavailablePercentage must be between 1 and 100/); + }); + + test('throws when maxUnavailablePercentage is greater than 100', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { maxUnavailablePercentage: 101 })).toThrow(/maxUnavailablePercentage must be between 1 and 100/); + }); }); From 1310a26dcce712796264871453a58102d5f27931 Mon Sep 17 00:00:00 2001 From: Mitchell Valine Date: Tue, 31 Oct 2023 13:46:25 -0700 Subject: [PATCH 06/14] chore: add more details to CONTRIBUTING (#27703) Add more details to our contributing guidelines about what we look for in contributions to aws/aws-cdk and what may be better suited to third party packages. If there are other details and guidelines that we should enumerate up front we should add those here as well. Added a fancy little diagram cause they are fun and I'm the best. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- CONTRIBUTING.md | 46 +++++++++++++++++++++++++++++++++++++ docs/contribution_flow.png | Bin 0 -> 174069 bytes 2 files changed, 46 insertions(+) create mode 100644 docs/contribution_flow.png diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb80a883d68e3..d4a7504637c87 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,6 +13,7 @@ Any code you submit will be released under that license. This document describes how to set up a development environment and submit your changes. Please let us know if it's not up-to-date (even better, submit a PR with your corrections ;-)). +- [Where To Contribute](#where-to-contribute) - [Getting Started](#getting-started) - [Local setup](#setup) - [Dev Container](#dev-container) @@ -47,6 +48,51 @@ let us know if it's not up-to-date (even better, submit a PR with your correcti - [Badges (Pilot Program)](#badges-pilot-program) - [Related Repositories](#related-repositories) +## Contribution Workflow Diagram +![A workflow diagram for contributing code to the aws-cdk ecosytem](./docs/contribution_flow.png) + +## Where to Contribute + +Contributions are accepted through a number of channels, including direct pull requests to the aws/aws-cdk repository. However, this may not be the ideal method depending on the circumstances of your proposed additions or changes. The aws-cdk team has limited availability for reviews, which means that sometimes, if making your change available for immediate use by yourself is your goal, it may be better to publish it in your own package or otherwise bypass the CDK team's review and feedback cycle. That being said, if your contribution contains changes that are desired by a large number of cdk users, we absolutely want to make sure those changes are included in the aws-cdk core packages. + +Here are some things we look at when evaluating a contribution: + +1. Signal - Is there a github issue, or possibly multiple related ones, that the contribution addresses. Do the issues have a lot of engagement, such as comments, +1 reactions, etc that indicate that many users are affected by it? +1. Size - Is the contribution limited to a relatively self-contained surface area? Is it broken up into the smallest possible unit of functionality that makes sense? +1. Priority - Does the contribution address an issue in, or add a new feature of, a service that has a high priority for coverage? These are generally core services most commonly used on AWS such as IAM, EC2, Lambda, and ECS. +1. Quality - Does the contribution take into account all of the guidance provided in our documentation regarding design patterns, test coverage, and best practices as it relates to code within the aws-cdk repository? Does it also make an effort to follow patterns commonly used within the aws-cdk repository and not deviate unecessarily from these conventions? +1. Breaking Changes - Does the contribution introduce any risk for breaking existing users applications? Specifically, does it require any code changes or can it trigger any resource replacement in cloudformation that would result in downtime? + +### Demonstrating Value + +When you create a pull-request, make sure to include justification related to all of the relevant criteria within the PR description in order to make it clear to reviewers why your contribution should be accepted. Specifically, provide justification for why this is functionality that should live within the core aws-cdk packages and be maintained by the cdk team. Are there technical reasons why this functionality could not be vended separately etc? If we are not convinced that the functionality should be part of the core framework, and therefore close your pull request, here are some ways you can go about gathering evidence to convince us otherwise. + +1. Link any relevant issues that you find and note their engagement by other users. +1. Describe common use cases that are not currently well served that your contribution addresses. +1. Link to any third party packages, including any published by you, and other prior art providing the same functionality. +1. Iterate the steps you have taken to ensure that the contribution is well thought out and stable. +1. Include any alternative solutions you explored and your reasoning as to why they weren't chosen. + +All of this information will help make it clear to reviewers why your contribution should be accepted. If a reviewer is still not convinced that the contribution is necessary or effective, an alternative route should be pursued. + +### Publishing Your Own Package + +This is by far the strongest signal you can give to the CDK team that a feature should be included within the core aws-cdk packages. A package published on npm, pypi, maven central, nuget, and github (for go) that has good documentation, a clear purpose, and an active group of users is a good indication that the functionality it provides is useful and should be examined for inclusion in the core aws-cdk packages. This may not be the goal of any given package, and some constructs and features do not provide functionality that should ever be vended as part of the core framework. However, if a package you own does include functionality that you and other users believe should be vended as part of the core CDK, we encourage making a pull request, or RFC if appropriate, proposing it's inclusion. + +#### Trust and Third Party Packages + +An argument we commonly hear why contributors don't want to publish their contributions in their own packages, is that organizations have restrictions on what packages they allow to be used and these restrictions commonly include limiting usage of packages to those owned and distributed only from trusted sources. We recognize trust is an important part of the software dependency chain, and we take that into consideration when evaluating contributions in aws-cdk. However, not everything can be owned by the aws-cdk team. Strictly from a technical limitation perspective, `aws-cdk-lib` is big. Continuing a system that makes it, potentially, many multiple times bigger, has a cost on usability. Additionally, as the surface area widens, the aws-cdk team becomes stretched ever thinner and isn't able to property maintain what we own. + +That being said, "trust", isn't as black and white as "it's owned by aws, so it's okay". The best way to trust that the packages you depend on to help generate your aws resources is to use [policy validation](https://docs.aws.amazon.com/cdk/v2/guide/policy-validation-synthesis.html) on the output of your application in order to ensure it is following the rules that are important to you or your organization. + +#### Third Party Package Administration + +Another reason we hear from authors that they don't want to publish their own packages, is they don't want to go through the trouble of setting up their own repository and publishing toolchain. This is something we are continuously working on making easier and we encourage you to check out some of the tools that we have available to aid in this. + +1. [Projen](https://github.com/projen/projen) - A tool with common repository and publishing setup abstracted, has a construct specifically for CDK construct libraries. +1. [Publib](https://github.com/cdklabs/publib) - A toolchain for publishing packages to multiple repositories. A lot of this is included in projen and we recommend using that instead of publib directly, but it may be useful for specific cases. +1. [Construct Hub](https://constructs.dev) - An index of all construct libraries published to NPM. When you publish a construct library, it will automatically have documentation generated and published to Construct Hub. + ## Getting Started The following steps describe how to set up the AWS CDK repository on your local machine. diff --git a/docs/contribution_flow.png b/docs/contribution_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..81aebe8df205802d25d7ebdbf4f501d3f5393e50 GIT binary patch literal 174069 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 Date: Tue, 31 Oct 2023 14:23:22 -0700 Subject: [PATCH 07/14] chore(cloudfront): create unit tests to mock edge function handler (#27768) This PR adds three unit tests that mock functionality found in the Lambda handler for edge functions. Specifically, this PR is adding one unit test for a create event, one unit test for an update event, and one unit test for a delete event to verify that the handler only executes for create and update events. Closes #27724 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/experimental/edge-function.test.ts | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/packages/aws-cdk-lib/aws-cloudfront/test/experimental/edge-function.test.ts b/packages/aws-cdk-lib/aws-cloudfront/test/experimental/edge-function.test.ts index 5b927a76ba2bb..bcf7a96ecd767 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/test/experimental/edge-function.test.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/test/experimental/edge-function.test.ts @@ -5,10 +5,40 @@ import * as iam from '../../../aws-iam'; import * as lambda from '../../../aws-lambda'; import * as cdk from '../../../core'; import * as cloudfront from '../../lib'; +import { handler } from '../../lib/experimental/edge-function/index'; let app: cdk.App; let stack: cdk.Stack; +type RequestType = 'Create' | 'Update' | 'Delete'; + +const mockSSM = { + getParameter: jest.fn().mockResolvedValue({ + Parameter: { Value: 'arn:aws:lambda:us-west-2:123456789012:function:edge-function' }, + }), +}; + +jest.mock('@aws-sdk/client-ssm', () => { + return { + SSM: jest.fn().mockImplementation(() => { + return mockSSM; + }), + }; +}); + +const eventCommon = { + ServiceToken: 'token', + ResponseURL: 'https://localhost', + StackId: 'stackId', + RequestId: 'requestId', + LogicalResourceId: 'logicalResourceId', + PhysicalResourceId: 'physicalResourceId', + ResourceProperties: { + Region: 'us-west-2', + ParameterName: 'edge-function-arn', + }, +}; + beforeEach(() => { app = new cdk.App(); stack = new cdk.Stack(app, 'Stack', { @@ -16,6 +46,8 @@ beforeEach(() => { }); }); +afterAll(() => { jest.resetAllMocks(); }); + describe('stacks', () => { test('creates a custom resource and supporting resources in main stack', () => { new cloudfront.experimental.EdgeFunction(stack, 'MyFn', defaultEdgeFunctionProps()); @@ -227,6 +259,58 @@ describe('stacks', () => { }); }); +describe('handler', () => { + afterEach(() => { + jest.restoreAllMocks(); + mockSSM.getParameter.mockClear(); + }); + + test('create event', async () => { + // GIVEN + const event = { + ...eventCommon, + RequestType: 'Create' as RequestType, + }; + + // WHEN + const response = await handler(event); + + // THEN + expect(mockSSM.getParameter).toBeCalledWith({ Name: 'edge-function-arn' }); + expect(response).toEqual({ Data: { FunctionArn: 'arn:aws:lambda:us-west-2:123456789012:function:edge-function' } }); + }); + + test('update event', async () => { + // GIVEN + const event = { + ...eventCommon, + RequestType: 'Update' as RequestType, + }; + + // WHEN + const response = await handler(event); + + // THEN + expect(mockSSM.getParameter).toBeCalledWith({ Name: 'edge-function-arn' }); + expect(response).toEqual({ Data: { FunctionArn: 'arn:aws:lambda:us-west-2:123456789012:function:edge-function' } }); + }); + + test('delete event', async () => { + // GIVEN + const event = { + ...eventCommon, + RequestType: 'Delete' as RequestType, + }; + + // WHEN + const response = await handler(event); + + // THEN + expect(mockSSM.getParameter).not.toHaveBeenCalled(); + expect(response).toBe(undefined); + }); +}); + test('addAlias() creates alias in function stack', () => { const fn = new cloudfront.experimental.EdgeFunction(stack, 'MyFn', defaultEdgeFunctionProps()); From 24ffb6a722a32c8727fbc843234f8ad39028f01a Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Tue, 31 Oct 2023 20:38:42 -0400 Subject: [PATCH 08/14] chore: update Contributors File (#27784) Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action --- CONTRIBUTORS.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 95c8d8b92cf20..8f4b65c49a03b 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -6,8 +6,8 @@ Shout out to our top contributors! - [skinny85](https://github.com/skinny85) - [RomainMuller](https://github.com/RomainMuller) - [njlynch](https://github.com/njlynch) -- [jogold](https://github.com/jogold) - [kaizencc](https://github.com/kaizencc) +- [jogold](https://github.com/jogold) - [iliapolo](https://github.com/iliapolo) - [corymhall](https://github.com/corymhall) - [shivlaks](https://github.com/shivlaks) @@ -16,17 +16,17 @@ Shout out to our top contributors! - [NetaNir](https://github.com/NetaNir) - [comcalvi](https://github.com/comcalvi) - [robertd](https://github.com/robertd) +- [MrArnoldPalmer](https://github.com/MrArnoldPalmer) - [pahud](https://github.com/pahud) - [mrgrain](https://github.com/mrgrain) -- [MrArnoldPalmer](https://github.com/MrArnoldPalmer) - [peterwoodworth](https://github.com/peterwoodworth) - [TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) +- [lpizzinidev](https://github.com/lpizzinidev) - [nija-at](https://github.com/nija-at) - [hoegertn](https://github.com/hoegertn) -- [lpizzinidev](https://github.com/lpizzinidev) - [jumic](https://github.com/jumic) -- [SoManyHs](https://github.com/SoManyHs) - [watany-dev](https://github.com/watany-dev) +- [SoManyHs](https://github.com/SoManyHs) -_Last updated: Sun, 01 Oct 23 00:09:32 +0000_ \ No newline at end of file +_Last updated: Wed, 01 Nov 23 00:09:18 +0000_ \ No newline at end of file From 00d2ff28e7a4ec0d6e97fe4e35d23c1f17ec4969 Mon Sep 17 00:00:00 2001 From: Markus Ziller Date: Wed, 1 Nov 2023 04:47:01 +0100 Subject: [PATCH 09/14] feat(cloud9-alpha): add support for `federated-user` and `assumed-role` for Cloud9 environment ownership (#27001) Currently, the cloud9-alpha module only supports two IAM entities as the owners of a Cloud9 environment - Account Root - User However, in many environments, access to an AWS account is gained via Federation. To use Cloud9 via the CDK in such environments, workarounds like the following one where required: ``` const cloud9 = new Ec2Environment(this, 'Cloud9', {..}); const cfnC9 = cloud9.node.findChild('Resource') as CfnEnvironmentEC2; cfnC9.ownerArn = 'arn:sts:..; ``` This merge request adds support for assumed roles and federated users to be owners of C9 environments directly in the CDK construct. ---- *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-cloud9-alpha/README.md | 46 +- .../aws-cloud9-alpha/lib/environment.ts | 20 + .../test/cloud9.environment.test.ts | 31 +- ...efaultTestDeployAssertEE359F09.assets.json | 19 + ...aultTestDeployAssertEE359F09.template.json | 36 + .../test/integ.owner.js.snapshot/cdk.out | 1 + .../cloud9-owner-integ.assets.json | 19 + .../cloud9-owner-integ.template.json | 470 ++++++++++ .../test/integ.owner.js.snapshot/integ.json | 12 + .../integ.owner.js.snapshot/manifest.json | 257 ++++++ .../test/integ.owner.js.snapshot/tree.json | 806 ++++++++++++++++++ .../aws-cloud9-alpha/test/integ.owner.ts | 43 + 12 files changed, 1756 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.assets.json create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.template.json create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.assets.json create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.template.json create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.ts diff --git a/packages/@aws-cdk/aws-cloud9-alpha/README.md b/packages/@aws-cdk/aws-cloud9-alpha/README.md index 497b932c101e4..f3d25d6dfd20d 100644 --- a/packages/@aws-cdk/aws-cloud9-alpha/README.md +++ b/packages/@aws-cdk/aws-cloud9-alpha/README.md @@ -105,7 +105,16 @@ Every Cloud9 Environment has an **owner**. An owner has full control over the en By default, the owner will be the identity that creates the Environment, which is most likely your CloudFormation Execution Role when the Environment is created using CloudFormation. Provider a value for the `owner` property to assign a different owner, either a specific IAM User or the AWS Account Root User. -`Owner` is a user that owns a Cloud9 environment . `Owner` has their own access permissions, resources. And we can specify an `Owner`in an Ec2 environment which could be of two types, 1. AccountRoot and 2. Iam User. It allows AWS to determine who has permissions to manage the environment, either an IAM user or the account root user (but using the account root user is not recommended, see [environment sharing best practices](https://docs.aws.amazon.com/cloud9/latest/user-guide/share-environment.html#share-environment-best-practices)). +`Owner` is an IAM entity that owns a Cloud9 environment. `Owner` has their own access permissions, and resources. You can specify an `Owner`in an EC2 environment which could be of the following types: + +1. Account Root +2. IAM User +3. IAM Federated User +4. IAM Assumed Role + +The ARN of the owner must satisfy the following regular expression: `^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):(iam|sts)::\d+:(root|(user\/[\w+=/:,.@-]{1,64}|federated-user\/[\w+=/:,.@-]{2,32}|assumed-role\/[\w+=:,.@-]{1,64}\/[\w+=,.@-]{1,64}))$` + +Note: Using the account root user is not recommended, see [environment sharing best practices](https://docs.aws.amazon.com/cloud9/latest/user-guide/share-environment.html#share-environment-best-practices). To specify the AWS Account Root User as the environment owner, use `Owner.accountRoot()` @@ -114,13 +123,14 @@ declare const vpc: ec2.Vpc; new cloud9.Ec2Environment(this, 'C9Env', { vpc, imageId: cloud9.ImageId.AMAZON_LINUX_2, - owner: cloud9.Owner.accountRoot('111111111') }) ``` To specify a specific IAM User as the environment owner, use `Owner.user()`. The user should have the `AWSCloud9Administrator` managed policy +The user should have the `AWSCloud9User` (preferred) or `AWSCloud9Administrator` managed policy attached. + ```ts import * as iam from 'aws-cdk-lib/aws-iam'; @@ -135,9 +145,39 @@ new cloud9.Ec2Environment(this, 'C9Env', { }) ``` +To specify a specific IAM Federated User as the environment owner, use `Owner.federatedUser(accountId, userName)`. + +The user should have the `AWSCloud9User` (preferred) or `AWSCloud9Administrator` managed policy attached. + +```ts +import * as iam from 'aws-cdk-lib/aws-iam'; + +declare const vpc: ec2.Vpc; +new cloud9.Ec2Environment(this, 'C9Env', { + vpc, + imageId: cloud9.ImageId.AMAZON_LINUX_2, + owner: cloud9.Owner.federatedUser(Stack.of(this).account, "Admin/johndoe") +}) +``` + +To specify an IAM Assumed Role as the environment owner, use `Owner.assumedRole(accountId: string, roleName: string)`. + +The role should have the `AWSCloud9User` (preferred) or `AWSCloud9Administrator` managed policy attached. + +```ts +import * as iam from 'aws-cdk-lib/aws-iam'; + +declare const vpc: ec2.Vpc; +new cloud9.Ec2Environment(this, 'C9Env', { + vpc, + imageId: cloud9.ImageId.AMAZON_LINUX_2, + owner: cloud9.Owner.assumedRole(Stack.of(this).account, "Admin/johndoe-role") +}) +``` + ## Auto-Hibernation -A Cloud9 environemnt can automatically start and stop the associated EC2 instance to reduce costs. +A Cloud9 environment can automatically start and stop the associated EC2 instance to reduce costs. Use `automaticStop` to specify the number of minutes until the running instance is shut down after the environment was last used. diff --git a/packages/@aws-cdk/aws-cloud9-alpha/lib/environment.ts b/packages/@aws-cdk/aws-cloud9-alpha/lib/environment.ts index 1894499e4da5f..3158a612061ef 100644 --- a/packages/@aws-cdk/aws-cloud9-alpha/lib/environment.ts +++ b/packages/@aws-cdk/aws-cloud9-alpha/lib/environment.ts @@ -257,6 +257,26 @@ export class Owner { return { ownerArn: user.userArn }; } + /** + * Make an IAM assumed role the environment owner + * + * @param accountId The account id of the target account + * @param roleName The name of the assumed role + */ + public static assumedRole(accountId: string, roleName: string): Owner { + return { ownerArn: `arn:${cdk.Aws.PARTITION}:sts::${accountId}:assumed-role/${roleName}` }; + } + + /** + * Make an IAM federated user the environment owner + * + * @param accountId The AccountId of the target account + * @param userName The name of the federated user + */ + public static federatedUser(accountId: string, userName: string): Owner { + return { ownerArn: `arn:${cdk.Aws.PARTITION}:sts::${accountId}:federated-user/${userName}` }; + } + /** * Make the Account Root User the environment owner (not recommended) * diff --git a/packages/@aws-cdk/aws-cloud9-alpha/test/cloud9.environment.test.ts b/packages/@aws-cdk/aws-cloud9-alpha/test/cloud9.environment.test.ts index 41879129e907e..ea3705edb5162 100644 --- a/packages/@aws-cdk/aws-cloud9-alpha/test/cloud9.environment.test.ts +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/cloud9.environment.test.ts @@ -124,14 +124,43 @@ test('environment owner can be an IAM user', () => { imageId: cloud9.ImageId.AMAZON_LINUX_2, owner: Owner.user(user), }); + // THEN + const userLogicalId = stack.getLogicalId(user.node.defaultChild as iam.CfnUser); Template.fromStack(stack).hasResourceProperties('AWS::Cloud9::EnvironmentEC2', { OwnerArn: { - 'Fn::GetAtt': ['User00B015A1', 'Arn'], + 'Fn::GetAtt': [userLogicalId, 'Arn'], }, }); }); +test('environment owner can be an IAM Assumed Role', () => { + // WHEN + new cloud9.Ec2Environment(stack, 'C9Env', { + vpc, + imageId: cloud9.ImageId.AMAZON_LINUX_2, + owner: Owner.assumedRole('123456789098', 'Admin'), + }); + // THEN + + Template.fromStack(stack).hasResourceProperties('AWS::Cloud9::EnvironmentEC2', { + OwnerArn: { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':sts::123456789098:assumed-role/Admin']] }, + }); +}); + +test('environment owner can be an IAM Federated User', () => { + // WHEN + new cloud9.Ec2Environment(stack, 'C9Env', { + vpc, + imageId: cloud9.ImageId.AMAZON_LINUX_2, + owner: Owner.federatedUser('123456789098', 'Admin'), + }); + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cloud9::EnvironmentEC2', { + OwnerArn: { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':sts::123456789098:federated-user/Admin']] }, + }); +}); + test('environment owner can be account root', () => { // WHEN new cloud9.Ec2Environment(stack, 'C9Env', { diff --git a/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.assets.json b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.assets.json new file mode 100644 index 0000000000000..d8b3fdecad0dd --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "OwnerIntegDefaultTestDeployAssertEE359F09.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-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.template.json b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/OwnerIntegDefaultTestDeployAssertEE359F09.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-cloud9-alpha/test/integ.owner.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.assets.json b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.assets.json new file mode 100644 index 0000000000000..0d7432d84f5b1 --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "d0bd32fadb21b986ec5baf0ba579723a391e4dc1e08beec36608a11de484bcc6": { + "source": { + "path": "cloud9-owner-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d0bd32fadb21b986ec5baf0ba579723a391e4dc1e08beec36608a11de484bcc6.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-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.template.json b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.template.json new file mode 100644 index 0000000000000..b71f72f084d15 --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/cloud9-owner-integ.template.json @@ -0,0 +1,470 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "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": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC" + ] + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "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": "cloud9-owner-integ/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "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": "cloud9-owner-integ/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "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": "cloud9-owner-integ/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "cloud9-owner-integ/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "Cloud9OwnerRole72D8750E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": "*" + } + } + ], + "Version": "2012-10-17" + }, + "Description": "Created as part of the integration tests for the Cloud9 CDK construct", + "RoleName": "Cloud9OwnerRole" + } + }, + "C9EnvF05FC3BE": { + "Type": "AWS::Cloud9::EnvironmentEC2", + "Properties": { + "ConnectionType": "CONNECT_SSH", + "ImageId": "amazonlinux-2-x86_64", + "InstanceType": "t2.micro", + "OwnerArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":sts::", + { + "Ref": "AWS::AccountId" + }, + ":assumed-role/", + { + "Ref": "Cloud9OwnerRole72D8750E" + }, + "/a-test-session" + ] + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + } + }, + "Outputs": { + "URL": { + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Ref": "AWS::Region" + }, + ".console.aws.amazon.com/cloud9/ide/", + { + "Ref": "C9EnvF05FC3BE" + } + ] + ] + } + }, + "ARN": { + "Value": { + "Fn::GetAtt": [ + "C9EnvF05FC3BE", + "Arn" + ] + } + } + }, + "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-cloud9-alpha/test/integ.owner.js.snapshot/integ.json b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/integ.json new file mode 100644 index 0000000000000..1feafd9709c7c --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "OwnerInteg/DefaultTest": { + "stacks": [ + "cloud9-owner-integ" + ], + "assertionStack": "OwnerInteg/DefaultTest/DeployAssert", + "assertionStackName": "OwnerIntegDefaultTestDeployAssertEE359F09" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/manifest.json b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/manifest.json new file mode 100644 index 0000000000000..2de47ca485815 --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/manifest.json @@ -0,0 +1,257 @@ +{ + "version": "34.0.0", + "artifacts": { + "cloud9-owner-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cloud9-owner-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cloud9-owner-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cloud9-owner-integ.template.json", + "terminationProtection": false, + "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}/d0bd32fadb21b986ec5baf0ba579723a391e4dc1e08beec36608a11de484bcc6.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cloud9-owner-integ.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cloud9-owner-integ.assets" + ], + "metadata": { + "/cloud9-owner-integ/VPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCB9E5F0B4" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1SubnetB4246D30" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableFEE4B781" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1DefaultRoute91CEF279" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1EIP6AD938E8" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1NATGatewayE0556630" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2Subnet74179F39" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTable6F1A15F1" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTableAssociation5A808732" + } + ], + "/cloud9-owner-integ/VPC/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2DefaultRouteB7481BBA" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableBE8A6027" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTable0A19E10E" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" + } + ], + "/cloud9-owner-integ/VPC/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" + } + ], + "/cloud9-owner-integ/VPC/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCIGWB7E252D3" + } + ], + "/cloud9-owner-integ/VPC/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCVPCGW99B986DC" + } + ], + "/cloud9-owner-integ/Cloud9OwnerRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Cloud9OwnerRole72D8750E" + } + ], + "/cloud9-owner-integ/C9Env/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "C9EnvF05FC3BE" + } + ], + "/cloud9-owner-integ/URL": [ + { + "type": "aws:cdk:logicalId", + "data": "URL" + } + ], + "/cloud9-owner-integ/ARN": [ + { + "type": "aws:cdk:logicalId", + "data": "ARN" + } + ], + "/cloud9-owner-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cloud9-owner-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cloud9-owner-integ" + }, + "OwnerIntegDefaultTestDeployAssertEE359F09.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "OwnerIntegDefaultTestDeployAssertEE359F09.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "OwnerIntegDefaultTestDeployAssertEE359F09": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "OwnerIntegDefaultTestDeployAssertEE359F09.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "OwnerIntegDefaultTestDeployAssertEE359F09.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": [ + "OwnerIntegDefaultTestDeployAssertEE359F09.assets" + ], + "metadata": { + "/OwnerInteg/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/OwnerInteg/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "OwnerInteg/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/tree.json b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/tree.json new file mode 100644 index 0000000000000..141c533809cc5 --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.js.snapshot/tree.json @@ -0,0 +1,806 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "cloud9-owner-integ": { + "id": "cloud9-owner-integ", + "path": "cloud9-owner-integ", + "children": { + "VPC": { + "id": "VPC", + "path": "cloud9-owner-integ/VPC", + "children": { + "Resource": { + "id": "Resource", + "path": "cloud9-owner-integ/VPC/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "cloud9-owner-integ/VPC/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "cloud9-owner-integ/VPC/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "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": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "cloud9-owner-integ/VPC/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "cloud9-owner-integ/VPC/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "cloud9-owner-integ/VPC/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "cloud9-owner-integ/VPC/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "cloud9-owner-integ/VPC/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "cloud9-owner-integ/VPC/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "cloud9-owner-integ/VPC/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "cloud9-owner-integ/VPC/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "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": "cloud9-owner-integ/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "cloud9-owner-integ/VPC/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "cloud9-owner-integ/VPC/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "cloud9-owner-integ/VPC/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "cloud9-owner-integ/VPC/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "cloud9-owner-integ/VPC/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "cloud9-owner-integ/VPC/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "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": "cloud9-owner-integ/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "cloud9-owner-integ/VPC/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "cloud9-owner-integ/VPC/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "cloud9-owner-integ/VPC/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "cloud9-owner-integ/VPC/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "cloud9-owner-integ/VPC/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "cloud9-owner-integ/VPC/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "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": "cloud9-owner-integ/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "cloud9-owner-integ/VPC/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "cloud9-owner-integ/VPC/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "cloud9-owner-integ/VPC/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "cloud9-owner-integ/VPC/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "cloud9-owner-integ/VPC/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "cloud9-owner-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "cloud9-owner-integ/VPC/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.Vpc", + "version": "0.0.0" + } + }, + "Cloud9OwnerRole": { + "id": "Cloud9OwnerRole", + "path": "cloud9-owner-integ/Cloud9OwnerRole", + "children": { + "ImportCloud9OwnerRole": { + "id": "ImportCloud9OwnerRole", + "path": "cloud9-owner-integ/Cloud9OwnerRole/ImportCloud9OwnerRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cloud9-owner-integ/Cloud9OwnerRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": "*" + } + } + ], + "Version": "2012-10-17" + }, + "description": "Created as part of the integration tests for the Cloud9 CDK construct", + "roleName": "Cloud9OwnerRole" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "C9Env": { + "id": "C9Env", + "path": "cloud9-owner-integ/C9Env", + "children": { + "Resource": { + "id": "Resource", + "path": "cloud9-owner-integ/C9Env/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Cloud9::EnvironmentEC2", + "aws:cdk:cloudformation:props": { + "connectionType": "CONNECT_SSH", + "imageId": "amazonlinux-2-x86_64", + "instanceType": "t2.micro", + "ownerArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":sts::", + { + "Ref": "AWS::AccountId" + }, + ":assumed-role/", + { + "Ref": "Cloud9OwnerRole72D8750E" + }, + "/a-test-session" + ] + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloud9.CfnEnvironmentEC2", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloud9-alpha.Ec2Environment", + "version": "0.0.0" + } + }, + "URL": { + "id": "URL", + "path": "cloud9-owner-integ/URL", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "ARN": { + "id": "ARN", + "path": "cloud9-owner-integ/ARN", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cloud9-owner-integ/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cloud9-owner-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "OwnerInteg": { + "id": "OwnerInteg", + "path": "OwnerInteg", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "OwnerInteg/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "OwnerInteg/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "OwnerInteg/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "OwnerInteg/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "OwnerInteg/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.ts b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.ts new file mode 100644 index 0000000000000..b9b8078fd699d --- /dev/null +++ b/packages/@aws-cdk/aws-cloud9-alpha/test/integ.owner.ts @@ -0,0 +1,43 @@ +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import { Stack, App, StackProps, CfnOutput } from 'aws-cdk-lib'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import { Construct } from 'constructs'; +import * as cloud9 from '../lib'; +import { AnyPrincipal, Role } from 'aws-cdk-lib/aws-iam'; + +class Cloud9Env extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + const vpc = new ec2.Vpc(this, 'VPC', { + restrictDefaultSecurityGroup: false, + maxAzs: 2, + natGateways: 1, + }); + + const role = new Role(this, 'Cloud9OwnerRole', { + roleName: 'Cloud9OwnerRole', + description: 'Created as part of the integration tests for the Cloud9 CDK construct', + assumedBy: new AnyPrincipal(), + }); + + const accountId = Stack.of(this).account; + const roleSessionName = 'a-test-session'; + const assumedRoleString = `${role.roleName}/${roleSessionName}`; + + // create a cloud9 ec2 environment in a new VPC + const c9env = new cloud9.Ec2Environment(this, 'C9Env', { + vpc, + imageId: cloud9.ImageId.AMAZON_LINUX_2, + owner: cloud9.Owner.assumedRole(accountId, assumedRoleString), + }); + new CfnOutput(this, 'URL', { value: c9env.ideUrl }); + new CfnOutput(this, 'ARN', { value: c9env.ec2EnvironmentArn }); + } +} + +const app = new App(); + +new integ.IntegTest(app, 'OwnerInteg', { + testCases: [new Cloud9Env(app, 'cloud9-owner-integ')], +}); From 93c6a9aca7e2323492d1c7bde53d0097ffb073b7 Mon Sep 17 00:00:00 2001 From: Joshua Weber <57131123+daschaa@users.noreply.github.com> Date: Wed, 1 Nov 2023 16:46:26 +0100 Subject: [PATCH 10/14] fix(codepipeline-actions): default branch for CodeCommit is master (under feature flag) (#27753) Closes #27710. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...dk-codepipeline-cloudformation.assets.json | 6 +- ...-codepipeline-cloudformation.template.json | 34 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 17 +- .../tree.json | 204 ++-- .../LambdaStack.assets.json | 4 +- .../LambdaStack.template.json | 2 +- .../PipelineStack.assets.json | 4 +- .../PipelineStack.template.json | 8 +- .../manifest.json | 6 +- .../tree.json | 30 +- ...k-codepipeline-codebuild-batch.assets.json | 6 +- ...codepipeline-codebuild-batch.template.json | 44 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 17 +- .../tree.json | 174 ++- ...ebuild-multiple-inputs-outputs.assets.json | 6 +- ...uild-multiple-inputs-outputs.template.json | 28 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 17 +- .../tree.json | 146 ++- ...epipeline-codecommit-codebuild.assets.json | 6 +- ...ipeline-codecommit-codebuild.template.json | 52 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 17 +- .../tree.json | 208 ++-- ...efaultTestDeployAssertE3E7D2A4.assets.json | 19 + ...aultTestDeployAssertE3E7D2A4.template.json | 36 + ...k-codepipeline-codecommit-main.assets.json | 19 + ...codepipeline-codecommit-main.template.json | 635 +++++++++++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 200 ++++ .../tree.json | 1012 +++++++++++++++++ .../test/integ.pipeline-code-commit-main.ts | 40 + ...ws-cdk-codepipeline-codecommit.assets.json | 6 +- ...-cdk-codepipeline-codecommit.template.json | 32 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 17 +- .../tree.json | 220 ++-- .../test/integ.pipeline-code-commit.ts | 6 +- .../aws-cdk-pipeline-event-target.assets.json | 6 +- ...ws-cdk-pipeline-event-target.template.json | 52 +- .../integ.pipeline-events.js.snapshot/cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 17 +- .../tree.json | 210 ++-- packages/@aws-cdk/cx-api/FEATURE_FLAGS.md | 19 +- .../lib/codecommit/source-action.ts | 26 +- .../codecommit-source-action.test.ts | 158 ++- packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md | 19 +- packages/aws-cdk-lib/cx-api/README.md | 18 + packages/aws-cdk-lib/cx-api/lib/features.ts | 14 + 58 files changed, 3191 insertions(+), 663 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json index 986992e06440f..cd7f3f314fdb6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "34.0.0", "files": { - "20da66e133f179332e83c9a4cb06c53d29a826f0c46e697026309729b765cef8": { + "084ca20cbe926238233c0a6584e19f8ce8057e3e7b7adcb4f21c6b6828acd256": { "source": { "path": "aws-cdk-codepipeline-cloudformation.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "20da66e133f179332e83c9a4cb06c53d29a826f0c46e697026309729b765cef8.json", + "objectKey": "084ca20cbe926238233c0a6584e19f8ce8057e3e7b7adcb4f21c6b6828acd256.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json index 15cbb079c47d0..1a40cea03c640 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json @@ -249,6 +249,21 @@ "PipelineC660917D": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { + "ArtifactStore": { + "EncryptionKey": { + "Id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + }, + "Type": "KMS" + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" + }, "RoleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -272,7 +287,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": true }, "Name": "Source", @@ -368,22 +383,7 @@ ], "Name": "Deploy" } - ], - "ArtifactStore": { - "EncryptionKey": { - "Id": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - }, - "Type": "KMS" - }, - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3" - } + ] }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out index 588d7b269d34f..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json index c2d0c27161ec7..19c9f44bcac42 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "34.0.0", "testCases": { "integ.cfn-template-from-repo.lit": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json index 5e5fb81dfb8dc..b7b1f0d0bb29e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "34.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-codepipeline-cloudformation.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-codepipeline-cloudformation.template.json", + "terminationProtection": false, "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}/20da66e133f179332e83c9a4cb06c53d29a826f0c46e697026309729b765cef8.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/084ca20cbe926238233c0a6584e19f8ce8057e3e7b7adcb4f21c6b6828acd256.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -155,6 +150,12 @@ ] }, "displayName": "aws-cdk-codepipeline-cloudformation" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/tree.json index 18e2268a98271..5ecb19c0bb7c9 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.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-codepipeline-cloudformation": { "id": "aws-cdk-codepipeline-cloudformation", "path": "aws-cdk-codepipeline-cloudformation", @@ -30,13 +22,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.CfnRepository", + "fqn": "aws-cdk-lib.aws_codecommit.CfnRepository", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.Repository", + "fqn": "aws-cdk-lib.aws_codecommit.Repository", "version": "0.0.0" } }, @@ -85,13 +77,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnKey", + "fqn": "aws-cdk-lib.aws_kms.CfnKey", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Key", + "fqn": "aws-cdk-lib.aws_kms.Key", "version": "0.0.0" } }, @@ -115,13 +107,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnAlias", + "fqn": "aws-cdk-lib.aws_kms.CfnAlias", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Alias", + "fqn": "aws-cdk-lib.aws_kms.Alias", "version": "0.0.0" } }, @@ -159,7 +151,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } }, @@ -218,19 +210,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -238,6 +230,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Role/Resource", @@ -259,7 +259,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -370,19 +370,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -392,6 +392,21 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "encryptionKey": { + "type": "KMS", + "id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + }, "roleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -422,7 +437,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": true }, "runOrder": 1, @@ -511,26 +526,11 @@ } ] } - ], - "artifactStore": { - "type": "S3", - "location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "encryptionKey": { - "type": "KMS", - "id": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - } - } - } + ] } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.CfnPipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", "version": "0.0.0" } }, @@ -546,6 +546,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Source/Source/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Source/Source/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Source/Source/CodePipelineActionRole/Resource", @@ -582,7 +590,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -679,32 +687,32 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "Deploy": { @@ -719,6 +727,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/CodePipelineActionRole/Resource", @@ -755,7 +771,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -764,7 +780,7 @@ "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/CodePipelineActionRole/8389e75f-0810-4838-bf64-d6f85a95cf83", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "DefaultPolicy": { @@ -878,19 +894,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -898,6 +914,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/Role/Resource", @@ -919,7 +943,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -995,26 +1019,26 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "ApproveChanges": { @@ -1025,6 +1049,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ApproveChanges/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ApproveChanges/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ApproveChanges/CodePipelineActionRole/Resource", @@ -1061,20 +1093,20 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "ExecuteChanges": { @@ -1085,6 +1117,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ExecuteChanges/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ExecuteChanges/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ExecuteChanges/CodePipelineActionRole/Resource", @@ -1121,7 +1161,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -1130,7 +1170,7 @@ "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ExecuteChanges/CodePipelineActionRole/8389e75f-0810-4838-bf64-d6f85a95cf83", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "DefaultPolicy": { @@ -1190,50 +1230,74 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.Pipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-codepipeline-cloudformation/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-codepipeline-cloudformation/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.assets.json index ef8172964f579..2f1be45d9958e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.assets.json @@ -1,7 +1,7 @@ { "version": "34.0.0", "files": { - "62d07ad6f5812b4baa20f87ec2114ca1702fd6a7da234a9da8bb814e4542dd7a": { + "3244d385f3a60d3e248c67f708aab8cdc802b25a2c753ed614d5fd89f0fa7b49": { "source": { "path": "LambdaStack.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "62d07ad6f5812b4baa20f87ec2114ca1702fd6a7da234a9da8bb814e4542dd7a.json", + "objectKey": "3244d385f3a60d3e248c67f708aab8cdc802b25a2c753ed614d5fd89f0fa7b49.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.template.json index fc1400c87daf5..7108d9d07b1e6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/LambdaStack.template.json @@ -49,7 +49,7 @@ "Arn" ] }, - "Runtime": "nodejs16.x" + "Runtime": "nodejs18.x" }, "DependsOn": [ "LambdaServiceRoleA8ED4D3B" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.assets.json index 01594cf03b513..c0ac1afc47eb5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.assets.json @@ -1,7 +1,7 @@ { "version": "34.0.0", "files": { - "11a226e917988273b2591c2e27d7ad60f4460292feba0c4e6afb9d472a865ad9": { + "17dfd970fa4ef33de4c8db97c6218fe1c1430baee9c59136dc009b508e20f380": { "source": { "path": "PipelineStack.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "11a226e917988273b2591c2e27d7ad60f4460292feba0c4e6afb9d472a865ad9.json", + "objectKey": "17dfd970fa4ef33de4c8db97c6218fe1c1430baee9c59136dc009b508e20f380.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.template.json index 3f2e680f53298..e879e1e55b596 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/PipelineStack.template.json @@ -287,7 +287,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "Name": "CdkCode_Source", @@ -318,7 +318,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "Name": "LambdaCode_Source", @@ -1116,7 +1116,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, @@ -1187,7 +1187,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/manifest.json index 8cc0455e9e59a..6982c2ef77164 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/manifest.json @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "LambdaStack.template.json", + "terminationProtection": false, "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}/62d07ad6f5812b4baa20f87ec2114ca1702fd6a7da234a9da8bb814e4542dd7a.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/3244d385f3a60d3e248c67f708aab8cdc802b25a2c753ed614d5fd89f0fa7b49.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -85,10 +86,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "PipelineStack.template.json", + "terminationProtection": false, "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}/11a226e917988273b2591c2e27d7ad60f4460292feba0c4e6afb9d472a865ad9.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/17dfd970fa4ef33de4c8db97c6218fe1c1430baee9c59136dc009b508e20f380.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/tree.json index 61b7cf0ef8829..eeaddd27df047 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.js.snapshot/tree.json @@ -106,7 +106,7 @@ "Arn" ] }, - "runtime": "nodejs16.x" + "runtime": "nodejs18.x" } }, "constructInfo": { @@ -557,7 +557,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "runOrder": 1, @@ -588,7 +588,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "runOrder": 1, @@ -890,7 +890,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } }, "LambdaCode_Source": { @@ -1061,13 +1061,13 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } }, "EventsRole": { @@ -1291,7 +1291,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } }, "Lambda_Build": { @@ -1407,13 +1407,13 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } }, "Deploy": { @@ -1481,7 +1481,7 @@ "path": "PipelineStack/Pipeline/Deploy/Lambda_CFN_Deploy/CodePipelineActionRole/8389e75f-0810-4838-bf64-d6f85a95cf83", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } }, "DefaultPolicy": { @@ -1737,13 +1737,13 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } } }, @@ -1801,7 +1801,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, @@ -1908,7 +1908,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, @@ -2539,7 +2539,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.assets.json index e7dbbb73ddb50..f2badba10e393 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "34.0.0", "files": { - "c22119c539ed84334ce603709e21e71a44647eb86b1a4c0bfd6fd0489d87e21d": { + "376af0ca9baed31bee3dcbb46ee8daffff17c3a1a36945ccd5cb9396c4528ffb": { "source": { "path": "aws-cdk-codepipeline-codebuild-batch.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "c22119c539ed84334ce603709e21e71a44647eb86b1a4c0bfd6fd0489d87e21d.json", + "objectKey": "376af0ca9baed31bee3dcbb46ee8daffff17c3a1a36945ccd5cb9396c4528ffb.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.template.json index 3a98cdabf9392..65f8f49e881bb 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/aws-cdk-codepipeline-codebuild-batch.template.json @@ -30,7 +30,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, @@ -194,6 +194,12 @@ "PipelineC660917D": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { + "ArtifactStore": { + "Location": { + "Ref": "MyBucketF68F3FF0" + }, + "Type": "S3" + }, "RoleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -217,7 +223,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "Name": "Source", @@ -269,13 +275,7 @@ ], "Name": "Build" } - ], - "ArtifactStore": { - "Location": { - "Ref": "MyBucketF68F3FF0" - }, - "Type": "S3" - } + ] }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", @@ -468,6 +468,18 @@ "Artifacts": { "Type": "CODEPIPELINE" }, + "BuildBatchConfig": { + "ServiceRole": { + "Fn::GetAtt": [ + "MyBuildProjectBatchServiceRole531F3056", + "Arn" + ] + } + }, + "Cache": { + "Type": "NO_CACHE" + }, + "EncryptionKey": "alias/aws/s3", "Environment": { "ComputeType": "BUILD_GENERAL1_SMALL", "Image": "aws/codebuild/standard:1.0", @@ -483,19 +495,7 @@ }, "Source": { "Type": "CODEPIPELINE" - }, - "BuildBatchConfig": { - "ServiceRole": { - "Fn::GetAtt": [ - "MyBuildProjectBatchServiceRole531F3056", - "Arn" - ] - } - }, - "Cache": { - "Type": "NO_CACHE" - }, - "EncryptionKey": "alias/aws/s3" + } } }, "MyBuildProjectBatchServiceRole531F3056": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/cdk.out index 588d7b269d34f..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/integ.json index a9501ce40cc70..123df545b0c36 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "34.0.0", "testCases": { "integ.pipeline-code-build-batch": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/manifest.json index 8fdd771a6346a..d60af03383002 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "34.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-codepipeline-codebuild-batch.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-codepipeline-codebuild-batch.template.json", + "terminationProtection": false, "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}/c22119c539ed84334ce603709e21e71a44647eb86b1a4c0bfd6fd0489d87e21d.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/376af0ca9baed31bee3dcbb46ee8daffff17c3a1a36945ccd5cb9396c4528ffb.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -131,6 +126,12 @@ ] }, "displayName": "aws-cdk-codepipeline-codebuild-batch" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/tree.json index 1fe59f01dda44..a5964ce197558 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-batch.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-codepipeline-codebuild-batch": { "id": "aws-cdk-codepipeline-codebuild-batch", "path": "aws-cdk-codepipeline-codebuild-batch", @@ -30,7 +22,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.CfnRepository", + "fqn": "aws-cdk-lib.aws_codecommit.CfnRepository", "version": "0.0.0" } }, @@ -65,7 +57,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, @@ -107,19 +99,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.CfnRule", + "fqn": "aws-cdk-lib.aws_events.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.Rule", + "fqn": "aws-cdk-lib.aws_events.Rule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.Repository", + "fqn": "aws-cdk-lib.aws_codecommit.Repository", "version": "0.0.0" } }, @@ -139,13 +131,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -157,6 +149,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/Role/Resource", @@ -178,7 +178,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -283,19 +283,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -305,6 +305,12 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "MyBucketF68F3FF0" + } + }, "roleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -335,7 +341,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "runOrder": 1, @@ -380,17 +386,11 @@ } ] } - ], - "artifactStore": { - "type": "S3", - "location": { - "Ref": "MyBucketF68F3FF0" - } - } + ] } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.CfnPipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", "version": "0.0.0" } }, @@ -403,19 +403,27 @@ "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/Source/Source", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "EventsRole": { "id": "EventsRole", "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/EventsRole", "children": { + "ImportEventsRole": { + "id": "ImportEventsRole", + "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/EventsRole/ImportEventsRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/EventsRole/Resource", @@ -437,7 +445,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -492,19 +500,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -517,18 +525,18 @@ "path": "aws-cdk-codepipeline-codebuild-batch/Pipeline/Build/Build", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.Pipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", "version": "0.0.0" } }, @@ -540,6 +548,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-codebuild-batch/MyBuildProject/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codebuild-batch/MyBuildProject/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codebuild-batch/MyBuildProject/Role/Resource", @@ -561,7 +577,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -676,19 +692,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -701,6 +717,18 @@ "artifacts": { "type": "CODEPIPELINE" }, + "buildBatchConfig": { + "serviceRole": { + "Fn::GetAtt": [ + "MyBuildProjectBatchServiceRole531F3056", + "Arn" + ] + } + }, + "cache": { + "type": "NO_CACHE" + }, + "encryptionKey": "alias/aws/s3", "environment": { "type": "LINUX_CONTAINER", "image": "aws/codebuild/standard:1.0", @@ -716,23 +744,11 @@ }, "source": { "type": "CODEPIPELINE" - }, - "buildBatchConfig": { - "serviceRole": { - "Fn::GetAtt": [ - "MyBuildProjectBatchServiceRole531F3056", - "Arn" - ] - } - }, - "cache": { - "type": "NO_CACHE" - }, - "encryptionKey": "alias/aws/s3" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.CfnProject", + "fqn": "aws-cdk-lib.aws_codebuild.CfnProject", "version": "0.0.0" } }, @@ -740,6 +756,14 @@ "id": "BatchServiceRole", "path": "aws-cdk-codepipeline-codebuild-batch/MyBuildProject/BatchServiceRole", "children": { + "ImportBatchServiceRole": { + "id": "ImportBatchServiceRole", + "path": "aws-cdk-codepipeline-codebuild-batch/MyBuildProject/BatchServiceRole/ImportBatchServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codebuild-batch/MyBuildProject/BatchServiceRole/Resource", @@ -761,7 +785,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -803,38 +827,62 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.PipelineProject", + "fqn": "aws-cdk-lib.aws_codebuild.PipelineProject", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-codepipeline-codebuild-batch/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-codepipeline-codebuild-batch/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.assets.json index 8884b2c3f1856..37f6976709c7c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "34.0.0", "files": { - "b78a0c2f1148e537323786370edbf28b5ad50993355bb1b0753a730ca18994cd": { + "540b3e94c2dc3a4be91e4a8d9ec4b533faf4bb2b9b5fe215f2122bf995a1df85": { "source": { "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "b78a0c2f1148e537323786370edbf28b5ad50993355bb1b0753a730ca18994cd.json", + "objectKey": "540b3e94c2dc3a4be91e4a8d9ec4b533faf4bb2b9b5fe215f2122bf995a1df85.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.template.json index 03592efd7cdfd..4c2e43447e268 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.template.json @@ -30,7 +30,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, @@ -224,6 +224,12 @@ "PipelineC660917D": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { + "ArtifactStore": { + "Location": { + "Ref": "MyBucketF68F3FF0" + }, + "Type": "S3" + }, "RoleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -247,7 +253,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "Name": "Source1", @@ -372,13 +378,7 @@ ], "Name": "Build" } - ], - "ArtifactStore": { - "Location": { - "Ref": "MyBucketF68F3FF0" - }, - "Type": "S3" - } + ] }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", @@ -578,6 +578,10 @@ "Artifacts": { "Type": "CODEPIPELINE" }, + "Cache": { + "Type": "NO_CACHE" + }, + "EncryptionKey": "alias/aws/s3", "Environment": { "ComputeType": "BUILD_GENERAL1_SMALL", "Image": "aws/codebuild/standard:1.0", @@ -593,11 +597,7 @@ }, "Source": { "Type": "CODEPIPELINE" - }, - "Cache": { - "Type": "NO_CACHE" - }, - "EncryptionKey": "alias/aws/s3" + } } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/cdk.out index 588d7b269d34f..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/integ.json index 7b02bd3eb4fd6..098c614109896 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "34.0.0", "testCases": { "integ.pipeline-code-build-multiple-inputs-outputs": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/manifest.json index 4ceea72903073..af515b2970ef9 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "34.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs.template.json", + "terminationProtection": false, "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}/b78a0c2f1148e537323786370edbf28b5ad50993355bb1b0753a730ca18994cd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/540b3e94c2dc3a4be91e4a8d9ec4b533faf4bb2b9b5fe215f2122bf995a1df85.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -119,6 +114,12 @@ ] }, "displayName": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/tree.json index dd8edf45ca533..2a34e7c859465 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.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-codepipeline-codebuild-multiple-inputs-outputs": { "id": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs", "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs", @@ -30,7 +22,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.CfnRepository", + "fqn": "aws-cdk-lib.aws_codecommit.CfnRepository", "version": "0.0.0" } }, @@ -65,7 +57,7 @@ "referenceUpdated" ], "referenceName": [ - "master" + "main" ] } }, @@ -107,19 +99,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.CfnRule", + "fqn": "aws-cdk-lib.aws_events.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.Rule", + "fqn": "aws-cdk-lib.aws_events.Rule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.Repository", + "fqn": "aws-cdk-lib.aws_codecommit.Repository", "version": "0.0.0" } }, @@ -139,13 +131,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -157,6 +149,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/Role/Resource", @@ -178,7 +178,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -313,19 +313,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -335,6 +335,12 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "MyBucketF68F3FF0" + } + }, "roleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -365,7 +371,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": false }, "runOrder": 1, @@ -483,17 +489,11 @@ } ] } - ], - "artifactStore": { - "type": "S3", - "location": { - "Ref": "MyBucketF68F3FF0" - } - } + ] } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.CfnPipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", "version": "0.0.0" } }, @@ -506,7 +506,7 @@ "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/Source/Source1", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "Source2": { @@ -514,19 +514,27 @@ "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/Source/Source2", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "EventsRole": { "id": "EventsRole", "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/EventsRole", "children": { + "ImportEventsRole": { + "id": "ImportEventsRole", + "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/EventsRole/ImportEventsRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/EventsRole/Resource", @@ -548,7 +556,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -603,19 +611,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -628,7 +636,7 @@ "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/Build/Build1", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "Build2": { @@ -636,18 +644,18 @@ "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/Pipeline/Build/Build2", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.Pipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", "version": "0.0.0" } }, @@ -659,6 +667,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/MyBuildProject/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/MyBuildProject/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/MyBuildProject/Role/Resource", @@ -680,7 +696,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -802,19 +818,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -827,6 +843,10 @@ "artifacts": { "type": "CODEPIPELINE" }, + "cache": { + "type": "NO_CACHE" + }, + "encryptionKey": "alias/aws/s3", "environment": { "type": "LINUX_CONTAINER", "image": "aws/codebuild/standard:1.0", @@ -842,34 +862,54 @@ }, "source": { "type": "CODEPIPELINE" - }, - "cache": { - "type": "NO_CACHE" - }, - "encryptionKey": "alias/aws/s3" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.CfnProject", + "fqn": "aws-cdk-lib.aws_codebuild.CfnProject", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.PipelineProject", + "fqn": "aws-cdk-lib.aws_codebuild.PipelineProject", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-codepipeline-codebuild-multiple-inputs-outputs/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.assets.json index bcb5ceb880a26..2e436750358b2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "34.0.0", "files": { - "d70a70876f599ba2b61b2c88a0976c58b385096b5899ac502b5d3f907c13955f": { + "9f480ced37f920854d640f2751264b2aed89d23d1434c950e67dade5e27ab00f": { "source": { "path": "aws-cdk-codepipeline-codecommit-codebuild.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d70a70876f599ba2b61b2c88a0976c58b385096b5899ac502b5d3f907c13955f.json", + "objectKey": "9f480ced37f920854d640f2751264b2aed89d23d1434c950e67dade5e27ab00f.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.template.json index 7ab7817439e35..4c6a4f4daa0f3 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/aws-cdk-codepipeline-codecommit-codebuild.template.json @@ -179,6 +179,15 @@ "Artifacts": { "Type": "CODEPIPELINE" }, + "Cache": { + "Type": "NO_CACHE" + }, + "EncryptionKey": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + }, "Environment": { "ComputeType": "BUILD_GENERAL1_SMALL", "Image": "aws/codebuild/standard:1.0", @@ -194,15 +203,6 @@ }, "Source": { "Type": "CODEPIPELINE" - }, - "Cache": { - "Type": "NO_CACHE" - }, - "EncryptionKey": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] } } }, @@ -443,6 +443,21 @@ "PipelineC660917D": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { + "ArtifactStore": { + "EncryptionKey": { + "Id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + }, + "Type": "KMS" + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" + }, "RoleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -466,7 +481,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": true }, "Name": "source", @@ -549,22 +564,7 @@ ], "Name": "build" } - ], - "ArtifactStore": { - "EncryptionKey": { - "Id": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - }, - "Type": "KMS" - }, - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3" - } + ] }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/cdk.out index 588d7b269d34f..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/integ.json index a0bbfb20d6493..d579c43eb36cf 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "34.0.0", "testCases": { "integ.pipeline-code-commit-build": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/manifest.json index b97a812848442..ded1e3a6cecaf 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "34.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-codepipeline-codecommit-codebuild.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-codepipeline-codecommit-codebuild.template.json", + "terminationProtection": false, "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}/d70a70876f599ba2b61b2c88a0976c58b385096b5899ac502b5d3f907c13955f.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/9f480ced37f920854d640f2751264b2aed89d23d1434c950e67dade5e27ab00f.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -155,6 +150,12 @@ ] }, "displayName": "aws-cdk-codepipeline-codecommit-codebuild" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/tree.json index d7ddec8f8395a..3839c31cc86b8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.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-codepipeline-codecommit-codebuild": { "id": "aws-cdk-codepipeline-codecommit-codebuild", "path": "aws-cdk-codepipeline-codecommit-codebuild", @@ -30,13 +22,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.CfnRepository", + "fqn": "aws-cdk-lib.aws_codecommit.CfnRepository", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.Repository", + "fqn": "aws-cdk-lib.aws_codecommit.Repository", "version": "0.0.0" } }, @@ -48,6 +40,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-codecommit-codebuild/MyBuildProject/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codecommit-codebuild/MyBuildProject/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit-codebuild/MyBuildProject/Role/Resource", @@ -69,7 +69,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -231,19 +231,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -256,6 +256,15 @@ "artifacts": { "type": "CODEPIPELINE" }, + "cache": { + "type": "NO_CACHE" + }, + "encryptionKey": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + }, "environment": { "type": "LINUX_CONTAINER", "image": "aws/codebuild/standard:1.0", @@ -271,26 +280,17 @@ }, "source": { "type": "CODEPIPELINE" - }, - "cache": { - "type": "NO_CACHE" - }, - "encryptionKey": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.CfnProject", + "fqn": "aws-cdk-lib.aws_codebuild.CfnProject", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.PipelineProject", + "fqn": "aws-cdk-lib.aws_codebuild.PipelineProject", "version": "0.0.0" } }, @@ -339,13 +339,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnKey", + "fqn": "aws-cdk-lib.aws_kms.CfnKey", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Key", + "fqn": "aws-cdk-lib.aws_kms.Key", "version": "0.0.0" } }, @@ -369,13 +369,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnAlias", + "fqn": "aws-cdk-lib.aws_kms.CfnAlias", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Alias", + "fqn": "aws-cdk-lib.aws_kms.Alias", "version": "0.0.0" } }, @@ -413,7 +413,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } }, @@ -472,19 +472,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -492,6 +492,14 @@ "id": "Role", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/Role/Resource", @@ -513,7 +521,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -618,19 +626,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -640,6 +648,21 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "encryptionKey": { + "type": "KMS", + "id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + }, "roleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -670,7 +693,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": true }, "runOrder": 1, @@ -746,26 +769,11 @@ } ] } - ], - "artifactStore": { - "type": "S3", - "location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "encryptionKey": { - "type": "KMS", - "id": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - } - } - } + ] } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.CfnPipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", "version": "0.0.0" } }, @@ -781,6 +789,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/source/source/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/source/source/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/source/source/CodePipelineActionRole/Resource", @@ -817,7 +833,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -914,32 +930,32 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "build": { @@ -954,6 +970,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/build/build/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/build/build/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/build/build/CodePipelineActionRole/Resource", @@ -990,7 +1014,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -1032,26 +1056,26 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "test": { @@ -1062,6 +1086,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/build/test/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/build/test/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit-codebuild/Pipeline/build/test/CodePipelineActionRole/Resource", @@ -1098,7 +1130,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -1140,50 +1172,74 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.Pipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-codepipeline-codecommit-codebuild/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-codepipeline-codecommit-codebuild/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json new file mode 100644 index 0000000000000..2220abb680bef --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.assets.json new file mode 100644 index 0000000000000..12d879c9e6f60 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "81579280bbd9d63d4651dc48fa99b7489d144a1259358e9aa0fca17cf7815747": { + "source": { + "path": "aws-cdk-codepipeline-codecommit-main.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "81579280bbd9d63d4651dc48fa99b7489d144a1259358e9aa0fca17cf7815747.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-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.template.json new file mode 100644 index 0000000000000..509c54d321d23 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/aws-cdk-codepipeline-codecommit-main.template.json @@ -0,0 +1,635 @@ +{ + "Resources": { + "MyRepoF4F48043": { + "Type": "AWS::CodeCommit::Repository", + "Properties": { + "RepositoryName": "my-repo" + } + }, + "MyRepoawscdkcodepipelinecodecommitmainPipelineF8D5F90EEventRuleE781B91A": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventPattern": { + "source": [ + "aws.codecommit" + ], + "resources": [ + { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Arn" + ] + } + ], + "detail-type": [ + "CodeCommit Repository State Change" + ], + "detail": { + "event": [ + "referenceCreated", + "referenceUpdated" + ], + "referenceName": [ + "main" + ] + } + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codepipeline:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "PipelineC660917D" + } + ] + ] + }, + "Id": "Target0", + "RoleArn": { + "Fn::GetAtt": [ + "PipelineEventsRole46BEEA7C", + "Arn" + ] + } + } + ] + } + }, + "PipelineArtifactsBucketEncryptionKey01D58D69": { + "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" + }, + "PipelineArtifactsBucketEncryptionKeyAlias5C510EEE": { + "Type": "AWS::KMS::Alias", + "Properties": { + "AliasName": "alias/codepipeline-aws-cdk-codepipeline-codecommit-main-pipeline-f8d5f90e", + "TargetKeyId": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "PipelineArtifactsBucket22248F97": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketEncryption": { + "ServerSideEncryptionConfiguration": [ + { + "ServerSideEncryptionByDefault": { + "KMSMasterKeyID": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + }, + "SSEAlgorithm": "aws:kms" + } + } + ] + }, + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "PipelineArtifactsBucketPolicyD4F9712A": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineRoleD68726F7": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codepipeline.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineRoleDefaultPolicyC7A05455": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelinebuildmanualCodePipelineActionRoleE3306AB0", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineRoleDefaultPolicyC7A05455", + "Roles": [ + { + "Ref": "PipelineRoleD68726F7" + } + ] + } + }, + "PipelineC660917D": { + "Type": "AWS::CodePipeline::Pipeline", + "Properties": { + "ArtifactStore": { + "EncryptionKey": { + "Id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + }, + "Type": "KMS" + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" + }, + "RoleArn": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + }, + "Stages": [ + { + "Actions": [ + { + "ActionTypeId": { + "Category": "Source", + "Owner": "AWS", + "Provider": "CodeCommit", + "Version": "1" + }, + "Configuration": { + "RepositoryName": { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Name" + ] + }, + "BranchName": "main", + "PollForSourceChanges": false + }, + "Name": "source", + "OutputArtifacts": [ + { + "Name": "SourceArtifact" + } + ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + }, + "RunOrder": 1 + } + ], + "Name": "source" + }, + { + "Actions": [ + { + "ActionTypeId": { + "Category": "Approval", + "Owner": "AWS", + "Provider": "Manual", + "Version": "1" + }, + "Name": "manual", + "RoleArn": { + "Fn::GetAtt": [ + "PipelinebuildmanualCodePipelineActionRoleE3306AB0", + "Arn" + ] + }, + "RunOrder": 1 + } + ], + "Name": "build" + } + ] + }, + "DependsOn": [ + "PipelineRoleDefaultPolicyC7A05455", + "PipelineRoleD68726F7" + ] + }, + "PipelinesourceCodePipelineActionRoleB7E0306A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:CancelUploadArchive", + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:GetUploadArchiveStatus", + "codecommit:UploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83", + "Roles": [ + { + "Ref": "PipelinesourceCodePipelineActionRoleB7E0306A" + } + ] + } + }, + "PipelineEventsRole46BEEA7C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineEventsRoleDefaultPolicyFF4FCCE0": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "codepipeline:StartPipelineExecution", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codepipeline:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "PipelineC660917D" + } + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineEventsRoleDefaultPolicyFF4FCCE0", + "Roles": [ + { + "Ref": "PipelineEventsRole46BEEA7C" + } + ] + } + }, + "PipelinebuildmanualCodePipelineActionRoleE3306AB0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + } + }, + "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-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/integ.json new file mode 100644 index 0000000000000..ab6e77dca5865 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "IntegTest/DefaultTest": { + "stacks": [ + "aws-cdk-codepipeline-codecommit-main" + ], + "assertionStack": "IntegTest/DefaultTest/DeployAssert", + "assertionStackName": "IntegTestDefaultTestDeployAssertE3E7D2A4" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/manifest.json new file mode 100644 index 0000000000000..46d36ab713f03 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/manifest.json @@ -0,0 +1,200 @@ +{ + "version": "34.0.0", + "artifacts": { + "aws-cdk-codepipeline-codecommit-main.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-codepipeline-codecommit-main.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-codepipeline-codecommit-main": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-codepipeline-codecommit-main.template.json", + "terminationProtection": false, + "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}/81579280bbd9d63d4651dc48fa99b7489d144a1259358e9aa0fca17cf7815747.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-codepipeline-codecommit-main.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-codepipeline-codecommit-main.assets" + ], + "metadata": { + "/aws-cdk-codepipeline-codecommit-main/MyRepo/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRepoF4F48043" + } + ], + "/aws-cdk-codepipeline-codecommit-main/MyRepo/awscdkcodepipelinecodecommitmainPipelineF8D5F90EEventRule/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRepoawscdkcodepipelinecodecommitmainPipelineF8D5F90EEventRuleE781B91A" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucketEncryptionKey/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineArtifactsBucketEncryptionKey01D58D69" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucketEncryptionKeyAlias/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineArtifactsBucketEncryptionKeyAlias5C510EEE" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucket/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineArtifactsBucket22248F97" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucket/Policy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineArtifactsBucketPolicyD4F9712A" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineRoleD68726F7" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineRoleDefaultPolicyC7A05455" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineC660917D" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/source/source/CodePipelineActionRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelinesourceCodePipelineActionRoleB7E0306A" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/source/source/CodePipelineActionRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/EventsRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineEventsRole46BEEA7C" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/EventsRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelineEventsRoleDefaultPolicyFF4FCCE0" + } + ], + "/aws-cdk-codepipeline-codecommit-main/Pipeline/build/manual/CodePipelineActionRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PipelinebuildmanualCodePipelineActionRoleE3306AB0" + } + ], + "/aws-cdk-codepipeline-codecommit-main/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-codepipeline-codecommit-main/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ], + "MyRepoawscdkcodepipelinecodecommitmainPipelineF8D5F90EmasterEventRule28CC1190": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRepoawscdkcodepipelinecodecommitmainPipelineF8D5F90EmasterEventRule28CC1190", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ] + }, + "displayName": "aws-cdk-codepipeline-codecommit-main" + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "metadata": { + "/IntegTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "IntegTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/tree.json new file mode 100644 index 0000000000000..ef21cb837640b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.js.snapshot/tree.json @@ -0,0 +1,1012 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-codepipeline-codecommit-main": { + "id": "aws-cdk-codepipeline-codecommit-main", + "path": "aws-cdk-codepipeline-codecommit-main", + "children": { + "MyRepo": { + "id": "MyRepo", + "path": "aws-cdk-codepipeline-codecommit-main/MyRepo", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/MyRepo/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeCommit::Repository", + "aws:cdk:cloudformation:props": { + "repositoryName": "my-repo" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codecommit.CfnRepository", + "version": "0.0.0" + } + }, + "awscdkcodepipelinecodecommitmainPipelineF8D5F90EEventRule": { + "id": "awscdkcodepipelinecodecommitmainPipelineF8D5F90EEventRule", + "path": "aws-cdk-codepipeline-codecommit-main/MyRepo/awscdkcodepipelinecodecommitmainPipelineF8D5F90EEventRule", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/MyRepo/awscdkcodepipelinecodecommitmainPipelineF8D5F90EEventRule/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Events::Rule", + "aws:cdk:cloudformation:props": { + "eventPattern": { + "source": [ + "aws.codecommit" + ], + "resources": [ + { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Arn" + ] + } + ], + "detail-type": [ + "CodeCommit Repository State Change" + ], + "detail": { + "event": [ + "referenceCreated", + "referenceUpdated" + ], + "referenceName": [ + "main" + ] + } + }, + "state": "ENABLED", + "targets": [ + { + "id": "Target0", + "arn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codepipeline:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "PipelineC660917D" + } + ] + ] + }, + "roleArn": { + "Fn::GetAtt": [ + "PipelineEventsRole46BEEA7C", + "Arn" + ] + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_events.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_events.Rule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codecommit.Repository", + "version": "0.0.0" + } + }, + "Pipeline": { + "id": "Pipeline", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline", + "children": { + "ArtifactsBucketEncryptionKey": { + "id": "ArtifactsBucketEncryptionKey", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucketEncryptionKey", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucketEncryptionKey/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KMS::Key", + "aws:cdk:cloudformation:props": { + "keyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.CfnKey", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.Key", + "version": "0.0.0" + } + }, + "ArtifactsBucketEncryptionKeyAlias": { + "id": "ArtifactsBucketEncryptionKeyAlias", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucketEncryptionKeyAlias", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucketEncryptionKeyAlias/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KMS::Alias", + "aws:cdk:cloudformation:props": { + "aliasName": "alias/codepipeline-aws-cdk-codepipeline-codecommit-main-pipeline-f8d5f90e", + "targetKeyId": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.CfnAlias", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.Alias", + "version": "0.0.0" + } + }, + "ArtifactsBucket": { + "id": "ArtifactsBucket", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucket", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucket/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "bucketEncryption": { + "serverSideEncryptionConfiguration": [ + { + "serverSideEncryptionByDefault": { + "sseAlgorithm": "aws:kms", + "kmsMasterKeyId": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + } + ] + }, + "publicAccessBlockConfiguration": { + "blockPublicAcls": true, + "blockPublicPolicy": true, + "ignorePublicAcls": true, + "restrictPublicBuckets": true + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + }, + "Policy": { + "id": "Policy", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucket/Policy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/ArtifactsBucket/Policy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy", + "aws:cdk:cloudformation:props": { + "bucket": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "policyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codepipeline.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelinebuildmanualCodePipelineActionRoleE3306AB0", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "policyName": "PipelineRoleDefaultPolicyC7A05455", + "roles": [ + { + "Ref": "PipelineRoleD68726F7" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", + "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "encryptionKey": { + "type": "KMS", + "id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + }, + "roleArn": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + }, + "stages": [ + { + "name": "source", + "actions": [ + { + "name": "source", + "outputArtifacts": [ + { + "name": "SourceArtifact" + } + ], + "actionTypeId": { + "category": "Source", + "version": "1", + "owner": "AWS", + "provider": "CodeCommit" + }, + "configuration": { + "RepositoryName": { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Name" + ] + }, + "BranchName": "main", + "PollForSourceChanges": false + }, + "runOrder": 1, + "roleArn": { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + } + } + ] + }, + { + "name": "build", + "actions": [ + { + "name": "manual", + "actionTypeId": { + "category": "Approval", + "version": "1", + "owner": "AWS", + "provider": "Manual" + }, + "runOrder": 1, + "roleArn": { + "Fn::GetAtt": [ + "PipelinebuildmanualCodePipelineActionRoleE3306AB0", + "Arn" + ] + } + } + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", + "version": "0.0.0" + } + }, + "source": { + "id": "source", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/source", + "children": { + "source": { + "id": "source", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/source/source", + "children": { + "CodePipelineActionRole": { + "id": "CodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/source/source/CodePipelineActionRole", + "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/source/source/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/source/source/CodePipelineActionRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/source/source/CodePipelineActionRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/source/source/CodePipelineActionRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:CancelUploadArchive", + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:GetUploadArchiveStatus", + "codecommit:UploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83", + "roles": [ + { + "Ref": "PipelinesourceCodePipelineActionRoleB7E0306A" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "EventsRole": { + "id": "EventsRole", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/EventsRole", + "children": { + "ImportEventsRole": { + "id": "ImportEventsRole", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/EventsRole/ImportEventsRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/EventsRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/EventsRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/EventsRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "codepipeline:StartPipelineExecution", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codepipeline:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "PipelineC660917D" + } + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "PipelineEventsRoleDefaultPolicyFF4FCCE0", + "roles": [ + { + "Ref": "PipelineEventsRole46BEEA7C" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "build": { + "id": "build", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/build", + "children": { + "manual": { + "id": "manual", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/build/manual", + "children": { + "CodePipelineActionRole": { + "id": "CodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/build/manual/CodePipelineActionRole", + "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/build/manual/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-codecommit-main/Pipeline/build/manual/CodePipelineActionRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-codepipeline-codecommit-main/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-codepipeline-codecommit-main/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "IntegTest": { + "id": "IntegTest", + "path": "IntegTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "IntegTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "IntegTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "IntegTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.ts new file mode 100644 index 0000000000000..6a2f137cb3864 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit-main.ts @@ -0,0 +1,40 @@ +import * as codecommit from 'aws-cdk-lib/aws-codecommit'; +import * as codepipeline from 'aws-cdk-lib/aws-codepipeline'; +import * as cdk from 'aws-cdk-lib'; +import * as cpactions from 'aws-cdk-lib/aws-codepipeline-actions'; +import { CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME } from 'aws-cdk-lib/cx-api'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; + +const defaultBranchFeatureFlag = { [CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME]: true }; +const app = new cdk.App({ postCliContext: defaultBranchFeatureFlag }); + +const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-codecommit-main'); + +const repo = new codecommit.Repository(stack, 'MyRepo', { + repositoryName: 'my-repo', +}); + +new codepipeline.Pipeline(stack, 'Pipeline', { + stages: [ + { + stageName: 'source', + actions: [ + new cpactions.CodeCommitSourceAction({ + actionName: 'source', + repository: repo, + output: new codepipeline.Artifact('SourceArtifact'), + }), + ], + }, + { + stageName: 'build', + actions: [ + new cpactions.ManualApprovalAction({ actionName: 'manual' }), + ], + }, + ], +}); + +new IntegTest(app, 'IntegTest', { + testCases: [stack], +}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.assets.json index 9210f8211d76d..9f4a73cecf92e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "34.0.0", "files": { - "79da7abe8282847647ae0b797c0e1e2759697fd91a9f11ec38d85a62f3ecb314": { + "0d8f63248f385d0c5c933c0e8bf4793b403ebc2c7aeecaa9e3287b6e33601ace": { "source": { "path": "aws-cdk-codepipeline-codecommit.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "79da7abe8282847647ae0b797c0e1e2759697fd91a9f11ec38d85a62f3ecb314.json", + "objectKey": "0d8f63248f385d0c5c933c0e8bf4793b403ebc2c7aeecaa9e3287b6e33601ace.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.template.json index 6a88f7d4af098..b8f9a2d9a7c1f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/aws-cdk-codepipeline-codecommit.template.json @@ -302,6 +302,21 @@ "PipelineC660917D": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { + "ArtifactStore": { + "EncryptionKey": { + "Id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + }, + "Type": "KMS" + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" + }, "RoleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -366,22 +381,7 @@ ], "Name": "build" } - ], - "ArtifactStore": { - "EncryptionKey": { - "Id": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - }, - "Type": "KMS" - }, - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3" - } + ] }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/cdk.out index 8ecc185e9dbee..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"21.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/integ.json index a0ec48fbc1144..b92f80c20d07c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "34.0.0", "testCases": { "integ.pipeline-code-commit": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/manifest.json index bbd053fce825e..62604c69be5b5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "34.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-codepipeline-codecommit.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-codepipeline-codecommit.template.json", + "terminationProtection": false, "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}/79da7abe8282847647ae0b797c0e1e2759697fd91a9f11ec38d85a62f3ecb314.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/0d8f63248f385d0c5c933c0e8bf4793b403ebc2c7aeecaa9e3287b6e33601ace.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -137,6 +132,12 @@ ] }, "displayName": "aws-cdk-codepipeline-codecommit" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/tree.json index ff9e699da1a7d..dbf15713bcd71 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.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-codepipeline-codecommit": { "id": "aws-cdk-codepipeline-codecommit", "path": "aws-cdk-codepipeline-codecommit", @@ -30,8 +22,8 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.CfnRepository", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "awscdkcodepipelinecodecommitPipelineF780CA18EventRule": { @@ -107,20 +99,20 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.CfnRule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.Rule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.Repository", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Pipeline": { @@ -168,14 +160,14 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnKey", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Key", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "ArtifactsBucketEncryptionKeyAlias": { @@ -198,14 +190,14 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnAlias", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Alias", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "ArtifactsBucket": { @@ -242,8 +234,8 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Policy": { @@ -301,26 +293,34 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Role": { "id": "Role", "path": "aws-cdk-codepipeline-codecommit/Pipeline/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-codecommit/Pipeline/Role/ImportRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit/Pipeline/Role/Resource", @@ -342,8 +342,8 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "DefaultPolicy": { @@ -441,20 +441,20 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Resource": { @@ -463,6 +463,21 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "encryptionKey": { + "type": "KMS", + "id": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + }, "roleArn": { "Fn::GetAtt": [ "PipelineRoleD68726F7", @@ -527,27 +542,12 @@ } ] } - ], - "artifactStore": { - "type": "S3", - "location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "encryptionKey": { - "type": "KMS", - "id": { - "Fn::GetAtt": [ - "PipelineArtifactsBucketEncryptionKey01D58D69", - "Arn" - ] - } - } - } + ] } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.CfnPipeline", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "source": { @@ -562,6 +562,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-codecommit/Pipeline/source/source/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit/Pipeline/source/source/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit/Pipeline/source/source/CodePipelineActionRole/Resource", @@ -598,8 +606,8 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "DefaultPolicy": { @@ -695,38 +703,46 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "EventsRole": { "id": "EventsRole", "path": "aws-cdk-codepipeline-codecommit/Pipeline/EventsRole", "children": { + "ImportEventsRole": { + "id": "ImportEventsRole", + "path": "aws-cdk-codepipeline-codecommit/Pipeline/EventsRole/ImportEventsRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit/Pipeline/EventsRole/Resource", @@ -748,8 +764,8 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "DefaultPolicy": { @@ -803,20 +819,20 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "build": { @@ -831,6 +847,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-codepipeline-codecommit/Pipeline/build/manual/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-codecommit/Pipeline/build/manual/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-codepipeline-codecommit/Pipeline/build/manual/CodePipelineActionRole/Resource", @@ -867,44 +891,68 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.Pipeline", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-codepipeline-codecommit/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-codepipeline-codecommit/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts index 7aabb4641a7da..c8478fae239f0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts @@ -2,8 +2,12 @@ import * as codecommit from 'aws-cdk-lib/aws-codecommit'; import * as codepipeline from 'aws-cdk-lib/aws-codepipeline'; import * as cdk from 'aws-cdk-lib'; import * as cpactions from 'aws-cdk-lib/aws-codepipeline-actions'; +import { CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME } from 'aws-cdk-lib/cx-api'; -const app = new cdk.App(); +const defaultBranchFeatureFlag = { [CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME]: false }; +const app = new cdk.App({ + postCliContext: defaultBranchFeatureFlag, +}); const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-codecommit'); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.assets.json index ef98d078f9e36..cbfdff0132cfa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "34.0.0", "files": { - "6f6e8ce8b267f72916a2fc862cccb29b1394eb307a2a265fadd3c0bceda1de4d": { + "b59fd597c82ae628aaec6146f67bab41da24a55bccaac46bcbcb666c89f083bf": { "source": { "path": "aws-cdk-pipeline-event-target.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "6f6e8ce8b267f72916a2fc862cccb29b1394eb307a2a265fadd3c0bceda1de4d.json", + "objectKey": "b59fd597c82ae628aaec6146f67bab41da24a55bccaac46bcbcb666c89f083bf.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.template.json index ca0a6faba2e5e..8c0a96dacfa2c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/aws-cdk-pipeline-event-target.template.json @@ -231,6 +231,21 @@ "MyPipelineAED38ECF": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { + "ArtifactStore": { + "EncryptionKey": { + "Id": { + "Fn::GetAtt": [ + "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", + "Arn" + ] + }, + "Type": "KMS" + }, + "Location": { + "Ref": "MyPipelineArtifactsBucket727923DD" + }, + "Type": "S3" + }, "RoleArn": { "Fn::GetAtt": [ "MyPipelineRoleC0D47CA4", @@ -254,7 +269,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": true }, "Name": "CodeCommitSource", @@ -310,22 +325,7 @@ ], "Name": "Build" } - ], - "ArtifactStore": { - "EncryptionKey": { - "Id": { - "Fn::GetAtt": [ - "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", - "Arn" - ] - }, - "Type": "KMS" - }, - "Location": { - "Ref": "MyPipelineArtifactsBucket727923DD" - }, - "Type": "S3" - } + ] }, "DependsOn": [ "MyPipelineRoleDefaultPolicy34F09EFA", @@ -830,6 +830,15 @@ "Artifacts": { "Type": "CODEPIPELINE" }, + "Cache": { + "Type": "NO_CACHE" + }, + "EncryptionKey": { + "Fn::GetAtt": [ + "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", + "Arn" + ] + }, "Environment": { "ComputeType": "BUILD_GENERAL1_SMALL", "Image": "aws/codebuild/standard:1.0", @@ -845,15 +854,6 @@ }, "Source": { "Type": "CODEPIPELINE" - }, - "Cache": { - "Type": "NO_CACHE" - }, - "EncryptionKey": { - "Fn::GetAtt": [ - "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", - "Arn" - ] } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/cdk.out index 8ecc185e9dbee..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"21.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/integ.json index 1f7fe7a2a53e4..730b8b4662be0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "34.0.0", "testCases": { "integ.pipeline-events": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/manifest.json index cce8c428fa803..58d1dfba74895 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "34.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-pipeline-event-target.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-pipeline-event-target.template.json", + "terminationProtection": false, "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}/6f6e8ce8b267f72916a2fc862cccb29b1394eb307a2a265fadd3c0bceda1de4d.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b59fd597c82ae628aaec6146f67bab41da24a55bccaac46bcbcb666c89f083bf.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -173,6 +168,12 @@ ] }, "displayName": "aws-cdk-pipeline-event-target" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/tree.json index 2b29919288e94..7f1d9e536b2f1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-events.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-pipeline-event-target": { "id": "aws-cdk-pipeline-event-target", "path": "aws-cdk-pipeline-event-target", @@ -61,13 +53,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnKey", + "fqn": "aws-cdk-lib.aws_kms.CfnKey", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Key", + "fqn": "aws-cdk-lib.aws_kms.Key", "version": "0.0.0" } }, @@ -91,13 +83,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnAlias", + "fqn": "aws-cdk-lib.aws_kms.CfnAlias", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Alias", + "fqn": "aws-cdk-lib.aws_kms.Alias", "version": "0.0.0" } }, @@ -135,7 +127,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } }, @@ -194,19 +186,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -214,6 +206,14 @@ "id": "Role", "path": "aws-cdk-pipeline-event-target/MyPipeline/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-pipeline-event-target/MyPipeline/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-pipeline-event-target/MyPipeline/Role/Resource", @@ -235,7 +235,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -334,19 +334,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -356,6 +356,21 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "MyPipelineArtifactsBucket727923DD" + }, + "encryptionKey": { + "type": "KMS", + "id": { + "Fn::GetAtt": [ + "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", + "Arn" + ] + } + } + }, "roleArn": { "Fn::GetAtt": [ "MyPipelineRoleC0D47CA4", @@ -386,7 +401,7 @@ "Name" ] }, - "BranchName": "master", + "BranchName": "main", "PollForSourceChanges": true }, "runOrder": 1, @@ -435,26 +450,11 @@ } ] } - ], - "artifactStore": { - "type": "S3", - "location": { - "Ref": "MyPipelineArtifactsBucket727923DD" - }, - "encryptionKey": { - "type": "KMS", - "id": { - "Fn::GetAtt": [ - "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", - "Arn" - ] - } - } - } + ] } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.CfnPipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", "version": "0.0.0" } }, @@ -470,6 +470,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-pipeline-event-target/MyPipeline/Source/CodeCommitSource/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-pipeline-event-target/MyPipeline/Source/CodeCommitSource/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-pipeline-event-target/MyPipeline/Source/CodeCommitSource/CodePipelineActionRole/Resource", @@ -506,7 +514,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -603,19 +611,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -685,20 +693,20 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.CfnRule", + "fqn": "aws-cdk-lib.aws_events.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.Rule", + "fqn": "aws-cdk-lib.aws_events.Rule", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "OnSourceStateChange": { @@ -761,20 +769,20 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.CfnRule", + "fqn": "aws-cdk-lib.aws_events.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.Rule", + "fqn": "aws-cdk-lib.aws_events.Rule", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "Build": { @@ -789,6 +797,14 @@ "id": "CodePipelineActionRole", "path": "aws-cdk-pipeline-event-target/MyPipeline/Build/CodeBuildAction/CodePipelineActionRole", "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-pipeline-event-target/MyPipeline/Build/CodeBuildAction/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-pipeline-event-target/MyPipeline/Build/CodeBuildAction/CodePipelineActionRole/Resource", @@ -825,7 +841,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -867,32 +883,32 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } }, "OnPipelineStateChange": { @@ -957,19 +973,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.CfnRule", + "fqn": "aws-cdk-lib.aws_events.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-events.Rule", + "fqn": "aws-cdk-lib.aws_events.Rule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.Pipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", "version": "0.0.0" } }, @@ -987,13 +1003,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.CfnRepository", + "fqn": "aws-cdk-lib.aws_codecommit.CfnRepository", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codecommit.Repository", + "fqn": "aws-cdk-lib.aws_codecommit.Repository", "version": "0.0.0" } }, @@ -1005,6 +1021,14 @@ "id": "Role", "path": "aws-cdk-pipeline-event-target/BuildProject/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-pipeline-event-target/BuildProject/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-pipeline-event-target/BuildProject/Role/Resource", @@ -1026,7 +1050,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -1164,19 +1188,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -1189,6 +1213,15 @@ "artifacts": { "type": "CODEPIPELINE" }, + "cache": { + "type": "NO_CACHE" + }, + "encryptionKey": { + "Fn::GetAtt": [ + "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", + "Arn" + ] + }, "environment": { "type": "LINUX_CONTAINER", "image": "aws/codebuild/standard:1.0", @@ -1204,26 +1237,17 @@ }, "source": { "type": "CODEPIPELINE" - }, - "cache": { - "type": "NO_CACHE" - }, - "encryptionKey": { - "Fn::GetAtt": [ - "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", - "Arn" - ] } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.CfnProject", + "fqn": "aws-cdk-lib.aws_codebuild.CfnProject", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codebuild.PipelineProject", + "fqn": "aws-cdk-lib.aws_codebuild.PipelineProject", "version": "0.0.0" } }, @@ -1239,7 +1263,7 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-sns.CfnTopic", + "fqn": "aws-cdk-lib.aws_sns.CfnTopic", "version": "0.0.0" } }, @@ -1277,32 +1301,56 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-sns.CfnTopicPolicy", + "fqn": "aws-cdk-lib.aws_sns.CfnTopicPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-sns.TopicPolicy", + "fqn": "aws-cdk-lib.aws_sns.TopicPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-sns.Topic", + "fqn": "aws-cdk-lib.aws_sns.Topic", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-pipeline-event-target/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-pipeline-event-target/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md index c410cfc629cc9..95817e6176cb4 100644 --- a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md +++ b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md @@ -62,6 +62,7 @@ Flags come in three types: | [@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier](#aws-cdkaws-appsyncusearnforsourceapiassociationidentifier) | When enabled, will always use the arn for identifiers for CfnSourceApiAssociation in the GraphqlApi construct rather than id. | 2.97.0 | (fix) | | [@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters](#aws-cdkaws-rdsauroraclusterchangescopeofinstanceparametergroupwitheachparameters) | When enabled, a scope of InstanceParameterGroup for AuroraClusterInstance with each parameters will change. | 2.97.0 | (fix) | | [@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials](#aws-cdkaws-rdspreventrenderingdeprecatedcredentials) | When enabled, creating an RDS database cluster from a snapshot will only render credentials for snapshot credentials. | 2.98.0 | (fix) | +| [@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource](#aws-cdkaws-codepipeline-actionsusenewdefaultbranchforcodecommitsource) | When enabled, the CodeCommit source action is using the default branch name 'main'. | 2.103.1 | (fix) | @@ -114,7 +115,8 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, - "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true } } ``` @@ -1176,4 +1178,19 @@ database cluster from a snapshot. | 2.98.0 | `false` | `true` | +### @aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource + +*When enabled, the CodeCommit source action is using the default branch name 'main'.* (fix) + +When setting up a CodeCommit source action for the source stage of a pipeline, please note that the +default branch is 'master'. +However, with the activation of this feature flag, the default branch is updated to 'main'. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| 2.103.1 | `false` | `true` | + + diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/codecommit/source-action.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/codecommit/source-action.ts index 2c4a96cacbad7..92ce94736911f 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/codecommit/source-action.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/codecommit/source-action.ts @@ -3,7 +3,8 @@ import * as codecommit from '../../../aws-codecommit'; import * as codepipeline from '../../../aws-codepipeline'; import * as targets from '../../../aws-events-targets'; import * as iam from '../../../aws-iam'; -import { Names, Stack, Token, TokenComparison } from '../../../core'; +import { FeatureFlags, Names, Stack, Token, TokenComparison } from '../../../core'; +import { CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME } from '../../../cx-api'; import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; @@ -121,12 +122,14 @@ export class CodeCommitSourceAction extends Action { * @internal */ public static readonly _FULL_CLONE_ARN_PROPERTY = 'CodeCommitCloneRepositoryArn'; + private static readonly NEW_DEFAULT_BRANCH_NAME = 'main'; + private static readonly OLD_DEFAULT_BRANCH_NAME = 'master'; private readonly branch: string; private readonly props: CodeCommitSourceActionProps; constructor(props: CodeCommitSourceActionProps) { - const branch = props.branch ?? 'master'; + const branch = props.branch ?? CodeCommitSourceAction.OLD_DEFAULT_BRANCH_NAME; if (!branch) { throw new Error("'branch' parameter cannot be an empty string"); } @@ -162,6 +165,8 @@ export class CodeCommitSourceAction extends Action { protected bound(_scope: Construct, stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig { + const branchOrDefault = this.getBranchOrDefault(_scope); + const createEvent = this.props.trigger === undefined || this.props.trigger === CodeCommitTrigger.EVENTS; if (createEvent) { @@ -170,7 +175,7 @@ export class CodeCommitSourceAction extends Action { target: new targets.CodePipeline(stage.pipeline, { eventRole: this.props.eventRole, }), - branches: [this.branch], + branches: [branchOrDefault], crossStackScope: stage.pipeline as unknown as Construct, }); } @@ -200,7 +205,7 @@ export class CodeCommitSourceAction extends Action { return { configuration: { RepositoryName: this.props.repository.repositoryName, - BranchName: this.branch, + BranchName: branchOrDefault, PollForSourceChanges: this.props.trigger === CodeCommitTrigger.POLL, OutputArtifactFormat: this.props.codeBuildCloneOutput === true ? 'CODEBUILD_CLONE_REF' @@ -209,6 +214,13 @@ export class CodeCommitSourceAction extends Action { }; } + private getBranchOrDefault(scope: Construct) { + const defaultBranch = FeatureFlags.of(scope).isEnabled(CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME) ? + CodeCommitSourceAction.NEW_DEFAULT_BRANCH_NAME : + CodeCommitSourceAction.OLD_DEFAULT_BRANCH_NAME; + return this.props.branch === undefined ? defaultBranch : this.branch; + } + private generateEventId(stage: codepipeline.IStage): string { const baseId = Names.nodeUniqueId(stage.pipeline.node); if (Token.isUnresolved(this.branch)) { @@ -220,7 +232,11 @@ export class CodeCommitSourceAction extends Action { } while (this.props.repository.node.tryFindChild(candidate) !== undefined); return candidate; } else { - const branchIdDisambiguator = this.branch === 'master' ? '' : `-${this.branch}-`; + // To not break backwards compatibility it needs to be checked if the branch was set to master or if no branch was provided + const branchIdDisambiguator = + this.props.branch === undefined || this.branch === CodeCommitSourceAction.OLD_DEFAULT_BRANCH_NAME + ? '' + : `-${this.branch}-`; return this.eventIdFromPrefix(`${baseId}${branchIdDisambiguator}`); } } diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/test/codecommit/codecommit-source-action.test.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/test/codecommit/codecommit-source-action.test.ts index b483270d960cb..1c8b9ac674fec 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/test/codecommit/codecommit-source-action.test.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/test/codecommit/codecommit-source-action.test.ts @@ -6,6 +6,7 @@ import * as iam from '../../../aws-iam'; import * as kms from '../../../aws-kms'; import * as s3 from '../../../aws-s3'; import { Stack, Lazy, App } from '../../../core'; +import { CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME } from '../../../cx-api'; import * as cpactions from '../../lib'; /* eslint-disable quote-props */ @@ -57,7 +58,11 @@ describe('CodeCommit Source Action', () => { { stageName: 'Build', actions: [ - new cpactions.CodeBuildAction({ actionName: 'Build', project: new codebuild.PipelineProject(targetStack, 'MyProject'), input: sourceOutput }), + new cpactions.CodeBuildAction({ + actionName: 'Build', + project: new codebuild.PipelineProject(targetStack, 'MyProject'), + input: sourceOutput, + }), ], }, ], @@ -591,6 +596,157 @@ describe('CodeCommit Source Action', () => { // By moving the Rule to pipeline's Stack, we get rid of the cycle. Template.fromStack(pipelineStack).resourceCountIs('AWS::Events::Rule', 1); }); + + test('using main as the default branch when feature flag is set', () => { + const defaultBranchFeatureFlag = { [CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME]: true }; + const app = new App({ context: defaultBranchFeatureFlag }); + + const repoStack = new Stack(app, 'RepositoryStack'); + const repo = new codecommit.Repository(repoStack, 'Repository', { + repositoryName: 'my-repo', + }); + + const pipelineStack = new Stack(app, 'PipelineStack'); + + const sourceOutput = new codepipeline.Artifact(); + new codepipeline.Pipeline(pipelineStack, 'Pipeline', { + stages: [ + { + stageName: 'Source', + actions: [ + new cpactions.CodeCommitSourceAction({ + actionName: 'Source', + repository: repo, + output: sourceOutput, + }), + ], + }, + { + stageName: 'Build', + actions: [ + new cpactions.CodeBuildAction({ + actionName: 'Build', + project: codebuild.Project.fromProjectName(pipelineStack, 'Project', 'my-project'), + input: sourceOutput, + }), + ], + }, + ], + }); + + const template = Template.fromStack(pipelineStack); + template.hasResourceProperties('AWS::CodePipeline::Pipeline', { + 'Stages': [ + { + 'Actions': [ + { + 'Configuration': { + 'BranchName': 'main', + }, + }, + ], + }, + {}, + ], + }); + template.hasResourceProperties('AWS::Events::Rule', { + 'EventPattern': { + 'source': [ + 'aws.codecommit', + ], + 'resources': [ + {}, + ], + 'detail-type': [ + 'CodeCommit Repository State Change', + ], + 'detail': { + 'event': [ + 'referenceCreated', + 'referenceUpdated', + ], + 'referenceName': [ + 'main', + ], + }, + }, + }); + }); + + test('using master as the default branch when feature flag is not set', () => { + const app = new App(); + + const repoStack = new Stack(app, 'RepositoryStack'); + const repo = new codecommit.Repository(repoStack, 'Repository', { + repositoryName: 'my-repo', + }); + + const pipelineStack = new Stack(app, 'PipelineStack'); + + const sourceOutput = new codepipeline.Artifact(); + new codepipeline.Pipeline(pipelineStack, 'Pipeline', { + stages: [ + { + stageName: 'Source', + actions: [ + new cpactions.CodeCommitSourceAction({ + actionName: 'Source', + repository: repo, + output: sourceOutput, + }), + ], + }, + { + stageName: 'Build', + actions: [ + new cpactions.CodeBuildAction({ + actionName: 'Build', + project: codebuild.Project.fromProjectName(pipelineStack, 'Project', 'my-project'), + input: sourceOutput, + }), + ], + }, + ], + }); + + const template = Template.fromStack(pipelineStack); + template.hasResourceProperties('AWS::CodePipeline::Pipeline', { + 'Stages': [ + { + 'Actions': [ + { + 'Configuration': { + 'BranchName': 'master', + }, + }, + ], + }, + {}, + ], + }); + template.hasResourceProperties('AWS::Events::Rule', { + 'EventPattern': { + 'source': [ + 'aws.codecommit', + ], + 'resources': [ + {}, + ], + 'detail-type': [ + 'CodeCommit Repository State Change', + ], + 'detail': { + 'event': [ + 'referenceCreated', + 'referenceUpdated', + ], + 'referenceName': [ + 'master', + ], + }, + }, + }); + }); }); }); diff --git a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md index c410cfc629cc9..95817e6176cb4 100644 --- a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +++ b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md @@ -62,6 +62,7 @@ Flags come in three types: | [@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier](#aws-cdkaws-appsyncusearnforsourceapiassociationidentifier) | When enabled, will always use the arn for identifiers for CfnSourceApiAssociation in the GraphqlApi construct rather than id. | 2.97.0 | (fix) | | [@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters](#aws-cdkaws-rdsauroraclusterchangescopeofinstanceparametergroupwitheachparameters) | When enabled, a scope of InstanceParameterGroup for AuroraClusterInstance with each parameters will change. | 2.97.0 | (fix) | | [@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials](#aws-cdkaws-rdspreventrenderingdeprecatedcredentials) | When enabled, creating an RDS database cluster from a snapshot will only render credentials for snapshot credentials. | 2.98.0 | (fix) | +| [@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource](#aws-cdkaws-codepipeline-actionsusenewdefaultbranchforcodecommitsource) | When enabled, the CodeCommit source action is using the default branch name 'main'. | 2.103.1 | (fix) | @@ -114,7 +115,8 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, - "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true } } ``` @@ -1176,4 +1178,19 @@ database cluster from a snapshot. | 2.98.0 | `false` | `true` | +### @aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource + +*When enabled, the CodeCommit source action is using the default branch name 'main'.* (fix) + +When setting up a CodeCommit source action for the source stage of a pipeline, please note that the +default branch is 'master'. +However, with the activation of this feature flag, the default branch is updated to 'main'. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| 2.103.1 | `false` | `true` | + + diff --git a/packages/aws-cdk-lib/cx-api/README.md b/packages/aws-cdk-lib/cx-api/README.md index 59c3d703ddeeb..f25b78a5e6a26 100644 --- a/packages/aws-cdk-lib/cx-api/README.md +++ b/packages/aws-cdk-lib/cx-api/README.md @@ -223,3 +223,21 @@ _cdk.json_ } } ``` + +* `@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource` + +Enable this feature flag to update the default branch for CodeCommit source actions to `main`. + +Previously, the default branch for CodeCommit source actions was set to `master`. +However, this convention is no longer supported, and repositories created after March 2021 now have `main` as +their default branch. + +_cdk.json_ + +```json +{ + "context": { + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true + } +} +``` diff --git a/packages/aws-cdk-lib/cx-api/lib/features.ts b/packages/aws-cdk-lib/cx-api/lib/features.ts index 6f494410f4dbd..b164badc1f9ba 100644 --- a/packages/aws-cdk-lib/cx-api/lib/features.ts +++ b/packages/aws-cdk-lib/cx-api/lib/features.ts @@ -96,6 +96,7 @@ export const LAMBDA_NODEJS_USE_LATEST_RUNTIME = '@aws-cdk/aws-lambda-nodejs:useL export const RDS_PREVENT_RENDERING_DEPRECATED_CREDENTIALS = '@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials'; export const AURORA_CLUSTER_CHANGE_SCOPE_OF_INSTANCE_PARAMETER_GROUP_WITH_EACH_PARAMETERS = '@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters'; export const APPSYNC_ENABLE_USE_ARN_IDENTIFIER_SOURCE_API_ASSOCIATION = '@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier'; +export const CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME = '@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource'; export const FLAGS: Record = { ////////////////////////////////////////////////////////////////////// @@ -962,6 +963,19 @@ export const FLAGS: Record = { introducedIn: { v2: '2.98.0' }, recommendedValue: true, }, + + ////////////////////////////////////////////////////////////////////// + [CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME]: { + type: FlagType.BugFix, + summary: 'When enabled, the CodeCommit source action is using the default branch name \'main\'.', + detailsMd: ` + When setting up a CodeCommit source action for the source stage of a pipeline, please note that the + default branch is \'master\'. + However, with the activation of this feature flag, the default branch is updated to \'main\'. + `, + introducedIn: { v2: '2.103.1' }, + recommendedValue: true, + }, }; const CURRENT_MV = 'v2'; From 89f4f86b27536d5fc891cadb88d679abb9b93b2e Mon Sep 17 00:00:00 2001 From: Sumu Pitchayan <35242245+sumupitchayan@users.noreply.github.com> Date: Wed, 1 Nov 2023 12:15:28 -0400 Subject: [PATCH 11/14] fix(apigatewayv2): trigger on websocket connect and disconnect is not working (#27732) Closes #19532 Lambda integrations for `$connect` and `$disconnect` routes were previously broken. Users would see this error message in the Lambda console: ![160185676-15ba5704-a7ba-49ef-b457-bb3f89094de6](https://github.com/aws/aws-cdk/assets/35242245/0938239a-b4f1-440d-9868-86ce3d213386) Fixing the path by removing the extra `*/` from the [code of the Lambda integration](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-apigatewayv2-integrations-alpha/lib/websocket/lambda.ts#L36) that adds permission, we no longer see that error message in the Lambda console as the path is now correct: Screenshot 2023-10-27 at 2 58 11 PM I could not manage to figure out how to verify this change via an Integration test assertion. However, I added a new integration test file for Lambda `$connect` and `$disconnect` integrations on a `WebSocketApi`. The attached screenshots above also verify that this change works when I manually run it locally. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../http/integ.lambda.js.snapshot/tree.json | 20 +- .../integ.user-pool.js.snapshot/tree.json | 168 ++-- .../IntegApiGatewayV2Iam.assets.json | 4 +- .../IntegApiGatewayV2Iam.template.json | 2 +- .../integ.iam.js.snapshot/manifest.json | 9 +- .../websocket/integ.iam.js.snapshot/tree.json | 2 +- .../lib/websocket/lambda.ts | 2 +- ...efaultTestDeployAssert4E6713E1.assets.json | 19 + ...aultTestDeployAssert4E6713E1.template.json | 36 + .../package.json | 11 + .../package.json | 11 + .../cdk.out | 1 + ...wv2-lambda-connect-integration.assets.json | 45 + ...2-lambda-connect-integration.template.json | 470 ++++++++++ .../integ.json | 12 + .../manifest.json | 211 +++++ .../tree.json | 849 ++++++++++++++++++ ...integ.lambda-connect-disconnect-trigger.ts | 81 ++ .../WebSocketApiInteg.assets.json | 4 +- .../WebSocketApiInteg.template.json | 8 +- .../integ.lambda.js.snapshot/manifest.json | 23 +- .../integ.lambda.js.snapshot/tree.json | 8 +- .../websocket/lambdas/connect/package.json | 11 + .../websocket/lambdas/disconnect/package.json | 11 + .../aws-cdk-scheduler-schedule.assets.json | 6 +- .../test/integ.schedule.js.snapshot/cdk.out | 2 +- .../integ.schedule.js.snapshot/integ.json | 2 +- ...efaultTestDeployAssert24CB3896.assets.json | 2 +- .../integ.schedule.js.snapshot/manifest.json | 4 +- .../test/integ.schedule.js.snapshot/tree.json | 5 + 30 files changed, 1915 insertions(+), 124 deletions(-) create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28/package.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0/package.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.assets.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.template.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.ts create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/connect/package.json create mode 100644 packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/disconnect/package.json diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.lambda.js.snapshot/tree.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.lambda.js.snapshot/tree.json index 996df67fee0c0..08ec1606edb94 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.lambda.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.lambda.js.snapshot/tree.json @@ -171,7 +171,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpStage", "version": "0.0.0" } }, @@ -209,7 +209,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpIntegration", "version": "0.0.0" } }, @@ -292,7 +292,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpRoute", "version": "0.0.0" } }, @@ -349,7 +349,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpAuthorizer", "version": "0.0.0" } }, @@ -403,7 +403,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpApi", "version": "0.0.0" } }, @@ -450,7 +450,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpStage", "version": "0.0.0" } }, @@ -507,7 +507,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpAuthorizer", "version": "0.0.0" } }, @@ -561,7 +561,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpApi", "version": "0.0.0" } }, @@ -719,7 +719,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpIntegration", "version": "0.0.0" } }, @@ -802,7 +802,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpRoute", "version": "0.0.0" } }, diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.user-pool.js.snapshot/tree.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.user-pool.js.snapshot/tree.json index 7dd213178bc9c..23f942bfe3fdc 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.user-pool.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/http/integ.user-pool.js.snapshot/tree.json @@ -45,8 +45,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool", + "version": "0.0.0" } }, "UserPoolAuthorizerClient": { @@ -83,20 +83,20 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPoolClient", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.UserPoolClient", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.UserPool", + "version": "0.0.0" } }, "userpoolForDefaultAuthorizer": { @@ -136,8 +136,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool", + "version": "0.0.0" } }, "UserPoolAuthorizerClient": { @@ -174,20 +174,20 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPoolClient", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.UserPoolClient", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_cognito.UserPool", + "version": "0.0.0" } }, "MyHttpApi": { @@ -205,8 +205,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnApi", + "version": "0.0.0" } }, "DefaultStage": { @@ -227,14 +227,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnStage", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpStage", + "version": "0.0.0" } }, "GET--": { @@ -265,14 +265,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpIntegration", + "version": "0.0.0" } }, "RootIntegratin-Permission": { @@ -316,8 +316,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "Resource": { @@ -348,14 +348,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpRoute", + "version": "0.0.0" } }, "UserPoolAuthorizer": { @@ -401,20 +401,20 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnAuthorizer", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpAuthorizer", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpApi", + "version": "0.0.0" } }, "MyHttpApiWithDefaultAuthorizer": { @@ -432,8 +432,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnApi", + "version": "0.0.0" } }, "DefaultStage": { @@ -454,14 +454,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnStage", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpStage", + "version": "0.0.0" } }, "UserPoolDefaultAuthorizer": { @@ -507,20 +507,20 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnAuthorizer", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpAuthorizer", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpApi", + "version": "0.0.0" } }, "lambda": { @@ -535,8 +535,8 @@ "id": "ImportServiceRole", "path": "AuthorizerInteg/lambda/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "Resource": { @@ -574,14 +574,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" } }, "Code": { @@ -592,22 +592,22 @@ "id": "Stage", "path": "AuthorizerInteg/lambda/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { "id": "AssetBucket", "path": "AuthorizerInteg/lambda/Code/AssetBucket", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_s3_assets.Asset", + "version": "0.0.0" } }, "Resource": { @@ -633,14 +633,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" } }, "Route": { @@ -671,14 +671,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpIntegration", + "version": "0.0.0" } }, "RootIntegration-Permission": { @@ -722,8 +722,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "Resource": { @@ -758,36 +758,36 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.HttpRoute", + "version": "0.0.0" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "AuthorizerInteg/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "AuthorizerInteg/CheckBootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" } }, "Tree": { @@ -800,8 +800,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.assets.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.assets.json index acfbbfa7a6875..4ab5619801629 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.assets.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.assets.json @@ -1,7 +1,7 @@ { "version": "34.0.0", "files": { - "89f3eb281075e38df0df45fd2cf30f90cd7bbaabddef614ebee1040631c2a0c6": { + "0fecdddcc93cb59f37820c43eaa8030e35f0be824e2f8e7b63bde0bb0b24e264": { "source": { "path": "IntegApiGatewayV2Iam.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "89f3eb281075e38df0df45fd2cf30f90cd7bbaabddef614ebee1040631c2a0c6.json", + "objectKey": "0fecdddcc93cb59f37820c43eaa8030e35f0be824e2f8e7b63bde0bb0b24e264.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-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.template.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.template.json index ec0283f3bd2bd..5e3e47d97b6cf 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.template.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/IntegApiGatewayV2Iam.template.json @@ -100,7 +100,7 @@ { "Ref": "WebSocketApi34BCF99B" }, - "/*/*$connect" + "/*$connect" ] ] } diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/manifest.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/manifest.json index 529e868fc518c..5cd819d527b7b 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/manifest.json @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "IntegApiGatewayV2Iam.template.json", + "terminationProtection": false, "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}/89f3eb281075e38df0df45fd2cf30f90cd7bbaabddef614ebee1040631c2a0c6.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/0fecdddcc93cb59f37820c43eaa8030e35f0be824e2f8e7b63bde0bb0b24e264.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -66,7 +67,10 @@ "/IntegApiGatewayV2Iam/WebSocketApi/$connect-Route/WebSocketLambdaIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "WebSocketApiconnectRouteWebSocketLambdaIntegrationPermission76CD86C6" + "data": "WebSocketApiconnectRouteWebSocketLambdaIntegrationPermission76CD86C6", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/IntegApiGatewayV2Iam/WebSocketApi/$connect-Route/WebSocketLambdaIntegration/Resource": [ @@ -133,6 +137,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "ApiGatewayV2WebSocketIamTestDefaultTestDeployAssert2B412D7B.template.json", + "terminationProtection": false, "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}", diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/tree.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/tree.json index 3aeaca1832db8..2192187ed14af 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers-alpha/test/websocket/integ.iam.js.snapshot/tree.json @@ -205,7 +205,7 @@ { "Ref": "WebSocketApi34BCF99B" }, - "/*/*$connect" + "/*$connect" ] ] } diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/lib/websocket/lambda.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/lib/websocket/lambda.ts index 9306ef7dc0e7a..e57068e90e1b3 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/lib/websocket/lambda.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/lib/websocket/lambda.ts @@ -33,7 +33,7 @@ export class WebSocketLambdaIntegration extends WebSocketRouteIntegration { sourceArn: Stack.of(route).formatArn({ service: 'execute-api', resource: route.webSocketApi.apiId, - resourceName: `*/*${route.routeKey}`, + resourceName: `*${route.routeKey}`, }), }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json new file mode 100644 index 0000000000000..618513371ae9f --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IntegDefaultTestDeployAssert4E6713E1.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-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.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-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28/package.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28/package.json new file mode 100644 index 0000000000000..941efba0e8117 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28/package.json @@ -0,0 +1,11 @@ +{ + "name": "connect", + "version": "1.0.0", + "description": "connect example for WebSockets on API Gateway", + "main": "index.js", + "author": "SAM CLI", + "license": "MIT", + "dependencies": { + "aws-sdk": "^2.690.0" + } +} diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0/package.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0/package.json new file mode 100644 index 0000000000000..f7f07857f72ea --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/asset.e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0/package.json @@ -0,0 +1,11 @@ +{ + "name": "disconnect", + "version": "1.0.0", + "description": "disconnect example for WebSockets on API Gateway", + "main": "index.js", + "author": "SAM CLI", + "license": "MIT", + "dependencies": { + "aws-sdk": "^2.690.0" + } +} diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/cdk.out b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.assets.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.assets.json new file mode 100644 index 0000000000000..b2efe2d122ad2 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.assets.json @@ -0,0 +1,45 @@ +{ + "version": "34.0.0", + "files": { + "2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28": { + "source": { + "path": "asset.2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0": { + "source": { + "path": "asset.e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "8d51b7c174041dae18b57745e88660ee14de05b2ac0e42fb860dca1ff5677b71": { + "source": { + "path": "integ-apigwv2-lambda-connect-integration.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "8d51b7c174041dae18b57745e88660ee14de05b2ac0e42fb860dca1ff5677b71.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-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.template.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.template.json new file mode 100644 index 0000000000000..c61991e3b6d33 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.template.json @@ -0,0 +1,470 @@ +{ + "Resources": { + "ConnectFunctionServiceRoleDD1EAA8C": { + "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" + ] + ] + } + ] + } + }, + "ConnectFunctionServiceRoleDefaultPolicy9C1FE0B3": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:BatchWriteItem", + "dynamodb:ConditionCheckItem", + "dynamodb:DeleteItem", + "dynamodb:DescribeTable", + "dynamodb:GetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:PutItem", + "dynamodb:Query", + "dynamodb:Scan", + "dynamodb:UpdateItem" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "WebSocketLogTable7F74AAC5", + "Arn" + ] + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ConnectFunctionServiceRoleDefaultPolicy9C1FE0B3", + "Roles": [ + { + "Ref": "ConnectFunctionServiceRoleDD1EAA8C" + } + ] + } + }, + "ConnectFunction4D4B4BB5": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28.zip" + }, + "Environment": { + "Variables": { + "TABLE_NAME": "WebSocketConnections" + } + }, + "FunctionName": "process_connect_requests", + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "ConnectFunctionServiceRoleDD1EAA8C", + "Arn" + ] + }, + "Runtime": "nodejs14.x", + "Timeout": 5 + }, + "DependsOn": [ + "ConnectFunctionServiceRoleDefaultPolicy9C1FE0B3", + "ConnectFunctionServiceRoleDD1EAA8C" + ] + }, + "DisconnectFunctionServiceRole49DB60AC": { + "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" + ] + ] + } + ] + } + }, + "DisconnectFunctionServiceRoleDefaultPolicyF5348EC3": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:BatchWriteItem", + "dynamodb:ConditionCheckItem", + "dynamodb:DeleteItem", + "dynamodb:DescribeTable", + "dynamodb:GetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:PutItem", + "dynamodb:Query", + "dynamodb:Scan", + "dynamodb:UpdateItem" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "WebSocketLogTable7F74AAC5", + "Arn" + ] + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "DisconnectFunctionServiceRoleDefaultPolicyF5348EC3", + "Roles": [ + { + "Ref": "DisconnectFunctionServiceRole49DB60AC" + } + ] + } + }, + "DisconnectFunction620A9610": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0.zip" + }, + "Environment": { + "Variables": { + "TABLE_NAME": "WebSocketConnections" + } + }, + "FunctionName": "process_disconnect_requests", + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "DisconnectFunctionServiceRole49DB60AC", + "Arn" + ] + }, + "Runtime": "nodejs14.x", + "Timeout": 5 + }, + "DependsOn": [ + "DisconnectFunctionServiceRoleDefaultPolicyF5348EC3", + "DisconnectFunctionServiceRole49DB60AC" + ] + }, + "WebSocketLogTable7F74AAC5": { + "Type": "AWS::DynamoDB::Table", + "Properties": { + "AttributeDefinitions": [ + { + "AttributeName": "ConnectionId", + "AttributeType": "S" + } + ], + "KeySchema": [ + { + "AttributeName": "ConnectionId", + "KeyType": "HASH" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "TableName": "WebSocketConnections" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "WebSocketAPIDA75128A": { + "Type": "AWS::ApiGatewayV2::Api", + "Properties": { + "Name": "webSocket", + "ProtocolType": "WEBSOCKET", + "RouteSelectionExpression": "$request.body.action" + } + }, + "WebSocketAPIconnectRouteConnectIntegrationPermission1FECDE58": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "ConnectFunction4D4B4BB5", + "Arn" + ] + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":execute-api:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "WebSocketAPIDA75128A" + }, + "/*$connect" + ] + ] + } + } + }, + "WebSocketAPIconnectRouteConnectIntegration2725692A": { + "Type": "AWS::ApiGatewayV2::Integration", + "Properties": { + "ApiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "IntegrationType": "AWS_PROXY", + "IntegrationUri": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "ConnectFunction4D4B4BB5", + "Arn" + ] + }, + "/invocations" + ] + ] + } + } + }, + "WebSocketAPIconnectRoute4BD84FCF": { + "Type": "AWS::ApiGatewayV2::Route", + "Properties": { + "ApiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "AuthorizationType": "NONE", + "RouteKey": "$connect", + "Target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "WebSocketAPIconnectRouteConnectIntegration2725692A" + } + ] + ] + } + } + }, + "WebSocketAPIdisconnectRouteDisconnectIntegrationPermission909CCDD8": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "DisconnectFunction620A9610", + "Arn" + ] + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":execute-api:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "WebSocketAPIDA75128A" + }, + "/*$disconnect" + ] + ] + } + } + }, + "WebSocketAPIdisconnectRouteDisconnectIntegration317B9227": { + "Type": "AWS::ApiGatewayV2::Integration", + "Properties": { + "ApiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "IntegrationType": "AWS_PROXY", + "IntegrationUri": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "DisconnectFunction620A9610", + "Arn" + ] + }, + "/invocations" + ] + ] + } + } + }, + "WebSocketAPIdisconnectRouteBC1A3C36": { + "Type": "AWS::ApiGatewayV2::Route", + "Properties": { + "ApiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "AuthorizationType": "NONE", + "RouteKey": "$disconnect", + "Target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "WebSocketAPIdisconnectRouteDisconnectIntegration317B9227" + } + ] + ] + } + } + }, + "ProductionStage7933AAB2": { + "Type": "AWS::ApiGatewayV2::Stage", + "Properties": { + "ApiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "AutoDeploy": true, + "StageName": "prod" + } + } + }, + "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-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ.json new file mode 100644 index 0000000000000..f122cfe8f44e1 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "Integ/DefaultTest": { + "stacks": [ + "integ-apigwv2-lambda-connect-integration" + ], + "assertionStack": "Integ/DefaultTest/DeployAssert", + "assertionStackName": "IntegDefaultTestDeployAssert4E6713E1" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/manifest.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/manifest.json new file mode 100644 index 0000000000000..43f212b29e333 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/manifest.json @@ -0,0 +1,211 @@ +{ + "version": "34.0.0", + "artifacts": { + "integ-apigwv2-lambda-connect-integration.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-apigwv2-lambda-connect-integration.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-apigwv2-lambda-connect-integration": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integ-apigwv2-lambda-connect-integration.template.json", + "terminationProtection": false, + "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}/8d51b7c174041dae18b57745e88660ee14de05b2ac0e42fb860dca1ff5677b71.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-apigwv2-lambda-connect-integration.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": [ + "integ-apigwv2-lambda-connect-integration.assets" + ], + "metadata": { + "/integ-apigwv2-lambda-connect-integration/Connect Function/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ConnectFunctionServiceRoleDD1EAA8C" + } + ], + "/integ-apigwv2-lambda-connect-integration/Connect Function/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ConnectFunctionServiceRoleDefaultPolicy9C1FE0B3" + } + ], + "/integ-apigwv2-lambda-connect-integration/Connect Function/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ConnectFunction4D4B4BB5" + } + ], + "/integ-apigwv2-lambda-connect-integration/Disconnect Function/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DisconnectFunctionServiceRole49DB60AC" + } + ], + "/integ-apigwv2-lambda-connect-integration/Disconnect Function/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DisconnectFunctionServiceRoleDefaultPolicyF5348EC3" + } + ], + "/integ-apigwv2-lambda-connect-integration/Disconnect Function/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DisconnectFunction620A9610" + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket Log Table": [ + { + "type": "aws:cdk:hasPhysicalName", + "data": { + "Ref": "WebSocketLogTable7F74AAC5" + } + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket Log Table/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketLogTable7F74AAC5" + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket API/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketAPIDA75128A" + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route/ConnectIntegration-Permission": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketAPIconnectRouteConnectIntegrationPermission1FECDE58", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route/ConnectIntegration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketAPIconnectRouteConnectIntegration2725692A" + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketAPIconnectRoute4BD84FCF" + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route/DisconnectIntegration-Permission": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketAPIdisconnectRouteDisconnectIntegrationPermission909CCDD8", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route/DisconnectIntegration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketAPIdisconnectRouteDisconnectIntegration317B9227" + } + ], + "/integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WebSocketAPIdisconnectRouteBC1A3C36" + } + ], + "/integ-apigwv2-lambda-connect-integration/Production Stage/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ProductionStage7933AAB2" + } + ], + "/integ-apigwv2-lambda-connect-integration/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-apigwv2-lambda-connect-integration/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-apigwv2-lambda-connect-integration" + }, + "IntegDefaultTestDeployAssert4E6713E1.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegDefaultTestDeployAssert4E6713E1.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegDefaultTestDeployAssert4E6713E1": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegDefaultTestDeployAssert4E6713E1.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegDefaultTestDeployAssert4E6713E1.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": [ + "IntegDefaultTestDeployAssert4E6713E1.assets" + ], + "metadata": { + "/Integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/Integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "Integ/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/tree.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/tree.json new file mode 100644 index 0000000000000..26157d6a3c755 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/tree.json @@ -0,0 +1,849 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-apigwv2-lambda-connect-integration": { + "id": "integ-apigwv2-lambda-connect-integration", + "path": "integ-apigwv2-lambda-connect-integration", + "children": { + "Connect Function": { + "id": "Connect Function", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/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-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:BatchWriteItem", + "dynamodb:ConditionCheckItem", + "dynamodb:DeleteItem", + "dynamodb:DescribeTable", + "dynamodb:GetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:PutItem", + "dynamodb:Query", + "dynamodb:Scan", + "dynamodb:UpdateItem" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "WebSocketLogTable7F74AAC5", + "Arn" + ] + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "Version": "2012-10-17" + }, + "policyName": "ConnectFunctionServiceRoleDefaultPolicy9C1FE0B3", + "roles": [ + { + "Ref": "ConnectFunctionServiceRoleDD1EAA8C" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/Code/Stage", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/Code/AssetBucket", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3_assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/Connect Function/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": "2748a200bf25c8ee2c2898271226a9f7bdc386b8ce9669528731eb36c5ed9e28.zip" + }, + "environment": { + "variables": { + "TABLE_NAME": "WebSocketConnections" + } + }, + "functionName": "process_connect_requests", + "handler": "index.handler", + "role": { + "Fn::GetAtt": [ + "ConnectFunctionServiceRoleDD1EAA8C", + "Arn" + ] + }, + "runtime": "nodejs14.x", + "timeout": 5 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "Disconnect Function": { + "id": "Disconnect Function", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/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-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:BatchWriteItem", + "dynamodb:ConditionCheckItem", + "dynamodb:DeleteItem", + "dynamodb:DescribeTable", + "dynamodb:GetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:PutItem", + "dynamodb:Query", + "dynamodb:Scan", + "dynamodb:UpdateItem" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "WebSocketLogTable7F74AAC5", + "Arn" + ] + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "Version": "2012-10-17" + }, + "policyName": "DisconnectFunctionServiceRoleDefaultPolicyF5348EC3", + "roles": [ + { + "Ref": "DisconnectFunctionServiceRole49DB60AC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/Code/Stage", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/Code/AssetBucket", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3_assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/Disconnect Function/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": "e593848af17fee558eece2cd2719347804c0c141cff4f8ea1fb8556cf986b5a0.zip" + }, + "environment": { + "variables": { + "TABLE_NAME": "WebSocketConnections" + } + }, + "functionName": "process_disconnect_requests", + "handler": "index.handler", + "role": { + "Fn::GetAtt": [ + "DisconnectFunctionServiceRole49DB60AC", + "Arn" + ] + }, + "runtime": "nodejs14.x", + "timeout": 5 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "WebSocket Log Table": { + "id": "WebSocket Log Table", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket Log Table", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket Log Table/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::DynamoDB::Table", + "aws:cdk:cloudformation:props": { + "attributeDefinitions": [ + { + "attributeName": "ConnectionId", + "attributeType": "S" + } + ], + "keySchema": [ + { + "attributeName": "ConnectionId", + "keyType": "HASH" + } + ], + "provisionedThroughput": { + "readCapacityUnits": 5, + "writeCapacityUnits": 5 + }, + "tableName": "WebSocketConnections" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.CfnTable", + "version": "0.0.0" + } + }, + "ScalingRole": { + "id": "ScalingRole", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket Log Table/ScalingRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.Table", + "version": "0.0.0" + } + }, + "WebSocket API": { + "id": "WebSocket API", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Api", + "aws:cdk:cloudformation:props": { + "name": "webSocket", + "protocolType": "WEBSOCKET", + "routeSelectionExpression": "$request.body.action" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnApi", + "version": "0.0.0" + } + }, + "$connect-Route": { + "id": "$connect-Route", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route", + "children": { + "ConnectIntegration-Permission": { + "id": "ConnectIntegration-Permission", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route/ConnectIntegration-Permission", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "ConnectFunction4D4B4BB5", + "Arn" + ] + }, + "principal": "apigateway.amazonaws.com", + "sourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":execute-api:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "WebSocketAPIDA75128A" + }, + "/*$connect" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + }, + "ConnectIntegration": { + "id": "ConnectIntegration", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route/ConnectIntegration", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route/ConnectIntegration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Integration", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "integrationType": "AWS_PROXY", + "integrationUri": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "ConnectFunction4D4B4BB5", + "Arn" + ] + }, + "/invocations" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$connect-Route/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Route", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "authorizationType": "NONE", + "routeKey": "$connect", + "target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "WebSocketAPIconnectRouteConnectIntegration2725692A" + } + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", + "version": "0.0.0" + } + }, + "$disconnect-Route": { + "id": "$disconnect-Route", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route", + "children": { + "DisconnectIntegration-Permission": { + "id": "DisconnectIntegration-Permission", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route/DisconnectIntegration-Permission", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "DisconnectFunction620A9610", + "Arn" + ] + }, + "principal": "apigateway.amazonaws.com", + "sourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":execute-api:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "WebSocketAPIDA75128A" + }, + "/*$disconnect" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + }, + "DisconnectIntegration": { + "id": "DisconnectIntegration", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route/DisconnectIntegration", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route/DisconnectIntegration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Integration", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "integrationType": "AWS_PROXY", + "integrationUri": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "DisconnectFunction620A9610", + "Arn" + ] + }, + "/invocations" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/WebSocket API/$disconnect-Route/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Route", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "authorizationType": "NONE", + "routeKey": "$disconnect", + "target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "WebSocketAPIdisconnectRouteDisconnectIntegration317B9227" + } + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketApi", + "version": "0.0.0" + } + }, + "Production Stage": { + "id": "Production Stage", + "path": "integ-apigwv2-lambda-connect-integration/Production Stage", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apigwv2-lambda-connect-integration/Production Stage/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Stage", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "WebSocketAPIDA75128A" + }, + "autoDeploy": true, + "stageName": "prod" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnStage", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketStage", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-apigwv2-lambda-connect-integration/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-apigwv2-lambda-connect-integration/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Integ": { + "id": "Integ", + "path": "Integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "Integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "Integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "Integ/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "Integ/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "Integ/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.ts new file mode 100644 index 0000000000000..8078678f45557 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda-connect-disconnect-trigger.ts @@ -0,0 +1,81 @@ +import { WebSocketApi, WebSocketStage } from '@aws-cdk/aws-apigatewayv2-alpha'; +import * as cdk from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { WebSocketLambdaIntegration } from '../../lib'; +import * as lambda from 'aws-cdk-lib/aws-lambda'; +import * as path from 'path'; +import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'integ-apigwv2-lambda-connect-integration'); +const webSocketTableName = 'WebSocketConnections'; + +const connectFunction = new lambda.Function(stack, 'Connect Function', { + functionName: 'process_connect_requests', + runtime: lambda.Runtime.NODEJS_14_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'lambdas', 'connect')), + timeout: cdk.Duration.seconds(5), + environment: { + TABLE_NAME: webSocketTableName, + }, +}); + +const disconnectFunction = new lambda.Function( + stack, + 'Disconnect Function', + { + functionName: 'process_disconnect_requests', + runtime: lambda.Runtime.NODEJS_14_X, + handler: 'index.handler', + code: lambda.Code.fromAsset( + path.join(__dirname, 'lambdas', 'disconnect'), + ), + timeout: cdk.Duration.seconds(5), + environment: { + TABLE_NAME: webSocketTableName, + }, + }, +); + +const webSocketLogTable = new dynamodb.Table(stack, 'WebSocket Log Table', { + tableName: webSocketTableName, + partitionKey: { + name: 'ConnectionId', + type: dynamodb.AttributeType.STRING, + }, + removalPolicy: cdk.RemovalPolicy.DESTROY, // not recommended for production +}); +webSocketLogTable.grantReadWriteData(connectFunction); +webSocketLogTable.grantReadWriteData(disconnectFunction); + +const webSocketConnectIntegration = new WebSocketLambdaIntegration( + 'ConnectIntegration', + connectFunction, +); +const webSocketDisconnectIntegration = new WebSocketLambdaIntegration( + 'DisconnectIntegration', + disconnectFunction, +); + +const webSocketApi = new WebSocketApi(stack, 'WebSocket API', { + apiName: 'webSocket', + routeSelectionExpression: '$request.body.action', + connectRouteOptions: { integration: webSocketConnectIntegration }, + disconnectRouteOptions: { integration: webSocketDisconnectIntegration }, +}); + +new WebSocketStage( + stack, + 'Production Stage', + { + webSocketApi: webSocketApi, + stageName: 'prod', + autoDeploy: true, + }, +); + +new IntegTest(app, 'Integ', { testCases: [stack] }); + +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json index 806e1a698a8a3..c73ed81c6cb7f 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json @@ -1,7 +1,7 @@ { "version": "34.0.0", "files": { - "26e34316c6931e2609524675771603977641dab52471e7fb4c21e998529ed3fd": { + "fa386136122b6cd106460ddbdcd437d10712be61617b8d1bf2110a459aa9e233": { "source": { "path": "WebSocketApiInteg.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "26e34316c6931e2609524675771603977641dab52471e7fb4c21e998529ed3fd.json", + "objectKey": "fa386136122b6cd106460ddbdcd437d10712be61617b8d1bf2110a459aa9e233.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-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json index b6e930b1fa098..e50d8cfbe1645 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json @@ -239,7 +239,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*$connect" + "/*$connect" ] ] } @@ -329,7 +329,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*$disconnect" + "/*$disconnect" ] ] } @@ -419,7 +419,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*$default" + "/*$default" ] ] } @@ -509,7 +509,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*sendmessage" + "/*sendmessage" ] ] } diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/manifest.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/manifest.json index 18f03b2eb267e..1f2c3210e48af 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/manifest.json @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "WebSocketApiInteg.template.json", + "terminationProtection": false, "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}/26e34316c6931e2609524675771603977641dab52471e7fb4c21e998529ed3fd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa386136122b6cd106460ddbdcd437d10712be61617b8d1bf2110a459aa9e233.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -90,7 +91,10 @@ "/WebSocketApiInteg/mywsapi/$connect-Route/ConnectIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapiconnectRouteConnectIntegrationPermission719B6E63" + "data": "mywsapiconnectRouteConnectIntegrationPermission719B6E63", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/WebSocketApiInteg/mywsapi/$connect-Route/ConnectIntegration/Resource": [ @@ -108,7 +112,10 @@ "/WebSocketApiInteg/mywsapi/$disconnect-Route/DisconnectIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapidisconnectRouteDisconnectIntegrationPermissionA8197C41" + "data": "mywsapidisconnectRouteDisconnectIntegrationPermissionA8197C41", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/WebSocketApiInteg/mywsapi/$disconnect-Route/DisconnectIntegration/Resource": [ @@ -126,7 +133,10 @@ "/WebSocketApiInteg/mywsapi/$default-Route/DefaultIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapidefaultRouteDefaultIntegrationPermission3B7F9CA1" + "data": "mywsapidefaultRouteDefaultIntegrationPermission3B7F9CA1", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/WebSocketApiInteg/mywsapi/$default-Route/DefaultIntegration/Resource": [ @@ -144,7 +154,10 @@ "/WebSocketApiInteg/mywsapi/sendmessage-Route/SendMessageIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapisendmessageRouteSendMessageIntegrationPermission92C9841E" + "data": "mywsapisendmessageRouteSendMessageIntegrationPermission92C9841E", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/WebSocketApiInteg/mywsapi/sendmessage-Route/SendMessageIntegration/Resource": [ diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/tree.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/tree.json index a3eaa745e06b2..990d79acbeef9 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/integ.lambda.js.snapshot/tree.json @@ -430,7 +430,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*$connect" + "/*$connect" ] ] } @@ -564,7 +564,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*$disconnect" + "/*$disconnect" ] ] } @@ -698,7 +698,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*$default" + "/*$default" ] ] } @@ -832,7 +832,7 @@ { "Ref": "mywsapi32E6CE11" }, - "/*/*sendmessage" + "/*sendmessage" ] ] } diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/connect/package.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/connect/package.json new file mode 100644 index 0000000000000..941efba0e8117 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/connect/package.json @@ -0,0 +1,11 @@ +{ + "name": "connect", + "version": "1.0.0", + "description": "connect example for WebSockets on API Gateway", + "main": "index.js", + "author": "SAM CLI", + "license": "MIT", + "dependencies": { + "aws-sdk": "^2.690.0" + } +} diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/disconnect/package.json b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/disconnect/package.json new file mode 100644 index 0000000000000..f7f07857f72ea --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations-alpha/test/websocket/lambdas/disconnect/package.json @@ -0,0 +1,11 @@ +{ + "name": "disconnect", + "version": "1.0.0", + "description": "disconnect example for WebSockets on API Gateway", + "main": "index.js", + "author": "SAM CLI", + "license": "MIT", + "dependencies": { + "aws-sdk": "^2.690.0" + } +} diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.assets.json b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.assets.json index 9c12eb7d9b585..a2459496af954 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.assets.json +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.assets.json @@ -1,7 +1,7 @@ { - "version": "33.0.0", + "version": "34.0.0", "files": { - "70a4ff6207a6b7ce2e7a4354be513e0143bb5f5c671d6826cfb30c010875e4bd": { + "eac1c2181558fb8d64de1b029b3b58376b7191ef29b61b4585bdc8f7a45b3671": { "source": { "path": "aws-cdk-scheduler-schedule.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "70a4ff6207a6b7ce2e7a4354be513e0143bb5f5c671d6826cfb30c010875e4bd.json", + "objectKey": "eac1c2181558fb8d64de1b029b3b58376b7191ef29b61b4585bdc8f7a45b3671.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-scheduler-alpha/test/integ.schedule.js.snapshot/cdk.out b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/cdk.out index 560dae10d018f..2313ab5436501 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"33.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integ.json b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integ.json index 8bd3af4b50e53..c1aec1a40f53f 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "33.0.0", + "version": "34.0.0", "testCases": { "integtest-schedule/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integtestscheduleDefaultTestDeployAssert24CB3896.assets.json b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integtestscheduleDefaultTestDeployAssert24CB3896.assets.json index 0ec5b6018b44a..8f8a003c1b5ba 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integtestscheduleDefaultTestDeployAssert24CB3896.assets.json +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integtestscheduleDefaultTestDeployAssert24CB3896.assets.json @@ -1,5 +1,5 @@ { - "version": "33.0.0", + "version": "34.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/manifest.json b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/manifest.json index 9e6c88e76c10e..482a334a2ce96 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "33.0.0", + "version": "34.0.0", "artifacts": { "aws-cdk-scheduler-schedule.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,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}/70a4ff6207a6b7ce2e7a4354be513e0143bb5f5c671d6826cfb30c010875e4bd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/eac1c2181558fb8d64de1b029b3b58376b7191ef29b61b4585bdc8f7a45b3671.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/tree.json b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/tree.json index 3f5cd77076180..0255afcabc32c 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/tree.json @@ -450,6 +450,11 @@ "Role1ABCC5F0", "Arn" ] + }, + "input": "\"Input Text\"", + "retryPolicy": { + "maximumEventAgeInSeconds": 180, + "maximumRetryAttempts": 3 } } } From 857ab7d8eb465afa50753b74d6a2a4bec2cddf1e Mon Sep 17 00:00:00 2001 From: Amplifiyer <51211245+Amplifiyer@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:45:17 +0100 Subject: [PATCH 12/14] fix(cli): fix stack monitoring when the stack events do not have phsical resource id set (#27692) `PhysicalResourceId` for a `StackEvent` is [not required](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackEvent.html) and can be empty. This causes error in stack deployment activty monitoring where we try to monitor nested stacks but empty `PhysicalResourceId` in the `StackEvent` causes it to fail with the error ``` [ValidationError]: 2 validation errors detected: Value '' at 'stackName' failed to satisfy constraint: Member must have length greater than or equal to 1; Value '' at 'stackName' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z][-a-zA-Z0-9]*|arn:[-a-zA-Z0-9:/._+]* ``` This PR adds a check to avoid that. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cloudformation/stack-activity-monitor.ts | 4 +- .../aws-cdk/test/util/stack-monitor.test.ts | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts index 63f2b9e6c2071..21d0fbc1a20f1 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts @@ -252,8 +252,8 @@ export class StackActivityMonitor { }); if (event.ResourceType === 'AWS::CloudFormation::Stack' && !CFN_SUCCESS_STATUS.includes(event.ResourceStatus ?? '')) { - // If the event is not for `this` stack, recursively call for events in the nested stack - if (event.PhysicalResourceId !== stackToPollForEvents) { + // If the event is not for `this` stack and has a physical resource Id, recursively call for events in the nested stack + if (event.PhysicalResourceId && event.PhysicalResourceId !== stackToPollForEvents) { await this.readNewEvents(event.PhysicalResourceId); } } diff --git a/packages/aws-cdk/test/util/stack-monitor.test.ts b/packages/aws-cdk/test/util/stack-monitor.test.ts index c34a7a3ae040e..8d88fe3e419aa 100644 --- a/packages/aws-cdk/test/util/stack-monitor.test.ts +++ b/packages/aws-cdk/test/util/stack-monitor.test.ts @@ -153,6 +153,43 @@ describe('stack monitor, collecting errors from events', () => { expect(monitor.errors).toStrictEqual(['actual failure error message', 'nested stack failed']); }); + test('does not consider events without physical resource id for monitoring nested stacks', async () => { + const monitor = await testMonitorWithEventCalls([ + (request) => { + expect(request.StackName).toStrictEqual('StackName'); + return { + StackEvents: [ + addErrorToStackEvent( + event(100), { + logicalResourceId: 'nestedStackLogicalResourceId', + physicalResourceId: '', + resourceType: 'AWS::CloudFormation::Stack', + resourceStatusReason: 'nested stack failed', + }, + ), + ], + }; + }, + (request) => { + // Note that the second call happened for the top level stack instead of a nested stack + expect(request.StackName).toStrictEqual('StackName'); + return { + StackEvents: [ + addErrorToStackEvent( + event(101), { + logicalResourceId: 'OtherResource', + resourceType: 'Some::Other::Resource', + resourceStatusReason: 'some failure', + }, + ), + ], + }; + }, + ]); + + expect(monitor.errors).toStrictEqual(['nested stack failed', 'some failure']); + }); + test('does not check for nested stacks that have already completed successfully', async () => { const monitor = await testMonitorWithEventCalls([ (request) => { From 22168b183417d446d6a5113cee569b4c814f10d8 Mon Sep 17 00:00:00 2001 From: Colin Francis <131073567+colifran@users.noreply.github.com> Date: Wed, 1 Nov 2023 14:58:46 -0700 Subject: [PATCH 13/14] feat(dynamodb): add seed capacity property to support changing table billing mode (#27734) This PR adds `seedCapacity` as a property on the `AutoscaledCapacityOptions` interface. `seedCapacity` must be provided for each autoscaled resource when changing a table's billing from on-demand to provisioned or from provisioned to on-demand. Closes #27735. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cdk-global-table.assets.json | 4 ++-- .../aws-cdk-global-table.template.json | 2 ++ .../manifest.json | 4 +++- .../tree.json | 2 ++ .../test/integ.table-v2-global.ts | 2 +- packages/aws-cdk-lib/aws-dynamodb/README.md | 12 ++++++++++ .../aws-cdk-lib/aws-dynamodb/lib/capacity.ts | 16 ++++++++++++- .../aws-dynamodb/test/capacity.test.ts | 24 +++++++++++++++++++ 8 files changed, 61 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.assets.json index 2a47502d9bdf3..367978078a86f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.assets.json @@ -1,7 +1,7 @@ { "version": "34.0.0", "files": { - "116ecd47ef9b5b3d293d7b3733b6a742a38eb54e2d54d79f9009fdbbb8c36dff": { + "655325b6fb8ec8800b23d95ba84700a27856d6a10c2a0557c2b17da00bf4f7b1": { "source": { "path": "aws-cdk-global-table.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-us-east-1": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", - "objectKey": "116ecd47ef9b5b3d293d7b3733b6a742a38eb54e2d54d79f9009fdbbb8c36dff.json", + "objectKey": "655325b6fb8ec8800b23d95ba84700a27856d6a10c2a0557c2b17da00bf4f7b1.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.template.json index c108cf892122a..9e1ae805f618c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/aws-cdk-global-table.template.json @@ -49,6 +49,7 @@ "WriteCapacityAutoScalingSettings": { "MaxCapacity": 20, "MinCapacity": 1, + "SeedCapacity": 10, "TargetTrackingScalingPolicyConfiguration": { "TargetValue": 60 } @@ -251,6 +252,7 @@ "WriteCapacityAutoScalingSettings": { "MaxCapacity": 20, "MinCapacity": 1, + "SeedCapacity": 10, "TargetTrackingScalingPolicyConfiguration": { "TargetValue": 60 } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/manifest.json index 9f5f8980ccc4a..48e0da18859d3 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/manifest.json @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/us-east-1", "properties": { "templateFile": "aws-cdk-global-table.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-us-east-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1/116ecd47ef9b5b3d293d7b3733b6a742a38eb54e2d54d79f9009fdbbb8c36dff.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1/655325b6fb8ec8800b23d95ba84700a27856d6a10c2a0557c2b17da00bf4f7b1.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -87,6 +88,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "awscdkglobaltableintegDefaultTestDeployAssertA2A9E81F.template.json", + "terminationProtection": false, "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}", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/tree.json index 6c0d53c9afce4..5cbdfe133287c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.js.snapshot/tree.json @@ -90,6 +90,7 @@ "writeCapacityAutoScalingSettings": { "minCapacity": 1, "maxCapacity": 20, + "seedCapacity": 10, "targetTrackingScalingPolicyConfiguration": { "targetValue": 60 } @@ -292,6 +293,7 @@ "writeCapacityAutoScalingSettings": { "minCapacity": 1, "maxCapacity": 20, + "seedCapacity": 10, "targetTrackingScalingPolicyConfiguration": { "targetValue": 60 } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.ts index 5a81eadcae96c..8cf849249f998 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-v2-global.ts @@ -16,7 +16,7 @@ class TestStack extends Stack { sortKey: { name: 'sk', type: AttributeType.NUMBER }, billing: Billing.provisioned({ readCapacity: Capacity.fixed(10), - writeCapacity: Capacity.autoscaled({ maxCapacity: 20, targetUtilizationPercent: 60 }), + writeCapacity: Capacity.autoscaled({ maxCapacity: 20, targetUtilizationPercent: 60, seedCapacity: 10 }), }), encryption: TableEncryptionV2.awsManagedKey(), contributorInsights: true, diff --git a/packages/aws-cdk-lib/aws-dynamodb/README.md b/packages/aws-cdk-lib/aws-dynamodb/README.md index e35e679605236..2212bf7ad305f 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/README.md +++ b/packages/aws-cdk-lib/aws-dynamodb/README.md @@ -201,6 +201,18 @@ const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', { }); ``` +When changing the billing for a table from provisioned to on-demand or from on-demand to provisioned, `seedCapacity` must be configured for each autoscaled resource: + +```ts +const globalTable = new dynamodb.TableV2(this, 'Table', { + partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING }, + billing: dynamodb.Billing.provisioned({ + readCapacity: dynamodb.Capacity.fixed(10), + writeCapacity: dynamodb.Capacity.autoscaled({ maxCapacity: 10, seedCapacity: 20 }), + }), +}); +``` + Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html diff --git a/packages/aws-cdk-lib/aws-dynamodb/lib/capacity.ts b/packages/aws-cdk-lib/aws-dynamodb/lib/capacity.ts index 0df1591d17178..a0443d1a41622 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/lib/capacity.ts +++ b/packages/aws-cdk-lib/aws-dynamodb/lib/capacity.ts @@ -39,7 +39,16 @@ export interface AutoscaledCapacityOptions { * * @default 70 */ - readonly targetUtilizationPercent?: number + readonly targetUtilizationPercent?: number; + + /** + * If you want to switch a table's billing mode from on-demand to provisioned or + * from provisioned to on-demand, you must specify a value for this property for + * each autoscaled resource. + * + * @default no seed capacity + */ + readonly seedCapacity?: number; } /** @@ -85,6 +94,10 @@ export abstract class Capacity { if (options.targetUtilizationPercent !== undefined && (options.targetUtilizationPercent < 20 || options.targetUtilizationPercent > 90)) { throw new Error('`targetUtilizationPercent` cannot be less than 20 or greater than 90'); } + + if (options.seedCapacity !== undefined && (options.seedCapacity < 1)) { + throw new Error(`'seedCapacity' cannot be less than 1 - received ${options.seedCapacity}`); + } } public _renderReadCapacity() { @@ -103,6 +116,7 @@ export abstract class Capacity { return { minCapacity: options.minCapacity ?? 1, maxCapacity: options.maxCapacity, + seedCapacity: options.seedCapacity, targetTrackingScalingPolicyConfiguration: { targetValue: options.targetUtilizationPercent ?? 70, }, diff --git a/packages/aws-cdk-lib/aws-dynamodb/test/capacity.test.ts b/packages/aws-cdk-lib/aws-dynamodb/test/capacity.test.ts index 0f0a472376aab..09ac42e9ce10c 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/test/capacity.test.ts +++ b/packages/aws-cdk-lib/aws-dynamodb/test/capacity.test.ts @@ -90,6 +90,23 @@ describe('autoscaled capacity', () => { }); }); + test('can specify seed capacity', () => { + // GIVEN + const capacity = Capacity.autoscaled({ maxCapacity: 10, seedCapacity: 20 }); + + // WHEN / THEN + expect(capacity._renderReadCapacity()).toEqual({ + readCapacityAutoScalingSettings: { + minCapacity: 1, + maxCapacity: 10, + seedCapacity: 20, + targetTrackingScalingPolicyConfiguration: { + targetValue: 70, + }, + }, + }); + }); + test('capacity mode is AUTOSCALED', () => { // GIVEN const capacity = Capacity.autoscaled({ minCapacity: 1, maxCapacity: 10 }); @@ -118,4 +135,11 @@ describe('autoscaled capacity', () => { Capacity.autoscaled({ maxCapacity: 10, targetUtilizationPercent: 91 }); }).toThrow('`targetUtilizationPercent` cannot be less than 20 or greater than 90'); }); + + test('throws if seed capacity is less than 1', () => { + // GIVEN / WHEN / THEN + expect(() => { + Capacity.autoscaled({ maxCapacity: 10, seedCapacity: 0 }); + }).toThrow("'seedCapacity' cannot be less than 1 - received 0"); + }); }); From d449cfd6408513e18d785d284995b99759a2aa46 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Vellingiri Date: Thu, 2 Nov 2023 06:58:42 +0530 Subject: [PATCH 14/14] feat(rds): support aurora MySQL 3.05.0 (#27748) Add support for Aurora MySQL Engine Version 3_05_0. AWS Release notes: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraMySQLReleaseNotes/AuroraMySQL.Updates.3050.html --- packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts b/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts index a07ac4deffbd2..495f4eb08f04c 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts @@ -438,6 +438,8 @@ export class AuroraMysqlEngineVersion { public static readonly VER_3_03_1 = AuroraMysqlEngineVersion.builtIn_8_0('3.03.1'); /** Version "8.0.mysql_aurora.3.04.0". */ public static readonly VER_3_04_0 = AuroraMysqlEngineVersion.builtIn_8_0('3.04.0'); + /** Version "8.0.mysql_aurora.3.05.0". */ + public static readonly VER_3_05_0 = AuroraMysqlEngineVersion.builtIn_8_0('3.05.0'); /** * Create a new AuroraMysqlEngineVersion with an arbitrary version.