# helm_charts_core-statefulset.yaml
apiVersion: "apps/v1"
kind: StatefulSet
metadata:
  name: "{{ template "neo4j.core.fullname" . }}"
spec:
  podManagementPolicy: Parallel
  serviceName: {{ template "neo4j.fullname" . }}
  replicas: {{ .Values.core.numberOfServers }}
  selector:
    matchLabels:
      app.kubernetes.io/instance: {{ .Release.Name | quote }}
      app.kubernetes.io/name: {{ template "neo4j.name" . }}
      app.kubernetes.io/component: core
  template:
    metadata:
      labels:
        app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
        app.kubernetes.io/instance: {{ .Release.Name | quote }}
        helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
        app.kubernetes.io/name: {{ template "neo4j.name" . }}
        app.kubernetes.io/component: core
    spec:
      containers:
      - name: {{ template "neo4j.fullname" . }}
        image: "{{ .Values.image }}:{{ .Values.imageTag }}"
        imagePullPolicy: "{{ .Values.imagePullPolicy }}"
        # Most pod config is factored into a different configMap, which is user overrideable.
        envFrom:
          - configMapRef:
              {{- if .Values.core.configMap }}
              name: "{{ .Values.core.configMap }}"
              {{- else }}
              name: {{ template "neo4j.coreConfig.fullname" . }}
              {{- end }}          
        env:
          {{- if .Values.authEnabled }}
          - name: NEO4J_SECRETS_PASSWORD
            valueFrom:
              secretKeyRef:
                name: {{ template "neo4j.secrets.fullname" . }}
                key: neo4j-password
          {{- end }}      
        command:
          - "/bin/bash"
          - "-c"
          - |
            # Making this host the default address, so that advertised addresses are over-rideable
            # by custom configmaps if specified.
            export HOST=$(hostname -f)
            export NEO4J_causal__clustering_discovery__advertised__address=${NEO4J_causal__clustering_discovery__advertised__address:-$HOST}
            export NEO4J_dbms_default__advertised__address=${NEO4J_dbms_default__advertised__address:-$HOST}
            export NEO4J_dbms_connector_bolt_advertised__address=${NEO4J_dbms_connector_bolt_advertised__address:-$HOST}
            export NEO4J_dbms_connector_http_advertised__address=${NEO4J_dbms_connector_http_advertised__address:-$HOST}
            export NEO4J_dbms_connector_https_advertised__address=${NEO4J_dbms_connector_https_advertised__address:-$HOST}
            
            # These settings are *not* overrideable, because they must match the initial_discovery_members
            # In the Neo4j node config, otherwise Neo4j's akka layer will reject connections.
            export NEO4J_causal__clustering_discovery__advertised__address=$(hostname -f):5000
            export NEO4J_causal__clustering_transaction__advertised__address=$(hostname -f):6000
            export NEO4J_causal__clustering_raft__advertised__address=$(hostname -f):7000

            if [ "${AUTH_ENABLED:-}" == "true" ]; then
              export NEO4J_AUTH="neo4j/${NEO4J_SECRETS_PASSWORD}"
            else
              export NEO4J_AUTH="none"
            fi

            echo "Starting Neo4j CORE on $HOST"
            exec /docker-entrypoint.sh "neo4j"
        ports:
        - containerPort: 5000
          name: discovery
        - containerPort: 7000
          name: raft
        - containerPort: 6000
          name: tx
        - containerPort: 7474
          name: browser
        - containerPort: 7687
          name: bolt
        volumeMounts:
        - name: datadir
          mountPath: "{{ .Values.core.persistentVolume.mountPath }}"
          {{- if .Values.core.persistentVolume.subPath }}
          subPath: {{ .Values.core.persistentVolume.subPath }}
          {{- end }}
        - name: plugins
          mountPath: /plugins
        readinessProbe:
          tcpSocket:
            port: 7687
          initialDelaySeconds: 30
          periodSeconds: 3
        livenessProbe:
          initialDelaySeconds: 60
          tcpSocket:
            port: 7687
        resources:
{{ toYaml .Values.resources | indent 10 }}
{{- if .Values.core.sidecarContainers }}
{{ toYaml .Values.core.sidecarContainers | indent 6 }}
{{- end }}
{{- if .Values.imagePullSecret }}
      imagePullSecrets:
      - name: {{ .Values.imagePullSecret }}
{{- end -}}
{{- if .Values.core.initContainers }}
      initContainers:
{{ toYaml .Values.core.initContainers | indent 6 }}
{{- end }}
      volumes:
        {{- if not .Values.core.persistentVolume.enabled }}
        - name: datadir
          emptyDir: {}
        {{- end }}
        - name: plugins
          emptyDir: {}
{{- with .Values.nodeSelector }}
      nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
      affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
      tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
  {{- if .Values.core.persistentVolume.enabled }}
  volumeClaimTemplates:
    - metadata:
        name: datadir
        annotations:
        {{- if .Values.core.persistentVolume.annotations }}
{{ toYaml .Values.core.persistentVolume.annotations | indent 12 }}
        {{- end }}
      spec:
        accessModes:
          - ReadWriteOnce
      {{- if .Values.core.persistentVolume.storageClass }}
      {{- if (eq "-" .Values.core.persistentVolume.storageClass) }}
        storageClassName: ""
      {{- else }}
        storageClassName: "{{ .Values.core.persistentVolume.storageClass }}"
      {{- end }}
      {{- end }}
        resources:
          requests:
            storage: "{{ .Values.core.persistentVolume.size }}"
  {{- end }}