agentstreams

package
v4.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package agentstreams is the kernel's view of its live agent sessions: the Agent Control streams, by node kind, and the legacy agent WebSocket. It is the seam between the KernelNodeOps executors (internal/kernelnodeops), which dispatch node operations, and the listeners that hold the sessions (internal/grpc, internal/handler). It carries no credential: a session is described by its node, transport, version and revisions, never by the key or certificate that authenticated it.

Index

Constants

View Source
const (
	// AuthenticationMTLS: an agent client certificate.
	AuthenticationMTLS = "mtls"
	// AuthenticationAPIKey: the node's API key or forward token.
	AuthenticationAPIKey = "api-key"
)

How a session authenticated.

View Source
const (
	// IdentityAPIKey is a stream authenticated by the node's API key or
	// forward token; a certificate's identity is its SPIFFE ID.
	IdentityAPIKey = "api-key"
)

Identity values of a session authenticated without a certificate.

Variables

View Source
var (
	// ErrNotConnected: the node has no stream session.
	ErrNotConnected = errors.New("agent is not connected")
	// ErrCapabilityMissing: the session does not advertise the operation
	// kind.
	ErrCapabilityMissing = errors.New("agent does not advertise the capability")
	// ErrSessionClosed: the session ended before the agent acknowledged.
	ErrSessionClosed = errors.New("agent session closed before the acknowledgement")
	// ErrOperationPending: the operation id is already in flight on the
	// session.
	ErrOperationPending = errors.New("agent operation is already pending")
)

Errors a Streams implementation reports from Dispatch and Cancel. They are wrapped, so callers test them with errors.Is.

Functions

This section is empty.

Types

type Ack

type Ack struct {
	Accepted   bool
	Error      string
	AcceptedAt time.Time
	SessionID  string
	Revision   uint64
}

Ack is an agent's acknowledgement of a dispatched task, as the transport reported it.

type ConfigStatusHandler

type ConfigStatusHandler func(report ConfigStatusReport)

ConfigStatusHandler receives every ConfigStatus an agent sends.

type ConfigStatusReport

type ConfigStatusReport struct {
	Node      agentcontrol.AgentNode
	SessionID string
	Status    *agentv1pb.ConfigStatus
	Verdict   string
}

ConfigStatusReport is one ConfigStatus an agent sent on its stream (config.v1), with the kernel's verdict on it (model.ConfigVerdict*): empty when the status could not be recorded.

type ConfigStreams

type ConfigStreams interface {
	// ConfigNegotiated reports whether the node's current session
	// negotiated config.v1.
	ConfigNegotiated(node agentcontrol.AgentNode) bool
	// PushConfig sends snapshot on the node's session and returns the
	// session's id. It does not wait for the agent's ConfigStatus. Errors
	// wrap ErrNotConnected or ErrCapabilityMissing. A snapshot older than
	// one the session was already sent is not sent again (sent is false):
	// the agent has a newer configuration.
	PushConfig(ctx context.Context, node agentcontrol.AgentNode, snapshot *agentv1pb.ConfigSnapshot) (sessionID string, sent bool, err error)
	// OnConfigStatus registers a handler for every ConfigStatus, of every
	// node kind.
	OnConfigStatus(handler ConfigStatusHandler)
}

ConfigStreams is a Streams that carries node configurations (config.v1, node-ops-service.md section 5.5): the kernel pushes a ConfigSnapshot to an agent that negotiated it, and the agent answers ConfigStatus. A Streams without it carries none, and node.sync pushes node.reload.

type DiagnosticDispatch

type DiagnosticDispatch struct {
	// MessageID identifies the dispatch on the transport: the WebSocket
	// message id, or the stream operation id.
	MessageID string
	// AckReceived is true when the agent acknowledged the task.
	AckReceived bool
	Ack         Ack
	// RawAck is the transport's own acknowledgement object, for answers
	// that show it as the legacy routes do.
	RawAck any
	// DispatchError is why the acknowledged dispatch failed.
	DispatchError error
	// LegacyFallback is true when, after DispatchError, the task went out
	// in the legacy task message without an acknowledgement.
	LegacyFallback bool
	// FallbackError is why the legacy fallback failed too.
	FallbackError error
}

DiagnosticDispatch is what a transport did with a task.

func (DiagnosticDispatch) Sent

func (d DiagnosticDispatch) Sent() bool

Sent reports whether the task reached the agent in some form.

type DiagnosticTask

type DiagnosticTask struct {
	ID      string         `json:"id"`
	Type    string         `json:"type"`
	Action  string         `json:"action"`
	Params  map[string]any `json:"params"`
	Timeout int            `json:"timeout"`
}

DiagnosticTask is one whitelisted diagnostic action as it is sent to an agent, on the WebSocket ("task.assign", and the legacy "task" message) and on the stream (an "agent.diagnostic" operation).

type DiagnosticTransport

type DiagnosticTransport interface {
	DispatchDiagnostic(ctx context.Context, task DiagnosticTask) DiagnosticDispatch
}

DiagnosticTransport carries a diagnostic task to one node's agent.

type ObservedHandler

type ObservedHandler func(node agentcontrol.AgentNode, observed *agentv1pb.ObservedState)

ObservedHandler receives every observed state an agent reports on its stream, for the node that reported it.

type Session

type Session struct {
	Node         agentcontrol.AgentNode
	Transport    Transport
	SessionID    string
	AgentVersion string
	InstanceID   string
	Capabilities []string
	ConnectedAt  time.Time
	LastSeen     time.Time
	// DesiredRevision and ObservedRevision are the stream's operation
	// revisions; zero on the WebSocket.
	DesiredRevision  uint64
	ObservedRevision uint64
	// System is what a WebSocket agent reported about its host.
	System map[string]any
	// Identity is the session's authenticated identity: the agent's SPIFFE
	// ID, or IdentityAPIKey.
	Identity string
	// Authentication is AuthenticationMTLS or AuthenticationAPIKey; empty
	// on the WebSocket, which authenticates by API key only.
	Authentication string
	// Certificate is the client certificate of an mTLS stream session.
	Certificate *SessionCertificate
	// NegotiatedCapabilities are the data-plane capabilities in use on a
	// stream session (both its Hello and HelloAck list them), as
	// name.version.
	NegotiatedCapabilities []string
	// AgentMetrics are the Agent's own health metrics (agent_control_*,
	// agent_identity_*, agent_dataplane_*) from the stream session's latest
	// heartbeat that carried any, reported at AgentMetricsAt.
	AgentMetrics   map[string]float64
	AgentMetricsAt *time.Time
}

Session is one live agent session, without its credentials.

type SessionCertificate added in v4.2.0

type SessionCertificate struct {
	Serial   string    `json:"serial"`
	NotAfter time.Time `json:"not_after"`
	SPIFFEID string    `json:"spiffe_id"`
}

SessionCertificate describes the client certificate of an mTLS session: its serial, expiry and URI SAN (the agent's SPIFFE ID). None of it is secret; the transport inventory shows the same.

type StatusConnections added in v4.2.0

type StatusConnections interface {
	StatusConnection(node agentcontrol.AgentNode) (any, bool)
}

StatusConnections is implemented by streams that can show a node's session as the administrator's Agent Control status (GET /api/v2/admin/nodes/:id/agent-control) shows it: the stream manager's own snapshot (internal/grpc.AgentControlSnapshot), which the kernel renders for both the legacy route and the session RPC.

type Streams

type Streams interface {
	// Session returns the node's current stream session.
	Session(node agentcontrol.AgentNode) (Session, bool)
	// Sessions lists every stream session, in no particular order.
	Sessions() []Session
	// Observed returns the last observed state the node's agent reported.
	Observed(node agentcontrol.AgentNode) (*agentv1pb.ObservedState, bool)
	// Dispatch sends a desired operation on the node's stream and waits for
	// the agent's acknowledgement, or for ctx to end. A revision of zero
	// takes the node's next one; the acknowledgement carries it.
	Dispatch(ctx context.Context, node agentcontrol.AgentNode, operation *agentv1pb.DesiredOperation) (*agentv1pb.OperationAck, error)
	// Cancel asks the agent to stop an operation it holds.
	Cancel(ctx context.Context, node agentcontrol.AgentNode, operationID string, revision uint64) error
	// OnObserved registers a handler for every observed state, of every
	// node kind.
	OnObserved(handler ObservedHandler)
}

Streams is the Agent Control streams of every node kind: the dispatcher of node-ops-service.md section 3.8 takes node kinds, since proxy and forward node ids overlap.

type Transport

type Transport string

Transport is the connection an agent session uses.

const (
	// TransportControlStream is the Agent Control gRPC stream.
	TransportControlStream Transport = "control-stream"
	// TransportWebSocket is the legacy agent WebSocket.
	TransportWebSocket Transport = "websocket"
)

type WebSockets

type WebSockets interface {
	// Sessions lists the connected WebSocket agents.
	Sessions() []Session
	// Monitor returns the last monitor snapshot a proxy node's agent posted.
	Monitor(nodeID uint) (system map[string]any, receivedAt time.Time, ok bool)
	// DiagnosticTransport returns the WebSocket of a connected proxy node's
	// agent, for diagnostic tasks.
	DiagnosticTransport(nodeID uint) (DiagnosticTransport, bool)
}

WebSockets is the legacy agent WebSocket, as the kernel reads it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL