3588AdminBackend/cmd/managerd/main.go

110 lines
3.3 KiB
Go

package main
import (
"fmt"
"log"
"net/http"
"os"
"3588AdminBackend/internal/api"
"3588AdminBackend/internal/config"
"3588AdminBackend/internal/service"
"3588AdminBackend/internal/web"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
)
func main() {
cfgPath := "managerd.json"
if len(os.Args) > 1 {
cfgPath = os.Args[1]
}
cfg, err := config.LoadConfig(cfgPath)
if err != nil {
log.Fatalf("failed to load config: %v", err)
}
// Initialize Services
agentClient := service.NewAgentClient(cfg)
regSvc := service.NewRegistryService(cfg, agentClient)
discoSvc := service.NewDiscoveryService(cfg, regSvc)
taskSvc := service.NewTaskService(cfg, agentClient, regSvc)
tplSvc := service.NewTemplateService(cfg)
h := api.NewHandler(discoSvc, regSvc, agentClient, taskSvc, tplSvc)
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(cors.Handler(cors.Options{
AllowedOrigins: []string{"http://localhost:5173", "http://127.0.0.1:5173"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-RK-Token", "X-Model-Sha256"},
MaxAge: 300,
}))
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
r.Get("/openapi.json", api.OpenAPI)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/ui", http.StatusFound)
})
ui, err := web.NewUI(discoSvc, regSvc, agentClient, taskSvc, tplSvc)
if err != nil {
log.Fatalf("failed to init ui: %v", err)
}
uiRouter, err := ui.Routes()
if err != nil {
log.Fatalf("failed to init ui routes: %v", err)
}
r.Mount("/ui", http.StripPrefix("/ui", uiRouter))
// API Routes
r.Route("/api", func(r chi.Router) {
r.Post("/discovery/search", h.Search)
r.Get("/devices", h.ListDevices)
r.Post("/devices", h.CreateDevice)
r.Get("/devices/{id}", h.GetDevice)
// Proxy routes for device actions
r.Get("/devices/{id}/info", h.ProxyAgent)
r.Get("/devices/{id}/config/status", h.ProxyAgent)
r.Put("/devices/{id}/config/candidate", h.ProxyAgent)
r.Post("/devices/{id}/reload", h.ProxyAgent)
r.Post("/devices/{id}/rollback", h.ProxyAgent)
r.Get("/devices/{id}/graphs", h.ProxyAgent)
r.Get("/devices/{id}/graphs/{name}", h.ProxyAgent)
r.Get("/devices/{id}/logs", h.ProxyAgent)
r.Post("/devices/{id}/config/apply", h.ProxyAgent)
r.Get("/devices/{id}/models", h.ProxyAgent)
r.Post("/devices/{id}/media-server/start", h.ProxyAgent)
r.Post("/devices/{id}/media-server/restart", h.ProxyAgent)
r.Post("/devices/{id}/media-server/stop", h.ProxyAgent)
r.Get("/devices/{id}/media-server/status", h.ProxyAgent)
// Generic passthrough for device agent /v1/* (covers config/ui/*, face-gallery, etc.)
r.Handle("/devices/{id}/v1/*", http.HandlerFunc(h.ProxyAgentV1))
// Task routes
r.Post("/tasks", h.CreateTask)
r.Get("/tasks", h.ListTasks)
r.Get("/tasks/{id}/events", h.TaskEvents)
// Template routes
r.Get("/templates", h.ListTemplates)
r.Get("/templates/{name}", h.GetTemplate)
// Model routes
r.Post("/devices/{id}/models/upload", h.UploadModel)
})
fmt.Printf("Starting managerd on %s\n", cfg.Listen)
if err := http.ListenAndServe(cfg.Listen, r); err != nil {
log.Fatalf("failed to start server: %v", err)
}
}