Skip to content

Commit

Permalink
Added ECR support
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaoTrann committed Jul 25, 2019
1 parent 5df03d8 commit ad41e26
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 40 deletions.
38 changes: 25 additions & 13 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 19 additions & 11 deletions lib/backend/registrybackend/security/basicauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"fmt"
"net/http"
"net/url"
"strings"

"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/auth/challenge"
Expand All @@ -41,19 +42,26 @@ func BasicAuthTransport(addr, repo string, tr http.RoundTripper, authConfig type
if err != nil {
return nil, fmt.Errorf("ping v2 registry: %s", err)
}
opts := auth.TokenHandlerOptions{
Transport: tr,
Credentials: defaultCredStore{authConfig},
Scopes: []auth.Scope{
auth.RepositoryScope{
Repository: repo,
Actions: []string{"pull", "push"},
// This looks weird but when using AWS ECR (especially the docker ecr helper) we get a Username and a Password
// Then, the ping will create a challenge by parsing the www-authenticate header from the ECR server (it will return a "Basic ...")
// So if we use the `NewTokenHandlerWithOptions` we will always fail the Scheme checking in vendor/github.com/docker/distribution/registry/client/auth/session.go#L98 ("basic" != "bearer")
if authConfig.Username != "" && authConfig.Password != "" && strings.HasSuffix(addr, "amazonaws.com") {
return transport.NewTransport(tr, auth.NewAuthorizer(cm, auth.NewBasicHandler(defaultCredStore{authConfig}))), nil
} else {
opts := auth.TokenHandlerOptions{
Transport: tr,
Credentials: defaultCredStore{authConfig},
Scopes: []auth.Scope{
auth.RepositoryScope{
Repository: repo,
Actions: []string{"pull", "push"},
},
},
},
ClientID: "docker",
ForceOAuth: false, // Only support basic auth.
ClientID: "docker",
ForceOAuth: false, // Only support basic auth.
}
return transport.NewTransport(tr, auth.NewAuthorizer(cm, auth.NewTokenHandlerWithOptions(opts))), nil
}
return transport.NewTransport(tr, auth.NewAuthorizer(cm, auth.NewTokenHandlerWithOptions(opts))), nil
}

func ping(addr string, tr http.RoundTripper) (challenge.Manager, error) {
Expand Down
47 changes: 31 additions & 16 deletions lib/backend/registrybackend/security/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"fmt"
"net/http"

"github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
"github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api"
"github.com/uber/kraken/utils/httputil"

"github.com/docker/docker-credential-helpers/client"
Expand Down Expand Up @@ -78,22 +80,35 @@ func (c Config) getCredentials(helper, addr string) (types.AuthConfig, error) {
}

func (c Config) getCredentialFromHelper(helper, addr string) (types.AuthConfig, error) {
helperFullName := credentialHelperPrefix + helper
creds, err := client.Get(client.NewShellProgramFunc(helperFullName), addr)
if err != nil {
return types.AuthConfig{}, err
}
switch helper {
case "ecr-login":
client := ecr.ECRHelper{ClientFactory: api.DefaultClientFactory{}}
username, password, err := client.Get(addr)
if err != nil {
return types.AuthConfig{}, fmt.Errorf("get credentials from helper ECR: %s", err)
}
return types.AuthConfig{
Username: username,
Password: password,
}, nil
default:
helperFullName := credentialHelperPrefix + helper
creds, err := client.Get(client.NewShellProgramFunc(helperFullName), addr)
if err != nil {
return types.AuthConfig{}, err
}

var ret types.AuthConfig
if c.BasicAuth != nil {
ret = *c.BasicAuth
}
ret.ServerAddress = addr
if creds.Username == tokenUsername {
ret.IdentityToken = creds.Secret
} else {
ret.Password = creds.Secret
ret.Username = creds.Username
var ret types.AuthConfig
if c.BasicAuth != nil {
ret = *c.BasicAuth
}
ret.ServerAddress = addr
if creds.Username == tokenUsername {
ret.IdentityToken = creds.Secret
} else {
ret.Password = creds.Secret
ret.Username = creds.Username
}
return ret, nil
}
return ret, nil
}

0 comments on commit ad41e26

Please sign in to comment.