- CLI: enroll, run, status, version, help (core.Main with a role factory); the agent binaries use a placeholder factory until the BIND and Kea roles are wired in. - Enrollment: local ECDSA P-256 key and CSR, TLS 1.3 to the agent API with the server chain pinned to the CA fingerprint. - ServerSource: mTLS gRPC with keepalive, Connect stream (Hello, Welcome, heartbeats, apply and renew commands), reconnect with exponential backoff and jitter, GetDesiredState polling as fallback, certificate renewal after half of the lifetime. - Apply pipeline: fetch, bundle verification with replay protection, store, Validate, Activate, Health with retries, rollback to the last good revision; outcomes succeeded/rejected/rolled_back/failed are queued in state.json and reported; failed revisions are retried only by a newer revision or an explicit push. - Lease reporting with change detection, persistent sequence and full snapshots at start, per connection and periodically. - Tests with fake roles, a fake source and an in-process fake AgentService over real mTLS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
73 lines
2.4 KiB
Go
73 lines
2.4 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package core
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// Source is where the agent learns its desired revision, fetches bundles and
|
|
// reports results (docs/adr/0010-agent-binaries-pro-rolle.md). M3 provides
|
|
// ServerSource (gRPC); a FileSource for standalone operation (M7) implements
|
|
// the same interface without changes to the apply pipeline.
|
|
type Source interface {
|
|
// Run delivers events to h until ctx is canceled. It returns ctx.Err()
|
|
// on shutdown or an error if the source cannot work at all.
|
|
Run(ctx context.Context, h SourceHandler) error
|
|
// FetchBundle returns the signed bundle of a revision. The caller
|
|
// verifies it.
|
|
FetchBundle(ctx context.Context, revision uint64) (*Bundle, error)
|
|
// ReportDeployment delivers an apply outcome.
|
|
ReportDeployment(ctx context.Context, r DeploymentReport) error
|
|
// ReportLeases delivers a batch of lease observations.
|
|
ReportLeases(ctx context.Context, b LeaseBatch) error
|
|
}
|
|
|
|
// SourceHandler receives the events of a Source. Its methods must not
|
|
// block for long.
|
|
type SourceHandler interface {
|
|
// Connected is called whenever the source (re)established contact;
|
|
// the agent then sends queued reports and a full lease snapshot.
|
|
Connected()
|
|
// Desired announces the revision the agent should run. autoApply is
|
|
// false in manual mode, where only explicit pushes are applied.
|
|
Desired(revision uint64, autoApply bool)
|
|
// Push asks for an explicit apply of a revision. Unlike Desired, it
|
|
// also retries a revision that failed before.
|
|
Push(revision uint64, deploymentID string)
|
|
// Status returns what the agent reports in Hello and heartbeats.
|
|
Status(ctx context.Context) AgentStatus
|
|
}
|
|
|
|
// AgentStatus is the agent's view of itself.
|
|
type AgentStatus struct {
|
|
Applied uint64
|
|
LastGood uint64
|
|
Health Health
|
|
CheckedAt time.Time
|
|
ServiceVersion string
|
|
}
|
|
|
|
// Bundle is a signed bundle as delivered by a Source.
|
|
type Bundle struct {
|
|
Manifest []byte
|
|
Signature []byte
|
|
Artifacts []BundleArtifact
|
|
}
|
|
|
|
// BundleArtifact is one artifact of a Bundle.
|
|
type BundleArtifact struct {
|
|
Path string
|
|
Content []byte
|
|
}
|
|
|
|
// LeaseBatch is one lease report. Sequence is monotonic per agent. A batch
|
|
// with FullSync replaces the server's view of all leases of this agent; the
|
|
// following batches (higher sequence) are changes on top of it.
|
|
type LeaseBatch struct {
|
|
Sequence uint64
|
|
FullSync bool
|
|
Leases []Lease
|
|
}
|