package httpserver import ( "io/fs" "net/http" "provisioning/internal/api" "provisioning/internal/events" "provisioning/internal/web" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" ) type Deps struct { HostAPI *api.HostAPI BootAPI *api.BootAPI ImageAPI *api.ImageAPI UI *api.UI Hub *events.Hub ImageDir string } func NewRouter(d Deps) http.Handler { r := chi.NewRouter() r.Use(middleware.RealIP) r.Use(middleware.Recoverer) r.Use(middleware.Logger) // Static files staticFS, _ := fs.Sub(web.Static, "static") r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.FS(staticFS)))) // Boot image files (kernel/initrd served from disk) r.Handle("/images/boot/*", http.StripPrefix("/images/boot/", http.FileServer(http.Dir(d.ImageDir)))) // SSE r.Get("/events", d.Hub.ServeSSE) // Dashboard UI r.Get("/", d.UI.Dashboard) r.Get("/hosts/new", d.UI.NewHostForm) r.Post("/hosts", d.UI.CreateHost) r.Get("/hosts/{id}", d.UI.HostDetail) r.Post("/hosts/{id}/rebuild", d.UI.TriggerRebuild) r.Post("/hosts/{id}/delete", d.UI.DeleteHost) r.Get("/ops/{id}", d.UI.OperationDetail) r.Post("/ops/{id}/cancel", d.UI.CancelOperation) r.Get("/images", d.UI.ImagesPage) r.Get("/images/new", d.UI.NewImageForm) r.Post("/images/upload", d.UI.UploadImage) r.Post("/images/{id}/default", d.UI.SetDefaultImage) r.Post("/images/{id}/delete", d.UI.DeleteImage) // Host JSON API r.Route("/api/hosts", func(r chi.Router) { r.Get("/", d.HostAPI.List) r.Post("/", d.HostAPI.Create) r.Get("/{id}", d.HostAPI.Get) r.Delete("/{id}", d.HostAPI.Delete) r.Post("/{id}/rebuild", d.HostAPI.Rebuild) }) // Image JSON API r.Route("/api/images", func(r chi.Router) { r.Get("/", d.ImageAPI.List) r.Post("/", d.ImageAPI.Upload) r.Get("/{id}", d.ImageAPI.Get) r.Delete("/{id}", d.ImageAPI.Delete) r.Post("/{id}/default", d.ImageAPI.SetDefault) }) // Boot / PXE endpoints r.Get("/ipxe/{mac}", d.BootAPI.IPXEScript) r.Post("/api/boot/answer", d.BootAPI.AnswerFile) r.Post("/api/hosts/{id}/installed", d.BootAPI.InstallComplete) r.Get("/api/hosts/{id}/first-boot-script", d.BootAPI.FirstBootScript) r.Post("/api/hosts/{id}/phone-home", d.BootAPI.PhoneHome) return r }