Initial implementation: host lifecycle + PXE + admin dashboard
Go service for Proxmox homelab cluster provisioning. Handles PXE boot, Proxmox autoinstall (answer file generation), cluster join via SSH, and Infrastructure API registration. - Host state machine (registered → pxe_ready → installing → ready) - dnsmasq supervisor with MAC-based allowlist - iPXE script and Proxmox answer file generation - First-boot phone-home → cluster join → infra registration - Operation locking with expiry (409 on conflict) - SSE event hub for real-time dashboard updates - Admin dashboard (host grid, detail, registration form) - Config-driven server types with hot-reload - Docker deployment (multi-stage fat image) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package httpserver
|
||||
|
||||
import (
|
||||
"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
|
||||
UI *api.UI
|
||||
Hub *events.Hub
|
||||
}
|
||||
|
||||
func NewRouter(d Deps) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.Logger)
|
||||
|
||||
// Static files
|
||||
r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.FS(web.Static))))
|
||||
|
||||
// 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("/images", d.UI.ImagesPage)
|
||||
|
||||
// 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)
|
||||
})
|
||||
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user