Documentation
¶
Overview ¶
Package hub implements the Regulus hub: the HTTP server that serves the dashboard and, in later phases, the API and the agent connections.
Index ¶
- Constants
- Variables
- func NewHandler(d Deps) http.Handler
- type AgentInfo
- type AgentSource
- type Deps
- type Enrollment
- type FleetControl
- type Hub
- func (h *Hub) AgentAddr() string
- func (h *Hub) AgentConn() (*grpc.ClientConn, error)
- func (h *Hub) Agents() []AgentInfo
- func (h *Hub) Close() error
- func (h *Hub) CreateEnrollment(ctx context.Context, by, name string) (Enrollment, error)
- func (h *Hub) Layout(ctx context.Context, userID int64) (json.RawMessage, time.Time, bool, error)
- func (h *Hub) Metrics(agentID string) (samples []MetricsSample, known bool)
- func (h *Hub) Registry(ctx context.Context) ([]fleet.Agent, error)
- func (h *Hub) Rejection(id string) (Rejection, bool)
- func (h *Hub) RenameAgent(ctx context.Context, by, id, name string) error
- func (h *Hub) RevokeAgent(ctx context.Context, by, id string) error
- func (h *Hub) RolloutStatus(_ context.Context) (RolloutStatus, error)
- func (h *Hub) SendCommand(ctx context.Context, agentID string, cmd *agentv1.Command) (*agentv1.CommandResult, error)
- func (h *Hub) Serve(ctx context.Context, ln net.Listener) error
- func (h *Hub) SetLayout(ctx context.Context, userID int64, layout json.RawMessage) error
- func (h *Hub) StaleAfter() time.Duration
- func (h *Hub) StartRollout(ctx context.Context, by string, opts RolloutOptions) (RolloutStatus, error)
- func (h *Hub) StopRollout(ctx context.Context, by string) (RolloutStatus, error)
- func (h *Hub) Subscribe() (<-chan []byte, func())
- func (h *Hub) Updates() *update.Manager
- type LayoutStore
- type MetricsSample
- type Option
- type Rejection
- type RolloutAgent
- type RolloutControl
- type RolloutOptions
- type RolloutStatus
- type UpdateControl
Constants ¶
const ( EventRolloutStarted = "update_rollout_started" EventRolloutFinished = "update_rollout_finished" EventAgentUpdated = "update_agent_updated" EventAgentFailed = "update_agent_failed" )
Audit events of the rollout.
const ( AgentPending = "pending" AgentOffered = "offered" // the update was sent; the server is fetching it AgentInstalling = "installing" // handed to the installer; waiting for it to come back AgentUpdated = "updated" AgentFailed = "failed" AgentSkipped = "skipped" // an earlier failure stopped the rollout )
Status of one server in a rollout.
const ( RolloutIdle = "idle" RolloutRunning = "running" RolloutDone = "done" RolloutFailed = "failed" // stopped by a failure RolloutStopped = "stopped" )
State of a rollout.
const BuiltinAgentID = "local"
BuiltinAgentID is the id of the agent that runs inside the hub.
const ReleaseRepo = "CodexCircle/Regulus"
ReleaseRepo is the repository the hub reads releases from.
Variables ¶
var ( ErrAgentNotFound = errors.New("agent is not connected") ErrAgentDisconnected = errors.New("agent disconnected before answering") )
Errors returned by SendCommand.
var ( ErrRolloutRunning = errors.New("an update of the servers is already running") ErrNothingToRoll = errors.New("no connected server runs an older version than this hub") ErrNotRelease = errors.New("this hub is not a release build, so it has no release to offer the servers") )
Errors of the rollout.
var ErrAgentsOff = errors.New("remote agents are off: set agent_listen in the configuration")
ErrAgentsOff is returned when remote agents are not enabled.
Functions ¶
func NewHandler ¶
NewHandler returns the hub HTTP handler. The API (under /api/) requires a login, except for the endpoints of the auth package. The dashboard files and /healthz are public: they hold no data, and the page asks for a login before it shows anything.
Types ¶
type AgentInfo ¶
type AgentInfo struct {
ID string
Version string
System *agentv1.SystemInfo
ConnectedAt time.Time
LastHeartbeat time.Time // zero until the first heartbeat
LastMetrics *agentv1.MetricsReport
// ProtocolVersion is the version negotiated for the connection.
ProtocolVersion uint32
// Compat tells how the agent's release relates to the hub's.
Compat update.Compat
}
AgentInfo is a snapshot of a connected agent.
type AgentSource ¶
type AgentSource interface {
Agents() []AgentInfo
// StaleAfter is how long an agent may stay silent before it is reported as
// stale.
StaleAfter() time.Duration
// Metrics returns the recent metrics of an agent, oldest first; known is
// false for an agent the hub never saw.
Metrics(agentID string) (samples []MetricsSample, known bool)
// Subscribe returns a channel of JSON events (see events.go) and a function
// that ends the subscription. The channel is closed if the subscriber falls
// too far behind.
Subscribe() (events <-chan []byte, cancel func())
}
AgentSource provides the agent data served by the HTTP API. *Hub implements it.
type Deps ¶
type Deps struct {
// UI holds the compiled dashboard.
UI fs.FS
// Agents, Layouts and Log may be nil in tests; the agent list is then empty
// and the layout endpoints answer 404.
Agents AgentSource
Layouts LayoutStore
Log *slog.Logger
// Auth protects the API. A nil Auth leaves it open, which is only meant for
// tests.
Auth *auth.Service
// Fleet enrolls and revokes remote agents. May be nil in tests; the
// endpoints then answer 404.
Fleet FleetControl
// Updates reports and steers the updates of the hub. May be nil in tests;
// the endpoints then answer 404.
Updates UpdateControl
// Rollout updates the managed servers to the version of the hub. May be nil
// in tests; the endpoints then answer 404.
Rollout RolloutControl
}
Deps are what the HTTP handler serves.
type Enrollment ¶
type Enrollment struct {
Token string
Name string
ExpiresAt time.Time
CAFingerprint string
AgentPort int
}
Enrollment is what an admin needs to add a server: the token, valid once, and what the agent must trust.
type FleetControl ¶
type FleetControl interface {
CreateEnrollment(ctx context.Context, by, name string) (Enrollment, error)
RevokeAgent(ctx context.Context, by, id string) error
RenameAgent(ctx context.Context, by, id, name string) error
}
FleetControl is what the HTTP API needs to enroll and revoke remote agents. *Hub implements it.
type Hub ¶
type Hub struct {
// contains filtered or unexported fields
}
Hub is a running-capable hub instance: its configuration, database, UI and the agents connected to it.
func New ¶
func New(ctx context.Context, cfg config.Config, log *slog.Logger, ui fs.FS, opts ...Option) (*Hub, error)
New opens the database (applying migrations) and returns a Hub that serves the dashboard from ui. Call Close when done.
func (*Hub) AgentAddr ¶
AgentAddr is where the listener for remote agents is bound, or "" while it is off.
func (*Hub) AgentConn ¶
func (h *Hub) AgentConn() (*grpc.ClientConn, error)
AgentConn returns a client connection to the hub's agent service over the in-process transport. The built-in agent uses it. Close it when done.
func (*Hub) CreateEnrollment ¶
CreateEnrollment makes a one-time enrollment token.
func (*Hub) Metrics ¶
func (h *Hub) Metrics(agentID string) (samples []MetricsSample, known bool)
Metrics returns the recent metrics reported by an agent, oldest first. known is false when the hub has never seen the agent.
func (*Hub) Rejection ¶
Rejection returns why an enrolled agent was last refused because of its version, if it has not connected since.
func (*Hub) RenameAgent ¶
RenameAgent sets the name shown for an enrolled agent.
func (*Hub) RevokeAgent ¶
RevokeAgent stops an agent from connecting again and drops its connection.
func (*Hub) RolloutStatus ¶
func (h *Hub) RolloutStatus(_ context.Context) (RolloutStatus, error)
RolloutStatus reports the servers that could be updated and what the last rollout did.
func (*Hub) SendCommand ¶
func (h *Hub) SendCommand(ctx context.Context, agentID string, cmd *agentv1.Command) (*agentv1.CommandResult, error)
SendCommand sends a command to a connected agent and waits for its result. It returns ErrAgentNotFound if the agent is not connected and ErrAgentDisconnected if it goes away before answering.
func (*Hub) StaleAfter ¶
StaleAfter is how long an agent may stay silent before it is reported as stale.
func (*Hub) StartRollout ¶
func (h *Hub) StartRollout(ctx context.Context, by string, opts RolloutOptions) (RolloutStatus, error)
StartRollout updates the connected servers that run an older version to the version of this hub, a wave at a time, and stops at the first failure.
func (*Hub) StopRollout ¶
StopRollout lets the servers already handed an update finish and offers it to no other.
type LayoutStore ¶
type LayoutStore interface {
// Layout returns the stored layout; found is false if the user has none.
Layout(ctx context.Context, userID int64) (layout json.RawMessage, updatedAt time.Time, found bool, err error)
SetLayout(ctx context.Context, userID int64, layout json.RawMessage) error
}
LayoutStore keeps the dashboard layout of each user. *Hub implements it.
type MetricsSample ¶
type MetricsSample struct {
At time.Time
Report *agentv1.MetricsReport
}
MetricsSample is one metrics report with the time the hub received it.
type Option ¶
type Option func(*Hub)
Option customizes a Hub.
func WithAgentIntervals ¶
WithAgentIntervals sets the heartbeat and metrics intervals the hub asks agents to use. Mostly useful in tests.
func WithUpdateSource ¶
WithUpdateSource replaces the place the hub looks for new releases. Mostly useful in tests.
func WithUpdateVerifier ¶
WithUpdateVerifier replaces the check of the signature of downloaded releases. Only for tests: a hub without it never trusts an unsigned release.
func WithVersion ¶
WithVersion sets the release version of the hub, reported by the built-in agent.
type Rejection ¶
Rejection is the last time the hub refused an enrolled agent because its version cannot work with this hub. The dashboard shows it until the agent connects.
type RolloutAgent ¶
type RolloutAgent struct {
ID string `json:"id"`
Hostname string `json:"hostname,omitempty"`
From string `json:"from"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
}
RolloutAgent is a server in a rollout, or one that could be in the next.
type RolloutControl ¶
type RolloutControl interface {
RolloutStatus(ctx context.Context) (RolloutStatus, error)
StartRollout(ctx context.Context, by string, opts RolloutOptions) (RolloutStatus, error)
StopRollout(ctx context.Context, by string) (RolloutStatus, error)
}
RolloutControl is what the HTTP API needs to update the servers. *Hub implements it.
type RolloutOptions ¶
type RolloutOptions struct {
// Agents limits the rollout to these servers; empty means every candidate.
Agents []string `json:"agents"`
// WaveSize is how many servers are updated at the same time (default 1).
// The rollout stops at the first failure.
WaveSize int `json:"wave_size"`
}
RolloutOptions say what a rollout does.
type RolloutStatus ¶
type RolloutStatus struct {
// Target is the version the servers are updated to: the one this hub runs.
Target string `json:"target"`
State string `json:"state"`
// Candidates are the connected servers that run an older version and would
// be updated by a new rollout.
Candidates []RolloutAgent `json:"candidates"`
// Agents is what the last rollout did.
Agents []RolloutAgent `json:"agents"`
WaveSize int `json:"wave_size,omitempty"`
StartedBy string `json:"started_by,omitempty"`
StartedAt *time.Time `json:"started_at"`
FinishedAt *time.Time `json:"finished_at"`
}
RolloutStatus is the state of updating the servers to the version of this hub.
type UpdateControl ¶
type UpdateControl interface {
Status(ctx context.Context) (update.Status, error)
SetSettings(ctx context.Context, by string, s update.Settings) (update.Status, error)
Check(ctx context.Context) (update.Status, error)
Download(ctx context.Context, by string) (update.Status, error)
Apply(ctx context.Context, by string) (update.Status, error)
}
UpdateControl is what the HTTP API needs to report and steer the updates of the hub. *update.Manager implements it.