Introduces a full per-tenant Gateway API setup backed by Cilium. The
publishing tenant (the one whose namespace matches
publishing.ingressName) can opt into a Gateway via tenant.spec.gateway
instead of or alongside the existing Service.spec.externalIPs-based
ingress-nginx deployment.
Package layout:
- packages/extra/gateway/ — new Helm chart that renders, per release:
* cert-manager Certificate for the apex and wildcard hostnames.
* One Gateway with three listeners — HTTP:80 (ACME challenges and
redirect), HTTPS:443 wildcard *.<host>, HTTPS:443 apex <host>.
Each listener uses allowedRoutes.namespaces.from=Selector keyed on
label cozystack.io/gateway=<tenant namespace> so system services
can attach HTTPRoutes cross-namespace without ReferenceGrants.
* HTTPRoute http-to-https-redirect (301) on the HTTP listener.
cert-manager's own ACME solver HTTPRoute for
/.well-known/acme-challenge/ will take precedence via Gateway
API's more-specific-path matching rules.
* CiliumLoadBalancerIPPool scoped to the tenant namespace and the
Gateway's cilium-gateway-cozystack Service, so the IPs from
publishing.externalIPs get announced via LB IPAM.
* Render-time guards: fails loudly if released outside the
publishing namespace or if publishing.host is unset.
- packages/apps/tenant/ — new values key 'gateway: false' and a
conditional HelmRelease template that references the gateway
ExternalArtifact when the tenant opts in. Mirrors the existing
ingress toggle verbatim, including labels and Flux reconcile config.
- packages/core/platform/sources/gateway-application.yaml — new
PackageSource cozystack.gateway-application with a single 'default'
variant that wires extra/gateway as a tenant module and dependsOn
cozystack.gateway-api-crds + cozystack.cert-manager.
- packages/core/platform/templates/bundles/system.yaml — loads
cozystack.gateway-application in every system variant so the
ExternalArtifact is materialised before any tenant tries to use it.
- api/apps/v1alpha1/tenant/types.go, values.schema.json, README.md,
packages/system/tenant-rd/cozyrds/tenant.yaml — regenerated to
include the new Gateway bool field on TenantSpec.
- packages/extra/gateway/tests/gateway_test.yaml — 6 helm-unittest
cases covering the IPv4/IPv6/mixed IP paths, empty-entry filtering,
the no-IPs-still-renders-Gateway path, the non-publishing-namespace
guard, and the empty-host guard.
Default behaviour is unchanged: tenants default to gateway=false and
the platform only materialises the ExternalArtifact (no resources
inside any tenant namespace unless it opts in).
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>