3

I'm trying to run this AWS CLI command:

aws ecr get-login --no-include-email --region <my-region>

But using the JavaScript SDK with new AWS.ECR(..).getAuthorizationToken method but I'm getting this error:

Error response from daemon: login attempt to https://xxxxx.dkr.ecr.<my-region>.amazonaws.com/v2/ failed with status: 400 Bad Request

From my understanding, I need to use some flag that is equal to the --no-include-email argument in the CLI command but I cannot find how to set it with the JavaScript SDK.

This is my code:

const ecr = new AWS.ECR({
    apiVersion: '2015-09-21',
    region: 'my-region'
});

const { authorizationData } = await ecr.getAuthorizationToken().promise();

if(!authorizationData || !authorizationData[0] || !authorizationData[0].authorizationToken){
    throw new Error('AWS getAuthorizationToken failed');
}

const password = authorizationData[0].authorizationToken;
const proxyEndpoint = authorizationData[0].proxyEndpoint;

await childProcessP.spawn('docker', [
    'login',
    '-u', 'AWS',
    '-p', password,
    proxyEndpoint
]);

Do anyone know how to do it?

Shlomi
  • 3,622
  • 5
  • 23
  • 34
  • How did you manage to solve it? – Totty.js Jan 18 '19 at 11:46
  • I'm not, just executed it as a bash command :( – Shlomi Jan 18 '19 at 12:04
  • oh crap... I was trying to upgrade my legacy bash command to something more proper... :/ I guess that's the way to go. Thanks anyway – Totty.js Jan 18 '19 at 12:07
  • We have AWS guys in our offices every week, I'll try to promote some feature request with them :) – Shlomi Jan 18 '19 at 12:38
  • That would be great. I think it should work but I can't get it to work. I'm using aws-sdk to login and get key and then use dockerode to push, but no luck. I have here my question: https://stackoverflow.com/questions/54252777/how-to-push-image-with-dockerode-image-not-pushed-but-no-error bashing my head for hours, and ended up with old bash solution... Not sure is even a aws issue at this point – Totty.js Jan 18 '19 at 12:51

3 Answers3

1

the AuthorizationToken contains a base64 encoded <username>:<password>

all you need to do is decode and split to get the values you want.

Rick Burgess
  • 704
  • 1
  • 5
  • 12
0

I have the same issue by using (golang) docker ENGINE libraries.

First I get credential (like you) from the ecr.GetAuthorizationToken() Then i call docker.RegistryLogin() function.

Here's my code:

authToken, err  := ecrSession.GetAuthorizationToken(&ecr.GetAuthorizationTokenInput{})
    if err != nil {
        color.Red(fmt.Sprintf("Getting ECR auth token: %s", err.Error()))
        return err
    }

    auth := types.AuthConfig{
        Username: "AWS",
        Password: *authToken.AuthorizationData[0].AuthorizationToken,
        ServerAddress: *authToken.AuthorizationData[0].ProxyEndpoint,

    }

     authenticatedOK, err := cli.RegistryLogin(ctx, auth)

always return to me 400 bad request.

However by running commands from shell:

aws ecr get-login --no-include-email --region eu-west-1

then copy paste the returning output

docker login -u AWS -p ... http://account-id.dkr.ecr.eu-west-1.amazonaws.com it works fine.

Sashimi
  • 103
  • 1
  • 9
  • I've noticed also that if I run `aws ecr get-login --no-include-email --region eu-west-1` the resulting token differs from the one generated at runtime from `ecrSession.GetAuthorizationToken` function. So I forced the code to use the token resulting from shell command and the request goes fine. I've also tried to run shell command without `--no-include-email` but the token it's still the same (the correct one). – Sashimi May 08 '18 at 15:46
0

I have had the same issue and I found in the documentation the token return in authToken.AuthorizationData[0].AuthorizationToken is a base 64 encoded string.

So if you want to use it to login your docker you have first decoded it.

When decoded you will se the something like: AWS:eyJwYXlsb2FkIjoiZGhtVzc5Sj....

It turns out the token is encoded with the user. Therefore, you have to take out the AWS: and use the remain string.