make the dockerkeyring handle mutiple matching credentials
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user