@@ -110,21 +110,22 @@ func (t *Translator) ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways
110110 return relevantGRPCRoutes
111111}
112112
113+ // gatewayAcceptedMsg returns the message embedding the Gateway's generation
114+ // so that a gateway-only update changes the message text and breaks the watchable DeepEqual gate
115+ // observedGeneration stays as the route's own generation to remain spec-compliant.
116+ func (t * Translator ) gatewayMsg (gw * GatewayContext , base string ) string {
117+ if gw != nil && gw .GetGeneration () > 0 {
118+ return fmt .Sprintf ("%s (gateway generation: %d)" , base , gw .GetGeneration ())
119+ }
120+ return base
121+ }
122+
113123func (t * Translator ) processHTTPRouteParentRefs (httpRoute * HTTPRouteContext , resources * resource.Resources , xdsIR resource.XdsIRMap ) {
114124 for _ , parentRef := range httpRoute .ParentRefs {
115125 // Need to compute Route rules within the parentRef loop because
116126 // any conditions that come out of it have to go on each RouteParentStatus,
117127 // not on the Route as a whole.
118128 routeRoutes , errs , unacceptedRules := t .processHTTPRouteRules (httpRoute , parentRef , resources )
119-
120- // For gateway-driven conditions, use the Gateway's generation as observedGeneration
121- // Gateway-only edit produces a condition value that differs
122- // from the stale stored one, unblocking the watchable DeepEqual gate.
123- observedGeneration := httpRoute .GetGeneration ()
124- if gw := parentRef .GetGateway (); gw != nil && gw .GetGeneration () > 0 {
125- observedGeneration = gw .GetGeneration ()
126- }
127-
128129 if len (errs ) > 0 {
129130 routeStatus := GetRouteStatus (httpRoute )
130131 // errs are already grouped by condition type in TypedErrorCollector
@@ -195,11 +196,11 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res
195196 routeStatus := GetRouteStatus (httpRoute )
196197 status .SetRouteStatusCondition (routeStatus ,
197198 parentRef .routeParentStatusIdx ,
198- observedGeneration ,
199+ httpRoute . GetGeneration () ,
199200 gwapiv1 .RouteConditionAccepted ,
200201 metav1 .ConditionFalse ,
201202 gwapiv1 .RouteReasonNoMatchingListenerHostname ,
202- "There were no hostname intersections between the HTTPRoute and this parent ref's Listener(s)." ,
203+ t . gatewayMsg ( parentRef . GetGateway (), "There were no hostname intersections between the HTTPRoute and this parent ref's Listener(s)." ) ,
203204 )
204205 }
205206
@@ -214,11 +215,11 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res
214215 routeStatus := GetRouteStatus (httpRoute )
215216 status .SetRouteStatusCondition (routeStatus ,
216217 parentRef .routeParentStatusIdx ,
217- observedGeneration ,
218+ httpRoute . GetGeneration () ,
218219 gwapiv1 .RouteConditionAccepted ,
219220 metav1 .ConditionTrue ,
220221 gwapiv1 .RouteReasonAccepted ,
221- "Route is accepted" ,
222+ t . gatewayMsg ( parentRef . GetGateway (), "Route is accepted" ) ,
222223 )
223224 }
224225 }
@@ -855,15 +856,6 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res
855856 // any conditions that come out of it have to go on each RouteParentStatus,
856857 // not on the Route as a whole.
857858 routeRoutes , errs , unacceptedRules := t .processGRPCRouteRules (grpcRoute , parentRef , resources )
858-
859- // For gateway-driven conditions, use the Gateway's generation as observedGeneration
860- // Gateway-only edit produces a condition value that differs
861- // from the stale stored one, unblocking the watchable DeepEqual gate.
862- observedGeneration := grpcRoute .GetGeneration ()
863- if gw := parentRef .GetGateway (); gw != nil && gw .GetGeneration () > 0 {
864- observedGeneration = gw .GetGeneration ()
865- }
866-
867859 if len (errs ) > 0 {
868860 routeStatus := GetRouteStatus (grpcRoute )
869861 // errs are already grouped by condition type in TypedErrorCollector
@@ -938,11 +930,11 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res
938930 routeStatus := GetRouteStatus (grpcRoute )
939931 status .SetRouteStatusCondition (routeStatus ,
940932 parentRef .routeParentStatusIdx ,
941- observedGeneration ,
933+ grpcRoute . GetGeneration () ,
942934 gwapiv1 .RouteConditionAccepted ,
943935 metav1 .ConditionFalse ,
944936 gwapiv1 .RouteReasonNoMatchingListenerHostname ,
945- "There were no hostname intersections between the GRPCRoute and this parent ref's Listener(s)." ,
937+ t . gatewayMsg ( parentRef . GetGateway (), "There were no hostname intersections between the GRPCRoute and this parent ref's Listener(s)." ) ,
946938 )
947939 }
948940
@@ -952,11 +944,11 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res
952944 routeStatus := GetRouteStatus (grpcRoute )
953945 status .SetRouteStatusCondition (routeStatus ,
954946 parentRef .routeParentStatusIdx ,
955- observedGeneration ,
947+ grpcRoute . GetGeneration () ,
956948 gwapiv1 .RouteConditionAccepted ,
957949 metav1 .ConditionTrue ,
958950 gwapiv1 .RouteReasonAccepted ,
959- "Route is accepted" ,
951+ t . gatewayMsg ( parentRef . GetGateway (), "Route is accepted" ) ,
960952 )
961953 }
962954
@@ -1413,14 +1405,6 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
14131405 destName = irRouteDestinationName (tlsRoute , - 1 /*rule index*/ )
14141406 )
14151407
1416- // For gateway-driven conditions, use the Gateway's generation as observedGeneration
1417- // Gateway-only edit produces a condition value that differs
1418- // from the stale stored one, unblocking the watchable DeepEqual gate.
1419- observedGeneration := tlsRoute .GetGeneration ()
1420- if gw := parentRef .GetGateway (); gw != nil && gw .GetGeneration () > 0 {
1421- observedGeneration = gw .GetGeneration ()
1422- }
1423-
14241408 // compute backends
14251409 for _ , rule := range tlsRoute .Spec .Rules {
14261410 for i := range rule .BackendRefs {
@@ -1521,11 +1505,11 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
15211505 routeStatus := GetRouteStatus (tlsRoute )
15221506 status .SetRouteStatusCondition (routeStatus ,
15231507 parentRef .routeParentStatusIdx ,
1524- observedGeneration ,
1508+ tlsRoute . GetGeneration () ,
15251509 gwapiv1 .RouteConditionAccepted ,
15261510 metav1 .ConditionFalse ,
15271511 gwapiv1 .RouteReasonNoMatchingListenerHostname ,
1528- "There were no hostname intersections between the TLSRoute and this parent ref's Listener(s)." ,
1512+ t . gatewayMsg ( parentRef . GetGateway (), "There were no hostname intersections between the TLSRoute and this parent ref's Listener(s)." ) ,
15291513 )
15301514 }
15311515
@@ -1540,11 +1524,11 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
15401524 routeStatus := GetRouteStatus (tlsRoute )
15411525 status .SetRouteStatusCondition (routeStatus ,
15421526 parentRef .routeParentStatusIdx ,
1543- observedGeneration ,
1527+ tlsRoute . GetGeneration () ,
15441528 gwapiv1 .RouteConditionAccepted ,
15451529 metav1 .ConditionTrue ,
15461530 gwapiv1 .RouteReasonAccepted ,
1547- "Route is accepted" ,
1531+ t . gatewayMsg ( parentRef . GetGateway (), "Route is accepted" ) ,
15481532 )
15491533 }
15501534 }
@@ -1604,14 +1588,6 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour
16041588 destName = irRouteDestinationName (udpRoute , - 1 /*rule index*/ )
16051589 )
16061590
1607- // For gateway-driven conditions, use the Gateway's generation as observedGeneration
1608- // Gateway-only edit produces a condition value that differs
1609- // from the stale stored one, unblocking the watchable DeepEqual gate.
1610- observedGeneration := udpRoute .GetGeneration ()
1611- if gw := parentRef .GetGateway (); gw != nil && gw .GetGeneration () > 0 {
1612- observedGeneration = gw .GetGeneration ()
1613- }
1614-
16151591 for i := range udpRoute .Spec .Rules [0 ].BackendRefs {
16161592 settingName := irDestinationSettingName (destName , i )
16171593 backendRefCtx := DirectBackendRef {BackendRef : & udpRoute .Spec .Rules [0 ].BackendRefs [i ]}
@@ -1689,23 +1665,23 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour
16891665 routeStatus := GetRouteStatus (udpRoute )
16901666 status .SetRouteStatusCondition (routeStatus ,
16911667 parentRef .routeParentStatusIdx ,
1692- observedGeneration ,
1668+ udpRoute . GetGeneration () ,
16931669 gwapiv1 .RouteConditionAccepted ,
16941670 metav1 .ConditionTrue ,
16951671 gwapiv1 .RouteReasonAccepted ,
1696- "Route is accepted" ,
1672+ t . gatewayMsg ( parentRef . GetGateway (), "Route is accepted" ) ,
16971673 )
16981674 }
16991675
17001676 if ! accepted {
17011677 routeStatus := GetRouteStatus (udpRoute )
17021678 status .SetRouteStatusCondition (routeStatus ,
17031679 parentRef .routeParentStatusIdx ,
1704- observedGeneration ,
1680+ udpRoute . GetGeneration () ,
17051681 gwapiv1 .RouteConditionAccepted ,
17061682 metav1 .ConditionFalse ,
17071683 gwapiv1 .RouteReasonUnsupportedValue ,
1708- "Multiple routes on the same UDP listener" ,
1684+ t . gatewayMsg ( parentRef . GetGateway (), "Multiple routes on the same UDP listener" ) ,
17091685 )
17101686 }
17111687 }
@@ -1765,14 +1741,6 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
17651741 destName = irRouteDestinationName (tcpRoute , - 1 /*rule index*/ )
17661742 )
17671743
1768- // For gateway-driven conditions, use the Gateway's generation as observedGeneration
1769- // Gateway-only edit produces a condition value that differs
1770- // from the stale stored one, unblocking the watchable DeepEqual gate.
1771- observedGeneration := tcpRoute .GetGeneration ()
1772- if gw := parentRef .GetGateway (); gw != nil && gw .GetGeneration () > 0 {
1773- observedGeneration = gw .GetGeneration ()
1774- }
1775-
17761744 for i := range tcpRoute .Spec .Rules [0 ].BackendRefs {
17771745 settingName := irDestinationSettingName (destName , i )
17781746 backendRefCtx := DirectBackendRef {BackendRef : & tcpRoute .Spec .Rules [0 ].BackendRefs [i ]}
@@ -1859,22 +1827,22 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
18591827 routeStatus := GetRouteStatus (tcpRoute )
18601828 status .SetRouteStatusCondition (routeStatus ,
18611829 parentRef .routeParentStatusIdx ,
1862- observedGeneration ,
1830+ tcpRoute . GetGeneration () ,
18631831 gwapiv1 .RouteConditionAccepted ,
18641832 metav1 .ConditionTrue ,
18651833 gwapiv1 .RouteReasonAccepted ,
1866- "Route is accepted" ,
1834+ t . gatewayMsg ( parentRef . GetGateway (), "Route is accepted" ) ,
18671835 )
18681836 }
18691837 if ! accepted {
18701838 routeStatus := GetRouteStatus (tcpRoute )
18711839 status .SetRouteStatusCondition (routeStatus ,
18721840 parentRef .routeParentStatusIdx ,
1873- observedGeneration ,
1841+ tcpRoute . GetGeneration () ,
18741842 gwapiv1 .RouteConditionAccepted ,
18751843 metav1 .ConditionFalse ,
18761844 gwapiv1 .RouteReasonUnsupportedValue ,
1877- "Multiple routes on the same TCP listener" ,
1845+ t . gatewayMsg ( parentRef . GetGateway (), "Multiple routes on the same TCP listener" ) ,
18781846 )
18791847 }
18801848
@@ -2310,7 +2278,7 @@ func (t *Translator) processAllowedListenersForParentRefs(
23102278 var relevantRoute bool
23112279 ns := gwapiv1 .Namespace (routeContext .GetNamespace ())
23122280 for _ , parentRef := range GetParentReferences (routeContext ) {
2313- isRelevantParentRef , matchedGateway , selectedListeners := GetReferencedListeners (ns , parentRef , gateways )
2281+ isRelevantParentRef , selectedListeners := GetReferencedListeners (ns , parentRef , gateways )
23142282
23152283 // Parent ref is not to a Gateway that we control: skip it
23162284 if ! isRelevantParentRef {
@@ -2322,23 +2290,15 @@ func (t *Translator) processAllowedListenersForParentRefs(
23222290 // Reset conditions since they will be recomputed during translation
23232291 parentRefCtx .ResetConditions (routeContext )
23242292
2325- // For gateway-driven conditions, use the Gateway's generation as observedGeneration
2326- // Gateway-only edit produces a condition value that differs
2327- // from the stale stored one, unblocking the watchable DeepEqual gate.
2328- observedGeneration := routeContext .GetGeneration ()
2329- if matchedGateway != nil && matchedGateway .GetGeneration () > 0 {
2330- observedGeneration = matchedGateway .GetGeneration ()
2331- }
2332-
23332293 if len (selectedListeners ) == 0 {
23342294 routeStatus := GetRouteStatus (routeContext )
23352295 status .SetRouteStatusCondition (routeStatus ,
23362296 parentRefCtx .routeParentStatusIdx ,
2337- observedGeneration ,
2297+ routeContext . GetGeneration () ,
23382298 gwapiv1 .RouteConditionAccepted ,
23392299 metav1 .ConditionFalse ,
23402300 gwapiv1 .RouteReasonNoMatchingParent ,
2341- "No listeners match this parent ref" ,
2301+ t . gatewayMsg ( parentRefCtx . GetGateway (), "No listeners match this parent ref" ) ,
23422302 )
23432303 continue
23442304 }
@@ -2352,28 +2312,46 @@ func (t *Translator) processAllowedListenersForParentRefs(
23522312 }
23532313 }
23542314
2315+ var selectedGateway * GatewayContext
2316+ if len (selectedListeners ) > 0 {
2317+ selectedGateway = selectedListeners [0 ].gateway
2318+ }
2319+
23552320 if len (allowedListeners ) == 0 {
23562321 routeStatus := GetRouteStatus (routeContext )
23572322 status .SetRouteStatusCondition (routeStatus ,
23582323 parentRefCtx .routeParentStatusIdx ,
2359- observedGeneration ,
2324+ routeContext . GetGeneration () ,
23602325 gwapiv1 .RouteConditionAccepted ,
23612326 metav1 .ConditionFalse ,
23622327 gwapiv1 .RouteReasonNotAllowedByListeners ,
2363- "No listeners included by this parent ref allowed this attachment." ,
2328+ t . gatewayMsg ( selectedGateway , "No listeners included by this parent ref allowed this attachment." ) ,
23642329 )
23652330 continue
23662331 }
23672332 parentRefCtx .SetListeners (allowedListeners ... )
23682333
2334+ if ! HasReadyListener (selectedListeners ) {
2335+ routeStatus := GetRouteStatus (routeContext )
2336+ status .SetRouteStatusCondition (routeStatus ,
2337+ parentRefCtx .routeParentStatusIdx ,
2338+ routeContext .GetGeneration (),
2339+ gwapiv1 .RouteConditionAccepted ,
2340+ metav1 .ConditionFalse ,
2341+ "NoReadyListeners" ,
2342+ t .gatewayMsg (parentRefCtx .GetGateway (), "There are no ready listeners for this parent ref" ),
2343+ )
2344+ continue
2345+ }
2346+
23692347 routeStatus := GetRouteStatus (routeContext )
23702348 status .SetRouteStatusCondition (routeStatus ,
23712349 parentRefCtx .routeParentStatusIdx ,
2372- observedGeneration ,
2350+ routeContext . GetGeneration () ,
23732351 gwapiv1 .RouteConditionAccepted ,
23742352 metav1 .ConditionTrue ,
23752353 gwapiv1 .RouteReasonAccepted ,
2376- "Route is accepted" ,
2354+ t . gatewayMsg ( parentRefCtx . GetGateway (), "Route is accepted" ) ,
23772355 )
23782356 }
23792357 return relevantRoute
0 commit comments