Skip to content

Commit

Permalink
fix(toolkit-cleaner): docker images with prefixed tags are always del…
Browse files Browse the repository at this point in the history
…eted (#250)

Use the hash of the dummy docker image to determine if 
there is a prefix.

Fixes #246
  • Loading branch information
jogold authored Dec 29, 2023
1 parent 7336490 commit be7bf44
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 10 deletions.
16 changes: 15 additions & 1 deletion src/toolkit-cleaner/extract-template-hashes.lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,21 @@ export async function handler(stackName: string) {
return [];
}

const hashes = template.TemplateBody.match(/[a-f0-9]{64}/g);
if (!process.env.DOCKER_IMAGE_ASSET_HASH) {
throw new Error('Missing DOCKER_IMAGE_ASSET_HASH environment variable');
}
const dockerTagPrefix = findDockerTagPrefix(process.env.DOCKER_IMAGE_ASSET_HASH);

const regexp = new RegExp(`(${dockerTagPrefix})?[a-f0-9]{64}`, 'g');
const hashes = template.TemplateBody.match(regexp);

return [...new Set(hashes)];
}

function findDockerTagPrefix(hash: string): string {
if (hash.length === 64) {
return '';
}

return hash.substring(0, hash.length - 64);
}
3 changes: 3 additions & 0 deletions src/toolkit-cleaner/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ export class ToolkitCleaner extends Construct {

const extractTemplateHashesFunction = new ExtractTemplateHashesFunction(this, 'ExtractTemplateHashesFunction', {
timeout: Duration.seconds(30),
environment: {
DOCKER_IMAGE_ASSET_HASH: dockerImageAsset.assetHash,
},
});
extractTemplateHashesFunction.addToRolePolicy(new PolicyStatement({
actions: ['cloudformation:GetTemplate'],
Expand Down
25 changes: 22 additions & 3 deletions test/toolkit-cleaner/extract-template-hashes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { mockClient } from 'aws-sdk-client-mock';
import { handler } from '../../src/toolkit-cleaner/extract-template-hashes.lambda';

const cloudFormationClientMock = mockClient(CloudFormationClient);
cloudFormationClientMock.on(GetTemplateCommand).resolves({
TemplateBody: 'hello 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 world 486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
});

test('extracts hashes', async () => {
process.env.DOCKER_IMAGE_ASSET_HASH = '5a7abf30ce10141adcb73c9b836ec68479c65fb4d1693df160563e36ece0d55e';

cloudFormationClientMock.on(GetTemplateCommand).resolves({
TemplateBody: 'hello 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 world 486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
});

const response = await handler('stack1');

Expand All @@ -19,3 +21,20 @@ test('extracts hashes', async () => {
'486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
]);
});

test('extracts hashes with docker tag prefix', async () => {
process.env.DOCKER_IMAGE_ASSET_HASH = 'prefix5a7abf30ce10141adcb73c9b836ec68479c65fb4d1693df160563e36ece0d55e';

cloudFormationClientMock.on(GetTemplateCommand).resolves({
TemplateBody: 'hello prefix2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 world 486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
});

const response = await handler('stack1');

expect(cloudFormationClientMock).toHaveReceivedCommandWith(GetTemplateCommand, { StackName: 'stack1' });

expect(response).toEqual([
'prefix2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824',
'486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7',
]);
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
}
}
},
"e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520": {
"839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9": {
"source": {
"path": "asset.e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520.lambda",
"path": "asset.839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9.lambda",
"packaging": "zip"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520.zip",
"objectKey": "839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9.zip",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down Expand Up @@ -79,15 +79,15 @@
}
}
},
"14fd8c2a54dd634868c0496f806f1d30d38056ee29131403ae4e4166ed615812": {
"98fffe1b2edbf8c7f26bc9d9b99a394ae270f6137796d379c74d08efc690cabb": {
"source": {
"path": "toolkit-cleaner-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "14fd8c2a54dd634868c0496f806f1d30d38056ee29131403ae4e4166ed615812.json",
"objectKey": "98fffe1b2edbf8c7f26bc9d9b99a394ae270f6137796d379c74d08efc690cabb.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"S3Key": "e2fc900c4989c9292d92789a3c86dc4c928e649bf168c2547f48b503dd41a520.zip"
"S3Key": "839231c3a66de2124ed53cba376ac7d09e962b10a04d77f96cd2f74e930f75c9.zip"
},
"Role": {
"Fn::GetAtt": [
Expand All @@ -155,6 +155,7 @@
"Description": "src/toolkit-cleaner/extract-template-hashes.lambda.ts",
"Environment": {
"Variables": {
"DOCKER_IMAGE_ASSET_HASH": "59bc252bbfc4819edcc48f546a0ea71b7b108d3899f8f503cd6f5bcc1f375126",
"AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1"
}
},
Expand Down

0 comments on commit be7bf44

Please sign in to comment.