fix: address final review findings for master/agent phase 1 (#6)
- inventory: resolve the image reference via ContainerInspect when a moved tag makes ContainerList report the image ID - store: allow reusing a revoked agent's name (partial unique index) and mark the revoked agent's compose/container services removed - web: publish a services event on revoke; no-store on the one-time token page - webauth: reject empty OIDC state; accept the CSRF form token from the body only - agent conn: bound the WebSocket handshake to 30s - hub: log agent_replaced when a connection replaces an older one
This commit is contained in:
@@ -39,9 +39,11 @@ type Hub interface {
|
||||
Disconnect(agentID int64)
|
||||
}
|
||||
|
||||
// Subscriber delivers change signals. *events.Broker satisfies it.
|
||||
type Subscriber interface {
|
||||
// Broker delivers change signals to open streams and accepts signals from
|
||||
// UI actions. *events.Broker satisfies it.
|
||||
type Broker interface {
|
||||
Subscribe() (<-chan events.Topic, func())
|
||||
Publish(t events.Topic)
|
||||
}
|
||||
|
||||
// Config holds values shown in the "add agent" snippet.
|
||||
@@ -53,18 +55,18 @@ type Config struct {
|
||||
|
||||
// Server renders the UI.
|
||||
type Server struct {
|
||||
store Store
|
||||
hub Hub
|
||||
sub Subscriber
|
||||
cfg Config
|
||||
log *slog.Logger
|
||||
now func() time.Time
|
||||
pages map[string]*template.Template
|
||||
store Store
|
||||
hub Hub
|
||||
broker Broker
|
||||
cfg Config
|
||||
log *slog.Logger
|
||||
now func() time.Time
|
||||
pages map[string]*template.Template
|
||||
}
|
||||
|
||||
// New parses the templates. Each page is its own template set so every page
|
||||
// can define its own "content" block.
|
||||
func New(store Store, hub Hub, sub Subscriber, cfg Config, log *slog.Logger) (*Server, error) {
|
||||
func New(store Store, hub Hub, broker Broker, cfg Config, log *slog.Logger) (*Server, error) {
|
||||
funcs := template.FuncMap{"shortRef": shortRef}
|
||||
pages := map[string]*template.Template{}
|
||||
for _, page := range []string{"overview.html", "agents.html", "agent_created.html"} {
|
||||
@@ -74,7 +76,7 @@ func New(store Store, hub Hub, sub Subscriber, cfg Config, log *slog.Logger) (*S
|
||||
}
|
||||
pages[page] = t
|
||||
}
|
||||
return &Server{store: store, hub: hub, sub: sub, cfg: cfg, log: log, now: time.Now, pages: pages}, nil
|
||||
return &Server{store: store, hub: hub, broker: broker, cfg: cfg, log: log, now: time.Now, pages: pages}, nil
|
||||
}
|
||||
|
||||
// Register adds the UI routes to mux. protect wraps every route except
|
||||
@@ -195,6 +197,7 @@ func (s *Server) createAgent(w http.ResponseWriter, r *http.Request) {
|
||||
data := s.base(r, "Agent created")
|
||||
data.Created = agent
|
||||
data.Snippet = agentSnippet(s.cfg, token)
|
||||
w.Header().Set("Cache-Control", "no-store") // the page shows the one-time token
|
||||
s.render(w, http.StatusOK, "agent_created.html", "layout", data)
|
||||
}
|
||||
|
||||
@@ -219,6 +222,7 @@ func (s *Server) revokeAgent(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
s.hub.Disconnect(id)
|
||||
s.broker.Publish(events.Services) // the agent's services were marked removed
|
||||
http.Redirect(w, r, "/agents", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@@ -231,7 +235,7 @@ func (s *Server) events(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("X-Accel-Buffering", "no") // stop nginx from buffering the stream
|
||||
|
||||
ch, cancel := s.sub.Subscribe()
|
||||
ch, cancel := s.broker.Subscribe()
|
||||
defer cancel()
|
||||
|
||||
if _, err := fmt.Fprint(w, ": connected\n\n"); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user