fix: read L4 routes and ReferenceGrant as v1 instead of the older versions - #2839
Merged
Conversation
Gateway API 1.6 promoted the L4 routes to v1 and deprecated v1alpha2, but the controller still registered, watched, indexed and validated all three through sigs.k8s.io/gateway-api/apis/v1alpha2. That is not just a deprecation warning on every informer re-list. In the 1.6 standard channel CRDs the v1alpha2 version is `served: false`, so for anyone who installs that channel the CRD probe in setupGatewayAPIControllers finds nothing and the TCPRoute, UDPRoute and TLSRoute reconcilers are silently skipped -- L4 routing does not work at all. The project's own Makefile installs the experimental channel, which still serves v1alpha2, which is why CI never caught it. Switch every reference to apis/v1: scheme registration, the CRD probe, the field indexers, the three reconcilers, the translator, the status writer, the route adapters and the TCPRoute/UDPRoute validating webhooks. The v1alpha2 rule and status types are already aliases of their v1 counterparts, so this is a version switch rather than a behavior change. The webhook paths move from /validate-gateway-networking-k8s-io-v1alpha2-* to -v1-*, and config/webhook/manifests.yaml is regenerated to match; the hand-written e2e webhook manifest is synced by hand. Manifests that still declare gateway.networking.k8s.io/v1alpha2 keep working wherever the installed CRDs serve that version, since the API server converts them before they reach the informer. Examples, e2e manifests and the docs support table now use v1. BREAKING CHANGE: L4 routing now requires Gateway API 1.6 or later, which is the first release that serves the v1 versions of TCPRoute, UDPRoute and TLSRoute.
Gateway API 1.6 added a v1 version of ReferenceGrant. Unlike the L4 routes, v1beta1 is not deprecated and remains the storage version, so nothing is broken today -- this is only about reading the resource through the version the API now leads with. Every symbol the controller used from apis/v1beta1 (ReferenceGrant, its Spec/From/To types, Group, Namespace, RouteReasonRefNotPermitted) exists in apis/v1, and the API server converts stored v1beta1 objects on the way out, so watches, the ReferenceGrant-to-route mappers and the cross-namespace permission checks behave identically. Also refresh the Gateway API spec link in the docs, which still pointed at the 1.3 reference.
AlinsRan
added a commit
to api7/api7-ingress-controller
that referenced
this pull request
Aug 10, 2026
…sions Sync of apache/apisix-ingress-controller#2839. Gateway API 1.6 promoted TCPRoute, UDPRoute and TLSRoute to v1 and deprecated v1alpha2, but the controller still registered, watched, indexed and validated all three through sigs.k8s.io/gateway-api/apis/v1alpha2. That is not only a deprecation warning on every informer re-list. In the 1.6 standard channel CRDs the v1alpha2 version is `served: false`, so for anyone who installs that channel the CRD probe in setupGatewayAPIControllers finds nothing and the three L4 reconcilers are silently skipped -- L4 routing does not work at all. Our own Makefile installs the experimental channel, which still serves v1alpha2, which is why CI never caught it. Envoy Gateway hit the same failure with TLSRoute (envoyproxy/gateway#8326). Switch every reference to apis/v1: scheme registration, the CRD probe, the field indexers, the three reconcilers, the translator, the status writers for both the APISIX and API7 EE providers, the route adapters and the TCPRoute/UDPRoute validating webhooks. The v1alpha2 rule and status types are already aliases of their v1 counterparts, so this is a version switch rather than a behavior change. ReferenceGrant moves to v1 as well. That one is not urgent -- v1beta1 is not deprecated and remains the storage version -- but every symbol used from apis/v1beta1 exists in apis/v1, so reading it through the version the API now leads with is free. The webhook paths move from /validate-gateway-networking-k8s-io-v1alpha2-* to -v1-*, config/webhook/manifests.yaml is regenerated to match, and the hand-written e2e webhook manifest is synced by hand. Manifests that still declare an older version keep working wherever the installed CRDs serve it, since the API server converts them before they reach the informer. Examples, e2e manifests and the docs support table now use v1. BREAKING CHANGE: L4 routing now requires Gateway API 1.6 or later, which is the first release that serves the v1 versions of TCPRoute, UDPRoute and TLSRoute.
shreemaan-abhishek
approved these changes
Aug 10, 2026
nic-6443
approved these changes
Aug 11, 2026
AlinsRan
added a commit
to AlinsRan/apisix-ingress-controller
that referenced
this pull request
Aug 11, 2026
This was referenced Aug 11, 2026
Merged
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Gateway API 1.6 promoted the L4 routes to
v1and deprecatedv1alpha2, but the controller still registers, watches, indexes and validates all three throughsigs.k8s.io/gateway-api/apis/v1alpha2. Every informer re-list logs:That warning is the visible half. The real problem is that in the 1.6 standard channel CRDs,
v1alpha2isserved: false:So for anyone installing the standard channel,
HasAPIResourceinsetupGatewayAPIControllersfinds nothing, and the TCPRoute, UDPRoute and TLSRoute reconcilers are silently skipped — L4 routing does not work at all.make install-gateway-apiinstalls the experimental channel, which still servesv1alpha2, which is why CI never caught this.Solution
Commit 1 — L4 routes to
v1. Switch every reference toapis/v1:internal/manager/run.go) and the CRD probe (internal/manager/controllers.go)/validate-gateway-networking-k8s-io-v1alpha2-*to-v1-*,config/webhook/manifests.yamlis regenerated to match, and the hand-written e2e webhook manifest is syncedThe
v1alpha2rule and status types are already type aliases of theirv1counterparts, so this is a version switch rather than a behavior change.Commit 2 — ReferenceGrant to
v1. 1.6 also added av1ReferenceGrant. This one is not urgent:v1beta1is not deprecated and remains the storage version, so nothing is broken today. But every symbol used fromapis/v1beta1exists inapis/v1, and the API server converts stored objects on the way out, so reading it through the version the API now leads with is free.User manifests that still declare an older version keep working wherever the installed CRDs serve it, because the API server converts them before they reach the informer. Examples, e2e manifests and the docs support table now use
v1.One schema difference worth noting:
v1tightensTCPRouteSpec.RulesfromMaxItems=16toMaxItems=1. The translator iterates rules and is unaffected, and every manifest in this repo already carries a single rule.Breaking change
L4 routing now requires Gateway API 1.6 or later, the first release that serves the
v1versions of TCPRoute, UDPRoute and TLSRoute.Makefilealready pinsGATEAY_API_VERSION ?= v1.6.0.Verification
go build ./...,go vet ./...,gofmt -lcleanmake lint— 0 issuesgo test ./internal/... ./pkg/...— all packages pass