Skip to content

feat: support Gateway API 1.6.0#431

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

feat: support Gateway API 1.6.0#431
AlinsRan wants to merge 23 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 thread internal/adc/translator/gateway.go
Comment thread internal/types/k8s.go
Comment thread Makefile
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-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

@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-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

AlinsRan added 4 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.
…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.
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

conformance test report

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

AlinsRan added 3 commits July 20, 2026 13:05
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.
@AlinsRan
AlinsRan force-pushed the feat/gateway-api-1.6.0 branch from d2709c4 to 97e5b0d Compare July 20, 2026 07:32
AlinsRan added 4 commits July 20, 2026 15:47
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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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, PortNumber alias changes, CORS allowCredentials pointer 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.

Comment thread internal/controller/utils.go
Comment thread internal/adc/translator/gateway.go
Comment thread test/e2e/scaffold/tunnel.go
Comment thread test/e2e/scaffold/tunnel.go
Comment thread .golangci.yml
AlinsRan added 3 commits July 23, 2026 08:50
- 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.
AlinsRan and others added 2 commits July 23, 2026 17:33
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.
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.

2 participants