Skip to content

Commit

Permalink
refactor: establish target.Reconciler
Browse files Browse the repository at this point in the history
Signed-off-by: Erik Godding Boye <[email protected]>
  • Loading branch information
erikgb committed Jul 19, 2024
1 parent 51f1e51 commit e6d182a
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 330 deletions.
20 changes: 8 additions & 12 deletions pkg/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,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"
)

Expand Down Expand Up @@ -68,10 +69,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
Expand All @@ -85,9 +82,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.
Expand All @@ -102,7 +97,7 @@ func (b *bundle) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result,
return ctrl.Result{}, utilerrors.NewAggregate([]error{resultErr, err})
}

if err := b.client.Status().Patch(ctx, con, patch, client.FieldOwner(fieldManager), client.ForceOwnership); err != nil {
if err := b.client.Status().Patch(ctx, con, patch, ssa_client.FieldManager, client.ForceOwnership); err != nil {
err = fmt.Errorf("failed to apply bundle status patch: %w", err)
return ctrl.Result{}, utilerrors.NewAggregate([]error{resultErr, err})
}
Expand Down Expand Up @@ -254,7 +249,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,
}),
Expand Down Expand Up @@ -304,12 +299,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)
}
}

Expand Down Expand Up @@ -388,7 +383,8 @@ func (b *bundle) bundleTargetNamespaceSelector(bundleObj *trustapi.Bundle) (labe
// to ensure that the apply operations will also remove fields that were
// created by the Update operation.
func (b *bundle) migrateBundleStatusToApply(ctx context.Context, obj client.Object) (bool, error) {
patch, err := csaupgrade.UpgradeManagedFieldsPatch(obj, sets.New(fieldManager, crRegressionFieldManager), fieldManager, csaupgrade.Subresource("status"))
fieldManager := string(ssa_client.FieldManager)
patch, err := csaupgrade.UpgradeManagedFieldsPatch(obj, sets.New(fieldManager, ssa_client.CRRegressionFieldManager), fieldManager, csaupgrade.Subresource("status"))
if err != nil {
return false, err
}
Expand Down
27 changes: 16 additions & 11 deletions pkg/bundle/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
}
Expand Down Expand Up @@ -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
},
},
}

Expand Down
14 changes: 9 additions & 5 deletions pkg/bundle/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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 != "" {
Expand Down
40 changes: 40 additions & 0 deletions pkg/bundle/internal/ssa_client/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,19 @@ 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 (
FieldManager = client.FieldOwner("trust-manager")
// CRRegressionFieldManager is the field manager that was introduced by a regression in controller-runtime
// version 0.15.0; fixed in 15.1 and 0.16.0: https://github.com/kubernetes-sigs/controller-runtime/pull/2435
// trust-manager 0.6.0 was released with this regression in controller-runtime, which means that we have to
// take extra care when migrating from CSA to SSA.
CRRegressionFieldManager = "Go-http-client"
)

type applyPatch struct {
Expand All @@ -34,3 +45,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,
},
},
}
}
57 changes: 57 additions & 0 deletions pkg/bundle/internal/target/data.go
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit e6d182a

Please sign in to comment.