Skip to content

Commit a07df6e

Browse files
committed
refactor TLSconfig funcs
Signed-off-by: Soule BA <[email protected]>
1 parent fec4955 commit a07df6e

22 files changed

+459
-392
lines changed

api/v1beta2/zz_generated.deepcopy.go

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/spec/v1beta2/helmrepositories.md

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -459,16 +459,8 @@ a deprecation warning will be logged.
459459

460460
### Cert secret reference
461461

462-
<<<<<<< HEAD
463-
**Note:** TLS authentication is not yet supported by OCI Helm repositories.
464-
465462
`.spec.certSecretRef.name` is an optional field to specify a secret containing TLS
466463
certificate data. The secret can contain the following keys:
467-
=======
468-
To provide TLS credentials to use while connecting with the Helm repository,
469-
the referenced Secret is expected to contain `.data.certFile` and
470-
`.data.keyFile`, and/or `.data.caFile` values.
471-
>>>>>>> 3df4c49 (refactoring and fix tests)
472464

473465
* `certFile` and `keyFile`, to specify the client certificate and private key used for
474466
TLS client authentication. These must be used in conjunction, i.e. specifying one without
@@ -515,28 +507,6 @@ data:
515507
caFile: <BASE64>
516508
```
517509

518-
#### Provide TLS credentials in a secret of type kubernetes.io/dockerconfigjson
519-
520-
For OCI Helm repositories, Kubernetes secrets of type [kubernetes.io/dockerconfigjson](https://kubernetes.io/docs/concepts/configuration/secret/#secret-types)
521-
are also supported. It is possible to append TLS credentials to the secret data.
522-
523-
For example:
524-
525-
```yaml
526-
apiVersion: v1
527-
kind: Secret
528-
metadata:
529-
name: example-tls
530-
namespace: default
531-
type: kubernetes.io/dockerconfigjson
532-
data:
533-
.dockerconfigjson: <BASE64>
534-
certFile: <BASE64>
535-
keyFile: <BASE64>
536-
# NOTE: Can be supplied without the above values
537-
caFile: <BASE64>
538-
```
539-
540510
### Pass credentials
541511

542512
`.spec.passCredentials` is an optional field to allow the credentials from the

internal/controller/helmchart_controller.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
512512
if err != nil {
513513
return chartRepoConfigErrorReturn(err, obj)
514514
}
515-
clientOpts, err := getter.GetClientOpts(ctxTimeout, r.Client, repo, normalizedURL)
515+
516+
clientOpts, certsTmpDir, err := getter.GetClientOpts(ctxTimeout, r.Client, repo, normalizedURL)
516517
if err != nil && !errors.Is(err, getter.ErrDeprecatedTLSConfig) {
517518
e := &serror.Event{
518519
Err: err,
@@ -521,6 +522,10 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
521522
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
522523
return sreconcile.ResultEmpty, e
523524
}
525+
if certsTmpDir != "" {
526+
// this happens when the tls certs are stored in a temporary directory
527+
defer os.RemoveAll(certsTmpDir)
528+
}
524529
getterOpts := clientOpts.GetterOpts
525530

526531
// Initialize the chart repository
@@ -536,7 +541,8 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
536541
// this is needed because otherwise the credentials are stored in ~/.docker/config.json.
537542
// TODO@souleb: remove this once the registry move to Oras v2
538543
// or rework to enable reusing credentials to avoid the unneccessary handshake operations
539-
registryClient, credentialsFile, err := r.RegistryClientGenerator(clientOpts.RegLoginOpt != nil)
544+
shouldLogin := len(clientOpts.RegLoginOpts) > 0 && clientOpts.RegLoginOpts[0] != nil
545+
registryClient, credentialsFile, err := r.RegistryClientGenerator(clientOpts.TlsConfig, shouldLogin)
540546
if err != nil {
541547
e := &serror.Event{
542548
Err: fmt.Errorf("failed to construct Helm client: %w", err),
@@ -585,8 +591,8 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
585591

586592
// If login options are configured, use them to login to the registry
587593
// The OCIGetter will later retrieve the stored credentials to pull the chart
588-
if clientOpts.RegLoginOpt != nil {
589-
err = ociChartRepo.Login(clientOpts.RegLoginOpt)
594+
if len(clientOpts.RegLoginOpts) > 0 && clientOpts.RegLoginOpts[0] != nil {
595+
err = ociChartRepo.Login(clientOpts.RegLoginOpts...)
590596
if err != nil {
591597
e := &serror.Event{
592598
Err: fmt.Errorf("failed to login to OCI registry: %w", err),
@@ -983,15 +989,20 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
983989
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
984990
defer cancel()
985991

986-
clientOpts, err := getter.GetClientOpts(ctxTimeout, r.Client, obj, normalizedURL)
992+
clientOpts, certsTmpDir, err := getter.GetClientOpts(ctxTimeout, r.Client, obj, normalizedURL)
987993
if err != nil && !errors.Is(err, getter.ErrDeprecatedTLSConfig) {
988994
return nil, err
989995
}
996+
if certsTmpDir != "" {
997+
// this happens when the tls certs are stored in a temporary directory
998+
defer os.RemoveAll(certsTmpDir)
999+
}
9901000
getterOpts := clientOpts.GetterOpts
9911001

9921002
var chartRepo repository.Downloader
9931003
if helmreg.IsOCI(normalizedURL) {
994-
registryClient, credentialsFile, err := r.RegistryClientGenerator(clientOpts.RegLoginOpt != nil)
1004+
shouldLogin := len(clientOpts.RegLoginOpts) > 0 && clientOpts.RegLoginOpts[0] != nil
1005+
registryClient, credentialsFile, err := r.RegistryClientGenerator(clientOpts.TlsConfig, shouldLogin)
9951006
if err != nil {
9961007
return nil, fmt.Errorf("failed to create registry client: %w", err)
9971008
}
@@ -1016,8 +1027,8 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
10161027

10171028
// If login options are configured, use them to login to the registry
10181029
// The OCIGetter will later retrieve the stored credentials to pull the chart
1019-
if clientOpts.RegLoginOpt != nil {
1020-
err = ociChartRepo.Login(clientOpts.RegLoginOpt)
1030+
if len(clientOpts.RegLoginOpts) > 0 && clientOpts.RegLoginOpts[0] != nil {
1031+
err = ociChartRepo.Login(clientOpts.RegLoginOpts...)
10211032
if err != nil {
10221033
errs = append(errs, fmt.Errorf("failed to login to OCI chart repository: %w", err))
10231034
// clean up the credentialsFile

internal/controller/helmchart_controller_test.go

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,24 +2245,27 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
22452245
registryOpts registryOptions
22462246
secretOpts secretOptions
22472247
secret *corev1.Secret
2248-
withTLS bool
2248+
certsecret *corev1.Secret
2249+
insecure bool
22492250
provider string
22502251
providerImg string
22512252
want sreconcile.Result
22522253
wantErr bool
22532254
assertConditions []metav1.Condition
22542255
}{
22552256
{
2256-
name: "HTTP without basic auth",
2257-
want: sreconcile.ResultSuccess,
2257+
name: "HTTP without basic auth",
2258+
want: sreconcile.ResultSuccess,
2259+
insecure: true,
22582260
assertConditions: []metav1.Condition{
22592261
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: pulled 'helmchart' chart with version '0.1.0'"),
22602262
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: pulled 'helmchart' chart with version '0.1.0'"),
22612263
},
22622264
},
22632265
{
2264-
name: "HTTP with basic auth secret",
2265-
want: sreconcile.ResultSuccess,
2266+
name: "HTTP with basic auth secret",
2267+
want: sreconcile.ResultSuccess,
2268+
insecure: true,
22662269
registryOpts: registryOptions{
22672270
withBasicAuth: true,
22682271
},
@@ -2283,9 +2286,10 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
22832286
},
22842287
},
22852288
{
2286-
name: "HTTP registry - basic auth with invalid secret",
2287-
want: sreconcile.ResultEmpty,
2288-
wantErr: true,
2289+
name: "HTTP registry - basic auth with invalid secret",
2290+
want: sreconcile.ResultEmpty,
2291+
wantErr: true,
2292+
insecure: true,
22892293
registryOpts: registryOptions{
22902294
withBasicAuth: true,
22912295
},
@@ -2307,6 +2311,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23072311
{
23082312
name: "with contextual login provider",
23092313
wantErr: true,
2314+
insecure: true,
23102315
provider: "aws",
23112316
providerImg: "oci://123456789000.dkr.ecr.us-east-2.amazonaws.com/test",
23122317
assertConditions: []metav1.Condition{
@@ -2319,6 +2324,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23192324
registryOpts: registryOptions{
23202325
withBasicAuth: true,
23212326
},
2327+
insecure: true,
23222328
secretOpts: secretOptions{
23232329
username: testRegistryUsername,
23242330
password: testRegistryPassword,
@@ -2340,9 +2346,9 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23402346
name: "HTTPS With invalid CA cert",
23412347
wantErr: true,
23422348
registryOpts: registryOptions{
2343-
withTLS: true,
2349+
withTLS: true,
2350+
withClientCertAuth: true,
23442351
},
2345-
withTLS: true,
23462352
secretOpts: secretOptions{
23472353
username: testRegistryUsername,
23482354
password: testRegistryPassword,
@@ -2357,16 +2363,16 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23572363
},
23582364
},
23592365
assertConditions: []metav1.Condition{
2360-
*conditions.TrueCondition(sourcev1.FetchFailedCondition, "Unknown", "unknown build error: failed to create TLS client config with secret data: cannot append certificate into certificate pool: invalid caFile"),
2366+
*conditions.TrueCondition(sourcev1.FetchFailedCondition, "Unknown", "unknown build error: failed to construct Helm client's TLS config: cannot append certificate into certificate pool: invalid caFile"),
23612367
},
23622368
},
23632369
{
23642370
name: "HTTPS With CA cert",
23652371
want: sreconcile.ResultSuccess,
23662372
registryOpts: registryOptions{
2367-
withTLS: true,
2373+
withTLS: true,
2374+
withClientCertAuth: true,
23682375
},
2369-
withTLS: true,
23702376
secretOpts: secretOptions{
23712377
username: testRegistryUsername,
23722378
password: testRegistryPassword,
@@ -2376,10 +2382,17 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23762382
Name: "auth-secretref",
23772383
},
23782384
Type: corev1.SecretTypeDockerConfigJson,
2385+
Data: map[string][]byte{},
2386+
},
2387+
certsecret: &corev1.Secret{
2388+
ObjectMeta: metav1.ObjectMeta{
2389+
Name: "cert-secretref",
2390+
},
2391+
Type: corev1.SecretTypeTLS,
23792392
Data: map[string][]byte{
23802393
"caFile": tlsCA,
2381-
"certFile": tlsPublicKey,
2382-
"keyFile": tlsPrivateKey,
2394+
"certFile": clientPublicKey,
2395+
"keyFile": clientPrivateKey,
23832396
},
23842397
},
23852398
assertConditions: []metav1.Condition{
@@ -2399,7 +2412,9 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23992412

24002413
workspaceDir := t.TempDir()
24012414

2402-
tt.registryOpts.disableDNSMocking = true
2415+
if tt.insecure {
2416+
tt.registryOpts.disableDNSMocking = true
2417+
}
24032418
server, err := setupRegistryServer(ctx, workspaceDir, tt.registryOpts)
24042419
g.Expect(err).NotTo(HaveOccurred())
24052420
t.Cleanup(func() {
@@ -2411,7 +2426,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
24112426
g.Expect(err).ToNot(HaveOccurred())
24122427

24132428
// Upload the test chart
2414-
metadata, err := loadTestChartToOCI(chartData, server, "testdata/certs/server.pem", "testdata/certs/server-key.pem", "testdata/certs/ca.pem")
2429+
metadata, err := loadTestChartToOCI(chartData, server, "testdata/certs/client.pem", "testdata/certs/client-key.pem", "testdata/certs/ca.pem")
24152430
g.Expect(err).ToNot(HaveOccurred())
24162431

24172432
repo := &helmv1.HelmRepository{
@@ -2446,11 +2461,18 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
24462461
repo.Spec.SecretRef = &meta.LocalObjectReference{
24472462
Name: tt.secret.Name,
24482463
}
2449-
clientBuilder.WithObjects(tt.secret, repo)
2450-
} else {
2451-
clientBuilder.WithObjects(repo)
2464+
clientBuilder.WithObjects(tt.secret)
2465+
}
2466+
2467+
if tt.certsecret != nil {
2468+
repo.Spec.CertSecretRef = &meta.LocalObjectReference{
2469+
Name: tt.certsecret.Name,
2470+
}
2471+
clientBuilder.WithObjects(tt.certsecret)
24522472
}
24532473

2474+
clientBuilder.WithObjects(repo)
2475+
24542476
obj := &helmv1.HelmChart{
24552477
ObjectMeta: metav1.ObjectMeta{
24562478
GenerateName: "auth-strategy-",
@@ -2761,18 +2783,18 @@ func loadTestChartToOCI(chartData []byte, server *registryClientTestServer, cert
27612783
helmreg.LoginOptBasicAuth(testRegistryUsername, testRegistryPassword),
27622784
helmreg.LoginOptTLSClientConfig(certFile, keyFile, cafile))
27632785
if err != nil {
2764-
return nil, err
2786+
return nil, fmt.Errorf("failed to login to OCI registry: %w", err)
27652787
}
27662788
metadata, err := extractChartMeta(chartData)
27672789
if err != nil {
2768-
return nil, err
2790+
return nil, fmt.Errorf("failed to extract chart metadata: %w", err)
27692791
}
27702792

27712793
// Upload the test chart
27722794
ref := fmt.Sprintf("%s/testrepo/%s:%s", server.registryHost, metadata.Name, metadata.Version)
27732795
_, err = server.registryClient.Push(chartData, ref)
27742796
if err != nil {
2775-
return nil, err
2797+
return nil, fmt.Errorf("failed to push chart: %w", err)
27762798
}
27772799

27782800
return metadata, nil

internal/controller/helmrepository_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
399399
return sreconcile.ResultEmpty, e
400400
}
401401

402-
clientOpts, err := getter.GetClientOpts(ctx, r.Client, obj, normalizedURL)
402+
clientOpts, _, err := getter.GetClientOpts(ctx, r.Client, obj, normalizedURL)
403403
if err != nil {
404404
if errors.Is(err, getter.ErrDeprecatedTLSConfig) {
405405
ctrl.LoggerFrom(ctx).

0 commit comments

Comments
 (0)