feat(keycloak): one hostname per realm, in both routing modes
Validate Helm Charts / Detect changed charts (pull_request) Successful in 4s
Validate Helm Charts / Resource quantities (pull_request) Successful in 14s
Validate Helm Charts / Selector match (pull_request) Successful in 14s
Validate Helm Charts / HTTPRoute match (pull_request) Successful in 14s
Validate Helm Charts / Build keycloak (pull_request) Successful in 8s
Validate Helm Charts / Trivy config keycloak (pull_request) Successful in 24s
Install-test / Install-test keycloak (pull_request) Successful in 3m29s
Validate Helm Charts / Install-test (pull_request) Successful in 3m29s
Validate Helm Charts / Detect changed charts (pull_request) Successful in 4s
Validate Helm Charts / Resource quantities (pull_request) Successful in 14s
Validate Helm Charts / Selector match (pull_request) Successful in 14s
Validate Helm Charts / HTTPRoute match (pull_request) Successful in 14s
Validate Helm Charts / Build keycloak (pull_request) Successful in 8s
Validate Helm Charts / Trivy config keycloak (pull_request) Successful in 24s
Install-test / Install-test keycloak (pull_request) Successful in 3m29s
Validate Helm Charts / Install-test (pull_request) Successful in 3m29s
keycloak.realmHosts gives a realm a hostname of its own: this release's Service published under a further name, with that name's bare / sent to /realms/<realm>/account/. It renders in BOTH modes - one Ingress per entry carrying nginx.ingress.kubernetes.io/app-root, or one HTTPRoute per entry whose Exact match on / carries a RequestRedirect filter - because a routing value in this repository is mode-independent by design - ingress.domain is read in Gateway mode too - so a feature rendering in one mode only would silently disappear when an installation switched. Default []: nothing renders, and the render is byte-identical to 1.2.0 for the fixture's values in both modes. Minor, additive, no value becomes required. ONE OBJECT PER ENTRY, not one with several hostnames. spec.hostnames applies to the whole object and a rule's matches are path-based, so inside a shared route every entry would match Exact: / and the realm could not be told apart. Names therefore carry the LIST INDEX, as homeassistant's per-host routes do and for the same reason - a realm name is not a dependable object-name fragment. The consequence is written down rather than left to be discovered: reordering the list renames and recreates the objects. THE WORK IS IN THE INGRESS HALF, NOT THE ROUTE. Two convention rules do not survive these objects, and both deviations are required rather than tolerated: tlsSecretName is a per-entry value with NO default, because these hostnames already have certificates and several entries typically share one, so a derived name would ask cert-manager for a second certificate for a name a wildcard already covers; and the cert-manager annotation is OPTIONAL per entry, because cert-manager keys a Certificate by the secret it writes and only one object per secret may request it - the same deliberate omission the qBittorrent object in freesailarr makes. Annotations are per entry too: of the four hostnames this was written for, three carry the proxy-buffer pair and one does not, which a chart-global block could not express. statusCode: 302 is written out at the field's own default. 301 and 302 are both Support: Core, so the portability trap of #119 - an implementation declining an Extended code sets Accepted: False on the WHOLE route - does not apply here; ingress-nginx emits 302 for app-root, and a value that is only accidentally right documents nothing. Five render aborts, each against a failure that reports nothing: an entry without a host (ingress-nginx reads an empty host as a catch-all for the whole controller), without a realm (/realms//account/, a 404 behind a healthy hostname and certificate), without a tlsSecretName in Ingress mode (the controller's default certificate, a browser-only failure), a repeated host or one the release already publishes (webhook rejection in Ingress mode, two merged routes decided by object age in Gateway mode), and a filled list with both modes off (no object at all, and nothing in the release that reveals the list was ignored). The entry-shape checks sit in a shared helper so they exist in both modes, and the Ingress template skips them while httpRoute.enabled is also true so that the specific message cannot hide the mutual-exclusion one. CI: the two entries live in ci/keycloak/test-values.yaml, which ci/httproute/keycloak.yaml is applied on top of, so one definition covers both modes - two Ingress objects in the install-test, two HTTPRoutes in the render test. They cover both Ingress forms, with and without a clusterIssuer, and the render test holds their inertness in Gateway mode. The httproute match test goes from 56 assertions over 21 charts to 60, keycloak's share from 4 to 8 plus two "not checked" lines for the backend-less redirect rules. The #118 prefix/redirect pairing correctly does not fire: it is scoped to rules that strip a prefix, and a realm route strips nothing. NOT IN THIS CHANGE: the migration. Nothing in jk-cluster-config is touched. With the default [] no running system changes, so the order a takeover has to run in is documented instead - remove the objects in the owning repository first, then install with the list filled, because the reverse or both at once is rejected by ingress-nginx's admission webhook and leaves a Fleet bundle in ErrApplied until forceSyncGeneration is raised. Whether anything there depends on those objects BY NAME is unchecked and named as unchecked. Fixes #122
This commit is contained in:
10 files changed
+629
-16
No files matched your search
@@ -30,11 +30,29 @@
|
||||
# parentRefs fall back to httpRoute.parentRefs below - the empty-admin
|
||||
# branch, which is the one an installation hits unless it wants an
|
||||
# internal Gateway.
|
||||
# - both routes' backendRef is checked against the serving Service of the
|
||||
# same render. Both point at the SAME Service, by PORT NUMBER
|
||||
# - every route's backendRef is checked against the serving Service of the
|
||||
# same render. They all point at the SAME Service, by PORT NUMBER
|
||||
# (keycloak.ports.http) rather than by the name "http" the Ingress uses,
|
||||
# because backendRefs takes a PortNumber - so this overlay is what holds
|
||||
# that number against the Service's.
|
||||
# - THE TWO REALM ROUTES (Gitea #122), which come from keycloak.realmHosts in
|
||||
# the fixture rather than from this file. Nothing is repeated here on
|
||||
# purpose: the fixture installs them as Ingress objects and this overlay
|
||||
# turns the same two entries into HTTPRoutes, so one definition covers both
|
||||
# modes and the two halves cannot drift into describing different hostnames.
|
||||
# What the routes add to the two above is a SECOND RULE SHAPE - an Exact
|
||||
# match on / carrying a RequestRedirect filter and no backendRefs at all.
|
||||
# That rule is reported as "not checked" by this test, correctly and by
|
||||
# design: a filter-only rule has no backend to resolve. The assertion it
|
||||
# does earn is on its sibling rule, the PathPrefix one that points at the
|
||||
# Service. The prefix/redirect pairing check of #118 does NOT fire for these
|
||||
# routes and must not: it is scoped to rules that STRIP a prefix with a
|
||||
# ReplacePrefixMatch rewrite, and these strip nothing - they redirect the
|
||||
# bare root of a hostname that serves one realm.
|
||||
# The entries also cover the two Ingress-mode forms (one with a
|
||||
# clusterIssuer, one without) and what this test holds about them is their
|
||||
# INERTNESS: neither tlsSecretName nor clusterIssuer nor the per-entry
|
||||
# annotation may appear anywhere in a rendered route.
|
||||
#
|
||||
# NOT covered here, and it cannot be: that either hostname answers. No Gateway
|
||||
# controller runs in CI, no route reaches "Accepted: True", and the
|
||||
|
||||
@@ -203,6 +203,43 @@ keycloak:
|
||||
mountPath: /opt/keycloak/themes/ci-theme
|
||||
readOnly: true
|
||||
|
||||
# TWO REALM HOSTNAMES (Gitea #122), and they are set HERE rather than in the
|
||||
# Gateway overlay on purpose: ci/httproute/keycloak.yaml is applied on top of
|
||||
# this file, so one definition covers BOTH modes - two Ingress objects in this
|
||||
# install, two HTTPRoutes in the render-only test, from the same two entries.
|
||||
# Defining them in the overlay instead would leave the Ingress half of the
|
||||
# feature with no coverage at all, and it is the half that carries the
|
||||
# required value and the convention deviation.
|
||||
#
|
||||
# WHAT THIS INSTALL ADDS TO THE RENDER TEST, which is the part a cluster-less
|
||||
# check cannot reach: the API server accepts both objects, including the
|
||||
# Service port named BY NAME ("http") - a typo there is invisible until
|
||||
# somebody opens the URL - and the second entry's cert-manager annotation does
|
||||
# not make the apply fail in a cluster without cert-manager. No ingress
|
||||
# controller answers in CI, so neither app-root nor the proxy buffers are
|
||||
# exercised; that is the same gap the two objects above have.
|
||||
#
|
||||
# THE TWO ENTRIES ARE THE TWO FORMS, deliberately:
|
||||
# [0] NO clusterIssuer - the normal case, where the certificate comes from
|
||||
# elsewhere (a wildcard, another release) and this object only consumes
|
||||
# the secret. It also carries a per-entry annotation, which is what
|
||||
# makes the per-entry (rather than chart-global) annotations block a
|
||||
# tested shape rather than an intended one.
|
||||
# [1] WITH clusterIssuer - the case where the certificate is issued for this
|
||||
# entry's own secret.
|
||||
# Both are inert in Gateway mode, and the render test is what holds that: the
|
||||
# routes it renders from these entries must show no trace of either field.
|
||||
realmHosts:
|
||||
- host: realm-one.ci.example.com
|
||||
realm: ci-realm-one
|
||||
tlsSecretName: tls-ci-realm-shared-ingress
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-buffer-size: 16k
|
||||
- host: realm-two.ci.example.com
|
||||
realm: ci-realm-two
|
||||
tlsSecretName: tls-ci-realm-two-ingress
|
||||
clusterIssuer: ci-selfsigned
|
||||
|
||||
ingress:
|
||||
# Left ON although no ingress controller answers in CI: the point is that
|
||||
# both objects are accepted and that the Service port they name BY NAME
|
||||
|
||||
Reference in new issue
Block a user