feat: per-host Let's Encrypt cert for instances outside tenant wildcard zone

This commit is contained in:
Tower deploy
2026-05-02 11:10:49 +03:00
parent 4a4efcabb8
commit 0cda7072eb

View File

@@ -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 `.<tenantWildcardHost>`), 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 }}