diff --git a/internal/bridge/crunchybridgecluster/crunchybridgecluster_controller.go b/internal/bridge/crunchybridgecluster/crunchybridgecluster_controller.go index cb071f4858..bfd358fecc 100644 --- a/internal/bridge/crunchybridgecluster/crunchybridgecluster_controller.go +++ b/internal/bridge/crunchybridgecluster/crunchybridgecluster_controller.go @@ -265,12 +265,15 @@ func (r *CrunchyBridgeClusterReconciler) Reconcile(ctx context.Context, req ctrl return ctrl.Result{}, nil } - // Remove cluster invalid status if found - if invalid != nil && - invalid.Status == metav1.ConditionFalse && - invalid.Reason == "ClusterInvalid" { - meta.RemoveStatusCondition(&crunchybridgecluster.Status.Conditions, - v1beta1.ConditionCreating) + // check for an upgrade error and return until observedGeneration has + // been incremented by updating the CR with valid value(s). + invalidUpgrade := meta.FindStatusCondition(crunchybridgecluster.Status.Conditions, + v1beta1.ConditionUpgrading) + if invalidUpgrade != nil && + invalidUpgrade.Status == metav1.ConditionFalse && + invalidUpgrade.Reason == "UpgradeError" && + invalidUpgrade.ObservedGeneration == crunchybridgecluster.GetGeneration() { + return ctrl.Result{}, nil } // We should only be missing the ID if no create has been issued @@ -350,6 +353,14 @@ func (r *CrunchyBridgeClusterReconciler) Reconcile(ctx context.Context, req ctrl return ctrl.Result{}, nil } crunchybridgecluster.Status.ID = cluster.ID + + meta.SetStatusCondition(&crunchybridgecluster.Status.Conditions, metav1.Condition{ + ObservedGeneration: crunchybridgecluster.GetGeneration(), + Type: v1beta1.ConditionUpgrading, + Status: metav1.ConditionUnknown, + Reason: "UpgradeConditionUnknown", + Message: "The condition of the upgrade(s) is unknown.", + }) return ctrl.Result{RequeueAfter: 3 * time.Minute}, nil } @@ -381,7 +392,25 @@ func (r *CrunchyBridgeClusterReconciler) Reconcile(ctx context.Context, req ctrl return ctrl.Result{}, err } clusterUpgradeDetails.AddDataToClusterStatus(crunchybridgecluster) - // TODO: Update the ConditionUpdating status here + if len(clusterUpgradeDetails.Operations) != 0 { + meta.SetStatusCondition(&crunchybridgecluster.Status.Conditions, metav1.Condition{ + ObservedGeneration: crunchybridgecluster.GetGeneration(), + Type: v1beta1.ConditionUpgrading, + Status: metav1.ConditionTrue, + Reason: clusterUpgradeDetails.Operations[0].Flavor, + Message: fmt.Sprintf( + "Performing an upgrade of type %v with a state of %v.", + clusterUpgradeDetails.Operations[0].Flavor, clusterUpgradeDetails.Operations[0].State), + }) + } else { + meta.SetStatusCondition(&crunchybridgecluster.Status.Conditions, metav1.Condition{ + ObservedGeneration: crunchybridgecluster.GetGeneration(), + Type: v1beta1.ConditionUpgrading, + Status: metav1.ConditionFalse, + Reason: "NoUpgradesInProgress", + Message: "No upgrades being performed", + }) + } // Reconcile roles and their secrets err = r.reconcilePostgresRoles(ctx, key, crunchybridgecluster) @@ -479,11 +508,30 @@ func (r *CrunchyBridgeClusterReconciler) handleUpgrade(ctx context.Context, // TODO(crunchybridgecluster): consider what errors we might get // and what different results/requeue times we want to return. // Currently: don't requeue and wait for user to change spec. + meta.SetStatusCondition(&crunchybridgecluster.Status.Conditions, metav1.Condition{ + ObservedGeneration: crunchybridgecluster.GetGeneration(), + Type: v1beta1.ConditionUpgrading, + Status: metav1.ConditionFalse, + Reason: "UpgradeError", + Message: fmt.Sprintf( + "Error performing an upgrade: %s", err), + }) log.Error(err, "Error while attempting cluster upgrade") return ctrl.Result{}, nil } clusterUpgrade.AddDataToClusterStatus(crunchybridgecluster) + if len(clusterUpgrade.Operations) != 0 { + meta.SetStatusCondition(&crunchybridgecluster.Status.Conditions, metav1.Condition{ + ObservedGeneration: crunchybridgecluster.GetGeneration(), + Type: v1beta1.ConditionUpgrading, + Status: metav1.ConditionTrue, + Reason: clusterUpgrade.Operations[0].Flavor, + Message: fmt.Sprintf( + "Performing an upgrade of type %v with a state of %v.", + clusterUpgrade.Operations[0].Flavor, clusterUpgrade.Operations[0].State), + }) + } return ctrl.Result{RequeueAfter: 3 * time.Minute}, nil } @@ -507,11 +555,29 @@ func (r *CrunchyBridgeClusterReconciler) handleUpgradeHA(ctx context.Context, // TODO(crunchybridgecluster): consider what errors we might get // and what different results/requeue times we want to return. // Currently: don't requeue and wait for user to change spec. + meta.SetStatusCondition(&crunchybridgecluster.Status.Conditions, metav1.Condition{ + ObservedGeneration: crunchybridgecluster.GetGeneration(), + Type: v1beta1.ConditionUpgrading, + Status: metav1.ConditionFalse, + Reason: "UpgradeError", + Message: fmt.Sprintf( + "Error performing an HA upgrade: %s", err), + }) log.Error(err, "Error while attempting cluster HA change") return ctrl.Result{}, nil } clusterUpgrade.AddDataToClusterStatus(crunchybridgecluster) - + if len(clusterUpgrade.Operations) != 0 { + meta.SetStatusCondition(&crunchybridgecluster.Status.Conditions, metav1.Condition{ + ObservedGeneration: crunchybridgecluster.GetGeneration(), + Type: v1beta1.ConditionUpgrading, + Status: metav1.ConditionTrue, + Reason: clusterUpgrade.Operations[0].Flavor, + Message: fmt.Sprintf( + "Perfoming an upgrade of type %v with a state of %v.", + clusterUpgrade.Operations[0].Flavor, clusterUpgrade.Operations[0].State), + }) + } return ctrl.Result{RequeueAfter: 3 * time.Minute}, nil } diff --git a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/crunchy_bridgecluster_types.go b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/crunchy_bridgecluster_types.go index b710dcf58e..c72d648847 100644 --- a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/crunchy_bridgecluster_types.go +++ b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/crunchy_bridgecluster_types.go @@ -182,12 +182,12 @@ type UpgradeOperation struct { // TODO(crunchybridgecluster) Think through conditions // CrunchyBridgeClusterStatus condition types. const ( - ConditionUnknown = "" - ConditionPending = "Pending" - ConditionCreating = "Creating" - ConditionUpdating = "Updating" - ConditionReady = "Ready" - ConditionDeleting = "Deleting" + ConditionUnknown = "" + ConditionPending = "Pending" + ConditionCreating = "Creating" + ConditionUpgrading = "Upgrading" + ConditionReady = "Ready" + ConditionDeleting = "Deleting" ) // +kubebuilder:object:root=true