# services/typhon/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: typhon
  namespace: climate
  labels:
    app: typhon
spec:
  replicas: 1
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: typhon
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: typhon
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9108"
        prometheus.io/path: "/metrics"
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "typhon"
        vault.hashicorp.com/agent-inject-secret-aci-env.sh: "kv/data/atlas/climate/typhon/ac-infinity"
        vault.hashicorp.com/agent-inject-template-aci-env.sh: |
          {{- with secret "kv/data/atlas/climate/typhon/ac-infinity" -}}
          {{- if index .Data.data "ACI_EMAIL" }}
          export ACI_EMAIL="{{ index .Data.data "ACI_EMAIL" }}"
          {{- end }}
          {{- if index .Data.data "ACI_PASSWORD" }}
          export ACI_PASSWORD="{{ index .Data.data "ACI_PASSWORD" }}"
          {{- end }}
          {{- if index .Data.data "ACI_HOST" }}
          export ACI_HOST="{{ index .Data.data "ACI_HOST" }}"
          {{- end }}
          {{- if index .Data.data "TYPHON_MODE" }}
          export TYPHON_MODE="{{ index .Data.data "TYPHON_MODE" }}"
          {{- end }}
          {{- if index .Data.data "ENABLE_CONTROL_API" }}
          export ENABLE_CONTROL_API="{{ index .Data.data "ENABLE_CONTROL_API" }}"
          {{- end }}
          {{- if index .Data.data "TY_BLE_DEFAULT_MAC" }}
          export TY_BLE_DEFAULT_MAC="{{ index .Data.data "TY_BLE_DEFAULT_MAC" }}"
          {{- end }}
          {{- if index .Data.data "TY_BLE_ALLOWED_MACS" }}
          export TY_BLE_ALLOWED_MACS="{{ index .Data.data "TY_BLE_ALLOWED_MACS" }}"
          {{- end }}
          {{- if index .Data.data "TY_BLE_DEVICE_TYPE" }}
          export TY_BLE_DEVICE_TYPE="{{ index .Data.data "TY_BLE_DEVICE_TYPE" }}"
          {{- end }}
          {{- if index .Data.data "TY_BLE_SCAN_TIMEOUT_MS" }}
          export TY_BLE_SCAN_TIMEOUT_MS="{{ index .Data.data "TY_BLE_SCAN_TIMEOUT_MS" }}"
          {{- end }}
          {{- if index .Data.data "TY_BLE_PORT_BASE" }}
          export TY_BLE_PORT_BASE="{{ index .Data.data "TY_BLE_PORT_BASE" }}"
          {{- end }}
          {{- end -}}
        typhon.bstein.dev/restart-rev: "2"
    spec:
      serviceAccountName: typhon
      imagePullSecrets:
        - name: harbor-regcred
      nodeSelector:
        kubernetes.io/arch: arm64
        node-role.kubernetes.io/worker: "true"
      containers:
        - name: typhon
          image: registry.bstein.dev/bstein/typhon:main
          imagePullPolicy: Always
          command: ["/bin/sh", "-c"]
          args:
            - |
              set -eu
              if [ -f /vault/secrets/aci-env.sh ]; then
                . /vault/secrets/aci-env.sh
              fi
              : "${TYPHON_MODE:=cloud}"
              : "${ENABLE_CONTROL_API:=false}"
              exec node dist/index.js
          env:
            - name: TYPHON_MODE
              value: "cloud"
            - name: ENABLE_CONTROL_API
              value: "false"
            - name: POLL_INTERVAL_SECONDS
              value: "30"
            - name: REQUEST_TIMEOUT_MS
              value: "10000"
            - name: LISTEN_PORT
              value: "9108"
            - name: CONTROL_LISTEN_PORT
              value: "9110"
            - name: TY_BLE_DEVICE_TYPE
              value: "11"
            - name: TY_BLE_SCAN_TIMEOUT_MS
              value: "20000"
            - name: TY_BLE_PORT_BASE
              value: "1"
            - name: LOG_LEVEL
              value: "info"
          ports:
            - name: metrics
              containerPort: 9108
            - name: control
              containerPort: 9110
          volumeMounts:
            - name: tmp
              mountPath: /tmp
          livenessProbe:
            httpGet:
              path: /healthz
              port: metrics
            initialDelaySeconds: 20
            periodSeconds: 20
            timeoutSeconds: 3
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /healthz
              port: metrics
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 3
            failureThreshold: 3
          securityContext:
            runAsNonRoot: true
            runAsUser: 65532
            runAsGroup: 65532
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop: ["ALL"]
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
      volumes:
        - name: tmp
          emptyDir: {}
