{{- if .Values.meshGateway.enabled }}
{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}}
{{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}}
{{- /* The below test checks if clients are disabled (and if so, fails). We use the conditional from other client files and prepend 'not' */ -}}
{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "consul.fullname" . }}-mesh-gateway
  namespace: {{ .Release.Namespace }}
  labels:
    app: {{ template "consul.name" . }}
    chart: {{ template "consul.chart" . }}
    heritage: {{ .Release.Service }}
    release: {{ .Release.Name }}
    component: mesh-gateway
spec:
  replicas: {{ .Values.meshGateway.replicas }}
  selector:
    matchLabels:
      app: {{ template "consul.name" . }}
      chart: {{ template "consul.chart" . }}
      release: {{ .Release.Name }}
      component: mesh-gateway
  template:
    metadata:
      labels:
        app: {{ template "consul.name" . }}
        chart: {{ template "consul.chart" . }}
        release: {{ .Release.Name }}
        component: mesh-gateway
      annotations:
        "consul.hashicorp.com/connect-inject": "false"
        {{- if .Values.meshGateway.annotations }}
        {{- tpl .Values.meshGateway.annotations . | nindent 8 }}
        {{- end }}
    spec:
      {{- if .Values.meshGateway.affinity }}
      affinity:
        {{ tpl .Values.meshGateway.affinity . | nindent 8 | trim }}
      {{- end }}
      {{- if .Values.meshGateway.tolerations }}
      tolerations:
        {{ tpl .Values.meshGateway.tolerations . | nindent 8 | trim }}
      {{- end }}
      terminationGracePeriodSeconds: 10
      serviceAccountName: {{ template "consul.fullname" . }}-mesh-gateway
      volumes:
        - name: consul-bin
          emptyDir: {}
        {{- 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
        {{- end }}
      {{- if .Values.meshGateway.hostNetwork }}
      hostNetwork: {{ .Values.meshGateway.hostNetwork }}
      {{- end }}
      {{- if .Values.meshGateway.dnsPolicy }}
      dnsPolicy: {{ .Values.meshGateway.dnsPolicy }}
      {{- end }}
      initContainers:
        # We use the Envoy image as our base image so we use an init container to
        # copy the Consul binary to a shared directory that can be used when
        # starting Envoy.
        - name: copy-consul-bin
          image: {{ .Values.global.image | quote }}
          command:
          - cp
          - /bin/consul
          - /consul-bin/consul
          volumeMounts:
          - name: consul-bin
            mountPath: /consul-bin
        {{- if .Values.global.bootstrapACLs }}
        # Wait for secret containing acl token to be ready.
        # Doesn't do anything with it but when the main container starts we
        # know that it's been created.
        - name: mesh-gateway-acl-init
          image: {{ .Values.global.imageK8S }}
          command:
            - "/bin/sh"
            - "-ec"
            - |
              consul-k8s acl-init \
                -secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \
                -k8s-namespace={{ .Release.Namespace }} \
                -init-type="sync"
        {{- end }}
      containers:
        - name: mesh-gateway
          image: {{ .Values.meshGateway.imageEnvoy | quote }}
          {{- if .Values.meshGateway.resources }}
          resources:
            {{ tpl .Values.meshGateway.resources . | nindent 12 | trim }}
          {{- end }}
          volumeMounts:
          - name: consul-bin
            mountPath: /consul-bin
          {{- if .Values.global.tls.enabled }}
          - name: consul-ca-cert
            mountPath: /consul/tls/ca
            readOnly: true
          {{- end }}
          env:
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            {{- if .Values.meshGateway.wanAddress.useNodeName }}
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            {{- end }}
            {{- if .Values.global.bootstrapACLs }}
            - name: CONSUL_HTTP_TOKEN
              valueFrom:
                secretKeyRef:
                  name: "{{ template "consul.fullname" . }}-mesh-gateway-acl-token"
                  key: "token"
            {{- end}}
            {{- if .Values.global.tls.enabled }}
            - name: CONSUL_HTTP_ADDR
              value: https://$(HOST_IP):8501
            - name: CONSUL_GRPC_ADDR
              value: https://$(HOST_IP):8502
            - name: CONSUL_CACERT
              value: /consul/tls/ca/tls.crt
            {{- else }}
            - name: CONSUL_HTTP_ADDR
              value: http://$(HOST_IP):8500
            - name: CONSUL_GRPC_ADDR
              value: $(HOST_IP):8502
            {{- end }}
          command:
            # /bin/sh -c is needed so we can use the pod-specific environment
            # variables.
            - "/bin/sh"
            - "-ec"
            - |
              exec /consul-bin/consul connect envoy \
                -mesh-gateway \
                -register \
                -address="${POD_IP}:{{ .Values.meshGateway.containerPort }}" \
                {{- if .Values.meshGateway.wanAddress.host }}
                -wan-address="{{ .Values.meshGateway.wanAddress.host }}:{{ .Values.meshGateway.wanAddress.port }}" \
                {{- else if .Values.meshGateway.wanAddress.useNodeName }}
                -wan-address="${NODE_NAME}:{{ .Values.meshGateway.wanAddress.port }}" \
                {{- else if .Values.meshGateway.wanAddress.useNodeIP }}
                -wan-address="${HOST_IP}:{{ .Values.meshGateway.wanAddress.port }}" \
                {{- end }}
                {{- if and .Values.meshGateway.consulServiceName }}
                {{- if and .Values.global.bootstrapACLs (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end }}
                -service={{ .Values.meshGateway.consulServiceName | quote }} \
                {{- end }}
          {{- if .Values.meshGateway.enableHealthChecks }}
          livenessProbe:
            tcpSocket:
              port: {{ .Values.meshGateway.containerPort }}
            failureThreshold: 3
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 5
          readinessProbe:
            tcpSocket:
              port: {{ .Values.meshGateway.containerPort }}
            failureThreshold: 3
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 5
          {{- end }}
          ports:
            - name: gateway
              containerPort: {{ .Values.meshGateway.containerPort }}
              {{- if .Values.meshGateway.hostPort }}
              hostPort:  {{ .Values.meshGateway.hostPort }}
              {{- end }}
          lifecycle:
            preStop:
              exec:
                command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -id=\"{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}\""]

      {{- if .Values.meshGateway.priorityClassName }}
      priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }}
      {{- end }}
      {{- if .Values.meshGateway.nodeSelector }}
      nodeSelector:
        {{ tpl .Values.meshGateway.nodeSelector . | indent 8 | trim }}
      {{- end }}
{{- end }}
