func (dk *BasicDockerKeyring) Lookup(image string) ([]docker.AuthConfiguration, bool) {
	ret := []docker.AuthConfiguration{}
	for _, k := range dk.index {
		if matched, _ := urlsMatchStr(k, image); !matched {
			continue
		}
		ret = append(ret, dk.creds[k]...)
	}
	if len(ret) > 0 {
		return ret, true
	}
	if isDefaultRegistryMatch(image) {
		if auth, ok := dk.creds[defaultRegistryHost]; ok {
			return auth, true
		}
	}
	return []docker.AuthConfiguration{}, false
}
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.
package credentialprovider
import (
	"encoding/json"
	"net"
	"net/url"
	"path/filepath"
	"sort"
	"strings"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/golang/glog"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/util/sets"
)
type DockerKeyring interface {
	Lookup(image string) ([]docker.AuthConfiguration, bool)
}
type BasicDockerKeyring struct {
	index []string
	creds map[string][]docker.AuthConfiguration
}
type lazyDockerKeyring struct {
	Providers []DockerConfigProvider
}
func (dk *BasicDockerKeyring) Add(cfg DockerConfig) {
	if dk.index == nil {
		dk.index = make([]string, 0)
		dk.creds = make(map[string][]docker.AuthConfiguration)
	}
	for loc, ident := range cfg {
		creds := docker.AuthConfiguration{
			Username: ident.Username,
			Password: ident.Password,
			Email:    ident.Email,
		}
		value := loc
		if !strings.HasPrefix(value, "https://") && !strings.HasPrefix(value, "http://") {
			value = "https://" + value
		}
		parsed, err := url.Parse(value)
		if err != nil {
			glog.Errorf("Entry %q in dockercfg invalid (%v), ignoring", loc, err)
			continue
		}
		effectivePath := parsed.Path
		if strings.HasPrefix(effectivePath, "/v2/") || strings.HasPrefix(effectivePath, "/v1/") {
			effectivePath = effectivePath[3:]
		}
		var key string
		if (len(effectivePath) > 0) && (effectivePath != "/") {
			key = parsed.Host + effectivePath
		} else {
			key = parsed.Host
		}
		dk.creds[key] = append(dk.creds[key], creds)
		dk.index = append(dk.index, key)
	}
	eliminateDupes := sets.NewString(dk.index...)
	dk.index = eliminateDupes.List()
	sort.Sort(sort.Reverse(sort.StringSlice(dk.index)))
}
const (
	defaultRegistryHost = "index.docker.io"
	defaultRegistryKey  = defaultRegistryHost + "/v1/"
)
func isDefaultRegistryMatch(image string) bool {
	parts := strings.SplitN(image, "/", 2)
	if len(parts[0]) == 0 {
		return false
	}
	if len(parts) == 1 {
		return true
	}
	if parts[0] == "docker.io" || parts[0] == "index.docker.io" {
		return true
	}
	return !strings.ContainsAny(parts[0], ".:")
}
func parseSchemelessUrl(schemelessUrl string) (*url.URL, error) {
	parsed, err := url.Parse("https://" + schemelessUrl)
	if err != nil {
		return nil, err
	}
	parsed.Scheme = ""
	return parsed, nil
}
func splitUrl(url *url.URL) (parts []string, port string) {
	host, port, err := net.SplitHostPort(url.Host)
	if err != nil {
		host, port = url.Host, ""
	}
	return strings.Split(host, "."), port
}
func urlsMatchStr(glob string, target string) (bool, error) {
	globUrl, err := parseSchemelessUrl(glob)
	if err != nil {
		return false, err
	}
	targetUrl, err := parseSchemelessUrl(target)
	if err != nil {
		return false, err
	}
	return urlsMatch(globUrl, targetUrl)
}
func urlsMatch(globUrl *url.URL, targetUrl *url.URL) (bool, error) {
	globUrlParts, globPort := splitUrl(globUrl)
	targetUrlParts, targetPort := splitUrl(targetUrl)
	if globPort != targetPort {
		return false, nil
	}
	if len(globUrlParts) != len(targetUrlParts) {
		return false, nil
	}
	if !strings.HasPrefix(targetUrl.Path, globUrl.Path) {
		return false, nil
	}
	for k, globUrlPart := range globUrlParts {
		targetUrlPart := targetUrlParts[k]
		matched, err := filepath.Match(globUrlPart, targetUrlPart)
		if err != nil {
			return false, err
		}
		if !matched {
			return false, nil
		}
	}
	return true, nil
}