# tls-init job generate Consul cluster CA and certificates for the Consul servers
# and creates Kubernetes secrets for them.
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ template "consul.fullname" . }}-tls-init
  labels:
    app: {{ template "consul.name" . }}
    chart: {{ template "consul.chart" . }}
    heritage: {{ .Release.Service }}
    release: {{ .Release.Name }}
  annotations:
    "helm.sh/hook": pre-install,pre-upgrade
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy":  hook-succeeded
spec:
  template:
    metadata:
      name: {{ template "consul.fullname" . }}-tls-init
      labels:
        app: {{ template "consul.name" . }}
        chart: {{ template "consul.chart" . }}
        release: {{ .Release.Name }}
        component: tls-init
      annotations:
        "consul.hashicorp.com/connect-inject": "false"
    spec:
      restartPolicy: Never
      serviceAccountName: {{ template "consul.fullname" . }}-tls-init
      {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }}
      volumes:
      - name: consul-ca-cert
        secret:
          secretName: {{ .Values.global.tls.caCert.secretName }}
          items:
          - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
            path: tls.crt
      - name: consul-ca-key
        secret:
          secretName: {{ .Values.global.tls.caKey.secretName }}
          items:
          - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }}
            path: tls.key
      {{- end }}
      containers:
        - name: tls-init
          image: "{{ .Values.global.image }}"
          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          # We're using POST requests below to create secrets via Kubernetes API.
          # Note that in the subsequent runs of the job, POST requests will
          # return a 409 because these secrets would already exist;
          # we are ignoring these response codes.
          command:
            - "/bin/sh"
            - "-ec"
            - |
              {{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }}
              consul tls ca create \
                -domain={{ .Values.global.domain }}
              curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
                https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \
                -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \
                -H "Content-Type: application/json" \
                -H "Accept: application/json" \
                -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.domain }}-agent-ca.pem | base64 | tr -d '\n' )\" }}" > /dev/null
              curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
                https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \
                -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \
                -H "Content-Type: application/json" \
                -H "Accept: application/json" \
                -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-key\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.key\": \"$( cat {{ .Values.global.domain }}-agent-ca-key.pem | base64 | tr -d '\n' )\" }}" > /dev/null
              {{- end }}
              consul tls cert create -server \
                -days=730 \
                {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }}
                -ca=/consul/tls/ca/cert/tls.crt \
                -key=/consul/tls/ca/key/tls.key \
                {{- end }}
                -additional-dnsname='{{ template "consul.fullname" . }}-server' \
                -additional-dnsname='*.{{ template "consul.fullname" . }}-server' \
                -additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}' \
                -additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc' \
                {{- range .Values.global.tls.serverAdditionalIPSANs }}
                -additional-ipaddress={{ . }} \
                {{- end }}
                {{- range .Values.global.tls.serverAdditionalDNSSANs }}
                 -additional-dnsname={{ . }} \
                 {{- end }}
                -dc={{ .Values.global.datacenter }} \
                -domain={{ .Values.global.domain }}
              curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
                https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \
                -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \
                -H "Content-Type: application/json" \
                -H "Accept: application/json" \
                -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-server-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"kubernetes.io/tls\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0.pem | base64 | tr -d '\n' )\", \"tls.key\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0-key.pem | base64 | tr -d '\n' )\" } }" > /dev/null
          {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }}
          volumeMounts:
            - name: consul-ca-cert
              mountPath: /consul/tls/ca/cert
              readOnly: true
            - name: consul-ca-key
              mountPath: /consul/tls/ca/key
              readOnly: true
          {{- end }}
{{- end }}
{{- end }}
