Skip to content

Commit 9cbac89

Browse files
committed
fix: find ECR region in image full name
when trying to pull images from ECR, decide the AWS region they reside in based on the image full name. an image full name is in the registry/repository:tag format, for example: aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app:latest (https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html)
1 parent b589b59 commit 9cbac89

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

src/images/credentials.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import * as aws from 'aws-sdk';
22

3+
import logger = require('../common/logger');
4+
35
export async function getSourceCredentials(imageSource: string): Promise<string | undefined> {
46
// TODO is this the best way we can determine the image's source?
57
if (imageSource.indexOf('.ecr.') !== -1) {
6-
return getEcrCredentials();
8+
const ecrRegion = ecrRegionFromFullImageName(imageSource);
9+
return getEcrCredentials(ecrRegion);
710
}
811
return undefined;
912
}
1013

11-
function getEcrCredentials(): Promise<string> {
14+
function getEcrCredentials(region: string): Promise<string> {
1215
return new Promise(async (resolve, reject) => {
13-
// TODO grab region... from...? ask users to provide it?
14-
const ecr = new aws.ECR({region: 'us-east-2'});
16+
const ecr = new aws.ECR({region});
1517
return ecr.getAuthorizationToken({}, (err, data) => {
1618
if (err) {
1719
return reject(err);
@@ -38,3 +40,29 @@ function getEcrCredentials(): Promise<string> {
3840
});
3941
});
4042
}
43+
44+
export function ecrRegionFromFullImageName(imageFullName: string): string {
45+
// should look like this
46+
// aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app:latest
47+
// https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html
48+
try {
49+
const [registry, repository] = imageFullName.split('/');
50+
if (!repository) {
51+
throw new Error('ECR image full name missing repository');
52+
}
53+
54+
const parts = registry.split('.');
55+
if (!(
56+
parts.length === 6 &&
57+
parts[1] === 'dkr' &&
58+
parts[2] === 'ecr' &&
59+
parts[4] === 'amazonaws'
60+
)) {
61+
throw new Error('ECR image full name in unexpected format');
62+
}
63+
return parts[3];
64+
} catch (err) {
65+
logger.error({err, imageFullName}, 'failed extracting ECR region from image full name');
66+
throw err;
67+
}
68+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as tap from 'tap';
2+
3+
import * as credentials from '../../src/images/credentials';
4+
5+
tap.test('ecrRegionFromFullImageName()', async (t) => {
6+
const imageFullNameTemplate = 'aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app:latest';
7+
const ecrRegionTemplate = credentials.ecrRegionFromFullImageName(imageFullNameTemplate);
8+
t.equals(ecrRegionTemplate, 'region', 'extracts region from the image full name template');
9+
10+
const imageFullName = '291964488713.dkr.ecr.us-east-2.amazonaws.com/snyk/debian:10';
11+
const ecrRegion = credentials.ecrRegionFromFullImageName(imageFullName);
12+
t.equals(ecrRegion, 'us-east-2', 'extracts region from the image full name fixture');
13+
14+
t.throws(() => {credentials.ecrRegionFromFullImageName('');}, 'throws on badly formatted images');
15+
t.throws(() => {credentials.ecrRegionFromFullImageName('dkr.ecr.region.amazonaws.com/my-web-app:latest');}, 'throws on badly formatted images');
16+
t.throws(() => {credentials.ecrRegionFromFullImageName('aws_account_id.dkr.ecr.amazonaws.com/my-web-app:latest');}, 'throws on badly formatted images');
17+
t.throws(() => {credentials.ecrRegionFromFullImageName('aws_account_id.dkr.ecr.region.amazonaws.com');}, 'throws on badly formatted images');
18+
});

0 commit comments

Comments
 (0)