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
| // frontendTLSValidation resolves the Gateway-level frontend TLS client-cert | ||
| // validation that applies to the given HTTPS listener. In Gateway API v1.6, | ||
| // frontendValidation moved from the per-listener TLS config to the Gateway-level | ||
| // spec.tls.frontend: Default applies to all HTTPS listeners, and a PerPort entry | ||
| // overrides it for listeners on the matching port. | ||
| func frontendTLSValidation(obj *gatewayv1.Gateway, listener gatewayv1.Listener) *gatewayv1.FrontendTLSValidation { | ||
| if obj.Spec.TLS == nil || obj.Spec.TLS.Frontend == nil { | ||
| return nil | ||
| } | ||
| frontend := obj.Spec.TLS.Frontend | ||
| for i := range frontend.PerPort { | ||
| if frontend.PerPort[i].Port == listener.Port { | ||
| return frontend.PerPort[i].TLS.Validation | ||
| } | ||
| } | ||
| return frontend.Default.Validation | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Extract shared helper for Gateway-level frontend TLS config access. Three separate implementations read gateway.Spec.TLS.Frontend with the same nil-guard and PerPort-walk pattern; keeping them in sync manually risks divergence in this security-relevant (mTLS trust-anchor) resolution path.
internal/adc/translator/gateway.go#L147-L163: replacefrontendTLSValidationwith a call to a shared helper (e.g. exported from a common package) that returns the Gateway's*FrontendTLSConfigor resolves per-listener validation.internal/controller/gateway_controller.go#L466-L481: replacefrontendTLSValidationForListenerwith the same shared helper instead of re-implementing the PerPort/Default resolution.internal/controller/indexer/indexer.go#L643-L660: reuse the shared accessor (e.g. to get*FrontendTLSConfig) insidegatewayFrontendValidations, then collect Default+PerPort locally, instead of re-deriving the nil-guard independently.
📍 Affects 3 files
internal/adc/translator/gateway.go#L147-L163(this comment)internal/controller/gateway_controller.go#L466-L481internal/controller/indexer/indexer.go#L643-L660
🤖 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.go` around lines 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.
| return schema.GroupVersion(gatewayv1.GroupVersion).WithKind(kind) | ||
| case *gatewayv1alpha2.TCPRoute, *gatewayv1alpha2.UDPRoute, *gatewayv1alpha2.TLSRoute: | ||
| return gatewayv1alpha2.SchemeGroupVersion.WithKind(kind) | ||
| return schema.GroupVersion(gatewayv1alpha2.GroupVersion).WithKind(kind) | ||
| case *gatewayv1beta1.ReferenceGrant: | ||
| return gatewayv1beta1.SchemeGroupVersion.WithKind(kind) | ||
| return schema.GroupVersion(gatewayv1beta1.GroupVersion).WithKind(kind) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
sed -n '1,260p' internal/types/k8s.goRepository: api7/api7-ingress-controller
Length of output: 7527
🏁 Script executed:
rg -n "ReferenceGrant|KindOf\\(" internal -SRepository: api7/api7-ingress-controller
Length of output: 10428
Handle ReferenceGrant in KindOf — GvkOf(&gatewayv1beta1.ReferenceGrant{}) currently returns gateway.networking.k8s.io/v1beta1 with kind Unknown. Add the missing *gatewayv1beta1.ReferenceGrant case before relying on this branch.
🤖 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/types/k8s.go` around lines 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.
| CONTROLLER_TOOLS_VERSION ?= v0.17.2 | ||
| ENVTEST_VERSION ?= release-0.18 | ||
| GOLANGCI_LINT_VERSION ?= v2.1.5 | ||
| GOLANGCI_LINT_VERSION ?= v2.7.1 |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n 'GOLANGCI_LINT_VERSION|golangci-lint/v2/cmd' Makefile
curl -fsSL https://api.github.com/repos/golangci/golangci-lint/pulls/6271 \
| jq -e '.merged_at != null'
curl -fsSL https://api.github.com/repos/golangci/golangci-lint/releases/tags/v2.9.0 \
| jq -e '.tag_name == "v2.9.0"'Repository: api7/api7-ingress-controller
Length of output: 379
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
sed -n '368,408p' MakefileRepository: api7/api7-ingress-controller
Length of output: 1774
🌐 Web query:
golangci-lint v2.7.1 Go 1.26 support v2.9.0 changelog
💡 Result:
Golangci-lint version 2.9.0, released on February 10, 2026, officially introduced support for Go 1.26 [1][2]. Regarding golangci-lint v2.7.1: This version was released on December 4, 2025 [3]. It does not include support for Go 1.26, as that support was added in the later v2.9.0 release [1][2]. As a general rule, golangci-lint supports Go versions lower than or equal to the version of Go used to compile the specific binary [4][5][6]. To check the Go version used to build your currently installed version of golangci-lint, you can run the command golangci-lint version [5].
Citations:
- 1: https://github.com/golangci/golangci-lint/releases/tag/v2.9.0
- 2: https://github.com/golangci/golangci-lint/blob/ab192139/CHANGELOG.md
- 3: https://github.com/golangci/golangci-lint/releases/tag/v2.7.1
- 4: https://golangci-lint.run/docs/welcome/faq/
- 5: go1.27 support golangci/golangci-lint#6643
- 6: go1.23 support golangci/golangci-lint#4837
Bump GOLANGCI_LINT_VERSION to a Go 1.26-capable release.
v2.7.1 predates Go 1.26 support; pin v2.9.0 or later so the source-built golangci-lint can type-check this module.
🤖 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 `@Makefile` at 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.
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-20T08:41:31Z"
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 |
conformance test report - apisix modeapiVersion: gateway.networking.k8s.io/v1
date: "2026-07-20T08:41:53Z"
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-20T04:47:08Z"
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:
result: success
statistics:
Failed: 0
Passed: 1
Skipped: 0
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
unsupportedFeatures:
- GatewayBackendClientCertificate
- GatewayFrontendClientCertificateValidation
- GatewayFrontendClientCertificateValidationInsecureFallback
- GatewayHTTPListenerIsolation
- GatewayHTTPSListenerDetectMisdirectedRequests
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- ListenerSet
- TLSRouteModeMixed
- TLSRouteModeTerminate
name: GATEWAY-TLS
summary: Core tests failed with 5 test failures. Extended tests succeeded.
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.
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.