From 4386d8ba945df56f463000f4ba23c9aad1ad561c Mon Sep 17 00:00:00 2001 From: David Winiarski Date: Mon, 31 Mar 2025 14:02:07 -0600 Subject: [PATCH] only consider accepted gateway routes if the condition generation matches the current one --- source/gateway.go | 10 +++--- source/gateway_test.go | 73 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/source/gateway.go b/source/gateway.go index 33ef3be3d..d901d7f16 100644 --- a/source/gateway.go +++ b/source/gateway.go @@ -293,7 +293,7 @@ func (c *gatewayRouteResolver) resolve(rt gatewayRoute) (map[string]endpoint.Tar return nil, err } hostTargets := make(map[string]endpoint.Targets) - + currentGeneration := rt.Metadata().Generation meta := rt.Metadata() for _, rps := range rt.RouteStatus().Parents { // Confirm the Parent is the standard Gateway kind. @@ -316,8 +316,8 @@ func (c *gatewayRouteResolver) resolve(rt gatewayRoute) (map[string]endpoint.Tar log.Debugf("Gateway %s/%s does not match %s %s/%s", namespace, ref.Name, c.src.gwName, meta.Namespace, meta.Name) continue } - // Confirm the Gateway has accepted the Route. - if !gwRouteIsAccepted(rps.Conditions) { + // Confirm the Gateway has accepted the Route, and that the generation matches. + if !gwRouteIsAccepted(rps.Conditions, currentGeneration) { log.Debugf("Gateway %s/%s has not accepted %s %s/%s", namespace, ref.Name, c.src.rtKind, meta.Namespace, meta.Name) continue } @@ -458,9 +458,9 @@ func (c *gatewayRouteResolver) routeIsAllowed(gw *v1beta1.Gateway, lis *v1.Liste return false } -func gwRouteIsAccepted(conds []metav1.Condition) bool { +func gwRouteIsAccepted(conds []metav1.Condition, currentGeneration int64) bool { for _, c := range conds { - if v1.RouteConditionType(c.Type) == v1.RouteConditionAccepted { + if v1.RouteConditionType(c.Type) == v1.RouteConditionAccepted && c.ObservedGeneration == currentGeneration { return c.Status == metav1.ConditionTrue } } diff --git a/source/gateway_test.go b/source/gateway_test.go index 940622e95..92e71a91f 100644 --- a/source/gateway_test.go +++ b/source/gateway_test.go @@ -20,6 +20,7 @@ import ( "strings" "testing" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "sigs.k8s.io/gateway-api/apis/v1" ) @@ -245,3 +246,75 @@ func TestIsDNS1123Domain(t *testing.T) { }) } } + +func TestGwRouteIsAccepted(t *testing.T) { + tests := []struct { + desc string + conditions []metav1.Condition + currentGeneration int64 + want bool + }{ + { + desc: "accepted condition with matching generation", + conditions: []metav1.Condition{ + { + Type: string(v1.RouteConditionAccepted), + Status: metav1.ConditionTrue, + ObservedGeneration: 1, + }, + }, + currentGeneration: 1, + want: true, + }, + { + desc: "accepted condition with different generation", + conditions: []metav1.Condition{ + { + Type: string(v1.RouteConditionAccepted), + Status: metav1.ConditionTrue, + ObservedGeneration: 1, + }, + }, + currentGeneration: 2, + want: false, + }, + { + desc: "accepted condition with false status", + conditions: []metav1.Condition{ + { + Type: string(v1.RouteConditionAccepted), + Status: metav1.ConditionFalse, + ObservedGeneration: 1, + }, + }, + currentGeneration: 1, + want: false, + }, + { + desc: "no accepted condition", + conditions: []metav1.Condition{ + { + Type: "OtherCondition", + Status: metav1.ConditionTrue, + ObservedGeneration: 1, + }, + }, + currentGeneration: 1, + want: false, + }, + { + desc: "empty conditions", + conditions: []metav1.Condition{}, + currentGeneration: 1, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + if got := gwRouteIsAccepted(tt.conditions, tt.currentGeneration); got != tt.want { + t.Errorf("gwRouteIsAccepted() = %v, want %v", got, tt.want) + } + }) + } +}