---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: es-data
  namespace: monitoring
  labels:
    app: es-data
spec:
  serviceName: es-data
  podManagementPolicy: "Parallel"
  selector:
    matchLabels:
      app: es-data
  replicas: 2
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
          - ReadWriteOnce
        volumeMode: Filesystem
        resources:
          requests:
            storage: 5Gi
        storageClassName: standard
        selector:
          matchLabels:
            app: es-data
  template:
    metadata:
      labels:
        app: es-data
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                  - es-data
            topologyKey: kubernetes.io/hostname
      terminationGracePeriodSeconds: 120
      initContainers:
      - name: init-chown-data
        image: "busybox:1.31.1"
        securityContext:
          runAsUser: 0
        command: ["chown", "-R", "1000:1000", "/usr/share/elasticsearch/data"]
        volumeMounts:
          - name: data
            mountPath: "/usr/share/elasticsearch/data"
      - name: configure-sysctl
        securityContext:
          runAsUser: 0
          privileged: true
        image: "elasticsearch:7.8.0"
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
      containers:
      - name: es-data
        image: "elasticsearch:7.8.0"
        readinessProbe:
          exec:
            command:
              - sh
              - -c
              - |
                #!/usr/bin/env bash -e
                # If the node is starting up wait for the cluster to be ready (request params: "wait_for_status=green&timeout=1s" )
                # Once it has started only check that the node itself is responding
                START_FILE=/tmp/.es_start_file
                http () {
                  local path="${1}"
                  local args="${2}"
                  set -- -XGET -s
                  if [ "$args" != "" ]; then
                    set -- "$@" $args
                  fi
                  if [ -n "${ELASTIC_USERNAME}" ] && [ -n "${ELASTIC_PASSWORD}" ]; then
                    set -- "$@" -u "${ELASTIC_USERNAME}:${ELASTIC_PASSWORD}"
                  fi
                  curl --output /dev/null -k "$@" "http://127.0.0.1:9200${path}"
                }
                if [ -f "${START_FILE}" ]; then
                  echo 'Elasticsearch is already running, lets check the node is healthy'
                  HTTP_CODE=$(http "/" "-w %{http_code}")
                  RC=$?
                  if [[ ${RC} -ne 0 ]]; then
                    echo "curl --output /dev/null -k -XGET -s -w '%{http_code}' \${BASIC_AUTH} http://127.0.0.1:9200/ failed with RC ${RC}"
                    exit ${RC}
                  fi
                  # ready if HTTP code 200, 503 is tolerable if ES version is 6.x
                  if [[ ${HTTP_CODE} == "200" ]]; then
                    exit 0
                  elif [[ ${HTTP_CODE} == "503" && "7" == "6" ]]; then
                    exit 0
                  else
                    echo "curl --output /dev/null -k -XGET -s -w '%{http_code}' \${BASIC_AUTH} http://127.0.0.1:9200/ failed with HTTP code ${HTTP_CODE}"
                    exit 1
                  fi
                else
                  echo 'Waiting for elasticsearch cluster to become ready (request params: "wait_for_status=green&timeout=1s" )'
                  if http "/_cluster/health?wait_for_status=green&timeout=1s" "--fail" ; then
                    touch ${START_FILE}
                    exit 0
                  else
                    echo 'Cluster is not yet ready (request params: "wait_for_status=green&timeout=1s" )'
                    exit 1
                  fi
                fi
          failureThreshold: 3
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 3
          timeoutSeconds: 5
        ports:
        - name: http
          containerPort: 9200
        - name: transport
          containerPort: 9300
        env:
          - name: node.name
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: discovery.seed_hosts
            value: "es-master.monitoring"
          - name: cluster.name
            value: "eslab"
          - name: network.host
            value: "0.0.0.0"
          - name: ES_JAVA_OPTS
            value: "-Xmx512m -Xms512m"
          - name: node.master
            value: "false"
          - name: node.data
            value: "true"
          - name: node.ingest
            value: "false"
        volumeMounts:
          - name: data
            mountPath: /usr/share/elasticsearch/data
