Add host-mode heartbeat: vetting-agent host + last-seen badge
CI / Lint + build + test (push) Has been cancelled
CI / Lint + build + test (push) Has been cancelled
vetting-agent gains a `host` subcommand that runs as a systemd service
installed by the quick-register one-liner, POSTing every 30s to
/api/v1/hosts/{mac}/heartbeat so the dashboard tile shows "online" or
"Nm ago" without waiting on WoL. Ships dormant client code for the
Phase 2 reboot_for_vetting command so the server can flip it on later
without a binary redeploy.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -15,9 +15,10 @@ import (
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
UI *api.UI
|
||||
Agent *api.Agent
|
||||
LiveDir string // directory containing vmlinuz + initrd.img; "" disables /live
|
||||
UI *api.UI
|
||||
Agent *api.Agent
|
||||
LiveDir string // directory containing vmlinuz + initrd.img; "" disables /live
|
||||
AgentAssetDir string // directory containing vetting-agent-linux-amd64; "" disables /assets
|
||||
}
|
||||
|
||||
func NewRouter(d Deps) http.Handler {
|
||||
@@ -36,6 +37,12 @@ func NewRouter(d Deps) http.Handler {
|
||||
r.Handle("/live/*", http.StripPrefix("/live/", http.FileServer(http.Dir(d.LiveDir))))
|
||||
}
|
||||
|
||||
// Host-mode agent binary is served here so the quick-register
|
||||
// one-liner can curl it without the operator pre-staging anything.
|
||||
if d.AgentAssetDir != "" {
|
||||
r.Handle("/assets/*", http.StripPrefix("/assets/", http.FileServer(http.Dir(d.AgentAssetDir))))
|
||||
}
|
||||
|
||||
// Agent / PXE endpoints — authenticated per-request by bearer token
|
||||
// or by the unforgeable MAC path parameter.
|
||||
r.Get("/ipxe/{mac}", d.Agent.IPXEScript)
|
||||
@@ -54,6 +61,10 @@ func NewRouter(d Deps) http.Handler {
|
||||
// as the browser UI.
|
||||
r.Post("/api/v1/hosts", d.UI.CreateHostJSON)
|
||||
|
||||
// Host-mode agent heartbeat. Keyed by MAC (no bearer token), same
|
||||
// LAN-trust model as /api/v1/hosts.
|
||||
r.Post("/api/v1/hosts/{mac}/heartbeat", d.UI.Heartbeat)
|
||||
|
||||
// Browser UI — no auth; bind to loopback or LAN only, or front
|
||||
// with a reverse proxy if you need a password.
|
||||
r.Get("/", d.UI.Dashboard)
|
||||
|
||||
Reference in New Issue
Block a user