diff --git a/internal/provisioner/controller/gatewayclass.go b/internal/provisioner/controller/gatewayclass.go index fa511d9a0c9..189ef560853 100644 --- a/internal/provisioner/controller/gatewayclass.go +++ b/internal/provisioner/controller/gatewayclass.go @@ -246,11 +246,22 @@ func (r *gatewayClassReconciler) setAcceptedCondition( reason gatewayapi_v1beta1.GatewayClassConditionReason, message string, ) error { + currentAcceptedCondition := metav1.Condition{ + Type: string(gatewayapi_v1beta1.GatewayClassConditionStatusAccepted), + Status: status, + ObservedGeneration: gatewayClass.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(reason), + Message: message, + } var newConds []metav1.Condition for _, cond := range gatewayClass.Status.Conditions { if cond.Type == string(gatewayapi_v1beta1.GatewayClassConditionStatusAccepted) { if cond.Status == status { - return nil + // If status hasn't changed, don't change the condition, just + // update the generation. + currentAcceptedCondition = cond + currentAcceptedCondition.ObservedGeneration = gatewayClass.Generation } continue @@ -262,14 +273,7 @@ func (r *gatewayClassReconciler) setAcceptedCondition( r.log.WithValues("gatewayclass-name", gatewayClass.Name).Info(fmt.Sprintf("setting gateway class's Accepted condition to %s", status)) // nolint:gocritic - gatewayClass.Status.Conditions = append(newConds, metav1.Condition{ - Type: string(gatewayapi_v1beta1.GatewayClassConditionStatusAccepted), - Status: status, - ObservedGeneration: gatewayClass.Generation, - LastTransitionTime: metav1.Now(), - Reason: string(reason), - Message: message, - }) + gatewayClass.Status.Conditions = append(newConds, currentAcceptedCondition) if err := r.client.Status().Update(ctx, gatewayClass); err != nil { return fmt.Errorf("failed to set gatewayclass %s accepted condition: %w", gatewayClass.Name, err) diff --git a/internal/provisioner/controller/gatewayclass_test.go b/internal/provisioner/controller/gatewayclass_test.go index f6e515bd20a..383951a5481 100644 --- a/internal/provisioner/controller/gatewayclass_test.go +++ b/internal/provisioner/controller/gatewayclass_test.go @@ -384,6 +384,31 @@ func TestGatewayClassReconcile(t *testing.T) { Reason: string(gatewayv1beta1.GatewayClassReasonInvalidParameters), }, }, + "gatewayclass with status from previous generation is updated": { + gatewayClass: &gatewayv1beta1.GatewayClass{ + ObjectMeta: metav1.ObjectMeta{ + Name: "gatewayclass-1", + Generation: 2, + }, + Spec: gatewayv1beta1.GatewayClassSpec{ + ControllerName: "projectcontour.io/gateway-controller", + }, + Status: gatewayv1beta1.GatewayClassStatus{ + Conditions: []metav1.Condition{{ + Type: string(gatewayv1beta1.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionTrue, + Reason: string(gatewayv1beta1.GatewayClassReasonAccepted), + ObservedGeneration: 1, + }}, + }, + }, + wantCondition: &metav1.Condition{ + Type: string(gatewayv1beta1.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionTrue, + Reason: string(gatewayv1beta1.GatewayClassReasonAccepted), + ObservedGeneration: 2, + }, + }, } for name, tc := range tests { @@ -424,6 +449,7 @@ func TestGatewayClassReconcile(t *testing.T) { assert.Equal(t, tc.wantCondition.Type, res.Status.Conditions[0].Type) assert.Equal(t, tc.wantCondition.Status, res.Status.Conditions[0].Status) assert.Equal(t, tc.wantCondition.Reason, res.Status.Conditions[0].Reason) + assert.Equal(t, tc.wantCondition.ObservedGeneration, res.Status.Conditions[0].ObservedGeneration) } if tc.assertions != nil {