From e3992568f59c5cb3a6f6b27b773a496bbb7fe6a3 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Tue, 10 Sep 2024 18:54:32 +0300 Subject: [PATCH] OCIRepository: Configure proxy for OIDC auth Signed-off-by: Stefan Prodan --- .../controller/ocirepository_controller.go | 20 ++++++++++++------- internal/helm/getter/client_opts.go | 2 +- internal/oci/auth.go | 5 +++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/internal/controller/ocirepository_controller.go b/internal/controller/ocirepository_controller.go index eaaf0647..bc0019cb 100644 --- a/internal/controller/ocirepository_controller.go +++ b/internal/controller/ocirepository_controller.go @@ -354,9 +354,19 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch return sreconcile.ResultEmpty, e } + proxyURL, err := r.getProxyURL(ctx, obj) + if err != nil { + e := serror.NewGeneric( + fmt.Errorf("failed to get proxy address: %w", err), + sourcev1.AuthenticationFailedReason, + ) + conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e) + return sreconcile.ResultEmpty, e + } + if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != ociv1.GenericOCIProvider && ok { var authErr error - auth, authErr = soci.OIDCAuth(ctxTimeout, obj.Spec.URL, obj.Spec.Provider) + auth, authErr = soci.OIDCAuth(ctxTimeout, obj.Spec.URL, obj.Spec.Provider, proxyURL) if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) { e := serror.NewGeneric( fmt.Errorf("failed to get credential from %s: %w", obj.Spec.Provider, authErr), @@ -368,7 +378,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch } // Generate the transport for remote operations - transport, err := r.transport(ctx, obj) + transport, err := r.transport(ctx, obj, proxyURL) if err != nil { e := serror.NewGeneric( fmt.Errorf("failed to generate transport for '%s': %w", obj.Spec.URL, err), @@ -927,7 +937,7 @@ func (r *OCIRepositoryReconciler) keychain(ctx context.Context, obj *ociv1.OCIRe // the returned transport will include the TLS client and/or CA certificates. // If the insecure flag is set, the transport will skip the verification of the server's certificate. // Additionally, if a proxy is specified, transport will use it. -func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *ociv1.OCIRepository) (*http.Transport, error) { +func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *ociv1.OCIRepository, proxyURL *url.URL) (*http.Transport, error) { transport := remote.DefaultTransport.(*http.Transport).Clone() tlsConfig, err := r.getTLSConfig(ctx, obj) @@ -938,10 +948,6 @@ func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *ociv1.OCIR transport.TLSClientConfig = tlsConfig } - proxyURL, err := r.getProxyURL(ctx, obj) - if err != nil { - return nil, err - } if proxyURL != nil { transport.Proxy = http.ProxyURL(proxyURL) } diff --git a/internal/helm/getter/client_opts.go b/internal/helm/getter/client_opts.go index c305b738..b586b41b 100644 --- a/internal/helm/getter/client_opts.go +++ b/internal/helm/getter/client_opts.go @@ -137,7 +137,7 @@ func GetClientOpts(ctx context.Context, c client.Client, obj *sourcev1.HelmRepos } } } else if obj.Spec.Provider != sourcev1beta2.GenericOCIProvider && obj.Spec.Type == sourcev1.HelmRepositoryTypeOCI && ociRepo { - authenticator, authErr := soci.OIDCAuth(ctx, obj.Spec.URL, obj.Spec.Provider) + authenticator, authErr := soci.OIDCAuth(ctx, obj.Spec.URL, obj.Spec.Provider, nil) if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) { return nil, "", fmt.Errorf("failed to get credential from '%s': %w", obj.Spec.Provider, authErr) } diff --git a/internal/oci/auth.go b/internal/oci/auth.go index 7b3eab89..cfbc684e 100644 --- a/internal/oci/auth.go +++ b/internal/oci/auth.go @@ -19,6 +19,7 @@ package oci import ( "context" "fmt" + "net/url" "strings" "github.com/fluxcd/pkg/oci/auth/login" @@ -40,7 +41,7 @@ func (a Anonymous) Resolve(_ authn.Resource) (authn.Authenticator, error) { } // OIDCAuth generates the OIDC credential authenticator based on the specified cloud provider. -func OIDCAuth(ctx context.Context, url, provider string) (authn.Authenticator, error) { +func OIDCAuth(ctx context.Context, url, provider string, proxyURL *url.URL) (authn.Authenticator, error) { u := strings.TrimPrefix(url, sourcev1.OCIRepositoryPrefix) ref, err := name.ParseReference(u) if err != nil { @@ -57,5 +58,5 @@ func OIDCAuth(ctx context.Context, url, provider string) (authn.Authenticator, e opts.GcpAutoLogin = true } - return login.NewManager().Login(ctx, u, ref, opts) + return login.NewManager(login.WithProxyURL(proxyURL)).Login(ctx, u, ref, opts) }