Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ include:
To use credentials associated with a different named profile in the shared credentials file (`~/.aws/credentials`), you
may set the `AWS_PROFILE` environment variable.

The Amazon ECR Docker Credential Helper can optionally read and support some configuration options specified in the AWS
shared configuration file (`~/.aws/config`). To use these options, you must set the `AWS_SDK_LOAD_CONFIG` environment
variable to `true`. The supported options include:
The Amazon ECR Docker Credential Helper reads and supports some configuration options specified in the AWS
shared configuration file (`~/.aws/config`). To disable these options, you must set the `AWS_SDK_LOAD_CONFIG` environment
variable to `false`. The supported options include:

* Assumed roles specified with `role_arn` and `source_profile`
* External credential processes specified with `credential_process`
Expand All @@ -202,12 +202,10 @@ The credentials must have a policy applied that
`docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repository:my-tag`

If you have configured additional profiles for use with the AWS CLI, you can use
those profiles by specifying the `AWS_PROFILE` environment variable when
invoking `docker`. If your profiles use assumed roles or additional credential
providing processes, you will also need to specify `AWS_SDK_LOAD_CONFIG=true`.
those profiles by specifying the `AWS_PROFILE` environment variable when invoking `docker`.
For example:

`AWS_SDK_LOAD_CONFIG=true AWS_PROFILE=myprofile docker pull 123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repository:my-tag`
`AWS_PROFILE=myprofile docker pull 123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repository:my-tag`

There is no need to use `docker login` or `docker logout`.

Expand Down
6 changes: 3 additions & 3 deletions docs/docker-credential-ecr-login.1
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ EC2 instance profiles, and ECS task roles.
To use credentials associated with a different named profile in the shared
credentials file, you may set the \fIAWS_PROFILE\fP environment variable.

The credential helper can optionally read and support some configuration
The credential helper reads and supports some configuration
options specified in the shared configuration file (\fI~/.aws/config\fP). To
use these options, you must set the \fIAWS_SDK_LOAD_CONFIG\fP environment
variable to \fItrue\fP. The supported options include:
disable these options, you must set the \fIAWS_SDK_LOAD_CONFIG\fP environment
variable to \fIfalse\fP. The supported options include:
.IP \[bu] 2
Assumed roles specified with \fIrole_arn\fP and \fIsource_profile\fP
.IP \[bu]
Expand Down
28 changes: 25 additions & 3 deletions ecr-login/api/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
package api

import (
"os"
"strconv"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
Expand Down Expand Up @@ -49,7 +52,10 @@ var userAgentHandler = request.NamedHandler{

// NewClientWithDefaults creates the client and defaults region
func (defaultClientFactory DefaultClientFactory) NewClientWithDefaults() Client {
awsSession := session.New()
awsSession := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: loadSharedConfigState(),
}))

awsSession.Handlers.Build.PushBackNamed(userAgentHandler)
awsConfig := awsSession.Config
return defaultClientFactory.NewClientWithOptions(Options{
Expand All @@ -60,7 +66,10 @@ func (defaultClientFactory DefaultClientFactory) NewClientWithDefaults() Client

// NewClientWithFipsEndpoint overrides the default ECR service endpoint in a given region to use the FIPS endpoint
func (defaultClientFactory DefaultClientFactory) NewClientWithFipsEndpoint(region string) (Client, error) {
awsSession := session.New()
awsSession := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: loadSharedConfigState(),
}))

awsSession.Handlers.Build.PushBackNamed(userAgentHandler)

endpoint, err := getServiceEndpoint("ecr-fips", region)
Expand All @@ -77,7 +86,9 @@ func (defaultClientFactory DefaultClientFactory) NewClientWithFipsEndpoint(regio

// NewClientFromRegion uses the region to create the client
func (defaultClientFactory DefaultClientFactory) NewClientFromRegion(region string) Client {
awsSession := session.New()
awsSession := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: loadSharedConfigState(),
}))
awsSession.Handlers.Build.PushBackNamed(userAgentHandler)
awsConfig := &aws.Config{Region: aws.String(region)}
return defaultClientFactory.NewClientWithOptions(Options{
Expand Down Expand Up @@ -109,3 +120,14 @@ func getServiceEndpoint(service, region string) (string, error) {
})
return endpoint.URL, err
}

func loadSharedConfigState() session.SharedConfigState {
loadConfig := os.Getenv("AWS_SDK_LOAD_CONFIG")
if loadConfig == "" {
return session.SharedConfigEnable
}
if enable, err := strconv.ParseBool(loadConfig); err == nil && !enable {
return session.SharedConfigDisable
}
return session.SharedConfigEnable
}
48 changes: 48 additions & 0 deletions ecr-login/api/factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.

package api

import (
"os"
"testing"

"github.com/aws/aws-sdk-go/aws/session"
"github.com/stretchr/testify/assert"
)

const loadConfigEnvVar = "AWS_SDK_LOAD_CONFIG"

func TestSharedConfigState(t *testing.T) {
defer func(value string) {
os.Setenv(loadConfigEnvVar, value)
}(os.Getenv(loadConfigEnvVar))

cases := []struct {
envValue string
expected session.SharedConfigState
}{
{"", session.SharedConfigEnable},
{"true", session.SharedConfigEnable},
{"false", session.SharedConfigDisable},
}

for _, testCase := range cases {
t.Run(testCase.envValue, func(t *testing.T) {
os.Setenv(loadConfigEnvVar, testCase.envValue)
state := loadSharedConfigState()
assert.NotNil(t, state)
assert.Equal(t, testCase.expected, state)
})
}
}