Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# [2026-05-12] (Chart Release 5.32.0)

## Release notes


* - `postgresMigration` now has a single source of truth in the Galley chart values. Galley, Brig, and background-worker all read their PostgreSQL migration settings from there.
- If your deployment overrides the full `postgresMigration` object, add the new `domainRegistration` field to that override. Otherwise services may fail to start because the config is incomplete.
- To migrate domain registration data to PostgreSQL, set `postgresMigration.domainRegistration` to `migration-to-postgresql`, run the background-worker migration with `migrateDomainRegistration: true`, and switch the setting to `postgresql` after completion.
- The domain registration migration covers these Cassandra tables:
`domain_registration`, `domain_registration_by_team`, and `domain_registration_challenge`. (#5195)


## API changes


* Discontinue redundant end-point for fetching user clients. (#5222)


## Documentation


* Improve swagger API docs. (#5220)


## Internal changes


* New `wire-ingress` Helm chart — Gateway API / Envoy Gateway replacement for `nginx-ingress-services`. Not yet production-ready. (#5150)


# [2026-05-08] (Chart Release 5.31.0)

## API changes
Expand Down
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
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 }}
{{- $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()
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 }}
Loading