feat: Gateway-API as an alternative to the Ingress in the six special shapes (group 3) #120
No files matched your search
@@ -0,0 +1,59 @@
|
|||||||
|
# Render-only overlay for ci/run-httproute-match-test.sh, applied LAST.
|
||||||
|
#
|
||||||
|
# Its one job is to put this chart into Gateway mode, because the convention
|
||||||
|
# ships with httpRoute.enabled: false and the test would otherwise be green
|
||||||
|
# over nothing. A chart that has an overlay here and still renders no
|
||||||
|
# HTTPRoute FAILS the test - that is the whole point of the file existing.
|
||||||
|
#
|
||||||
|
# An overlay and not a change to ci/matrix-synapse/test-values.yaml: the
|
||||||
|
# install-test runs exactly ONE configuration per chart, and this chart's
|
||||||
|
# fixture installs the StatefulSet with its PVC and the delegation Deployment.
|
||||||
|
# Trading its Ingress for a CRD schema check that cyberchef's fixture already
|
||||||
|
# performs against the real Gateway-API CRDs would be a bad swap. The install
|
||||||
|
# keeps the Ingress; the routes are held here, at render level, which is where
|
||||||
|
# their silent failure modes live.
|
||||||
|
#
|
||||||
|
# ingress.enabled: false is not optional here - ingress.enabled is this chart's
|
||||||
|
# routing switch and defaults to TRUE, so without this line the chart aborts
|
||||||
|
# its own render with both modes on.
|
||||||
|
#
|
||||||
|
# WHAT THIS OVERLAY COVERS, WHICH IS BOTH ROUTING OBJECTS - and this chart is
|
||||||
|
# the one in group 3 where "both" means two different hostnames, two different
|
||||||
|
# paths and two different backends:
|
||||||
|
#
|
||||||
|
# - ingress.domain comes from the fixture (matrix.ci.local), so the
|
||||||
|
# HOMESERVER route renders with its hostname from that single source of
|
||||||
|
# truth. httpRoute.hostnames stays empty on purpose: the fallback is the
|
||||||
|
# path every installation will actually use.
|
||||||
|
# - matrix.delegation.enabled is TRUE in the fixture with
|
||||||
|
# matrix.delegation.serverUrl: ci.local, so the DELEGATION route renders
|
||||||
|
# too - on its own hostname, matching PathPrefix /.well-known/matrix, and
|
||||||
|
# pointing at the delegation Service rather than at Synapse. Its
|
||||||
|
# parentRefs fall back to httpRoute.parentRefs below, which is the branch
|
||||||
|
# an installation hits unless the server name sits behind a different
|
||||||
|
# Gateway.
|
||||||
|
# - both routes' backendRefs are checked against the Services of the same
|
||||||
|
# render, and they are DIFFERENT Services. Both references are by PORT
|
||||||
|
# NUMBER rather than by the name "http" the Ingress uses, because
|
||||||
|
# backendRefs takes a PortNumber - so this overlay is what holds those
|
||||||
|
# numbers against the Services'.
|
||||||
|
#
|
||||||
|
# No URLRewrite filter is rendered by this chart in either mode: the delegation
|
||||||
|
# nginx answers on the full /.well-known/matrix/* path, so nothing is stripped
|
||||||
|
# and the #118 prefix/redirect assurance has no precondition to meet here.
|
||||||
|
#
|
||||||
|
# NOT covered here, and it cannot be: that either hostname answers, which for
|
||||||
|
# Matrix is also whether FEDERATION works. No Gateway controller runs in CI, no
|
||||||
|
# route reaches "Accepted: True", and Matrix federation is HTTPS-only while
|
||||||
|
# nothing in this mode renders a certificate. Nor is the body-size limit
|
||||||
|
# covered - proxy-body-size: 50m is on the live Ingress and has no counterpart
|
||||||
|
# in the specification; that loss is documented in values.yaml and printed by
|
||||||
|
# NOTES.txt, and documentation is not something a test can assert.
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
httpRoute:
|
||||||
|
enabled: true
|
||||||
|
parentRefs:
|
||||||
|
- name: public
|
||||||
|
namespace: gateway
|
||||||
|
sectionName: https
|
||||||
@@ -3,7 +3,7 @@ name: matrix-synapse
|
|||||||
description: A Helm chart to deploy a Matrix Synapse server on Kubernetes
|
description: A Helm chart to deploy a Matrix Synapse server on Kubernetes
|
||||||
icon: https://raw.githubusercontent.com/element-hq/synapse/develop/docs/favicon.png
|
icon: https://raw.githubusercontent.com/element-hq/synapse/develop/docs/favicon.png
|
||||||
type: application
|
type: application
|
||||||
version: 7.1.1+upv1.159.0
|
version: 7.2.0+upv1.159.0
|
||||||
appVersion: "v1.159.0"
|
appVersion: "v1.159.0"
|
||||||
maintainers:
|
maintainers:
|
||||||
- name: jklein
|
- name: jklein
|
||||||
@@ -1,5 +1,29 @@
|
|||||||
|
{{- /*
|
||||||
|
NOTHING IN CI READS THIS FILE. `helm template` does not emit notes and no
|
||||||
|
workflow or script under ci/ reads it, so every claim below carries
|
||||||
|
review-only assurance - it is checked by being read, not by a stage. A
|
||||||
|
rendering ERROR here does fail `helm template`, which is all the pipeline can
|
||||||
|
see of it.
|
||||||
|
*/ -}}
|
||||||
{{- $replicas := include "matrix-synapse.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.matrix.replicas) -}}
|
{{- $replicas := include "matrix-synapse.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.matrix.replicas) -}}
|
||||||
{{- $delegation := .Values.matrix.delegation | default dict -}}
|
{{- $delegation := .Values.matrix.delegation | default dict -}}
|
||||||
|
{{- $httpRoute := .Values.httpRoute | default dict -}}
|
||||||
|
{{- $httpRouteDelegation := $httpRoute.delegation | default dict -}}
|
||||||
|
{{- /*
|
||||||
|
"Published" rather than "has an Ingress": the two modes are alternatives, and
|
||||||
|
every paragraph below that used to ask ingress.enabled was really asking
|
||||||
|
whether anything publishes this release. Gitea #114, and the sure.publishedOverTls
|
||||||
|
/ freesailarr.published shape.
|
||||||
|
*/ -}}
|
||||||
|
{{- $published := or .Values.ingress.enabled $httpRoute.enabled -}}
|
||||||
|
{{- $hostnames := $httpRoute.hostnames | default list -}}
|
||||||
|
{{- if not $hostnames -}}
|
||||||
|
{{- $hostnames = list .Values.ingress.domain -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $delegationHostnames := $httpRouteDelegation.hostnames | default list -}}
|
||||||
|
{{- if not $delegationHostnames -}}
|
||||||
|
{{- $delegationHostnames = list $delegation.serverUrl -}}
|
||||||
|
{{- end -}}
|
||||||
{{- $delegationReplicas := include "matrix-synapse.replicas" (dict "scaleDown" .Values.scaleDown "replicas" $delegation.replicas) -}}
|
{{- $delegationReplicas := include "matrix-synapse.replicas" (dict "scaleDown" .Values.scaleDown "replicas" $delegation.replicas) -}}
|
||||||
{{- $res := fromYaml (include "matrix-synapse.effectiveResources" .Values.matrix.resources) -}}
|
{{- $res := fromYaml (include "matrix-synapse.effectiveResources" .Values.matrix.resources) -}}
|
||||||
{{- $eph := index ($res.limits | default dict) "ephemeral-storage" | default "the computed ephemeral-storage limit" -}}
|
{{- $eph := index ($res.limits | default dict) "ephemeral-storage" | default "the computed ephemeral-storage limit" -}}
|
||||||
@@ -14,7 +38,7 @@ Matrix Synapse {{ .Chart.AppVersion }} — release {{ .Release.Name }} in namesp
|
|||||||
|
|
||||||
{{- if .Values.ingress.enabled }}
|
{{- if .Values.ingress.enabled }}
|
||||||
|
|
||||||
ACCESS
|
ACCESS — INGRESS MODE (ingress.enabled: true, httpRoute.enabled: false)
|
||||||
https://{{ .Values.ingress.domain }}
|
https://{{ .Values.ingress.domain }}
|
||||||
|
|
||||||
That host carries the whole client and federation API: the Ingress sends "/"
|
That host carries the whole client and federation API: the Ingress sends "/"
|
||||||
@@ -24,11 +48,96 @@ ACCESS
|
|||||||
shows a warning and federation fails. Follow it with
|
shows a warning and federation fails. Follow it with
|
||||||
|
|
||||||
kubectl -n {{ .Release.Namespace }} get certificate tls-{{ .Release.Name }}-{{ .Chart.Name }}-ingress
|
kubectl -n {{ .Release.Namespace }} get certificate tls-{{ .Release.Name }}-{{ .Chart.Name }}-ingress
|
||||||
|
{{- else if $httpRoute.enabled }}
|
||||||
|
|
||||||
|
ACCESS — GATEWAY MODE (httpRoute.enabled: true, ingress.enabled: false)
|
||||||
|
{{- range $hostnames }}
|
||||||
|
https://{{ . }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
That host carries the whole client and federation API: the HTTPRoute sends
|
||||||
|
"/" on it to the Synapse Service, which forwards port 80 to the container's
|
||||||
|
8008.
|
||||||
|
|
||||||
|
THIS RELEASE RENDERS {{ if $delegation.enabled }}TWO HTTPRoutes{{ else }}ONE HTTPRoute{{ end }} AND NOTHING ELSE of the routing
|
||||||
|
path — no Gateway, no class, no Certificate, no policy object.
|
||||||
|
|
||||||
|
{{ .Release.Name }}-{{ .Chart.Name }}-httproute {{ join ", " $hostnames }}
|
||||||
|
{{- if $delegation.enabled }}
|
||||||
|
{{ .Release.Name }}-{{ .Chart.Name }}-delegation-httproute {{ join ", " $delegationHostnames }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
Three things therefore belong to the cluster, and if any is missing the
|
||||||
|
hostname does not answer — which for Matrix means federation is down, not
|
||||||
|
just the web client:
|
||||||
|
|
||||||
|
1. The Gateway-API CRDs. Without them this install would have failed, so
|
||||||
|
they are present — nothing to check.
|
||||||
|
2. The Gateway(s) named in parentRefs
|
||||||
|
{{- range $httpRoute.parentRefs }}
|
||||||
|
{{ .name }}{{ if .namespace }} in namespace {{ .namespace }}{{ end }}{{ if .sectionName }}, listener {{ .sectionName }}{{ end }} (homeserver)
|
||||||
|
{{- end }}
|
||||||
|
{{- if $delegation.enabled }}
|
||||||
|
{{- range ($httpRouteDelegation.parentRefs | default $httpRoute.parentRefs) }}
|
||||||
|
{{ .name }}{{ if .namespace }} in namespace {{ .namespace }}{{ end }}{{ if .sectionName }}, listener {{ .sectionName }}{{ end }} (delegation)
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
must exist AND their listeners must allow routes from this namespace
|
||||||
|
({{ .Release.Namespace }}) in allowedRoutes. A rejected attachment is visible only
|
||||||
|
in the route's status:
|
||||||
|
|
||||||
|
kubectl -n {{ .Release.Namespace }} get httproute {{ .Release.Name }}-{{ .Chart.Name }}-httproute -o yaml
|
||||||
|
|
||||||
|
Read status.parents[].conditions — "Accepted: True" and
|
||||||
|
"ResolvedRefs: True" is what a working attachment looks like. An empty
|
||||||
|
status means no controller has looked at the route at all.
|
||||||
|
3. {{ if $delegation.enabled }}The TLS certificates — one per hostname, on the Gateway's listeners,
|
||||||
|
or one wildcard listener covering both{{ else }}The TLS certificate for the hostname, on the Gateway's listener{{ end }}.
|
||||||
|
ingress.clusterIssuer is NOT used in this mode and is not required: the
|
||||||
|
chart renders no Certificate here, so there is no
|
||||||
|
tls-{{ .Release.Name }}-{{ .Chart.Name }}-ingress secret{{ if $delegation.enabled }} and no
|
||||||
|
tls-{{ .Release.Name }}-{{ .Chart.Name }}-delegation secret{{ end }} and nothing for
|
||||||
|
cert-manager to do for this release. MATRIX FEDERATION IS HTTPS-ONLY,
|
||||||
|
so a listener without a valid certificate for these names is a
|
||||||
|
federation outage that no probe in this release can see.
|
||||||
|
|
||||||
|
THE UPLOAD LIMIT IS NOT ENFORCED BY ANYTHING THIS CHART RENDERS.
|
||||||
|
|
||||||
|
In Ingress mode an operator sets
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size through ingress.annotations —
|
||||||
|
this installation runs with 50m — because Synapse's media repository takes
|
||||||
|
uploads and nginx's default of 1m rejects nearly all of them. IN THIS MODE
|
||||||
|
THAT IS GONE: the Gateway API has no body-size field, it is implementation
|
||||||
|
policy rather than routing, and this chart renders no policy object on
|
||||||
|
purpose (it would bind the chart to one Gateway implementation).
|
||||||
|
|
||||||
|
The ceiling in force is the smaller of max_upload_size in your
|
||||||
|
homeserver.yaml — which this chart cannot see, it comes from 1Password —
|
||||||
|
and whatever the GATEWAY enforces. Neither number anyone can point at is
|
||||||
|
necessarily the one that decides. Set the Gateway's half, in your
|
||||||
|
implementation's own object, to match max_upload_size, BEFORE you point DNS
|
||||||
|
at it.
|
||||||
|
|
||||||
|
AND ONE THING NOT TO RE-CREATE. The live Ingress also carries a
|
||||||
|
configuration-snippet of three more_set_headers directives
|
||||||
|
(X-Forwarded-For $remote_addr, X-Forwarded-Proto $scheme, Host). It LOOKS
|
||||||
|
like what Synapse's x_forwarded setting depends on. It is not:
|
||||||
|
more_set_headers is the headers-more module's OUTPUT-header directive, so
|
||||||
|
those three headers go on the RESPONSE TO THE CLIENT and Synapse never sees
|
||||||
|
them. What Synapse reads with x_forwarded: true is the REQUEST's
|
||||||
|
X-Forwarded-For, which the proxy supplies by itself. Do not spend effort
|
||||||
|
rebuilding this at the Gateway, and do not read its absence as the cause of
|
||||||
|
a rate-limiting or federation problem. (This is a reading of the directive's
|
||||||
|
documented semantics; nothing here A/B-tested a Synapse instance.)
|
||||||
|
|
||||||
|
ingress.annotations is inert in this mode in general: the Gateway API has no
|
||||||
|
annotation channel for controller behaviour.
|
||||||
{{- else }}
|
{{- else }}
|
||||||
|
|
||||||
ACCESS — NO INGRESS
|
ACCESS — NEITHER INGRESS NOR HTTPROUTE
|
||||||
ingress.enabled is false, so this release has no Ingress and no certificate;
|
ingress.enabled and httpRoute.enabled are both false, so this release has no
|
||||||
ingress.clusterIssuer is not needed.
|
Ingress, no HTTPRoute and no certificate; ingress.clusterIssuer is not
|
||||||
|
needed.
|
||||||
{{- if $delegation.enabled }}
|
{{- if $delegation.enabled }}
|
||||||
ingress.domain still is: the delegation nginx renders it into the
|
ingress.domain still is: the delegation nginx renders it into the
|
||||||
/.well-known/matrix/* documents, so it stays the host every other Matrix
|
/.well-known/matrix/* documents, so it stays the host every other Matrix
|
||||||
@@ -56,10 +165,10 @@ DELEGATION — TWO HOSTNAMES THAT ARE NOT INTERCHANGEABLE
|
|||||||
→ {"m.server": "{{ .Values.ingress.domain }}:443"}
|
→ {"m.server": "{{ .Values.ingress.domain }}:443"}
|
||||||
/.well-known/matrix/client
|
/.well-known/matrix/client
|
||||||
→ {"m.homeserver": {"base_url": "https://{{ .Values.ingress.domain }}"}}
|
→ {"m.homeserver": {"base_url": "https://{{ .Values.ingress.domain }}"}}
|
||||||
{{- if .Values.ingress.enabled }}
|
{{- if $published }}
|
||||||
|
|
||||||
The Ingress publishes them on a SECOND host. Read that split carefully,
|
{{ if $httpRoute.enabled }}A SECOND HTTPRoute publishes{{ else }}The Ingress publishes{{ end }} them on a SECOND host. Read that split
|
||||||
because the chart cannot check it for you:
|
carefully, because the chart cannot check it for you:
|
||||||
|
|
||||||
matrix.delegation.serverUrl ({{ $delegation.serverUrl }})
|
matrix.delegation.serverUrl ({{ $delegation.serverUrl }})
|
||||||
is the DELEGATING host — the domain in every user ID (@user:{{ $delegation.serverUrl }}).
|
is the DELEGATING host — the domain in every user ID (@user:{{ $delegation.serverUrl }}).
|
||||||
@@ -69,18 +178,36 @@ DELEGATION — TWO HOSTNAMES THAT ARE NOT INTERCHANGEABLE
|
|||||||
is where Synapse actually answers. It appears inside the documents
|
is where Synapse actually answers. It appears inside the documents
|
||||||
above and needs no relation to the server name.
|
above and needs no relation to the server name.
|
||||||
|
|
||||||
Only the path /.well-known/matrix is routed to nginx on {{ $delegation.serverUrl }};
|
Only the path /.well-known/matrix is routed to nginx on {{ join ", " $delegationHostnames }};
|
||||||
everything else on that host is not served by this release. Both hosts need
|
everything else on that host is not served by this release.
|
||||||
|
{{- if $httpRoute.enabled }}
|
||||||
|
|
||||||
|
AND THAT CO-EXISTENCE IS EASIER HERE THAN IT WAS. The server name is usually
|
||||||
|
an apex domain that already serves a website, and under ingress-nginx two
|
||||||
|
Ingress objects cannot both claim one hostname — the admission webhook
|
||||||
|
rejects the second — which is why the delegation rule had to sit inside this
|
||||||
|
chart's single Ingress object. HTTPRoutes attached to the same listener for
|
||||||
|
the same hostname are MERGED by the implementation, longest match winning,
|
||||||
|
so this route may sit beside whatever owns that apex without either side
|
||||||
|
knowing about the other.
|
||||||
|
|
||||||
|
Both hosts need a certificate ON THE GATEWAY'S LISTENERS — this chart renders
|
||||||
|
none in this mode — and a listener without a valid certificate for the server
|
||||||
|
name is a federation outage, not a cosmetic problem.
|
||||||
|
{{- else }}
|
||||||
|
Both hosts need
|
||||||
a certificate — the second one is tls-{{ .Release.Name }}-{{ .Chart.Name }}-delegation — and
|
a certificate — the second one is tls-{{ .Release.Name }}-{{ .Chart.Name }}-delegation — and
|
||||||
cert-manager only issues it once {{ $delegation.serverUrl }} resolves to this cluster.
|
cert-manager only issues it once {{ $delegation.serverUrl }} resolves to this cluster.
|
||||||
A pending certificate there is a federation outage, not a cosmetic problem.
|
A pending certificate there is a federation outage, not a cosmetic problem.
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
Check what is actually being served, from outside the cluster:
|
Check what is actually being served, from outside the cluster:
|
||||||
|
|
||||||
curl -s https://{{ $delegation.serverUrl }}/.well-known/matrix/server
|
curl -s https://{{ first $delegationHostnames }}/.well-known/matrix/server
|
||||||
{{- else }}
|
{{- else }}
|
||||||
|
|
||||||
Nothing publishes them, though: ingress.enabled is false, so the documents
|
Nothing publishes them, though: ingress.enabled and httpRoute.enabled are
|
||||||
|
both false, so the documents
|
||||||
exist only on the in-cluster Service {{ .Release.Name }}-{{ .Chart.Name }}-delegation-service, and
|
exist only on the in-cluster Service {{ .Release.Name }}-{{ .Chart.Name }}-delegation-service, and
|
||||||
matrix.delegation.serverUrl ({{ $delegation.serverUrl }}) is rendered into no object of this
|
matrix.delegation.serverUrl ({{ $delegation.serverUrl }}) is rendered into no object of this
|
||||||
release. Whatever terminates TLS in front of the cluster has to route
|
release. Whatever terminates TLS in front of the cluster has to route
|
||||||
@@ -101,7 +228,7 @@ NO DELEGATION IN THIS RELEASE — FEDERATION LIKELY DOES NOT WORK
|
|||||||
8448 anywhere: the container publishes 8008 only, and the Service maps port
|
8448 anywhere: the container publishes 8008 only, and the Service maps port
|
||||||
80 onto it. Unless the delegation is served by something else (a static
|
80 onto it. Unless the delegation is served by something else (a static
|
||||||
.well-known on the server-name host, or an SRV record), federation stays
|
.well-known on the server-name host, or an SRV record), federation stays
|
||||||
broken{{ if .Values.ingress.enabled }} while clients on {{ .Values.ingress.domain }} work fine{{ end }}.
|
broken{{ if $published }} while clients on {{ first $hostnames }} work fine{{ end }}.
|
||||||
Setting matrix.delegation.enabled to true and matrix.delegation.serverUrl
|
Setting matrix.delegation.enabled to true and matrix.delegation.serverUrl
|
||||||
to the server name lets this chart serve it.
|
to the server name lets this chart serve it.
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@@ -120,7 +247,11 @@ SCALED TO ZERO
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
The PVC, the Secret and the Services stay in place, so no data is lost{{ if .Values.ingress.enabled }} and
|
The PVC, the Secret and the Services stay in place, so no data is lost{{ if .Values.ingress.enabled }} and
|
||||||
the certificates are not re-issued{{ end }}. Set it back and upgrade again to
|
the certificates are not re-issued{{ else if $httpRoute.enabled }} and the
|
||||||
|
HTTPRoutes stay in place, so the hostnames keep pointing at Services with no
|
||||||
|
endpoints — the Gateway answers with an error of its own rather than with
|
||||||
|
nothing, and remote homeservers see a failing .well-known instead of an
|
||||||
|
unresolvable name{{ end }}. Set it back and upgrade again to
|
||||||
return.
|
return.
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
@@ -190,7 +321,7 @@ THE SERVER NAME IS DECIDED ONCE, AND NOT BY matrix.serverName
|
|||||||
a different name is a new server with a new database, not an upgrade. Decide
|
a different name is a new server with a new database, not an upgrade. Decide
|
||||||
it before the first start — together with matrix.delegation.serverUrl, which
|
it before the first start — together with matrix.delegation.serverUrl, which
|
||||||
has to match it.
|
has to match it.
|
||||||
{{- if and .Values.ingress.enabled $delegation.enabled .Values.matrix.serverName $delegation.serverUrl }}
|
{{- if and $published $delegation.enabled .Values.matrix.serverName $delegation.serverUrl }}
|
||||||
{{- if ne (printf "%v" .Values.matrix.serverName) (printf "%v" $delegation.serverUrl) }}
|
{{- if ne (printf "%v" .Values.matrix.serverName) (printf "%v" $delegation.serverUrl) }}
|
||||||
|
|
||||||
MISMATCH IN THIS RELEASE: matrix.serverName is "{{ .Values.matrix.serverName }}" but the
|
MISMATCH IN THIS RELEASE: matrix.serverName is "{{ .Values.matrix.serverName }}" but the
|
||||||
|
|||||||
@@ -0,0 +1,198 @@
|
|||||||
|
{{/*
|
||||||
|
HTTPRoute - the Gateway-API alternative to matrix-synapse.ingress.yaml
|
||||||
|
(Gitea #114).
|
||||||
|
|
||||||
|
TWO ROUTES, AND THE SHAPE IS NOT WHAT #114 EXPECTED. The issue describes this
|
||||||
|
chart as rendering "its Ingresses in a loop over several apps". It does not -
|
||||||
|
that is freesailarr. This chart renders ONE Ingress object with TWO host rules:
|
||||||
|
|
||||||
|
ingress.domain / synapse service
|
||||||
|
matrix.delegation.serverUrl /.well-known/matrix delegation service
|
||||||
|
|
||||||
|
In the Gateway API that has to become TWO HTTPRoute objects, and not because of
|
||||||
|
style: spec.hostnames applies to the WHOLE object, so one route can carry
|
||||||
|
several hostnames only when they want the SAME rules. These two want different
|
||||||
|
paths and different backends, so one object per hostname is the only faithful
|
||||||
|
translation.
|
||||||
|
|
||||||
|
WHAT THIS MODE IMPROVES, WHICH IS WORTH KNOWING BEFORE THE MIGRATION
|
||||||
|
|
||||||
|
The delegation hostname is the Matrix SERVER NAME - the apex domain, not the
|
||||||
|
homeserver's own host - and it is almost always already serving something else
|
||||||
|
(a website at /). Under ingress-nginx two Ingress objects on one hostname are a
|
||||||
|
fight: the admission webhook rejects the second claim on the same host and
|
||||||
|
path, which is why the delegation rule has to live INSIDE this chart's single
|
||||||
|
Ingress object rather than beside it. HTTPRoutes do not work that way: several
|
||||||
|
routes may attach to the same listener for the same hostname and the
|
||||||
|
implementation merges them by match specificity (a longer path wins). So in
|
||||||
|
this mode the /.well-known/matrix route can sit next to whatever else owns that
|
||||||
|
apex, without either side knowing about the other.
|
||||||
|
|
||||||
|
WHAT THIS RENDERS, AND WHAT IT MUST NOT
|
||||||
|
|
||||||
|
Only HTTPRoutes with parentRefs. No Gateway, no gatewayClassName, no
|
||||||
|
Certificate, no implementation-specific policy object - the subset that looks
|
||||||
|
identical on nginx-gateway-fabric, Cilium, Envoy Gateway and Istio (decision 1
|
||||||
|
of #114). Class and certificate belong to the PLATFORM, on the Gateway and its
|
||||||
|
listeners, in cluster-config. Note that the two hostnames need certificates on
|
||||||
|
TWO listeners (or one wildcard listener covering both), which in Ingress mode
|
||||||
|
were two entries in the one object's tls block.
|
||||||
|
|
||||||
|
WHAT THIS MODE DROPS, MEASURED ON THE LIVE OBJECT - AND ONE OF THE TWO IS NOT
|
||||||
|
WHAT IT LOOKS LIKE
|
||||||
|
|
||||||
|
On 2026-10-12 the live Ingress (jk-cluster, namespace matrix-synapse) carried,
|
||||||
|
all of it OPERATOR-supplied through ingress.annotations - this chart sets none
|
||||||
|
of it:
|
||||||
|
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: 50m
|
||||||
|
nginx.org/client-max-body-size: 50m
|
||||||
|
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||||
|
more_set_headers "X-Forwarded-For $remote_addr";
|
||||||
|
more_set_headers "X-Forwarded-Proto $scheme";
|
||||||
|
more_set_headers "Host $host:$server_port";
|
||||||
|
|
||||||
|
1. THE BODY SIZE IS THE REAL LOSS. Synapse's media repository takes uploads,
|
||||||
|
its own ceiling is max_upload_size in homeserver.yaml - which this chart
|
||||||
|
cannot see, because the whole config arrives from 1Password through
|
||||||
|
secrets.configSecretRef - and the effective limit is the smaller of the two.
|
||||||
|
In this mode the proxy half becomes THE GATEWAY'S default, so neither number
|
||||||
|
anyone can point at is necessarily the one that decides. There is no
|
||||||
|
counterpart in the Gateway API: body size is implementation policy, not
|
||||||
|
routing, and decision 2 of #114 says it is documented rather than rebuilt.
|
||||||
|
(nginx.org/client-max-body-size is the same limit spelled for the OTHER
|
||||||
|
nginx ingress controller, NGINX Inc's; it is a hedge across both
|
||||||
|
implementations and it disappears for the same reason.)
|
||||||
|
|
||||||
|
2. THE SNIPPET IS NOT LOAD-BEARING, AND THAT TOOK CHECKING RATHER THAN
|
||||||
|
ASSUMING. It looks like the thing Synapse's x_forwarded setting depends on -
|
||||||
|
client IP for rate limiting, and federation. It is not, because
|
||||||
|
more_set_headers is the module's OUTPUT-header directive:
|
||||||
|
headers-more-nginx-module, verbatim - more_set_headers "Replaces (if any) or
|
||||||
|
adds (if not any) the specified OUTPUT headers", while the request-side
|
||||||
|
directive is a different one, more_set_input_headers ("it operates on input
|
||||||
|
headers (or request headers)"). So these three headers are added to the
|
||||||
|
RESPONSE TO THE CLIENT. Synapse never sees them; what Synapse reads with
|
||||||
|
x_forwarded: true is the REQUEST's X-Forwarded-For, which ingress-nginx
|
||||||
|
populates itself.
|
||||||
|
|
||||||
|
The honest statement for the migration is therefore: not translatable, and
|
||||||
|
not needed. The Gateway API's ResponseHeaderModifier could set static
|
||||||
|
response headers but knows no nginx variables ($remote_addr, $scheme,
|
||||||
|
$host), so a rebuild is impossible anyway - and pointless, since dropping
|
||||||
|
them changes nothing Synapse depends on. What does change is that a client
|
||||||
|
stops receiving three headers echoing the proxy's view of its own request,
|
||||||
|
which is at best noise.
|
||||||
|
|
||||||
|
This is a claim about a directive's documented semantics, not an experiment:
|
||||||
|
nothing here observed a Synapse instance with and without the snippet.
|
||||||
|
|
||||||
|
Both are named in the Gateway branch of NOTES.txt, the first as a limit to
|
||||||
|
re-establish at the Gateway and the second as a thing NOT to re-establish.
|
||||||
|
*/}}
|
||||||
|
{{- /*
|
||||||
|
Null-safe like every other block a template here dereferences (#99): an
|
||||||
|
override written without children - "httpRoute:" with its keys deleted - is
|
||||||
|
YAML null, and .Values.httpRoute.enabled would abort with a nil pointer.
|
||||||
|
*/ -}}
|
||||||
|
{{- $httpRoute := .Values.httpRoute | default dict -}}
|
||||||
|
{{- if and $httpRoute.enabled .Values.ingress.enabled -}}
|
||||||
|
{{- fail "ingress.enabled and httpRoute.enabled are both true - set exactly one of them. The Ingress and the HTTPRoute would publish the same Services under the same hostnames over two different data paths, which is already a conflict at DNS level: one name, two addresses, and which one a client reaches is luck. For Matrix it is worse than for a stateless app: the /.well-known/matrix delegation tells every OTHER homeserver in the federation where to find this one, and a server name that resolves to two data paths makes federation succeed or fail per remote server and per retry. A migration runs over a SECOND hostname (set httpRoute.hostnames explicitly while the Ingress keeps ingress.domain), never over parallel operation of both - and the delegation host moves last, after the homeserver host answers." -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $httpRoute.enabled -}}
|
||||||
|
{{- $parentRefs := $httpRoute.parentRefs | default list -}}
|
||||||
|
{{- if not $parentRefs -}}
|
||||||
|
{{- fail "httpRoute.enabled is true but httpRoute.parentRefs is empty - an HTTPRoute without a parent attaches to no Gateway. It is created, it is schema-valid, and it routes NOTHING, with no event and no condition that says so; the only symptom is a hostname that does not answer. Name the cluster's Gateway, e.g. httpRoute.parentRefs: [{name: public, namespace: gateway}]." -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- /*
|
||||||
|
One source of truth for the hostname: an empty httpRoute.hostnames means
|
||||||
|
[ingress.domain]. Two values that have to agree drift apart. ingress.domain is
|
||||||
|
read outside the routing templates in this chart - the delegation nginx serves
|
||||||
|
it inside /.well-known/matrix/client - so it already carries a required() of
|
||||||
|
its own there and stays mandatory with the Ingress off (README, guideline 12,
|
||||||
|
point 1). This required() is the route's own, so the message names the route.
|
||||||
|
*/ -}}
|
||||||
|
{{- $hostnames := $httpRoute.hostnames | default list -}}
|
||||||
|
{{- if not $hostnames -}}
|
||||||
|
{{- $hostnames = list (required "A Domain/Host must be provided: set ingress.domain (used as the homeserver HTTPRoute's single hostname when httpRoute.hostnames is empty) or set httpRoute.hostnames explicitly" .Values.ingress.domain) -}}
|
||||||
|
{{- end -}}
|
||||||
|
apiVersion: gateway.networking.k8s.io/v1
|
||||||
|
kind: HTTPRoute
|
||||||
|
metadata:
|
||||||
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-httproute
|
||||||
|
spec:
|
||||||
|
parentRefs:
|
||||||
|
{{- toYaml $parentRefs | nindent 4 }}
|
||||||
|
hostnames:
|
||||||
|
{{- toYaml $hostnames | nindent 4 }}
|
||||||
|
rules:
|
||||||
|
{{- /*
|
||||||
|
The Ingress counterpart is `path: / , pathType: Prefix` on the Synapse
|
||||||
|
Service. The port is the Service's port NUMBER and not its name "http":
|
||||||
|
backendRefs takes a PortNumber, so unlike the Ingress this reference
|
||||||
|
cannot be made by name. ci/run-httproute-match-test.sh is what holds the
|
||||||
|
pair - it fails when a backendRef names a Service, or a port, that the
|
||||||
|
same render does not create.
|
||||||
|
*/}}
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: PathPrefix
|
||||||
|
value: /
|
||||||
|
backendRefs:
|
||||||
|
- name: {{ .Release.Name }}-{{ .Chart.Name }}-service
|
||||||
|
port: 80
|
||||||
|
{{- if .Values.matrix.delegation.enabled }}
|
||||||
|
---
|
||||||
|
{{- /*
|
||||||
|
The delegation route, on the SERVER NAME rather than on the homeserver's host.
|
||||||
|
Gated on matrix.delegation.enabled exactly as the second host rule of the
|
||||||
|
Ingress is, and for the same reason: without the delegation workload there is
|
||||||
|
nothing to route to.
|
||||||
|
|
||||||
|
Its hostname deliberately does NOT fall back to httpRoute.hostnames. The
|
||||||
|
delegation host is matrix.delegation.serverUrl - the Matrix server name, which
|
||||||
|
is a different thing from the homeserver's hostname and is what remote servers
|
||||||
|
resolve. Letting a chart-global hostname list cover it would make the two
|
||||||
|
indistinguishable, and the migration order (homeserver host first, server name
|
||||||
|
last) depends on telling them apart. httpRoute.delegation.hostnames exists for
|
||||||
|
the one case where the server name itself has to move.
|
||||||
|
*/ -}}
|
||||||
|
{{- $delegation := $httpRoute.delegation | default dict -}}
|
||||||
|
{{- $delegationHostnames := $delegation.hostnames | default list -}}
|
||||||
|
{{- if not $delegationHostnames -}}
|
||||||
|
{{- $delegationHostnames = list (required "If delegation is enabled you must provide a serverUrl: set matrix.delegation.serverUrl (used as the delegation HTTPRoute's single hostname when httpRoute.delegation.hostnames is empty) or set httpRoute.delegation.hostnames explicitly" .Values.matrix.delegation.serverUrl) -}}
|
||||||
|
{{- end -}}
|
||||||
|
apiVersion: gateway.networking.k8s.io/v1
|
||||||
|
kind: HTTPRoute
|
||||||
|
metadata:
|
||||||
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-delegation-httproute
|
||||||
|
spec:
|
||||||
|
{{- /*
|
||||||
|
Its own parent, falling back to the homeserver route's. The server name may
|
||||||
|
well be published by a different Gateway than the homeserver host - it is a
|
||||||
|
domain somebody else's website usually owns - and in that case this is where
|
||||||
|
it is said.
|
||||||
|
*/}}
|
||||||
|
parentRefs:
|
||||||
|
{{- toYaml ($delegation.parentRefs | default $parentRefs) | nindent 4 }}
|
||||||
|
hostnames:
|
||||||
|
{{- toYaml $delegationHostnames | nindent 4 }}
|
||||||
|
rules:
|
||||||
|
{{- /*
|
||||||
|
PathPrefix and not Exact, and the same path the Ingress uses: the
|
||||||
|
delegation nginx serves two documents below it
|
||||||
|
(/.well-known/matrix/server and /.well-known/matrix/client), so the
|
||||||
|
prefix has to carry both. NO URLRewrite filter - the delegation nginx's
|
||||||
|
own config answers on the full path, so nothing is stripped, which is
|
||||||
|
also why the #118 prefix/redirect assurance has no precondition to meet
|
||||||
|
here.
|
||||||
|
*/}}
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: PathPrefix
|
||||||
|
value: /.well-known/matrix
|
||||||
|
backendRefs:
|
||||||
|
- name: {{ .Release.Name }}-{{ .Chart.Name }}-delegation-service
|
||||||
|
port: 80
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -119,10 +119,11 @@
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"description": "Gates the whole Ingress template (issue #93). false omits the Ingress and makes clusterIssuer unnecessary - but NOT domain, which the delegation nginx also serves in its /.well-known/matrix/* endpoints.",
|
"description": "Gates the whole Ingress template (issue #93). Mutually exclusive with httpRoute.enabled - the render aborts when both are true. false omits the Ingress and makes clusterIssuer unnecessary - but NOT domain, which the delegation nginx also serves in its /.well-known/matrix/* endpoints and which the HTTPRoute reads as its hostname.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"domain": {
|
"domain": {
|
||||||
|
"description": "The homeserver hostname. Read by the Ingress, by the HTTPRoute (when httpRoute.hostnames is empty) and by the delegation nginx, which serves it inside /.well-known/matrix/client - so it is required in every mode while delegation is on.",
|
||||||
"type": ["string", "null"]
|
"type": ["string", "null"]
|
||||||
},
|
},
|
||||||
"clusterIssuer": {
|
"clusterIssuer": {
|
||||||
@@ -132,13 +133,53 @@
|
|||||||
"type": ["string", "null"]
|
"type": ["string", "null"]
|
||||||
},
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"description": "Extra Ingress annotations, merged with the cert-manager annotation the chart always sets. Free-form keys by nature.",
|
"description": "Extra Ingress annotations, merged with the cert-manager annotation the chart always sets. Free-form keys by nature. INERT IN GATEWAY MODE: the Gateway API has no annotation channel. This installation's live Ingress carries proxy-body-size 50m (which has no counterpart and must be re-established at the Gateway) and a configuration-snippet of more_set_headers directives (which must NOT be re-established - see values.yaml, httpRoute block).",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"httpRoute": {
|
||||||
|
"description": "Gateway-API alternative to the Ingress (Gitea #114). Mutually exclusive with ingress.enabled - the render aborts when both are true, naming both value paths. The chart renders only HTTPRoutes with parentRefs; class and certificate sit on the Gateway and belong to the platform. TWO routes, not one: the Ingress is a single object with two host rules (homeserver at /, delegation at /.well-known/matrix), and an HTTPRoute's hostnames apply to the whole object, so two hostnames wanting different paths and backends must be two objects. NOT COVERED IN THIS MODE: proxy-body-size, which this installation carries at 50m and which Synapse's own max_upload_size has to agree with - see values.yaml, httpRoute block, including why the configuration-snippet on the live object is NOT a loss. The Gateway-API CRDs must be present in the cluster, because the chart cannot detect them.",
|
||||||
|
"type": ["object", "null"],
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"enabled": { "type": "boolean" },
|
||||||
|
"parentRefs": {
|
||||||
|
"description": "The Gateway(s) the homeserver route attaches to. Required while httpRoute.enabled is true, enforced by required()-equivalent in the template (an empty list aborts the render) - a JSON Schema \"required\" cannot do it, because the key ships as an empty list and is therefore present. Entries are the Gateway API's ParentReference and are passed through unchanged.",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/parentRef" }
|
||||||
|
},
|
||||||
|
"hostnames": {
|
||||||
|
"description": "Empty means [ingress.domain], so the homeserver hostname has a single source of truth. Does NOT cover the delegation host - see httpRoute.delegation.hostnames.",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
|
},
|
||||||
|
"delegation": {
|
||||||
|
"description": "The delegation route, rendered while matrix.delegation.enabled is true - the same switch the Ingress's second host rule uses.",
|
||||||
|
"type": ["object", "null"],
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"parentRefs": {
|
||||||
|
"description": "Empty falls back to httpRoute.parentRefs. Worth setting when the server name is published by a different Gateway than the homeserver host, which is the normal case - the server name is an apex domain somebody else's website usually owns.",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/parentRef" }
|
||||||
|
},
|
||||||
|
"hostnames": {
|
||||||
|
"description": "Empty means [matrix.delegation.serverUrl]. Deliberately does NOT fall back to httpRoute.hostnames: the server name is what remote homeservers resolve and is a different thing from the homeserver's hostname, and the migration order depends on telling them apart.",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"parentRef": {
|
||||||
|
"description": "A Gateway API ParentReference, passed verbatim into HTTPRoute.spec.parentRefs. Deliberately left OPEN (no additionalProperties: false), for the same reason probes and security contexts are: Kubernetes owns this schema, the Gateway API adds fields to it across releases, and a closed list here would reject a field only upstream knows about. What the chart can assert is that \"name\" is there - it is required by the API and a reference without it attaches to nothing, which is the silent failure this chart aborts the render over.",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name"]
|
||||||
|
},
|
||||||
"resources": {
|
"resources": {
|
||||||
"description": "May be null / empty: the chart then falls back to its default requests and computed limits (issue #99) instead of rendering a container without resource accounting.",
|
"description": "May be null / empty: the chart then falls back to its default requests and computed limits (issue #99) instead of rendering a container without resource accounting.",
|
||||||
"type": ["object", "null"],
|
"type": ["object", "null"],
|
||||||
|
|||||||
@@ -155,10 +155,133 @@ ingress:
|
|||||||
# read by the delegation nginx, which serves it in the /.well-known/matrix/*
|
# read by the delegation nginx, which serves it in the /.well-known/matrix/*
|
||||||
# endpoints, so it stays required whenever matrix.delegation.enabled is true.
|
# endpoints, so it stays required whenever matrix.delegation.enabled is true.
|
||||||
# Only clusterIssuer becomes unnecessary.
|
# Only clusterIssuer becomes unnecessary.
|
||||||
|
#
|
||||||
|
# MUTUALLY EXCLUSIVE WITH httpRoute.enabled - the render aborts when both are
|
||||||
|
# true, and the message names both value paths.
|
||||||
enabled: true
|
enabled: true
|
||||||
domain: null
|
domain: null
|
||||||
clusterIssuer: null
|
clusterIssuer: null
|
||||||
className: nginx
|
className: nginx
|
||||||
# Extra annotations for the Ingress; merged with the cert-manager
|
# Extra annotations for the Ingress; merged with the cert-manager
|
||||||
# cluster-issuer annotation the chart always sets.
|
# cluster-issuer annotation the chart always sets.
|
||||||
|
#
|
||||||
|
# INERT IN GATEWAY MODE - the Gateway API has no annotation channel for
|
||||||
|
# controller behaviour. For THIS chart that is not a formality: read the
|
||||||
|
# httpRoute block below for what this installation actually has in here and
|
||||||
|
# which half of it matters.
|
||||||
annotations: {}
|
annotations: {}
|
||||||
|
|
||||||
|
# THE GATEWAY-API ALTERNATIVE TO THE INGRESS (Gitea #114).
|
||||||
|
#
|
||||||
|
# Mutually exclusive with ingress.enabled - the render aborts when both are
|
||||||
|
# true. The chart renders ONLY HTTPRoutes with parentRefs: no Gateway, no
|
||||||
|
# class, no Certificate, and no implementation-specific policy object. Class
|
||||||
|
# and certificate sit on the Gateway and its listeners and belong to the
|
||||||
|
# platform (cluster-config), which is what keeps the Gateway implementation
|
||||||
|
# replaceable without touching this chart again.
|
||||||
|
#
|
||||||
|
# TWO ROUTES, not one. The Ingress is a single object with two HOST rules - the
|
||||||
|
# homeserver on ingress.domain at "/", and the delegation nginx on
|
||||||
|
# matrix.delegation.serverUrl at "/.well-known/matrix". An HTTPRoute's
|
||||||
|
# hostnames apply to the whole object, so two hostnames wanting different paths
|
||||||
|
# and different backends must be two objects. (#114 describes this chart as
|
||||||
|
# rendering its Ingresses in a loop over several apps; it does not - that is
|
||||||
|
# freesailarr.)
|
||||||
|
#
|
||||||
|
# ONE THING THIS MODE MAKES EASIER, and it is the awkward part of Matrix
|
||||||
|
# delegation: the server name is usually an apex domain that already serves a
|
||||||
|
# website. Under ingress-nginx two Ingress objects cannot both claim one
|
||||||
|
# hostname - the admission webhook rejects the second - which is why the
|
||||||
|
# delegation rule has to live inside this chart's single Ingress object.
|
||||||
|
# HTTPRoutes attached to the same listener for the same hostname are MERGED by
|
||||||
|
# the implementation, longest match winning, so here the /.well-known/matrix
|
||||||
|
# route can sit beside whatever owns that apex without either side knowing.
|
||||||
|
#
|
||||||
|
# WHAT THIS MODE COSTS, MEASURED ON THE LIVE OBJECT ON 2026-10-12, where the
|
||||||
|
# Ingress carried - all of it OPERATOR-supplied through ingress.annotations,
|
||||||
|
# since this chart sets none of it:
|
||||||
|
#
|
||||||
|
# nginx.ingress.kubernetes.io/proxy-body-size: 50m
|
||||||
|
# nginx.org/client-max-body-size: 50m
|
||||||
|
# nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||||
|
# more_set_headers "X-Forwarded-For $remote_addr";
|
||||||
|
# more_set_headers "X-Forwarded-Proto $scheme";
|
||||||
|
# more_set_headers "Host $host:$server_port";
|
||||||
|
#
|
||||||
|
# 1. THE BODY SIZE IS THE REAL LOSS. Synapse's media repository takes uploads
|
||||||
|
# and its own ceiling is max_upload_size in homeserver.yaml - which this
|
||||||
|
# chart cannot see, because the whole config comes from 1Password through
|
||||||
|
# secrets.configSecretRef. The effective limit is the smaller of the two,
|
||||||
|
# and in this mode the proxy half becomes THE GATEWAY'S default: neither
|
||||||
|
# number anyone can point at is necessarily the one that decides. The
|
||||||
|
# Gateway API has no body-size field, so per decision 2 of #114 this is
|
||||||
|
# documented rather than rebuilt. Set it next to the Gateway, in that
|
||||||
|
# implementation's own object, and set it to match max_upload_size.
|
||||||
|
# (nginx.org/client-max-body-size is the same limit spelled for NGINX Inc's
|
||||||
|
# ingress controller rather than ingress-nginx - a hedge across both - and
|
||||||
|
# it goes for the same reason.)
|
||||||
|
#
|
||||||
|
# 2. THE SNIPPET IS NOT LOAD-BEARING, WHICH TOOK CHECKING. It looks like what
|
||||||
|
# Synapse's x_forwarded setting depends on - client IP for rate limiting,
|
||||||
|
# and federation. It is not: more_set_headers is the OUTPUT-header directive
|
||||||
|
# of headers-more-nginx-module ("Replaces (if any) or adds (if not any) the
|
||||||
|
# specified output headers"), while the request-side directive is
|
||||||
|
# more_set_input_headers. These three headers are therefore added to the
|
||||||
|
# RESPONSE TO THE CLIENT; Synapse never sees them, and what it reads with
|
||||||
|
# x_forwarded: true is the REQUEST's X-Forwarded-For, which ingress-nginx
|
||||||
|
# sets itself.
|
||||||
|
#
|
||||||
|
# So for the migration: not translatable, and not needed. The Gateway API's
|
||||||
|
# ResponseHeaderModifier can set static response headers but knows no nginx
|
||||||
|
# variables ($remote_addr, $scheme, $host), so rebuilding it is impossible
|
||||||
|
# anyway - and pointless. Do NOT re-create it at the Gateway in the belief
|
||||||
|
# that Synapse needs it.
|
||||||
|
#
|
||||||
|
# Stated as what it is: a reading of the directive's documented semantics.
|
||||||
|
# Nothing here observed a Synapse instance with and without the snippet.
|
||||||
|
#
|
||||||
|
# THE GATEWAY-API CRDs MUST BE PRESENT. The chart cannot detect them
|
||||||
|
# (.Capabilities.APIVersions is unreliable at template time) and an HTTPRoute
|
||||||
|
# without them fails at install, so this is a value and not a guess.
|
||||||
|
httpRoute:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# The Gateway(s) the HOMESERVER route attaches to - a platform object,
|
||||||
|
# usually in another namespace, whose listener must allow this namespace in
|
||||||
|
# allowedRoutes. Entries are the Gateway API's ParentReference (name, and
|
||||||
|
# optionally namespace, sectionName, port, group, kind), passed through
|
||||||
|
# unchanged:
|
||||||
|
#
|
||||||
|
# parentRefs:
|
||||||
|
# - name: public
|
||||||
|
# namespace: gateway
|
||||||
|
# sectionName: https
|
||||||
|
#
|
||||||
|
# REQUIRED while httpRoute.enabled is true - the render aborts on an empty
|
||||||
|
# list, because a route without a parent is created, is valid and routes
|
||||||
|
# nothing, with no event to say so.
|
||||||
|
parentRefs: []
|
||||||
|
|
||||||
|
# Empty means [ingress.domain], so the homeserver hostname has one source of
|
||||||
|
# truth. Set explicitly only to publish under a different or an additional
|
||||||
|
# name - which is how a migration from the Ingress runs: the HTTPRoute takes
|
||||||
|
# a second hostname while the Ingress keeps ingress.domain.
|
||||||
|
#
|
||||||
|
# THE DELEGATION HOST IS NOT COVERED BY THIS LIST, deliberately - see below.
|
||||||
|
hostnames: []
|
||||||
|
|
||||||
|
delegation:
|
||||||
|
# The delegation route's own parent. Empty falls back to
|
||||||
|
# httpRoute.parentRefs. Worth setting when the SERVER NAME is published by
|
||||||
|
# a different Gateway than the homeserver host, which is the normal case:
|
||||||
|
# the server name is an apex domain somebody else's website usually owns.
|
||||||
|
parentRefs: []
|
||||||
|
|
||||||
|
# Empty means [matrix.delegation.serverUrl], and it deliberately does NOT
|
||||||
|
# fall back to httpRoute.hostnames. The server name is a different thing
|
||||||
|
# from the homeserver's hostname - it is what REMOTE homeservers resolve -
|
||||||
|
# and the migration order depends on telling them apart: move the
|
||||||
|
# homeserver host first, confirm it answers, move the server name last.
|
||||||
|
# A chart-global hostname list covering both would erase that distinction.
|
||||||
|
# Set this only when the server name itself has to move.
|
||||||
|
hostnames: []
|
||||||
Reference in new issue
Block a user