---
apiVersion: apps/v1
kind: StatefulSet

metadata:
  name: xray-rabbitmq
  namespace: x-ray
  labels:
    app.kubernetes.io/name: rabbitmq
    app.kubernetes.io/component: message-broker
    app.kubernetes.io/instance: xray
  annotations:
    container.apparmor.security.beta.kubernetes.io/rabbitmq: runtime/default  ##  Policy Id: https://snyk.io/security-rules/SNYK-CC-K8S-32 ✔

spec:
  serviceName: xray-rabbitmq-headless  ##  dependency: create xray-rabbitmq-headless service ✔
  replicas: 1
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app.kubernetes.io/name: rabbitmq  ##  has to match .spec.template.metadata.labels.
      app.kubernetes.io/component: message-broker
      app.kubernetes.io/instance: xray

  template:
    metadata:
      labels:
        app.kubernetes.io/name: rabbitmq  ##  has to match .spec.selector.matchLabels.
        app.kubernetes.io/component: message-broker
        app.kubernetes.io/instance: xray

    spec:
      serviceAccountName: xray-rabbitmq  ##  dependency: create xray-rabbitmq serviceaccount ✔
      terminationGracePeriodSeconds: 120

      securityContext:
        runAsUser: 1001
        fsGroup: 1001
      volumes:

      - name: configuration  ##  dependency: create xray-rabbitmq-config secret ✔
        secret:
          secretName: xray-rabbitmq-config
          items:
          - key: rabbitmq.conf
            path: rabbitmq.conf

      - name: load-definition-volume  ##  dependency: create load-definition secret ✔
        secret:
          secretName: load-definition

      containers:

      - name: rabbitmq
        image: bitnami/rabbitmq:3.8.21-debian-10-r6
        imagePullPolicy: IfNotPresent
        securityContext:
          capabilities:                    ##  Policy Id: https://snyk.io/security-rules/SNYK-CC-K8S-6 ✔
            drop:
              - all
          readOnlyRootFilesystem: false    ##  Policy Id: https://snyk.io/security-rules/SNYK-CC-K8S-8 ✘
          allowPrivilegeEscalation: false  ##  Policy Id: https://snyk.io/security-rules/SNYK-CC-K8S-9 ✔
          runAsNonRoot: true               ##  Policy Id: https://snyk.io/security-rules/SNYK-CC-K8S-10 ✔

        lifecycle:
          preStop:
            exec:
              command:
              - /bin/bash
              - -ec
              - |
                if [[ -f /opt/bitnami/scripts/rabbitmq/nodeshutdown.sh ]]; then
                    /opt/bitnami/scripts/rabbitmq/nodeshutdown.sh -t "120" -d  "false"
                else
                    rabbitmqctl stop_app
                fi

        envFrom:
        - configMapRef:
            name: rabbitmq-env-variables

        env:

        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP

        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name

        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace

        - name: RABBITMQ_NODE_NAME
          value: rabbit@$(MY_POD_NAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE).svc.cluster.local

        - name: K8S_HOSTNAME_SUFFIX
          value: .$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE).svc.cluster.local

        - name: RABBITMQ_MNESIA_DIR
          value: /bitnami/rabbitmq/mnesia/$(RABBITMQ_NODE_NAME)

        - name: RABBITMQ_ERL_COOKIE  ##  dependency: create rabbitmq-app-credentials secret ✔
          valueFrom:
            secretKeyRef:
              key: rabbitmq-erlang-cookie
              name: rabbitmq-app-credentials

        - name: RABBITMQ_USERNAME
          valueFrom:
            secretKeyRef:
              key: username
              name: rabbitmq-app-credentials

        - name: RABBITMQ_PASSWORD  ##  dependency: create rabbitmq-app-credentials secret ✔
          valueFrom:
            secretKeyRef:
              key: rabbitmq-password
              name: rabbitmq-app-credentials

        livenessProbe:
          exec:
            command:
            - /bin/bash
            - -ec
            - rabbitmq-diagnostics -q ping
          failureThreshold: 6
          initialDelaySeconds: 120
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 20

        ports:  ##  Policy Id: https://snyk.io/security-rules/SNYK-CC-K8S-36 ✘
        - containerPort: 5672
          name: amqp   ##  used by AMQP 0-9-1 and 1.0 clients without and with TLS
          protocol: TCP
        - containerPort: 25672
          name: dist   ##  used for inter-node and CLI tools communication, these ports should not be publicly exposed
          protocol: TCP
        - containerPort: 15672
          name: stats  ##  HTTP API clients, management UI and rabbitmqadmin (only if the management plugin is enabled)
          protocol: TCP
        - containerPort: 4369
          name: epmd   ##  a peer discovery service used by RabbitMQ nodes and CLI tools
          protocol: TCP

        readinessProbe:
          exec:
            command:
            - /bin/bash
            - -ec
            - rabbitmq-diagnostics -q check_running && rabbitmq-diagnostics -q check_local_alarms
          failureThreshold: 3
          initialDelaySeconds: 10
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 20

        resources:
          requests:
            cpu: 192m      ##  prod: 500m
            memory: 384Mi  ##  prod: 1Gi
          limits:
            cpu: 384m      ##  prod: 1
            memory: 768Mi  ##  prod: 2Gi

        volumeMounts:

        - name: configuration
          mountPath: /bitnami/rabbitmq/conf

        - name: data
          mountPath: /bitnami/rabbitmq/mnesia

        - name: load-definition-volume
          mountPath: /app
          readOnly: true

  volumeClaimTemplates:
  - metadata:
      name: data
      labels:
        app.kubernetes.io/name: rabbitmq
        app.kubernetes.io/component: message-broker
        app.kubernetes.io/instance: xray
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: default
      resources:
        requests:
          storage: 1Gi
