From 36db15b08818a538032ebdb251000149d2d99342 Mon Sep 17 00:00:00 2001 From: Niraj Yadav Date: Thu, 24 Oct 2024 15:02:20 +0530 Subject: [PATCH 1/2] 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 +} From 54fb0a8472bcf731a63e65ceaf99e50ae8278059 Mon Sep 17 00:00:00 2001 From: Niraj Yadav Date: Tue, 29 Oct 2024 18:10:28 +0530 Subject: [PATCH 2/2] update docs for disabling key rotation Signed-off-by: Niraj Yadav --- docs/encryptionkeyrotation.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/encryptionkeyrotation.md b/docs/encryptionkeyrotation.md index d3af50d92..3368f2060 100644 --- a/docs/encryptionkeyrotation.md +++ b/docs/encryptionkeyrotation.md @@ -157,3 +157,29 @@ itself by adding the `csiaddons.openshift.io/state: "unmanaged"` annotation. CSI Addons will not perform any further modifications on the `EncryptionKeyRotationCronJob` with the `unmanaged` state. To have a custom schedule the user can then modify the `schedule` field of the `EncryptionKeyRotationCronJob` spec. + +## Disabling Key Rotation + +### Disabling Key Rotation for a Specific PersistentVolumeClaim + +To disable key rotation for a specific PersistentVolumeClaim (PVC), edit the `EncryptionKeyRotationCronJob` custom resource (CR) associated with that PVC. Follow these steps: + +1. **Identify the `EncryptionKeyRotationCronJob` CR**: Run the following command to retrieve the name of the `EncryptionKeyRotationCronJob` CR associated with the PVC: + + ```bash + kubectl get encryptionkeyrotationcronjob -o jsonpath='{range .items[?(@.spec.jobTemplate.spec.target.persistentVolumeClaim=="")]}{.metadata.name}{"\n"}{end}' + ``` + + Replace `` with the name of your PVC. + +2. **Edit the `EncryptionKeyRotationCronJob` CR**: Use the following settings in the CR to disable key rotation for this specific PVC: + - Update the `csiaddons.openshift.io/state` annotation from `"managed"` to `"unmanaged"`. + - Add `suspend: true` under the `spec` field. + +These changes will disable key rotation for the specified PVC. + +### Disabling Key Rotation for All PersistentVolumeClaims in a StorageClass + +To disable key rotation for all PVCs in a particular StorageClass, annotate the StorageClass with `keyrotation.csiaddons.openshift.io/enable: "false"`. + +This action will disable key rotation across all PVCs in that StorageClass and remove any existing `EncryptionKeyRotationCronJob` CRs for PVCs within it.