From bed2d0740653a6fd7822426f77bef8b3fec38b33 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 1 Dec 2023 21:58:08 -0500 Subject: [PATCH] feat(ecr): Add emptyOnDelete CloudFormation property to L2 construct --- .../aws-ecr-integ-stack.assets.json | 6 ++-- .../aws-ecr-integ-stack.template.json | 8 ++++++ .../test/integ.basic.js.snapshot/cdk.out | 2 +- ...efaultTestDeployAssert4F7FBFB4.assets.json | 2 +- .../test/integ.basic.js.snapshot/integ.json | 2 +- .../integ.basic.js.snapshot/manifest.json | 12 ++++++-- .../test/integ.basic.js.snapshot/tree.json | 28 +++++++++++++++++-- .../test/aws-ecr/test/integ.basic.ts | 4 +++ .../aws-cdk-lib/aws-ecr/lib/repository.ts | 8 ++++++ .../aws-ecr/test/repository.test.ts | 11 ++++++++ 10 files changed, 73 insertions(+), 10 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json index de9244e843078..4806953949c6c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json @@ -1,7 +1,7 @@ { - "version": "31.0.0", + "version": "35.0.0", "files": { - "a047e78171779d23d25e3fc35f2b3ce7ff7313e616a588b6f8773b9360f12b26": { + "7c7613fcf3318384ba85d0f5893acc56e522085d12fa287077dd58888f1f23dc": { "source": { "path": "aws-ecr-integ-stack.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "a047e78171779d23d25e3fc35f2b3ce7ff7313e616a588b6f8773b9360f12b26.json", + "objectKey": "7c7613fcf3318384ba85d0f5893acc56e522085d12fa287077dd58888f1f23dc.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json index fea2eae1cf611..932f8d5320695 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json @@ -65,6 +65,14 @@ } ] } + }, + "RepoWithEmptyOnDeleteCA5C67FA": { + "Type": "AWS::ECR::Repository", + "Properties": { + "EmptyOnDelete": true + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" } }, "Outputs": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out index 7925065efbcc4..c5cb2e5de6344 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"31.0.0"} \ No newline at end of file +{"version":"35.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json index fbfe3f9089f79..4a4a176d22fed 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json @@ -1,5 +1,5 @@ { - "version": "31.0.0", + "version": "35.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json index 8ded05fd44287..530efded1be3b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "31.0.0", + "version": "35.0.0", "testCases": { "cdk-ecr-integ-test-basic/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json index 299140c835cd5..91ee72e5a748d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "31.0.0", + "version": "35.0.0", "artifacts": { "aws-ecr-integ-stack.assets": { "type": "cdk:asset-manifest", @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-ecr-integ-stack.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a047e78171779d23d25e3fc35f2b3ce7ff7313e616a588b6f8773b9360f12b26.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7c7613fcf3318384ba85d0f5893acc56e522085d12fa287077dd58888f1f23dc.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -51,6 +52,12 @@ "data": "MyUserDefaultPolicy7B897426" } ], + "/aws-ecr-integ-stack/RepoWithEmptyOnDelete/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RepoWithEmptyOnDeleteCA5C67FA" + } + ], "/aws-ecr-integ-stack/RepositoryURI": [ { "type": "aws:cdk:logicalId", @@ -85,6 +92,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json index 5278e08ffe6e2..35e356fa8be0c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json @@ -127,6 +127,30 @@ "version": "0.0.0" } }, + "RepoWithEmptyOnDelete": { + "id": "RepoWithEmptyOnDelete", + "path": "aws-ecr-integ-stack/RepoWithEmptyOnDelete", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-ecr-integ-stack/RepoWithEmptyOnDelete/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ECR::Repository", + "aws:cdk:cloudformation:props": { + "emptyOnDelete": true + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecr.CfnRepository", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecr.Repository", + "version": "0.0.0" + } + }, "RepositoryURI": { "id": "RepositoryURI", "path": "aws-ecr-integ-stack/RepositoryURI", @@ -170,7 +194,7 @@ "path": "cdk-ecr-integ-test-basic/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.270" + "version": "10.3.0" } }, "DeployAssert": { @@ -216,7 +240,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.270" + "version": "10.3.0" } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.ts index 3830660077478..4c7b8a61bfb78 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.ts @@ -17,6 +17,10 @@ const user = new iam.User(stack, 'MyUser'); repo.grantRead(user); repo.grantPullPush(user); +new ecr.Repository(stack, 'RepoWithEmptyOnDelete', { + emptyOnDelete: true, +}); + new cdk.CfnOutput(stack, 'RepositoryURI', { value: repo.repositoryUri, }); diff --git a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts index ef4fa18d809c9..381d952648d66 100644 --- a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts +++ b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts @@ -569,6 +569,13 @@ export interface RepositoryProps { * @default false */ readonly autoDeleteImages?: boolean; + + /** + * If true, deleting the repository force deletes the contents of the repository. If false, the repository must be empty before attempting to delete it. + * + * @default false + */ + readonly emptyOnDelete?: boolean; } export interface RepositoryAttributes { @@ -706,6 +713,7 @@ export class Repository extends RepositoryBase { imageScanningConfiguration: props.imageScanOnPush !== undefined ? { scanOnPush: props.imageScanOnPush } : undefined, imageTagMutability: props.imageTagMutability || undefined, encryptionConfiguration: this.parseEncryption(props), + emptyOnDelete: props.emptyOnDelete, }); this._resource = resource; diff --git a/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts b/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts index 002c347688457..2e475fe59e1f3 100644 --- a/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts +++ b/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts @@ -77,6 +77,17 @@ describe('repository', () => { }); }); + test('emptyOnDelete can be set', () => { + // GIVEN + const stack = new cdk.Stack(); + new ecr.Repository(stack, 'Repo', { emptyOnDelete: true }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { + EmptyOnDelete: true, + }); + }); + test('add day-based lifecycle policy', () => { // GIVEN const stack = new cdk.Stack();