@@ -28,6 +28,7 @@ import (
2828
2929 securejoin "github.com/cyphar/filepath-securejoin"
3030 "github.com/fluxcd/pkg/runtime/logger"
31+ "github.com/go-git/go-git/v5/plumbing/transport"
3132 corev1 "k8s.io/api/core/v1"
3233 "k8s.io/apimachinery/pkg/runtime"
3334 "k8s.io/apimachinery/pkg/types"
@@ -473,24 +474,19 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
473474 conditions .Delete (obj , sourcev1 .SourceVerifiedCondition )
474475 }
475476
476- var authData map [string ][]byte
477- if obj .Spec .SecretRef != nil {
478- // Attempt to retrieve secret
479- name := types.NamespacedName {
480- Namespace : obj .GetNamespace (),
481- Name : obj .Spec .SecretRef .Name ,
482- }
483- var secret corev1.Secret
484- if err := r .Client .Get (ctx , name , & secret ); err != nil {
477+ var proxyOpts * transport.ProxyOptions
478+ if obj .Spec .ProxySecretRef != nil {
479+ var err error
480+ proxyOpts , err = r .getProxyOpts (ctx , obj .Spec .ProxySecretRef .Name , obj .GetNamespace ())
481+ if err != nil {
485482 e := serror .NewGeneric (
486- fmt .Errorf ("failed to get secret '%s' : %w" , name . String () , err ),
483+ fmt .Errorf ("failed to configure proxy options : %w" , err ),
487484 sourcev1 .AuthenticationFailedReason ,
488485 )
489486 conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
490487 // Return error as the world as observed may change
491488 return sreconcile .ResultEmpty , e
492489 }
493- authData = secret .Data
494490 }
495491
496492 u , err := url .Parse (obj .Spec .URL )
@@ -503,14 +499,14 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
503499 return sreconcile .ResultEmpty , e
504500 }
505501
506- // Configure authentication strategy to access the source
507- authOpts , err := git .NewAuthOptions (* u , authData )
502+ authOpts , err := r .getAuthOpts (ctx , obj , * u )
508503 if err != nil {
509504 e := serror .NewGeneric (
510505 fmt .Errorf ("failed to configure authentication options: %w" , err ),
511506 sourcev1 .AuthenticationFailedReason ,
512507 )
513508 conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
509+ // Return error as the world as observed may change
514510 return sreconcile .ResultEmpty , e
515511 }
516512
@@ -536,7 +532,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
536532 // Persist the ArtifactSet.
537533 * includes = * artifacts
538534
539- c , err := r .gitCheckout (ctx , obj , authOpts , dir , true )
535+ c , err := r .gitCheckout (ctx , obj , authOpts , proxyOpts , dir , true )
540536 if err != nil {
541537 return sreconcile .ResultEmpty , err
542538 }
@@ -578,7 +574,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
578574
579575 // If we can't skip the reconciliation, checkout again without any
580576 // optimization.
581- c , err := r .gitCheckout (ctx , obj , authOpts , dir , false )
577+ c , err := r .gitCheckout (ctx , obj , authOpts , proxyOpts , dir , false )
582578 if err != nil {
583579 return sreconcile .ResultEmpty , err
584580 }
@@ -606,6 +602,60 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
606602 return sreconcile .ResultSuccess , nil
607603}
608604
605+ // getProxyOpts fetches the secret containing the proxy settings, constructs a
606+ // transport.ProxyOptions object using those settings and then returns it.
607+ func (r * GitRepositoryReconciler ) getProxyOpts (ctx context.Context , proxySecretName ,
608+ proxySecretNamespace string ) (* transport.ProxyOptions , error ) {
609+ proxyData , err := r .getSecretData (ctx , proxySecretName , proxySecretNamespace )
610+ if err != nil {
611+ return nil , fmt .Errorf ("failed to get proxy secret '%s/%s': %w" , proxySecretNamespace , proxySecretName , err )
612+ }
613+ address , ok := proxyData ["address" ]
614+ if ! ok {
615+ return nil , fmt .Errorf ("invalid proxy secret '%s/%s': key 'address' is missing" , proxySecretNamespace , proxySecretName )
616+ }
617+
618+ proxyOpts := & transport.ProxyOptions {
619+ URL : string (address ),
620+ Username : string (proxyData ["username" ]),
621+ Password : string (proxyData ["password" ]),
622+ }
623+ return proxyOpts , nil
624+ }
625+
626+ // getAuthOpts fetches the secret containing the auth options (if specified),
627+ // constructs a git.AuthOptions object using those options along with the provided
628+ // URL and returns it.
629+ func (r * GitRepositoryReconciler ) getAuthOpts (ctx context.Context , obj * sourcev1.GitRepository , u url.URL ) (* git.AuthOptions , error ) {
630+ var authData map [string ][]byte
631+ if obj .Spec .SecretRef != nil {
632+ var err error
633+ authData , err = r .getSecretData (ctx , obj .Spec .SecretRef .Name , obj .GetNamespace ())
634+ if err != nil {
635+ return nil , fmt .Errorf ("failed to get secret '%s/%s': %w" , obj .GetNamespace (), obj .Spec .SecretRef .Name , err )
636+ }
637+ }
638+
639+ // Configure authentication strategy to access the source
640+ authOpts , err := git .NewAuthOptions (u , authData )
641+ if err != nil {
642+ return nil , err
643+ }
644+ return authOpts , nil
645+ }
646+
647+ func (r * GitRepositoryReconciler ) getSecretData (ctx context.Context , name , namespace string ) (map [string ][]byte , error ) {
648+ key := types.NamespacedName {
649+ Namespace : namespace ,
650+ Name : name ,
651+ }
652+ var secret corev1.Secret
653+ if err := r .Client .Get (ctx , key , & secret ); err != nil {
654+ return nil , err
655+ }
656+ return secret .Data , nil
657+ }
658+
609659// reconcileArtifact archives a new Artifact to the Storage, if the current
610660// (Status) data on the object does not match the given.
611661//
@@ -776,8 +826,8 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patc
776826
777827// gitCheckout builds checkout options with the given configurations and
778828// performs a git checkout.
779- func (r * GitRepositoryReconciler ) gitCheckout (ctx context.Context ,
780- obj * sourcev1. GitRepository , authOpts * git. AuthOptions , dir string , optimized bool ) (* git.Commit , error ) {
829+ func (r * GitRepositoryReconciler ) gitCheckout (ctx context.Context , obj * sourcev1. GitRepository ,
830+ authOpts * git. AuthOptions , proxyOpts * transport. ProxyOptions , dir string , optimized bool ) (* git.Commit , error ) {
781831 // Configure checkout strategy.
782832 cloneOpts := repository.CloneConfig {
783833 RecurseSubmodules : obj .Spec .RecurseSubmodules ,
@@ -807,6 +857,9 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
807857 if authOpts .Transport == git .HTTP {
808858 clientOpts = append (clientOpts , gogit .WithInsecureCredentialsOverHTTP ())
809859 }
860+ if proxyOpts != nil {
861+ clientOpts = append (clientOpts , gogit .WithProxy (* proxyOpts ))
862+ }
810863
811864 gitReader , err := gogit .NewClient (dir , authOpts , clientOpts ... )
812865 if err != nil {
0 commit comments