rdev/deployments/k8s/base/rdev-api.yaml
jordan 39df51defd feat: Add multi-provider code agent interface with Claude Code and OpenCode adapters
Implements weeks 1-4 of the multi-provider architecture:

Week 1 - Foundation:
- Add domain models (AgentProvider, AgentRequest, AgentEvent, AgentResult)
- Define CodeAgent port interface with Execute, Cancel, Capabilities
- Create thread-safe provider registry with first-registered default

Week 2 - Claude Code Adapter:
- Extract kubectl exec logic into CodeAgent implementation
- Parse stream-json output format (init, message, tool_use, result)
- Support session continuation via --resume flag

Week 3 - OpenCode Adapter:
- HTTP/SSE client for opencode serve API
- Session management (create, send message, abort)
- Event streaming with documented buffer rationale

Week 4 - Quality & Polish:
- Fix race condition in OpenCode Cancel method
- Add AgentRequest.Validate() with ErrPromptRequired, ErrInvalidTimeout
- Document DefaultAvailabilityTimeout constants
- Add HTTP error context for debugging

Also includes:
- Work queue system with PostgreSQL adapter
- Credential store for infrastructure secrets
- Project templates with Woodpecker CI integration
- Comprehensive test coverage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 09:25:51 -07:00

221 lines
5.6 KiB
YAML

# 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.7.2
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"
- name: DB_PORT
value: "5432"
- name: DB_USER
value: "appuser"
- 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)
- 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
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"]
# Pod logs for deployment status
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
# Secrets for TLS certificates (read-only to reference existing)
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
---
# 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