From 300c9be291e1ee72cd69177c0a22a4d4cbfe0dca Mon Sep 17 00:00:00 2001 From: Paul Laffitte Date: Mon, 29 May 2023 12:14:14 +0200 Subject: [PATCH] feat: add support for kubernetes.io/dockercfg secret type --- internal/registry/keychain.go | 24 ++++++++++------ internal/registry/keychain_test.go | 44 +++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/internal/registry/keychain.go b/internal/registry/keychain.go index 26ae495c..ee098b64 100644 --- a/internal/registry/keychain.go +++ b/internal/registry/keychain.go @@ -3,7 +3,7 @@ package registry import ( "bytes" "context" - "errors" + "fmt" "sync" "github.com/docker/cli/cli/config" @@ -21,8 +21,6 @@ const ( DefaultAuthKey = "https://" + name.DefaultRegistry + "/v1/" ) -var missingDockerConfigJsonError = errors.New("invalid secret: missing .dockerconfigjson key") - type kubernetesKeychain struct { client client.Client mu sync.Mutex @@ -56,9 +54,17 @@ func (k *kubernetesKeychain) Resolve(target authn.Resource) (authn.Authenticator return nil, err } - dockerConfigJson, ok := secret.Data[".dockerconfigjson"] + secretKey := "" + if secret.Type == corev1.SecretTypeDockerConfigJson { + secretKey = corev1.DockerConfigJsonKey + } else if secret.Type == corev1.SecretTypeDockercfg { + secretKey = corev1.DockerConfigKey + } else { + return nil, fmt.Errorf("invalid secret type (%s)", secret.Type) + } + dockerConfigJson, ok := secret.Data[secretKey] if !ok { - return nil, missingDockerConfigJsonError + return nil, fmt.Errorf("invalid secret: missing %s key", secretKey) } cf, err := config.LoadFromReader(bytes.NewReader(dockerConfigJson)) if err != nil { @@ -68,12 +74,12 @@ func (k *kubernetesKeychain) Resolve(target authn.Resource) (authn.Authenticator // See: // https://github.com/google/ko/issues/90 // https://github.com/moby/moby/blob/fc01c2b481097a6057bec3cd1ab2d7b4488c50c4/registry/config.go#L397-L404 - key := target.RegistryStr() - if key == name.DefaultRegistry { - key = DefaultAuthKey + authKey := target.RegistryStr() + if authKey == name.DefaultRegistry { + authKey = DefaultAuthKey } - cfg, err := cf.GetAuthConfig(key) + cfg, err := cf.GetAuthConfig(authKey) if err != nil { return nil, err } diff --git a/internal/registry/keychain_test.go b/internal/registry/keychain_test.go index 11efee40..68ad8551 100644 --- a/internal/registry/keychain_test.go +++ b/internal/registry/keychain_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "errors" + "fmt" "testing" "github.com/docker/cli/cli/config" @@ -20,33 +21,53 @@ type mockClient struct { var pullSecrets = map[string]corev1.Secret{ "missing_.dockerconfigjson": { + Type: corev1.SecretTypeDockerConfigJson, + Data: map[string][]byte{}, + }, + "missing_.dockercfg": { + Type: corev1.SecretTypeDockercfg, + Data: map[string][]byte{}, + }, + "invalidSecretType": { + Type: corev1.SecretTypeBasicAuth, Data: map[string][]byte{}, }, "invalidJson": { + Type: corev1.SecretTypeDockerConfigJson, Data: map[string][]byte{ ".dockerconfigjson": []byte("invalid"), }, }, "invalidConfigurationFile": { + Type: corev1.SecretTypeDockerConfigJson, Data: map[string][]byte{ ".dockerconfigjson": []byte("{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"00000000\"}}}"), }, }, "foo": { + Type: corev1.SecretTypeDockerConfigJson, Data: map[string][]byte{ ".dockerconfigjson": []byte("{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"bG9naW46cGFzc3dvcmQ=\"}}}"), }, }, "bar": { + Type: corev1.SecretTypeDockerConfigJson, Data: map[string][]byte{ ".dockerconfigjson": []byte("{\"auths\":{\"localhost:5000\":{\"auth\":\"bG9jYWxsb2dpbjpsb2NhbHBhc3N3b3Jk\"}}}"), }, }, "foobar": { + Type: corev1.SecretTypeDockerConfigJson, Data: map[string][]byte{ ".dockerconfigjson": []byte("{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"bG9naW46cGFzc3dvcmQ=\"},\"localhost:5000\":{\"auth\":\"bG9jYWxsb2dpbjpsb2NhbHBhc3N3b3Jk\"}}}"), }, }, + "dockercfg": { + Type: corev1.SecretTypeDockercfg, + Data: map[string][]byte{ + ".dockercfg": []byte("{\"auths\":{\"https://index.docker.io/v1/\":{\"username\":\"login\",\"password\":\"password\"}}}"), + }, + }, } var notFoundError = errors.New("not found") @@ -94,7 +115,21 @@ func TestResolve(t *testing.T) { pullSecrets: []string{ "missing_.dockerconfigjson", }, - wantErr: missingDockerConfigJsonError, + wantErr: errors.New("invalid secret: missing .dockerconfigjson key"), + }, + { + name: "Missing .dockercfg", + pullSecrets: []string{ + "missing_.dockercfg", + }, + wantErr: errors.New("invalid secret: missing .dockercfg key"), + }, + { + name: "Invalid secret type", + pullSecrets: []string{ + "invalidSecretType", + }, + wantErr: fmt.Errorf("invalid secret type (%s)", corev1.SecretTypeBasicAuth), }, { name: "Invalid json", @@ -142,6 +177,13 @@ func TestResolve(t *testing.T) { }, expectedAuthenticator: defaultAuthenticator, }, + { + name: ".dockercfg format", + pullSecrets: []string{ + "dockercfg", + }, + expectedAuthenticator: defaultAuthenticator, + }, } g := NewWithT(t)