Skip to content

Commit 4b237d5

Browse files
committed
refactor TLSconfig funcs
Signed-off-by: Soule BA <[email protected]>
1 parent 22942cb commit 4b237d5

22 files changed

+453
-420
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: 50 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,
@@ -2352,21 +2358,27 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23522358
Name: "auth-secretref",
23532359
},
23542360
Type: corev1.SecretTypeDockerConfigJson,
2361+
Data: map[string][]byte{},
2362+
},
2363+
certsecret: &corev1.Secret{
2364+
ObjectMeta: metav1.ObjectMeta{
2365+
Name: "certs-secretref",
2366+
},
23552367
Data: map[string][]byte{
23562368
"caFile": []byte("invalid caFile"),
23572369
},
23582370
},
23592371
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"),
2372+
*conditions.TrueCondition(sourcev1.FetchFailedCondition, "Unknown", "unknown build error: failed to construct Helm client's TLS config: cannot append certificate into certificate pool: invalid caFile"),
23612373
},
23622374
},
23632375
{
23642376
name: "HTTPS With CA cert",
23652377
want: sreconcile.ResultSuccess,
23662378
registryOpts: registryOptions{
2367-
withTLS: true,
2379+
withTLS: true,
2380+
withClientCertAuth: true,
23682381
},
2369-
withTLS: true,
23702382
secretOpts: secretOptions{
23712383
username: testRegistryUsername,
23722384
password: testRegistryPassword,
@@ -2376,10 +2388,16 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23762388
Name: "auth-secretref",
23772389
},
23782390
Type: corev1.SecretTypeDockerConfigJson,
2391+
Data: map[string][]byte{},
2392+
},
2393+
certsecret: &corev1.Secret{
2394+
ObjectMeta: metav1.ObjectMeta{
2395+
Name: "certs-secretref",
2396+
},
23792397
Data: map[string][]byte{
23802398
"caFile": tlsCA,
2381-
"certFile": tlsPublicKey,
2382-
"keyFile": tlsPrivateKey,
2399+
"certFile": clientPublicKey,
2400+
"keyFile": clientPrivateKey,
23832401
},
23842402
},
23852403
assertConditions: []metav1.Condition{
@@ -2399,7 +2417,9 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
23992417

24002418
workspaceDir := t.TempDir()
24012419

2402-
tt.registryOpts.disableDNSMocking = true
2420+
if tt.insecure {
2421+
tt.registryOpts.disableDNSMocking = true
2422+
}
24032423
server, err := setupRegistryServer(ctx, workspaceDir, tt.registryOpts)
24042424
g.Expect(err).NotTo(HaveOccurred())
24052425
t.Cleanup(func() {
@@ -2411,7 +2431,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
24112431
g.Expect(err).ToNot(HaveOccurred())
24122432

24132433
// Upload the test chart
2414-
metadata, err := loadTestChartToOCI(chartData, server, "testdata/certs/server.pem", "testdata/certs/server-key.pem", "testdata/certs/ca.pem")
2434+
metadata, err := loadTestChartToOCI(chartData, server, "testdata/certs/client.pem", "testdata/certs/client-key.pem", "testdata/certs/ca.pem")
24152435
g.Expect(err).ToNot(HaveOccurred())
24162436

24172437
repo := &helmv1.HelmRepository{
@@ -2446,11 +2466,18 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_authStrategy(t *testing.T) {
24462466
repo.Spec.SecretRef = &meta.LocalObjectReference{
24472467
Name: tt.secret.Name,
24482468
}
2449-
clientBuilder.WithObjects(tt.secret, repo)
2450-
} else {
2451-
clientBuilder.WithObjects(repo)
2469+
clientBuilder.WithObjects(tt.secret)
2470+
}
2471+
2472+
if tt.certsecret != nil {
2473+
repo.Spec.CertSecretRef = &meta.LocalObjectReference{
2474+
Name: tt.certsecret.Name,
2475+
}
2476+
clientBuilder.WithObjects(tt.certsecret)
24522477
}
24532478

2479+
clientBuilder.WithObjects(repo)
2480+
24542481
obj := &helmv1.HelmChart{
24552482
ObjectMeta: metav1.ObjectMeta{
24562483
GenerateName: "auth-strategy-",
@@ -2761,18 +2788,18 @@ func loadTestChartToOCI(chartData []byte, server *registryClientTestServer, cert
27612788
helmreg.LoginOptBasicAuth(testRegistryUsername, testRegistryPassword),
27622789
helmreg.LoginOptTLSClientConfig(certFile, keyFile, cafile))
27632790
if err != nil {
2764-
return nil, err
2791+
return nil, fmt.Errorf("failed to login to OCI registry: %w", err)
27652792
}
27662793
metadata, err := extractChartMeta(chartData)
27672794
if err != nil {
2768-
return nil, err
2795+
return nil, fmt.Errorf("failed to extract chart metadata: %w", err)
27692796
}
27702797

27712798
// Upload the test chart
27722799
ref := fmt.Sprintf("%s/testrepo/%s:%s", server.registryHost, metadata.Name, metadata.Version)
27732800
_, err = server.registryClient.Push(chartData, ref)
27742801
if err != nil {
2775-
return nil, err
2802+
return nil, fmt.Errorf("failed to push chart: %w", err)
27762803
}
27772804

27782805
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)