From 4fbc1827b8978262da0b5b77b1ee9bc0ecfdcc3e Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Fri, 23 Dec 2022 08:58:54 -0800 Subject: [PATCH] fix(cfnspec): v101.0.0 introduced specific types on several types that previously were typed as json (#23448) This PR reverts all changes where a type changed from `Json` to a specific type in CfnSpec v101.0.0. See https://github.com/aws/aws-cdk/commit/3951f09fb370b74936f3fb45e7188ac6c7343b67 - [x] 000_AWS_Backup.json - [x] 000_AWS_CloudFormation.json - [x] 000_AWS_CodeGuruProfiler.json - [x] 000_AWS_Config.json - [x] 000_AWS_Connect.json - [x] 000_AWS_DataBrew.json - [x] 000_AWS_EC2.json - [x] 000_AWS_ECR.json - [x] 000_AWS_ElastiCache.json - [x] 000_AWS_FIS.json - [x] 000_AWS_Forecast.json - [x] 000_AWS_GreengrassV2.json - [x] 000_AWS_IoT.json - [ ] ~000_AWS_IoTAnalytics.json~ - [x] 000_AWS_IoTCoreDeviceAdvisor.json - [ ] ~000_AWS_IoTFleetWise.json~ - [x] 000_AWS_IoTSiteWise.json - [x] 000_AWS_IoTTwinMaker.json - [x] 000_AWS_IoTWireless.json - [ ] ~000_AWS_LakeFormation.json~ - [x] 000_AWS_Lex.json - [x] 000_AWS_LookoutEquipment.json - [ ] ~000_AWS_Macie.json~ - [x] 000_AWS_MemoryDB.json - [x] 000_AWS_Personalize.json - [x] 000_AWS_Redshift.json - [x] 000_AWS_Route53.json - [x] 000_AWS_S3.json - [x] 000_AWS_S3ObjectLambda.json - [x] 000_AWS_S3Outposts.json - [x] 000_AWS_SageMaker.json - [ ] ~000_AWS_Scheduler.json~ - [ ] ~000_AWS_StepFunctions.json~ - [ ] ~000_AWS_Timestream.json~ - [x] 000_AWS_Transfer.json - [x] 000_AWS_WAFv2.json ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts | 12 +- ...efaultTestDeployAssert6AFD1854.assets.json | 10 +- ...aultTestDeployAssert6AFD1854.template.json | 4 +- .../FlowLogsFeatureFlag.assets.json | 4 +- .../FlowLogsFeatureFlag.template.json | 14 +- .../FlowLogsTestStack.assets.json | 10 +- .../FlowLogsTestStack.template.json | 14 +- .../__entrypoint__.js | 144 --- .../__entrypoint__.js | 118 +++ .../index.d.ts | 1 + .../index.js | 0 .../index.ts | 82 ++ .../index.js | 215 +--- .../manifest.json | 23 +- .../integ.vpc-flow-logs.js.snapshot/tree.json | 112 +- .../aws-ec2/test/vpc-flow-logs.test.ts | 6 +- .../aws-s3objectlambda/lib/access-point.ts | 6 +- .../500_Revert_To_Json_Types_patch.json | 961 ++++++++++++++++++ packages/awslint/lib/rules/resource.ts | 1 - 19 files changed, 1261 insertions(+), 476 deletions(-) delete mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts rename packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/{asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c => asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26}/index.js (100%) create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts rename packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/{asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle => asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle}/index.js (75%) create mode 100644 packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts index 30cd9fe7d7e0d..d43f9f9aac26c 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-flow-logs.ts @@ -676,7 +676,7 @@ export class FlowLog extends FlowLogBase { } const flowLog = new CfnFlowLog(this, 'FlowLog', { - destinationOptions: renderDestinationOptions(destinationConfig.destinationOptions), + destinationOptions: destinationConfig.destinationOptions, deliverLogsPermissionArn: this.iamRole ? this.iamRole.roleArn : undefined, logDestinationType: destinationConfig.logDestinationType, logGroupName: this.logGroup ? this.logGroup.logGroupName : undefined, @@ -694,13 +694,3 @@ export class FlowLog extends FlowLogBase { this.node.defaultChild = flowLog; } } - -function renderDestinationOptions(opts: DestinationOptions | undefined): CfnFlowLog.DestinationOptionsProperty | undefined { - if (opts === undefined) { return undefined; } - - return { - fileFormat: opts.fileFormat ?? 'plain-text', - hiveCompatiblePartitions: opts.hiveCompatiblePartitions ?? false, - perHourPartition: opts.perHourPartition ?? false, - }; -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json index 7b8f6b3c685fc..297a68239d9a3 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.assets.json @@ -1,20 +1,20 @@ { "version": "21.0.0", "files": { - "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac": { + "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b": { "source": { - "path": "asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle", + "path": "asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.zip", + "objectKey": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd": { + "1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7": { "source": { "path": "FlowLogsDefaultTestDeployAssert6AFD1854.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd.json", + "objectKey": "1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json index d8bc055b720ef..e8cb5fe5ffe8f 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsDefaultTestDeployAssert6AFD1854.template.json @@ -31,7 +31,7 @@ } }, "flattenResponse": "false", - "salt": "1668693953813" + "salt": "1666810703150" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -115,7 +115,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.zip" + "S3Key": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip" }, "Timeout": 120, "Handler": "index.handler", diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json index ff70a68b4bce9..fa5105def2d15 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.assets.json @@ -1,7 +1,7 @@ { "version": "21.0.0", "files": { - "8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f": { + "2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9": { "source": { "path": "FlowLogsFeatureFlag.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f.json", + "objectKey": "2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json index 9f63324d697a3..0c55b91df3207 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsFeatureFlag.template.json @@ -524,6 +524,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -536,8 +537,7 @@ "Key": "Name", "Value": "FlowLogsFeatureFlag/VPC" } - ], - "TrafficType": "ALL" + ] } }, "VPCFlowLogsS3WithDestinationOptionsBucket1B7AC456": { @@ -673,10 +673,11 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "DestinationOptions": { - "FileFormat": "plain-text", - "HiveCompatiblePartitions": true, - "PerHourPartition": false + "fileFormat": "plain-text", + "perHourPartition": false, + "hiveCompatiblePartitions": true }, "LogDestination": { "Fn::GetAtt": [ @@ -690,8 +691,7 @@ "Key": "Name", "Value": "FlowLogsFeatureFlag/VPC" } - ], - "TrafficType": "ALL" + ] } }, "FlowLogsInstanceInstanceSecurityGroupF61782E0": { diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json index d99b980527565..310bb5c387339 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.assets.json @@ -1,20 +1,20 @@ { "version": "21.0.0", "files": { - "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { + "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d": { "source": { - "path": "asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c", + "path": "asset.bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip", + "objectKey": "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79": { + "2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7": { "source": { "path": "FlowLogsTestStack.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79.json", + "objectKey": "2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json index c368f02a02265..43b56bfee9517 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/FlowLogsTestStack.template.json @@ -524,6 +524,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -536,8 +537,7 @@ "Key": "Name", "Value": "FlowLogsTestStack/VPC" } - ], - "TrafficType": "ALL" + ] } }, "VPCFlowLogsS3KeyPrefixFlowLogB57F1746": { @@ -547,6 +547,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "LogDestination": { "Fn::Join": [ "", @@ -567,8 +568,7 @@ "Key": "Name", "Value": "FlowLogsTestStack/VPC" } - ], - "TrafficType": "ALL" + ] } }, "FlowLogsCWIAMRole017AD736": { @@ -643,6 +643,7 @@ "Ref": "VPCB9E5F0B4" }, "ResourceType": "VPC", + "TrafficType": "ALL", "DeliverLogsPermissionArn": { "Fn::GetAtt": [ "FlowLogsCWIAMRole017AD736", @@ -652,8 +653,7 @@ "LogDestinationType": "cloud-watch-logs", "LogGroupName": { "Ref": "FlowLogsCWLogGroup0398E8F8" - }, - "TrafficType": "ALL" + } } }, "Bucket83908E77": { @@ -888,7 +888,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip" + "S3Key": "bb426cfb5fed5237e5928f871893b243ddf86a591a592b558bd29f60e28bad9d.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js deleted file mode 100644 index 1e3a3093c1706..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js +++ /dev/null @@ -1,144 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.withRetries = exports.handler = exports.external = void 0; -const https = require("https"); -const url = require("url"); -// for unit tests -exports.external = { - sendHttpRequest: defaultSendHttpRequest, - log: defaultLog, - includeStackTraces: true, - userHandlerIndex: './index', -}; -const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; -const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; -async function handler(event, context) { - const sanitizedEvent = { ...event, ResponseURL: '...' }; - exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); - // ignore DELETE event when the physical resource ID is the marker that - // indicates that this DELETE is a subsequent DELETE to a failed CREATE - // operation. - if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { - exports.external.log('ignoring DELETE event caused by a failed CREATE event'); - await submitResponse('SUCCESS', event); - return; - } - try { - // invoke the user handler. this is intentionally inside the try-catch to - // ensure that if there is an error it's reported as a failure to - // cloudformation (otherwise cfn waits). - // eslint-disable-next-line @typescript-eslint/no-require-imports - const userHandler = require(exports.external.userHandlerIndex).handler; - const result = await userHandler(sanitizedEvent, context); - // validate user response and create the combined event - const responseEvent = renderResponse(event, result); - // submit to cfn as success - await submitResponse('SUCCESS', responseEvent); - } - catch (e) { - const resp = { - ...event, - Reason: exports.external.includeStackTraces ? e.stack : e.message, - }; - if (!resp.PhysicalResourceId) { - // special case: if CREATE fails, which usually implies, we usually don't - // have a physical resource id. in this case, the subsequent DELETE - // operation does not have any meaning, and will likely fail as well. to - // address this, we use a marker so the provider framework can simply - // ignore the subsequent DELETE. - if (event.RequestType === 'Create') { - exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); - resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; - } - else { - // otherwise, if PhysicalResourceId is not specified, something is - // terribly wrong because all other events should have an ID. - exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); - } - } - // this is an actual error, fail the activity altogether and exist. - await submitResponse('FAILED', resp); - } -} -exports.handler = handler; -function renderResponse(cfnRequest, handlerResponse = {}) { - // if physical ID is not returned, we have some defaults for you based - // on the request type. - const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; - // if we are in DELETE and physical ID was changed, it's an error. - if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { - throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); - } - // merge request event and result event (result prevails). - return { - ...cfnRequest, - ...handlerResponse, - PhysicalResourceId: physicalResourceId, - }; -} -async function submitResponse(status, event) { - const json = { - Status: status, - Reason: event.Reason ?? status, - StackId: event.StackId, - RequestId: event.RequestId, - PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, - LogicalResourceId: event.LogicalResourceId, - NoEcho: event.NoEcho, - Data: event.Data, - }; - exports.external.log('submit response to cloudformation', json); - const responseBody = JSON.stringify(json); - const parsedUrl = url.parse(event.ResponseURL); - const req = { - hostname: parsedUrl.hostname, - path: parsedUrl.path, - method: 'PUT', - headers: { 'content-type': '', 'content-length': responseBody.length }, - }; - const retryOptions = { - attempts: 5, - sleep: 1000, - }; - await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); -} -async function defaultSendHttpRequest(options, responseBody) { - return new Promise((resolve, reject) => { - try { - const request = https.request(options, _ => resolve()); - request.on('error', reject); - request.write(responseBody); - request.end(); - } - catch (e) { - reject(e); - } - }); -} -function defaultLog(fmt, ...params) { - // eslint-disable-next-line no-console - console.log(fmt, ...params); -} -function withRetries(options, fn) { - return async (...xs) => { - let attempts = options.attempts; - let ms = options.sleep; - while (true) { - try { - return await fn(...xs); - } - catch (e) { - if (attempts-- <= 0) { - throw e; - } - await sleep(Math.floor(Math.random() * ms)); - ms *= 2; - } - } - }; -} -exports.withRetries = withRetries; -async function sleep(ms) { - return new Promise((ok) => setTimeout(ok, ms)); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFN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RUFBRSxFQUFFO1FBQ3hCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDaEMsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUN2QixPQUFPLElBQUksRUFBRTtZQUNYLElBQUk7Z0JBQ0YsT0FBTyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2FBQ3hCO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsSUFBSSxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUU7b0JBQ25CLE1BQU0sQ0FBQyxDQUFDO2lCQUNUO2dCQUNELE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDVDtTQUNGO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQWhCRCxrQ0FnQkM7QUFFRCxLQUFLLFVBQVUsS0FBSyxDQUFDLEVBQVU7SUFDN0IsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zdCByZXNwOiBSZXNwb25zZSA9IHtcbiAgICAgIC4uLmV2ZW50LFxuICAgICAgUmVhc29uOiBleHRlcm5hbC5pbmNsdWRlU3RhY2tUcmFjZXMgPyBlLnN0YWNrIDogZS5tZXNzYWdlLFxuICAgIH07XG5cbiAgICBpZiAoIXJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICAvLyBzcGVjaWFsIGNhc2U6IGlmIENSRUFURSBmYWlscywgd2hpY2ggdXN1YWxseSBpbXBsaWVzLCB3ZSB1c3VhbGx5IGRvbid0XG4gICAgICAvLyBoYXZlIGEgcGh5c2ljYWwgcmVzb3VyY2UgaWQuIGluIHRoaXMgY2FzZSwgdGhlIHN1YnNlcXVlbnQgREVMRVRFXG4gICAgICAvLyBvcGVyYXRpb24gZG9lcyBub3QgaGF2ZSBhbnkgbWVhbmluZywgYW5kIHdpbGwgbGlrZWx5IGZhaWwgYXMgd2VsbC4gdG9cbiAgICAgIC8vIGFkZHJlc3MgdGhpcywgd2UgdXNlIGEgbWFya2VyIHNvIHRoZSBwcm92aWRlciBmcmFtZXdvcmsgY2FuIHNpbXBseVxuICAgICAgLy8gaWdub3JlIHRoZSBzdWJzZXF1ZW50IERFTEVURS5cbiAgICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICAgICAgZXh0ZXJuYWwubG9nKCdDUkVBVEUgZmFpbGVkLCByZXNwb25kaW5nIHdpdGggYSBtYXJrZXIgcGh5c2ljYWwgcmVzb3VyY2UgaWQgc28gdGhhdCB0aGUgc3Vic2VxdWVudCBERUxFVEUgd2lsbCBiZSBpZ25vcmVkJyk7XG4gICAgICAgIHJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkID0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvdGhlcndpc2UsIGlmIFBoeXNpY2FsUmVzb3VyY2VJZCBpcyBub3Qgc3BlY2lmaWVkLCBzb21ldGhpbmcgaXNcbiAgICAgICAgLy8gdGVycmlibHkgd3JvbmcgYmVjYXVzZSBhbGwgb3RoZXIgZXZlbnRzIHNob3VsZCBoYXZlIGFuIElELlxuICAgICAgICBleHRlcm5hbC5sb2coYEVSUk9SOiBNYWxmb3JtZWQgZXZlbnQuIFwiUGh5c2ljYWxSZXNvdXJjZUlkXCIgaXMgcmVxdWlyZWQ6ICR7SlNPTi5zdHJpbmdpZnkoZXZlbnQpfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoaXMgaXMgYW4gYWN0dWFsIGVycm9yLCBmYWlsIHRoZSBhY3Rpdml0eSBhbHRvZ2V0aGVyIGFuZCBleGlzdC5cbiAgICBhd2FpdCBzdWJtaXRSZXNwb25zZSgnRkFJTEVEJywgcmVzcCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyUmVzcG9uc2UoXG4gIGNmblJlcXVlc3Q6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQgJiB7IFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZyB9LFxuICBoYW5kbGVyUmVzcG9uc2U6IHZvaWQgfCBIYW5kbGVyUmVzcG9uc2UgPSB7IH0pOiBSZXNwb25zZSB7XG5cbiAgLy8gaWYgcGh5c2ljYWwgSUQgaXMgbm90IHJldHVybmVkLCB3ZSBoYXZlIHNvbWUgZGVmYXVsdHMgZm9yIHlvdSBiYXNlZFxuICAvLyBvbiB0aGUgcmVxdWVzdCB0eXBlLlxuICBjb25zdCBwaHlzaWNhbFJlc291cmNlSWQgPSBoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUmVxdWVzdElkO1xuXG4gIC8vIGlmIHdlIGFyZSBpbiBERUxFVEUgYW5kIHBoeXNpY2FsIElEIHdhcyBjaGFuZ2VkLCBpdCdzIGFuIGVycm9yLlxuICBpZiAoY2ZuUmVxdWVzdC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScgJiYgcGh5c2ljYWxSZXNvdXJjZUlkICE9PSBjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgREVMRVRFOiBjYW5ub3QgY2hhbmdlIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBmcm9tIFwiJHtjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZH1cIiB0byBcIiR7aGFuZGxlclJlc3BvbnNlLlBoeXNpY2FsUmVzb3VyY2VJZH1cIiBkdXJpbmcgZGVsZXRpb25gKTtcbiAgfVxuXG4gIC8vIG1lcmdlIHJlcXVlc3QgZXZlbnQgYW5kIHJlc3VsdCBldmVudCAocmVzdWx0IHByZXZhaWxzKS5cbiAgcmV0dXJuIHtcbiAgICAuLi5jZm5SZXF1ZXN0LFxuICAgIC4uLmhhbmRsZXJSZXNwb25zZSxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3VibWl0UmVzcG9uc2Uoc3RhdHVzOiAnU1VDQ0VTUycgfCAnRkFJTEVEJywgZXZlbnQ6IFJlc3BvbnNlKSB7XG4gIGNvbnN0IGpzb246IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2UgPSB7XG4gICAgU3RhdHVzOiBzdGF0dXMsXG4gICAgUmVhc29uOiBldmVudC5SZWFzb24gPz8gc3RhdHVzLFxuICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfHwgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIsXG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgIE5vRWNobzogZXZlbnQuTm9FY2hvLFxuICAgIERhdGE6IGV2ZW50LkRhdGEsXG4gIH07XG5cbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBqc29uKTtcblxuICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKGV2ZW50LlJlc3BvbnNlVVJMKTtcbiAgY29uc3QgcmVxID0ge1xuICAgIGhvc3RuYW1lOiBwYXJzZWRVcmwuaG9zdG5hbWUsXG4gICAgcGF0aDogcGFyc2VkVXJsLnBhdGgsXG4gICAgbWV0aG9kOiAnUFVUJyxcbiAgICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnJywgJ2NvbnRlbnQtbGVuZ3RoJzogcmVzcG9uc2VCb2R5Lmxlbmd0aCB9LFxuICB9O1xuXG4gIGNvbnN0IHJldHJ5T3B0aW9ucyA9IHtcbiAgICBhdHRlbXB0czogNSxcbiAgICBzbGVlcDogMTAwMCxcbiAgfTtcbiAgYXdhaXQgd2l0aFJldHJpZXMocmV0cnlPcHRpb25zLCBleHRlcm5hbC5zZW5kSHR0cFJlcXVlc3QpKHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59Il19 \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js new file mode 100644 index 0000000000000..9df94382cc74e --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/__entrypoint__.js @@ -0,0 +1,118 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = exports.external = void 0; +const https = require("https"); +const url = require("url"); +// for unit tests +exports.external = { + sendHttpRequest: defaultSendHttpRequest, + log: defaultLog, + includeStackTraces: true, + userHandlerIndex: './index', +}; +const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; +const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; +async function handler(event, context) { + const sanitizedEvent = { ...event, ResponseURL: '...' }; + exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); + // ignore DELETE event when the physical resource ID is the marker that + // indicates that this DELETE is a subsequent DELETE to a failed CREATE + // operation. + if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { + exports.external.log('ignoring DELETE event caused by a failed CREATE event'); + await submitResponse('SUCCESS', event); + return; + } + try { + // invoke the user handler. this is intentionally inside the try-catch to + // ensure that if there is an error it's reported as a failure to + // cloudformation (otherwise cfn waits). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const userHandler = require(exports.external.userHandlerIndex).handler; + const result = await userHandler(sanitizedEvent, context); + // validate user response and create the combined event + const responseEvent = renderResponse(event, result); + // submit to cfn as success + await submitResponse('SUCCESS', responseEvent); + } + catch (e) { + const resp = { + ...event, + Reason: exports.external.includeStackTraces ? e.stack : e.message, + }; + if (!resp.PhysicalResourceId) { + // special case: if CREATE fails, which usually implies, we usually don't + // have a physical resource id. in this case, the subsequent DELETE + // operation does not have any meaning, and will likely fail as well. to + // address this, we use a marker so the provider framework can simply + // ignore the subsequent DELETE. + if (event.RequestType === 'Create') { + exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); + resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; + } + else { + // otherwise, if PhysicalResourceId is not specified, something is + // terribly wrong because all other events should have an ID. + exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); + } + } + // this is an actual error, fail the activity altogether and exist. + await submitResponse('FAILED', resp); + } +} +exports.handler = handler; +function renderResponse(cfnRequest, handlerResponse = {}) { + // if physical ID is not returned, we have some defaults for you based + // on the request type. + const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; + // if we are in DELETE and physical ID was changed, it's an error. + if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { + throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); + } + // merge request event and result event (result prevails). + return { + ...cfnRequest, + ...handlerResponse, + PhysicalResourceId: physicalResourceId, + }; +} +async function submitResponse(status, event) { + const json = { + Status: status, + Reason: event.Reason ?? status, + StackId: event.StackId, + RequestId: event.RequestId, + PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, + LogicalResourceId: event.LogicalResourceId, + NoEcho: event.NoEcho, + Data: event.Data, + }; + exports.external.log('submit response to cloudformation', json); + const responseBody = JSON.stringify(json); + const parsedUrl = url.parse(event.ResponseURL); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + await exports.external.sendHttpRequest(req, responseBody); +} +async function defaultSendHttpRequest(options, responseBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, _ => resolve()); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +function defaultLog(fmt, ...params) { + // eslint-disable-next-line no-console + console.log(fmt, ...params); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFN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QzVCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtRQUNwQixNQUFNLEVBQUUsS0FBSztRQUNiLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRTtLQUN2RSxDQUFDO0lBRUYsTUFBTSxnQkFBUSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUVELEtBQUssVUFBVSxzQkFBc0IsQ0FBQyxPQUE2QixFQUFFLFlBQW9CO0lBQ3ZGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNmO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDWDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxHQUFHLE1BQWE7SUFDL0Msc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCAqIGFzIHVybCBmcm9tICd1cmwnO1xuXG4vLyBmb3IgdW5pdCB0ZXN0c1xuZXhwb3J0IGNvbnN0IGV4dGVybmFsID0ge1xuICBzZW5kSHR0cFJlcXVlc3Q6IGRlZmF1bHRTZW5kSHR0cFJlcXVlc3QsXG4gIGxvZzogZGVmYXVsdExvZyxcbiAgaW5jbHVkZVN0YWNrVHJhY2VzOiB0cnVlLFxuICB1c2VySGFuZGxlckluZGV4OiAnLi9pbmRleCcsXG59O1xuXG5jb25zdCBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUiA9ICdBV1NDREs6OkN1c3RvbVJlc291cmNlUHJvdmlkZXJGcmFtZXdvcms6OkNSRUFURV9GQUlMRUQnO1xuY29uc3QgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpNSVNTSU5HX1BIWVNJQ0FMX0lEJztcblxuZXhwb3J0IHR5cGUgUmVzcG9uc2UgPSBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50ICYgSGFuZGxlclJlc3BvbnNlO1xuZXhwb3J0IHR5cGUgSGFuZGxlciA9IChldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpID0+IFByb21pc2U8SGFuZGxlclJlc3BvbnNlIHwgdm9pZD47XG5leHBvcnQgdHlwZSBIYW5kbGVyUmVzcG9uc2UgPSB1bmRlZmluZWQgfCB7XG4gIERhdGE/OiBhbnk7XG4gIFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZztcbiAgUmVhc29uPzogc3RyaW5nO1xuICBOb0VjaG8/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGNvbnN0IHNhbml0aXplZEV2ZW50ID0geyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH07XG4gIGV4dGVybmFsLmxvZyhKU09OLnN0cmluZ2lmeShzYW5pdGl6ZWRFdmVudCwgdW5kZWZpbmVkLCAyKSk7XG5cbiAgLy8gaWdub3JlIERFTEVURSBldmVudCB3aGVuIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBpcyB0aGUgbWFya2VyIHRoYXRcbiAgLy8gaW5kaWNhdGVzIHRoYXQgdGhpcyBERUxFVEUgaXMgYSBzdWJzZXF1ZW50IERFTEVURSB0byBhIGZhaWxlZCBDUkVBVEVcbiAgLy8gb3BlcmF0aW9uLlxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnICYmIGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCA9PT0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIpIHtcbiAgICBleHRlcm5hbC5sb2coJ2lnbm9yaW5nIERFTEVURSBldmVudCBjYXVzZWQgYnkgYSBmYWlsZWQgQ1JFQVRFIGV2ZW50Jyk7XG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCBldmVudCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBpbnZva2UgdGhlIHVzZXIgaGFuZGxlci4gdGhpcyBpcyBpbnRlbnRpb25hbGx5IGluc2lkZSB0aGUgdHJ5LWNhdGNoIHRvXG4gICAgLy8gZW5zdXJlIHRoYXQgaWYgdGhlcmUgaXMgYW4gZXJyb3IgaXQncyByZXBvcnRlZCBhcyBhIGZhaWx1cmUgdG9cbiAgICAvLyBjbG91ZGZvcm1hdGlvbiAob3RoZXJ3aXNlIGNmbiB3YWl0cykuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCB1c2VySGFuZGxlcjogSGFuZGxlciA9IHJlcXVpcmUoZXh0ZXJuYWwudXNlckhhbmRsZXJJbmRleCkuaGFuZGxlcjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB1c2VySGFuZGxlcihzYW5pdGl6ZWRFdmVudCwgY29udGV4dCk7XG5cbiAgICAvLyB2YWxpZGF0ZSB1c2VyIHJlc3BvbnNlIGFuZCBjcmVhdGUgdGhlIGNvbWJpbmVkIGV2ZW50XG4gICAgY29uc3QgcmVzcG9uc2VFdmVudCA9IHJlbmRlclJlc3BvbnNlKGV2ZW50LCByZXN1bHQpO1xuXG4gICAgLy8gc3VibWl0IHRvIGNmbiBhcyBzdWNjZXNzXG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCByZXNwb25zZUV2ZW50KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnN0IHJlc3A6IFJlc3BvbnNlID0ge1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBSZWFzb246IGV4dGVybmFsLmluY2x1ZGVTdGFja1RyYWNlcyA/IGUuc3RhY2sgOiBlLm1lc3NhZ2UsXG4gICAgfTtcblxuICAgIGlmICghcmVzcC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogaWYgQ1JFQVRFIGZhaWxzLCB3aGljaCB1c3VhbGx5IGltcGxpZXMsIHdlIHVzdWFsbHkgZG9uJ3RcbiAgICAgIC8vIGhhdmUgYSBwaHlzaWNhbCByZXNvdXJjZSBpZC4gaW4gdGhpcyBjYXNlLCB0aGUgc3Vic2VxdWVudCBERUxFVEVcbiAgICAgIC8vIG9wZXJhdGlvbiBkb2VzIG5vdCBoYXZlIGFueSBtZWFuaW5nLCBhbmQgd2lsbCBsaWtlbHkgZmFpbCBhcyB3ZWxsLiB0b1xuICAgICAgLy8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYSBtYXJrZXIgc28gdGhlIHByb3ZpZGVyIGZyYW1ld29yayBjYW4gc2ltcGx5XG4gICAgICAvLyBpZ25vcmUgdGhlIHN1YnNlcXVlbnQgREVMRVRFLlxuICAgICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgICAgICBleHRlcm5hbC5sb2coJ0NSRUFURSBmYWlsZWQsIHJlc3BvbmRpbmcgd2l0aCBhIG1hcmtlciBwaHlzaWNhbCByZXNvdXJjZSBpZCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IERFTEVURSB3aWxsIGJlIGlnbm9yZWQnKTtcbiAgICAgICAgcmVzcC5QaHlzaWNhbFJlc291cmNlSWQgPSBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG90aGVyd2lzZSwgaWYgUGh5c2ljYWxSZXNvdXJjZUlkIGlzIG5vdCBzcGVjaWZpZWQsIHNvbWV0aGluZyBpc1xuICAgICAgICAvLyB0ZXJyaWJseSB3cm9uZyBiZWNhdXNlIGFsbCBvdGhlciBldmVudHMgc2hvdWxkIGhhdmUgYW4gSUQuXG4gICAgICAgIGV4dGVybmFsLmxvZyhgRVJST1I6IE1hbGZvcm1lZCBldmVudC4gXCJQaHlzaWNhbFJlc291cmNlSWRcIiBpcyByZXF1aXJlZDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBpcyBhbiBhY3R1YWwgZXJyb3IsIGZhaWwgdGhlIGFjdGl2aXR5IGFsdG9nZXRoZXIgYW5kIGV4aXN0LlxuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdGQUlMRUQnLCByZXNwKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSZXNwb25zZShcbiAgY2ZuUmVxdWVzdDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIHsgUGh5c2ljYWxSZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gIGhhbmRsZXJSZXNwb25zZTogdm9pZCB8IEhhbmRsZXJSZXNwb25zZSA9IHsgfSk6IFJlc3BvbnNlIHtcblxuICAvLyBpZiBwaHlzaWNhbCBJRCBpcyBub3QgcmV0dXJuZWQsIHdlIGhhdmUgc29tZSBkZWZhdWx0cyBmb3IgeW91IGJhc2VkXG4gIC8vIG9uIHRoZSByZXF1ZXN0IHR5cGUuXG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGhhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5SZXF1ZXN0SWQ7XG5cbiAgLy8gaWYgd2UgYXJlIGluIERFTEVURSBhbmQgcGh5c2ljYWwgSUQgd2FzIGNoYW5nZWQsIGl0J3MgYW4gZXJyb3IuXG4gIGlmIChjZm5SZXF1ZXN0LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBwaHlzaWNhbFJlc291cmNlSWQgIT09IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBERUxFVEU6IGNhbm5vdCBjaGFuZ2UgdGhlIHBoeXNpY2FsIHJlc291cmNlIElEIGZyb20gXCIke2NmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIHRvIFwiJHtoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIGR1cmluZyBkZWxldGlvbmApO1xuICB9XG5cbiAgLy8gbWVyZ2UgcmVxdWVzdCBldmVudCBhbmQgcmVzdWx0IGV2ZW50IChyZXN1bHQgcHJldmFpbHMpLlxuICByZXR1cm4ge1xuICAgIC4uLmNmblJlcXVlc3QsXG4gICAgLi4uaGFuZGxlclJlc3BvbnNlLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdWJtaXRSZXNwb25zZShzdGF0dXM6ICdTVUNDRVNTJyB8ICdGQUlMRUQnLCBldmVudDogUmVzcG9uc2UpIHtcbiAgY29uc3QganNvbjogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSA9IHtcbiAgICBTdGF0dXM6IHN0YXR1cyxcbiAgICBSZWFzb246IGV2ZW50LlJlYXNvbiA/PyBzdGF0dXMsXG4gICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBNSVNTSU5HX1BIWVNJQ0FMX0lEX01BUktFUixcbiAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgTm9FY2hvOiBldmVudC5Ob0VjaG8sXG4gICAgRGF0YTogZXZlbnQuRGF0YSxcbiAgfTtcblxuICBleHRlcm5hbC5sb2coJ3N1Ym1pdCByZXNwb25zZSB0byBjbG91ZGZvcm1hdGlvbicsIGpzb24pO1xuXG4gIGNvbnN0IHJlc3BvbnNlQm9keSA9IEpTT04uc3RyaW5naWZ5KGpzb24pO1xuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICBjb25zdCByZXEgPSB7XG4gICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICBwYXRoOiBwYXJzZWRVcmwucGF0aCxcbiAgICBtZXRob2Q6ICdQVVQnLFxuICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICcnLCAnY29udGVudC1sZW5ndGgnOiByZXNwb25zZUJvZHkubGVuZ3RoIH0sXG4gIH07XG5cbiAgYXdhaXQgZXh0ZXJuYWwuc2VuZEh0dHBSZXF1ZXN0KHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts new file mode 100644 index 0000000000000..3554dc94d4617 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.d.ts @@ -0,0 +1 @@ +export declare function handler(event: AWSLambda.CloudFormationCustomResourceEvent): Promise; diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.js similarity index 100% rename from packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js rename to packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.js diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts new file mode 100644 index 0000000000000..2459d44ab1d18 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.60767da3831353fede3cfe92efef10580a600592dec8ccbb06c051e95b9c1b26/index.ts @@ -0,0 +1,82 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { S3 } from 'aws-sdk'; + +const AUTO_DELETE_OBJECTS_TAG = 'aws-cdk:auto-delete-objects'; + +const s3 = new S3(); + +export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent) { + switch (event.RequestType) { + case 'Create': + return; + case 'Update': + return onUpdate(event); + case 'Delete': + return onDelete(event.ResourceProperties?.BucketName); + } +} + +async function onUpdate(event: AWSLambda.CloudFormationCustomResourceEvent) { + const updateEvent = event as AWSLambda.CloudFormationCustomResourceUpdateEvent; + const oldBucketName = updateEvent.OldResourceProperties?.BucketName; + const newBucketName = updateEvent.ResourceProperties?.BucketName; + const bucketNameHasChanged = newBucketName != null && oldBucketName != null && newBucketName !== oldBucketName; + + /* If the name of the bucket has changed, CloudFormation will try to delete the bucket + and create a new one with the new name. So we have to delete the contents of the + bucket so that this operation does not fail. */ + if (bucketNameHasChanged) { + return onDelete(oldBucketName); + } +} + +/** + * Recursively delete all items in the bucket + * + * @param bucketName the bucket name + */ +async function emptyBucket(bucketName: string) { + const listedObjects = await s3.listObjectVersions({ Bucket: bucketName }).promise(); + const contents = [...listedObjects.Versions ?? [], ...listedObjects.DeleteMarkers ?? []]; + if (contents.length === 0) { + return; + } + + const records = contents.map((record: any) => ({ Key: record.Key, VersionId: record.VersionId })); + await s3.deleteObjects({ Bucket: bucketName, Delete: { Objects: records } }).promise(); + + if (listedObjects?.IsTruncated) { + await emptyBucket(bucketName); + } +} + +async function onDelete(bucketName?: string) { + if (!bucketName) { + throw new Error('No BucketName was provided.'); + } + if (!await isBucketTaggedForDeletion(bucketName)) { + process.stdout.write(`Bucket does not have '${AUTO_DELETE_OBJECTS_TAG}' tag, skipping cleaning.\n`); + return; + } + try { + await emptyBucket(bucketName); + } catch (e) { + if (e.code !== 'NoSuchBucket') { + throw e; + } + // Bucket doesn't exist. Ignoring + } +} + +/** + * The bucket will only be tagged for deletion if it's being deleted in the same + * deployment as this Custom Resource. + * + * If the Custom Resource is every deleted before the bucket, it must be because + * `autoDeleteObjects` has been switched to false, in which case the tag would have + * been removed before we get to this Delete event. + */ +async function isBucketTaggedForDeletion(bucketName: string) { + const response = await s3.getBucketTagging({ Bucket: bucketName }).promise(); + return response.TagSet.some(tag => tag.Key === AUTO_DELETE_OBJECTS_TAG && tag.Value === 'true'); +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js similarity index 75% rename from packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js rename to packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js index 6bee1ced2a9b7..ba956d47f51fe 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.3074b79e05e7b98930b6449e01baa3e68b32ecff86328933c2542f7b7fe6fdac.bundle/index.js +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/asset.84802aa01d2d2c9e7d8d69705ee832c97f1ebad2d73c72be5c32d53f16cf90a7.bundle/index.js @@ -1,3 +1,4 @@ +"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; @@ -25,9 +26,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru // lib/assertions/providers/lambda-handler/index.ts var lambda_handler_exports = {}; __export(lambda_handler_exports, { - handler: () => handler, - isComplete: () => isComplete, - onTimeout: () => onTimeout + handler: () => handler }); module.exports = __toCommonJS(lambda_handler_exports); @@ -387,7 +386,6 @@ var StringLikeRegexpMatch = class extends Matcher { // lib/assertions/providers/lambda-handler/base.ts var https = __toESM(require("https")); var url = __toESM(require("url")); -var AWS = __toESM(require("aws-sdk")); var CustomResourceHandler = class { constructor(event, context) { this.event = event; @@ -406,40 +404,20 @@ var CustomResourceHandler = class { } async handle() { try { - if ("stateMachineArn" in this.event.ResourceProperties) { - const req = { - stateMachineArn: this.event.ResourceProperties.stateMachineArn, - name: this.event.RequestId, - input: JSON.stringify(this.event) - }; - await this.startExecution(req); - return; - } else { - const response = await this.processEvent(this.event.ResourceProperties); - return response; - } - } catch (e) { - console.log(e); - throw e; - } finally { - clearTimeout(this.timeout); - } - } - async handleIsComplete() { - try { - const result = await this.processEvent(this.event.ResourceProperties); - return result; + console.log(`Event: ${JSON.stringify({ ...this.event, ResponseURL: "..." })}`); + const response = await this.processEvent(this.event.ResourceProperties); + console.log(`Event output : ${JSON.stringify(response)}`); + await this.respond({ + status: "SUCCESS", + reason: "OK", + data: response + }); } catch (e) { console.log(e); - return; - } finally { - clearTimeout(this.timeout); - } - } - async startExecution(req) { - try { - const sfn = new AWS.StepFunctions(); - await sfn.startExecution(req).promise(); + await this.respond({ + status: "FAILED", + reason: e.message ?? "Internal Error" + }); } finally { clearTimeout(this.timeout); } @@ -475,8 +453,6 @@ var CustomResourceHandler = class { request2.end(); } catch (e) { reject(e); - } finally { - clearTimeout(this.timeout); } }); } @@ -503,8 +479,7 @@ var AssertionHandler = class extends CustomResourceHandler { matchResult.finished(); if (matchResult.hasFailed()) { result = { - failed: true, - assertion: JSON.stringify({ + data: JSON.stringify({ status: "fail", message: [ ...matchResult.toHumanStrings(), @@ -513,11 +488,11 @@ var AssertionHandler = class extends CustomResourceHandler { }) }; if (request2.failDeployment) { - throw new Error(result.assertion); + throw new Error(result.data); } } else { result = { - assertion: JSON.stringify({ + data: JSON.stringify({ status: "success" }) }; @@ -587,10 +562,7 @@ function flatten(object) { {}, ...function _flatten(child, path = []) { return [].concat(...Object.keys(child).map((key) => { - let childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; - if (typeof childKey === "string") { - childKey = isJsonString(childKey); - } + const childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; return typeof childKey === "object" && childKey !== null ? _flatten(childKey, path.concat([key])) : { [path.concat([key]).join(".")]: childKey }; })); }(object) @@ -598,12 +570,9 @@ function flatten(object) { } var AwsApiCallHandler = class extends CustomResourceHandler { async processEvent(request2) { - const AWS2 = require("aws-sdk"); - console.log(`AWS SDK VERSION: ${AWS2.VERSION}`); - if (!Object.prototype.hasOwnProperty.call(AWS2, request2.service)) { - throw Error(`Service ${request2.service} does not exist in AWS SDK version ${AWS2.VERSION}.`); - } - const service = new AWS2[request2.service](); + const AWS = require("aws-sdk"); + console.log(`AWS SDK VERSION: ${AWS.VERSION}`); + const service = new AWS[request2.service](); const response = await service[request2.api](request2.parameters && decode(request2.parameters)).promise(); console.log(`SDK response received ${JSON.stringify(response)}`); delete response.ResponseMetadata; @@ -613,18 +582,9 @@ var AwsApiCallHandler = class extends CustomResourceHandler { const flatData = { ...flatten(respond) }; - const resp = request2.flattenResponse === "true" ? flatData : respond; - console.log(`Returning result ${JSON.stringify(resp)}`); - return resp; + return request2.flattenResponse === "true" ? flatData : respond; } }; -function isJsonString(value) { - try { - return JSON.parse(value); - } catch { - return value; - } -} // lib/assertions/providers/lambda-handler/types.ts var ASSERT_RESOURCE_TYPE = "Custom::DeployAssert@AssertEquals"; @@ -632,136 +592,21 @@ var SDK_RESOURCE_TYPE_PREFIX = "Custom::DeployAssert@SdkCall"; // lib/assertions/providers/lambda-handler/index.ts async function handler(event, context) { - console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); - const provider = createResourceHandler(event, context); - try { - if (event.RequestType === "Delete") { - await provider.respond({ - status: "SUCCESS", - reason: "OK" - }); - return; - } - const result = await provider.handle(); - if ("stateMachineArn" in event.ResourceProperties) { - console.info('Found "stateMachineArn", waiter statemachine started'); - return; - } else if ("expected" in event.ResourceProperties) { - console.info('Found "expected", testing assertions'); - const actualPath = event.ResourceProperties.actualPath; - const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; - const assertion = new AssertionHandler({ - ...event, - ResourceProperties: { - ServiceToken: event.ServiceToken, - actual, - expected: event.ResourceProperties.expected - } - }, context); - try { - const assertionResult = await assertion.handle(); - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: { - ...assertionResult, - ...result - } - }); - return; - } catch (e) { - await provider.respond({ - status: "FAILED", - reason: e.message ?? "Internal Error" - }); - return; - } - } - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: result - }); - } catch (e) { - await provider.respond({ - status: "FAILED", - reason: e.message ?? "Internal Error" - }); - return; - } - return; -} -async function onTimeout(timeoutEvent) { - const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage); - const provider = createResourceHandler(isCompleteRequest, standardContext); - await provider.respond({ - status: "FAILED", - reason: "Operation timed out: " + JSON.stringify(isCompleteRequest) - }); -} -async function isComplete(event, context) { - console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); const provider = createResourceHandler(event, context); - try { - const result = await provider.handleIsComplete(); - const actualPath = event.ResourceProperties.actualPath; - if (result) { - const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; - if ("expected" in event.ResourceProperties) { - const assertion = new AssertionHandler({ - ...event, - ResourceProperties: { - ServiceToken: event.ServiceToken, - actual, - expected: event.ResourceProperties.expected - } - }, context); - const assertionResult = await assertion.handleIsComplete(); - if (!(assertionResult == null ? void 0 : assertionResult.failed)) { - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: { - ...assertionResult, - ...result - } - }); - return; - } else { - console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`); - throw new Error(JSON.stringify(event)); - } - } - await provider.respond({ - status: "SUCCESS", - reason: "OK", - data: result - }); - } else { - console.log("No result"); - throw new Error(JSON.stringify(event)); - } - return; - } catch (e) { - console.log(e); - throw new Error(JSON.stringify(event)); - } + await provider.handle(); } function createResourceHandler(event, context) { if (event.ResourceType.startsWith(SDK_RESOURCE_TYPE_PREFIX)) { return new AwsApiCallHandler(event, context); - } else if (event.ResourceType.startsWith(ASSERT_RESOURCE_TYPE)) { - return new AssertionHandler(event, context); - } else { - throw new Error(`Unsupported resource type "${event.ResourceType}`); + } + switch (event.ResourceType) { + case ASSERT_RESOURCE_TYPE: + return new AssertionHandler(event, context); + default: + throw new Error(`Unsupported resource type "${event.ResourceType}`); } } -var standardContext = { - getRemainingTimeInMillis: () => 9e4 -}; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { - handler, - isComplete, - onTimeout + handler }); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json index 773077597be42..a114baf10c235 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/manifest.json @@ -1,6 +1,12 @@ { "version": "21.0.0", "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, "FlowLogsFeatureFlag.assets": { "type": "cdk:asset-manifest", "properties": { @@ -17,7 +23,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/8f4f8db3ea3ad2d5f5678275c75dce7d9b67b46d8df7d92c62913bdc5a03cd3f.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2db53e096625b4b167fb15dd7bdc246692b381f45e28c509614fef7d41c20bc9.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -204,10 +210,7 @@ "/FlowLogsFeatureFlag/VPC/FlowLogsS3WithDestinationOptions/FlowLog": [ { "type": "aws:cdk:logicalId", - "data": "VPCFlowLogsS3WithDestinationOptionsFlowLog030C15B2", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "VPCFlowLogsS3WithDestinationOptionsFlowLog030C15B2" } ], "/FlowLogsFeatureFlag/Exports/Output{\"Fn::GetAtt\":[\"VPCFlowLogsS3BucketFB7DC2BE\",\"Arn\"]}": [ @@ -283,7 +286,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/23955aa16c5d59106d93ecce9cedd43aa5782fbf23bb2ef8549b2119345a6f79.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2090a74d484bc155b48d7511b99e4921b8f55e488c3fe1500cffede0cdfd33b7.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -546,7 +549,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd951509b1e22484b40a66a661cb8cebce3087b8cb381e3dcf02e641e5eb08cd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1dcf759cd2c8928f5b1acfbf439f1751e25367a5ac61ba5e640ff8b78fdf89f7.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -601,12 +604,6 @@ ] }, "displayName": "FlowLogs/DefaultTest/DeployAssert" - }, - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json index f6e0ef7c83ea9..9a0ff6b79a4b7 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.js.snapshot/tree.json @@ -4,6 +4,14 @@ "id": "App", "path": "", "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.123" + } + }, "FlowLogsFeatureFlag": { "id": "FlowLogsFeatureFlag", "path": "FlowLogsFeatureFlag", @@ -819,6 +827,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -831,8 +840,7 @@ "key": "Name", "value": "FlowLogsFeatureFlag/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -1020,10 +1028,11 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "destinationOptions": { "fileFormat": "plain-text", - "hiveCompatiblePartitions": true, - "perHourPartition": false + "perHourPartition": false, + "hiveCompatiblePartitions": true }, "logDestination": { "Fn::GetAtt": [ @@ -1037,8 +1046,7 @@ "key": "Name", "value": "FlowLogsFeatureFlag/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -1081,7 +1089,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } }, "FlowLogsInstance": { @@ -1132,14 +1140,6 @@ "id": "InstanceRole", "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole", "children": { - "ImportInstanceRole": { - "id": "ImportInstanceRole", - "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole/ImportInstanceRole", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, "Resource": { "id": "Resource", "path": "FlowLogsFeatureFlag/FlowLogsInstance/InstanceRole/Resource", @@ -1264,22 +1264,6 @@ "fqn": "@aws-cdk/core.Resource", "version": "0.0.0" } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogsFeatureFlag/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogsFeatureFlag/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" - } } }, "constructInfo": { @@ -2102,6 +2086,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::GetAtt": [ "VPCFlowLogsS3BucketFB7DC2BE", @@ -2114,8 +2099,7 @@ "key": "Name", "value": "FlowLogsTestStack/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -2143,6 +2127,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "logDestination": { "Fn::Join": [ "", @@ -2163,8 +2148,7 @@ "key": "Name", "value": "FlowLogsTestStack/VPC" } - ], - "trafficType": "ALL" + ] } }, "constructInfo": { @@ -2192,14 +2176,6 @@ "id": "IAMRole", "path": "FlowLogsTestStack/FlowLogsCW/IAMRole", "children": { - "ImportIAMRole": { - "id": "ImportIAMRole", - "path": "FlowLogsTestStack/FlowLogsCW/IAMRole/ImportIAMRole", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, "Resource": { "id": "Resource", "path": "FlowLogsTestStack/FlowLogsCW/IAMRole/Resource", @@ -2323,6 +2299,7 @@ "Ref": "VPCB9E5F0B4" }, "resourceType": "VPC", + "trafficType": "ALL", "deliverLogsPermissionArn": { "Fn::GetAtt": [ "FlowLogsCWIAMRole017AD736", @@ -2332,8 +2309,7 @@ "logDestinationType": "cloud-watch-logs", "logGroupName": { "Ref": "FlowLogsCWLogGroup0398E8F8" - }, - "trafficType": "ALL" + } } }, "constructInfo": { @@ -2616,22 +2592,6 @@ "fqn": "@aws-cdk/core.CustomResourceProvider", "version": "0.0.0" } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogsTestStack/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogsTestStack/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" - } } }, "constructInfo": { @@ -2652,7 +2612,7 @@ "path": "FlowLogs/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } }, "DeployAssert": { @@ -2672,7 +2632,7 @@ "path": "FlowLogs/DefaultTest/DeployAssert/AwsApiCallS3listObjectsV2/SdkProvider/AssertionsProvider", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" + "version": "10.1.123" } } }, @@ -2744,23 +2704,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.161" - } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "FlowLogs/DefaultTest/DeployAssert/BootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "FlowLogs/DefaultTest/DeployAssert/CheckBootstrapVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" + "version": "10.1.123" } } }, @@ -2780,14 +2724,6 @@ "fqn": "@aws-cdk/integ-tests.IntegTest", "version": "0.0.0" } - }, - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.161" - } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts index 7a068377feffb..5b16d80caf50d 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts @@ -93,9 +93,9 @@ describe('vpc flow logs', () => { TrafficType: 'ALL', ResourceId: 'eni-123456', DestinationOptions: { - HiveCompatiblePartitions: true, - FileFormat: 'plain-text', - PerHourPartition: false, + hiveCompatiblePartitions: true, + fileFormat: 'plain-text', + perHourPartition: false, }, LogDestination: { 'Fn::GetAtt': [ diff --git a/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts b/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts index 7136bd3d267a7..7d0804aa3367a 100644 --- a/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts +++ b/packages/@aws-cdk/aws-s3objectlambda/lib/access-point.ts @@ -232,9 +232,9 @@ export class AccessPoint extends AccessPointBase { { actions: ['GetObject'], contentTransformation: { - awsLambda: { - functionArn: props.handler.functionArn, - functionPayload: props.payload ? JSON.stringify(props.payload) : undefined, + AwsLambda: { + FunctionArn: props.handler.functionArn, + FunctionPayload: props.payload ? JSON.stringify(props.payload) : undefined, }, }, }, diff --git a/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json new file mode 100644 index 0000000000000..237e302807756 --- /dev/null +++ b/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/500_Revert_To_Json_Types_patch.json @@ -0,0 +1,961 @@ +{ + "ResourceTypes": { + "AWS::Backup::ReportPlan": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ReportDeliveryChannel/Type" + }, + { + "op": "add", + "path": "/Properties/ReportDeliveryChannel/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/ReportSetting/Type" + }, + { + "op": "add", + "path": "/Properties/ReportSetting/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::CloudFormation::StackSet": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ManagedExecution/Type" + }, + { + "op": "add", + "path": "/Properties/ManagedExecution/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::CodeGuruProfiler::ProfilingGroup": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AgentPermissions/Type" + }, + { + "op": "add", + "path": "/Properties/AgentPermissions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Config::ConformancePack": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/TemplateSSMDocumentDetails/Type" + }, + { + "op": "add", + "path": "/Properties/TemplateSSMDocumentDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Connect::TaskTemplate": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Constraints/Type" + }, + { + "op": "add", + "path": "/Properties/Constraints/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::FlowLog": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DestinationOptions/Type" + }, + { + "op": "add", + "path": "/Properties/DestinationOptions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::Subnet": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/PrivateDnsNameOptionsOnLaunch/Type" + }, + { + "op": "add", + "path": "/Properties/PrivateDnsNameOptionsOnLaunch/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayAttachment": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayMulticastDomain": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::EC2::TransitGatewayVpcAttachment": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Options/Type" + }, + { + "op": "add", + "path": "/Properties/Options/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::ECR::PublicRepository": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RepositoryCatalogData/Type" + }, + { + "op": "add", + "path": "/Properties/RepositoryCatalogData/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::ElastiCache::User": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AuthenticationMode/Type" + }, + { + "op": "add", + "path": "/Properties/AuthenticationMode/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Forecast::Dataset": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/EncryptionConfig/Type" + }, + { + "op": "add", + "path": "/Properties/EncryptionConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Schema/Type" + }, + { + "op": "add", + "path": "/Properties/Schema/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoT::JobTemplate": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AbortConfig/Type" + }, + { + "op": "add", + "path": "/Properties/AbortConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/JobExecutionsRolloutConfig/Type" + }, + { + "op": "add", + "path": "/Properties/JobExecutionsRolloutConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/PresignedUrlConfig/Type" + }, + { + "op": "add", + "path": "/Properties/PresignedUrlConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/TimeoutConfig/Type" + }, + { + "op": "add", + "path": "/Properties/TimeoutConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTCoreDeviceAdvisor::SuiteDefinition": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SuiteDefinitionConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/SuiteDefinitionConfiguration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTSiteWise::Portal": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Alarms/Type" + }, + { + "op": "add", + "path": "/Properties/Alarms/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTWireless::NetworkAnalyzerConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/TraceContent/Type" + }, + { + "op": "add", + "path": "/Properties/TraceContent/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::Bot": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataPrivacy/Type" + }, + { + "op": "add", + "path": "/Properties/DataPrivacy/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::BotAlias": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SentimentAnalysisSettings/Type" + }, + { + "op": "add", + "path": "/Properties/SentimentAnalysisSettings/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::LookoutEquipment::InferenceScheduler": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataInputConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/DataInputConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/DataOutputConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/DataOutputConfiguration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::MemoryDB::User": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AuthenticationMode/Type" + }, + { + "op": "add", + "path": "/Properties/AuthenticationMode/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Redshift::EndpointAccess": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/VpcEndpoint/Type" + }, + { + "op": "add", + "path": "/Properties/VpcEndpoint/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Route53::HealthCheck": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/HealthCheckConfig/Type" + }, + { + "op": "add", + "path": "/Properties/HealthCheckConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3::AccessPoint": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/PolicyStatus/Type" + }, + { + "op": "add", + "path": "/Properties/PolicyStatus/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::FeatureGroup": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/OfflineStoreConfig/Type" + }, + { + "op": "add", + "path": "/Properties/OfflineStoreConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/OnlineStoreConfig/Type" + }, + { + "op": "add", + "path": "/Properties/OnlineStoreConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::Pipeline": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ParallelismConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/ParallelismConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/PipelineDefinition/Type" + }, + { + "op": "add", + "path": "/Properties/PipelineDefinition/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::Project": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ServiceCatalogProvisioningDetails/Type" + }, + { + "op": "add", + "path": "/Properties/ServiceCatalogProvisioningDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Transfer::Connector": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/As2Config/Type" + }, + { + "op": "add", + "path": "/Properties/As2Config/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::LoggingConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/LoggingFilter/Type" + }, + { + "op": "add", + "path": "/Properties/LoggingFilter/PrimitiveType", + "value": "Json" + } + ] + } + } + }, + "PropertyTypes": { + "AWS::Backup::BackupSelection.BackupSelectionResourceType": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Conditions/Type" + }, + { + "op": "add", + "path": "/Properties/Conditions/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Backup::Framework.FrameworkControl": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ControlScope/Type" + }, + { + "op": "add", + "path": "/Properties/ControlScope/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::DataBrew::Recipe.RecipeParameters": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Input/Type" + }, + { + "op": "add", + "path": "/Properties/Input/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::FIS::ExperimentTemplate.ExperimentTemplateLogConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/CloudWatchLogsConfiguration/Type" + }, + { + "op": "add", + "path": "/Properties/CloudWatchLogsConfiguration/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/S3Configuration/Type" + }, + { + "op": "add", + "path": "/Properties/S3Configuration/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::GreengrassV2::Deployment.IoTJobRateIncreaseCriteria": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties" + }, + { + "op": "add", + "path": "/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::ComponentType.DataValue": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RelationshipValue/Type" + }, + { + "op": "add", + "path": "/Properties/RelationshipValue/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.DataValue": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/RelationshipValue/Type" + }, + { + "op": "add", + "path": "/Properties/RelationshipValue/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.Property": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Definition/Type" + }, + { + "op": "add", + "path": "/Properties/Definition/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::IoTTwinMaker::Entity.Status": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Error/Type" + }, + { + "op": "add", + "path": "/Properties/Error/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Lex::Bot.TestBotAliasSettings": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SentimentAnalysisSettings/Type" + }, + { + "op": "add", + "path": "/Properties/SentimentAnalysisSettings/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Personalize::Dataset.DatasetImportJob": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/DataSource/Type" + }, + { + "op": "add", + "path": "/Properties/DataSource/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Personalize::Solution.SolutionConfig": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/AutoMLConfig/Type" + }, + { + "op": "add", + "path": "/Properties/AutoMLConfig/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/HpoConfig/Type" + }, + { + "op": "add", + "path": "/Properties/HpoConfig/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3ObjectLambda::AccessPoint.TransformationConfiguration": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ContentTransformation/Type" + }, + { + "op": "add", + "path": "/Properties/ContentTransformation/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::S3Outposts::Bucket.Rule": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Filter/Type" + }, + { + "op": "add", + "path": "/Properties/Filter/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::SageMaker::ModelPackage.ModelPackageContainerDefinition": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/ModelInput/Type" + }, + { + "op": "add", + "path": "/Properties/ModelInput/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::Transfer::Workflow.WorkflowStep": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/CopyStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/CopyStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/CustomStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/CustomStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/DeleteStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/DeleteStepDetails/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/TagStepDetails/Type" + }, + { + "op": "add", + "path": "/Properties/TagStepDetails/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::LoggingConfiguration.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/JsonBody/Type" + }, + { + "op": "add", + "path": "/Properties/JsonBody/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::RuleGroup.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SingleQueryArgument/Type" + }, + { + "op": "add", + "path": "/Properties/SingleQueryArgument/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::RuleGroup.RuleAction": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/Allow/Type" + }, + { + "op": "add", + "path": "/Properties/Allow/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Block/Type" + }, + { + "op": "add", + "path": "/Properties/Block/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Captcha/Type" + }, + { + "op": "add", + "path": "/Properties/Captcha/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/Count/Type" + }, + { + "op": "add", + "path": "/Properties/Count/PrimitiveType", + "value": "Json" + } + ] + } + }, + "AWS::WAFv2::WebACL.FieldToMatch": { + "patch": { + "description": "This patch fixes all types that were previously typed as Json, and CfnSpec v101.0.0 added types to them, which is a breaking change.", + "operations": [ + { + "op": "remove", + "path": "/Properties/SingleQueryArgument/Type" + }, + { + "op": "add", + "path": "/Properties/SingleQueryArgument/PrimitiveType", + "value": "Json" + }, + { + "op": "remove", + "path": "/Properties/SingleHeader/Type" + }, + { + "op": "add", + "path": "/Properties/SingleHeader/PrimitiveType", + "value": "Json" + } + ] + } + } + } +} diff --git a/packages/awslint/lib/rules/resource.ts b/packages/awslint/lib/rules/resource.ts index 95894c847f71d..e7478a811fa57 100644 --- a/packages/awslint/lib/rules/resource.ts +++ b/packages/awslint/lib/rules/resource.ts @@ -189,7 +189,6 @@ resourceLinter.add({ // This rule is the worst resourceLinter.add({ code: 'resource-attribute', - warning: true, message: 'resources must represent all cloudformation attributes as attribute properties. ' + '"@attribute ATTR[,ATTR]" can be used to tag non-standard attribute names. ' +