Skip to content

Commit c4fbdc0

Browse files
authored
Reset status conditions in GatewayAPI translator (#516)
* Reset status conditions in GatewayAPI translator * reset the conditions field within the listeners field (Gateway status) and the the parents field (HTTPRoute Status) before further setting any newer conditions so older conditons that are no longer true can be reset. * Enhance the status updater to merge the listener and parents conditions so existing older conditions that are same as the newer ones (except the LastTransitionTime field) can be retained and writes to the API Server can be mitigated Fixes: #415 Signed-off-by: Arko Dasgupta <[email protected]> * test Signed-off-by: Arko Dasgupta <[email protected]> * use reflect.DeepEqual Signed-off-by: Arko Dasgupta <[email protected]> * rm merge logic and rely on cmp status Signed-off-by: Arko Dasgupta <[email protected]> Signed-off-by: Arko Dasgupta <[email protected]>
1 parent 3ec7db1 commit c4fbdc0

File tree

5 files changed

+23
-44
lines changed

5 files changed

+23
-44
lines changed

internal/gatewayapi/contexts.go

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,6 @@ type GatewayContext struct {
2020
listeners map[v1beta1.SectionName]*ListenerContext
2121
}
2222

23-
func (g *GatewayContext) SetCondition(conditionType v1beta1.GatewayConditionType, status metav1.ConditionStatus, reason v1beta1.GatewayConditionReason, message string) {
24-
cond := metav1.Condition{
25-
Type: string(conditionType),
26-
Status: status,
27-
Reason: string(reason),
28-
Message: message,
29-
ObservedGeneration: g.Generation,
30-
LastTransitionTime: metav1.NewTime(time.Now()),
31-
}
32-
33-
idx := -1
34-
for i, existing := range g.Status.Conditions {
35-
if existing.Type == cond.Type {
36-
// return early if the condition is unchanged
37-
if existing.Status == cond.Status &&
38-
existing.Reason == cond.Reason &&
39-
existing.Message == cond.Message {
40-
return
41-
}
42-
idx = i
43-
break
44-
}
45-
}
46-
47-
if idx > -1 {
48-
g.Status.Conditions[idx] = cond
49-
} else {
50-
g.Status.Conditions = append(g.Status.Conditions, cond)
51-
}
52-
}
53-
5423
func (g *GatewayContext) GetListenerContext(listenerName v1beta1.SectionName) *ListenerContext {
5524
if g.listeners == nil {
5625
g.listeners = make(map[v1beta1.SectionName]*ListenerContext)
@@ -135,6 +104,10 @@ func (l *ListenerContext) SetCondition(conditionType v1beta1.ListenerConditionTy
135104
}
136105
}
137106

107+
func (l *ListenerContext) ResetConditions() {
108+
l.gateway.Status.Listeners[l.listenerStatusIdx].Conditions = make([]metav1.Condition, 0)
109+
}
110+
138111
func (l *ListenerContext) SetSupportedKinds(kinds ...v1beta1.RouteGroupKind) {
139112
l.gateway.Status.Listeners[l.listenerStatusIdx].SupportedKinds = kinds
140113
}
@@ -213,7 +186,7 @@ func (h *HTTPRouteContext) GetRouteParentContext(forParentRef v1beta1.ParentRefe
213186

214187
var parentRef *v1beta1.ParentReference
215188
for i, p := range h.Spec.ParentRefs {
216-
if p == forParentRef {
189+
if reflect.DeepEqual(p, forParentRef) {
217190
parentRef = &h.Spec.ParentRefs[i]
218191
break
219192
}
@@ -295,6 +268,10 @@ func (r *RouteParentContext) SetCondition(conditionType v1beta1.RouteConditionTy
295268
}
296269
}
297270

271+
func (r *RouteParentContext) ResetConditions() {
272+
r.route.Status.Parents[r.routeParentStatusIdx].Conditions = make([]metav1.Condition, 0)
273+
}
274+
298275
func (r *RouteParentContext) IsAccepted() bool {
299276
for _, cond := range r.route.Status.Parents[r.routeParentStatusIdx].Conditions {
300277
if cond.Type == string(v1beta1.RouteConditionAccepted) && cond.Status == metav1.ConditionTrue {

internal/gatewayapi/contexts_test.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,6 @@ func TestContexts(t *testing.T) {
2727
Gateway: gateway,
2828
}
2929

30-
gctx.SetCondition(v1beta1.GatewayConditionReady, metav1.ConditionTrue, v1beta1.GatewayReasonReady, "Gateway is ready")
31-
32-
require.Len(t, gateway.Status.Conditions, 1)
33-
require.EqualValues(t, gateway.Status.Conditions[0].Type, v1beta1.GatewayConditionReady)
34-
require.EqualValues(t, gateway.Status.Conditions[0].Status, metav1.ConditionTrue)
35-
require.EqualValues(t, gateway.Status.Conditions[0].Reason, v1beta1.GatewayReasonReady)
36-
require.EqualValues(t, gateway.Status.Conditions[0].Message, "Gateway is ready")
37-
3830
lctx := gctx.GetListenerContext("http")
3931
require.NotNil(t, lctx)
4032

@@ -53,4 +45,7 @@ func TestContexts(t *testing.T) {
5345
require.Len(t, gateway.Status.Listeners, 1)
5446
require.Len(t, gateway.Status.Listeners[0].SupportedKinds, 1)
5547
require.EqualValues(t, gateway.Status.Listeners[0].SupportedKinds[0].Kind, "HTTPRoute")
48+
49+
lctx.ResetConditions()
50+
require.Len(t, gateway.Status.Listeners[0].Conditions, 0)
5651
}

internal/gatewayapi/translator.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ func (t *Translator) GetRelevantGateways(gateways []*v1beta1.Gateway) []*Gateway
144144

145145
for _, listener := range gateway.Spec.Listeners {
146146
l := gc.GetListenerContext(listener.Name)
147-
// Reset attached route count since it will be recomputed during translation.
147+
// Reset conditions and attached route count
148+
// since it will be recomputed during translation.
149+
l.ResetConditions()
148150
l.ResetAttachedRoutes()
149151
}
150152

@@ -637,6 +639,8 @@ func (t *Translator) ProcessHTTPRoutes(httpRoutes []*v1beta1.HTTPRoute, gateways
637639
relevantRoute = true
638640

639641
parentRefCtx := httpRoute.GetRouteParentContext(parentRef)
642+
// Reset conditions since they will be recomputed during translation
643+
parentRefCtx.ResetConditions()
640644

641645
if !HasReadyListener(selectedListeners) {
642646
parentRefCtx.SetCondition(v1beta1.RouteConditionAccepted, metav1.ConditionFalse, "NoReadyListeners", "There are no ready listeners for this parent ref")

internal/provider/kubernetes/httproute.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,13 @@ func (r *httpRouteReconciler) subscribeAndUpdateStatus(ctx context.Context) {
331331
NamespacedName: key,
332332
Resource: new(gwapiv1b1.HTTPRoute),
333333
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
334-
if _, ok := obj.(*gwapiv1b1.HTTPRoute); !ok {
334+
h, ok := obj.(*gwapiv1b1.HTTPRoute)
335+
if !ok {
335336
panic(fmt.Sprintf("unsupported object type %T", obj))
336337
}
337-
return val
338+
hCopy := h.DeepCopy()
339+
hCopy.Status.Parents = val.Status.Parents
340+
return hCopy
338341
}),
339342
})
340343
}

internal/status/status.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func (u *UpdateWriter) Send(update Update) {
144144
// Gateway
145145
// HTTPRoute
146146
func isStatusEqual(objA, objB interface{}) bool {
147-
opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")
147+
opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime", "ObservedGeneration")
148148
switch a := objA.(type) {
149149
case *gwapiv1b1.GatewayClass:
150150
if b, ok := objB.(*gwapiv1b1.GatewayClass); ok {

0 commit comments

Comments
 (0)