feat: Implement Phase 2 dashboard for K8s agent system

Lightweight Go-based dashboard for Raspberry Pi cluster:

Backend:
- chi router with REST API
- Embedded static file serving
- JSON file-based state storage
- Health checks and CORS support

Frontend:
- Responsive dark theme UI
- Status view with nodes, alerts, ArgoCD apps
- Pending actions with approve/reject
- Action history and audit trail
- Workflow listing and manual triggers

Deployment:
- Multi-stage Dockerfile (small Alpine image)
- Kubernetes manifests with Pi 3 tolerations
- Resource limits: 32-64Mi memory, 10-100m CPU
- ArgoCD application manifest
- Kustomize configuration

API endpoints:
- GET /api/status - Cluster status
- GET/POST /api/pending - Action management
- GET /api/history - Action audit trail
- GET/POST /api/workflows - Workflow management

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OpenCode Test
2025-12-26 11:34:36 -08:00
parent a80f714fc2
commit 5646508adb
18 changed files with 1712 additions and 0 deletions

45
dashboard/Dockerfile Normal file
View File

@@ -0,0 +1,45 @@
# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /app
# Install dependencies
RUN apk add --no-cache git
# Copy go mod files
COPY go.mod go.sum* ./
RUN go mod download
# Copy source code
COPY . .
# Build binary
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server ./cmd/server
# Final stage - minimal image
FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /app
# Copy binary from builder
COPY --from=builder /server /app/server
# Create data directory
RUN mkdir -p /data
# Expose port
EXPOSE 8080
# Run as non-root user
RUN adduser -D -u 1000 appuser
RUN chown -R appuser:appuser /app /data
USER appuser
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/api/health || exit 1
ENTRYPOINT ["/app/server"]
CMD ["--port", "8080", "--data", "/data"]