apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "rabbitmq.fullname" . }}
  labels:
    app: {{ template "rabbitmq.name" . }}
    chart: {{ template "rabbitmq.chart" .  }}
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
spec:
  serviceName: {{ template "rabbitmq.fullname" . }}-headless
  podManagementPolicy: {{ .Values.podManagementPolicy }}
  replicas: {{ .Values.replicas }}
  updateStrategy:
    type: {{ .Values.updateStrategy.type }}
    {{- if (eq "Recreate" .Values.updateStrategy.type) }}
    rollingUpdate: null
    {{- end }}
  selector:
    matchLabels:
      app: {{ template "rabbitmq.name" . }}
      release: "{{ .Release.Name }}"
  template:
    metadata:
      labels:
        app: {{ template "rabbitmq.name" . }}
        release: "{{ .Release.Name }}"
        chart: {{ template "rabbitmq.chart" .  }}
      {{- if .Values.podLabels }}
{{ toYaml .Values.podLabels | indent 8 }}
      {{- end }}
      annotations:
        {{- if or (not .Values.rabbitmq.existingErlangSecret) (not .Values.rabbitmq.existingPasswordSecret) }}
        checksum/secret: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }}
        {{- end }}
      {{- if .Values.podAnnotations }}
{{ toYaml .Values.podAnnotations | indent 8 }}
      {{- end }}
    spec:
      {{- if .Values.schedulerName }}
      schedulerName: "{{ .Values.schedulerName }}"
      {{- end }}
{{- include "rabbitmq.imagePullSecrets" . | indent 6 }}
      {{- if .Values.rbacEnabled}}
      serviceAccountName: {{ template "rabbitmq.fullname" . }}
      {{- end }}
      {{- if .Values.affinity }}
      affinity: {{- include "rabbitmq.tplValue" (dict "value" .Values.affinity "context" .) | nindent 8 }}
      {{- end }}
      {{- if .Values.priorityClassName }}
      priorityClassName: {{ .Values.priorityClassName }}
      {{- end }}
      {{- if .Values.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
      {{- end }}
      {{- if .Values.tolerations }}
      tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
      {{- end }}
      terminationGracePeriodSeconds: 10
      {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled .Values.securityContext.enabled }}
      initContainers:
      - name: volume-permissions
        image: "{{ template "rabbitmq.volumePermissions.image" . }}"
        imagePullPolicy: {{ default "" .Values.volumePermissions.image.pullPolicy | quote }}
        command: ["/bin/chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }}", "{{ .Values.persistence.path }}"]
        securityContext:
          runAsUser: 0
        resources:
{{ toYaml .Values.volumePermissions.resources | indent 10 }}
        volumeMounts:
        - name: data
          mountPath: "{{ .Values.persistence.path }}"
      {{- end }}
      containers:
      - name: rabbitmq
        image: {{ template "rabbitmq.image" . }}
        imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
        command:
         - bash
         - -ec
         - |
            mkdir -p /opt/bitnami/rabbitmq/.rabbitmq/
            mkdir -p /opt/bitnami/rabbitmq/etc/rabbitmq/
            touch /opt/bitnami/rabbitmq/var/lib/rabbitmq/.start
            #persist the erlang cookie in both places for server and cli tools
            echo $RABBITMQ_ERL_COOKIE > /opt/bitnami/rabbitmq/var/lib/rabbitmq/.erlang.cookie
            cp /opt/bitnami/rabbitmq/var/lib/rabbitmq/.erlang.cookie /opt/bitnami/rabbitmq/.rabbitmq/
            #change permission so only the user has access to the cookie file
            chmod 600 /opt/bitnami/rabbitmq/.rabbitmq/.erlang.cookie /opt/bitnami/rabbitmq/var/lib/rabbitmq/.erlang.cookie
            #copy the mounted configuration to both places
            cp  /opt/bitnami/rabbitmq/conf/* /opt/bitnami/rabbitmq/etc/rabbitmq
            # Apply resources limits
            {{- if .Values.rabbitmq.setUlimitNofiles }}
            ulimit -n "${RABBITMQ_ULIMIT_NOFILES}"
            {{- end }}
            #replace the default password that is generated
            sed -i "/CHANGEME/cdefault_pass=${RABBITMQ_PASSWORD//\\/\\\\}" /opt/bitnami/rabbitmq/etc/rabbitmq/rabbitmq.conf
            {{- if and .Values.persistence.enabled .Values.forceBoot.enabled }}
            if [ -d "{{ .Values.persistence.path }}/mnesia/${RABBITMQ_NODENAME}" ]; then rabbitmqctl force_boot; fi
            {{- end }}
            exec rabbitmq-server
        {{- if .Values.resources }}
        resources:
{{ toYaml .Values.resources | indent 10 }}
        {{- end }}
        volumeMounts:
          - name: config-volume
            mountPath: /opt/bitnami/rabbitmq/conf
          - name: healthchecks
            mountPath: /usr/local/sbin/rabbitmq-api-check
            subPath: rabbitmq-api-check
          - name: healthchecks
            mountPath: /usr/local/sbin/rabbitmq-health-check
            subPath: rabbitmq-health-check
          {{- if .Values.rabbitmq.tls.enabled }}
          - name: {{ template "rabbitmq.fullname" . }}-certs
            mountPath: /opt/bitnami/rabbitmq/certs
          {{- end }}
          - name: data
            mountPath: "{{ .Values.persistence.path }}"
          {{- if .Values.rabbitmq.loadDefinition.enabled }}
          - name: load-definition-volume
            mountPath: /app
            readOnly: true
          {{- end }}
        ports:
        - name: epmd
          containerPort: 4369
        - name: amqp
          containerPort: {{ .Values.service.port }}
        {{- if .Values.rabbitmq.tls.enabled }}
        - name: amqp-ssl
          containerPort: {{ .Values.service.tlsPort }}
        {{- end }}
        - name: dist
          containerPort: {{ .Values.service.distPort }}
        - name: stats
          containerPort: {{ .Values.service.managerPort }}
{{- if .Values.service.extraContainerPorts }}
{{ toYaml .Values.service.extraContainerPorts | indent 8 }}
{{- end }}
        {{- if .Values.livenessProbe.enabled }}
        livenessProbe:
          exec:
            command:
              - sh
              - -c
              - rabbitmq-api-check "http://{{ .Values.rabbitmq.username }}:$RABBITMQ_PASSWORD@127.0.0.1:{{ .Values.service.managerPort }}/api/healthchecks/node" '{"status":"ok"}'
          initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
          periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
          failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
          successThreshold: {{ .Values.livenessProbe.successThreshold }}
        {{- end }}
        {{- if .Values.readinessProbe.enabled }}
        readinessProbe:
          exec:
            command:
              - sh
              - -c
              - rabbitmq-health-check "http://{{ .Values.rabbitmq.username }}:$RABBITMQ_PASSWORD@127.0.0.1:{{ .Values.service.managerPort }}/api/healthchecks/node" '{"status":"ok"}'
          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
          periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
          failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
          successThreshold: {{ .Values.readinessProbe.successThreshold }}
        {{- end }}
        {{- if and (gt (.Values.replicas | int) 1) ( eq .Values.rabbitmq.clustering.rebalance true) }}
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh
              - -c
              - until rabbitmqctl cluster_status >/dev/null; do echo Waiting for
                cluster readiness...; sleep 5 ; done; rabbitmq-queues rebalance "all"
        {{- end }}
        env:
          - name: BITNAMI_DEBUG
            value: {{ ternary "true" "false" .Values.image.debug | quote }}
          - name: MY_POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
          - name: MY_POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: MY_POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: K8S_SERVICE_NAME
            value: "{{ template "rabbitmq.fullname" . }}-headless"
          - name: K8S_ADDRESS_TYPE
            value: {{ .Values.rabbitmq.clustering.address_type }}
          {{- if (eq "hostname" .Values.rabbitmq.clustering.address_type) }}
          - name: RABBITMQ_NODENAME
            value: "rabbit@$(MY_POD_NAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE).svc.{{ .Values.rabbitmq.clustering.k8s_domain }}"
          - name: K8S_HOSTNAME_SUFFIX
            value: ".$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE).svc.{{ .Values.rabbitmq.clustering.k8s_domain }}"
          {{- else }}
          - name: RABBITMQ_NODENAME
            {{- if .Values.rabbitmq.rabbitmqClusterNodeName }}
            value: {{ .Values.rabbitmq.rabbitmqClusterNodeName | quote }}
            {{- else }}
            value: "rabbit@$(MY_POD_NAME)"
            {{- end }}
          {{- end }}
          {{- if .Values.ldap.enabled }}
          - name: RABBITMQ_LDAP_ENABLE
            value: "yes"
          - name: RABBITMQ_LDAP_TLS
            value: {{ ternary "yes" "no" .Values.ldap.tls.enabled | quote }}
          - name: RABBITMQ_LDAP_SERVER
            value: {{ .Values.ldap.server }}
          - name: RABBITMQ_LDAP_SERVER_PORT
            value: {{ .Values.ldap.port | quote }}
          - name: RABBITMQ_LDAP_USER_DN_PATTERN
            value: {{ .Values.ldap.user_dn_pattern }}
          {{- end }}
          - name: RABBITMQ_LOGS
            value: {{ .Values.rabbitmq.logs | quote }}
          - name: RABBITMQ_ULIMIT_NOFILES
            value: {{ .Values.rabbitmq.ulimitNofiles | quote }}
          {{- if and .Values.rabbitmq.maxAvailableSchedulers }}
          - name: RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS
            value: {{ printf "+S %s:%s" (toString .Values.rabbitmq.maxAvailableSchedulers) (toString .Values.rabbitmq.onlineSchedulers) -}}
          {{- end }}
          - name: RABBITMQ_USE_LONGNAME
            value: "true"
          - name: RABBITMQ_ERL_COOKIE
            valueFrom:
              secretKeyRef:
                name: {{ template "rabbitmq.secretErlangName" . }}
                key: rabbitmq-erlang-cookie
          - name: RABBITMQ_PASSWORD
            valueFrom:
              secretKeyRef:
                name: {{ template "rabbitmq.secretPasswordName" . }}
                key: rabbitmq-password
          {{- range $key, $value := .Values.rabbitmq.env }}
          - name: {{ $key }}
            value: {{ $value | quote }}
          {{- end }}
{{- if .Values.metrics.enabled }}
      - name: metrics
        image: {{ template "rabbitmq.metrics.image" . }}
        imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }}
        env:
        - name: RABBIT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "rabbitmq.secretPasswordName" . }}
              key: rabbitmq-password
        - name: RABBIT_URL
          value: "http://{{ .Values.metrics.rabbitmqAddress }}:{{ .Values.service.managerPort }}"
        - name: RABBIT_USER
          value: {{ .Values.rabbitmq.username }}
        - name: PUBLISH_PORT
          value: "{{ .Values.metrics.port }}"
        {{ if .Values.metrics.capabilities }}
        - name: RABBIT_CAPABILITIES
          value: "{{ .Values.metrics.capabilities }}"
        {{- end }}
        {{- range $key, $value := .Values.metrics.env }}
        - name: {{ $key }}
          value: {{ $value | quote }}
        {{- end }}
        ports:
        - name: metrics
          containerPort: {{ .Values.metrics.port }}
        {{- if .Values.metrics.livenessProbe.enabled }}
        livenessProbe:
          httpGet:
            path: /metrics
            port: metrics
          initialDelaySeconds: {{ .Values.metrics.livenessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.metrics.livenessProbe.timeoutSeconds }}
          periodSeconds: {{ .Values.metrics.livenessProbe.periodSeconds }}
          failureThreshold: {{ .Values.metrics.livenessProbe.failureThreshold }}
          successThreshold: {{ .Values.metrics.livenessProbe.successThreshold }}
        {{- end }}
        {{- if .Values.metrics.readinessProbe.enabled }}
        readinessProbe:
          httpGet:
            path: /metrics
            port: metrics
          initialDelaySeconds: {{ .Values.metrics.readinessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.metrics.readinessProbe.timeoutSeconds }}
          periodSeconds: {{ .Values.metrics.readinessProbe.periodSeconds }}
          failureThreshold: {{ .Values.metrics.readinessProbe.failureThreshold }}
          successThreshold: {{ .Values.metrics.readinessProbe.successThreshold }}
        {{- end }}
        resources:
{{ toYaml .Values.metrics.resources | indent 10 }}
{{- end }}
      {{- if .Values.securityContext.enabled }}
      securityContext:
        fsGroup: {{ .Values.securityContext.fsGroup }}
        runAsUser: {{ .Values.securityContext.runAsUser }}
        {{- if .Values.securityContext.extra }}
        {{- toYaml .Values.securityContext.extra | nindent 8 }}
        {{- end }}
      {{- end }}
      volumes:
        {{- if .Values.rabbitmq.tls.enabled }}
        - name: {{ template "rabbitmq.fullname" . }}-certs
          secret:
            secretName: {{ if .Values.rabbitmq.tls.existingSecret }}{{ .Values.rabbitmq.tls.existingSecret }}{{- else }}{{ template "rabbitmq.fullname" . }}-certs{{- end }}
            items:
            - key: ca.crt
              path: ca_certificate.pem
            - key: tls.crt
              path: server_certificate.pem
            - key: tls.key
              path: server_key.pem
        {{- end }}
        - name: config-volume
          configMap:
            name: {{ template "rabbitmq.fullname" . }}-config
            items:
            - key: rabbitmq.conf
              path: rabbitmq.conf
        {{- if .Values.rabbitmq.advancedConfiguration}}
            - key: advanced.config
              path: advanced.config
        {{- end }}
            - key: enabled_plugins
              path: enabled_plugins
        - name: healthchecks
          configMap:
            name: {{ template "rabbitmq.fullname" . }}-healthchecks
            items:
            - key: rabbitmq-health-check
              path: rabbitmq-health-check
              mode: 111
            - key: rabbitmq-api-check
              path: rabbitmq-api-check
              mode: 111
        {{- if .Values.rabbitmq.loadDefinition.enabled }}
        - name: load-definition-volume
          secret:
            secretName: {{ .Values.rabbitmq.loadDefinition.secretName | quote }}
        {{- end }}
      {{- if not .Values.persistence.enabled }}
        - name: data
          emptyDir: {}
      {{- else if .Values.persistence.existingClaim }}
        - name: data
          persistentVolumeClaim:
          {{- with .Values.persistence.existingClaim }}
            claimName: {{ tpl . $ }}
          {{- end }}
  {{- else }}
  volumeClaimTemplates:
    - metadata:
        name: data
        labels:
          app: {{ template "rabbitmq.name" . }}
          release: "{{ .Release.Name }}"
          heritage: "{{ .Release.Service }}"
      spec:
        accessModes:
          - {{ .Values.persistence.accessMode | quote }}
        resources:
            requests:
              storage: {{ .Values.persistence.size | quote }}
        {{ include "rabbitmq.storageClass" . }}
  {{- end }}
