Skip to content

Add Gateway API (HTTPRoute) support to Console Helm chart and CRD#1329

Open
david-yu wants to merge 18 commits intomainfrom
1308-add-gateway-support-to-console-helm-chart
Open

Add Gateway API (HTTPRoute) support to Console Helm chart and CRD#1329
david-yu wants to merge 18 commits intomainfrom
1308-add-gateway-support-to-console-helm-chart

Conversation

@david-yu
Copy link
Copy Markdown
Contributor

@david-yu david-yu commented Mar 20, 2026

Summary

Adds support for Kubernetes Gateway API HTTPRoute resources to the Console chart and operator, allowing users to expose Console via Gateway API controllers (e.g. Envoy Gateway, Istio, Cilium) as an alternative to classic Ingress.

Closes #1308
Supersedes #1309 (recreated from upstream branch for CI)

Original chart work by @w1ndhunter.

Prerequisites

Gateway API CRDs must be installed in your cluster before enabling this feature. The CRDs are not bundled with the Redpanda Helm chart or operator — they are maintained by the Kubernetes Gateway API project.

Install Gateway API CRDs

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml

Install a Gateway controller

You also need a Gateway API-compatible controller running in your cluster. Common options include:

Create a Gateway resource that the HTTPRoute will attach to:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
  namespace: gateway-system
spec:
  gatewayClassName: eg  # varies by controller
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: my-tls-cert

Changes

Console Helm Chart

  • New gateway values block alongside existing ingress block
  • New gateway.go with HTTPRoute() rendering function
  • HTTPRoute added to Render() manifest list and Types() scheme registration
  • gatewayv1.Install(Scheme) for Gateway API type serialization
  • Updated notes.go to show Gateway URLs (mutually exclusive with Ingress)
  • Validation in NewRenderState rejects both gateway and ingress enabled simultaneously
  • New test cases: gateway-only, mutual exclusion validation, gateway removal/switch scenarios
  • Regenerated schema, golden files, and templates

Operator (Console CRD)

  • New GatewayConfig and GatewayParentReference types in console_types.go
  • Gateway field added to ConsoleValues and RedpandaConsole structs
  • Auto-generated conversion (goverter) from CRD types → chart partial values
  • RBAC: added gateway.networking.k8s.io/httproutes permissions
  • Registered gatewayv1 types in V2 scheme
  • Bumped sigs.k8s.io/gateway-api from v1.4.1 → v1.5.1
  • Regenerated deepcopy, conversion, and CRD manifests
  • HTTPRoute watch is skipped gracefully when Gateway API CRDs are not installed

Console Controller Tests — Gateway API CRD Loading ⚠️

Reviewer note: The console controller test (operator/internal/controller/console/controller_test.go) now loads Gateway API CRDs from the sigs.k8s.io/gateway-api Go module cache at test time. This is needed because envtest must have the HTTPRoute CRD installed for the controller to reconcile gateway-enabled Console objects (list HTTPRoutes, create/delete them).

The loadGatewayAPICRDs helper resolves the module directory via go list -m -f {{.Dir}} sigs.k8s.io/gateway-api, reads all standard CRD YAMLs from config/crd/standard/, and parses them. Non-CRD files (e.g. ValidatingAdmissionPolicy) are skipped gracefully.

This approach avoids vendoring the ~7K-line HTTPRoute CRD YAML into testdata while keeping the CRD version in sync with go.mod.

Bug Fix: InUseServerCerts external TLS cert mounting

  • Fixed InUseServerCerts in charts/redpanda/values.go (and operator/multicluster/values.go) where a continue statement on the internal listener's TLS check would skip registering external sub-listener certs. External certs are now checked independently of internal TLS state.

Usage Examples

Helm Chart — Gateway API

# 1. Install Gateway API CRDs (if not already installed)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml

# 2. Install Console with gateway enabled
helm install console redpanda/console -f values.yaml
# values.yaml
gateway:
  enabled: true
  annotations:
    example.com/owner: my-team
  parentRefs:
    - name: my-gateway
      namespace: gateway-system
      sectionName: https
  hostnames:
    - console.example.com
  path: /
  pathType: PathPrefix

Helm Chart — Classic Ingress (unchanged)

# values.yaml
ingress:
  enabled: true
  hosts:
    - host: console.example.com
      paths:
        - path: /
          pathType: Prefix

Note: Enabling both ingress.enabled: true and gateway.enabled: true will fail with: ingress and gateway cannot both be enabled; use one or the other

Console CRD (Operator) — Gateway API

# 1. Install Gateway API CRDs (if not already installed)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml

# 2. Apply the Console CR with gateway enabled
kubectl apply -f console.yaml
# console.yaml
apiVersion: cluster.redpanda.com/v1alpha2
kind: Console
metadata:
  name: my-console
  namespace: redpanda
spec:
  clusterSource:
    clusterRef:
      name: my-cluster
  gateway:
    enabled: true
    annotations:
      example.com/owner: my-team
    parentRefs:
      - name: my-gateway
        namespace: gateway-system
        sectionName: https
    hostnames:
      - console.example.com
    path: /
    pathType: PathPrefix

Console CRD (Operator) — Switching from Gateway to Ingress

To switch, remove the gateway stanza and add ingress:

apiVersion: cluster.redpanda.com/v1alpha2
kind: Console
metadata:
  name: my-console
  namespace: redpanda
spec:
  clusterSource:
    clusterRef:
      name: my-cluster
  ingress:
    enabled: true
    hosts:
      - host: console.example.com
        paths:
          - path: /
            pathType: Prefix

The operator will remove the HTTPRoute and create an Ingress instead.

Test plan

  • go build ./... passes in operator/ and charts/console/
  • go test ./... passes in charts/console/ — includes:
    • TestIngressGatewayMutualExclusion — both enabled → error
    • TestGatewayRemoval/gateway_removed_from_config — no gateway stanza → no HTTPRoute
    • TestGatewayRemoval/gateway_explicitly_disabledenabled: false → no HTTPRoute
    • TestGatewayRemoval/switch_from_gateway_to_ingress — gateway→ingress produces Ingress, no HTTPRoute
    • TestTemplate golden tests (gateway-templating case)
  • Console controller tests pass with Gateway API CRDs loaded into envtest
    • TestController/gateway-enabled — basic gateway with parentRefs
    • TestController/gateway-custom-path — custom path and multiple parentRefs
  • CRD schema includes gateway field with correct OpenAPI validation
  • Deploy Console CRD with gateway.enabled: true → HTTPRoute created
  • Deploy via Helm with gateway.enabled: true → HTTPRoute created
  • Enabling both ingress and gateway → validation error

🤖 Generated with Claude Code

w1ndhunter and others added 5 commits March 16, 2026 17:44
- Add GatewayConfig and GatewayParentReference types to console_types.go
- Add Gateway field to ConsoleValues and RedpandaConsole structs
- Add RBAC permission for gateway.networking.k8s.io/httproutes
- Register gatewayv1 types in V2 scheme
- Bump sigs.k8s.io/gateway-api from v1.4.1 to v1.5.1
- Regenerate deepcopy and goverter conversion code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add validation in NewRenderState to reject both gateway and ingress enabled
- Update notes.go to use else-if for gateway vs ingress
- Remove ingress-and-gateway-templating test case (no longer valid)
- Add TestIngressGatewayMutualExclusion test
- Add TestGatewayRemoval tests (config removal, explicit disable, switch)
- Add changelog entries for console chart and operator

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
david-yu and others added 11 commits March 20, 2026 12:57
Chart-level tests (TestGatewayConfigFields):
- hostnames: set and change hostnames
- path/pathType: set custom path, change path, default PathPrefix
- annotations: set, change, verify old keys removed
- parentRefs: all fields, name-only, multiple refs, change refs
- backend service port derived from service config

CRD-level tests (TestController):
- gateway-enabled: Console CRD with gateway config renders HTTPRoute
- gateway-custom-path: multiple hostnames, custom path, multiple parentRefs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Run `go work sync` to propagate gateway-api v1.5.1 to all modules
- Regenerate console chart golden txtar with correct gateway-templating output
- Fix lint alignment in render_test.go (Enabled field spacing)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Regenerate CRDs, deepcopy, RBAC, and schema for gateway API support
- Fix InUseServerCerts to not skip external listener certs when internal
  TLS is disabled (the original bug fix for values.go)
- Add Gateway API CRD loading in console controller tests so envtest
  can handle HTTPRoute resources
- Update lifecycle and controller golden test files
- Run go mod tidy across all modules
- Regenerate crd-docs.adoc

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve conflict: accept deletion of operator/multicluster/values.go
(removed in main by commit 16dcf9d). The InUseServerCerts bug fix
now only lives in charts/redpanda/values.go.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… CRDs missing

- Regenerate operator/chart/testdata/template-cases.golden.txtar to
  include the new gateway.networking.k8s.io httproutes RBAC rules added
  to console.ClusterRole.yaml.

- Skip watching HTTPRoute resources when Gateway API CRDs are not
  installed in the cluster, following the same pattern used for
  ServiceMonitor. This prevents the operator from crashing at startup
  in environments without Gateway API (e.g. kuttl test clusters).

- Generalize skipServiceMonitorWatchIfNotInstalled into a reusable
  skipWatchIfNotInstalled method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move common-go/kube/kubetest to the third-party import group where gci
expects it (not the redpanda-operator prefix group).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The gotohelm-generated template was stale after the InUseServerCerts
refactor in values.go.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The InUseServerCerts refactor in values.go now correctly includes
external listener certs when internal TLS is disabled. This updates
the golden test output to reflect the additional cert mounts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update licenses/third_party.md for gomega v1.39.1 and gateway-api v1.5.1
- Regenerate lifecycle golden files with CI env vars (TEST_REDPANDA_REPO
  and TEST_REDPANDA_VERSION) so they match CI-rendered output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restore common-go/kube/kubetest to the redpanda-operator import group
as requested by RafalKorepta.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove mutual exclusion validation so both Ingress and HTTPRoute can be
enabled simultaneously, enabling gradual traffic migration from Ingress
to Gateway API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

This PR is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the stale label Apr 5, 2026
@david-yu david-yu removed the stale label Apr 6, 2026
@github-actions
Copy link
Copy Markdown

This PR is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the stale label Apr 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Gateway API support in Console Helm chart (alongside Ingress)

3 participants