client

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package client is the controller's end of the HAPTIC agent wire contract (pkg/dataplane/agent/api): one pooled keep-alive HTTP client per pod, a state read and a streaming multipart apply.

Pure: no controller, templating or Kubernetes imports. Every limit the contract states is asserted here as well as in the agent, so a malformed apply never reaches the wire.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoPlanEndpoint = errors.New("agent client: the agent has no plan endpoint")

ErrNoPlanEndpoint is PutPlan's answer from an agent that predates it.

View Source
var ErrPlanMoved = errors.New("agent client: the pod's applied plan has moved on")

ErrPlanMoved is PutPlan's answer when the pod has applied another plan since the one the blob describes.

Functions

func CheckSkew

func CheckSkew(state *api.State) (incompatible bool, missingOps []string)

CheckSkew compares an agent's reported contract with this controller's. An incompatible pod gets full state and a reload; a missing op kind only takes the changes that need it off the runtime path, which deployplan gates per op. Neither is a refusal, because a fleet-correlated refusal would fence the repair path.

func ComposableOps

func ComposableOps() []string

ComposableOps returns the op kinds this controller composes — the set CheckSkew measures an agent against. It is deployplan's own list, so the skew check cannot drift from what the decision layer emits.

Types

type Client

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

Client talks to one agent.

func New

func New(cfg *Config) (*Client, error)

New validates cfg and builds a client with its own connection pool. cfg is copied; the caller may reuse it for the next pod.

func (*Client) Apply

func (c *Client) Apply(ctx context.Context, m *api.Manifest, parts map[string]io.Reader, plan io.Reader) (*api.ApplyResult, error)

Apply streams one apply: the manifest part first, the optional zstd plan blob, then one part per file whose content the agent lacks, named by its manifest path.

A NACK is a successful call with ApplyResult.OK false — the agent's verdict, not a transport failure. A baseline mismatch returns *ConflictError, missing file parts *MissingError.

func (*Client) Close

func (c *Client) Close()

Close releases the pooled connections.

func (*Client) Health

func (c *Client) Health(ctx context.Context) error

Health checks process liveness independently of the HAProxy worker.

func (*Client) PutPlan

func (c *Client) PutPlan(ctx context.Context, planID, proof string, blob []byte) error

PutPlan stores the blob of the plan the pod applied under (planID, proof), after the apply that landed it. ErrPlanMoved means the pod has applied another plan since and dropped the blob; ErrNoPlanEndpoint means the agent predates the call, so the blob has to ride the next apply.

func (*Client) State

func (c *Client) State(ctx context.Context, read api.StateRead) (*api.State, error)

State reads the agent's baseline. verify makes the agent re-hash its tree so the reported digests are observations rather than its last-known set.

type Config

type Config struct {
	BaseURL  string
	Username string
	Password string
	TLS      *transportsecurity.Source
	// UnixSocket uses local filesystem access instead of network authentication.
	UnixSocket string
	// Timeout bounds a State call, PerPodApplyTimeout an Apply call.
	Timeout            time.Duration
	PerPodApplyTimeout time.Duration
	// ConnectRetries and ConnectRetryBackoff cover the master's re-exec
	// window; nothing but a refused or reset connection is ever retried.
	ConnectRetries      int
	ConnectRetryBackoff time.Duration
}

Config configures one agent endpoint. Zero fields take the contract's defaults; BaseURL is the only required one.

type ConflictError

type ConflictError struct {
	Conflict api.Conflict
}

ConflictError is a 409 whose body is the agent's actual baseline: the ops were composed against a state the agent no longer has, and it wrote nothing.

func (*ConflictError) Error

func (e *ConflictError) Error() string

type HTTPError

type HTTPError struct {
	Status int
	Body   string
}

HTTPError is any other non-200 answer.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type MissingError

type MissingError struct {
	Missing []string
}

MissingError is a 409 listing the file parts the agent does not hold: resend the apply with those contents.

func (*MissingError) Error

func (e *MissingError) Error() string

Jump to

Keyboard shortcuts

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