|
| 1 | +package auth |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/base64" |
| 5 | + "errors" |
| 6 | + "fmt" |
| 7 | + "github.com/cpuguy83/dockercfg" |
| 8 | + "github.com/distribution/reference" |
| 9 | + "github.com/docker/docker/api/types/registry" |
| 10 | + "log" |
| 11 | + "os" |
| 12 | +) |
| 13 | + |
| 14 | +type DefaultAuthProvider struct { |
| 15 | + authConfigs map[string]*registry.AuthConfig |
| 16 | +} |
| 17 | + |
| 18 | +func (d *DefaultAuthProvider) AuthConfig(ref reference.Named) registry.AuthConfig { |
| 19 | + domain := reference.Domain(ref) |
| 20 | + if ac, ok := d.authConfigs[domain]; ok { |
| 21 | + log.Printf("using auth config for %s", domain) |
| 22 | + return *ac |
| 23 | + } |
| 24 | + log.Printf("no auth config for %s", domain) |
| 25 | + return registry.AuthConfig{} |
| 26 | +} |
| 27 | + |
| 28 | +func NewDefaultProvider() (*DefaultAuthProvider, error) { |
| 29 | + authConfigs := map[string]*registry.AuthConfig{} |
| 30 | + |
| 31 | + cfg, err := dockercfg.LoadDefaultConfig() |
| 32 | + if err != nil && !errors.Is(err, os.ErrNotExist) { |
| 33 | + log.Printf("failed to load docker config: %v", err) |
| 34 | + return nil, err |
| 35 | + } else if errors.Is(err, os.ErrNotExist) { |
| 36 | + log.Printf("docker config not found, using empty config") |
| 37 | + return &DefaultAuthProvider{authConfigs}, nil |
| 38 | + } |
| 39 | + |
| 40 | + for k, v := range cfg.AuthConfigs { |
| 41 | + ac := ®istry.AuthConfig{ |
| 42 | + Username: v.Username, |
| 43 | + Password: v.Password, |
| 44 | + Email: v.Email, |
| 45 | + Auth: v.Auth, |
| 46 | + IdentityToken: v.IdentityToken, |
| 47 | + RegistryToken: v.RegistryToken, |
| 48 | + ServerAddress: v.ServerAddress, |
| 49 | + } |
| 50 | + if ac.Username == "" && ac.Password == "" { |
| 51 | + err := getCredentials(k, &cfg, ac) |
| 52 | + if err != nil { |
| 53 | + log.Printf("failed to get credentials for registry %s: %v", k, err) |
| 54 | + continue |
| 55 | + } |
| 56 | + } |
| 57 | + if ac.Auth == "" { |
| 58 | + ac.Auth = base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ac.Username, ac.Password))) |
| 59 | + } |
| 60 | + authConfigs[k] = ac |
| 61 | + } |
| 62 | + |
| 63 | + for k := range cfg.CredentialHelpers { |
| 64 | + err := getCredentials(k, &cfg, authConfigs[k]) |
| 65 | + if err != nil { |
| 66 | + log.Printf("failed to get credentials for registry %s: %v", k, err) |
| 67 | + } |
| 68 | + } |
| 69 | + return &DefaultAuthProvider{authConfigs}, nil |
| 70 | +} |
| 71 | + |
| 72 | +func getCredentials(registryHost string, cfg *dockercfg.Config, ac *registry.AuthConfig) error { |
| 73 | + u, p, err := cfg.GetRegistryCredentials(registryHost) |
| 74 | + if err != nil { |
| 75 | + return err |
| 76 | + } |
| 77 | + if u == "" { |
| 78 | + ac.IdentityToken = p |
| 79 | + } else { |
| 80 | + ac.Username = u |
| 81 | + ac.Password = p |
| 82 | + } |
| 83 | + |
| 84 | + return nil |
| 85 | +} |
0 commit comments