# rdev-api - Go REST API for controlling claudebox pods
# v0.5 - API Server with Authentication

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rdev-api
  namespace: rdev
  labels:
    app.kubernetes.io/name: rdev-api
    app.kubernetes.io/part-of: rdev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rdev-api
  template:
    metadata:
      labels:
        app: rdev-api
        app.kubernetes.io/name: rdev-api
        app.kubernetes.io/part-of: rdev
    spec:
      serviceAccountName: rdev-api
      containers:
        - name: rdev-api
          image: ghcr.io/orchard9/rdev-api:v0.10.52
          imagePullPolicy: Always

          ports:
            - containerPort: 8080
              name: http

          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"

          securityContext:
            runAsNonRoot: true
            runAsUser: 1000
            readOnlyRootFilesystem: true
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]

          livenessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 10
            periodSeconds: 30

          readinessProbe:
            httpGet:
              path: /ready
              port: http
            initialDelaySeconds: 5
            periodSeconds: 10

          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: PORT
              value: "8080"
            - name: DB_HOST
              value: "postgres.databases.svc.cluster.local"
            - name: DB_PORT
              value: "5432"
            - name: DB_USER
              value: "rdev"
            - name: DB_NAME
              value: "rdev"
            - name: DB_SSL_MODE
              value: "disable"
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: DB_PASSWORD
            - name: RDEV_ADMIN_KEY
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: RDEV_ADMIN_KEY
            - name: CREDENTIAL_ENCRYPTION_KEY
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: CREDENTIAL_ENCRYPTION_KEY
            # Infrastructure adapters for threesix.ai (fallback if not in DB)
            # Note: Using internal service hostnames to avoid hairpin NAT issues
            - name: GITEA_URL
              value: "http://gitea.threesix.svc.cluster.local"
            - name: GITEA_TOKEN
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: GITEA_TOKEN
            - name: CLOUDFLARE_API_TOKEN
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: CLOUDFLARE_API_TOKEN
            - name: CLOUDFLARE_ZONE_ID
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: CLOUDFLARE_ZONE_ID
            - name: WOODPECKER_WEBHOOK_SECRET
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: WOODPECKER_WEBHOOK_SECRET
            - name: WOODPECKER_URL
              value: "http://woodpecker-server.threesix.svc.cluster.local:8000"
            - name: WOODPECKER_API_TOKEN
              valueFrom:
                secretKeyRef:
                  name: rdev-credentials
                  key: WOODPECKER_API_TOKEN
            # CockroachDB for project database provisioning
            - name: CRDB_HOST
              value: "cockroachdb-public.databases.svc.cluster.local"
            - name: CRDB_PORT
              value: "26257"
            - name: CRDB_USER
              value: "root"
            - name: CRDB_SSL_MODE
              value: "disable"
            # Redis for project cache provisioning
            - name: REDIS_HOST
              value: "redis.databases.svc.cluster.local"
            - name: REDIS_PORT
              value: "6379"
            - name: REDIS_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: REDIS_PASSWORD
            # OpenTelemetry
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              value: "otel-collector.observability.svc.cluster.local:4317"

      imagePullSecrets:
        - name: ghcr-secret
---
# Service for rdev-api
apiVersion: v1
kind: Service
metadata:
  name: rdev-api
  namespace: rdev
  labels:
    app.kubernetes.io/name: rdev-api
    app.kubernetes.io/part-of: rdev
spec:
  type: ClusterIP
  selector:
    app: rdev-api
  ports:
    - port: 8080
      targetPort: http
      name: http
---
# ServiceAccount for rdev-api
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rdev-api
  namespace: rdev
---
# Role for rdev-api to exec into claudebox pods and read configmaps
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rdev-api
  namespace: rdev
rules:
# Pod access for discovery and status
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
# Pod exec for command execution
- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create"]
# ConfigMap access for project configuration
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list", "watch"]
---
# RoleBinding for rdev-api
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rdev-api
  namespace: rdev
subjects:
- kind: ServiceAccount
  name: rdev-api
  namespace: rdev
roleRef:
  kind: Role
  name: rdev-api
  apiGroup: rbac.authorization.k8s.io
---
# ClusterRole for rdev-api to deploy projects across namespaces
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: rdev-api-deployer
rules:
# Deployment management
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Service management
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Ingress management
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Namespace verification (check exists before creating)
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "create"]
# Pod logs for deployment status
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
# Secrets for env vars and TLS certificates
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create", "update", "patch"]
---
# ClusterRoleBinding for rdev-api deployer
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: rdev-api-deployer
subjects:
- kind: ServiceAccount
  name: rdev-api
  namespace: rdev
roleRef:
  kind: ClusterRole
  name: rdev-api-deployer
  apiGroup: rbac.authorization.k8s.io
---
# Ingress for rdev-api
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rdev-api
  namespace: rdev
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
spec:
  ingressClassName: traefik
  rules:
  - host: rdev.masq-ops.orchard9.ai
    http:
      paths:
      - backend:
          service:
            name: rdev-api
            port:
              number: 8080
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - rdev.masq-ops.orchard9.ai
    secretName: rdev-api-tls
