@@ -56,6 +56,7 @@ import (
56
56
"github.com/fluxcd/pkg/runtime/patch"
57
57
"github.com/fluxcd/pkg/runtime/predicates"
58
58
"github.com/fluxcd/pkg/untar"
59
+ "github.com/google/go-containerregistry/pkg/authn"
59
60
60
61
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
61
62
"github.com/fluxcd/source-controller/internal/cache"
@@ -455,8 +456,9 @@ func (r *HelmChartReconciler) reconcileSource(ctx context.Context, obj *sourcev1
455
456
func (r * HelmChartReconciler ) buildFromHelmRepository (ctx context.Context , obj * sourcev1.HelmChart ,
456
457
repo * sourcev1.HelmRepository , b * chart.Build ) (sreconcile.Result , error ) {
457
458
var (
458
- tlsConfig * tls.Config
459
- loginOpts []helmreg.LoginOption
459
+ tlsConfig * tls.Config
460
+ authenticator authn.Authenticator
461
+ keychain authn.Keychain
460
462
)
461
463
// Used to login with the repository declared provider
462
464
ctxTimeout , cancel := context .WithTimeout (ctx , repo .Spec .Timeout .Duration )
@@ -481,31 +483,21 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
481
483
}
482
484
483
485
// Build client options from secret
484
- opts , err := getter . ClientOptionsFromSecret ( * secret )
486
+ opts , tls , err := r . clientOptionsFromSecret ( secret , normalizedURL )
485
487
if err != nil {
486
488
e := & serror.Event {
487
- Err : fmt . Errorf ( "failed to configure Helm client with secret data: %w" , err ) ,
489
+ Err : err ,
488
490
Reason : sourcev1 .AuthenticationFailedReason ,
489
491
}
490
492
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
491
493
// Requeue as content of secret might change
492
494
return sreconcile .ResultEmpty , e
493
495
}
494
496
clientOpts = append (clientOpts , opts ... )
495
-
496
- tlsConfig , err = getter .TLSClientConfigFromSecret (* secret , normalizedURL )
497
- if err != nil {
498
- e := & serror.Event {
499
- Err : fmt .Errorf ("failed to create TLS client config with secret data: %w" , err ),
500
- Reason : sourcev1 .AuthenticationFailedReason ,
501
- }
502
- conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
503
- // Requeue as content of secret might change
504
- return sreconcile .ResultEmpty , e
505
- }
497
+ tlsConfig = tls
506
498
507
499
// Build registryClient options from secret
508
- loginOpt , err : = registry .LoginOptionFromSecret (normalizedURL , * secret )
500
+ keychain , err = registry .LoginOptionFromSecret (normalizedURL , * secret )
509
501
if err != nil {
510
502
e := & serror.Event {
511
503
Err : fmt .Errorf ("failed to configure Helm client with secret data: %w" , err ),
@@ -515,10 +507,8 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
515
507
// Requeue as content of secret might change
516
508
return sreconcile .ResultEmpty , e
517
509
}
518
-
519
- loginOpts = append ([]helmreg.LoginOption {}, loginOpt )
520
510
} else if repo .Spec .Provider != sourcev1 .GenericOCIProvider && repo .Spec .Type == sourcev1 .HelmRepositoryTypeOCI {
521
- auth , authErr := oidcAuthFromAdapter (ctxTimeout , repo .Spec .URL , repo .Spec .Provider )
511
+ auth , authErr := oidcAuth (ctxTimeout , repo .Spec .URL , repo .Spec .Provider )
522
512
if authErr != nil && ! errors .Is (authErr , oci .ErrUnconfiguredProvider ) {
523
513
e := & serror.Event {
524
514
Err : fmt .Errorf ("failed to get credential from %s: %w" , repo .Spec .Provider , authErr ),
@@ -528,10 +518,20 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
528
518
return sreconcile .ResultEmpty , e
529
519
}
530
520
if auth != nil {
531
- loginOpts = append ([]helmreg. LoginOption {}, auth )
521
+ authenticator = auth
532
522
}
533
523
}
534
524
525
+ loginOpt , err := makeLoginOption (authenticator , keychain , normalizedURL )
526
+ if err != nil {
527
+ e := & serror.Event {
528
+ Err : err ,
529
+ Reason : sourcev1 .AuthenticationFailedReason ,
530
+ }
531
+ conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
532
+ return sreconcile .ResultEmpty , e
533
+ }
534
+
535
535
// Initialize the chart repository
536
536
var chartRepo repository.Downloader
537
537
switch repo .Spec .Type {
@@ -545,7 +545,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
545
545
// this is needed because otherwise the credentials are stored in ~/.docker/config.json.
546
546
// TODO@souleb: remove this once the registry move to Oras v2
547
547
// or rework to enable reusing credentials to avoid the unneccessary handshake operations
548
- registryClient , credentialsFile , err := r .RegistryClientGenerator (loginOpts != nil )
548
+ registryClient , credentialsFile , err := r .RegistryClientGenerator (loginOpt != nil )
549
549
if err != nil {
550
550
e := & serror.Event {
551
551
Err : fmt .Errorf ("failed to construct Helm client: %w" , err ),
@@ -574,8 +574,8 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
574
574
575
575
// If login options are configured, use them to login to the registry
576
576
// The OCIGetter will later retrieve the stored credentials to pull the chart
577
- if loginOpts != nil {
578
- err = ociChartRepo .Login (loginOpts ... )
577
+ if keychain != nil {
578
+ err = ociChartRepo .Login (loginOpt )
579
579
if err != nil {
580
580
e := & serror.Event {
581
581
Err : fmt .Errorf ("failed to login to OCI registry: %w" , err ),
@@ -941,8 +941,9 @@ func (r *HelmChartReconciler) garbageCollect(ctx context.Context, obj *sourcev1.
941
941
func (r * HelmChartReconciler ) namespacedChartRepositoryCallback (ctx context.Context , name , namespace string ) chart.GetChartDownloaderCallback {
942
942
return func (url string ) (repository.Downloader , error ) {
943
943
var (
944
- tlsConfig * tls.Config
945
- loginOpts []helmreg.LoginOption
944
+ tlsConfig * tls.Config
945
+ authenticator authn.Authenticator
946
+ keychain authn.Keychain
946
947
)
947
948
normalizedURL := repository .NormalizeURL (url )
948
949
repo , err := r .resolveDependencyRepository (ctx , url , namespace )
@@ -972,37 +973,39 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
972
973
if err != nil {
973
974
return nil , err
974
975
}
975
- opts , err := getter .ClientOptionsFromSecret (* secret )
976
+
977
+ // Build client options from secret
978
+ opts , tls , err := r .clientOptionsFromSecret (secret , normalizedURL )
976
979
if err != nil {
977
980
return nil , err
978
981
}
979
982
clientOpts = append (clientOpts , opts ... )
980
-
981
- tlsConfig , err = getter .TLSClientConfigFromSecret (* secret , normalizedURL )
982
- if err != nil {
983
- return nil , fmt .Errorf ("failed to create TLS client config for HelmRepository '%s': %w" , repo .Name , err )
984
- }
983
+ tlsConfig = tls
985
984
986
985
// Build registryClient options from secret
987
- loginOpt , err : = registry .LoginOptionFromSecret (normalizedURL , * secret )
986
+ keychain , err = registry .LoginOptionFromSecret (normalizedURL , * secret )
988
987
if err != nil {
989
988
return nil , fmt .Errorf ("failed to create login options for HelmRepository '%s': %w" , repo .Name , err )
990
989
}
991
990
992
- loginOpts = append ([]helmreg.LoginOption {}, loginOpt )
993
991
} else if repo .Spec .Provider != sourcev1 .GenericOCIProvider && repo .Spec .Type == sourcev1 .HelmRepositoryTypeOCI {
994
- auth , authErr := oidcAuthFromAdapter (ctxTimeout , repo .Spec .URL , repo .Spec .Provider )
992
+ auth , authErr := oidcAuth (ctxTimeout , repo .Spec .URL , repo .Spec .Provider )
995
993
if authErr != nil && ! errors .Is (authErr , oci .ErrUnconfiguredProvider ) {
996
994
return nil , fmt .Errorf ("failed to get credential from %s: %w" , repo .Spec .Provider , authErr )
997
995
}
998
996
if auth != nil {
999
- loginOpts = append ([]helmreg. LoginOption {}, auth )
997
+ authenticator = auth
1000
998
}
1001
999
}
1002
1000
1001
+ loginOpt , err := makeLoginOption (authenticator , keychain , normalizedURL )
1002
+ if err != nil {
1003
+ return nil , err
1004
+ }
1005
+
1003
1006
var chartRepo repository.Downloader
1004
1007
if helmreg .IsOCI (normalizedURL ) {
1005
- registryClient , credentialsFile , err := r .RegistryClientGenerator (loginOpts != nil )
1008
+ registryClient , credentialsFile , err := r .RegistryClientGenerator (loginOpt != nil )
1006
1009
if err != nil {
1007
1010
return nil , fmt .Errorf ("failed to create registry client for HelmRepository '%s': %w" , repo .Name , err )
1008
1011
}
@@ -1027,8 +1030,8 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
1027
1030
1028
1031
// If login options are configured, use them to login to the registry
1029
1032
// The OCIGetter will later retrieve the stored credentials to pull the chart
1030
- if loginOpts != nil {
1031
- err = ociChartRepo .Login (loginOpts ... )
1033
+ if keychain != nil {
1034
+ err = ociChartRepo .Login (loginOpt )
1032
1035
if err != nil {
1033
1036
errs = append (errs , fmt .Errorf ("failed to login to OCI chart repository for HelmRepository '%s': %w" , repo .Name , err ))
1034
1037
// clean up the credentialsFile
@@ -1078,6 +1081,20 @@ func (r *HelmChartReconciler) resolveDependencyRepository(ctx context.Context, u
1078
1081
return nil , fmt .Errorf ("no HelmRepository found for '%s' in '%s' namespace" , url , namespace )
1079
1082
}
1080
1083
1084
+ func (r * HelmChartReconciler ) clientOptionsFromSecret (secret * corev1.Secret , normalizedURL string ) ([]helmgetter.Option , * tls.Config , error ) {
1085
+ opts , err := getter .ClientOptionsFromSecret (* secret )
1086
+ if err != nil {
1087
+ return nil , nil , fmt .Errorf ("failed to configure Helm client with secret data: %w" , err )
1088
+ }
1089
+
1090
+ tlsConfig , err := getter .TLSClientConfigFromSecret (* secret , normalizedURL )
1091
+ if err != nil {
1092
+ return nil , nil , fmt .Errorf ("failed to create TLS client config with secret data: %w" , err )
1093
+ }
1094
+
1095
+ return opts , tlsConfig , nil
1096
+ }
1097
+
1081
1098
func (r * HelmChartReconciler ) getHelmRepositorySecret (ctx context.Context , repository * sourcev1.HelmRepository ) (* corev1.Secret , error ) {
1082
1099
if repository .Spec .SecretRef == nil {
1083
1100
return nil , nil
0 commit comments