Validate Helm Charts / Resource quantities (pull_request) Successful in 15s
Validate Helm Charts / Selector match (pull_request) Successful in 14s
Validate Helm Charts / HTTPRoute match (pull_request) Successful in 14s
Validate Helm Charts / Detect changed charts (pull_request) Successful in 4s
Validate Helm Charts / Build rss-bridge (pull_request) Successful in 8s
Validate Helm Charts / Trivy config rss-bridge (pull_request) Successful in 23s
Install-test / Install-test rss-bridge (pull_request) Successful in 1m6s
Validate Helm Charts / Install-test (pull_request) Successful in 1m6s
Publish Helm Chart with patched Application Version / publish-helm-chart (push) Successful in 12s
Publish RSS-Bridge Helm Chart / Publish RSS-Bridge Helm Chart (push) Successful in 12s
SonarQube Analysis / SonarQube Analysis (push) Successful in 45s
PR #124 merged at 12:25 and the maintainer closed #51 one second later, on the strength of that round's green install-test. Three statements that merged with #124 are stale as a result, and they are stale in the direction that matters - they describe a failing test and an open issue: - rss-bridge/templates/rss-bridge.httproute.yaml and values.yaml said the install-test "fails on the Gitea runner (#51)", in the present tense, and values.yaml added "and that test is still red". - ci/httproute/rss-bridge.yaml said "#51 is not closed on the strength of a colour", which was true when written and is now the opposite of what happened. Replaced with what is actually known, and the emphasis moved to the part that outlives the colour: the test went green on a render byte-identical to main, which rules the chart out and leaves the runner - and THE CAUSE WAS NEVER IDENTIFIED. The diagnostic programme in #51 (docker info for userns and the dind configuration, the same image in a local k3d without remapping) was not executed. So a recurrence is a fresh finding rather than a known quirk, and the overlay comment now says so where whoever sees the red will be reading. Also carries the wording change that was already on this branch when #124 merged: the reproduced green is phrased as "every run of that branch since" rather than pinned to a count, because each commit recording the count invalidated it - a third green arrived with the push after "two". Patch bump, per the rule #40 was argued on: a comment in a chart directory is still a change to that chart, so it is a patch plus a publish. No template output changes - the render for the fixture values is byte-identical to the pre-#124 main, which the tests re-confirm.
145 lines
8.8 KiB
YAML
145 lines
8.8 KiB
YAML
{{/*
|
|
The Gateway-API alternative to rss-bridge.ingress.yaml (Gitea #114), and the
|
|
LAST chart of that sweep: 22 charts carried an Ingress template and 21 an
|
|
HTTPRoute template, and the difference was this one. It was held back because
|
|
its install-test had been failing on the Gitea runner (#51), not for anything
|
|
about its shape - and that test went green in the very PR that converted it,
|
|
on a render byte-identical to main, which is what ruled the chart out and left
|
|
the runner. #51 was closed on the strength of that round; the cause was never
|
|
identified, so a recurrence is a fresh finding rather than a known quirk.
|
|
|
|
WHAT THIS RENDERS, AND WHAT IT DELIBERATELY DOES NOT
|
|
|
|
Only an HTTPRoute with parentRefs. No Gateway, no gatewayClassName, no
|
|
Certificate, and no implementation-specific policy object (nginx-gateway-
|
|
fabric's ClientSettingsPolicy, Envoy Gateway's ClientTrafficPolicy or whatever
|
|
the next one calls it). That subset is the part which looks IDENTICAL on
|
|
nginx-gateway-fabric, Cilium, Envoy Gateway and Istio - keeping to it is what
|
|
lets the cluster's implementation be chosen, or changed, without touching this
|
|
chart again. A policy object here would bind the chart to one implementation
|
|
and to a CRD whose presence it cannot check.
|
|
|
|
So the class and the certificate move from this chart to the PLATFORM: they sit
|
|
on the Gateway and its listeners, which belong in cluster-config, not here.
|
|
|
|
ONE OBJECT FOR ALL THREE HOSTNAMES, BECAUSE NOTHING DIFFERS PER HOST
|
|
|
|
spec.hostnames is a LIST and its rules apply to every hostname of the object.
|
|
That is a problem for a chart whose paths differ per host, and this chart is
|
|
the opposite case: every hostname serves the SAME Service at "/" - measured on
|
|
the live Ingress, which carries three host rules with byte-identical path and
|
|
backend. So one object with three hostnames, not three objects.
|
|
|
|
Contrast, because both shapes exist in this repository and the difference is
|
|
not style: homeassistant renders one route PER host entry (its paths differ per
|
|
host), matrix-synapse renders two (homeserver and delegation want different
|
|
paths and different backends), and the keycloak realms of Gitea #122 would need
|
|
one each (app-root differs per host). Here a second object would carry the same
|
|
rule twice.
|
|
|
|
WHY httpRoute.hostnames IS ITS OWN VALUE AND DOES NOT REUSE ingress.hosts
|
|
|
|
The other charts of the sweep fall into two camps, and this chart is in
|
|
neither. Where a chart has ingress.domain - a single public name - empty
|
|
hostnames falls back to it, so there is one source of truth (cyberchef).
|
|
Where a chart has no ingress.domain, httpRoute has no hostnames key at all and
|
|
the names come from the values that already hold them, because a chart-global
|
|
list could not say which app or which host entry it belonged to (freesailarr,
|
|
homeassistant).
|
|
|
|
This chart has no ingress.domain either, but its hostnames are unambiguous:
|
|
one Service, one path, so a chart-global list means exactly one thing. What
|
|
makes reuse of ingress.hosts wrong here is the other half of those entries -
|
|
each carries an OPTIONAL tlsSecretName, which exists only to keep three grown
|
|
certificates alive on their existing secret names (see the deviation note in
|
|
values.yaml). In Gateway mode TLS sits on the Gateway's listener, so those
|
|
names address nothing. Reusing the list would carry a structure whose second
|
|
field is meaningless into the new mode and invite somebody to set it there.
|
|
|
|
Hence: httpRoute.hostnames is a plain list of strings and is MANDATORY in this
|
|
mode. There is no ingress.domain to fall back to, and an empty list would
|
|
render a route matching every request that reaches its listener - on a shared
|
|
Gateway that means answering for hostnames belonging to other releases.
|
|
|
|
AND THEREFORE rss-bridge.tlsGroups IS INERT IN THIS MODE
|
|
|
|
That helper exists for one purpose: group hosts by TLS secret name so that
|
|
hosts sharing a name share one certificate with several SANs. With the
|
|
certificate on the listener there is nothing left for it to group. It is read
|
|
by the Ingress template and by NOTES.txt's Ingress branch, both behind
|
|
ingress.enabled, so this mode simply never calls it. That is a SIMPLIFICATION
|
|
and is named as one rather than quietly translated: the most intricate part of
|
|
this chart's Ingress has no counterpart here because it has no job here.
|
|
|
|
NOTHING IS LOST WITH THE ANNOTATIONS, AND THAT IS MEASURED, NOT ASSUMED
|
|
|
|
Group 3 of the sweep screened the LIVE Ingress objects, not just the charts,
|
|
because an operator's annotation can fill a gap the chart never sets and this
|
|
mode drops ingress.annotations - four of its six charts carried exactly such an
|
|
annotation. The same screen was run here against the running object
|
|
(2026-10-13, read-only kubectl): it carries the cert-manager cluster-issuer
|
|
annotation plus Helm and Rancher/Fleet bookkeeping, and NOT ONE
|
|
nginx.ingress.kubernetes.io annotation. So this is the first chart of the sweep
|
|
whose Gateway branch in NOTES.txt has no loss to explain. ingress.annotations
|
|
is still inert in this mode - whatever a future installation puts there is
|
|
gone - but there is nothing there today to lose.
|
|
|
|
WHY A VALUE AND NOT AUTO-DETECTION
|
|
|
|
.Capabilities.APIVersions is unreliable at template time (it answers from the
|
|
cluster helm happens to be pointed at, and not at all for `helm template`),
|
|
while an HTTPRoute without the Gateway-API CRDs fails at INSTALL time. A chart
|
|
that guessed would therefore sometimes render an object the cluster rejects and
|
|
sometimes silently render nothing. So the mode is a value.
|
|
*/}}
|
|
{{- /*
|
|
Null-safe like every other block this chart dereferences (#99): an override
|
|
written without children - "httpRoute:" with the keys below it deleted - is
|
|
YAML null, and `.Values.httpRoute.enabled` would abort the render with a nil
|
|
pointer. An empty block means "chart defaults apply", and all three defaults
|
|
here are empty or false, so the whole block collapses to "no HTTPRoute".
|
|
*/ -}}
|
|
{{- $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 Service 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. Note that ingress.enabled DEFAULTS TO TRUE in this chart, so switching to Gateway mode means setting ingress.enabled: false explicitly. A migration runs over a SECOND hostname (give httpRoute.hostnames a name the Ingress does not serve) and never over parallel operation of both." -}}
|
|
{{- 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 -}}
|
|
{{- $hostnames := $httpRoute.hostnames | default list -}}
|
|
{{- if not $hostnames -}}
|
|
{{- fail "httpRoute.enabled is true but httpRoute.hostnames is empty - there is no hostname to publish. Unlike most charts here this one has NO ingress.domain to fall back to, and ingress.hosts is deliberately not reused: its entries carry tlsSecretName values that address nothing once TLS sits on the Gateway's listener. An HTTPRoute with no hostnames also does not render nothing - it matches EVERY request reaching its listener, so on a shared Gateway this release would answer for hostnames belonging to other releases. Set the public names explicitly, e.g. httpRoute.hostnames: [rss-bridge.example.com, feeds.example.com]." -}}
|
|
{{- 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 one backend
|
|
Service, repeated once per host rule - RSS-Bridge is served at the root and
|
|
has no second path, so one rule covers all hostnames of this object.
|
|
|
|
The port is the Service's port NUMBER and not its name: backendRefs takes a
|
|
PortNumber, so unlike the Ingress - which references the targetPort by the
|
|
name rss-bridge-port - this reference cannot be made by name, and the 80
|
|
below has to track rss-bridge.service.yaml by hand.
|
|
ci/run-httproute-match-test.sh is what holds that pair: it fails when a
|
|
backendRef names a Service, or a port, the same render does not create.
|
|
*/}}
|
|
- matches:
|
|
- path:
|
|
type: PathPrefix
|
|
value: /
|
|
backendRefs:
|
|
- name: {{ .Release.Name }}-{{ .Chart.Name }}-service
|
|
port: 80
|
|
{{- end }}
|