make the dockerkeyring handle mutiple matching credentials

This commit is contained in:
deads2k
2015-05-08 13:30:59 -04:00
parent 16a76f1bd3
commit 2ecb0ebd73
9 changed files with 142 additions and 65 deletions

View File

@@ -23,6 +23,8 @@ import (
docker "github.com/fsouza/go-dockerclient"
"github.com/golang/glog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
// DockerKeyring tracks a set of docker registry credentials, maintaining a
@@ -33,13 +35,13 @@ import (
// most specific match for a given image
// - iterating a map does not yield predictable results
type DockerKeyring interface {
Lookup(image string) (docker.AuthConfiguration, bool)
Lookup(image string) ([]docker.AuthConfiguration, bool)
}
// BasicDockerKeyring is a trivial map-backed implementation of DockerKeyring
type BasicDockerKeyring struct {
index []string
creds map[string]docker.AuthConfiguration
creds map[string][]docker.AuthConfiguration
}
// lazyDockerKeyring is an implementation of DockerKeyring that lazily
@@ -51,9 +53,10 @@ type lazyDockerKeyring struct {
func (dk *BasicDockerKeyring) Add(cfg DockerConfig) {
if dk.index == nil {
dk.index = make([]string, 0)
dk.creds = make(map[string]docker.AuthConfiguration)
dk.creds = make(map[string][]docker.AuthConfiguration)
}
for loc, ident := range cfg {
creds := docker.AuthConfiguration{
Username: ident.Username,
Password: ident.Password,
@@ -73,15 +76,19 @@ func (dk *BasicDockerKeyring) Add(cfg DockerConfig) {
// See ResolveAuthConfig in docker/registry/auth.go.
if parsed.Host != "" {
// NOTE: foo.bar.com comes through as Path.
dk.creds[parsed.Host] = creds
dk.creds[parsed.Host] = append(dk.creds[parsed.Host], creds)
dk.index = append(dk.index, parsed.Host)
}
if parsed.Path != "/" {
dk.creds[parsed.Host+parsed.Path] = creds
dk.index = append(dk.index, parsed.Host+parsed.Path)
if (len(parsed.Path) > 0) && (parsed.Path != "/") {
key := parsed.Host + parsed.Path
dk.creds[key] = append(dk.creds[key], creds)
dk.index = append(dk.index, key)
}
}
eliminateDupes := util.NewStringSet(dk.index...)
dk.index = eliminateDupes.List()
// Update the index used to identify which credentials to use for a given
// image. The index is reverse-sorted so more specific paths are matched
// first. For example, if for the given image "quay.io/coreos/etcd",
@@ -109,11 +116,12 @@ func isDefaultRegistryMatch(image string) bool {
return !strings.ContainsAny(parts[0], ".:")
}
// Lookup implements the DockerKeyring method for fetching credentials
// based on image name.
func (dk *BasicDockerKeyring) Lookup(image string) (docker.AuthConfiguration, bool) {
// range over the index as iterating over a map does not provide
// a predictable ordering
// Lookup implements the DockerKeyring method for fetching credentials based on image name.
// Multiple credentials may be returned if there are multiple potentially valid credentials
// available. This allows for rotation.
func (dk *BasicDockerKeyring) Lookup(image string) ([]docker.AuthConfiguration, bool) {
// range over the index as iterating over a map does not provide a predictable ordering
ret := []docker.AuthConfiguration{}
for _, k := range dk.index {
// NOTE: prefix is a sufficient check because while scheme is allowed,
// it is stripped as part of 'Add'
@@ -121,7 +129,11 @@ func (dk *BasicDockerKeyring) Lookup(image string) (docker.AuthConfiguration, bo
continue
}
return dk.creds[k], true
ret = append(ret, dk.creds[k]...)
}
if len(ret) > 0 {
return ret, true
}
// Use credentials for the default registry if provided, and appropriate
@@ -129,12 +141,12 @@ func (dk *BasicDockerKeyring) Lookup(image string) (docker.AuthConfiguration, bo
return auth, true
}
return docker.AuthConfiguration{}, false
return []docker.AuthConfiguration{}, false
}
// Lookup implements the DockerKeyring method for fetching credentials
// based on image name.
func (dk *lazyDockerKeyring) Lookup(image string) (docker.AuthConfiguration, bool) {
func (dk *lazyDockerKeyring) Lookup(image string) ([]docker.AuthConfiguration, bool) {
keyring := &BasicDockerKeyring{}
for _, p := range dk.Providers {
@@ -145,10 +157,10 @@ func (dk *lazyDockerKeyring) Lookup(image string) (docker.AuthConfiguration, boo
}
type FakeKeyring struct {
auth docker.AuthConfiguration
auth []docker.AuthConfiguration
ok bool
}
func (f *FakeKeyring) Lookup(image string) (docker.AuthConfiguration, bool) {
func (f *FakeKeyring) Lookup(image string) ([]docker.AuthConfiguration, bool) {
return f.auth, f.ok
}