From 5fce786ba67fb5c651d5672f5411662477687531 Mon Sep 17 00:00:00 2001 From: yati1998 Date: Tue, 15 Oct 2024 10:07:44 +0530 Subject: [PATCH] update the volumereplication condition this commit updates the volumereplication conditions to include descriptive message for every operations Signed-off-by: yati1998 --- .../v1alpha1/volumereplication_types.go | 19 ++++++++++ .../controller/replication.storage/status.go | 38 ++++++++++++++++--- .../volumereplication_controller.go | 32 ++++++++-------- 3 files changed, 67 insertions(+), 22 deletions(-) diff --git a/api/replication.storage/v1alpha1/volumereplication_types.go b/api/replication.storage/v1alpha1/volumereplication_types.go index 0e777409b..a6e9149e6 100644 --- a/api/replication.storage/v1alpha1/volumereplication_types.go +++ b/api/replication.storage/v1alpha1/volumereplication_types.go @@ -36,6 +36,25 @@ const ( ConditionValidated = "Validated" ) +// These are valid messages for various +// conditions and states of Volume +// replication. +const ( + MessagePromoted = "volume is promoted" + MessageHealthy = "volume is healthy" + MessageNotResyncing = "volume is not resyncing" + MessagePromotionErrorDetected = "error detected while promotion" + MessageDemotionErrorDetected = "error detected while demotion" + MessageResyncErrorDetected = "error detected while resyncing" + MessageValidated = "volume is validated" + MessageFailedPromoted = "failed to promote volume" + MessageFailedPreCondition = "failed to meet prerequisite" + MessageDemoted = "volume is demoted" + MessageDegraded = "volume is degraded" + MessageResyncTriggered = "resync is triggered" + MessageResyncFailed = "failed to resync" +) + // These are valid conditions. const ( diff --git a/internal/controller/replication.storage/status.go b/internal/controller/replication.storage/status.go index d8c1de8f3..a268b373c 100644 --- a/internal/controller/replication.storage/status.go +++ b/internal/controller/replication.storage/status.go @@ -26,18 +26,21 @@ import ( // sets conditions when volume was promoted successfully. func setPromotedCondition(conditions *[]metav1.Condition, observedGeneration int64) { setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessagePromoted, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.Promoted, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageHealthy, Type: v1alpha1.ConditionDegraded, Reason: v1alpha1.Healthy, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageNotResyncing, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.NotResyncing, ObservedGeneration: observedGeneration, @@ -46,26 +49,30 @@ func setPromotedCondition(conditions *[]metav1.Condition, observedGeneration int } // sets conditions when volume promotion was failed. -func setFailedPromotionCondition(conditions *[]metav1.Condition, observedGeneration int64) { +func setFailedPromotionCondition(conditions *[]metav1.Condition, observedGeneration int64, errMessage string, errFromCephCSI string) { setStatusCondition(conditions, &metav1.Condition{ + Message: errMessage, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToPromote, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessagePromotionErrorDetected, Type: v1alpha1.ConditionDegraded, - Reason: v1alpha1.Error, + Reason: errFromCephCSI, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageNotResyncing, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.NotResyncing, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageValidated, Type: v1alpha1.ConditionValidated, Reason: v1alpha1.PrerequisiteMet, ObservedGeneration: observedGeneration, @@ -76,24 +83,28 @@ func setFailedPromotionCondition(conditions *[]metav1.Condition, observedGenerat // sets conditions when volume promotion was failed due to failed validation. func setFailedValidationCondition(conditions *[]metav1.Condition, observedGeneration int64) { setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageFailedPromoted, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToPromote, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessagePromotionErrorDetected, Type: v1alpha1.ConditionDegraded, Reason: v1alpha1.Error, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageNotResyncing, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.NotResyncing, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageFailedPreCondition, Type: v1alpha1.ConditionValidated, Reason: v1alpha1.PrerequisiteNotMet, ObservedGeneration: observedGeneration, @@ -104,12 +115,14 @@ func setFailedValidationCondition(conditions *[]metav1.Condition, observedGenera // sets conditions when volume is demoted and ready to use (resync completed). func setNotDegradedCondition(conditions *[]metav1.Condition, observedGeneration int64) { setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageDemoted, Type: v1alpha1.ConditionDegraded, Reason: v1alpha1.Healthy, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageNotResyncing, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.NotResyncing, ObservedGeneration: observedGeneration, @@ -120,18 +133,21 @@ func setNotDegradedCondition(conditions *[]metav1.Condition, observedGeneration // sets conditions when volume was demoted successfully. func setDemotedCondition(conditions *[]metav1.Condition, observedGeneration int64) { setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageDemoted, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.Demoted, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageDegraded, Type: v1alpha1.ConditionDegraded, Reason: v1alpha1.VolumeDegraded, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageNotResyncing, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.NotResyncing, ObservedGeneration: observedGeneration, @@ -140,20 +156,23 @@ func setDemotedCondition(conditions *[]metav1.Condition, observedGeneration int6 } // sets conditions when volume demotion was failed. -func setFailedDemotionCondition(conditions *[]metav1.Condition, observedGeneration int64) { +func setFailedDemotionCondition(conditions *[]metav1.Condition, observedGeneration int64, errMessage string, errFromCephCSI string) { setStatusCondition(conditions, &metav1.Condition{ + Message: errMessage, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToDemote, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageDemotionErrorDetected, Type: v1alpha1.ConditionDegraded, - Reason: v1alpha1.Error, + Reason: errFromCephCSI, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageNotResyncing, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.NotResyncing, ObservedGeneration: observedGeneration, @@ -164,18 +183,21 @@ func setFailedDemotionCondition(conditions *[]metav1.Condition, observedGenerati // sets conditions when volume resync was triggered successfully. func setResyncCondition(conditions *[]metav1.Condition, observedGeneration int64) { setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageDemoted, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.Demoted, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageDegraded, Type: v1alpha1.ConditionDegraded, Reason: v1alpha1.VolumeDegraded, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageResyncTriggered, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.ResyncTriggered, ObservedGeneration: observedGeneration, @@ -184,20 +206,23 @@ func setResyncCondition(conditions *[]metav1.Condition, observedGeneration int64 } // sets conditions when volume resync failed. -func setFailedResyncCondition(conditions *[]metav1.Condition, observedGeneration int64) { +func setFailedResyncCondition(conditions *[]metav1.Condition, observedGeneration int64, errMessage string, errFromCephCSI string) { setStatusCondition(conditions, &metav1.Condition{ + Message: errMessage, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToResync, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageResyncErrorDetected, Type: v1alpha1.ConditionDegraded, - Reason: v1alpha1.Error, + Reason: errFromCephCSI, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageResyncFailed, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.FailedToResync, ObservedGeneration: observedGeneration, @@ -223,6 +248,7 @@ func setStatusCondition(existingConditions *[]metav1.Condition, newCondition *me existingCondition.LastTransitionTime = metav1.NewTime(time.Now()) } + existingCondition.Message = newCondition.Message existingCondition.Reason = newCondition.Reason existingCondition.ObservedGeneration = newCondition.ObservedGeneration } diff --git a/internal/controller/replication.storage/volumereplication_controller.go b/internal/controller/replication.storage/volumereplication_controller.go index c69fd8e40..75c4fe4a0 100644 --- a/internal/controller/replication.storage/volumereplication_controller.go +++ b/internal/controller/replication.storage/volumereplication_controller.go @@ -112,7 +112,7 @@ func (r *VolumeReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Re // Get VolumeReplicationClass vrcObj, err := r.getVolumeReplicationClass(logger, instance.Spec.VolumeReplicationClass) if err != nil { - setFailureCondition(instance) + setFailureCondition(instance, "failed to get volumeReplication class", err.Error()) uErr := r.updateReplicationStatus(instance, logger, getCurrentReplicationState(instance), err.Error()) if uErr != nil { logger.Error(uErr, "failed to update volumeReplication status", "VRName", instance.Name) @@ -124,7 +124,7 @@ func (r *VolumeReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Re err = validatePrefixedParameters(vrcObj.Spec.Parameters) if err != nil { logger.Error(err, "failed to validate parameters of volumeReplicationClass", "VRCName", instance.Spec.VolumeReplicationClass) - setFailureCondition(instance) + setFailureCondition(instance, "failed to validate parameters of volumeReplicationClass", err.Error()) uErr := r.updateReplicationStatus(instance, logger, getCurrentReplicationState(instance), err.Error()) if uErr != nil { logger.Error(uErr, "failed to update volumeReplication status", "VRName", instance.Name) @@ -160,7 +160,7 @@ func (r *VolumeReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Re pvc, pv, pvErr = r.getPVCDataSource(logger, nameSpacedName) if pvErr != nil { logger.Error(pvErr, "failed to get PVC", "PVCName", instance.Spec.DataSource.Name) - setFailureCondition(instance) + setFailureCondition(instance, "failed to get PVC", pvErr.Error()) uErr := r.updateReplicationStatus(instance, logger, getCurrentReplicationState(instance), pvErr.Error()) if uErr != nil { logger.Error(uErr, "failed to update volumeReplication status", "VRName", instance.Name) @@ -175,7 +175,7 @@ func (r *VolumeReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Re vgr, vgrc, vgrErr = r.getVolumeGroupReplicationDataSource(logger, nameSpacedName) if vgrErr != nil { logger.Error(vgrErr, "failed to get VolumeGroupReplication", "VGRName", instance.Spec.DataSource.Name) - setFailureCondition(instance) + setFailureCondition(instance, "failed to get VolumeGroupReplication", vgrErr.Error()) uErr := r.updateReplicationStatus(instance, logger, getCurrentReplicationState(instance), vgrErr.Error()) if uErr != nil { logger.Error(uErr, "failed to update volumeReplication status", "VRName", instance.Name) @@ -187,7 +187,7 @@ func (r *VolumeReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Re default: err = fmt.Errorf("unsupported datasource kind") logger.Error(err, "given kind not supported", "Kind", instance.Spec.DataSource.Kind) - setFailureCondition(instance) + setFailureCondition(instance, "unsupported datasource", err.Error()) uErr := r.updateReplicationStatus(instance, logger, getCurrentReplicationState(instance), err.Error()) if uErr != nil { logger.Error(uErr, "failed to update volumeReplication status", "VRName", instance.Name) @@ -371,7 +371,7 @@ func (r *VolumeReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Re default: replicationErr = fmt.Errorf("unsupported volume state") logger.Error(replicationErr, "given volume state is not supported", "ReplicationState", instance.Spec.ReplicationState) - setFailureCondition(instance) + setFailureCondition(instance, "unsupported volume state", replicationErr.Error()) err = r.updateReplicationStatus(instance, logger, getCurrentReplicationState(instance), replicationErr.Error()) if err != nil { logger.Error(err, "failed to update volumeReplication status", "VRName", instance.Name) @@ -632,7 +632,7 @@ func (r *VolumeReplicationReconciler) markVolumeAsPrimary(vr *volumeReplicationI if !isKnownError { if resp.Error != nil { vr.logger.Error(resp.Error, "failed to promote volume") - setFailedPromotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation) + setFailedPromotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation, "failed to promote volume", resp.Error.Error()) return resp.Error } @@ -643,7 +643,7 @@ func (r *VolumeReplicationReconciler) markVolumeAsPrimary(vr *volumeReplicationI resp := volumeReplication.Promote() if resp.Error != nil { vr.logger.Error(resp.Error, "failed to force promote volume") - setFailedPromotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation) + setFailedPromotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation, "failed to force promote volume", resp.Error.Error()) return resp.Error } @@ -665,7 +665,7 @@ func (r *VolumeReplicationReconciler) markVolumeAsSecondary(vr *volumeReplicatio if resp.Error != nil { vr.logger.Error(resp.Error, "failed to demote volume") - setFailedDemotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation) + setFailedDemotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation, "failed to demote volume", resp.Error.Error()) return resp.Error } @@ -686,7 +686,7 @@ func (r *VolumeReplicationReconciler) resyncVolume(vr *volumeReplicationInstance if resp.Error != nil { vr.logger.Error(resp.Error, "failed to resync volume") - setFailedResyncCondition(&vr.instance.Status.Conditions, vr.instance.Generation) + setFailedResyncCondition(&vr.instance.Status.Conditions, vr.instance.Generation, "failed to resync volume", resp.Error.Error()) return false, resp.Error } @@ -694,7 +694,7 @@ func (r *VolumeReplicationReconciler) resyncVolume(vr *volumeReplicationInstance if !ok { err := fmt.Errorf("received response of unexpected type") vr.logger.Error(err, "unable to parse response") - setFailedResyncCondition(&vr.instance.Status.Conditions, vr.instance.Generation) + setFailedResyncCondition(&vr.instance.Status.Conditions, vr.instance.Generation, "unable to parse resync response", "received response of unexpected type") return false, err } @@ -750,7 +750,7 @@ func (r *VolumeReplicationReconciler) enableReplication(vr *volumeReplicationIns if resp.HasKnownGRPCError(enableReplicationKnownErrors) { setFailedValidationCondition(&vr.instance.Status.Conditions, vr.instance.Generation) } else { - setFailedPromotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation) + setFailedPromotionCondition(&vr.instance.Status.Conditions, vr.instance.Generation, "failed to enable volume replication", resp.Error.Error()) } return resp.Error @@ -805,14 +805,14 @@ func getCurrentReplicationState(instance *replicationv1alpha1.VolumeReplication) return instance.Status.State } -func setFailureCondition(instance *replicationv1alpha1.VolumeReplication) { +func setFailureCondition(instance *replicationv1alpha1.VolumeReplication, errMessage string, errFromCephCSI string) { switch instance.Spec.ReplicationState { case replicationv1alpha1.Primary: - setFailedPromotionCondition(&instance.Status.Conditions, instance.Generation) + setFailedPromotionCondition(&instance.Status.Conditions, instance.Generation, errMessage, errFromCephCSI) case replicationv1alpha1.Secondary: - setFailedDemotionCondition(&instance.Status.Conditions, instance.Generation) + setFailedDemotionCondition(&instance.Status.Conditions, instance.Generation, errMessage, errFromCephCSI) case replicationv1alpha1.Resync: - setFailedResyncCondition(&instance.Status.Conditions, instance.Generation) + setFailedResyncCondition(&instance.Status.Conditions, instance.Generation, errMessage, errFromCephCSI) } }