Documentation
¶
Overview ¶
Package attachment holds the edge Gateway API controller's route→listener attachment resolution: parentRef matching, allowedRoutes (namespaces/kinds) admission, ReferenceGrant-gated backendRef admission, and listener/route hostname intersection. It is deliberately free of any xDS proxy/cache dependency so the attachment semantics (and their tests) stand alone from Envoy resource generation; the gatewayapi reconciler composes it.
Index ¶
- func AttachedGatewayKeys(parentRefs []gatewayv1.ParentReference, routeNamespace string, ...) []string
- func AttachedHostnameLookupKeys(parentRefs []gatewayv1.ParentReference, routeNamespace string, ...) []string
- func AttachedToOurGateway(parentRefs []gatewayv1.ParentReference, routeNamespace string, ...) bool
- func BackendPermitted(backendNamespace *gatewayv1.Namespace, routeNamespace, routeKind, name string, ...) bool
- func BuildGatewayListenerHostnames(gws []gatewayv1.Gateway) map[string][]string
- func DerefBackendNamespace(ns *gatewayv1.Namespace) string
- func EffectiveHostnames(routeHosts []string, gwKeys []string, gwListenerHostnames map[string][]string) []string
- func GatewayParentPorts(parentRefs []gatewayv1.ParentReference, routeNamespace string, ...) []uint32
- func ListenerHasInvalidRouteKinds(ln gatewayv1.Listener) bool
- func ListenerSupportedKinds(ln gatewayv1.Listener) []gatewayv1.RouteGroupKind
- func OurGatewayParentRefs(parentRefs []gatewayv1.ParentReference, routeNamespace string, ...) []gatewayv1.ParentReference
- func SupportedKindsFor(protocol gatewayv1.ProtocolType) []gatewayv1.RouteGroupKind
- type GatewayKey
- type GatewayListenerKey
- type Resolver
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AttachedGatewayKeys ¶
func AttachedGatewayKeys(parentRefs []gatewayv1.ParentReference, routeNamespace string, gateways map[GatewayKey]struct{}) []string
AttachedGatewayKeys returns the "<ns>/<name>" keys of OUR Gateways a route's parentRefs attach to. Used to scope a vhost to its actual Gateways' route tables (Phase 2 assignment by attachment, not by cert).
func AttachedHostnameLookupKeys ¶
func AttachedHostnameLookupKeys(parentRefs []gatewayv1.ParentReference, routeNamespace string, gateways map[GatewayKey]struct{}) []string
AttachedHostnameLookupKeys returns the hostname-lookup keys for EffectiveHostnames. When a parentRef specifies a sectionName the key is "ns/name/sectionName" so EffectiveHostnames uses only that listener's hostname; otherwise it uses the gateway-level "ns/name" key (union of all listener hostnames). This implements Gateway API §hostname-intersection: "If the listener section name and/or port is specified, Hostnames must match only that listener."
func AttachedToOurGateway ¶
func AttachedToOurGateway(parentRefs []gatewayv1.ParentReference, routeNamespace string, gateways map[GatewayKey]struct{}) bool
AttachedToOurGateway reports whether the given parentRefs (belonging to a route in routeNamespace) include a reference to one of our Gateways. A parentRef's namespace defaults to the route's own namespace when unset (per the Gateway API spec), so cross-namespace attachment is matched correctly.
func BackendPermitted ¶
func BackendPermitted(backendNamespace *gatewayv1.Namespace, routeNamespace, routeKind, name string, grants []gatewayv1beta1.ReferenceGrant) bool
BackendPermitted reports whether a backendRef is allowed onto the data plane: a same-namespace ref always is; a cross-namespace ref needs a matching ReferenceGrant in the backend's namespace whose from matches the route and whose to allows the Service. routeKind is the referring route's kind (HTTPRoute/TCPRoute/TLSRoute).
func BuildGatewayListenerHostnames ¶
BuildGatewayListenerHostnames extracts the listener hostnames for each Gateway into a map keyed by "<namespace>/<name>". A listener with no hostname is represented by an empty string "". The returned value is used to compute effective route hostnames via EffectiveHostnames.
Keys: "ns/name" for the per-Gateway union (used by routes without a sectionName), and "ns/name/sectionName" for per-section lookup (used when a parentRef specifies a sectionName). The per-section value contains only that listener's hostname so EffectiveHostnames scopes the route to exactly the hostnames of the listener it attached to.
func DerefBackendNamespace ¶
DerefBackendNamespace returns the backendRef namespace ("" when unset).
func EffectiveHostnames ¶
func EffectiveHostnames(routeHosts []string, gwKeys []string, gwListenerHostnames map[string][]string) []string
EffectiveHostnames computes the Gateway API effective hostname set for a route:
effective = ∪(over attached Gateways) of { route.Hostnames ∩ listenerHostnames(gw) }
Gateway API intersection rules (per spec):
- A listener hostname "" (no hostname) admits ALL route hostnames unchanged.
- A route hostname "" (no hostnames on the route) inherits the listener's hostname(s); a listener "" × route "" = "*" (catch-all, no constraint).
- exact == exact: they match; result is that exact hostname.
- listener "*.example.com" ∩ route "a.example.com": route is more specific → result "a.example.com".
- route "*.example.com" ∩ listener "a.example.com": listener is more specific → result "a.example.com".
The return value replaces vh.Hosts in the reconciler so downstream code (the cache's buildEdgeVhostsLocked) sees only the hosts the route ACTUALLY matches. A nil/empty return means the route has no valid attachment (no listener admits any of its declared hosts) and must be discarded by the caller.
Multi-Gateway: takes the union of intersections across all attached Gateways, deduplicating. This is a correct first cut (see implementation note).
func GatewayParentPorts ¶
func GatewayParentPorts( parentRefs []gatewayv1.ParentReference, routeNamespace string, gateways map[GatewayKey]struct{}, protocol gatewayv1.ProtocolType, listenerKeys map[GatewayListenerKey]struct{}, ) []uint32
GatewayParentPorts returns the distinct ports of our Gateway listeners that match the given protocol and are referenced by the given parentRefs (belonging to a route in routeNamespace). Used to scope TCPRoute/TLSRoute attachments to the exact Gateway listener ports. A parentRef namespace defaults to the route's own namespace when unset.
func ListenerHasInvalidRouteKinds ¶
ListenerHasInvalidRouteKinds reports whether a listener's allowedRoutes.kinds names any kind the listener's protocol does not support (drives the ResolvedRefs=False / InvalidRouteKinds listener condition).
func ListenerSupportedKinds ¶
func ListenerSupportedKinds(ln gatewayv1.Listener) []gatewayv1.RouteGroupKind
ListenerSupportedKinds returns the supportedKinds to publish on a listener's status: the protocol-default kinds, intersected with allowedRoutes.kinds when the listener sets one. A listener whose allowedRoutes.kinds names only unsupported kinds yields an empty (non-nil) slice, matching the upstream conformance expectation (supportedKinds: []).
func OurGatewayParentRefs ¶
func OurGatewayParentRefs(parentRefs []gatewayv1.ParentReference, routeNamespace string, gateways map[GatewayKey]struct{}) []gatewayv1.ParentReference
OurGatewayParentRefs returns the parentRefs of a route (in routeNamespace) that point at one of our Gateways — the only entries we own status for. The parentRef namespace defaults to the route's namespace.
func SupportedKindsFor ¶
func SupportedKindsFor(protocol gatewayv1.ProtocolType) []gatewayv1.RouteGroupKind
SupportedKindsFor maps a listener protocol to the Route kinds the edge serves on it: HTTPRoute for HTTP/HTTPS, TCPRoute for TCP, TLSRoute for TLS.
Types ¶
type GatewayKey ¶
GatewayKey identifies a Gateway by namespace+name. Since the edge reconciles cluster-wide, Gateway names alone are no longer unique (two namespaces may each have a Gateway "edge"), so route attachment must match on the full namespaced name.
type GatewayListenerKey ¶
type GatewayListenerKey struct {
Gateway GatewayKey
Port uint32
Protocol gatewayv1.ProtocolType
}
GatewayListenerKey identifies a listener within a gateway by namespace+name+protocol+port. Used to scope TCPRoute/TLSRoute parentRef port matching.
type Resolver ¶
Resolver resolves route→listener attachment. It needs only a Kubernetes reader (to fetch route-namespace labels for allowedRoutes.namespaces selectors) and a logger — no xDS proxy/cache types.
func (*Resolver) AttachedRoutesForListener ¶
func (r *Resolver) AttachedRoutesForListener( ctx context.Context, gw *gatewayv1.Gateway, ln gatewayv1.Listener, httpRoutes []gatewayv1.HTTPRoute, tcpRoutes []gatewayv1.TCPRoute, tlsRoutes []gatewayv1.TLSRoute, gateways map[GatewayKey]struct{}, listenerKeys map[GatewayListenerKey]struct{}, ) int32
AttachedRoutesForListener counts the routes (with Accepted=True) attached to a specific listener. HTTP/HTTPS listeners accept HTTPRoutes attached to the gateway; TCP/TLS listeners accept TCP/TLSRoutes whose parentRef resolves to that listener's port (via GatewayParentPorts).
func (*Resolver) HTTPRouteAcceptance ¶
func (r *Resolver) HTTPRouteAcceptance(ctx context.Context, hr *gatewayv1.HTTPRoute, gwByKey map[GatewayKey]*gatewayv1.Gateway) (bool, string, string)
HTTPRouteAcceptance computes the route-level Accepted condition for an HTTPRoute across all of our Gateways it references. The route is Accepted when it attaches to at least one listener of at least one of our Gateways; otherwise the most specific failure reason wins (NoMatchingListenerHostname > NotAllowedByListeners > NoMatchingParent).