agent

package
v1.3.6 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: AGPL-3.0 Imports: 35 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RuntimeDocker     = "docker"
	RuntimeSwarm      = "swarm"
	RuntimeKubernetes = "kubernetes"
)

Runtime labels reported by the agent during enrollment. "docker" / "kubernetes" come from runtime.Runtime.Name(); "swarm" is derived from the swarm.Detector check applied to the docker runtime.

Variables

View Source
var (
	ErrAgentNotFound        = errors.New("agent not found")
	ErrTokenNotFound        = errors.New("enrollment token not found")
	ErrTokenAlreadyConsumed = errors.New("enrollment token already consumed")
	ErrTokenExpired         = errors.New("enrollment token expired")
	ErrLabelTooLong         = errors.New("label exceeds 64 characters")
	ErrAgentRevoked         = errors.New("agent is revoked")
	ErrBadSignature         = errors.New("invalid Ed25519 signature")
	ErrClockSkew            = errors.New("clock skew exceeds 300s")
	ErrAgentUnknown         = errors.New("agent unknown")
	ErrHostLimitReached     = errors.New("agent host limit reached")
)

Sentinel errors for agent store operations.

View Source
var ErrAgentRevokedServer = errors.New("agent revoked by server")

ErrAgentRevokedServer is returned by RunWithReconnect when the server revokes the agent. The caller should exit without retrying.

Functions

func Run

func Run(ctx context.Context, cfg AgentConfig, logger *slog.Logger) error

Run is the main agent entry point (mode=agent). It detects the local runtime, loads or creates the agent identity, enrolls if needed, then enters the long-lived Push streaming loop (US2).

func RunCollector

func RunCollector(ctx context.Context, id *Identity, rt runtime.Runtime, label string, stream *PushStream, logger *slog.Logger) error

RunCollector starts collecting events from the local runtime and pushing them to stream. rt is the already-connected runtime resolved by agent.Run; label is the reported runtime kind ("docker", "swarm" or "kubernetes"). Blocks until ctx is cancelled or a fatal push error occurs.

func RunEnrollment

func RunEnrollment(
	ctx context.Context,
	id *Identity,
	dataDir string,
	enrollmentToken string,
	runtimeLabel string,
	label string,
	agentVersion string,
	client *Client,
) error

RunEnrollment sends a RegisterRequest to the server using the enrollment token. On success it marks the identity as registered and persists it to dataDir.

func RunWithReconnect

func RunWithReconnect(
	ctx context.Context,
	c *Client,
	id *Identity,
	logger *slog.Logger,
	onStream func(ctx context.Context, stream *PushStream) error,
) error

RunWithReconnect runs onStream with exponential backoff reconnect. Returns nil when ctx is cancelled, ErrAgentRevokedServer when the server revokes the agent. Backoff: min(60s, 1s * 2^attempt) ±25% jitter. Attempt resets to 0 if stream was stable >30s.

Types

type Agent

type Agent struct {
	AgentID         string
	PublicKey       []byte // raw 32 bytes Ed25519
	Hostname        string
	Label           string
	OSArch          string
	AgentVersion    string
	DetectedRuntime string // "docker"|"swarm"|"kubernetes"
	Status          string // "active"|"revoked"
	LastSeenAt      *time.Time
	CreatedAt       time.Time
	RevokedAt       *time.Time
	RevokedBy       *string
}

Agent represents a remote agent registered with the server.

type AgentConfig

type AgentConfig struct {
	DataDir            string
	ServerURL          string
	EnrollmentToken    string
	RuntimeOverride    string
	Label              string
	AgentVersion       string
	InsecureSkipVerify bool
}

AgentConfig holds runtime configuration for an agent process.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client wraps the gRPC IngestClient with connection lifecycle management.

func NewClient

func NewClient(ctx context.Context, serverURL string, insecureSkipVerify bool, logger *slog.Logger) (*Client, error)

NewClient dials the server at serverURL and returns a ready-to-use Client. serverURL should start with "grpcs://" (TLS) or "grpc://" (plaintext, not recommended). If insecureSkipVerify is true, TLS certificate validation is skipped (debug only).

func (*Client) Close

func (c *Client) Close() error

Close closes the underlying gRPC connection.

func (*Client) DialPush

func (c *Client) DialPush(ctx context.Context, id *Identity, logger *slog.Logger) (*PushStream, error)

DialPush opens the bidirectional Push stream, performs the Ed25519 auth handshake, and returns a PushStream ready to send events.

func (*Client) Register

Register calls the unary RegisterAgent RPC.

type EnrollmentToken

type EnrollmentToken struct {
	TokenID           string
	Token             string // cleartext (only stored, never returned via API after creation)
	CreatedAt         time.Time
	ExpiresAt         time.Time
	ConsumedAt        *time.Time
	ConsumedByAgentID *string
}

EnrollmentToken represents a one-time token for enrolling an agent.

type Identity

type Identity struct {
	AgentID      string     `json:"agent_id"`
	PublicKey    []byte     `json:"public_key"`
	PrivateKey   []byte     `json:"private_key"`
	Registered   bool       `json:"registered"`
	RegisteredAt *time.Time `json:"registered_at,omitempty"`
}

Identity holds the persistent agent identity stored on disk.

func LoadOrCreate

func LoadOrCreate(dataDir string) (*Identity, error)

LoadOrCreate loads an existing identity from dataDir/identity.json, or generates and persists a new Ed25519 keypair if no file exists. File is created with mode 0600.

func (*Identity) Save

func (id *Identity) Save(dataDir string) error

Save persists updated identity fields (e.g. Registered) back to disk with mode 0600.

func (*Identity) Sign

func (id *Identity) Sign(message []byte) []byte

Sign returns an Ed25519 signature over message using the stored private key.

type PushStream

type PushStream struct {
	// contains filtered or unexported fields
}

PushStream wraps an authenticated bidirectional gRPC stream for pushing agent events. Multiple goroutines may call Send concurrently.

func (*PushStream) Close

func (ps *PushStream) Close()

Close signals the end of the send side of the stream.

func (*PushStream) Send

func (ps *PushStream) Send(evt *agentpb.AgentEvent) error

Send wraps evt in a ClientMessage and delivers it, assigning a monotonic seq.

func (*PushStream) Wait

func (ps *PushStream) Wait(ctx context.Context) error

Wait blocks until the receive goroutine exits and returns its error (nil on clean close). If ctx is cancelled before recvLoop exits, it returns ctx.Err() immediately so the caller can proceed with shutdown. The leaked recvLoop goroutine terminates when the underlying gRPC stream is finally closed (typically by the deferred grpcClient.Close()).

Jump to

Keyboard shortcuts

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