112 lines
4.2 KiB
Go
112 lines
4.2 KiB
Go
package httpserver
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/toki/oto/services/core/internal/cicdstate"
|
|
"github.com/toki/oto/services/core/internal/runnerregistry"
|
|
)
|
|
|
|
// registerRoutes registers all HTTP routes on the given ServeMux.
|
|
// This file exists to separate route registration logic from handler
|
|
// implementation, making it easier to refactor handlers and DTOs later.
|
|
func registerRoutes(mux *http.ServeMux, registry *runnerregistry.Registry, store *cicdstate.Store) {
|
|
mux.HandleFunc("/healthz", handleHealthz)
|
|
mux.HandleFunc("/readyz", handleReadyz)
|
|
mux.HandleFunc("/api/v1/runners/register", handleRunnerRegister(registry))
|
|
mux.HandleFunc("/api/v1/runners/bootstrap-command", handleRunnerBootstrapCommand(registry))
|
|
mux.HandleFunc("/api/v1/runners/{id}/heartbeat", handleRunnerHeartbeat(registry))
|
|
mux.HandleFunc("/api/v1/runners/{id}/disconnect", handleRunnerDisconnect(registry))
|
|
mux.HandleFunc("/api/v1/runners/{id}", handleGetRunner(registry))
|
|
mux.HandleFunc("/bootstrap/oto-agent.sh", handleServeBootstrapScript())
|
|
mux.HandleFunc("/api/v1/", handleRouter(store, registry))
|
|
}
|
|
|
|
// Extract path segments after "/api/v1/"
|
|
func apiPathSegments(path string) []string {
|
|
if !strings.HasPrefix(path, "/api/v1/") {
|
|
return nil
|
|
}
|
|
trimmed := strings.TrimPrefix(path, "/api/v1/")
|
|
trimmed = strings.TrimRight(trimmed, "/")
|
|
if trimmed == "" {
|
|
return nil
|
|
}
|
|
return strings.Split(trimmed, "/")
|
|
}
|
|
|
|
func handleRouter(store *cicdstate.Store, registry *runnerregistry.Registry) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
parts := apiPathSegments(r.URL.Path)
|
|
if parts == nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
switch parts[0] {
|
|
case "jobs":
|
|
switch {
|
|
case len(parts) == 1 && r.Method == http.MethodPost:
|
|
handleCreateJob(store)(w, r)
|
|
case len(parts) == 1 && r.Method == http.MethodGet:
|
|
writeResponse(w, http.StatusMethodNotAllowed, map[string]string{"error": "method not allowed"})
|
|
return
|
|
case len(parts) == 2 && r.Method == http.MethodGet:
|
|
handleGetJob(store)(w, r)
|
|
case len(parts) == 3 && parts[2] == "executions" && r.Method == http.MethodPost:
|
|
handleCreateExecution(store)(w, r)
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
|
|
case "executions":
|
|
if len(parts) < 2 {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
switch {
|
|
case len(parts) == 2 && r.Method == http.MethodGet:
|
|
handleGetExecution(store)(w, r)
|
|
case len(parts) == 3 && parts[2] == "logs" && r.Method == http.MethodPost:
|
|
handleAppendLog(store)(w, r)
|
|
case len(parts) == 3 && parts[2] == "logs" && r.Method == http.MethodGet:
|
|
handleGetLogs(store)(w, r)
|
|
case len(parts) == 3 && parts[2] == "artifacts" && r.Method == http.MethodPost:
|
|
handleAppendArtifact(store)(w, r)
|
|
case len(parts) == 3 && parts[2] == "artifacts" && r.Method == http.MethodGet:
|
|
handleGetArtifacts(store)(w, r)
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
|
|
case "runners":
|
|
if len(parts) < 2 {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
runnerID := parts[1]
|
|
switch {
|
|
case len(parts) == 3 && parts[2] == "status" && r.Method == http.MethodGet:
|
|
handleRunnerStatus(store, registry, runnerID)(w, r)
|
|
case len(parts) == 3 && parts[2] == "self-update" && r.Method == http.MethodPost:
|
|
handleRunnerSelfUpdate(store, registry, runnerID)(w, r)
|
|
case len(parts) == 4 && parts[2] == "jobs" && parts[3] == "claim" && r.Method == http.MethodPost:
|
|
handleRunnerClaimJob(store, registry, runnerID)(w, r)
|
|
case len(parts) == 5 && parts[2] == "executions" && parts[4] == "cancel" && r.Method == http.MethodPost:
|
|
handleRunnerCancelExecution(store, registry, runnerID, parts[3])(w, r)
|
|
case len(parts) == 5 && parts[2] == "executions" && parts[4] == "report" && r.Method == http.MethodPost:
|
|
handleRunnerReportExecution(store, registry, runnerID, parts[3])(w, r)
|
|
case len(parts) == 5 && parts[2] == "executions" && parts[4] == "logs" && r.Method == http.MethodPost:
|
|
handleRunnerAppendLog(store, registry, runnerID, parts[3])(w, r)
|
|
case len(parts) == 5 && parts[2] == "executions" && parts[4] == "artifacts" && r.Method == http.MethodPost:
|
|
handleRunnerAppendArtifact(store, registry, runnerID, parts[3])(w, r)
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
}
|
|
}
|