# BZZZ SLURP Coordinator Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: slurp-coordinator
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/instance: slurp-coordinator
    app.kubernetes.io/component: coordinator
    app.kubernetes.io/part-of: bzzz-slurp
    app.kubernetes.io/version: "1.0.0"
    app.kubernetes.io/managed-by: kubernetes
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: slurp-coordinator
      app.kubernetes.io/instance: slurp-coordinator
  template:
    metadata:
      labels:
        app.kubernetes.io/name: slurp-coordinator
        app.kubernetes.io/instance: slurp-coordinator
        app.kubernetes.io/component: coordinator
        app.kubernetes.io/part-of: bzzz-slurp
        app.kubernetes.io/version: "1.0.0"
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
        prometheus.io/path: "/metrics"
        cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
    spec:
      serviceAccountName: slurp-coordinator
      securityContext:
        runAsNonRoot: true
        runAsUser: 1001
        runAsGroup: 1001
        fsGroup: 1001
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: coordinator
        image: registry.home.deepblack.cloud/bzzz/slurp-coordinator:latest
        imagePullPolicy: Always
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        - name: metrics
          containerPort: 9090
          protocol: TCP
        - name: health
          containerPort: 8081
          protocol: TCP
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: ROLE
          value: "coordinator"
        - name: NODE_ID
          value: "$(POD_NAME)"
        - name: CLUSTER_NAME
          value: "bzzz-slurp-prod"
        - name: LOG_LEVEL
          value: "info"
        - name: ENVIRONMENT
          value: "production"
        - name: METRICS_PORT
          value: "9090"
        - name: HEALTH_PORT
          value: "8081"
        - name: REDIS_ENDPOINT
          value: "redis:6379"
        - name: ELASTICSEARCH_ENDPOINT
          value: "http://elasticsearch:9200"
        - name: JAEGER_AGENT_HOST
          value: "jaeger-agent"
        - name: JAEGER_AGENT_PORT
          value: "6831"
        envFrom:
        - configMapRef:
            name: slurp-config
        - secretRef:
            name: slurp-secrets
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 2
            memory: 4Gi
        livenessProbe:
          httpGet:
            path: /health
            port: health
          initialDelaySeconds: 60
          periodSeconds: 30
          timeoutSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: health
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /startup
            port: health
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 12
        volumeMounts:
        - name: config
          mountPath: /app/config
          readOnly: true
        - name: data
          mountPath: /app/data
        - name: logs
          mountPath: /app/logs
        - name: tmp
          mountPath: /tmp
      - name: monitoring-agent
        image: prom/node-exporter:v1.7.0
        imagePullPolicy: IfNotPresent
        ports:
        - name: node-metrics
          containerPort: 9100
          protocol: TCP
        resources:
          requests:
            cpu: 50m
            memory: 64Mi
          limits:
            cpu: 200m
            memory: 256Mi
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
      volumes:
      - name: config
        configMap:
          name: slurp-config
          defaultMode: 0644
      - name: data
        persistentVolumeClaim:
          claimName: coordinator-data-pvc
      - name: logs
        emptyDir:
          sizeLimit: 1Gi
      - name: tmp
        emptyDir:
          sizeLimit: 500Mi
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app.kubernetes.io/name
                  operator: In
                  values:
                  - slurp-coordinator
              topologyKey: kubernetes.io/hostname
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 50
            preference:
              matchExpressions:
              - key: node-type
                operator: In
                values:
                - coordinator
      tolerations:
      - key: "node.kubernetes.io/not-ready"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 300
      - key: "node.kubernetes.io/unreachable"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 300
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst

---
# Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: slurp-coordinator
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: service-account
automountServiceAccountToken: true

---
# Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: slurp-coordinator
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: rbac
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch"]

---
# Role Binding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: slurp-coordinator
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: rbac
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: slurp-coordinator
subjects:
- kind: ServiceAccount
  name: slurp-coordinator
  namespace: bzzz-slurp

---
# Service
apiVersion: v1
kind: Service
metadata:
  name: slurp-coordinator
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: service
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9090"
    prometheus.io/path: "/metrics"
spec:
  type: ClusterIP
  ports:
  - port: 8080
    targetPort: http
    protocol: TCP
    name: http
  - port: 9090
    targetPort: metrics
    protocol: TCP
    name: metrics
  selector:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/instance: slurp-coordinator

---
# Headless Service for StatefulSet
apiVersion: v1
kind: Service
metadata:
  name: slurp-coordinator-headless
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: headless-service
spec:
  type: ClusterIP
  clusterIP: None
  ports:
  - port: 8080
    targetPort: http
    protocol: TCP
    name: http
  selector:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/instance: slurp-coordinator

---
# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: coordinator-data-pvc
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: storage
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 50Gi

---
# HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: slurp-coordinator-hpa
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: slurp-coordinator
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60

---
# PodDisruptionBudget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: slurp-coordinator-pdb
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-coordinator
    app.kubernetes.io/component: pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: slurp-coordinator
      app.kubernetes.io/instance: slurp-coordinator