Skip to content

Commit 6a2df76

Browse files
committed
only use provider auth if sa and secretRef aren't set
Signed-off-by: Somtochi Onyekwere <[email protected]>
1 parent 2dfa042 commit 6a2df76

File tree

2 files changed

+74
-28
lines changed

2 files changed

+74
-28
lines changed

internal/helm/getter/client_opts.go

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"fmt"
2525
"net/url"
2626

27-
"github.com/fluxcd/pkg/oci"
2827
"github.com/google/go-containerregistry/pkg/authn"
2928
"github.com/google/go-containerregistry/pkg/authn/k8schain"
3029
helmgetter "helm.sh/helm/v3/pkg/getter"
@@ -33,6 +32,7 @@ import (
3332
"k8s.io/apimachinery/pkg/types"
3433
"sigs.k8s.io/controller-runtime/pkg/client"
3534

35+
"github.com/fluxcd/pkg/oci"
3636
helmv1 "github.com/fluxcd/source-controller/api/v1beta2"
3737
"github.com/fluxcd/source-controller/internal/helm/registry"
3838
soci "github.com/fluxcd/source-controller/internal/oci"
@@ -82,15 +82,6 @@ func GetClientOpts(ctx context.Context, c client.Client, obj *helmv1.HelmReposit
8282
var authSecret *corev1.Secret
8383
var deprecatedTLSConfig bool
8484

85-
if ociRepo {
86-
if obj.Spec.ServiceAccountName != "" {
87-
hrOpts.Keychain, err = getKeychainFromSAImagePullSecrets(ctx, c, obj.GetNamespace(), obj.Spec.ServiceAccountName)
88-
if err != nil {
89-
return nil, fmt.Errorf("failed to get keychain from service account: %w", err)
90-
}
91-
}
92-
}
93-
9485
if obj.Spec.SecretRef != nil {
9586
authSecret, err = fetchSecret(ctx, c, obj.Spec.SecretRef.Name, obj.GetNamespace())
9687
if err != nil {
@@ -118,28 +109,43 @@ func GetClientOpts(ctx context.Context, c client.Client, obj *helmv1.HelmReposit
118109
}
119110

120111
if ociRepo {
121-
keychain, err := registry.LoginOptionFromSecret(url, *authSecret)
112+
hrOpts.Keychain, err = registry.LoginOptionFromSecret(url, *authSecret)
122113
if err != nil {
123114
return nil, fmt.Errorf("failed to configure login options: %w", err)
124115
}
116+
}
117+
}
118+
119+
if ociRepo {
120+
if obj.Spec.ServiceAccountName != "" {
121+
keychain, err := getKeychainFromSAImagePullSecrets(ctx, c, obj.GetNamespace(), obj.Spec.ServiceAccountName)
122+
if err != nil {
123+
return nil, fmt.Errorf("failed to get keychain from service account: %w", err)
124+
}
125125

126126
if hrOpts.Keychain != nil {
127-
hrOpts.Keychain = authn.NewMultiKeychain(keychain, hrOpts.Keychain)
127+
hrOpts.Keychain = authn.NewMultiKeychain(hrOpts.Keychain, keychain)
128128
} else {
129129
hrOpts.Keychain = keychain
130130
}
131131
}
132-
} else if obj.Spec.Provider != helmv1.GenericOCIProvider && obj.Spec.Type == helmv1.HelmRepositoryTypeOCI && ociRepo {
133-
authenticator, authErr := soci.OIDCAuth(ctx, obj.Spec.URL, obj.Spec.Provider)
134-
if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) {
135-
return nil, fmt.Errorf("failed to get credential from '%s': %w", obj.Spec.Provider, authErr)
132+
133+
var hasKeychain bool
134+
if hrOpts.Keychain != nil {
135+
_, ok := hrOpts.Keychain.(soci.Anonymous)
136+
hasKeychain = !ok
136137
}
137-
if authenticator != nil {
138-
hrOpts.Authenticator = authenticator
138+
139+
if !hasKeychain && obj.Spec.Provider != helmv1.GenericOCIProvider {
140+
authenticator, authErr := soci.OIDCAuth(ctx, obj.Spec.URL, obj.Spec.Provider)
141+
if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) {
142+
return nil, fmt.Errorf("failed to get credential from '%s': %w", obj.Spec.Provider, authErr)
143+
}
144+
if authenticator != nil {
145+
hrOpts.Authenticator = authenticator
146+
}
139147
}
140-
}
141148

142-
if ociRepo {
143149
hrOpts.RegLoginOpt, err = registry.NewLoginOption(hrOpts.Authenticator, hrOpts.Keychain, url)
144150
if err != nil {
145151
return nil, err

internal/helm/getter/client_opts_test.go

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ func TestGetClientOpts(t *testing.T) {
4444
}
4545

4646
tests := []struct {
47-
name string
48-
certSecret *corev1.Secret
49-
authSecret *corev1.Secret
50-
serviceAccount *corev1.ServiceAccount
51-
afterFunc func(t *WithT, hcOpts *ClientOpts)
52-
oci bool
53-
err error
47+
name string
48+
certSecret *corev1.Secret
49+
authSecret *corev1.Secret
50+
imagePullSecret *corev1.Secret
51+
serviceAccount *corev1.ServiceAccount
52+
provider string
53+
afterFunc func(t *WithT, hcOpts *ClientOpts)
54+
oci bool
55+
err error
5456
}{
5557
{
5658
name: "HelmRepository with certSecretRef discards TLS config in secretRef",
@@ -130,7 +132,41 @@ func TestGetClientOpts(t *testing.T) {
130132
},
131133
},
132134
},
133-
authSecret: &corev1.Secret{
135+
imagePullSecret: &corev1.Secret{
136+
ObjectMeta: metav1.ObjectMeta{
137+
Name: "pull-secret",
138+
},
139+
Type: corev1.SecretTypeDockerConfigJson,
140+
Data: map[string][]byte{
141+
corev1.DockerConfigJsonKey: []byte(`{"auths":{"ghcr.io":{"username":"user","password":"pass","auth":"dXNlcjpwYXNz"}}}`),
142+
},
143+
},
144+
afterFunc: func(t *WithT, hcOpts *ClientOpts) {
145+
repo, err := name.NewRepository("ghcr.io/dummy")
146+
t.Expect(err).ToNot(HaveOccurred())
147+
authenticator, err := hcOpts.Keychain.Resolve(repo)
148+
t.Expect(err).ToNot(HaveOccurred())
149+
config, err := authenticator.Authorization()
150+
t.Expect(err).ToNot(HaveOccurred())
151+
t.Expect(config.Username).To(Equal("user"))
152+
t.Expect(config.Password).To(Equal("pass"))
153+
},
154+
oci: true,
155+
},
156+
{
157+
name: "OCI HelmRepository with serviceaccount name and provider (serviceaccount takes precedence)",
158+
provider: helmv1.AzureOCIProvider,
159+
serviceAccount: &corev1.ServiceAccount{
160+
ObjectMeta: metav1.ObjectMeta{
161+
Name: "test-sa",
162+
},
163+
ImagePullSecrets: []corev1.LocalObjectReference{
164+
{
165+
Name: "pull-secret",
166+
},
167+
},
168+
},
169+
imagePullSecret: &corev1.Secret{
134170
ObjectMeta: metav1.ObjectMeta{
135171
Name: "pull-secret",
136172
},
@@ -159,6 +195,7 @@ func TestGetClientOpts(t *testing.T) {
159195

160196
helmRepo := &helmv1.HelmRepository{
161197
Spec: helmv1.HelmRepositorySpec{
198+
Provider: tt.provider,
162199
Timeout: &metav1.Duration{
163200
Duration: time.Second,
164201
},
@@ -181,6 +218,9 @@ func TestGetClientOpts(t *testing.T) {
181218
Name: tt.certSecret.Name,
182219
}
183220
}
221+
if tt.imagePullSecret != nil {
222+
clientBuilder.WithObjects(tt.imagePullSecret.DeepCopy())
223+
}
184224
if tt.serviceAccount != nil {
185225
clientBuilder.WithObjects(tt.serviceAccount.DeepCopy())
186226
helmRepo.Spec.ServiceAccountName = tt.serviceAccount.Name

0 commit comments

Comments
 (0)