From 0cda7072ebc248c1bef9efeeed65e114e2059e20 Mon Sep 17 00:00:00 2001 From: Tower deploy Date: Sat, 2 May 2026 11:10:49 +0300 Subject: [PATCH] feat: per-host Let's Encrypt cert for instances outside tenant wildcard zone --- templates/ingressroute.yaml | 49 +++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/templates/ingressroute.yaml b/templates/ingressroute.yaml index 63cb029..e50313c 100644 --- a/templates/ingressroute.yaml +++ b/templates/ingressroute.yaml @@ -1,3 +1,46 @@ +{{- /* +TLS source resolution: + + - If the instance domain is COVERED by the tenant's shared wildcard + cert (e.g. instance domain ends in `.`), we + reuse the existing wildcard Secret — no new cert to issue. + - Otherwise (multi-domain tenants deploying on a domain outside their + wildcard zone, e.g. `app.havari.me` when wildcard is + `*.tenants.4th.online`), cert-manager issues a per-host + Let's Encrypt cert via HTTP-01. The IngressRoute references that + cert's Secret instead. + +This logic lives at template render time so a single chart serves both +shapes — operators don't have to think about "which TLS mode am I in". + +`tenantWildcardHost` is set by Tower per-instance from the tenant's +settings (the suffix of the wildcard pattern, without the `*.`). Empty +(legacy / no wildcard configured) → always per-host. +*/}} +{{- $useWildcard := false -}} +{{- if .Values.tenantWildcardHost -}} + {{- if hasSuffix (printf ".%s" .Values.tenantWildcardHost) .Values.instance.domain -}} + {{- $useWildcard = true -}} + {{- end -}} +{{- end -}} + +{{- if not $useWildcard }} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "instance.fullname" . }}-tls + labels: + {{- include "instance.labels" . | nindent 4 }} +spec: + secretName: {{ include "instance.fullname" . }}-tls + issuerRef: + name: {{ .Values.ingress.certIssuer | default "letsencrypt-prod" }} + kind: ClusterIssuer + dnsNames: + - {{ .Values.instance.domain }} +{{- end }} +--- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: @@ -14,8 +57,4 @@ spec: - name: {{ include "instance.fullname" . }}-odoo port: 8069 tls: - # Shared wildcard cert for *.tenants.odoosky.org. The Secret is - # provisioned ONCE per cluster (see infrastructure/cluster/) and - # mirrored into the chart's release namespace by the cluster - # operator. Instances do NOT issue their own certs. - secretName: {{ .Values.ingress.tlsSecret }} + secretName: {{ if $useWildcard }}{{ .Values.ingress.tlsSecret }}{{ else }}{{ include "instance.fullname" . }}-tls{{ end }}