From 1bc8624d9930927703615bcf48e8ca6986ea5c49 Mon Sep 17 00:00:00 2001 From: Niraj Yadav Date: Thu, 24 Oct 2024 15:02:20 +0530 Subject: [PATCH] Add option to disable KeyRotation This commit adds the option to disable the keyrotation by annotating the storageclasses, namespaces or PVCs with:`keyrotation.csiaddons-opneshift.io/enable: false` Signed-off-by: Niraj Yadav --- .../persistentvolumeclaim_controller.go | 99 ++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/internal/controller/csiaddons/persistentvolumeclaim_controller.go b/internal/controller/csiaddons/persistentvolumeclaim_controller.go index b10f6b538..00ec72238 100644 --- a/internal/controller/csiaddons/persistentvolumeclaim_controller.go +++ b/internal/controller/csiaddons/persistentvolumeclaim_controller.go @@ -67,6 +67,7 @@ var ( rsCronJobNameAnnotation = "reclaimspace." + csiaddonsv1alpha1.GroupVersion.Group + "/cronjob" rsCSIAddonsDriverAnnotation = "reclaimspace." + csiaddonsv1alpha1.GroupVersion.Group + "/drivers" + krEnableAnnotation = "keyrotation." + csiaddonsv1alpha1.GroupVersion.Group + "/enable" krcJobScheduleTimeAnnotation = "keyrotation." + csiaddonsv1alpha1.GroupVersion.Group + "/schedule" krcJobNameAnnotation = "keyrotation." + csiaddonsv1alpha1.GroupVersion.Group + "/cronjob" krCSIAddonsDriverAnnotation = "keyrotation." + csiaddonsv1alpha1.GroupVersion.Group + "/drivers" @@ -296,6 +297,7 @@ func (r *PersistentVolumeClaimReconciler) storageClassEventHandler() handler.Eve annotationsToWatch := []string{ rsCronJobScheduleTimeAnnotation, krcJobScheduleTimeAnnotation, + krEnableAnnotation, } var requests []reconcile.Request @@ -370,8 +372,8 @@ func (r *PersistentVolumeClaimReconciler) SetupWithManager(mgr ctrl.Manager, ctr return err } - pvcPred := createAnnotationPredicate(rsCronJobScheduleTimeAnnotation, krcJobScheduleTimeAnnotation) - scPred := createAnnotationPredicate(rsCronJobScheduleTimeAnnotation, krcJobScheduleTimeAnnotation) + pvcPred := createAnnotationPredicate(rsCronJobScheduleTimeAnnotation, krcJobScheduleTimeAnnotation, krEnableAnnotation) + scPred := createAnnotationPredicate(rsCronJobScheduleTimeAnnotation, krcJobScheduleTimeAnnotation, krEnableAnnotation) return ctrl.NewControllerManagedBy(mgr). For(&corev1.PersistentVolumeClaim{}). @@ -754,6 +756,25 @@ func (r *PersistentVolumeClaimReconciler) processKeyRotation( } } + disabled, err := r.checkDisabledByAnnotation(ctx, logger, pvc, krEnableAnnotation) + if err != nil { + return err + } + + if disabled { + if krcJob != nil { + err = r.Delete(ctx, krcJob) + if client.IgnoreNotFound(err) != nil { + errMsg := "failed to delete EncryptionKeyRotationCronJob" + logger.Error(err, errMsg) + return fmt.Errorf("%w: %s", err, errMsg) + } + } + + logger.Info("EncryptionKeyRotationCronJob is disabled by annotation, exiting reconcile") + return nil + } + // Determine schedule sched, err := r.determineScheduleAndRequeue(ctx, logger, pvc, pv.Spec.CSI.Driver, krcJobScheduleTimeAnnotation) if errors.Is(err, ErrScheduleNotFound) { @@ -976,3 +997,77 @@ func (r *PersistentVolumeClaimReconciler) getScheduleFromPVC( return "" } + +// checkAnnotationForValue checks if the given object has the specified annotation +// with the expected value. +func checkAnnotationForValue(obj metav1.Object, key, expected string) bool { + if val, ok := obj.GetAnnotations()[key]; ok && val == expected { + return true + } + return false +} + +// hasValidStorageClassName checks if the provided PersistentVolumeClaim has a non-empty StorageClassName. +func hasValidStorageClassName(pvc *corev1.PersistentVolumeClaim) bool { + return pvc.Spec.StorageClassName != nil && len(*pvc.Spec.StorageClassName) > 0 +} + +// checkDisabledByAnnotation checks if the given object has an annotation +// that disables the functionality represented by the provided annotationKey. +func (r *PersistentVolumeClaimReconciler) checkDisabledByAnnotation( + ctx context.Context, + logger *logr.Logger, + pvc *corev1.PersistentVolumeClaim, + annotationKey string) (bool, error) { + isDisabledOnSC := func() (bool, error) { + // Not an error, static PVs + if !hasValidStorageClassName(pvc) { + return false, nil + } + + storageClassName := *pvc.Spec.StorageClassName + storageClass := &storagev1.StorageClass{} + + err := r.Client.Get(ctx, client.ObjectKey{Name: storageClassName}, storageClass) + if err != nil { + logger.Error(err, "Failed to get StorageClass", "StorageClass", storageClassName) + return false, err + } + + return checkAnnotationForValue(storageClass, annotationKey, "false"), nil + } + + if r.SchedulePrecedence == util.ScheduleSCOnly { + disabled, err := isDisabledOnSC() + if err != nil { + return false, err + } + + return disabled, nil + } + + // Else, we follow the regular precedence + // Check on PVC + if checkAnnotationForValue(pvc, annotationKey, "false") { + return true, nil + } + + // Check on Namespace + ns := &corev1.Namespace{} + err := r.Client.Get(ctx, types.NamespacedName{Name: pvc.Namespace}, ns) + if err != nil { + logger.Error(err, "Failed to get Namespace", "Namespace", pvc.Namespace) + return false, err + } + if checkAnnotationForValue(ns, annotationKey, "false") { + return true, nil + } + + // Check on SC + disabled, err := isDisabledOnSC() + if err != nil { + return false, err + } + + return disabled, nil +}