Documentation
¶
Overview ¶
Package sync maintains the agent's single persistent stream to the control plane and applies versioned desired-state updates in order (ADR-0002, ADR-0015). Every stream starts with Hello and receives a snapshot; deltas follow on the same stream. Each update is applied atomically through the enforce.PolicyStore and acknowledged; a failed apply leaves the last good policy installed and is acknowledged FAILED, after which the control plane sends a fresh snapshot. Reconnects use exponential backoff with full jitter. Persistence of the last applied policy to disk, which makes the agent fail static across restarts (ADR-0011), lands with enforcement behind the same store interface.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrReconnectDirected = errors.New("sync: reconnect directed")
ErrReconnectDirected is returned when the control plane directs the agent to reconnect immediately.
var ErrReenrollRequired = errors.New("sync: control plane directed re-enrollment; enroll again with a new provisioning token")
ErrReenrollRequired is returned by Run when the control plane directs the workload to re-enroll. The daemon cannot do that itself: enrollment needs a provisioning token delivered out of band (ADR-0016).
Functions ¶
func Backoff ¶
Backoff returns the wait before reconnect attempt number attempt (1 for the first retry): a random duration in [0, min(cap, base × 2^attempt)], so that a control-plane restart produces a smooth trickle of handshakes rather than a synchronized wave (ADR-0002).
func DialGRPC ¶
func DialGRPC(_ context.Context, server string, holder *credential.Holder) (innerwallv1.AgentServiceClient, io.Closer, error)
DialGRPC is the production dialer: mutual TLS with the holder's current credential, refreshed at each handshake. The flow reporter dials with it too, on its own connection.
Types ¶
type Config ¶
type Config struct {
// Server is the control-plane address, host:port.
Server string
// Holder presents the workload credential.
Holder *credential.Holder
// Store receives each complete policy.
Store enforce.PolicyStore
// AgentVersion and Capabilities are reported in Hello.
AgentVersion string
Capabilities []string
// Facts and ListeningServices are collected for Hello and for every
// inventory report. Either may be nil.
Facts func() *innerwallv1.HostFacts
ListeningServices func() []*innerwallv1.ListeningService
Log *slog.Logger
// BackoffBase and BackoffCap bound the reconnect wait: one second and
// five minutes when zero.
BackoffBase time.Duration
BackoffCap time.Duration
// HelloTimeout bounds the wait for HelloAck; 30 seconds when zero.
HelloTimeout time.Duration
// Dial replaces the default dialer.
Dial Dialer
// Uptime reports the daemon's uptime for heartbeats; measured from
// New when nil.
Uptime func() time.Duration
// DroppedFlowRecords reports the flow records the collection loop has
// dropped to buffer pressure, carried on every heartbeat. Zero when nil.
DroppedFlowRecords func() uint64
// SourceOverruns reports the kernel-side overruns of the flow sources
// since the agent started, carried on every heartbeat. Zero when nil.
SourceOverruns func() uint64
// RenewalError reports the reason the last automatic credential
// renewal failed, or empty, carried on every heartbeat. Empty when nil.
RenewalError func() string
// OwnedTable reads whether the owned firewall table is in the kernel,
// carried on every heartbeat, so a table removed behind the daemon's
// back (the local kill switch) is reported within one heartbeat.
// Unspecified when nil.
OwnedTable func(ctx context.Context) innerwallv1.OwnedTableState
// OnSyncConfig is called with the configuration in every HelloAck, so
// the other loops adopt the control plane's parameters.
OnSyncConfig func(*innerwallv1.SyncConfig)
// OnReconnect reports reconnect attempts and their scheduled wait; nil
// when unused.
OnReconnect func(attempt int, wait time.Duration)
}
Config configures a Daemon.
type Daemon ¶
type Daemon struct {
// contains filtered or unexported fields
}
Daemon is the agent's sync loop.
func (*Daemon) Run ¶
Run maintains the stream until ctx ends, reconnecting with backoff after failures, and immediately upon directed reconnects. Every reconnect is a fresh Hello and snapshot. It returns ErrReenrollRequired when the control plane says so; every other stream error is a reason to reconnect, not to stop.
type Dialer ¶
type Dialer func(ctx context.Context, server string, holder *credential.Holder) (innerwallv1.AgentServiceClient, io.Closer, error)
Dialer opens a connection to the control plane. The default dials gRPC over the holder's TLS configuration; tests substitute a loopback.