Files
orca/internal/daemon/nodes_handler.go
T
Jon Chery 708d983429 feat(P05): health check daemon with /healthz, /readyz, /v1/* handlers
- internal/daemon/server.go: HTTP Server with lifecycle, logging middleware
- internal/daemon/health.go: /healthz (liveness), /readyz (db+ready), /v1/status
- internal/daemon/jobs_handler.go: GET /v1/jobs, /v1/jobs/{id}, /v1/jobs/{id}/tasks
- internal/daemon/nodes_handler.go: GET /v1/nodes
- internal/daemon/tasks_handler.go: GET /v1/tasks (with ?job_id and ?limit)
- internal/daemon/validate.go: input validation for path IDs
- internal/daemon/version.go: ldflags-friendly version var
- internal/store: added TaskRepo.ListRecent for unfiltered task listing
- internal/cli/daemon.go: CLI wiring with signal.NotifyContext shutdown

Personas: backend-engineer (handlers), cli-engineer (CLI wiring),
security-engineer (input validation, no secrets in access logs, slog JSON).

---ci---
project: orca
phase: 5
milestone: v0.1
status: execute
requirements:
  covered: [REQ-006, REQ-017, REQ-019]
  partial: []
---/ci---
2026-06-03 19:23:21 +00:00

32 lines
849 B
Go

package daemon
import (
"context"
"net/http"
"time"
"git.cloudinit.dev/coreci/orca/internal/model"
"git.cloudinit.dev/coreci/orca/internal/store"
)
// handleNodesCollection handles /v1/nodes (GET only in v0.1).
// Node registration is CLI-only; the API is read-only for observability.
func (s *Server) handleNodesCollection(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
return
}
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
nodes, err := store.NewNodeRepo(s.db).List(ctx)
if err != nil {
writeError(w, http.StatusInternalServerError, "failed to list nodes")
return
}
if nodes == nil {
nodes = []*model.Node{}
}
writeJSON(w, http.StatusOK, map[string]any{"nodes": nodes, "count": len(nodes)})
}