From 1650b2ef630525f403b348964b3149fdaf71d293 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 | 15 ++++++++ .../controller/replication.storage/status.go | 35 ++++++++++++++++--- .../volumereplication_controller.go | 34 +++++++++--------- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/api/replication.storage/v1alpha1/volumereplication_types.go b/api/replication.storage/v1alpha1/volumereplication_types.go index 0e777409b..781ee5d82 100644 --- a/api/replication.storage/v1alpha1/volumereplication_types.go +++ b/api/replication.storage/v1alpha1/volumereplication_types.go @@ -36,6 +36,21 @@ const ( ConditionValidated = "Validated" ) +// These are valid messages for various conditions and states of volume replication. +const ( + MessagePromoted = "volume is promoted to primary and replicating to secondary volume" + MessageHealthy = "volume is healthy" + MessageNotResyncing = "volume is not resyncing" + MessageValidated = "volume is validated and met all prerequisites" + MessageFailedPromoted = "failed to promote volume" + MessageFailedDemoted = "failed to demote volume" + MessageFailedPreCondition = "failed to meet prerequisite" + MessageDemoted = "volume is demoted to secondary" + MessageDegraded = "volume is degraded" + MessageResyncTriggered = "volume is resyncing changes from primary to secondary" + 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..c3fc92561 100644 --- a/internal/controller/replication.storage/status.go +++ b/internal/controller/replication.storage/status.go @@ -17,6 +17,7 @@ limitations under the License. package controller import ( + "fmt" "time" "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1" @@ -26,18 +27,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 +50,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, message, messageFromDriver string) { setStatusCondition(conditions, &metav1.Condition{ + Message: message, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToPromote, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: fmt.Sprintf("%s: %s", v1alpha1.MessageFailedPromoted, messageFromDriver), 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.MessageValidated, Type: v1alpha1.ConditionValidated, Reason: v1alpha1.PrerequisiteMet, ObservedGeneration: observedGeneration, @@ -74,26 +82,30 @@ func setFailedPromotionCondition(conditions *[]metav1.Condition, observedGenerat } // sets conditions when volume promotion was failed due to failed validation. -func setFailedValidationCondition(conditions *[]metav1.Condition, observedGeneration int64) { +func setFailedValidationCondition(conditions *[]metav1.Condition, observedGeneration int64, message, messageFromDriver string) { setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageFailedPromoted, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToPromote, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: message, 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: fmt.Sprintf("%s: %s", v1alpha1.MessageFailedPreCondition, messageFromDriver), Type: v1alpha1.ConditionValidated, Reason: v1alpha1.PrerequisiteNotMet, ObservedGeneration: observedGeneration, @@ -104,12 +116,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 +134,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 +157,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, message, messageFromDriver string) { setStatusCondition(conditions, &metav1.Condition{ + Message: message, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToDemote, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: fmt.Sprintf("%s: %s", v1alpha1.MessageFailedDemoted, messageFromDriver), 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, @@ -164,18 +184,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 +207,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, message, messageFromDriver string) { setStatusCondition(conditions, &metav1.Condition{ + Message: message, Type: v1alpha1.ConditionCompleted, Reason: v1alpha1.FailedToResync, ObservedGeneration: observedGeneration, Status: metav1.ConditionFalse, }) setStatusCondition(conditions, &metav1.Condition{ + Message: fmt.Sprintf("%s: %s", v1alpha1.MessageResyncFailed, messageFromDriver), Type: v1alpha1.ConditionDegraded, Reason: v1alpha1.Error, ObservedGeneration: observedGeneration, Status: metav1.ConditionTrue, }) setStatusCondition(conditions, &metav1.Condition{ + Message: v1alpha1.MessageResyncFailed, Type: v1alpha1.ConditionResyncing, Reason: v1alpha1.FailedToResync, ObservedGeneration: observedGeneration, @@ -223,6 +249,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..6f5cd6ea5 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 find 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 } @@ -748,9 +748,9 @@ func (r *VolumeReplicationReconciler) enableReplication(vr *volumeReplicationIns vr.logger.Error(resp.Error, "failed to enable volume replication") if resp.HasKnownGRPCError(enableReplicationKnownErrors) { - setFailedValidationCondition(&vr.instance.Status.Conditions, vr.instance.Generation) + setFailedValidationCondition(&vr.instance.Status.Conditions, vr.instance.Generation, "failed to enable volume replication", resp.Error.Error()) } 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) } }