# BZZZ SLURP Distributor StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: slurp-distributor
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-distributor
    app.kubernetes.io/instance: slurp-distributor
    app.kubernetes.io/component: distributor
    app.kubernetes.io/part-of: bzzz-slurp
    app.kubernetes.io/version: "1.0.0"
    app.kubernetes.io/managed-by: kubernetes
spec:
  serviceName: slurp-distributor-headless
  replicas: 3
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: slurp-distributor
      app.kubernetes.io/instance: slurp-distributor
  template:
    metadata:
      labels:
        app.kubernetes.io/name: slurp-distributor
        app.kubernetes.io/instance: slurp-distributor
        app.kubernetes.io/component: distributor
        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: "false"
    spec:
      serviceAccountName: slurp-distributor
      securityContext:
        runAsNonRoot: true
        runAsUser: 1001
        runAsGroup: 1001
        fsGroup: 1001
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: distributor
        image: registry.home.deepblack.cloud/bzzz/slurp-distributor:latest
        imagePullPolicy: Always
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        - name: dht-p2p
          containerPort: 11434
          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: "distributor"
        - name: NODE_ID
          value: "$(POD_NAME)"
        - name: CLUSTER_NAME
          value: "bzzz-slurp-prod"
        - name: LOG_LEVEL
          value: "info"
        - name: ENVIRONMENT
          value: "production"
        - name: DHT_PORT
          value: "11434"
        - name: METRICS_PORT
          value: "9090"
        - name: HEALTH_PORT
          value: "8081"
        - name: REPLICATION_FACTOR
          value: "3"
        - name: COORDINATOR_ENDPOINT
          value: "http://slurp-coordinator:8080"
        - name: REDIS_ENDPOINT
          value: "redis:6379"
        - name: MINIO_ENDPOINT
          value: "http://minio:9000"
        - name: ELASTICSEARCH_ENDPOINT
          value: "http://elasticsearch:9200"
        - name: JAEGER_AGENT_HOST
          value: "jaeger-agent"
        - name: JAEGER_AGENT_PORT
          value: "6831"
        # DHT Bootstrap peers - constructed from headless service
        - name: DHT_BOOTSTRAP_PEERS
          value: "slurp-distributor-0.slurp-distributor-headless:11434,slurp-distributor-1.slurp-distributor-headless:11434,slurp-distributor-2.slurp-distributor-headless:11434"
        envFrom:
        - configMapRef:
            name: slurp-config
        - secretRef:
            name: slurp-secrets
        resources:
          requests:
            cpu: 1
            memory: 2Gi
          limits:
            cpu: 4
            memory: 8Gi
        livenessProbe:
          exec:
            command:
            - /slurp-distributor
            - health
          initialDelaySeconds: 60
          periodSeconds: 30
          timeoutSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          exec:
            command:
            - /slurp-distributor
            - ready
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        startupProbe:
          exec:
            command:
            - /slurp-distributor
            - startup
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 18 # 3 minutes
        volumeMounts:
        - name: config
          mountPath: /app/config
          readOnly: true
        - name: data
          mountPath: /app/data
        - name: logs
          mountPath: /app/logs
        - name: tmp
          mountPath: /tmp
      - name: dht-monitor
        image: busybox:1.36-musl
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh"]
        args:
        - -c
        - |
          while true; do
            echo "DHT Status: $(nc -z localhost 11434 && echo 'UP' || echo 'DOWN')"
            sleep 60
          done
        resources:
          requests:
            cpu: 10m
            memory: 16Mi
          limits:
            cpu: 50m
            memory: 64Mi
      volumes:
      - name: config
        configMap:
          name: slurp-config
          defaultMode: 0644
      - name: logs
        emptyDir:
          sizeLimit: 2Gi
      - name: tmp
        emptyDir:
          sizeLimit: 1Gi
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app.kubernetes.io/name
                operator: In
                values:
                - slurp-distributor
            topologyKey: kubernetes.io/hostname
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 50
            preference:
              matchExpressions:
              - key: node-type
                operator: In
                values:
                - storage
                - compute
      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: 60
      dnsPolicy: ClusterFirst
  volumeClaimTemplates:
  - metadata:
      name: data
      labels:
        app.kubernetes.io/name: slurp-distributor
        app.kubernetes.io/component: storage
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: fast-ssd
      resources:
        requests:
          storage: 100Gi

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

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

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

---
# Service
apiVersion: v1
kind: Service
metadata:
  name: slurp-distributor
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-distributor
    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-distributor
    app.kubernetes.io/instance: slurp-distributor

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

---
# DHT P2P Service (NodePort for external connectivity)
apiVersion: v1
kind: Service
metadata:
  name: slurp-distributor-p2p
  namespace: bzzz-slurp
  labels:
    app.kubernetes.io/name: slurp-distributor
    app.kubernetes.io/component: p2p-service
spec:
  type: NodePort
  ports:
  - port: 11434
    targetPort: dht-p2p
    protocol: TCP
    name: dht-p2p
    nodePort: 31434
  selector:
    app.kubernetes.io/name: slurp-distributor
    app.kubernetes.io/instance: slurp-distributor

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