diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go index 4490f888d1a0..e73fe3722afa 100644 --- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go +++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go @@ -752,14 +752,7 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques // So consumers e.g. UI can categorize as good (True) / bad (False). if conditionType == hyperv1.ClusterVersionSucceeding { hcCVOCondition.Type = string(hyperv1.ClusterVersionSucceeding) - var status metav1.ConditionStatus - switch hcpCVOConditions[conditionType].Status { - case metav1.ConditionTrue: - status = metav1.ConditionFalse - case metav1.ConditionFalse: - status = metav1.ConditionTrue - } - hcCVOCondition.Status = status + hcCVOCondition.Status = invertConditionStatus(hcpCVOConditions[conditionType].Status) } } @@ -3318,6 +3311,17 @@ func reconcileCAPIManagerClusterRoleBinding(binding *rbacv1.ClusterRoleBinding, return nil } +func invertConditionStatus(s metav1.ConditionStatus) metav1.ConditionStatus { + switch s { + case metav1.ConditionTrue: + return metav1.ConditionFalse + case metav1.ConditionFalse: + return metav1.ConditionTrue + default: + return metav1.ConditionUnknown + } +} + // computeClusterVersionStatus determines the ClusterVersionStatus of the // given HostedCluster and returns it. func computeClusterVersionStatus(clock clock.WithTickerAndDelayedExecution, hcluster *hyperv1.HostedCluster, hcp *hyperv1.HostedControlPlane) *hyperv1.ClusterVersionStatus { diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go index 76c5b9538049..f4ce7ee8f84d 100644 --- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go +++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go @@ -3995,6 +3995,47 @@ func TestIsProgressing(t *testing.T) { } } +func TestInvertConditionStatus(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + input metav1.ConditionStatus + expectedStatus metav1.ConditionStatus + }{ + { + name: "When status is True it should invert to False", + input: metav1.ConditionTrue, + expectedStatus: metav1.ConditionFalse, + }, + { + name: "When status is False it should invert to True", + input: metav1.ConditionFalse, + expectedStatus: metav1.ConditionTrue, + }, + { + name: "When status is Unknown it should produce Unknown", + input: metav1.ConditionUnknown, + expectedStatus: metav1.ConditionUnknown, + }, + { + name: "When status is empty string it should produce Unknown", + input: metav1.ConditionStatus(""), + expectedStatus: metav1.ConditionUnknown, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + g := NewWithT(t) + result := invertConditionStatus(tc.input) + g.Expect(result).To(Equal(tc.expectedStatus)) + g.Expect(result).ToNot(BeEmpty(), "Status must not be empty string — API server rejects it") + }) + } +} + func TestComputeAWSDefaultSGDeletedCondition(t *testing.T) { t.Parallel() diff --git a/hypershift-operator/controllers/hostedcluster/reconcile_legacy.go b/hypershift-operator/controllers/hostedcluster/reconcile_legacy.go index 4b84a70b8dea..9e36c7d392a9 100644 --- a/hypershift-operator/controllers/hostedcluster/reconcile_legacy.go +++ b/hypershift-operator/controllers/hostedcluster/reconcile_legacy.go @@ -434,14 +434,7 @@ func (r *HostedClusterReconciler) reconcileLegacy(ctx context.Context, req ctrl. // So consumers e.g. UI can categorize as good (True) / bad (False). if conditionType == hyperv1.ClusterVersionSucceeding { hcCVOCondition.Type = string(hyperv1.ClusterVersionSucceeding) - var status metav1.ConditionStatus - switch hcpCVOConditions[conditionType].Status { - case metav1.ConditionTrue: - status = metav1.ConditionFalse - case metav1.ConditionFalse: - status = metav1.ConditionTrue - } - hcCVOCondition.Status = status + hcCVOCondition.Status = invertConditionStatus(hcpCVOConditions[conditionType].Status) } }