Skip to content

Commit

Permalink
Preserve ordering behavior in k8schain -- first matching secret wins,…
Browse files Browse the repository at this point in the history
… don't override
  • Loading branch information
imjasonh committed Jan 7, 2022
1 parent 147d78f commit 1352567
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
15 changes: 11 additions & 4 deletions pkg/authn/kubernetes/keychain.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,29 @@ func NewInCluster(ctx context.Context, opt Options) (authn.Keychain, error) {
func NewFromPullSecrets(ctx context.Context, secrets []corev1.Secret) (authn.Keychain, error) {
m := map[string]authn.AuthConfig{}
for _, secret := range secrets {
auths := map[string]authn.AuthConfig{}
if b, exists := secret.Data[corev1.DockerConfigJsonKey]; secret.Type == corev1.SecretTypeDockerConfigJson && exists && len(b) > 0 {
var cfg struct {
Auths map[string]authn.AuthConfig
}
if err := json.Unmarshal(b, &cfg); err != nil {
return nil, err
}
for k, v := range cfg.Auths {
m[k] = v
}
auths = cfg.Auths
}
if b, exists := secret.Data[corev1.DockerConfigKey]; secret.Type == corev1.SecretTypeDockercfg && exists && len(b) > 0 {
if err := json.Unmarshal(b, &m); err != nil {
if err := json.Unmarshal(b, &auths); err != nil {
return nil, err
}
}

for k, v := range auths {
// Don't overwrite previously specified Auths for a
// given key.
if _, found := m[k]; !found {
m[k] = v
}
}
}
return authsKeychain(m), nil
}
Expand Down
42 changes: 27 additions & 15 deletions pkg/authn/kubernetes/keychain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,22 +183,34 @@ func TestFromPullSecrets(t *testing.T) {
username, password := "foo", "bar"
specificUser, specificPass := "very", "specific"

pullSecrets := []corev1.Secret{
{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "ns",
},
Type: corev1.SecretTypeDockercfg,
Data: map[string][]byte{
corev1.DockerConfigKey: []byte(
fmt.Sprintf(`{"fake.registry.io": {"auth": %q}, "fake.registry.io/more/specific": {"auth": %q}}`,
base64.StdEncoding.EncodeToString([]byte(username+":"+password)),
base64.StdEncoding.EncodeToString([]byte(specificUser+":"+specificPass))),
),
},
pullSecrets := []corev1.Secret{{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "ns",
},
}
Type: corev1.SecretTypeDockercfg,
Data: map[string][]byte{
corev1.DockerConfigKey: []byte(
fmt.Sprintf(`{"fake.registry.io": {"auth": %q}, "fake.registry.io/more/specific": {"auth": %q}}`,
base64.StdEncoding.EncodeToString([]byte(username+":"+password)),
base64.StdEncoding.EncodeToString([]byte(specificUser+":"+specificPass))),
),
},
}, {
// Check that a subsequent Secret that matches the registry is
// _not_ used; i.e., first matching Secret wins.
ObjectMeta: metav1.ObjectMeta{
Name: "secret-2",
Namespace: "ns",
},
Type: corev1.SecretTypeDockercfg,
Data: map[string][]byte{
corev1.DockerConfigKey: []byte(
fmt.Sprintf(`{"fake.registry.io": {"auth": %q}}`,
base64.StdEncoding.EncodeToString([]byte("anotherUser:anotherPass"))),
),
},
}}

kc, err := NewFromPullSecrets(context.Background(), pullSecrets)
if err != nil {
Expand Down

0 comments on commit 1352567

Please sign in to comment.