Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
3c13e5e
wip
smatting Mar 9, 2026
0e32863
checkboxes
smatting Mar 9, 2026
9487700
mention nginx-ingress-services in the backwards compatbility section
smatting Mar 9, 2026
466b51b
scaffolding + helpers
smatting Mar 9, 2026
c3fb370
modify .envrc for development
smatting Mar 9, 2026
aa46978
update plan
smatting Mar 10, 2026
9404385
phase 2-3
smatting Mar 10, 2026
7c6c5d6
Allow for externally created secret
smatting Mar 12, 2026
357edd5
nginz routes
smatting Mar 12, 2026
ad89047
more routes
smatting Mar 13, 2026
f2f4e3c
Adjust plan: routes together with services
smatting Mar 13, 2026
2af357a
team settings and account pages
smatting Mar 13, 2026
7e27e06
fake-s3 route
smatting Mar 13, 2026
b2a50c4
complete federator phase
smatting Mar 16, 2026
c2ba573
use different secret name for federators certificate
smatting Mar 17, 2026
0fb6404
udpate plan notes for federation helper
smatting Mar 17, 2026
2106e42
wip integrations tests
smatting Mar 17, 2026
d565e87
Add post-upgrade hook to all tests
smatting Mar 18, 2026
6a77715
use type: ClusterIP on gateway instead of LoadBlancer, use port 10443
smatting Mar 18, 2026
47888ec
make mtls client cert validation optional at the ingress level
smatting Mar 18, 2026
ae2bd53
add todo
smatting Mar 18, 2026
f3f6d88
support sharing envoyproxy objects
smatting Mar 19, 2026
91c7f98
remove skipPriviledgedPortCheck
smatting Mar 19, 2026
0772c5a
integration chart: remove ingress (and service targeting ingress)
smatting Mar 19, 2026
59a3fd2
complete todo
smatting Mar 19, 2026
b0931a1
drop customSolversSecrets
smatting Mar 19, 2026
8f74de5
update README
smatting Mar 19, 2026
abf7f54
add TODO
smatting Mar 19, 2026
76a48ee
integration tests: fix originDomains
smatting Mar 19, 2026
2b1fa53
add go.sh
smatting Mar 20, 2026
ed723b6
force explicit hostnames in gateway listeners
smatting Mar 20, 2026
fa24187
fix trailing dot problem of integration tests.
smatting Mar 20, 2026
d989c8d
remove unused ExternalName service from previous attempts
smatting Mar 20, 2026
b23471b
Revert "integration chart: remove ingress (and service targeting ingr…
smatting Mar 20, 2026
62df1dd
wip integration envoy
smatting Mar 23, 2026
d014c4f
fix (workaround): [emerg] 850#850: too long path in the unix domain …
smatting Mar 23, 2026
12c652e
wip
smatting Mar 23, 2026
16ac8c7
use new build in go.sh
smatting Mar 23, 2026
6ab8ec0
run all tests
smatting Mar 23, 2026
75795d1
add TODOs
smatting Mar 24, 2026
a4f54a4
make ingress mode configurable for integration tests
smatting Mar 24, 2026
bc99a36
replace envoy-gateway-system hardcoded name with var
smatting Mar 24, 2026
1735bb4
envoy patch policies
smatting Mar 24, 2026
60aa86f
rename federation-test-helper.yaml to service-test-fed.yaml
smatting Mar 24, 2026
66382bd
update parameter documentation
smatting Mar 24, 2026
e9cb81a
use a different patch policy to support the FQDMs
smatting Mar 24, 2026
e1e3169
test envoy by default
smatting Mar 24, 2026
457f1d7
follow-up to patch policies: make configurable
smatting Mar 25, 2026
c34eeb7
update envoypatchpolicy section
smatting Mar 25, 2026
329198f
wip migration guide
smatting Mar 25, 2026
373bc43
polish a bit
smatting Mar 25, 2026
a6da965
move planning out of readme
smatting Mar 25, 2026
caf3618
small corrections
smatting Mar 25, 2026
e6d9479
revert to normal
smatting Mar 25, 2026
b57c883
remove unused file
smatting Mar 25, 2026
dba41cc
revert file
smatting Mar 25, 2026
d5a92ef
update comment
smatting Mar 25, 2026
fb06b53
rename file ingress-envoy.aml to envoy-gateway.yaml
smatting Mar 25, 2026
6fce96e
add missing backentrafficpolicy to support websockets
smatting Mar 25, 2026
a51ed9e
remove CLAUDE.md
smatting Mar 25, 2026
f5b4422
moved todo to ticket
smatting Mar 25, 2026
d27cf75
prevent any untested changes to the nginx-ingress-services chart
smatting Mar 27, 2026
1206c78
remove PLAN.md
smatting Mar 27, 2026
a59a6c7
add changelog entry
smatting Mar 27, 2026
300c32e
Prevent spoofing of the X-SSL-Certificate header
smatting Apr 29, 2026
249e3b5
fix: remove unused arg
smatting Apr 29, 2026
adc4668
integration tests: Prevent spoofing of the X-SSL-Certificate header
smatting Apr 29, 2026
d9dac75
Set namespace consitently
smatting Apr 29, 2026
196c682
apply labels consitenly
smatting Apr 29, 2026
7f220cc
leave comments to keep service names in-sync
smatting Apr 29, 2026
0377f36
Fix spelling
smatting Apr 29, 2026
05e23ad
integration tests: solve trailing dot same way as rest
smatting Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ DOCKER_TAG ?= $(USER)
# default helm chart version must be 0.0.42 for local development (because 42 is the answer to the universe and everything)
HELM_SEMVER ?= 0.0.42
# The list of helm charts needed on internal kubernetes testing environments
CHARTS_INTEGRATION := wire-server databases-ephemeral rabbitmq fake-aws ingress-nginx-controller nginx-ingress-services fluent-bit kibana k8ssandra-test-cluster wire-server-enterprise
CHARTS_INTEGRATION := wire-server databases-ephemeral rabbitmq fake-aws ingress-nginx-controller nginx-ingress-services wire-ingress fluent-bit kibana k8ssandra-test-cluster wire-server-enterprise
# The list of helm charts to publish on S3
# FUTUREWORK: after we "inline local subcharts",
# (e.g. move charts/brig to charts/wire-server/brig)
Expand All @@ -18,7 +18,8 @@ fake-aws fake-aws-s3 fake-aws-sqs aws-ingress fluent-bit kibana backoffice \
calling-test demo-smtp elasticsearch-curator elasticsearch-external \
elasticsearch-ephemeral minio-external cassandra-external \
ingress-nginx-controller nginx-ingress-services reaper \
k8ssandra-test-cluster ldap-scim-bridge wire-server-enterprise
k8ssandra-test-cluster ldap-scim-bridge wire-server-enterprise \
wire-ingress
KIND_CLUSTER_NAME := wire-server
HELM_PARALLELISM ?= 1 # 1 for sequential tests; 6 for all-parallel tests
PSQL_DB ?= backendA
Expand Down
1 change: 1 addition & 0 deletions changelog.d/5-internal/WPB-23903
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
New `wire-ingress` Helm chart — Gateway API / Envoy Gateway replacement for `nginx-ingress-services`. Not yet production-ready.
2 changes: 1 addition & 1 deletion charts/backoffice/templates/tests/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: ConfigMap
metadata:
name: "stern-integration"
annotations:
"helm.sh/hook": post-install
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-delete-policy": before-hook-creation
data:
integration.yaml: |
Expand Down
6 changes: 3 additions & 3 deletions charts/federator/templates/tests/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: ConfigMap
metadata:
name: "federator-integration"
annotations:
"helm.sh/hook": post-install
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-delete-policy": before-hook-creation
data:
integration.yaml: |
Expand All @@ -23,6 +23,6 @@ data:
host: cargohold
port: 8080
nginxIngress:
host: federation-test-helper.{{ .Release.Namespace }}.svc.cluster.local
host: {{ .Values.tests.nginxIngressHost }}
port: 443
originDomain: federation-test-helper.{{ .Release.Namespace }}.svc.cluster.local
originDomain: {{ .Values.tests.nginxIngressHost }}
4 changes: 4 additions & 0 deletions charts/federator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ podSecurityContext:
type: RuntimeDefault

tests:
# The host used for the nginxIngress endpoint and originDomain in the integration
# test config. Depends on the release name of the "wire-ingress" helm chart
# (see federation-test-helper.yaml in that chart).
nginxIngressHost: "set-me"
config: {}
# config:
# uploadXml:
Expand Down
45 changes: 45 additions & 0 deletions charts/integration/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,49 @@

{{/*
Name of the Gateway resource for dynamic backends in envoy mode.
*/}}
{{- define "integration.getDynBackendsGatewayName" -}}
{{- if .Values.envoy.gateway.name -}}
{{ .Values.envoy.gateway.name }}
{{- else -}}
{{ .Release.Name }}-dynamic-backends
{{- end -}}
{{- end -}}

{{/*
Federation origin domain for a given namespace (used as originDomain in the config).
Returns the SRV hostname that other backends use to reach this namespace's federator.
NOTE: Keep the naming assumption %s-fed in sync with the wire-ingress and nginx-ingress-services chart!
Args: list $namespace $envoyEnabled $controllerNamespace
*/}}
{{- define "integration.federationOriginDomain" -}}
{{- $namespace := index . 0 -}}
{{- $envoyEnabled := index . 1 -}}
{{- $controllerNs := index . 2 -}}
{{- if $envoyEnabled -}}
{{- printf "%s-fed.%s.svc.cluster.local" $namespace $controllerNs -}}
{{- else -}}
{{- printf "federation-test-helper.%s.svc.cluster.local" $namespace -}}
{{- end -}}
{{- end -}}

{{/*
Domain for a dynamic backend. Returns the correct hostname depending on whether
envoy mode is enabled.
Args: list $dynamicBackend $namespace $envoyEnabled $controllerNamespace
*/}}
{{- define "integration.dynamicBackendDomain" -}}
{{- $dynamicBackend := index . 0 -}}
{{- $namespace := index . 1 -}}
{{- $envoyEnabled := index . 2 -}}
{{- $controllerNs := index . 3 -}}
{{- if $envoyEnabled -}}
{{- printf "%s-%s.%s.svc.cluster.local" $dynamicBackend.federatorExternalHostPrefix $namespace $controllerNs -}}
{{- else -}}
{{- printf "%s.%s.svc.cluster.local" $dynamicBackend.federatorExternalHostPrefix $namespace -}}
{{- end -}}
{{- end -}}

{{/* Allow KubeVersion to be overridden. */}}
{{- define "kubeVersion" -}}
{{- default $.Capabilities.KubeVersion.Version $.Values.kubeVersionOverride -}}
Expand Down
6 changes: 3 additions & 3 deletions charts/integration/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ data:
apiPort: 5380
dohPort: 5381

originDomain: federation-test-helper.{{ .Release.Namespace }}.svc.cluster.local
originDomain: {{ include "integration.federationOriginDomain" (list .Release.Namespace .Values.envoy.enabled .Values.envoy.controllerNamespace) }}

rabbitmq:
host: rabbitmq
Expand Down Expand Up @@ -158,12 +158,12 @@ data:

rabbitMqVHost: /

originDomain: federation-test-helper.{{ .Release.Namespace }}-fed2.svc.cluster.local
originDomain: {{ include "integration.federationOriginDomain" (list (printf "%s-fed2" .Release.Namespace) .Values.envoy.enabled .Values.envoy.controllerNamespace) }}

dynamicBackends:
{{- range $name, $dynamicBackend := .Values.config.dynamicBackends }}
{{ $name }}:
domain: {{ $dynamicBackend.federatorExternalHostPrefix }}.{{ $.Release.Namespace }}.svc.cluster.local
domain: {{ include "integration.dynamicBackendDomain" (list $dynamicBackend $.Release.Namespace $.Values.envoy.enabled $.Values.envoy.controllerNamespace) }}
federatorExternalPort: {{ $dynamicBackend.federatorExternalPort }}
mlsPrivateKeyPaths:
removal:
Expand Down
161 changes: 161 additions & 0 deletions charts/integration/templates/envoy-gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
{{- if .Values.envoy.enabled }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

None of the five kinds here carry chart/release label

{{- $gatewayName := include "integration.getDynBackendsGatewayName" . }}
{{- $httpsPort := int .Values.envoy.gateway.listeners.https.port }}
{{- $controllerNs := .Values.envoy.controllerNamespace }}
{{- if lt $httpsPort 1024 }}
{{- fail (printf "envoy.gateway.listeners.https.port is %d (privileged, <1024). Envoy Gateway remaps it to %d on the proxy pod. Set envoy.gateway.listeners.https.port to the actual container port (e.g. %d)." $httpsPort (add $httpsPort 10000) (add $httpsPort 10000)) }}
{{- end }}
---
# EnvoyProxy configures the proxy deployment/service for the dynamic-backends Gateway.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: {{ $gatewayName }}
spec:
provider:
type: Kubernetes
kubernetes:
envoyService:
# ClusterIP: no external load balancer needed for in-cluster integration tests.
type: ClusterIP
---
# Gateway for all dynamic backends. A single HTTPS listener covers all backend hostnames.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ $gatewayName }}
spec:
gatewayClassName: {{ required "envoy.gateway.className is required when envoy.enabled is true" .Values.envoy.gateway.className | quote }}
infrastructure:
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: {{ $gatewayName | quote }}
listeners:
- name: https
port: {{ $httpsPort }}
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: {{ .Values.envoy.federator.tls.secretName | quote }}
kind: Secret
---
# ClientTrafficPolicy enforces optional mTLS client cert validation on all dynamic-backend
# connections (mirrors the nginx auth-tls-verify-client: "on" annotation).
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
name: {{ $gatewayName }}-mtls
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: {{ $gatewayName | quote }}
sectionName: https
tls:
clientValidation:
optional: true
caCertificateRefs:
- name: federator-ca
kind: ConfigMap
---
{{- $backendNames := keys .Values.config.dynamicBackends | sortAlpha }}
{{- range $index, $name := $backendNames }}
{{- $dynamicBackend := index $.Values.config.dynamicBackends $name }}
{{- $httpRouteName := printf "%s-dynbackend-%s" $gatewayName $name }}
{{- $svcDomain := printf "%s-%s.%s.svc.cluster.local" $dynamicBackend.federatorExternalHostPrefix $.Release.Namespace $controllerNs }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: {{ $httpRouteName }}
spec:
parentRefs:
- name: {{ $gatewayName | quote }}
namespace: {{ $.Release.Namespace | quote }}
kind: Gateway
sectionName: https
hostnames:
- {{ $svcDomain | quote }}
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: integration
port: {{ $dynamicBackend.federatorExternalPort }}
kind: Service
---
# EnvoyExtensionPolicy injects the mTLS client certificate as X-SSL-Certificate request
# header, matching the nginx $ssl_client_escaped_cert behaviour expected by federator.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
metadata:
name: {{ $httpRouteName }}-cert-header
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: {{ $httpRouteName }}
lua:
- type: Inline
inline: |
function envoy_on_request(request_handle)
{{/* Strip any client-provided header to prevent spoofing */}}
request_handle:headers():remove("X-SSL-Certificate")
local ssl = request_handle:connection():ssl()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

same headers():add issue

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

addressed in adc4668

if ssl ~= nil then
local cert = ssl:urlEncodedPemEncodedPeerCertificate()
if cert ~= nil and cert ~= "" then
request_handle:headers():add("X-SSL-Certificate", cert)
end
end
end
---
# EnvoyPatchPolicy adds the FQDN variant (with trailing dot) of the backend domain
# to the virtual host's domain list. Wire federator resolves targets via DNS SRV records;
# per RFC 2782, SRV record targets are FQDNs (e.g. "backend-fed.ns.svc.cluster.local.").
# HTTP/2 passes that dot in :authority; without this patch the virtual host only matches
# the bare domain and returns route_not_found. Adding the FQDN allows Envoy to match both.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
name: {{ $httpRouteName }}-fqdn-domain
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: {{ $gatewayName | quote }}
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
# RouteConfiguration is per-listener, named <namespace>/<gateway>/<listener>
name: {{ printf "%s/%s/https" $.Release.Namespace $gatewayName | quote }}
operation:
op: add
# Virtual hosts are indexed in the order of stable key sorting (sortAlpha).
path: {{ printf "/virtual_hosts/%d/domains/-" $index | quote }}
value: {{ printf "%s." $svcDomain | quote }}
---
# ClusterIP service in {{ $controllerNs }} selects the Envoy proxy pods for this Gateway.
# The service name determines the SRV record used by federation discovery:
# _wire-server-federator._tcp.{{ $svcDomain }}
apiVersion: v1
kind: Service
metadata:
name: {{ $dynamicBackend.federatorExternalHostPrefix }}-{{ $.Release.Namespace }}
namespace: {{ $controllerNs }}
spec:
type: ClusterIP
ports:
- name: wire-server-federator
port: 443
protocol: TCP
targetPort: {{ $httpsPort }}
selector:
gateway.envoyproxy.io/owning-gateway-name: {{ $gatewayName }}
gateway.envoyproxy.io/owning-gateway-namespace: {{ $.Release.Namespace }}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{{- if not .Values.envoy.enabled }}
{{- $newLabels := eq (include "integrationTestHelperNewLabels" .) "true" -}}
{{- range $name, $dynamicBackend := .Values.config.dynamicBackends }}
---
apiVersion: networking.k8s.io/v1
Expand Down Expand Up @@ -29,4 +31,25 @@ spec:
name: integration
port:
number: {{ $dynamicBackend.federatorExternalPort }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $dynamicBackend.federatorExternalHostPrefix }}
spec:
ports:
- name: wire-server-federator
port: 443
protocol: TCP
targetPort: https
selector:
{{- if $newLabels }}
app.kubernetes.io/component: controller
app.kubernetes.io/name: ingress-nginx
{{- else }}
app: nginx-ingress
component: controller
{{- end }}
type: ClusterIP
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ spec:
integration-dynamic-backends-ses.sh {{ .Values.config.sesEndpointUrl }}
integration-dynamic-backends-s3.sh {{ .Values.config.s3EndpointUrl }}
{{- range $name, $dynamicBackend := .Values.config.dynamicBackends }}
integration-dynamic-backends-vhosts.sh {{ $.Values.config.rabbitmqPutVHostUrl }} {{ $dynamicBackend.federatorExternalHostPrefix}}.{{ $.Release.Namespace }}.svc.cluster.local
integration-dynamic-backends-vhosts.sh {{ $.Values.config.rabbitmqPutVHostUrl }} {{ include "integration.dynamicBackendDomain" (list $dynamicBackend $.Release.Namespace $.Values.envoy.enabled $.Values.envoy.controllerNamespace) }}
{{- end }}
resources:
requests:
Expand Down
24 changes: 0 additions & 24 deletions charts/integration/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{{- $newLabels := eq (include "integrationTestHelperNewLabels" .) "true" -}}
---
apiVersion: v1
kind: Service
Expand Down Expand Up @@ -26,26 +25,3 @@ spec:
selector:
app: integration-integration
type: ClusterIP

{{- range $name, $dynamicBackend := .Values.config.dynamicBackends }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $dynamicBackend.federatorExternalHostPrefix }}
spec:
ports:
- name: wire-server-federator
port: 443
protocol: TCP
targetPort: https
selector:
{{- if $newLabels }}
app.kubernetes.io/component: controller
app.kubernetes.io/name: ingress-nginx
{{- else }}
app: nginx-ingress
component: controller
{{- end }}
type: ClusterIP
{{- end }}
23 changes: 23 additions & 0 deletions charts/integration/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,27 @@ tls:
ingress:
class: nginx

envoy:
# Set to true to deploy Gateway API resources instead of nginx Ingress objects
# for the dynamic backends. Requires an Envoy Gateway controller in the cluster.
enabled: false
# Namespace where the Envoy Gateway controller runs its proxy pods.
# Change only if you installed Envoy Gateway into a non-default namespace.
controllerNamespace: envoy-gateway-system
gateway:
# Name of the Gateway resource. Defaults to <release-name>-dynamic-backends if empty.
name: ""
# Name of the GatewayClass installed by the Envoy Gateway controller (e.g. "envoy").
className: ""
listeners:
https:
# Use a non-privileged port (>=1024) to avoid the +10000 container-port
# remapping applied by Envoy Gateway to privileged ports.
port: 10443
federator:
tls:
# Name of the TLS Secret presented by the Gateway for the dynamic-backend
# listeners. Must exist before deploying (created by the wire-ingress chart).
secretName: "federator-certificate-secret"

secrets: {}
Loading