From b36f9c2d0c4e2eea79e7a34f68c31a9ac7e9607b Mon Sep 17 00:00:00 2001 From: Erik Godding Boye Date: Wed, 14 Aug 2024 14:42:23 +0200 Subject: [PATCH] refactor: establish target.Reconciler Signed-off-by: Erik Godding Boye --- pkg/bundle/bundle.go | 15 +- pkg/bundle/bundle_test.go | 27 +- pkg/bundle/controller.go | 14 +- pkg/bundle/internal/ssa_client/patch.go | 31 ++ pkg/bundle/internal/target/data.go | 57 ++++ pkg/bundle/{ => internal/target}/target.go | 281 ++++++++---------- .../{ => internal/target}/target_test.go | 155 ++++------ pkg/bundle/source.go | 32 +- pkg/bundle/source_test.go | 14 +- 9 files changed, 310 insertions(+), 316 deletions(-) create mode 100644 pkg/bundle/internal/target/data.go rename pkg/bundle/{ => internal/target}/target.go (55%) rename pkg/bundle/{ => internal/target}/target_test.go (90%) diff --git a/pkg/bundle/bundle.go b/pkg/bundle/bundle.go index cc9953a0..b146996f 100644 --- a/pkg/bundle/bundle.go +++ b/pkg/bundle/bundle.go @@ -37,6 +37,7 @@ import ( trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1" "github.com/cert-manager/trust-manager/pkg/bundle/internal/ssa_client" + "github.com/cert-manager/trust-manager/pkg/bundle/internal/target" "github.com/cert-manager/trust-manager/pkg/fspkg" ) @@ -67,10 +68,6 @@ type bundle struct { // a cache-backed Kubernetes client client client.Client - // targetCache is a cache.Cache that holds cached ConfigMap and Secret - // resources that are used as targets for Bundles. - targetCache client.Reader - // defaultPackage holds the loaded 'default' certificate package, if one was specified // at startup. defaultPackage *fspkg.Package @@ -84,9 +81,7 @@ type bundle struct { // Options holds options for the Bundle controller. Options - // patchResourceOverwrite allows use to override the patchResource function - // it is used for testing purposes - patchResourceOverwrite func(ctx context.Context, obj interface{}) error + targetReconciler *target.Reconciler } // Reconcile is the top level function for reconciling over synced Bundles. @@ -253,7 +248,7 @@ func (b *bundle) reconcileBundle(ctx context.Context, req ctrl.Request) (result Kind: string(kind), }, } - err := b.targetCache.List(ctx, targetList, &client.ListOptions{ + err := b.targetReconciler.Cache.List(ctx, targetList, &client.ListOptions{ LabelSelector: labels.SelectorFromSet(map[string]string{ trustapi.BundleLabelKey: bundle.Name, }), @@ -303,12 +298,12 @@ func (b *bundle) reconcileBundle(ctx context.Context, req ctrl.Request) (result if target.Kind == configMapTarget { syncFunc = func(targetLog logr.Logger, target targetResource, shouldExist bool) (bool, error) { - return b.syncConfigMapTarget(ctx, targetLog, &bundle, target.Name, target.Namespace, resolvedBundle, shouldExist) + return b.targetReconciler.SyncConfigMap(ctx, targetLog, &bundle, target.NamespacedName, resolvedBundle.Data, shouldExist) } } if target.Kind == secretTarget { syncFunc = func(targetLog logr.Logger, target targetResource, shouldExist bool) (bool, error) { - return b.syncSecretTarget(ctx, targetLog, &bundle, target.Name, target.Namespace, resolvedBundle, shouldExist) + return b.targetReconciler.SyncSecret(ctx, targetLog, &bundle, target.NamespacedName, resolvedBundle.Data, shouldExist) } } diff --git a/pkg/bundle/bundle_test.go b/pkg/bundle/bundle_test.go index bea8371f..274c5bf3 100644 --- a/pkg/bundle/bundle_test.go +++ b/pkg/bundle/bundle_test.go @@ -40,6 +40,8 @@ import ( fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1" + "github.com/cert-manager/trust-manager/pkg/bundle/internal/ssa_client" + "github.com/cert-manager/trust-manager/pkg/bundle/internal/target" "github.com/cert-manager/trust-manager/pkg/bundle/internal/truststore" "github.com/cert-manager/trust-manager/pkg/fspkg" "github.com/cert-manager/trust-manager/pkg/util" @@ -217,7 +219,7 @@ func Test_Reconcile(t *testing.T) { Labels: baseBundleLabels, Annotations: annotations, OwnerReferences: baseBundleOwnerRef, - ManagedFields: managedFieldEntries(dataEntries, binDataEntries), + ManagedFields: ssa_client.ManagedFieldEntries(dataEntries, binDataEntries), }, Data: data, BinaryData: binData, @@ -254,7 +256,7 @@ func Test_Reconcile(t *testing.T) { Labels: baseBundleLabels, Annotations: annotations, OwnerReferences: baseBundleOwnerRef, - ManagedFields: managedFieldEntries(dataEntries, nil), + ManagedFields: ssa_client.ManagedFieldEntries(dataEntries, nil), }, Data: binaryData, } @@ -1311,22 +1313,25 @@ func Test_Reconcile(t *testing.T) { log, ctx := ktesting.NewTestContext(t) b := &bundle{ - client: fakeclient, - targetCache: fakeclient, - recorder: fakerecorder, - clock: fixedclock, + client: fakeclient, + recorder: fakerecorder, + clock: fixedclock, Options: Options{ Log: log, Namespace: trustNamespace, SecretTargetsEnabled: !test.disableSecretTargets, FilterExpiredCerts: true, }, - patchResourceOverwrite: func(ctx context.Context, obj interface{}) error { - logMutex.Lock() - defer logMutex.Unlock() + targetReconciler: &target.Reconciler{ + Client: fakeclient, + Cache: fakeclient, + PatchResourceOverwrite: func(ctx context.Context, obj interface{}) error { + logMutex.Lock() + defer logMutex.Unlock() - resourcePatches = append(resourcePatches, obj) - return nil + resourcePatches = append(resourcePatches, obj) + return nil + }, }, } diff --git a/pkg/bundle/controller.go b/pkg/bundle/controller.go index 40c5cc77..c5be1e43 100644 --- a/pkg/bundle/controller.go +++ b/pkg/bundle/controller.go @@ -37,6 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1" + "github.com/cert-manager/trust-manager/pkg/bundle/internal/target" "github.com/cert-manager/trust-manager/pkg/fspkg" ) @@ -52,11 +53,14 @@ func AddBundleController( targetCache cache.Cache, ) error { b := &bundle{ - client: mgr.GetClient(), - targetCache: targetCache, - recorder: mgr.GetEventRecorderFor("bundles"), - clock: clock.RealClock{}, - Options: opts, + client: mgr.GetClient(), + recorder: mgr.GetEventRecorderFor("bundles"), + clock: clock.RealClock{}, + Options: opts, + targetReconciler: &target.Reconciler{ + Client: mgr.GetClient(), + Cache: targetCache, + }, } if b.Options.DefaultPackageLocation != "" { diff --git a/pkg/bundle/internal/ssa_client/patch.go b/pkg/bundle/internal/ssa_client/patch.go index 8939d467..26c8ddae 100644 --- a/pkg/bundle/internal/ssa_client/patch.go +++ b/pkg/bundle/internal/ssa_client/patch.go @@ -17,8 +17,10 @@ limitations under the License. package ssa_client import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/structured-merge-diff/fieldpath" ) const ( @@ -38,3 +40,32 @@ func (p applyPatch) Data(_ client.Object) ([]byte, error) { func (p applyPatch) Type() types.PatchType { return types.ApplyPatchType } + +func ManagedFieldEntries(fields []string, dataFields []string) []v1.ManagedFieldsEntry { + fieldset := fieldpath.NewSet() + for _, property := range fields { + fieldset.Insert( + fieldpath.MakePathOrDie("data", property), + ) + } + for _, property := range dataFields { + fieldset.Insert( + fieldpath.MakePathOrDie("binaryData", property), + ) + } + + jsonFieldSet, err := fieldset.ToJSON() + if err != nil { + panic(err) + } + + return []v1.ManagedFieldsEntry{ + { + Manager: "trust-manager", + Operation: v1.ManagedFieldsOperationApply, + FieldsV1: &v1.FieldsV1{ + Raw: jsonFieldSet, + }, + }, + } +} diff --git a/pkg/bundle/internal/target/data.go b/pkg/bundle/internal/target/data.go new file mode 100644 index 00000000..cd01d288 --- /dev/null +++ b/pkg/bundle/internal/target/data.go @@ -0,0 +1,57 @@ +/* +Copyright 2021 The cert-manager Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "fmt" + + trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1" + "github.com/cert-manager/trust-manager/pkg/bundle/internal/truststore" + "github.com/cert-manager/trust-manager/pkg/util" +) + +// Data contains the resulting PEM-encoded certificate data from concatenating all the bundle sources together +// and binary data for any additional formats. +type Data struct { + Data string + BinaryData map[string][]byte +} + +func (b *Data) Populate(pool *util.CertPool, formats *trustapi.AdditionalFormats) error { + b.Data = pool.PEM() + + if formats != nil { + b.BinaryData = make(map[string][]byte) + + if formats.JKS != nil { + encoded, err := truststore.NewJKSEncoder(*formats.JKS.Password).Encode(pool) + if err != nil { + return fmt.Errorf("failed to encode JKS: %w", err) + } + b.BinaryData[formats.JKS.Key] = encoded + } + + if formats.PKCS12 != nil { + encoded, err := truststore.NewPKCS12Encoder(*formats.PKCS12.Password).Encode(pool) + if err != nil { + return fmt.Errorf("failed to encode PKCS12: %w", err) + } + b.BinaryData[formats.PKCS12.Key] = encoded + } + } + return nil +} diff --git a/pkg/bundle/target.go b/pkg/bundle/internal/target/target.go similarity index 55% rename from pkg/bundle/target.go rename to pkg/bundle/internal/target/target.go index e857458d..6f1725c1 100644 --- a/pkg/bundle/target.go +++ b/pkg/bundle/internal/target/target.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package bundle +package target import ( "bytes" @@ -25,8 +25,10 @@ import ( "strings" "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" coreapplyconfig "k8s.io/client-go/applyconfigurations/core/v1" metav1applyconfig "k8s.io/client-go/applyconfigurations/meta/v1" @@ -38,105 +40,87 @@ import ( "github.com/cert-manager/trust-manager/pkg/bundle/internal/ssa_client" ) -// syncConfigMapTarget syncs the given data to the target ConfigMap in the given namespace. +type Reconciler struct { + // a cache-backed Kubernetes client + Client client.Client + + // Cache is a cache.Cache that holds cached ConfigMap and Secret + // resources that are used as targets for Bundles. + Cache client.Reader + + // PatchResourceOverwrite allows use to override the patchResource function + // it is used for testing purposes + PatchResourceOverwrite func(ctx context.Context, obj interface{}) error +} + +// SyncConfigMap syncs the given data to the target ConfigMap in the given namespace. // The name of the ConfigMap is the same as the Bundle. // Ensures the ConfigMap is owned by the given Bundle, and the data is up to date. // Returns true if the ConfigMap has been created or was updated. -func (b *bundle) syncConfigMapTarget( +func (r *Reconciler) SyncConfigMap( ctx context.Context, log logr.Logger, bundle *trustapi.Bundle, - name string, - namespace string, - resolvedBundle bundleData, + name types.NamespacedName, + data Data, shouldExist bool, ) (bool, error) { - configMap := &metav1.PartialObjectMetadata{ + targetObj := &metav1.PartialObjectMetadata{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", APIVersion: "v1", }, } - err := b.targetCache.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, configMap) + err := r.Cache.Get(ctx, name, targetObj) if err != nil && !apierrors.IsNotFound(err) { - return false, fmt.Errorf("failed to get ConfigMap %s/%s: %w", namespace, name, err) - } - - // If the ConfigMap exists, but the Bundle is being deleted, delete the ConfigMap. - if apierrors.IsNotFound(err) && !shouldExist { - return false, nil + return false, fmt.Errorf("failed to get ConfigMap %s: %w", name, err) } - // If the ConfigMap should not exist, but it does, delete it. - if !apierrors.IsNotFound(err) && !shouldExist { - // apply empty patch to remove the key - configMapPatch := coreapplyconfig. - ConfigMap(name, namespace). - WithLabels(map[string]string{ - trustapi.BundleLabelKey: bundle.Name, - }). - WithOwnerReferences( - metav1applyconfig.OwnerReference(). - WithAPIVersion(trustapi.SchemeGroupVersion.String()). - WithKind(trustapi.BundleKind). - WithName(bundle.GetName()). - WithUID(bundle.GetUID()). - WithBlockOwnerDeletion(true). - WithController(true), - ) - - if err = b.patchConfigMapResource(ctx, configMapPatch); err != nil { - return false, fmt.Errorf("failed to patch ConfigMap %s/%s: %w", namespace, bundle.Name, err) + if !shouldExist { + // If the ConfigMap is not found and should not exist we are done. + if apierrors.IsNotFound(err) { + return false, nil + } + // If the ConfigMap should not exist, but it does, delete it. + // Apply empty patch to remove the keys + configMap, err := r.patchConfigMap(ctx, newConfigMapPatch(name, *bundle)) + if err != nil { + return false, fmt.Errorf("failed to patch ConfigMap %s: %w", name, err) } + // If the configMap is empty, delete it + if configMap != nil && len(configMap.Data) == 0 && len(configMap.BinaryData) == 0 { + return true, r.Client.Delete(ctx, configMap) + } return true, nil } - target := bundle.Spec.Target - if target.ConfigMap == nil { + if bundle.Spec.Target.ConfigMap == nil { return false, errors.New("target not defined") } // Generated JKS is not deterministic - best we can do here is update if the pem cert has // changed (hence not checking if JKS matches) - dataHash := fmt.Sprintf("%x", sha256.Sum256([]byte(resolvedBundle.data))) - configmapData := map[string]string{ - target.ConfigMap.Key: resolvedBundle.data, - } - configmapBinData := resolvedBundle.binaryData - + dataHash := fmt.Sprintf("%x", sha256.Sum256([]byte(data.Data))) // If the ConfigMap doesn't exist, create it. if !apierrors.IsNotFound(err) { // Exit early if no update is needed - if exit, err := b.needsUpdate(ctx, targetKindConfigMap, log, configMap, bundle, dataHash); err != nil { + if exit, err := r.needsUpdate(ctx, KindConfigMap, log, targetObj, bundle, dataHash); err != nil { return false, err } else if !exit { return false, nil } } - configMapPatch := coreapplyconfig. - ConfigMap(name, namespace). - WithLabels(map[string]string{ - trustapi.BundleLabelKey: bundle.Name, - }). + configMapPatch := newConfigMapPatch(name, *bundle). WithAnnotations(map[string]string{ trustapi.BundleHashAnnotationKey: dataHash, }). - WithOwnerReferences( - metav1applyconfig.OwnerReference(). - WithAPIVersion(trustapi.SchemeGroupVersion.String()). - WithKind(trustapi.BundleKind). - WithName(bundle.GetName()). - WithUID(bundle.GetUID()). - WithBlockOwnerDeletion(true). - WithController(true), - ). - WithData(configmapData). - WithBinaryData(configmapBinData) + WithData(map[string]string{bundle.Spec.Target.ConfigMap.Key: data.Data}). + WithBinaryData(data.BinaryData) - if err = b.patchConfigMapResource(ctx, configMapPatch); err != nil { - return false, fmt.Errorf("failed to patch ConfigMap %s/%s: %w", namespace, bundle.Name, err) + if _, err = r.patchConfigMap(ctx, configMapPatch); err != nil { + return false, fmt.Errorf("failed to patch ConfigMap %s: %w", name, err) } log.V(2).Info("synced bundle to namespace for target ConfigMap") @@ -144,107 +128,80 @@ func (b *bundle) syncConfigMapTarget( return true, nil } -// syncSecretTarget syncs the given data to the target Secret in the given namespace. +// SyncSecret syncs the given data to the target Secret in the given namespace. // The name of the Secret is the same as the Bundle. // Ensures the Secret is owned by the given Bundle, and the data is up to date. // Returns true if the Secret has been created or was updated. -func (b *bundle) syncSecretTarget( +func (r *Reconciler) SyncSecret( ctx context.Context, log logr.Logger, bundle *trustapi.Bundle, - name string, - namespace string, - resolvedBundle bundleData, + name types.NamespacedName, + data Data, shouldExist bool, ) (bool, error) { - secret := &metav1.PartialObjectMetadata{ + targetObj := &metav1.PartialObjectMetadata{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", APIVersion: "v1", }, } - err := b.targetCache.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, secret) + err := r.Cache.Get(ctx, name, targetObj) if err != nil && !apierrors.IsNotFound(err) { - return false, fmt.Errorf("failed to get Secret %s/%s: %w", namespace, name, err) + return false, fmt.Errorf("failed to get Secret %s: %w", name, err) } - // If the target obj exists, but the Bundle is being deleted, delete the Secret. - if apierrors.IsNotFound(err) && !shouldExist { - return false, nil - } - - // If the Secret should not exist, but it does, delete it. - if !apierrors.IsNotFound(err) && !shouldExist { - // apply empty patch to remove the key - secretPatch := coreapplyconfig. - Secret(name, namespace). - WithLabels(map[string]string{ - trustapi.BundleLabelKey: bundle.Name, - }). - WithOwnerReferences( - metav1applyconfig.OwnerReference(). - WithAPIVersion(trustapi.SchemeGroupVersion.String()). - WithKind(trustapi.BundleKind). - WithName(bundle.GetName()). - WithUID(bundle.GetUID()). - WithBlockOwnerDeletion(true). - WithController(true), - ) - - if err = b.patchSecretResource(ctx, secretPatch); err != nil { - return false, fmt.Errorf("failed to patch secret %s/%s: %w", namespace, bundle.Name, err) + if !shouldExist { + // If the Secret is not found and should not exist we are done. + if apierrors.IsNotFound(err) { + return false, nil + } + // If the Secret should not exist, but it does, delete it. + // Apply empty patch to remove the keys + secret, err := r.patchSecret(ctx, newSecretPatch(name, *bundle)) + if err != nil { + return false, fmt.Errorf("failed to patch Secret %s: %w", name, err) } + // If the secret is empty, delete it + if secret != nil && len(secret.Data) == 0 { + return true, r.Client.Delete(ctx, secret) + } return true, nil } - target := bundle.Spec.Target - if target.Secret == nil { + if bundle.Spec.Target.Secret == nil { return false, errors.New("target not defined") } // Generated JKS is not deterministic - best we can do here is update if the pem cert has // changed (hence not checking if JKS matches) - dataHash := fmt.Sprintf("%x", sha256.Sum256([]byte(resolvedBundle.data))) + dataHash := fmt.Sprintf("%x", sha256.Sum256([]byte(data.Data))) targetData := map[string][]byte{ - target.Secret.Key: []byte(resolvedBundle.data), + bundle.Spec.Target.Secret.Key: []byte(data.Data), } - - for k, v := range resolvedBundle.binaryData { + for k, v := range data.BinaryData { targetData[k] = v } // If the Secret doesn't exist, create it. if !apierrors.IsNotFound(err) { // Exit early if no update is needed - if exit, err := b.needsUpdate(ctx, targetKindSecret, log, secret, bundle, dataHash); err != nil { + if exit, err := r.needsUpdate(ctx, KindSecret, log, targetObj, bundle, dataHash); err != nil { return false, err } else if !exit { return false, nil } } - secretPatch := coreapplyconfig. - Secret(name, namespace). - WithLabels(map[string]string{ - trustapi.BundleLabelKey: bundle.Name, - }). + secretPatch := newSecretPatch(name, *bundle). WithAnnotations(map[string]string{ trustapi.BundleHashAnnotationKey: dataHash, }). - WithOwnerReferences( - metav1applyconfig.OwnerReference(). - WithAPIVersion(trustapi.SchemeGroupVersion.String()). - WithKind(trustapi.BundleKind). - WithName(bundle.GetName()). - WithUID(bundle.GetUID()). - WithBlockOwnerDeletion(true). - WithController(true), - ). WithData(targetData) - if err = b.patchSecretResource(ctx, secretPatch); err != nil { - return false, fmt.Errorf("failed to patch Secret %s/%s: %w", namespace, bundle.Name, err) + if _, err = r.patchSecret(ctx, secretPatch); err != nil { + return false, fmt.Errorf("failed to patch Secret %s: %w", name, err) } log.V(2).Info("synced bundle to namespace for target Secret") @@ -252,14 +209,14 @@ func (b *bundle) syncSecretTarget( return true, nil } -type targetKind string +type Kind string const ( - targetKindConfigMap targetKind = "ConfigMap" - targetKindSecret targetKind = "Secret" + KindConfigMap Kind = "ConfigMap" + KindSecret Kind = "Secret" ) -func (b *bundle) needsUpdate(ctx context.Context, kind targetKind, log logr.Logger, obj *metav1.PartialObjectMetadata, bundle *trustapi.Bundle, dataHash string) (bool, error) { +func (r *Reconciler) needsUpdate(ctx context.Context, kind Kind, log logr.Logger, obj *metav1.PartialObjectMetadata, bundle *trustapi.Bundle, dataHash string) (bool, error) { needsUpdate := false if !metav1.IsControlledBy(obj, bundle) { needsUpdate = true @@ -277,10 +234,10 @@ func (b *bundle) needsUpdate(ctx context.Context, kind targetKind, log logr.Logg var key string var targetFieldNames []string switch kind { - case targetKindConfigMap: + case KindConfigMap: key = bundle.Spec.Target.ConfigMap.Key targetFieldNames = []string{"data", "binaryData"} - case targetKindSecret: + case KindSecret: key = bundle.Spec.Target.Secret.Key targetFieldNames = []string{"data"} default: @@ -302,10 +259,10 @@ func (b *bundle) needsUpdate(ctx context.Context, kind targetKind, log logr.Logg needsUpdate = true } - if kind == targetKindConfigMap { + if kind == KindConfigMap { if bundle.Spec.Target.ConfigMap != nil { // Check if we need to migrate the ConfigMap managed fields to the Apply field operation - if didMigrate, err := ssa_client.MigrateToApply(ctx, b.client, obj); err != nil { + if didMigrate, err := ssa_client.MigrateToApply(ctx, r.Client, obj); err != nil { return false, fmt.Errorf("failed to migrate ConfigMap %s/%s to Apply: %w", obj.Namespace, obj.Name, err) } else if didMigrate { log.V(2).Info("migrated configmap from CSA to SSA") @@ -349,48 +306,62 @@ func listManagedProperties(configmap *metav1.PartialObjectMetadata, fieldManager return properties, nil } -func (b *bundle) patchConfigMapResource(ctx context.Context, applyConfig *coreapplyconfig.ConfigMapApplyConfiguration) error { - if b.patchResourceOverwrite != nil { - return b.patchResourceOverwrite(ctx, applyConfig) +func (r *Reconciler) patchConfigMap(ctx context.Context, applyConfig *coreapplyconfig.ConfigMapApplyConfiguration) (*corev1.ConfigMap, error) { + if r.PatchResourceOverwrite != nil { + return nil, r.PatchResourceOverwrite(ctx, applyConfig) } - configMap, patch, err := ssa_client.GenerateConfigMapPatch(applyConfig) + target, patch, err := ssa_client.GenerateConfigMapPatch(applyConfig) if err != nil { - return fmt.Errorf("failed to generate patch: %w", err) - } - - err = b.client.Patch(ctx, configMap, patch, ssa_client.FieldManager, client.ForceOwnership) - if err != nil { - return err - } - - // If the configMap is empty, delete it - if len(configMap.Data) == 0 && len(configMap.BinaryData) == 0 { - return b.client.Delete(ctx, configMap) + return nil, fmt.Errorf("failed to generate patch: %w", err) } - return nil + return target, r.Client.Patch(ctx, target, patch, ssa_client.FieldManager, client.ForceOwnership) } -func (b *bundle) patchSecretResource(ctx context.Context, applyConfig *coreapplyconfig.SecretApplyConfiguration) error { - if b.patchResourceOverwrite != nil { - return b.patchResourceOverwrite(ctx, applyConfig) +func (r *Reconciler) patchSecret(ctx context.Context, applyConfig *coreapplyconfig.SecretApplyConfiguration) (*corev1.Secret, error) { + if r.PatchResourceOverwrite != nil { + return nil, r.PatchResourceOverwrite(ctx, applyConfig) } - secret, patch, err := ssa_client.GenerateSecretPatch(applyConfig) + target, patch, err := ssa_client.GenerateSecretPatch(applyConfig) if err != nil { - return fmt.Errorf("failed to generate patch: %w", err) + return nil, fmt.Errorf("failed to generate patch: %w", err) } - err = b.client.Patch(ctx, secret, patch, ssa_client.FieldManager, client.ForceOwnership) - if err != nil { - return err - } + return target, r.Client.Patch(ctx, target, patch, ssa_client.FieldManager, client.ForceOwnership) +} - // If the secret is empty, delete it - if len(secret.Data) == 0 { - return b.client.Delete(ctx, secret) - } +func newConfigMapPatch(name types.NamespacedName, bundle trustapi.Bundle) *coreapplyconfig.ConfigMapApplyConfiguration { + return coreapplyconfig. + ConfigMap(name.Name, name.Namespace). + WithLabels(map[string]string{ + trustapi.BundleLabelKey: bundle.Name, + }). + WithOwnerReferences( + metav1applyconfig.OwnerReference(). + WithAPIVersion(trustapi.SchemeGroupVersion.String()). + WithKind(trustapi.BundleKind). + WithName(bundle.GetName()). + WithUID(bundle.GetUID()). + WithBlockOwnerDeletion(true). + WithController(true), + ) +} - return nil +func newSecretPatch(name types.NamespacedName, bundle trustapi.Bundle) *coreapplyconfig.SecretApplyConfiguration { + return coreapplyconfig. + Secret(name.Name, name.Namespace). + WithLabels(map[string]string{ + trustapi.BundleLabelKey: bundle.Name, + }). + WithOwnerReferences( + metav1applyconfig.OwnerReference(). + WithAPIVersion(trustapi.SchemeGroupVersion.String()). + WithKind(trustapi.BundleKind). + WithName(bundle.GetName()). + WithUID(bundle.GetUID()). + WithBlockOwnerDeletion(true). + WithController(true), + ) } diff --git a/pkg/bundle/target_test.go b/pkg/bundle/internal/target/target_test.go similarity index 90% rename from pkg/bundle/target_test.go rename to pkg/bundle/internal/target/target_test.go index 7457aaeb..d7a0ff75 100644 --- a/pkg/bundle/target_test.go +++ b/pkg/bundle/internal/target/target_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package bundle +package target import ( "context" @@ -27,15 +27,15 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" coreapplyconfig "k8s.io/client-go/applyconfigurations/core/v1" metav1applyconfig "k8s.io/client-go/applyconfigurations/meta/v1" - "k8s.io/client-go/tools/record" "k8s.io/klog/v2/ktesting" "k8s.io/utils/ptr" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/structured-merge-diff/fieldpath" trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1" + "github.com/cert-manager/trust-manager/pkg/bundle/internal/ssa_client" "github.com/cert-manager/trust-manager/test/dummy" ) @@ -53,35 +53,6 @@ var ( pkcs12Data = []byte("PKCS12") ) -func managedFieldEntries(fields []string, dataFields []string) []metav1.ManagedFieldsEntry { - fieldset := fieldpath.NewSet() - for _, property := range fields { - fieldset.Insert( - fieldpath.MakePathOrDie("data", property), - ) - } - for _, property := range dataFields { - fieldset.Insert( - fieldpath.MakePathOrDie("binaryData", property), - ) - } - - jsonFieldSet, err := fieldset.ToJSON() - if err != nil { - panic(err) - } - - return []metav1.ManagedFieldsEntry{ - { - Manager: "trust-manager", - Operation: metav1.ManagedFieldsOperationApply, - FieldsV1: &metav1.FieldsV1{ - Raw: jsonFieldSet, - }, - }, - } -} - func Test_syncConfigMapTarget(t *testing.T) { dataHash := fmt.Sprintf("%x", sha256.Sum256([]byte(data))) @@ -99,7 +70,6 @@ func Test_syncConfigMapTarget(t *testing.T) { expJKS bool // Expect PKCS12 to exist in the configmap at the end of the sync. expPKCS12 bool - expEvent string // Expect the owner reference of the configmap to point to the bundle. expOwnerReference bool expNeedsUpdate bool @@ -139,7 +109,7 @@ func Test_syncConfigMapTarget(t *testing.T) { Namespace: "test-namespace", Labels: map[string]string{trustapi.BundleLabelKey: bundleName}, Annotations: map[string]string{trustapi.BundleHashAnnotationKey: dataHash}, - ManagedFields: managedFieldEntries(nil, nil), + ManagedFields: ssa_client.ManagedFieldEntries(nil, nil), }, }, namespace: corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace"}}, @@ -155,7 +125,7 @@ func Test_syncConfigMapTarget(t *testing.T) { Namespace: "test-namespace", Labels: map[string]string{trustapi.BundleLabelKey: bundleName}, Annotations: map[string]string{trustapi.BundleHashAnnotationKey: dataHash}, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -205,7 +175,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: "wrong data"}, }, @@ -231,7 +201,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -259,7 +229,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -287,7 +257,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{"wrong key"}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{"wrong key"}, nil), }, BinaryData: map[string][]byte{"wrong key": []byte(data)}, }, @@ -313,7 +283,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, []string{"wrong key"}), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, []string{"wrong key"}), }, BinaryData: map[string][]byte{ key: []byte(data), @@ -344,7 +314,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key, "wrong key"}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key, "wrong key"}, nil), }, Data: map[string]string{ key: data, @@ -375,7 +345,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -401,7 +371,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -429,7 +399,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -464,7 +434,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{ key: data, @@ -515,7 +485,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -544,7 +514,7 @@ func Test_syncConfigMapTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -564,7 +534,7 @@ func Test_syncConfigMapTarget(t *testing.T) { Namespace: "test-namespace", Labels: map[string]string{trustapi.BundleLabelKey: bundleName}, Annotations: map[string]string{trustapi.BundleHashAnnotationKey: dataHash}, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string]string{key: data}, }, @@ -590,19 +560,17 @@ func Test_syncConfigMapTarget(t *testing.T) { clientBuilder.WithRuntimeObjects(test.object) } - fakeclient := clientBuilder.Build() - fakerecorder := record.NewFakeRecorder(1) + client := clientBuilder.Build() var ( logMutex sync.Mutex resourcePatches []interface{} ) - b := &bundle{ - client: fakeclient, - targetCache: fakeclient, - recorder: fakerecorder, - patchResourceOverwrite: func(ctx context.Context, obj interface{}) error { + r := &Reconciler{ + Client: client, + Cache: client, + PatchResourceOverwrite: func(ctx context.Context, obj interface{}) error { logMutex.Lock() defer logMutex.Unlock() @@ -617,14 +585,14 @@ func Test_syncConfigMapTarget(t *testing.T) { AdditionalFormats: &trustapi.AdditionalFormats{}, }, } - resolvedBundle := bundleData{data: data, binaryData: make(map[string][]byte)} + targetData := Data{Data: data, BinaryData: make(map[string][]byte)} if test.withJKS { spec.Target.AdditionalFormats.JKS = &trustapi.JKS{ KeySelector: trustapi.KeySelector{ Key: jksKey, }, } - resolvedBundle.binaryData[jksKey] = jksData + targetData.BinaryData[jksKey] = jksData } if test.withPKCS12 { spec.Target.AdditionalFormats.PKCS12 = &trustapi.PKCS12{ @@ -632,14 +600,14 @@ func Test_syncConfigMapTarget(t *testing.T) { Key: pkcs12Key, }, } - resolvedBundle.binaryData[pkcs12Key] = pkcs12Data + targetData.BinaryData[pkcs12Key] = pkcs12Data } log, ctx := ktesting.NewTestContext(t) - needsUpdate, err := b.syncConfigMapTarget(ctx, log, &trustapi.Bundle{ + needsUpdate, err := r.SyncConfigMap(ctx, log, &trustapi.Bundle{ ObjectMeta: metav1.ObjectMeta{Name: bundleName}, Spec: spec, - }, bundleName, test.namespace.Name, resolvedBundle, test.shouldExist) + }, types.NamespacedName{Name: bundleName, Namespace: test.namespace.Name}, targetData, test.shouldExist) assert.NoError(t, err) assert.Equalf(t, test.expNeedsUpdate, needsUpdate, "unexpected needsUpdate, exp=%t got=%t", test.expNeedsUpdate, needsUpdate) @@ -686,13 +654,6 @@ func Test_syncConfigMapTarget(t *testing.T) { assert.Equal(t, pkcs12Data, binData) } } - - var event string - select { - case event = <-fakerecorder.Events: - default: - } - assert.Equal(t, test.expEvent, event) }) } } @@ -719,7 +680,6 @@ func Test_syncSecretTarget(t *testing.T) { expJKS bool // Expect PKCS12 to exist in the secret at the end of the sync. expPKCS12 bool - expEvent string // Expect the owner reference of the secret to point to the bundle. expOwnerReference bool expNeedsUpdate bool @@ -759,7 +719,7 @@ func Test_syncSecretTarget(t *testing.T) { Namespace: "test-namespace", Labels: map[string]string{trustapi.BundleLabelKey: bundleName}, Annotations: map[string]string{trustapi.BundleHashAnnotationKey: dataHash}, - ManagedFields: managedFieldEntries(nil, nil), + ManagedFields: ssa_client.ManagedFieldEntries(nil, nil), }, }, namespace: corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace"}}, @@ -775,7 +735,7 @@ func Test_syncSecretTarget(t *testing.T) { Namespace: "test-namespace", Labels: map[string]string{trustapi.BundleLabelKey: bundleName}, Annotations: map[string]string{trustapi.BundleHashAnnotationKey: dataHash}, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -825,7 +785,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte("wrong data")}, }, @@ -851,7 +811,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -879,7 +839,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -907,7 +867,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{"wrong key"}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{"wrong key"}, nil), }, Data: map[string][]byte{"wrong key": []byte(data)}, }, @@ -933,7 +893,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, []string{"wrong key"}), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, []string{"wrong key"}), }, Data: map[string][]byte{ key: []byte(data), @@ -964,7 +924,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key, "wrong key"}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key, "wrong key"}, nil), }, Data: map[string][]byte{ key: []byte(data), @@ -995,7 +955,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -1021,7 +981,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -1049,7 +1009,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -1084,7 +1044,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{ key: []byte(data), @@ -1135,7 +1095,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -1164,7 +1124,7 @@ func Test_syncSecretTarget(t *testing.T) { BlockOwnerDeletion: ptr.To(true), }, }, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -1184,7 +1144,7 @@ func Test_syncSecretTarget(t *testing.T) { Namespace: "test-namespace", Labels: map[string]string{trustapi.BundleLabelKey: bundleName}, Annotations: map[string]string{trustapi.BundleHashAnnotationKey: dataHash}, - ManagedFields: managedFieldEntries([]string{key}, nil), + ManagedFields: ssa_client.ManagedFieldEntries([]string{key}, nil), }, Data: map[string][]byte{key: []byte(data)}, }, @@ -1210,19 +1170,17 @@ func Test_syncSecretTarget(t *testing.T) { clientBuilder.WithRuntimeObjects(test.object) } - fakeclient := clientBuilder.Build() - fakerecorder := record.NewFakeRecorder(1) + client := clientBuilder.Build() var ( logMutex sync.Mutex resourcePatches []interface{} ) - b := &bundle{ - client: fakeclient, - targetCache: fakeclient, - recorder: fakerecorder, - patchResourceOverwrite: func(ctx context.Context, obj interface{}) error { + r := &Reconciler{ + Client: client, + Cache: client, + PatchResourceOverwrite: func(ctx context.Context, obj interface{}) error { logMutex.Lock() defer logMutex.Unlock() @@ -1237,14 +1195,14 @@ func Test_syncSecretTarget(t *testing.T) { AdditionalFormats: &trustapi.AdditionalFormats{}, }, } - resolvedBundle := bundleData{data: data, binaryData: make(map[string][]byte)} + targetData := Data{Data: data, BinaryData: make(map[string][]byte)} if test.withJKS { spec.Target.AdditionalFormats.JKS = &trustapi.JKS{ KeySelector: trustapi.KeySelector{ Key: jksKey, }, } - resolvedBundle.binaryData[jksKey] = jksData + targetData.BinaryData[jksKey] = jksData } if test.withPKCS12 { spec.Target.AdditionalFormats.PKCS12 = &trustapi.PKCS12{ @@ -1252,14 +1210,14 @@ func Test_syncSecretTarget(t *testing.T) { Key: pkcs12Key, }, } - resolvedBundle.binaryData[pkcs12Key] = pkcs12Data + targetData.BinaryData[pkcs12Key] = pkcs12Data } log, ctx := ktesting.NewTestContext(t) - needsUpdate, err := b.syncSecretTarget(ctx, log, &trustapi.Bundle{ + needsUpdate, err := r.SyncSecret(ctx, log, &trustapi.Bundle{ ObjectMeta: metav1.ObjectMeta{Name: bundleName}, Spec: spec, - }, bundleName, test.namespace.Name, resolvedBundle, test.shouldExist) + }, types.NamespacedName{Name: bundleName, Namespace: test.namespace.Name}, targetData, test.shouldExist) assert.NoError(t, err) assert.Equalf(t, test.expNeedsUpdate, needsUpdate, "unexpected needsUpdate, exp=%t got=%t", test.expNeedsUpdate, needsUpdate) @@ -1304,13 +1262,6 @@ func Test_syncSecretTarget(t *testing.T) { assert.Equal(t, pkcs12Data, binData) } } - - var event string - select { - case event = <-fakerecorder.Events: - default: - } - assert.Equal(t, test.expEvent, event) }) } } diff --git a/pkg/bundle/source.go b/pkg/bundle/source.go index e94c6df2..e02aabb2 100644 --- a/pkg/bundle/source.go +++ b/pkg/bundle/source.go @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1" - "github.com/cert-manager/trust-manager/pkg/bundle/internal/truststore" + "github.com/cert-manager/trust-manager/pkg/bundle/internal/target" "github.com/cert-manager/trust-manager/pkg/util" ) @@ -37,8 +37,7 @@ type notFoundError struct{ error } // certificate data from concatenating all the sources together, binary data for any additional formats and // any metadata from the sources which needs to be exposed on the Bundle resource's status field. type bundleData struct { - data string - binaryData map[string][]byte + target.Data defaultCAPackageStringID string } @@ -93,7 +92,7 @@ func (b *bundle) buildSourceBundle(ctx context.Context, sources []trustapi.Bundl return bundleData{}, fmt.Errorf("couldn't find any valid certificates in bundle") } - if err := resolvedBundle.populateData(certPool, formats); err != nil { + if err := resolvedBundle.Data.Populate(certPool, formats); err != nil { return bundleData{}, err } @@ -193,28 +192,3 @@ func (b *bundle) secretBundle(ctx context.Context, ref *trustapi.SourceObjectKey } return results.String(), nil } - -func (b *bundleData) populateData(pool *util.CertPool, formats *trustapi.AdditionalFormats) error { - b.data = pool.PEM() - - if formats != nil { - b.binaryData = make(map[string][]byte) - - if formats.JKS != nil { - encoded, err := truststore.NewJKSEncoder(*formats.JKS.Password).Encode(pool) - if err != nil { - return fmt.Errorf("failed to encode JKS: %w", err) - } - b.binaryData[formats.JKS.Key] = encoded - } - - if formats.PKCS12 != nil { - encoded, err := truststore.NewPKCS12Encoder(*formats.PKCS12.Password).Encode(pool) - if err != nil { - return fmt.Errorf("failed to encode PKCS12: %w", err) - } - b.binaryData[formats.PKCS12.Key] = encoded - } - } - return nil -} diff --git a/pkg/bundle/source_test.go b/pkg/bundle/source_test.go index 26283697..077038ea 100644 --- a/pkg/bundle/source_test.go +++ b/pkg/bundle/source_test.go @@ -39,6 +39,12 @@ import ( "github.com/cert-manager/trust-manager/test/dummy" ) +const ( + jksKey = "trust.jks" + pkcs12Key = "trust.p12" + data = dummy.TestCertificate1 +) + func Test_buildSourceBundle(t *testing.T) { tests := map[string]struct { sources []trustapi.BundleSource @@ -347,11 +353,11 @@ func Test_buildSourceBundle(t *testing.T) { t.Errorf("unexpected notFoundError, exp=%t got=%v", test.expNotFoundError, err) } - if resolvedBundle.data != test.expData { - t.Errorf("unexpected data, exp=%q got=%q", test.expData, resolvedBundle.data) + if resolvedBundle.Data.Data != test.expData { + t.Errorf("unexpected data, exp=%q got=%q", test.expData, resolvedBundle.Data.Data) } - binData, jksExists := resolvedBundle.binaryData[jksKey] + binData, jksExists := resolvedBundle.Data.BinaryData[jksKey] assert.Equal(t, test.expJKS, jksExists) if test.expJKS { @@ -375,7 +381,7 @@ func Test_buildSourceBundle(t *testing.T) { assert.Equal(t, p.Bytes, cert.Certificate.Content) } - binData, pkcs12Exists := resolvedBundle.binaryData[pkcs12Key] + binData, pkcs12Exists := resolvedBundle.Data.BinaryData[pkcs12Key] assert.Equal(t, test.expPKCS12, pkcs12Exists) if test.expPKCS12 {