Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion internal/gatewayapi/contexts.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ func (l *ListenerContext) SetSupportedKinds(kinds ...gwapiv1.RouteGroupKind) {
}
}

// IncrementAttachedRoutes increments the number of attached routes for the listener in the status.
//
// xref: https://github.com/kubernetes-sigs/gateway-api/issues/2402
// Namely:
// - AttachedRoutes should be set on Listeners that are valid or invalid
// - The count of AttachedRoutes should include Routes that are valid or invalid
func (l *ListenerContext) IncrementAttachedRoutes() {
if l.isFromXListenerSet() {
l.xListenerSet.Status.Listeners[l.xListenerSetStatusIdx].AttachedRoutes++
Expand All @@ -155,7 +161,8 @@ func (l *ListenerContext) AllowsKind(kind gwapiv1.RouteGroupKind) bool {
}

for _, allowed := range supportedKinds {
if GroupDerefOr(allowed.Group, "") == GroupDerefOr(kind.Group, "") &&
// The default group is "gateway.networking.k8s.io"
if GroupDerefOr(allowed.Group, "gateway.networking.k8s.io") == GroupDerefOr(kind.Group, "gateway.networking.k8s.io") &&
allowed.Kind == kind.Kind {
return true
}
Expand Down
61 changes: 28 additions & 33 deletions internal/gatewayapi/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,6 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res
"Resolved all the Object references for the Route",
)
}

// Skip parent refs that did not accept the route
if parentRef.HasCondition(httpRoute, gwapiv1.RouteConditionAccepted, metav1.ConditionFalse) {
continue
}

hasHostnameIntersection := t.processHTTPRouteParentRefListener(httpRoute, routeRoutes, parentRef, xdsIR)
if !hasHostnameIntersection {
routeStatus := GetRouteStatus(httpRoute)
Expand All @@ -198,6 +192,11 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res
)
}

// Skip parent refs that did not accept the route
if parentRef.HasCondition(httpRoute, gwapiv1.RouteConditionAccepted, metav1.ConditionFalse) {
continue
}

// If no negative conditions have been set, the route is considered "Accepted=True".
if parentRef.HTTPRoute != nil &&
len(parentRef.HTTPRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 {
Expand All @@ -211,7 +210,6 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res
"Route is accepted",
)
}

}
}

Expand Down Expand Up @@ -1248,14 +1246,18 @@ func (t *Translator) processGRPCRouteMethodRegularExpression(method *gwapiv1.GRP
}

func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, routeRoutes []*ir.HTTPRoute, parentRef *RouteParentContext, xdsIR resource.XdsIRMap) bool {
var hasHostnameIntersection bool

// need to check hostname intersection if there are listeners
hasHostnameIntersection := len(parentRef.listeners) == 0
for _, listener := range parentRef.listeners {
hosts := computeHosts(GetHostnames(route), listener)
if len(hosts) == 0 {
continue
}
hasHostnameIntersection = true
listener.IncrementAttachedRoutes()
if !listener.IsReady() {
continue
}

var perHostRoutes []*ir.HTTPRoute
for _, host := range hosts {
Expand Down Expand Up @@ -1412,19 +1414,18 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
)
}

// Skip parent refs that did not accept the route
if parentRef.HasCondition(tlsRoute, gwapiv1.RouteConditionAccepted, metav1.ConditionFalse) {
continue
}

var hasHostnameIntersection bool
// need to check hostname intersection if there are listeners
hasHostnameIntersection := len(parentRef.listeners) == 0
for _, listener := range parentRef.listeners {
hosts := computeHosts(GetHostnames(tlsRoute), listener)
if len(hosts) == 0 {
continue
}

hasHostnameIntersection = true
listener.IncrementAttachedRoutes()
if !listener.IsReady() {
continue
}

irKey := t.getIRKey(listener.gateway.Gateway)
gwXdsIR := xdsIR[irKey]
Expand Down Expand Up @@ -1462,7 +1463,6 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
Metadata: buildResourceMetadata(tlsRoute, nil),
}
irListener.Routes = append(irListener.Routes, irRoute)

}
}

Expand All @@ -1478,6 +1478,11 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
)
}

// Skip parent refs that did not accept the route
if parentRef.HasCondition(tlsRoute, gwapiv1.RouteConditionAccepted, metav1.ConditionFalse) {
continue
}

// If no negative conditions have been set, the route is considered "Accepted=True".
if parentRef.TLSRoute != nil &&
len(parentRef.TLSRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 {
Expand Down Expand Up @@ -1591,9 +1596,10 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour
accepted := false
for _, listener := range parentRef.listeners {
// only one route is allowed for a UDP listener
if listener.AttachedRoutes() > 1 {
if listener.AttachedRoutes() >= 1 {
continue
}
listener.IncrementAttachedRoutes()
if !listener.IsReady() {
continue
}
Expand Down Expand Up @@ -1741,12 +1747,14 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
accepted := false
for _, listener := range parentRef.listeners {
// only one route is allowed for a TCP listener
if listener.AttachedRoutes() > 1 {
if listener.AttachedRoutes() >= 1 {
continue
}
if !listener.IsReady() {
continue
}
listener.IncrementAttachedRoutes()

accepted = true
irKey := t.getIRKey(listener.gateway.Gateway)

Expand Down Expand Up @@ -1774,9 +1782,7 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
}

irListener.Routes = append(irListener.Routes, irRoute)

}

}

// If no negative conditions have been set, the route is considered "Accepted=True".
Expand Down Expand Up @@ -2237,16 +2243,7 @@ func (t *Translator) processAllowedListenersForParentRefs(
)
continue
}

// Its safe to increment AttachedRoutes since we've found a valid parentRef
// and the listener allows this Route kind

// Theoretically there should only be one parent ref per
// Route that attaches to a given Listener, so fine to just increment here, but we
// might want to check to ensure we're not double-counting.
for _, listener := range allowedListeners {
listener.IncrementAttachedRoutes()
}
parentRefCtx.SetListeners(allowedListeners...)

if !HasReadyListener(selectedListeners) {
routeStatus := GetRouteStatus(routeContext)
Expand All @@ -2261,8 +2258,6 @@ func (t *Translator) processAllowedListenersForParentRefs(
continue
}

parentRefCtx.SetListeners(allowedListeners...)

routeStatus := GetRouteStatus(routeContext)
status.SetRouteStatusCondition(routeStatus,
parentRefCtx.routeParentStatusIdx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ gateways:
mode: Terminate
status:
listeners:
- attachedRoutes: 2
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
Expand Down Expand Up @@ -109,7 +109,7 @@ gateways:
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 2
- attachedRoutes: 1
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
Expand Down Expand Up @@ -139,7 +139,7 @@ gateways:
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 2
- attachedRoutes: 1
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,20 @@ xdsIR:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
routes:
- directResponse:
statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
kind: HTTPRoute
name: httproute-1
namespace: default
name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
name: ""
prefix: /
readyListener:
address: 0.0.0.0
ipFamily: IPv4
Expand Down
131 changes: 131 additions & 0 deletions internal/gatewayapi/testdata/gateway-with-attached-routes.in.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway-with-one-attached-route
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Same
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway-with-two-attached-routes
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
port: 80
protocol: HTTP
hostname: "foo.example.com"
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Same
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: unresolved-gateway-with-one-attached-unresolved-route
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: tls
port: 443
protocol: HTTPS
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Same
tls:
certificateRefs:
- group: ""
kind: Secret
name: does-not-exist
mode: Terminate
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-1
namespace: envoy-gateway
spec:
parentRefs:
- kind: Gateway
name: gateway-with-one-attached-route
namespace: envoy-gateway
rules:
- backendRefs:
- name: infra-backend-v1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-2
namespace: envoy-gateway
spec:
parentRefs:
- kind: Gateway
name: gateway-with-two-attached-routes
namespace: envoy-gateway
rules:
- backendRefs:
- name: infra-backend-v1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-3
namespace: envoy-gateway
spec:
parentRefs:
- kind: Gateway
name: gateway-with-two-attached-routes
namespace: envoy-gateway
rules:
- backendRefs:
- name: infra-backend-v1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-not-accepted
namespace: envoy-gateway
spec:
hostnames:
# mismatched hostname here (listener hostname is foo.example.com) triggers NoMatchingListenerHostname reason
- "not-accepted.test.com"
parentRefs:
- kind: Gateway
name: gateway-with-two-attached-routes
namespace: envoy-gateway
rules:
- backendRefs:
- name: infra-backend-v1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: http-route-4
namespace: envoy-gateway
spec:
parentRefs:
- kind: Gateway
name: unresolved-gateway-with-one-attached-unresolved-route
namespace: envoy-gateway
sectionName: tls
rules:
- backendRefs:
- name: does-not-exist
port: 8080
Loading