Skip to content

feat: support Gateway API 1.6.0#431

Open
AlinsRan wants to merge 9 commits into
masterfrom
feat/gateway-api-1.6.0
Open

feat: support Gateway API 1.6.0#431
AlinsRan wants to merge 9 commits into
masterfrom
feat/gateway-api-1.6.0

Conversation

@AlinsRan

@AlinsRan AlinsRan commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Type of change:

  • New feature provided
  • CI/CD or Tests

What this PR does / why we need it:

The bump pulls in k8s.io v0.36 and controller-runtime v0.24 (both require Go 1.26), so the go directive and CI Go version are bumped to 1.26.

Gateway API v1.6 API changes handled:

  • Frontend mTLS validation moved from the per-listener TLS config (listener.tls.frontendValidation) to the Gateway level (spec.tls.frontend). The validation that applies to each HTTPS listener is now resolved by port (perPort overrides default) in the gateway translator, indexer, and status/reconcile paths.
  • listener.TLS type renamed GatewayTLSConfigListenerTLSConfig.
  • HTTPCORSFilter.AllowCredentials is now *bool.
  • Policy status/target types and Policy* condition/reason constants graduated to apis/v1; usages switched off v1alpha2.
  • PortNumber is now an alias of int32; redundant conversions dropped.

controller-runtime v0.24 changes handled:

  • Webhook builder migrated to the generic NewWebhookManagedBy[runtime.Object](mgr, obj) + typed Validator[T] API.

Conformance:

  • Both suites (test/conformance and test/conformance/api7ee) rewritten for the v1.6 conformance-module API (RunConformanceWithOptions, report via ReportOutputPath).

Tooling:

  • golangci-lint is 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.
  • SA1019 suppressed for intentional legacy usage the k8s v0.36 bump now flags (scheme.Builder scaffold, corev1.Endpoints).

Pre-submission checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • Have you added corresponding test cases? (existing unit + conformance suites updated)
  • Have you modified the corresponding document?
  • Is this PR backward compatible? Downstream mTLS users must move frontendValidation from the listener to gateway.spec.tls.frontend, following the upstream Gateway API 1.6 change.

Summary by CodeRabbit

Summary

  • New Features
    • Added Gateway API v1.6 compatibility, including Gateway-level frontend mTLS validation with per-port overrides.
  • Bug Fixes
    • Improved CORS behavior so credentials are only enabled when allowCredentials is set.
    • Refined backend service port matching and policy ancestor/condition status reporting.
  • Chores
    • Updated CI/tooling versions (Go 1.26, kind v0.27, golangci-lint v2.7.x) and refreshed Gateway API CRD status.ancestors schema requirements/semantics.

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).
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The 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.

Changes

Gateway API v1.6 migration

Layer / File(s) Summary
Toolchain and dependency updates
.github/workflows/*, .golangci.yml, Makefile, go.mod
CI uses Go 1.26 and kind v0.27.0, Gateway API is updated to v1.6.0, golangci-lint is updated to v2.7.1, and module dependencies are refreshed.
Policy API contracts and CRD schemas
api/v1alpha1/*, config/crd/bases/*
Policy references and status types use Gateway API v1, generated deepcopy code is updated, and ancestor status schemas document atomic lists and required fields.
Gateway-level frontend mTLS resolution
internal/adc/translator/*, internal/controller/*, internal/provider/provider.go
Frontend validation is resolved from Gateway defaults or per-port overrides and used for translation, listener processing, indexing, and TLS configuration.
Route translation and policy status migration
internal/adc/translator/*, internal/controller/*, internal/types/k8s.go
Backend port handling removes obsolete casts, policy condition and ancestor handling use v1 types, and Gateway API GVK construction is updated.
Typed validating webhook registration
internal/webhook/v1/*
Webhook builders use generic controller-runtime registration and validators assert admission.Validator[runtime.Object].
Conformance and end-to-end validation
test/conformance/*, test/e2e/*, internal/webhook/v1/*_test.go
Conformance tests call the Gateway API runner directly, preserve existing skips, and update policy and TLS test fixtures to Gateway API v1 types.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: nic-6443, shreemaan-abhishek


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Security Check ❌ Error consumer_webhook.go:177 returns the raw key-auth credential value in a duplicate-error, exposing secret material to API clients. Drop the key from the error; compare/hint on a hash or opaque ID and return only a generic duplicate-credential message.
E2e Test Quality Review ⚠️ Warning The new downstream-mTLS E2E only inspects the dataplane SSL object; it never exercises a real client handshake or perPort/default resolution, so the key v1.6 flow isn’t fully covered. Add request-level handshake assertions (with and without client cert) and a perPort-vs-default override case; replace fixed sleeps with polling on resource readiness.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: upgrading support to Gateway API 1.6.0.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/gateway-api-1.6.0

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
internal/adc/translator/gateway_test.go (1)

46-78: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

No test coverage for the PerPort override branch of frontendTLSValidation.

All test cases exercise only Spec.TLS.Frontend.Default.Validation; none exercise PerPort matching/override or the case where a PerPort entry exists for the port but has no Validation (which, per spec, must NOT fall back to Default). 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

📥 Commits

Reviewing files that changed from the base of the PR and between 5f84a00 and ed6bb92.

⛔ Files ignored due to path filters (1)
  • go.sum is 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.yml
  • Makefile
  • api/v1alpha1/httproutepolicy_types.go
  • api/v1alpha1/l4routepolicy_types.go
  • api/v1alpha1/policies_type.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml
  • config/crd/bases/apisix.apache.org_httproutepolicies.yaml
  • config/crd/bases/apisix.apache.org_l4routepolicies.yaml
  • go.mod
  • internal/adc/translator/apisixroute.go
  • internal/adc/translator/gateway.go
  • internal/adc/translator/gateway_test.go
  • internal/adc/translator/gatewayproxy.go
  • internal/adc/translator/grpcroute.go
  • internal/adc/translator/httproute.go
  • internal/adc/translator/httproute_test.go
  • internal/adc/translator/l4routepolicy_test.go
  • internal/adc/translator/policies.go
  • internal/adc/translator/tcproute.go
  • internal/adc/translator/tlsroute.go
  • internal/adc/translator/udproute.go
  • internal/controller/gateway_controller.go
  • internal/controller/gatewayclass_controller.go
  • internal/controller/grpcroute_controller.go
  • internal/controller/httproute_controller.go
  • internal/controller/httproutepolicy.go
  • internal/controller/indexer/indexer.go
  • internal/controller/policies.go
  • internal/controller/status.go
  • internal/controller/tcproute_controller.go
  • internal/controller/tlsroute_controller.go
  • internal/controller/udproute_controller.go
  • internal/controller/utils.go
  • internal/provider/provider.go
  • internal/types/k8s.go
  • internal/webhook/v1/apisixconsumer_webhook.go
  • internal/webhook/v1/apisixroute_webhook.go
  • internal/webhook/v1/apisixtls_webhook.go
  • internal/webhook/v1/consumer_webhook.go
  • internal/webhook/v1/gateway_webhook.go
  • internal/webhook/v1/gateway_webhook_test.go
  • internal/webhook/v1/gatewayproxy_webhook.go
  • internal/webhook/v1/grpcroute_webhook.go
  • internal/webhook/v1/httproute_webhook.go
  • internal/webhook/v1/ingress_webhook.go
  • internal/webhook/v1/ingressclass_webhook.go
  • internal/webhook/v1/ssl/conflict_detector_test.go
  • internal/webhook/v1/tcproute_webhook.go
  • internal/webhook/v1/udproute_webhook.go
  • test/conformance/api7ee/conformance_test.go
  • test/conformance/conformance_test.go
  • test/e2e/gatewayapi/httproute.go
  • test/e2e/gatewayapi/tcproute.go
  • test/e2e/scaffold/k8s.go

Comment on lines +147 to +163
// 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
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 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: replace frontendTLSValidation with a call to a shared helper (e.g. exported from a common package) that returns the Gateway's *FrontendTLSConfig or resolves per-listener validation.
  • internal/controller/gateway_controller.go#L466-L481: replace frontendTLSValidationForListener with 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) inside gatewayFrontendValidations, 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-L481
  • internal/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.

Comment thread internal/types/k8s.go
Comment on lines +155 to +159
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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,260p' internal/types/k8s.go

Repository: api7/api7-ingress-controller

Length of output: 7527


🏁 Script executed:

rg -n "ReferenceGrant|KindOf\\(" internal -S

Repository: api7/api7-ingress-controller

Length of output: 10428


Handle ReferenceGrant in KindOfGvkOf(&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.

Comment thread Makefile
CONTROLLER_TOOLS_VERSION ?= v0.17.2
ENVTEST_VERSION ?= release-0.18
GOLANGCI_LINT_VERSION ?= v2.1.5
GOLANGCI_LINT_VERSION ?= v2.7.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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' Makefile

Repository: 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:


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.

AlinsRan added 6 commits July 15, 2026 17:57
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.
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

conformance test report - apisix-standalone mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-16T03:20:19Z"
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:
    - HTTPRouteInvalidBackendRefUnknownKind
    - 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:
    result: success
    statistics:
      Failed: 0
      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
  name: GATEWAY-GRPC
  summary: Core tests succeeded. Extended tests succeeded.
- core:
    failedTests:
    - TLSRouteHostnameIntersection
    - TLSRouteInvalidBackendRefNonexistent
    - TLSRouteInvalidBackendRefUnknownKind
    - TLSRouteInvalidNoMatchingListener
    - TLSRouteInvalidNoMatchingListenerHostname
    - TLSRouteListenerPassthroughSupportedKinds
    - TLSRouteListenerTerminateNotSupported
    result: failure
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 7
      Passed: 12
      Skipped: 1
  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 7 test failures. Extended tests succeeded.
succeededProvisionalTests:
- GatewayOptionalAddressValue

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

conformance test report - apisix mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-16T03:20:03Z"
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:
    - HTTPRouteInvalidBackendRefUnknownKind
    - 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:
    result: success
    statistics:
      Failed: 0
      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
  name: GATEWAY-GRPC
  summary: Core tests succeeded. Extended tests succeeded.
- core:
    failedTests:
    - TLSRouteHostnameIntersection
    - TLSRouteInvalidBackendRefNonexistent
    - TLSRouteInvalidBackendRefUnknownKind
    - TLSRouteInvalidNoMatchingListener
    - TLSRouteInvalidNoMatchingListenerHostname
    - TLSRouteListenerPassthroughSupportedKinds
    - TLSRouteListenerTerminateNotSupported
    result: failure
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 7
      Passed: 12
      Skipped: 1
  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 7 test failures. Extended tests succeeded.
succeededProvisionalTests:
- GatewayOptionalAddressValue

AlinsRan added 2 commits July 16, 2026 10:08
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant