@@ -28,6 +28,7 @@ import (
28
28
29
29
securejoin "github.com/cyphar/filepath-securejoin"
30
30
"github.com/fluxcd/pkg/runtime/logger"
31
+ "github.com/go-git/go-git/v5/plumbing/transport"
31
32
corev1 "k8s.io/api/core/v1"
32
33
"k8s.io/apimachinery/pkg/runtime"
33
34
"k8s.io/apimachinery/pkg/types"
@@ -473,24 +474,19 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
473
474
conditions .Delete (obj , sourcev1 .SourceVerifiedCondition )
474
475
}
475
476
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 {
485
482
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 ),
487
484
sourcev1 .AuthenticationFailedReason ,
488
485
)
489
486
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
490
487
// Return error as the world as observed may change
491
488
return sreconcile .ResultEmpty , e
492
489
}
493
- authData = secret .Data
494
490
}
495
491
496
492
u , err := url .Parse (obj .Spec .URL )
@@ -503,14 +499,14 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
503
499
return sreconcile .ResultEmpty , e
504
500
}
505
501
506
- // Configure authentication strategy to access the source
507
- authOpts , err := git .NewAuthOptions (* u , authData )
502
+ authOpts , err := r .getAuthOpts (ctx , obj , * u )
508
503
if err != nil {
509
504
e := serror .NewGeneric (
510
505
fmt .Errorf ("failed to configure authentication options: %w" , err ),
511
506
sourcev1 .AuthenticationFailedReason ,
512
507
)
513
508
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
509
+ // Return error as the world as observed may change
514
510
return sreconcile .ResultEmpty , e
515
511
}
516
512
@@ -536,7 +532,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
536
532
// Persist the ArtifactSet.
537
533
* includes = * artifacts
538
534
539
- c , err := r .gitCheckout (ctx , obj , authOpts , dir , true )
535
+ c , err := r .gitCheckout (ctx , obj , authOpts , proxyOpts , dir , true )
540
536
if err != nil {
541
537
return sreconcile .ResultEmpty , err
542
538
}
@@ -578,7 +574,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
578
574
579
575
// If we can't skip the reconciliation, checkout again without any
580
576
// optimization.
581
- c , err := r .gitCheckout (ctx , obj , authOpts , dir , false )
577
+ c , err := r .gitCheckout (ctx , obj , authOpts , proxyOpts , dir , false )
582
578
if err != nil {
583
579
return sreconcile .ResultEmpty , err
584
580
}
@@ -606,6 +602,60 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
606
602
return sreconcile .ResultSuccess , nil
607
603
}
608
604
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
+
609
659
// reconcileArtifact archives a new Artifact to the Storage, if the current
610
660
// (Status) data on the object does not match the given.
611
661
//
@@ -776,8 +826,8 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patc
776
826
777
827
// gitCheckout builds checkout options with the given configurations and
778
828
// 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 ) {
781
831
// Configure checkout strategy.
782
832
cloneOpts := repository.CloneConfig {
783
833
RecurseSubmodules : obj .Spec .RecurseSubmodules ,
@@ -807,6 +857,9 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
807
857
if authOpts .Transport == git .HTTP {
808
858
clientOpts = append (clientOpts , gogit .WithInsecureCredentialsOverHTTP ())
809
859
}
860
+ if proxyOpts != nil {
861
+ clientOpts = append (clientOpts , gogit .WithProxy (* proxyOpts ))
862
+ }
810
863
811
864
gitReader , err := gogit .NewClient (dir , authOpts , clientOpts ... )
812
865
if err != nil {
0 commit comments