Skip to content

Commit

Permalink
ECR auth: multi-region support
Browse files Browse the repository at this point in the history
  • Loading branch information
protomouse committed Apr 15, 2016
1 parent 37b71e9 commit 0118947
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* `emp run` now works with unofficial Docker registries [#740](https://github.com/remind101/empire/pull/740).
* `emp scale -l` now lists configured scale, not the running processes [#769](https://github.com/remind101/empire/pull/769)
* Fixed a bug where it was previously possible to create a signed access token with an empty username [#780](https://github.com/remind101/empire/pull/780)
* ECR authentication now supports multiple regions, and works independently of ECS region [#784](https://github.com/remind101/empire/pull/784)

**Performance**

Expand Down
5 changes: 4 additions & 1 deletion cmd/empire/factories.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,11 @@ func newHBReporter(key, env string) (reporter.Reporter, error) {
// Auth provider =======================

func newAuthProvider(c *cli.Context) (dockerauth.AuthProvider, error) {
awsSession := newConfigProvider(c)
provider := dockerauth.NewMultiAuthProvider()
provider.AddProvider(dockerauth.NewECRAuthProvider(ecr.New(newConfigProvider(c))))
provider.AddProvider(dockerauth.NewECRAuthProvider(func(region string) dockerauth.ECR {
return ecr.New(awsSession, &aws.Config{Region: aws.String(region)})
}))

if dockerConfigPath := c.String(FlagDockerAuth); dockerConfigPath != "" {
dockerConfigFile, err := os.Open(dockerConfigPath)
Expand Down
19 changes: 11 additions & 8 deletions pkg/dockerauth/ecr.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ type ECR interface {
GetAuthorizationToken(*ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error)
}

type ECRFactory func(region string) ECR

type ecrAuthProvider struct {
svc ECR
svcFactory ECRFactory
}

func NewECRAuthProvider(svc ECR) *ecrAuthProvider {
func NewECRAuthProvider(svcFactory ECRFactory) *ecrAuthProvider {
return &ecrAuthProvider{
svc: svc,
svcFactory: svcFactory,
}
}

func (p *ecrAuthProvider) AuthConfiguration(registry string) (*docker.AuthConfiguration, error) {
registryId, err := extractRegistryId(registry)
registryId, registryRegion, err := extractRegistryInfo(registry)
if err != nil {
return nil, nil
}
Expand All @@ -39,7 +41,8 @@ func (p *ecrAuthProvider) AuthConfiguration(registry string) (*docker.AuthConfig
},
}

output, err := p.svc.GetAuthorizationToken(input)
svc := p.svcFactory(registryRegion)
output, err := svc.GetAuthorizationToken(input)
if err != nil {
return nil, err
}
Expand All @@ -52,13 +55,13 @@ func (p *ecrAuthProvider) AuthConfiguration(registry string) (*docker.AuthConfig
return newAuthConfiguration(aws.StringValue(authData.AuthorizationToken), aws.StringValue(authData.ProxyEndpoint))
}

func extractRegistryId(registry string) (string, error) {
func extractRegistryInfo(registry string) (string, string, error) {
matches := ecrRegistryExp.FindStringSubmatch(registry)
if len(matches) == 0 {
return "", fmt.Errorf("%q is not an ECR registry", registry)
return "", "", fmt.Errorf("%q is not an ECR registry", registry)
}

return matches[1], nil
return matches[1], matches[2], nil
}

func newAuthConfiguration(encodedToken string, endpoint string) (*docker.AuthConfiguration, error) {
Expand Down
14 changes: 9 additions & 5 deletions pkg/dockerauth/ecr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ import (
"github.com/stretchr/testify/mock"
)

func TestECRAuthProvider_extractRegistryId(t *testing.T) {
registryId, err := extractRegistryId("123456789012.dkr.ecr.us-east-1.amazonaws.com")
func TestECRAuthProvider_extractRegistryInfo(t *testing.T) {
registryId, registryRegion, err := extractRegistryInfo("123456789012.dkr.ecr.us-east-1.amazonaws.com")
assert.NoError(t, err)
assert.Equal(t, "123456789012", registryId)
assert.Equal(t, "us-east-1", registryRegion)

registryId, err = extractRegistryId("https://index.docker.io/v1")
_, _, err = extractRegistryInfo("https://index.docker.io/v1")
assert.EqualError(t, err, "\"https://index.docker.io/v1\" is not an ECR registry")

registryId, err = extractRegistryId("")
_, _, err = extractRegistryInfo("")
assert.EqualError(t, err, "\"\" is not an ECR registry")
}

Expand All @@ -36,7 +37,10 @@ func TestECRAuthProvider_AuthConfiguration(t *testing.T) {
svc := new(mockECR)
svc.On("GetAuthorizationToken", newGetAuthorizationTokenInput("123456789012")).Return(newGetAuthorizationTokenOutput("123456789012", "us-east-1", "foo:bar"), nil)
svc.On("GetAuthorizationToken", newGetAuthorizationTokenInput("123456789013")).Return(&ecr.GetAuthorizationTokenOutput{}, nil)
provider := NewECRAuthProvider(svc)
provider := NewECRAuthProvider(func(region string) ECR {
assert.Equal(t, "us-east-1", region)
return svc
})
authConf, err := provider.AuthConfiguration("123456789012.dkr.ecr.us-east-1.amazonaws.com")
assert.NoError(t, err)
assert.Equal(t, "foo", authConf.Username)
Expand Down

0 comments on commit 0118947

Please sign in to comment.