Skip to content

Commit 5c4bb79

Browse files
committed
refactor TLSconfig funcs
Signed-off-by: Soule BA <[email protected]>
1 parent 3adf2e3 commit 5c4bb79

File tree

5 files changed

+228
-138
lines changed

5 files changed

+228
-138
lines changed

docs/spec/v1beta2/helmrepositories.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ data:
485485
caFile: <BASE64>
486486
```
487487

488-
#### Provide TLS credentials in a secret of type kubernetes.io/dockerconfigjson
488+
##### Provide TLS credentials in a secret of type kubernetes.io/dockerconfigjson
489489

490490
For OCI Helm repositories, Kubernetes secrets of type [kubernetes.io/dockerconfigjson](https://kubernetes.io/docs/concepts/configuration/secret/#secret-types)
491491
are also supported. It is possible to append TLS credentials to the secret data.

internal/controller/helmchart_controller.go

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
510510
tlsConfig *tls.Config
511511
authenticator authn.Authenticator
512512
keychain authn.Keychain
513-
tlsLoginOpt helmreg.LoginOption
514-
tmpCertsDir string
513+
secret *corev1.Secret
515514
)
516515
// Used to login with the repository declared provider
517516
ctxTimeout, cancel := context.WithTimeout(ctx, repo.Spec.Timeout.Duration)
@@ -527,7 +526,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
527526
helmgetter.WithTimeout(repo.Spec.Timeout.Duration),
528527
helmgetter.WithPassCredentialsAll(repo.Spec.PassCredentials),
529528
}
530-
if secret, err := r.getHelmRepositorySecret(ctx, repo); secret != nil || err != nil {
529+
if secret, err = r.getHelmRepositorySecret(ctx, repo); secret != nil || err != nil {
531530
if err != nil {
532531
e := &serror.Event{
533532
Err: fmt.Errorf("failed to get secret '%s': %w", repo.Spec.SecretRef.Name, err),
@@ -551,22 +550,6 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
551550
}
552551
clientOpts = append(clientOpts, opts...)
553552
tlsConfig = tlsCfg
554-
tlsLoginOpt, tmpCertsDir, err = makeTLSLoginOption(secret)
555-
if err != nil {
556-
e := &serror.Event{
557-
Err: err,
558-
Reason: sourcev1.AuthenticationFailedReason,
559-
}
560-
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
561-
// Requeue as content of secret might change
562-
return sreconcile.ResultEmpty, e
563-
}
564-
defer func() {
565-
if err := os.RemoveAll(tmpCertsDir); err != nil {
566-
r.eventLogf(ctx, obj, corev1.EventTypeWarning, meta.FailedReason,
567-
"failed to delete temporary certificates directory: %s", err)
568-
}
569-
}()
570553

571554
// Build registryClient options from secret
572555
keychain, err = registry.LoginOptionFromSecret(normalizedURL, *secret)
@@ -669,8 +652,26 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
669652
// The OCIGetter will later retrieve the stored credentials to pull the chart
670653
if loginOpt != nil {
671654
opts := []helmreg.LoginOption{loginOpt}
672-
if tlsLoginOpt != nil {
673-
opts = append(opts, tlsLoginOpt)
655+
if tlsConfig != nil && secret != nil {
656+
tlsLoginOpt, tmpCertsDir, err := registry.TLSLoginOptionFromSecret(secret)
657+
if err != nil {
658+
e := &serror.Event{
659+
Err: err,
660+
Reason: sourcev1.AuthenticationFailedReason,
661+
}
662+
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
663+
// Requeue as content of secret might change
664+
return sreconcile.ResultEmpty, e
665+
}
666+
defer func() {
667+
if err := os.RemoveAll(tmpCertsDir); err != nil {
668+
r.eventLogf(ctx, obj, corev1.EventTypeWarning, meta.FailedReason,
669+
"failed to delete temporary certificates directory: %s", err)
670+
}
671+
}()
672+
if tlsLoginOpt != nil {
673+
opts = append(opts, tlsLoginOpt)
674+
}
674675
}
675676
err = ociChartRepo.Login(opts...)
676677
if err != nil {
@@ -1048,8 +1049,7 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
10481049
return func(url string) (repo repository.Downloader, err error) {
10491050
var (
10501051
tlsConfig *tls.Config
1051-
tlsLoginOpt helmreg.LoginOption
1052-
tmpCertsDir string
1052+
secret *corev1.Secret
10531053
authenticator authn.Authenticator
10541054
keychain authn.Keychain
10551055
)
@@ -1081,7 +1081,7 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
10811081
helmgetter.WithTimeout(obj.Spec.Timeout.Duration),
10821082
helmgetter.WithPassCredentialsAll(obj.Spec.PassCredentials),
10831083
}
1084-
if secret, err := r.getHelmRepositorySecret(ctx, obj); secret != nil || err != nil {
1084+
if secret, err = r.getHelmRepositorySecret(ctx, obj); secret != nil || err != nil {
10851085
if err != nil {
10861086
return nil, err
10871087
}
@@ -1093,19 +1093,6 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
10931093
}
10941094
clientOpts = append(clientOpts, opts...)
10951095
tlsConfig = tlsCfg
1096-
tlsLoginOpt, tmpCertsDir, err = makeTLSLoginOption(secret)
1097-
if err != nil {
1098-
return nil, err
1099-
}
1100-
defer func() {
1101-
var errs []error
1102-
if errf := os.RemoveAll(tmpCertsDir); errf != nil {
1103-
errs = append(errs, errf)
1104-
}
1105-
errs = append(errs, err)
1106-
err = kerrors.NewAggregate(errs)
1107-
return
1108-
}()
11091096

11101097
// Build registryClient options from secret
11111098
keychain, err = registry.LoginOptionFromSecret(normalizedURL, *secret)
@@ -1157,8 +1144,23 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
11571144
// The OCIGetter will later retrieve the stored credentials to pull the chart
11581145
if loginOpt != nil {
11591146
opts := []helmreg.LoginOption{loginOpt}
1160-
if tlsLoginOpt != nil {
1161-
opts = append(opts, tlsLoginOpt)
1147+
if tlsConfig != nil && secret != nil {
1148+
tlsLoginOpt, tmpCertsDir, err := registry.TLSLoginOptionFromSecret(secret)
1149+
if err != nil {
1150+
return nil, err
1151+
}
1152+
defer func() {
1153+
var errs []error
1154+
if errf := os.RemoveAll(tmpCertsDir); errf != nil {
1155+
errs = append(errs, errf)
1156+
}
1157+
errs = append(errs, err)
1158+
err = kerrors.NewAggregate(errs)
1159+
return
1160+
}()
1161+
if tlsLoginOpt != nil {
1162+
opts = append(opts, tlsLoginOpt)
1163+
}
11621164
}
11631165
err = ociChartRepo.Login(opts...)
11641166
if err != nil {

internal/controller/helmrepository_controller_oci.go

Lines changed: 36 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -309,47 +309,29 @@ func (r *HelmRepositoryOCIReconciler) reconcile(ctx context.Context, sp *patch.S
309309
authenticator authn.Authenticator
310310
keychain authn.Keychain
311311
tlsConfig *tls.Config
312-
tmpCertsDir string
313-
tlsLoginOpt helmreg.LoginOption
312+
secret *corev1.Secret
314313
err error
315314
)
316315
// Configure any authentication related options.
317316
if obj.Spec.SecretRef != nil {
318-
// Attempt to retrieve secret.
319-
name := types.NamespacedName{
320-
Namespace: obj.GetNamespace(),
321-
Name: obj.Spec.SecretRef.Name,
322-
}
323-
var secret corev1.Secret
324-
if err := r.Client.Get(ctx, name, &secret); err != nil {
325-
conditions.MarkFalse(obj, meta.ReadyCondition, sourcev1.AuthenticationFailedReason, err.Error())
326-
result, retErr = ctrl.Result{}, err
327-
return
328-
}
329-
keychain, err = authFromSecret(ctx, r.Client, obj.Spec.URL, secret)
317+
secret, err = r.getSecret(ctx, obj)
330318
if err != nil {
331319
conditions.MarkFalse(obj, meta.ReadyCondition, sourcev1.AuthenticationFailedReason, err.Error())
332320
result, retErr = ctrl.Result{}, err
333321
return
334322
}
335-
tlsConfig, err = getter.TLSClientConfigFromSecret(secret, obj.Spec.URL)
323+
keychain, err = authFromSecret(ctx, r.Client, obj.Spec.URL, *secret)
336324
if err != nil {
337325
conditions.MarkFalse(obj, meta.ReadyCondition, sourcev1.AuthenticationFailedReason, err.Error())
338326
result, retErr = ctrl.Result{}, err
339327
return
340328
}
341-
tlsLoginOpt, tmpCertsDir, err = makeTLSLoginOption(&secret)
329+
tlsConfig, err = getter.TLSClientConfigFromSecret(*secret, obj.Spec.URL)
342330
if err != nil {
343331
conditions.MarkFalse(obj, meta.ReadyCondition, sourcev1.AuthenticationFailedReason, err.Error())
344332
result, retErr = ctrl.Result{}, err
345333
return
346334
}
347-
defer func() {
348-
if err := os.RemoveAll(tmpCertsDir); err != nil {
349-
r.eventLogf(ctx, obj, corev1.EventTypeWarning, meta.FailedReason,
350-
"failed to delete temporary certificates directory: %s", err)
351-
}
352-
}()
353335
} else if obj.Spec.Provider != helmv1.GenericOCIProvider && obj.Spec.Type == helmv1.HelmRepositoryTypeOCI {
354336
auth, authErr := oidcAuth(ctxTimeout, obj.Spec.URL, obj.Spec.Provider)
355337
if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) {
@@ -400,8 +382,22 @@ func (r *HelmRepositoryOCIReconciler) reconcile(ctx context.Context, sp *patch.S
400382
// Attempt to login to the registry if credentials are provided.
401383
if loginOpt != nil {
402384
opts := []helmreg.LoginOption{loginOpt}
403-
if tlsLoginOpt != nil {
404-
opts = append(opts, tlsLoginOpt)
385+
if tlsConfig != nil && secret != nil {
386+
tlsLoginOpt, tmpCertsDir, err := registry.TLSLoginOptionFromSecret(secret)
387+
if err != nil {
388+
conditions.MarkFalse(obj, meta.ReadyCondition, sourcev1.AuthenticationFailedReason, err.Error())
389+
result, retErr = ctrl.Result{}, err
390+
return
391+
}
392+
defer func() {
393+
if err := os.RemoveAll(tmpCertsDir); err != nil {
394+
r.eventLogf(ctx, obj, corev1.EventTypeWarning, meta.FailedReason,
395+
"failed to delete temporary certificates directory: %s", err)
396+
}
397+
}()
398+
if tlsLoginOpt != nil {
399+
opts = append(opts, tlsLoginOpt)
400+
}
405401
}
406402
err = chartRepo.Login(opts...)
407403
if err != nil {
@@ -429,6 +425,22 @@ func (r *HelmRepositoryOCIReconciler) reconcileDelete(ctx context.Context, obj *
429425
return ctrl.Result{}, nil
430426
}
431427

428+
func (r *HelmRepositoryOCIReconciler) getSecret(ctx context.Context, obj *helmv1.HelmRepository) (*corev1.Secret, error) {
429+
if obj.Spec.SecretRef == nil {
430+
return nil, nil
431+
}
432+
name := types.NamespacedName{
433+
Namespace: obj.GetNamespace(),
434+
Name: obj.Spec.SecretRef.Name,
435+
}
436+
var secret corev1.Secret
437+
err := r.Client.Get(ctx, name, &secret)
438+
if err != nil {
439+
return nil, err
440+
}
441+
return &secret, nil
442+
}
443+
432444
// eventLogf records events, and logs at the same time.
433445
//
434446
// This log is different from the debug log in the EventRecorder, in the sense
@@ -470,80 +482,6 @@ func makeLoginOption(auth authn.Authenticator, keychain authn.Keychain, registry
470482
return nil, nil
471483
}
472484

473-
func makeTLSLoginOption(secret *corev1.Secret) (helmreg.LoginOption, string, error) {
474-
var errs []error
475-
certFile, keyFile, caFile, tmpDir, err := certsFilesFromSecret(secret)
476-
if err != nil {
477-
errs = append(errs, err)
478-
if tmpDir != "" {
479-
if err := os.RemoveAll(tmpDir); err != nil {
480-
errs = append(errs, err)
481-
}
482-
}
483-
return nil, "", kerrors.NewAggregate(errs)
484-
}
485-
486-
if (certFile != "" && keyFile != "") || caFile != "" {
487-
return helmreg.LoginOptTLSClientConfig(certFile, keyFile, caFile), tmpDir, nil
488-
}
489-
490-
return nil, "", nil
491-
}
492-
493-
func certsFilesFromSecret(secret *corev1.Secret) (string, string, string, string, error) {
494-
certBytes, keyBytes, caBytes := secret.Data["certFile"], secret.Data["keyFile"], secret.Data["caFile"]
495-
switch {
496-
case len(certBytes)+len(keyBytes)+len(caBytes) == 0:
497-
return "", "", "", "", nil
498-
case (len(certBytes) > 0 && len(keyBytes) == 0) || (len(keyBytes) > 0 && len(certBytes) == 0):
499-
return "", "", "", "", fmt.Errorf("invalid '%s' secret data: fields 'certFile' and 'keyFile' require each other's presence",
500-
secret.Name)
501-
}
502-
503-
var (
504-
certFile string
505-
keyFile string
506-
caFile string
507-
err error
508-
)
509-
510-
// create temporary folder to store the certs
511-
tmpDir, err := os.MkdirTemp("", "helm-repo-oci-certs")
512-
if err != nil {
513-
return "", "", "", "", err
514-
}
515-
516-
if len(certBytes) > 0 && len(keyBytes) > 0 {
517-
certFile, err = writeTofile(certBytes, "cert.pem", tmpDir)
518-
if err != nil {
519-
return "", "", "", "", err
520-
}
521-
keyFile, err = writeTofile(keyBytes, "key.pem", tmpDir)
522-
if err != nil {
523-
return "", "", "", "", err
524-
}
525-
}
526-
if len(caBytes) > 0 {
527-
caFile, err = writeTofile(caBytes, "ca.pem", tmpDir)
528-
if err != nil {
529-
return "", "", "", "", err
530-
}
531-
}
532-
return certFile, keyFile, caFile, tmpDir, nil
533-
}
534-
535-
func writeTofile(data []byte, filename, tmpDir string) (string, error) {
536-
file, err := os.CreateTemp(tmpDir, filename)
537-
if err != nil {
538-
return "", err
539-
}
540-
defer file.Close()
541-
if _, err := file.Write(data); err != nil {
542-
return "", err
543-
}
544-
return file.Name(), nil
545-
}
546-
547485
func conditionsDiff(a, b []string) []string {
548486
bMap := make(map[string]struct{}, len(b))
549487
for _, j := range b {

0 commit comments

Comments
 (0)