apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  labels:
    app: {{ template "elasticsearch.name" . }}
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    component: "{{ .Values.data.name }}"
    heritage: {{ .Release.Service }}
    release: {{ .Release.Name }}
  name: {{ template "elasticsearch.data.fullname" . }}
spec:
  serviceName: {{ template "elasticsearch.data.fullname" . }}
  replicas: {{ .Values.data.replicas }}
  template:
    metadata:
      labels:
        app: {{ template "elasticsearch.name" . }}
        component: "{{ .Values.data.name }}"
        release: {{ .Release.Name }}
        {{- if .Values.data.podAnnotations }}
      annotations:
{{ toYaml .Values.data.podAnnotations | indent 8 }}
        {{- end }}
    spec:
{{- if .Values.data.priorityClassName }}
      priorityClassName: "{{ .Values.data.priorityClassName }}"
{{- end }}
      securityContext:
        fsGroup: 1000
      {{- if eq .Values.data.antiAffinity "hard" }}
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - topologyKey: "kubernetes.io/hostname"
              labelSelector:
                matchLabels:
                  app: "{{ template "elasticsearch.name" . }}"
                  release: "{{ .Release.Name }}"
                  component: "{{ .Values.data.name }}"
      {{- else if eq .Values.data.antiAffinity "soft" }}
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  app: "{{ template "elasticsearch.name" . }}"
                  release: "{{ .Release.Name }}"
                  component: "{{ .Values.data.name }}"
      {{- end }}
{{- if .Values.data.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.data.nodeSelector | indent 8 }}
{{- end }}
{{- if .Values.data.tolerations }}
      tolerations:
{{ toYaml .Values.data.tolerations | indent 8 }}
{{- end }}
      initContainers:
      # see https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html
      # and https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html#mlockall
      - name: "sysctl"
        image: "busybox"
        imagePullPolicy: "Always"
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
      - name: "chown"
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
        command:
        - /bin/bash
        - -c
        - chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/data &&
          chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/logs
        securityContext:
          runAsUser: 0
        volumeMounts:
        - mountPath: /usr/share/elasticsearch/data
          name: data
      containers:
      - name: elasticsearch
        env:
        - name: DISCOVERY_SERVICE
          value: {{ template "elasticsearch.fullname" . }}-discovery.{{ .Release.Namespace }}.svc.{{ .Values.cluster.kubernetesDomain }}
        - name: NODE_MASTER
          value: "false"
        - name: PROCESSORS
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        - name: ES_JAVA_OPTS
          value: "-Djava.net.preferIPv4Stack=true -Xms{{ .Values.data.heapSize }} -Xmx{{ .Values.data.heapSize }}"
        {{- range $key, $value :=  .Values.cluster.env }}
        - name: {{ $key }}
          value: {{ $value | quote }}
        {{- end }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
        ports:
        - containerPort: 9300
          name: transport
{{ if .Values.data.exposeHttp }}
        - containerPort: 9200
          name: http
{{ end }}
        resources:
{{ toYaml .Values.data.resources | indent 12 }}
        readinessProbe:
          httpGet:
            path: /_cluster/health?local=true
            port: 9200
          initialDelaySeconds: 5
        volumeMounts:
        - mountPath: /usr/share/elasticsearch/data
          name: data
        - mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
          name: config
          subPath: elasticsearch.yml
{{- if hasPrefix "2." .Values.image.tag }}
        - mountPath: /usr/share/elasticsearch/config/logging.yml
          name: config
          subPath: logging.yml
{{- end }}
{{- if hasPrefix "5." .Values.image.tag }}
        - mountPath: /usr/share/elasticsearch/config/log4j2.properties
          name: config
          subPath: log4j2.properties
{{- end }}
        - name: config
          mountPath: /pre-stop-hook.sh
          subPath: pre-stop-hook.sh
        - name: config
          mountPath: /post-start-hook.sh
          subPath: post-start-hook.sh
        lifecycle:
          preStop:
            exec:
              command: ["/bin/bash","/pre-stop-hook.sh"]
          postStart:
            exec:
              command: ["/bin/bash","/post-start-hook.sh"]
      terminationGracePeriodSeconds: {{ .Values.data.terminationGracePeriodSeconds }}
{{- if .Values.image.pullSecrets }}
      imagePullSecrets:
      {{- range $pullSecret := .Values.image.pullSecrets }}
        - name: {{ $pullSecret }}
      {{- end }}
{{- end }}
      volumes:
      - name: config
        configMap:
          name: {{ template "elasticsearch.fullname" . }}
  {{- if not .Values.data.persistence.enabled }}
      - name: data
        emptyDir: {}
  {{- else }}
  volumeClaimTemplates:
  - metadata:
      name: {{ .Values.data.persistence.name }}
    spec:
      accessModes:
        - {{ .Values.data.persistence.accessMode | quote }}
    {{- if .Values.data.persistence.storageClass }}
    {{- if (eq "-" .Values.data.persistence.storageClass) }}
      storageClassName: ""
    {{- else }}
      storageClassName: "{{ .Values.data.persistence.storageClass }}"
    {{- end }}
    {{- end }}
      resources:
        requests:
          storage: "{{ .Values.data.persistence.size }}"
  {{- end }}
