Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions internal/controller/managedcrl_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
cmmetav1 "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
"github.com/go-logr/logr"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
Expand All @@ -54,6 +55,9 @@ const (
// secretCRLKey is the key in the Secret data where the CRL is stored.
secretCRLKey = "ca.crl"

// finalizerName is the name of the finalizer used to clean up resources.
finalizerName = "crl-operator.scality.com/finalizer"

// Common labels
labelManagedByName = "app.kubernetes.io/managed-by"
labelManagedByValue = "crl-operator"
Expand Down Expand Up @@ -120,6 +124,32 @@ func (r *ManagedCRLReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, client.IgnoreNotFound(err)
}

if instance.DeletionTimestamp.IsZero() {
// Add finalizer if not present
if !controllerutil.ContainsFinalizer(instance, finalizerName) {
logger.WithValues("finalizer", finalizerName).Info("adding finalizer")
controllerutil.AddFinalizer(instance, finalizerName)
if err := r.Update(ctx, instance); err != nil {
return ctrl.Result{}, err
}
}
} else {
// The object is being deleted
if controllerutil.ContainsFinalizer(instance, finalizerName) {
finLogger := logger.WithValues("finalizer", finalizerName)
if err := r.handleFinalization(finLogger, ctx, instance); err != nil {
return ctrl.Result{}, err
}

// Remove finalizer
finLogger.Info("removing finalizer")
controllerutil.RemoveFinalizer(instance, finalizerName)
if err := r.Update(ctx, instance); err != nil {
return ctrl.Result{}, err
}
}
return ctrl.Result{}, nil
}
// Apply defaults
instance.WithDefaults()
if err := instance.Validate(); err != nil {
Expand Down Expand Up @@ -756,6 +786,53 @@ func (r *ManagedCRLReconciler) stdMutate(obj metav1.Object, instance *crloperato
return nil
}

// handleFinalization handles the deletion of a ManagedCRL resource by cleaning up
// the CRL distribution points from the issuer and removing the finalizer.
func (r *ManagedCRLReconciler) handleFinalization(logger logr.Logger, ctx context.Context, instance *crloperatorv1alpha1.ManagedCRL) error {
logger.Info("handling ManagedCRL deletion")

issuer, err := r.getIssuer(ctx, instance.Namespace, instance.Spec.IssuerRef)
if err != nil {
if apierrors.IsNotFound(err) {
// Issuer no longer exists, nothing to clean up
logger.Info("issuer not found, skipping cleanup")
} else {
return fmt.Errorf("failed to get issuer: %w", err)
}
}

var originalIssuer client.Object
switch issuer := issuer.(type) {
case *cmv1.Issuer:
if issuer.Spec.CA == nil || len(issuer.Spec.CA.CRLDistributionPoints) == 0 {
// Nothing to do
break
}
originalIssuer = issuer.DeepCopy()
issuer.Spec.CA.CRLDistributionPoints = nil
case *cmv1.ClusterIssuer:
if issuer.Spec.CA == nil || len(issuer.Spec.CA.CRLDistributionPoints) == 0 {
// Nothing to do
break
}
originalIssuer = issuer.DeepCopy()
issuer.Spec.CA.CRLDistributionPoints = nil
default:
logger.Error(errors.New("unsupported issuer kind for cleaning up CRL distribution points"), "unsupported issuer kind")
// Nothing to do
}

if originalIssuer != nil {
if err := r.Patch(ctx, issuer, client.MergeFrom(originalIssuer)); err != nil {
return fmt.Errorf("failed to patch issuer: %w", err)
}
logger.Info("removed CRL distribution points from issuer during deletion")
}

logger.Info("ManagedCRL deletion handled successfully")
return nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *ManagedCRLReconciler) SetupWithManager(mgr ctrl.Manager) error {
mapIssuerToCRL := func(ctx context.Context, obj client.Object) []ctrl.Request {
Expand Down
29 changes: 29 additions & 0 deletions test/integration/managedcrl_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,33 @@ var _ = Describe("ManagedCRL Controller", func() {
k8sClient.Get(ctx, typeNamespacedName, &crloperatorv1alpha1.ManagedCRL{}),
)
}, 10*time.Second, time.Second).Should(BeTrue())

By("checking the CRL Distribution Points have been removed from the Issuer/ClusterIssuer")
switch tc.spec.IssuerRef.Kind {
case "Issuer":
issuer := &cmv1.Issuer{}
Expect(k8sClient.Get(
ctx,
types.NamespacedName{
Name: tc.spec.IssuerRef.Name,
Namespace: typeNamespacedName.Namespace,
},
issuer,
)).To(Succeed())
Expect(issuer.Spec.CA.CRLDistributionPoints).To(BeEmpty())
case "ClusterIssuer":
clusterIssuer := &cmv1.ClusterIssuer{}
Expect(k8sClient.Get(
ctx,
types.NamespacedName{
Name: tc.spec.IssuerRef.Name,
},
clusterIssuer,
)).To(Succeed())
Expect(clusterIssuer.Spec.CA.CRLDistributionPoints).To(BeEmpty())
default:
Fail("unexpected IssuerRef.Kind")
}
})
}, toTableEntry(testCases))
})
Expand Down Expand Up @@ -390,6 +417,8 @@ func checkSecret(mcrlRef types.NamespacedName) {
}, 10*time.Second, time.Second).Should(BeTrue())
retrieved.WithDefaults()

Expect(retrieved.ObjectMeta.Finalizers).To(ContainElement("crl-operator.scality.com/finalizer"))

expectedSecretNs := mcrlRef.Namespace
if retrieved.Spec.IssuerRef.Kind == "ClusterIssuer" {
expectedSecretNs = certManagerNamespace
Expand Down