Skip to content

Commit 942f938

Browse files
alex-bergerrix0rrr
authored andcommittedMar 19, 2019
feat(aws-cdk): support fixed repository name for DockerImageAsset (#2032)
Add a `repositoryName` argument to `DockerImageAsset` to control the name of the repository that the image gets uploaded to. This makes it easier to reference Docker Images created and deployed by CDK from EKS (Kubernetes) YAML resource files.
1 parent 133dc98 commit 942f938

File tree

6 files changed

+96
-6
lines changed

6 files changed

+96
-6
lines changed
 

‎packages/@aws-cdk/assets-docker/lib/image-asset.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ export interface DockerImageAssetProps {
1010
* The directory where the Dockerfile is stored
1111
*/
1212
directory: string;
13+
14+
/**
15+
* ECR repository name
16+
*
17+
* Specify this property if you need to statically address the image, e.g.
18+
* from a Kubernetes Pod. Note, this is only the repository name, without the
19+
* registry and the tag parts.
20+
*
21+
* @default automatically derived from the asset's ID.
22+
*/
23+
repositoryName?: string;
1324
}
1425

1526
/**
@@ -55,7 +66,8 @@ export class DockerImageAsset extends cdk.Construct {
5566
packaging: 'container-image',
5667
path: this.directory,
5768
id: this.node.uniqueId,
58-
imageNameParameter: imageNameParameter.logicalId
69+
imageNameParameter: imageNameParameter.logicalId,
70+
repositoryName: props.repositoryName,
5971
};
6072

6173
this.node.addMetadata(cxapi.ASSET_METADATA, asset);

‎packages/@aws-cdk/cx-api/lib/metadata/assets.ts

+11
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ export interface ContainerImageAssetMetadataEntry {
7373
* ECR Repository name and tag (separated by ":") where this asset is stored.
7474
*/
7575
imageNameParameter: string;
76+
77+
/**
78+
* ECR repository name, if omitted a default name based on the asset's
79+
* ID is used instead. Specify this property if you need to statically
80+
* address the image, e.g. from a Kubernetes Pod.
81+
* Note, this is only the repository name, without the registry and
82+
* the tag parts.
83+
*
84+
* * @default automatically derived from the asset's ID.
85+
*/
86+
repositoryName?: string;
7687
}
7788

7889
export type AssetMetadataEntry = FileAssetMetadataEntry | ContainerImageAssetMetadataEntry;

‎packages/aws-cdk/lib/api/toolkit-info.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,17 @@ export class ToolkitInfo {
9999
/**
100100
* Prepare an ECR repository for uploading to using Docker
101101
*/
102-
public async prepareEcrRepository(assetId: string): Promise<EcrRepositoryInfo> {
102+
public async prepareEcrRepository(asset: cxapi.ContainerImageAssetMetadataEntry): Promise<EcrRepositoryInfo> {
103103
const ecr = await this.props.sdk.ecr(this.props.environment, Mode.ForWriting);
104-
105-
// Repository name based on asset id
106-
const repositoryName = 'cdk/' + assetId.replace(/[:/]/g, '-').toLowerCase();
104+
let repositoryName;
105+
if ( asset.repositoryName ) {
106+
// Repository name provided by user
107+
repositoryName = asset.repositoryName;
108+
} else {
109+
// Repository name based on asset id
110+
const assetId = asset.id;
111+
repositoryName = 'cdk/' + assetId.replace(/[:/]/g, '-').toLowerCase();
112+
}
107113

108114
let repository;
109115
try {

‎packages/aws-cdk/lib/docker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export async function prepareContainerAsset(asset: ContainerImageAssetMetadataEn
4343

4444
const buildHold = new PleaseHold(` ⌛ Building Asset Docker image ${asset.id} from ${asset.path}; this may take a while.`);
4545
try {
46-
const ecr = await toolkitInfo.prepareEcrRepository(asset.id);
46+
const ecr = await toolkitInfo.prepareEcrRepository(asset);
4747
const latest = `${ecr.repositoryUri}:latest`;
4848

4949
let loggedIn = false;

‎packages/aws-cdk/test/test.docker.ts

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import cxapi = require('@aws-cdk/cx-api');
2+
import { Test } from 'nodeunit';
3+
import { ToolkitInfo } from '../lib';
4+
import { prepareContainerAsset } from '../lib/docker';
5+
import { MockSDK } from './util/mock-sdk';
6+
7+
export = {
8+
async 'creates repository with given name'(test: Test) {
9+
// GIVEN
10+
11+
let createdName;
12+
13+
const sdk = new MockSDK();
14+
sdk.stubEcr({
15+
describeRepositories() {
16+
return { repositories: [] };
17+
},
18+
19+
createRepository(req) {
20+
createdName = req.repositoryName;
21+
22+
// Stop the test so that we don't actually docker build
23+
throw new Error('STOPTEST');
24+
},
25+
});
26+
27+
const toolkit = new ToolkitInfo({
28+
sdk,
29+
bucketName: 'BUCKET_NAME',
30+
bucketEndpoint: 'BUCKET_ENDPOINT',
31+
environment: { name: 'env', account: '1234', region: 'abc' }
32+
});
33+
34+
// WHEN
35+
const asset: cxapi.ContainerImageAssetMetadataEntry = {
36+
id: 'assetId',
37+
imageNameParameter: 'MyParameter',
38+
packaging: 'container-image',
39+
path: '/foo',
40+
repositoryName: 'some-name',
41+
};
42+
43+
try {
44+
await prepareContainerAsset(asset, toolkit, false);
45+
} catch (e) {
46+
if (!/STOPTEST/.test(e.toString())) { throw e; }
47+
}
48+
49+
// THEN
50+
test.deepEqual(createdName, 'some-name');
51+
52+
test.done();
53+
},
54+
};

‎packages/aws-cdk/test/util/mock-sdk.ts

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ export class MockSDK extends SDK {
2121
public stubCloudFormation(stubs: SyncHandlerSubsetOf<AWS.CloudFormation>) {
2222
this.sandbox.stub(this, 'cloudFormation').returns(Promise.resolve(partialAwsService<AWS.CloudFormation>(stubs)));
2323
}
24+
25+
/**
26+
* Replace the ECR client with the given object
27+
*/
28+
public stubEcr(stubs: SyncHandlerSubsetOf<AWS.ECR>) {
29+
this.sandbox.stub(this, 'ecr').returns(Promise.resolve(partialAwsService<AWS.ECR>(stubs)));
30+
}
2431
}
2532

2633
/**

0 commit comments

Comments
 (0)