# StatefulSet to run the actual Consul server cluster.
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "consul.fullname" . }}-server
  namespace: {{ .Release.Namespace }}
  labels:
    app: {{ template "consul.name" . }}
    chart: {{ template "consul.chart" . }}
    heritage: {{ .Release.Service }}
    release: {{ .Release.Name }}
    component: server
spec:
  serviceName: {{ template "consul.fullname" . }}-server
  podManagementPolicy: Parallel
  replicas: {{ .Values.server.replicas }}
  {{- if (gt (int .Values.server.updatePartition) 0) }}
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: {{ .Values.server.updatePartition }}
  {{- end }}
  selector:
    matchLabels:
      app: {{ template "consul.name" . }}
      chart: {{ template "consul.chart" . }}
      release: {{ .Release.Name }}
      component: server
      hasDNS: "true"
  template:
    metadata:
      labels:
        app: {{ template "consul.name" . }}
        chart: {{ template "consul.chart" . }}
        release: {{ .Release.Name }}
        component: server
        hasDNS: "true"
      annotations:
        "consul.hashicorp.com/connect-inject": "false"
        {{- if .Values.server.annotations }}
          {{- tpl .Values.server.annotations . | nindent 8 }}
        {{- end }}
    spec:
    {{- if .Values.server.affinity }}
      affinity:
        {{ tpl .Values.server.affinity . | nindent 8 | trim }}
    {{- end }}
    {{- if .Values.server.tolerations }}
      tolerations:
        {{ tpl .Values.server.tolerations . | nindent 8 | trim }}
    {{- end }}
      terminationGracePeriodSeconds: 30
      serviceAccountName: {{ template "consul.fullname" . }}-server
      securityContext:
        fsGroup: 1000
      volumes:
        - name: config
          configMap:
            name: {{ template "consul.fullname" . }}-server-config
        {{- if .Values.global.tls.enabled }}
        - name: consul-ca-cert
          secret:
            {{- if .Values.global.tls.caCert.secretName }}
            secretName: {{ .Values.global.tls.caCert.secretName }}
            {{- else }}
            secretName: {{ template "consul.fullname" . }}-ca-cert
            {{- end }}
            items:
            - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
              path: tls.crt
        - name: tls-server-cert
          secret:
            secretName: {{ template "consul.fullname" . }}-server-cert
        {{- end }}
        {{- range .Values.server.extraVolumes }}
        - name: userconfig-{{ .name }}
          {{ .type }}:
            {{- if (eq .type "configMap") }}
            name: {{ .name }}
            {{- else if (eq .type "secret") }}
            secretName: {{ .name }}
            {{- end }}
        {{- end }}
      {{- if .Values.server.priorityClassName }}
      priorityClassName: {{ .Values.server.priorityClassName | quote }}
      {{- end }}
      containers:
        - name: consul
          image: "{{ default .Values.global.image .Values.server.image }}"
          env:
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }}
            - name: GOSSIP_KEY
              valueFrom:
                secretKeyRef:
                  name: {{ .Values.global.gossipEncryption.secretName }}
                  key: {{ .Values.global.gossipEncryption.secretKey }}
            {{- end }}
            {{- if .Values.global.tls.enabled }}
            - name: CONSUL_HTTP_ADDR
              value: https://localhost:8501
            - name: CONSUL_CACERT
              value: /consul/tls/ca/tls.crt
            {{- end }}
            {{- include "consul.extraEnvironmentVars" .Values.server | nindent 12 }}
          command:
            - "/bin/sh"
            - "-ec"
            - |
              CONSUL_FULLNAME="{{template "consul.fullname" . }}"

              exec /bin/consul agent \
                -advertise="${POD_IP}" \
                -bind=0.0.0.0 \
                -bootstrap-expect={{ .Values.server.bootstrapExpect }} \
                {{- if .Values.global.tls.enabled }}
                -hcl='ca_file = "/consul/tls/ca/tls.crt"' \
                -hcl='cert_file = "/consul/tls/server/tls.crt"' \
                -hcl='key_file = "/consul/tls/server/tls.key"' \
                {{- if .Values.global.tls.verify }}
                -hcl='verify_incoming_rpc = true' \
                -hcl='verify_outgoing = true' \
                -hcl='verify_server_hostname = true' \
                {{- end }}
                -hcl='ports { https = 8501 }' \
                {{- if .Values.global.tls.httpsOnly }}
                -hcl='ports { http = -1 }' \
                {{- end }}
                {{- end }}
                -client=0.0.0.0 \
                -config-dir=/consul/config \
                {{- range .Values.server.extraVolumes }}
                {{- if .load }}
                -config-dir=/consul/userconfig/{{ .name }} \
                {{- end }}
                {{- end }}
                -datacenter={{ .Values.global.datacenter }} \
                -data-dir=/consul/data \
                -domain={{ .Values.global.domain }} \
                {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }}
                -encrypt="${GOSSIP_KEY}" \
                {{- end }}
                {{- if .Values.server.connect }}
                -hcl="connect { enabled = true }" \
                {{- end }}
                {{- if .Values.ui.enabled }}
                -ui \
                {{- end }}
                {{- range $index := until (.Values.server.replicas | int) }}
                -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \
                {{- end }}
                -server
          volumeMounts:
            - name: data-{{ .Release.Namespace }}
              mountPath: /consul/data
            - name: config
              mountPath: /consul/config
            {{- if .Values.global.tls.enabled }}
            - name: consul-ca-cert
              mountPath: /consul/tls/ca/
              readOnly: true
            - name: tls-server-cert
              mountPath: /consul/tls/server
              readOnly: true
            {{- end }}
            {{- range .Values.server.extraVolumes }}
            - name: userconfig-{{ .name }}
              readOnly: true
              mountPath: /consul/userconfig/{{ .name }}
            {{- end }}
          lifecycle:
            preStop:
              exec:
                command:
                - /bin/sh
                - -c
                - consul leave
          ports:
            {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }}
            - containerPort: 8500
              name: http
            {{- end }}
            {{- if .Values.global.tls.enabled }}
            - containerPort: 8501
              name: https
            {{- end }}
            - containerPort: 8301
              name: serflan
            - containerPort: 8302
              name: serfwan
            - containerPort: 8300
              name: server
            - containerPort: 8600
              name: dns-tcp
              protocol: "TCP"
            - containerPort: 8600
              name: dns-udp
              protocol: "UDP"
          readinessProbe:
            # NOTE(mitchellh): when our HTTP status endpoints support the
            # proper status codes, we should switch to that. This is temporary.
            exec:
              command:
                - "/bin/sh"
                - "-ec"
                - |
                  {{- if .Values.global.tls.enabled }}
                  curl \
                    --cacert /consul/tls/ca/tls.crt \
                    https://127.0.0.1:8501/v1/status/leader \
                  {{- else }}
                  curl http://127.0.0.1:8500/v1/status/leader \
                  {{- end }}
                  2>/dev/null | grep -E '".+"'
            failureThreshold: 2
            initialDelaySeconds: 5
            periodSeconds: 3
            successThreshold: 1
            timeoutSeconds: 5
          {{- if .Values.server.resources }}
          resources:
            {{ tpl .Values.server.resources . | nindent 12 | trim }}
          {{- end }}
      {{- if .Values.server.nodeSelector }}
      nodeSelector:
        {{ tpl .Values.server.nodeSelector . | indent 8 | trim }}
      {{- end }}
  volumeClaimTemplates:
    - metadata:
        name: data-{{ .Release.Namespace }}
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: {{ .Values.server.storage }}
        {{- if .Values.server.storageClass }}
        storageClassName: {{ .Values.server.storageClass }}
        {{- end }}
{{- end }}
