apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ include "emqx.fullname" . }}
  namespace: {{ .Release.Namespace }}
  labels:
    app.kubernetes.io/name: {{ include "emqx.name" . }}
    helm.sh/chart: {{ include "emqx.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
  serviceName: {{ include "emqx.fullname" . }}-headless
  podManagementPolicy: {{ .Values.podManagementPolicy }}
  {{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
  volumeClaimTemplates:
    - metadata:
        name: emqx-data
        namespace: {{ .Release.Namespace }}
        labels:
          app.kubernetes.io/name: {{ include "emqx.name" . }}
          app.kubernetes.io/instance: {{ .Release.Name }}
          app.kubernetes.io/managed-by: {{ .Release.Service }}
      spec:
        {{- if .Values.persistence.storageClassName }}
        storageClassName: {{ .Values.persistence.storageClassName | quote }}
        {{- end }}
        accessModes:
          - {{ .Values.persistence.accessMode | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.size | quote }}
  {{- end }}
  updateStrategy:
    type: RollingUpdate
  {{- if .Values.minReadySeconds }}
  minReadySeconds: {{ .Values.minReadySeconds }}
  {{- end }}
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "emqx.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
      {{- with .Values.podLabels }}
          {{- toYaml . | nindent 8 }}
      {{- end }}
        app: {{ include "emqx.name" . }}
        version: {{ .Chart.AppVersion }}
        app.kubernetes.io/name: {{ include "emqx.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
      annotations:
      {{- with .Values.podAnnotations }}
          {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- if .Values.recreatePods }}
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | quote }}
      {{- end }}
    spec:
      serviceAccountName: {{ include "emqx.serviceAccountName" . }}
      {{- if .Values.priorityClassName }}
      priorityClassName: {{ .Values.priorityClassName }}
      {{- end }}
      volumes:
      {{- if .Values.ssl.enabled }}
      - name: ssl-cert
        secret:
          secretName: {{ include "emqx.ssl.secretName" . }}
      {{- end }}
      {{- if not .Values.persistence.enabled }}
      - name: emqx-data
        emptyDir: {}
      {{- else if .Values.persistence.existingClaim }}
      - name: emqx-data
        persistentVolumeClaim:
        {{- with .Values.persistence.existingClaim }}
          claimName: {{ tpl . $ }}
        {{- end }}
      {{- end }}
      {{- if .Values.emqxLicenseSecretName  }}
      - name: emqx-license
        secret:
          secretName: {{ .Values.emqxLicenseSecretName }}
      {{- end }}
    {{- if .Values.extraVolumes }}
      {{- toYaml .Values.extraVolumes | nindent 6 }}
    {{- end }}
      {{- if .Values.podSecurityContext.enabled }}
      securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }}
      {{- end }}
      {{- if .Values.initContainers }}
      initContainers:
        {{- toYaml .Values.initContainers | nindent 8 }}
      {{- end }}
      {{- if .Values.image.pullSecrets }}
      imagePullSecrets:
        {{- range .Values.image.pullSecrets }}
        - name: {{ . }}
      {{- end }}
      {{- end }}
      containers:
        - name: emqx
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          {{- if .Values.containerSecurityContext.enabled }}
          securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }}
          {{- end }}
          ports:
          - name: mqtt
            containerPort: {{ splitList ":" ( .Values.emqxConfig.EMQX_LISTENERS__TCP__DEFAULT__BIND | default "1883" ) | last }}
          - name: mqttssl
            containerPort: {{ splitList ":" ( .Values.emqxConfig.EMQX_LISTENERS__SSL__DEFAULT__BIND | default "8883" ) | last }}
          - name: ws
            containerPort: {{ splitList ":" ( .Values.emqxConfig.EMQX_LISTENERS__WS__DEFAULT__BIND | default "8083" ) | last }}
          - name: wss
            containerPort: {{ splitList ":" ( .Values.emqxConfig.EMQX_LISTENERS__WSS__DEFAULT__BIND | default "8084" ) | last }}
          - name: dashboard
            containerPort: {{ splitList ":" ( .Values.emqxConfig.EMQX_DASHBOARD__LISTENERS__HTTP__BIND | default "18083" ) | last }}
          {{- if not (empty .Values.emqxConfig.EMQX_DASHBOARD__LISTENERS__HTTPS__BIND) }}
          - name: dashboardtls
            containerPort: {{ splitList ":" .Values.emqxConfig.EMQX_DASHBOARD__LISTENERS__HTTPS__BIND | last }}
          {{- end }}
          - name: ekka
            containerPort: 4370
          - name: genrpc-manual
            containerPort: 5369
          env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: metadata.name
          - name: EMQX_HOST
            value: $(POD_NAME).{{ include "emqx.fullname" . }}-headless.{{ .Release.Namespace }}.svc.cluster.local
          envFrom:
            - configMapRef:
                name: {{ include "emqx.fullname" . }}-env
          {{- if .Values.envFromSecret }}
            - secretRef:
                name: {{ .Values.envFromSecret }}
          {{- end }}
          resources:
{{ toYaml .Values.resources | indent 12 }}
          volumeMounts:
          - name: emqx-data
            mountPath: "/opt/emqx/data"
          {{- if .Values.ssl.enabled }}
          - name: ssl-cert
            mountPath: /tmp/ssl
            readOnly: true
          {{- end}}
          {{ if .Values.emqxLicenseSecretName }}
          - name: emqx-license
            mountPath: "/opt/emqx/etc/emqx.lic"
            subPath: "emqx.lic"
            readOnly: true
          {{- end }}
        {{- if .Values.extraVolumeMounts }}
          {{- toYaml .Values.extraVolumeMounts | nindent 10 }}
        {{- end }}
          readinessProbe:
            httpGet:
              path: /status
              port: {{ splitList ":" ( .Values.emqxConfig.EMQX_DASHBOARD__LISTENERS__HTTP__BIND | default "18083" ) | last }}
            initialDelaySeconds: 10
            periodSeconds: 5
            failureThreshold: 30
          livenessProbe:
            httpGet:
              path: /status
              port: {{ splitList ":" ( .Values.emqxConfig.EMQX_DASHBOARD__LISTENERS__HTTP__BIND | default "18083" ) | last }}
            initialDelaySeconds: 60
            periodSeconds: 30
            failureThreshold: 10
    {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
    {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.topologySpreadConstraints }}
      topologySpreadConstraints:
        {{- range . }}
        - maxSkew: {{ .maxSkew }}
          topologyKey: {{ .topologyKey }}
          whenUnsatisfiable: {{ .whenUnsatisfiable }}
          labelSelector:
            matchLabels:
              app.kubernetes.io/name: {{ include "emqx.name" $ }}
              app.kubernetes.io/instance: {{ $.Release.Name }}
        {{- if .minDomains }}
          minDomains: {{ .minDomains }}
        {{- end }}
        {{- if .matchLabelKeys }}
          matchLabelKeys:
            {{- range .matchLabelKeys }}
            - {{ . }}
            {{- end }}
        {{- end }}
        {{- if .nodeAffinityPolicy }}
          nodeAffinityPolicy: {{ .nodeAffinityPolicy }}
        {{- end }}
        {{- if .nodeTaintsPolicy }}
          nodeTaintsPolicy: {{ .nodeTaintsPolicy }}
        {{- end }}
        {{- end }}
    {{- end }}
