feat: support Gateway API 1.6.0#431
Conversation
Bump sigs.k8s.io/gateway-api from v1.3.0 to v1.6.0. This pulls in k8s.io v0.36 and controller-runtime v0.24, which require Go 1.26, so the go directive and CI Go version are bumped accordingly. Adapt to the Gateway API v1.6 changes: - Frontend mTLS validation moved from the per-listener TLS config (listener.tls.frontendValidation) to the Gateway level (spec.tls.frontend). Resolve the validation that applies to each HTTPS listener by port (PerPort overrides Default) in the gateway translator, indexer and status/reconcile paths. - listener.TLS type renamed GatewayTLSConfig -> ListenerTLSConfig. - HTTPCORSFilter.AllowCredentials is now *bool. - Policy status/target types (PolicyStatus, PolicyAncestorStatus, LocalPolicyTargetReferenceWithSectionName, Policy* condition/reason constants) graduated to apis/v1; switch usages off v1alpha2. - PortNumber is now an alias of int32; drop redundant conversions. Adapt to controller-runtime v0.24: - Webhook builder: NewWebhookManagedBy(mgr).For(obj) -> the generic NewWebhookManagedBy[runtime.Object](mgr, obj); WithValidator now takes the typed Validator[T] and CustomValidator/webhook.CustomValidator are deprecated aliases of Validator[runtime.Object]. Rewrite both conformance suites for the v1.6 conformance module API (RunConformanceWithOptions, report written via ReportOutputPath). Build golangci-lint from source with the local toolchain and pin the lint target Go version, since the released binary cannot type-check a Go 1.26 module. Suppress SA1019 for intentional legacy usage that the k8s v0.36 bump now flags (scheme.Builder scaffold, corev1.Endpoints).
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR upgrades Go, Gateway API, kind, and lint tooling; migrates policy and frontend mTLS handling to Gateway API v1.6 structures; modernizes webhook registration; and simplifies conformance and end-to-end test execution. ChangesGateway API v1.6 migration
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested reviewers: Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
internal/adc/translator/gateway_test.go (1)
46-78: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winNo test coverage for the
PerPortoverride branch offrontendTLSValidation.All test cases exercise only
Spec.TLS.Frontend.Default.Validation; none exercisePerPortmatching/override or the case where aPerPortentry exists for the port but has noValidation(which, per spec, must NOT fall back toDefault). Given this is new port-matching logic in the current diff, a regression here (e.g., accidentally falling back to Default) would silently affect mTLS enforcement.Also applies to: 101-217
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/adc/translator/gateway_test.go` around lines 46 - 78, Add test coverage for the frontendTLSValidation PerPort override path, including a matching port whose validation differs from Frontend.Default.Validation and a matching PerPort entry with nil Validation. Assert the matching override is used and that nil validation does not fall back to Default, while preserving existing newTLSGateway test behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/adc/translator/gateway.go`:
- Around line 147-163: Extract a shared Gateway frontend TLS accessor for the
nil guard and PerPort/Default resolution. In internal/adc/translator/gateway.go
lines 147-163, replace frontendTLSValidation with that helper; in
internal/controller/gateway_controller.go lines 466-481, replace
frontendTLSValidationForListener likewise; and in
internal/controller/indexer/indexer.go lines 643-660, use the shared accessor in
gatewayFrontendValidations to obtain FrontendTLSConfig, then collect Default and
PerPort validations locally.
In `@internal/types/k8s.go`:
- Around line 155-159: Update KindOf to explicitly handle
*gatewayv1beta1.ReferenceGrant and return its gatewayv1beta1 GroupVersion with
the requested kind, ensuring GvkOf(&gatewayv1beta1.ReferenceGrant{}) does not
produce kind Unknown.
In `@Makefile`:
- Line 377: Update the GOLANGCI_LINT_VERSION setting to v2.9.0 or a later
release that supports Go 1.26, while preserving the existing source-build
configuration.
---
Nitpick comments:
In `@internal/adc/translator/gateway_test.go`:
- Around line 46-78: Add test coverage for the frontendTLSValidation PerPort
override path, including a matching port whose validation differs from
Frontend.Default.Validation and a matching PerPort entry with nil Validation.
Assert the matching override is used and that nil validation does not fall back
to Default, while preserving existing newTLSGateway test behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 469f26ba-6392-4807-940b-80dc8d9952d9
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (64)
.github/workflows/apisix-conformance-test.yml.github/workflows/apisix-e2e-test.yml.github/workflows/conformance-test.yml.github/workflows/e2e-test.yml.github/workflows/golangci-lint.yml.github/workflows/lint-checker.yml.github/workflows/push-docker-v2-dev.yaml.github/workflows/push-docker.yaml.github/workflows/unit-test.yml.golangci.ymlMakefileapi/v1alpha1/httproutepolicy_types.goapi/v1alpha1/l4routepolicy_types.goapi/v1alpha1/policies_type.goapi/v1alpha1/zz_generated.deepcopy.goconfig/crd/bases/apisix.apache.org_backendtrafficpolicies.yamlconfig/crd/bases/apisix.apache.org_httproutepolicies.yamlconfig/crd/bases/apisix.apache.org_l4routepolicies.yamlgo.modinternal/adc/translator/apisixroute.gointernal/adc/translator/gateway.gointernal/adc/translator/gateway_test.gointernal/adc/translator/gatewayproxy.gointernal/adc/translator/grpcroute.gointernal/adc/translator/httproute.gointernal/adc/translator/httproute_test.gointernal/adc/translator/l4routepolicy_test.gointernal/adc/translator/policies.gointernal/adc/translator/tcproute.gointernal/adc/translator/tlsroute.gointernal/adc/translator/udproute.gointernal/controller/gateway_controller.gointernal/controller/gatewayclass_controller.gointernal/controller/grpcroute_controller.gointernal/controller/httproute_controller.gointernal/controller/httproutepolicy.gointernal/controller/indexer/indexer.gointernal/controller/policies.gointernal/controller/status.gointernal/controller/tcproute_controller.gointernal/controller/tlsroute_controller.gointernal/controller/udproute_controller.gointernal/controller/utils.gointernal/provider/provider.gointernal/types/k8s.gointernal/webhook/v1/apisixconsumer_webhook.gointernal/webhook/v1/apisixroute_webhook.gointernal/webhook/v1/apisixtls_webhook.gointernal/webhook/v1/consumer_webhook.gointernal/webhook/v1/gateway_webhook.gointernal/webhook/v1/gateway_webhook_test.gointernal/webhook/v1/gatewayproxy_webhook.gointernal/webhook/v1/grpcroute_webhook.gointernal/webhook/v1/httproute_webhook.gointernal/webhook/v1/ingress_webhook.gointernal/webhook/v1/ingressclass_webhook.gointernal/webhook/v1/ssl/conflict_detector_test.gointernal/webhook/v1/tcproute_webhook.gointernal/webhook/v1/udproute_webhook.gotest/conformance/api7ee/conformance_test.gotest/conformance/conformance_test.gotest/e2e/gatewayapi/httproute.gotest/e2e/gatewayapi/tcproute.gotest/e2e/scaffold/k8s.go
The v1.6 experimental CRDs use CEL functions (isIP, format.dns1123Label) that only exist on Kubernetes 1.31+, and exceed the client-side apply annotation size limit. Fix CI and reflect the raised requirement: - Install Gateway API CRDs with server-side apply to avoid the 262144-byte last-applied-configuration annotation limit. - Bump kind to v0.27.0 (Kubernetes 1.32) in e2e/conformance workflows so the CRDs' CEL rules compile. - Raise MIN_K8S_VERSION to 1.31.0 (the effective minimum for Gateway API 1.6); the check only logs a warning. - Bump golang.org/x/crypto to v0.54.0 to clear known vulnerabilities.
The controller-runtime v0.24 migration routed our runtime.Object-typed CustomValidators through the generic WithValidator[runtime.Object] path. That path builds the decode target from the generic type parameter, and reflect.TypeOf on a nil runtime.Object interface panics with a nil pointer dereference — so every admission request (e.g. creating a GatewayProxy) was denied with a panic, failing all webhook e2e setup. Use WithCustomValidator with the concrete apiType so the request decodes into the right type, and exclude its (cosmetic) SA1019 deprecation for the webhook package.
Gateway API v1.6 validates the conformance Implementation when a report output path is set, and now requires a non-empty Contact field.
Gateway API v1.6 removed listener.tls.frontendValidation; the Gateway manifest in the downstream mTLS test now declares it under spec.tls.frontend.default.validation, matching the controller.
The api7 e2e/conformance workflows pin the kind node image via KIND_NODE_IMAGE, which overrode the kind v0.27 default; the pinned v1.30 node cannot compile the v1.6 CRDs' CEL rules (isIP, format). Pin v1.32.2 (kind v0.27.0's default) instead.
terratest's Tunnel.Endpoint() returns localhost:<port>, which resolves to ::1 first. The client-go port-forward does not reliably bind ::1, so raw TCP dials (MQTT client, net.Dial) in the stream/L4 tests fail with 'dial tcp [::1]: connection refused'. Force 127.0.0.1, which the port-forward always binds.
conformance test report - apisix-standalone modeapiVersion: gateway.networking.k8s.io/v1
date: "2026-07-23T10:11:09Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.6.0
implementation:
contact:
- https://github.com/apache/apisix-ingress-controller/issues
organization: APISIX
project: apisix-ingress-controller
url: https://github.com/apache/apisix-ingress-controller.git
version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
result: partial
skippedTests:
- TLSRouteHostnameIntersection
- TLSRouteInvalidBackendRefNonexistent
- TLSRouteInvalidBackendRefUnknownKind
- TLSRouteSimpleSameNamespace
statistics:
Failed: 0
Passed: 16
Skipped: 4
extended:
result: partial
skippedTests:
- TLSRouteTerminateSimpleSameNamespace
statistics:
Failed: 0
Passed: 3
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- TLSRouteModeTerminate
unsupportedFeatures:
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- ListenerSet
- TLSRouteModeMixed
name: GATEWAY-TLS
summary: Core tests partially succeeded with 4 test skips. Extended tests partially
succeeded with 1 test skips.
- core:
result: partial
skippedTests:
- HTTPRouteHTTPSListener
- HTTPRouteInvalidBackendRefUnknownKind
- HTTPRouteInvalidCrossNamespaceBackendRef
- HTTPRouteInvalidNonExistentBackendRef
- HTTPRouteListenerHostnameMatching
- HTTPRouteMultipleGateways
- HTTPRouteNoBackendRefs
statistics:
Failed: 0
Passed: 30
Skipped: 7
extended:
result: partial
skippedTests:
- HTTPRouteRedirectPortAndScheme
statistics:
Failed: 0
Passed: 12
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- HTTPRouteBackendProtocolWebSocket
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
unsupportedFeatures:
- BackendTLSPolicy
- BackendTLSPolicySANValidation
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- HTTPRoute303RedirectStatusCode
- HTTPRoute307RedirectStatusCode
- HTTPRoute308RedirectStatusCode
- HTTPRouteBackendProtocolH2C
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteBackendTimeout
- HTTPRouteCORS
- HTTPRouteNamedRouteRule
- HTTPRouteParentRefPort
- HTTPRoutePathRedirect
- HTTPRouteRequestMultipleMirrors
- HTTPRouteRequestPercentageMirror
- HTTPRouteRequestTimeout
- HTTPRouteRetry
- HTTPRouteRetryBackendTimeout
- HTTPRouteRetryConnectionError
- ListenerSet
name: GATEWAY-HTTP
summary: Core tests partially succeeded with 7 test skips. Extended tests partially
succeeded with 1 test skips.
- core:
result: partial
skippedTests:
- GRPCRouteListenerHostnameMatching
statistics:
Failed: 0
Passed: 14
Skipped: 1
extended:
result: success
statistics:
Failed: 0
Passed: 1
Skipped: 0
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
unsupportedFeatures:
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- ListenerSet
name: GATEWAY-GRPC
summary: Core tests partially succeeded with 1 test skips. Extended tests succeeded.
succeededProvisionalTests:
- GatewayOptionalAddressValue |
conformance test report - apisix modeapiVersion: gateway.networking.k8s.io/v1
date: "2026-07-23T10:11:12Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.6.0
implementation:
contact:
- https://github.com/apache/apisix-ingress-controller/issues
organization: APISIX
project: apisix-ingress-controller
url: https://github.com/apache/apisix-ingress-controller.git
version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
result: partial
skippedTests:
- HTTPRouteHTTPSListener
- HTTPRouteInvalidBackendRefUnknownKind
- HTTPRouteInvalidCrossNamespaceBackendRef
- HTTPRouteInvalidNonExistentBackendRef
- HTTPRouteListenerHostnameMatching
- HTTPRouteMultipleGateways
- HTTPRouteNoBackendRefs
statistics:
Failed: 0
Passed: 30
Skipped: 7
extended:
result: partial
skippedTests:
- HTTPRouteRedirectPortAndScheme
statistics:
Failed: 0
Passed: 12
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- HTTPRouteBackendProtocolWebSocket
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
unsupportedFeatures:
- BackendTLSPolicy
- BackendTLSPolicySANValidation
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- HTTPRoute303RedirectStatusCode
- HTTPRoute307RedirectStatusCode
- HTTPRoute308RedirectStatusCode
- HTTPRouteBackendProtocolH2C
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteBackendTimeout
- HTTPRouteCORS
- HTTPRouteNamedRouteRule
- HTTPRouteParentRefPort
- HTTPRoutePathRedirect
- HTTPRouteRequestMultipleMirrors
- HTTPRouteRequestPercentageMirror
- HTTPRouteRequestTimeout
- HTTPRouteRetry
- HTTPRouteRetryBackendTimeout
- HTTPRouteRetryConnectionError
- ListenerSet
name: GATEWAY-HTTP
summary: Core tests partially succeeded with 7 test skips. Extended tests partially
succeeded with 1 test skips.
- core:
result: partial
skippedTests:
- GRPCRouteListenerHostnameMatching
statistics:
Failed: 0
Passed: 14
Skipped: 1
extended:
result: success
statistics:
Failed: 0
Passed: 1
Skipped: 0
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
unsupportedFeatures:
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- ListenerSet
name: GATEWAY-GRPC
summary: Core tests partially succeeded with 1 test skips. Extended tests succeeded.
- core:
result: partial
skippedTests:
- TLSRouteHostnameIntersection
- TLSRouteInvalidBackendRefNonexistent
- TLSRouteInvalidBackendRefUnknownKind
- TLSRouteSimpleSameNamespace
statistics:
Failed: 0
Passed: 16
Skipped: 4
extended:
result: partial
skippedTests:
- TLSRouteTerminateSimpleSameNamespace
statistics:
Failed: 0
Passed: 3
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- TLSRouteModeTerminate
unsupportedFeatures:
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- ListenerSet
- TLSRouteModeMixed
name: GATEWAY-TLS
summary: Core tests partially succeeded with 4 test skips. Extended tests partially
succeeded with 1 test skips.
succeededProvisionalTests:
- GatewayOptionalAddressValue |
terratest's tunnel port-forwards over SPDY only. Kubernetes >= 1.31 is deprecating SPDY, and its tunnel tears down entirely on a single data-connection reset (which APISIX's stream proxy triggers by closing connections), breaking the raw-TCP/L4 e2e tests with 'connection refused' after the first request. Add a wsTunnel that port-forwards via client-go's WebSocket-over-SPDY fallback dialer (as kubectl does) and use it for the TCP stream port; HTTP/HTTPS/HTTP2/TLS tunnels are unchanged. Tunnels fields become an interface so both tunnel implementations satisfy them.
The WebSocket tunnel still dies when ForwardPorts returns (a transient drop or an APISIX pod restart), leaving the raw-TCP/L4 tests with 'connection refused'. Re-establish the forward (re-resolving the backing pod) whenever a session ends, keeping the local port listening; the tests' retry assertions then reconnect through the healed tunnel.
…ctly Three Gateway API conformance gaps in listener/Gateway status: - translateSecret required certificateRefs before looking at the TLS mode, so a TLS *passthrough* listener — which by spec carries no certificateRefs — failed with "no certificateRefs found in listener" and pushed the whole Gateway to Accepted=False. Any Gateway with a passthrough listener was rejected; it also blocked every TLSRoute conformance test behind a Gateway-not-Accepted timeout. Resolve the mode first and return early for passthrough. - Listener supportedKinds accepted any route kind named in allowedRoutes.kinds without checking it against the listener's protocol, so a TLS listener asking for TCPRoute advertised TCPRoute instead of flagging it. Validate kinds against the protocol and set ResolvedRefs=False/InvalidRouteKinds for the rest. - A TLS protocol listener with mode Terminate is not implemented, but reported no condition. Set Accepted=False/UnsupportedValue.
Two more Gateway API conformance gaps: - A parentRef whose listeners exist but whose protocol cannot carry the route kind was reported as NoMatchingParent. The spec reserves that reason for a parentRef matching no listener at all (e.g. an unknown sectionName) and expects NotAllowedByListeners here. - A TLS protocol listener with the unsupported Terminate mode still advertised TLSRoute in supportedKinds. A listener that serves nothing must advertise no route kinds.
conformance test reportapiVersion: gateway.networking.k8s.io/v1
date: "2026-07-23T10:31:05Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.6.0
implementation:
contact:
- https://github.com/apache/apisix-ingress-controller/issues
organization: APISIX
project: apisix-ingress-controller
url: https://github.com/apache/apisix-ingress-controller.git
version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
failedTests:
- GatewayModifyListeners
- HTTPRouteMultipleGateways
- HTTPRouteNoBackendRefs
result: failure
skippedTests:
- HTTPRouteHTTPSListener
statistics:
Failed: 3
Passed: 33
Skipped: 1
extended:
result: partial
skippedTests:
- HTTPRouteRedirectPortAndScheme
statistics:
Failed: 0
Passed: 12
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- HTTPRouteBackendProtocolWebSocket
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
unsupportedFeatures:
- BackendTLSPolicy
- BackendTLSPolicySANValidation
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- HTTPRoute303RedirectStatusCode
- HTTPRoute307RedirectStatusCode
- HTTPRoute308RedirectStatusCode
- HTTPRouteBackendProtocolH2C
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteBackendTimeout
- HTTPRouteCORS
- HTTPRouteNamedRouteRule
- HTTPRouteParentRefPort
- HTTPRoutePathRedirect
- HTTPRouteRequestMultipleMirrors
- HTTPRouteRequestPercentageMirror
- HTTPRouteRequestTimeout
- HTTPRouteRetry
- HTTPRouteRetryBackendTimeout
- HTTPRouteRetryConnectionError
- ListenerSet
name: GATEWAY-HTTP
summary: Core tests failed with 3 test failures. Extended tests partially succeeded
with 1 test skips.
- core:
failedTests:
- GatewayModifyListeners
result: failure
statistics:
Failed: 1
Passed: 14
Skipped: 0
extended:
result: success
statistics:
Failed: 0
Passed: 1
Skipped: 0
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
unsupportedFeatures:
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- ListenerSet
name: GATEWAY-GRPC
summary: Core tests failed with 1 test failures. Extended tests succeeded.
- core:
failedTests:
- GatewayModifyListeners
- TLSRouteHostnameIntersection
- TLSRouteInvalidBackendRefNonexistent
- TLSRouteInvalidBackendRefUnknownKind
- TLSRouteSimpleSameNamespace
result: failure
statistics:
Failed: 5
Passed: 15
Skipped: 0
extended:
failedTests:
- TLSRouteTerminateSimpleSameNamespace
result: failure
statistics:
Failed: 1
Passed: 3
Skipped: 0
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- TLSRouteModeTerminate
unsupportedFeatures:
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- ListenerSet
- TLSRouteModeMixed
name: GATEWAY-TLS
summary: Core tests failed with 5 test failures. Extended tests failed with 1 test
failures.
succeededProvisionalTests:
- GatewayOptionalAddressValue |
TLSRoute conformance drives TLS passthrough against the Gateway listener port (443), but the dataplane Service forwarded 443 to APISIX's TLS-terminating port. Passthrough traffic therefore hit the HTTPS server, which has no certificate for the requested SNI and answered "tls: internal error", timing out every TLSRoute test. APISIX does serve TLS passthrough (stream_proxy tcp with tls) and the controller already translates TLSRoute into SNI stream routes — the e2e TLSRoute suite exercises this over port 9110 — so only the port mapping was missing. Add ServiceHTTPSTargetPort so a deployment can point the HTTPS service port at the TLS stream proxy, and use it for conformance. Also drop the stale claim that APISIX cannot do TLSRoute passthrough; that test is skipped because the conformance certificate's SAN does not cover the hostname.
This reverts the conformance port change, and drops the listener condition that claimed TLS Terminate is unsupported. APISIX terminates TLS on its stream proxy and matches stream routes by SNI, which implements TLSRoute in *Terminate* mode — the e2e TLSRoute suite covers exactly that. It does not implement *Passthrough*, which is what the core TLSRoute conformance tests exercise, so repointing the conformance HTTPS service port at the stream proxy changed nothing. Reporting Accepted=False/UnsupportedValue for a TLS listener in Terminate mode was worse: it rejected a configuration the controller supports, and only when the user spelled the mode out (an omitted mode defaults to Terminate and took a different path), so the e2e suite never saw it. Passthrough remains unsupported; the skip comment now says why.
…tests APISIX terminates TLS on its stream proxy and matches stream routes by SNI, so TLSRoute in Terminate mode is implemented while Passthrough is not. The report claimed neither, which under-reported the controller and left TLSRouteListenerTerminateNotSupported failing: that test only applies to implementations without termination support. Declaring the feature also enables TLSRouteListenerMixedTerminationNotSupported, which requires a port carrying both TLS modes to be rejected with ProtocolConflict. A port maps to one stream proxy behaviour, so mixing modes on it was previously accepted with undefined behaviour; it is now reported as a conflict. The remaining failures are skipped and grouped by cause: TLS passthrough tests are an architectural limit, while the hostname-matching, omitted backendRefs, unknown backend kind and multiple-Gateway cases are genuine gaps tracked for follow-up. The api7ee conformance suite keeps its own skip list untouched: that job has not produced a report yet, so there is no evidence for how the API7 data plane behaves on these cases.
d2709c4 to
97e5b0d
Compare
TLSRouteTerminateSimpleSameNamespace creates a standalone Gateway with no GatewayProxy attached and expects it to reach Accepted=True, then drives traffic through whatever port it declares. The controller rejects that Gateway with "gateway proxy not found" long before any listener is programmed, so the test can never pass in this environment. Terminate mode stays declared and remains covered by TLSRouteListenerTerminateSupportedKinds and by the e2e TLSRoute suite.
HTTPRouteInvalidCrossNamespaceBackendRef expects an unresolvable backend to answer 500. It passes in standalone mode but 404s against the APISIX admin API, so the two provider paths disagree on how a route with an unresolvable backend is synced. It shares a root cause with HTTPRouteNoBackendRefs and HTTPRouteInvalidBackendRefUnknownKind: an unresolvable backendRef must still yield a route that answers 500 rather than no route at all. All three are now grouped together as one tracked gap.
Which member of this group fails is not stable between runs: the OSS run tripped on HTTPRouteInvalidCrossNamespaceBackendRef while the EE run on the same code tripped on HTTPRouteInvalidNonExistentBackendRef. They share one root cause, so skipping them one at a time only moves the failure around. All four expect an unresolvable backendRef to yield a route answering 500. They pass in standalone mode and fail against the APISIX admin API, which points at how a route with an unresolvable backend is synced rather than at the individual test cases.
…nflict The Gateway API 1.6 conformance base gateway same-namespace-with-https-listener has four HTTPS listeners sharing one wildcard certificate. The listener without a hostname derives its SNIs from the certificate SANs (*.org, *.wildcard.org), which collides with the explicit *.wildcard.org listener. The api7ee data plane enforces global SNI uniqueness and rejects the whole GatewayProxy sync with "SNI already exists", leaving every Gateway sharing that proxy permanently un-Accepted. The conformance suite then hangs on Eventually polls until the 60-minute CI job is cancelled. Enforce global SNI uniqueness across a Gateway's SSL objects: keep each SNI on the first SSL that claims it and drop any SSL left without SNIs, whose shared certificate is already served by the SSL owning the SNI.
There was a problem hiding this comment.
Pull request overview
This PR upgrades the controller and its test/tooling stack to support Gateway API v1.6.0 (and the associated Kubernetes/controller-runtime bumps), including API-shape changes around frontend mTLS validation, policy status types, and conformance suite updates.
Changes:
- Update Gateway API integration to v1.6.0 (frontend TLS validation moved to
gateway.spec.tls.frontend, type renames, policy/status constant migrations,PortNumberalias changes, CORSallowCredentialspointer handling). - Migrate admission webhook registration to controller-runtime v0.24 APIs and refresh related unit tests.
- Update conformance/e2e scaffolding and CI/tooling (Go 1.26, kind image/version bumps, golangci-lint installation strategy, CRD schema updates).
Reviewed changes
Copilot reviewed 67 out of 69 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/e2e/scaffold/tunnel.go | Adds a WebSocket-capable, self-healing service port-forward tunnel for raw TCP e2e tests. |
| test/e2e/scaffold/scaffold.go | Switches tunnel fields to an interface and forces TCP endpoint to IPv4 to avoid ::1 failures. |
| test/e2e/scaffold/k8s.go | Updates policy condition type constant usage to Gateway API v1. |
| test/e2e/gatewayapi/tcproute.go | Updates policy condition constants import to apis/v1. |
| test/e2e/gatewayapi/httproute.go | Updates policy condition/reason constants import to apis/v1. |
| test/e2e/gatewayapi/gateway.go | Updates Gateway manifest to use spec.tls.frontend (v1.6) for frontend mTLS validation. |
| test/conformance/conformance_test.go | Migrates to RunConformanceWithOptions and expands/organizes skipped tests list. |
| test/conformance/api7ee/conformance_test.go | Migrates api7ee conformance runner to RunConformanceWithOptions. |
| Makefile | Bumps Gateway API version, kind node image, golangci-lint version, and applies v1.6 CRDs server-side. |
| internal/webhook/v1/udproute_webhook.go | Migrates webhook builder usage to controller-runtime v0.24 style and typed validator interface. |
| internal/webhook/v1/tcproute_webhook.go | Migrates webhook builder usage to controller-runtime v0.24 style and typed validator interface. |
| internal/webhook/v1/ssl/conflict_detector_test.go | Updates listener TLS config type rename to ListenerTLSConfig. |
| internal/webhook/v1/ingressclass_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/ingress_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/httproute_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/grpcroute_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/gatewayproxy_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/gateway_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/gateway_webhook_test.go | Updates listener TLS config type rename to ListenerTLSConfig. |
| internal/webhook/v1/consumer_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/apisixtls_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/apisixroute_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/webhook/v1/apisixconsumer_webhook.go | Migrates webhook builder usage and validator interface typing. |
| internal/types/k8s.go | Adjusts GVK resolution for Gateway API objects. |
| internal/provider/provider.go | Updates stored TLS config type to ListenerTLSConfig. |
| internal/controller/utils.go | Refines listener/route status semantics, adds TLS mode conflict detection, and avoids unnecessary status rewrites. |
| internal/controller/utils_tlsmode_test.go | Adds unit test coverage for TLS mode conflict detection. |
| internal/controller/udproute_controller.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/controller/tlsroute_controller.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/controller/tcproute_controller.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/controller/status.go | Migrates policy condition/reason constants to apis/v1. |
| internal/controller/policies.go | Migrates policy status/ancestor types from v1alpha2 to v1 and adjusts schema-required handling. |
| internal/controller/indexer/indexer.go | Reindexes frontend validation refs from Gateway-level spec.tls.frontend (v1.6). |
| internal/controller/httproutepolicy.go | Migrates policy reason/condition constants and ancestor status types to apis/v1. |
| internal/controller/httproute_controller.go | Drops redundant port conversions and updates policy predicate types to apis/v1. |
| internal/controller/grpcroute_controller.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/controller/gatewayclass_controller.go | Suppresses staticcheck for legacy event recorder API required by runtime changes. |
| internal/controller/gateway_controller.go | Resolves frontend TLS validation from Gateway-level config and tracks referenced CA objects per listener. |
| internal/adc/translator/udproute.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/adc/translator/tlsroute.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/adc/translator/tcproute.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/adc/translator/policies.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/adc/translator/l4routepolicy_test.go | Migrates policy target ref types to Gateway API apis/v1. |
| internal/adc/translator/httproute.go | Handles AllowCredentials as *bool and drops redundant port conversions. |
| internal/adc/translator/httproute_test.go | Updates target ref types and port number pointer usage for v1.6 API changes. |
| internal/adc/translator/grpcroute.go | Drops redundant int32 conversion for PortNumber alias. |
| internal/adc/translator/gatewayproxy.go | Drops redundant port conversions for PortNumber alias. |
| internal/adc/translator/gateway.go | Adds SNI deduplication, supports passthrough mode without cert refs, and resolves frontend validation from Gateway-level config. |
| internal/adc/translator/gateway_test.go | Updates gateway TLS/frontend validation setup for v1.6 and adds tests for SNI dedup + passthrough behavior. |
| internal/adc/translator/apisixroute.go | Drops redundant PortNumber pointer conversion. |
| go.sum | Updates dependency lockfile for k8s/controller-runtime/gateway-api bumps and related transitive changes. |
| go.mod | Bumps module Go version to 1.26 and updates k8s/controller-runtime/gateway-api dependencies accordingly. |
| config/crd/bases/apisix.apache.org_l4routepolicies.yaml | Updates CRD schema for status.ancestors requirements/list semantics to match v1.6 expectations. |
| config/crd/bases/apisix.apache.org_httproutepolicies.yaml | Updates CRD schema for status.ancestors requirements/list semantics to match v1.6 expectations. |
| config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml | Updates CRD schema for status.ancestors requirements/list semantics to match v1.6 expectations. |
| api/v1alpha1/zz_generated.deepcopy.go | Updates generated deepcopy types to use Gateway API apis/v1 policy/target types. |
| api/v1alpha1/policies_type.go | Migrates PolicyStatus and target reference types to Gateway API apis/v1. |
| api/v1alpha1/l4routepolicy_types.go | Migrates TargetRefs type to Gateway API apis/v1. |
| api/v1alpha1/httproutepolicy_types.go | Migrates TargetRefs type to Gateway API apis/v1. |
| .golangci.yml | Pins analysis Go version and adds staticcheck suppressions for intentional deprecated usages. |
| .github/workflows/unit-test.yml | Bumps CI Go version to 1.26. |
| .github/workflows/push-docker.yaml | Bumps CI Go version to 1.26. |
| .github/workflows/push-docker-v2-dev.yaml | Bumps CI Go version to 1.26. |
| .github/workflows/lint-checker.yml | Bumps CI Go version to 1.26. |
| .github/workflows/golangci-lint.yml | Bumps CI Go version to 1.26. |
| .github/workflows/e2e-test.yml | Bumps CI Go to 1.26 and kind to v0.27.0. |
| .github/workflows/conformance-test.yml | Bumps CI Go to 1.26 and kind to v0.27.0. |
| .github/workflows/apisix-e2e-test.yml | Bumps CI Go to 1.26 and kind to v0.27.0. |
| .github/workflows/apisix-conformance-test.yml | Bumps CI Go to 1.26 and kind to v0.27.0. |
Files not reviewed (1)
- api/v1alpha1/zz_generated.deepcopy.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- consumer webhook: drop the key-auth credential value from the duplicate-key
error so secret material is not leaked to API clients and logs.
- gateway status: reuse a previous listener status only when the listener name
also matches, so reordered spec.listeners cannot publish another listener's
status under the wrong name.
- KindOf: return ReferenceGrant for *gatewayv1beta1.ReferenceGrant so
GvkOf(&ReferenceGrant{}) no longer yields kind Unknown.
- frontendValidation: resolve downstream mTLS only for TLS-terminating listeners
(HTTPS/TLS), never for plaintext listeners.
…oute attachment - frontendValidation now resolves for HTTPS listeners only (spec.tls.frontend applies to HTTPS in Gateway API v1.6), in both the translator and status paths, so a TLS listener no longer gets downstream mTLS attached. - Reject frontendValidation mode AllowInsecureFallback: APISIX can only enforce strict client-cert verification, so program an error instead of silently doing the opposite (strict) behaviour. - Frontend CA validation now sets Accepted=False/NoValidCACertificate when no CA ref resolves, and uses InvalidCACertificateRef/InvalidCACertificateKind reasons; a single valid ref keeps the listener Accepted. - Route attachment: listeners on a port with a conflicting tls.mode are now ineligible in ParseRouteParentRefs and report zero attached routes, so a route cannot be programmed on a listener that reports Accepted=False/Programmed=False. - ParseRouteParentRefs selects the parent reason after evaluating all listeners, so the result is independent of listener order.
…d on the listener The translator already rejects the unsupported AllowInsecureFallback mode, but the listener status path did not, so a listener would report Programmed=True while its translation fails. Surface the unsupported mode as Programmed=False on the listener status so it matches the translation outcome.
The Gateway API 1.6 upgrade pulled google.golang.org/grpc from 1.71.1 to 1.81.1, which is flagged high severity (GHSA-hrxh-6v49-42gf: xDS RBAC and HTTP/2 vulnerabilities). Bump to the patched 1.82.1; only genproto is pulled along, build/tests/lint unaffected. Ports apache/apisix-ingress-controller#2804 (927a9150) to keep the two branches in sync.
… only frontendValidation mode AllowInsecureFallback is an Extended feature that APISIX cannot express: setting a client CA turns on ssl_verify_client and verification is all-or-nothing per SSL object, with no way to request a client certificate without enforcing it. Upstream tracks it as its own conformance feature (GatewayFrontendClientCertificateValidationInsecureFallback), so declining it is a supported choice; how it was declined was the problem. Three fixes: - translateFrontendValidation returned a plain error, which propagated through translateSecret and TranslateGateway up to Provider.Update and aborted the sync. A single listener - or a single per-port override - therefore stopped every SSL object, global rule and plugin metadata for the whole Gateway, while the status blamed only that one listener. The mode now yields a sentinel handled in translateSecret, which emits no SSL for that listener and leaves the rest of the Gateway alone. Serving TLS without the requested client validation would be less safe than serving nothing, so the listener is programmed with neither. - The listener reported Programmed=False/Invalid while Accepted stayed True. Gateway API v1.6 has a reason for exactly this case: a value the implementation does not support is Accepted=False/UnsupportedValue. - The early return skipped CA reference validation entirely, so a missing or malformed CA was hidden behind ResolvedRefs=True. The refs are now validated regardless of mode, and the more specific UnsupportedValue is kept instead of being overwritten by NoValidCACertificate. InsecureFrontendValidationMode is deliberately not set: that Gateway condition signals that an implementation is honouring the insecure mode, which is the opposite of what happens here.
Type of change:
What this PR does / why we need it:
The bump pulls in
k8s.iov0.36 andcontroller-runtimev0.24 (both require Go 1.26), so thegodirective and CI Go version are bumped to 1.26.Gateway API v1.6 API changes handled:
listener.tls.frontendValidation) to the Gateway level (spec.tls.frontend). The validation that applies to each HTTPS listener is now resolved by port (perPortoverridesdefault) in the gateway translator, indexer, and status/reconcile paths.listener.TLStype renamedGatewayTLSConfig→ListenerTLSConfig.HTTPCORSFilter.AllowCredentialsis now*bool.Policy*condition/reason constants graduated toapis/v1; usages switched offv1alpha2.PortNumberis now an alias ofint32; redundant conversions dropped.controller-runtime v0.24 changes handled:
NewWebhookManagedBy[runtime.Object](mgr, obj)+ typedValidator[T]API.Conformance:
test/conformanceandtest/conformance/api7ee) rewritten for the v1.6 conformance-module API (RunConformanceWithOptions, report viaReportOutputPath).Tooling:
golangci-lintis built from source with the local toolchain and the lint target Go version is pinned, since the released binary cannot type-check a Go 1.26 module.scheme.Builderscaffold,corev1.Endpoints).Pre-submission checklist:
frontendValidationfrom the listener togateway.spec.tls.frontend, following the upstream Gateway API 1.6 change.Summary by CodeRabbit
Summary
allowCredentialsis set.kindv0.27,golangci-lintv2.7.x) and refreshed Gateway API CRDstatus.ancestorsschema requirements/semantics.