{{- /* The certificate for the MAIL ports, issued by cert-manager and mounted into every node group read-only. WHY THE INGRESS CERTIFICATE IS NOT ENOUGH: the Ingress covers the WebUI and JMAP only. The HA proxy in front of the cluster terminates no TLS, so Stalwart itself has to present a certificate for STARTTLS on 25 and implicit TLS on 465 and 993. Those connections never pass through the ingress controller. WHY NOT STALWART'S OWN ACME: the HA proxy forwards 25, 465 and 993 and not 80, so an HTTP-01 challenge answered by Stalwart is unreachable from outside. DNS-01 inside Stalwart would work and would duplicate what cert-manager already does here. THIS OBJECT ONLY OBTAINS THE FILES. Pointing Stalwart at them is a separate, manual step: the TLS object in the DATABASE has to name the two paths below. Until it does, the mail ports serve whatever default certificate Stalwart generates for itself, and clients see a name mismatch while every Kubernetes object here is green. */ -}} {{- if .Values.certificate.enabled }} {{- $domain := required "A Domain/Host must be provided (ingress.domain) - it is read here for the mail certificate as well as by the Ingress, so it stays required even with ingress.enabled false" .Values.ingress.domain -}} {{- /* An explicit if, NOT .Values.certificate.clusterIssuer | default (required "..." .Values.ingress.clusterIssuer) which is the obvious one-liner and is wrong: Go evaluates a pipeline's arguments eagerly, so required() fires whenever ingress.clusterIssuer is null even though certificate.clusterIssuer is set and the fallback is never needed. Measured: ingress.enabled=false plus certificate.clusterIssuer= aborted the render. */ -}} {{- $issuer := .Values.certificate.clusterIssuer -}} {{- if not $issuer -}} {{- $issuer = required "A Cluster-Issuer must be provided: set certificate.clusterIssuer for the mail certificate (usually a DNS-01 issuer), or ingress.clusterIssuer, which it falls back to" .Values.ingress.clusterIssuer -}} {{- end -}} apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: {{ include "stalwart.fullname" . }}-mail-certificate labels: app: {{ include "stalwart.fullname" . }} spec: # Deliberately NOT the Ingress TLS secret name (tls--stalwart-ingress). # Two separate certificates on purpose: this one usually comes from a # different issuer (DNS-01, see below) and covers different names, and # sharing one secret would make the ingress controller and the mail # listeners fight over which names the certificate has to carry. secretName: tls-{{ include "stalwart.fullname" . }}-mail issuerRef: name: {{ $issuer }} kind: ClusterIssuer group: cert-manager.io dnsNames: - {{ $domain | quote }} {{- range .Values.certificate.extraDnsNames }} - {{ . | quote }} {{- end }} {{- end }}