Documentation
¶
Overview ¶
Package cli turns the agent's typed ops into HAProxy runtime commands and runs them against the worker stats socket. It knows command strings and success strings; it makes no decisions and parses no configuration.
Index ¶
- Constants
- Variables
- func Kinds() []string
- type Client
- func (c *Client) Execute(programs []Program) ([]api.OpResult, error)
- func (c *Client) FrontendConnections(ignore map[string]bool) (uint64, error)
- func (c *Client) Info() (api.HAProxyInfo, error)
- func (c *Client) Inventory(generation uint64) (api.Inventory, error)
- func (c *Client) MapEntries(path string) (map[string][]string, error)
- func (c *Client) Raw(command string) (string, error)
- func (c *Client) Reload() (string, error)
- func (c *Client) ServerNames(backend string) (map[string]struct{}, error)
- func (c *Client) ShowProc() (string, error)
- type Command
- type CommandResult
- type Config
- type Content
- type Deferrals
- func (d *Deferrals) Check(servers []ServerRef, backends []string) error
- func (d *Deferrals) Enqueue(worker api.HAProxyInfo, servers []ServerRef, backends []string) error
- func (d *Deferrals) Pending() api.PendingDeletes
- func (d *Deferrals) SetWorker(worker api.HAProxyInfo)
- func (d *Deferrals) Start(ctx context.Context) error
- func (d *Deferrals) Wake()
- type Observer
- type Program
- type ServerRef
Constants ¶
const PayloadTerminator = "HAPTIC"
PayloadTerminator ends a payload block. HAProxy's default terminator is an empty line, which a blank line inside a certificate or a map would trip; a custom pattern (max 7 characters) is what makes the content irrelevant to the framing.
const VersionPlaceholder = "\x01ver\x01"
VersionPlaceholder stands in for the map version `prepare map` allocates. The executor substitutes it in the rest of the program once the allocating command answered.
Variables ¶
var ( // ErrNameCollision means a backend of that name already exists. The shape // behind the name is unreadable at runtime, so the apply stops and reloads. ErrNameCollision = errors.New("backend name already in use") // ErrWaitExpired means the object still has attached connections. ErrWaitExpired = errors.New("wait delay expired") // ErrRejected is HAProxy refusing a command. ErrRejected = errors.New("haproxy rejected the command") // ErrUnreadableResponse means the batch answered something the matcher // cannot attribute. The baseline is unknown from here on. ErrUnreadableResponse = errors.New("unreadable runtime response") )
Typed outcomes the caller acts on rather than just reports.
var ErrDeferralOverflow = errors.New("deferred delete queue is full")
ErrDeferralOverflow means the queue is at its cap: the caller must reload instead of deferring more deletes.
var ErrTooManyEntries = errors.New("runtime listing exceeds the entry limit")
ErrTooManyEntries means a listing is above the agent's limit, which is a refusal to read it, not a statement about what the worker holds.
var ErrUnknownOp = errors.New("unknown op kind")
ErrUnknownOp is what an op kind this agent does not execute wraps. The server refuses the whole batch and falls back to a reload.
var ErrUnsafeToken = errors.New("unsafe runtime token")
ErrUnsafeToken is what every negative-space rejection wraps. A token that reaches HAProxy unchecked can split the command line and run a second command, so the check is a refusal, never a sanitisation.
var ErrWorkerGone = errors.New("the deferred delete's HAProxy worker has changed")
ErrWorkerGone means a deferred attempt no longer addresses its original worker.
Functions ¶
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the agent's runtime plumbing.
func New ¶
New wires both sockets without probing them: readiness is the server's job, and the agent must come up before HAProxy answers.
func (*Client) Execute ¶
Execute runs the programs of one apply in the order the controller composed them and returns one result per program. It stops at the first failure: the caller's answer to a rejected op is to reload the desired set, which makes the commands after the failure irrelevant.
func (*Client) FrontendConnections ¶
FrontendConnections sums the cumulative accepted-connection counter of every frontend except the ignored ones. It is the drain's signal: the sum stops moving once nothing routes new connections to the worker any more.
func (*Client) Info ¶
func (c *Client) Info() (api.HAProxyInfo, error)
Info reads the worker's process ID and microsecond-resolution start time.
func (*Client) Inventory ¶
Inventory reads what the running worker has loaded. The controller needs it to know whether a certificate or map it wants to touch at runtime exists at all; a path that is not in here is structural.
func (*Client) MapEntries ¶
MapEntries reads back one map file's runtime contents, keyed by map key. Duplicate keys keep every value, in insertion order, because that is what decides which one a lookup wins.
func (*Client) Reload ¶
Reload asks the master to re-exec. The returned string is HAProxy's startup log, which is what a NACK carries back to the operator.
func (*Client) ServerNames ¶
ServerNames reads the servers the running worker holds for a backend.
type Command ¶
type Command struct {
// Text is the command line. It never contains a newline, so a batch can
// join commands with ';'.
Text string
// Payload is the block a "<<" command carries. A command with a payload is
// always the last one on its line.
Payload string
// Expect is the substring HAProxy answers on success, matched
// case-insensitively. Empty means success is any response that is not an
// error.
Expect string
// Capture marks the command whose response carries the map version the rest
// of the program substitutes into VersionPlaceholder.
Capture bool
// Repeat marks a command that has to run until HAProxy refuses it: `del map`
// removes one duplicate per call on 3.4 and all of them on 3.0.
Repeat bool
// Optional marks the session prefix, whose response is version-dependent
// and must never be mistaken for an op's verdict.
Optional bool
}
Command is one HAProxy runtime command with the framing and the verdict rule that belong to it.
type CommandResult ¶
CommandResult is one command's verdict, with HAProxy's own words.
type Content ¶
Content supplies the on-disk bytes of a manifest path for the ops that push a whole file through the socket.
type Deferrals ¶
type Deferrals struct {
// contains filtered or unexported fields
}
Deferrals drains the delete tail of an apply off the apply path: `wait …-removable` blocks for as long as a client keeps a connection, and no apply may pay that.
func NewDeferrals ¶
NewDeferrals builds the queue. observer may be nil.
func (*Deferrals) Enqueue ¶
Enqueue commits deletes only after their inline traffic-stopping ops succeed.
func (*Deferrals) Pending ¶
func (d *Deferrals) Pending() api.PendingDeletes
Pending reports what is still to happen, for /v1/state: the queue plus the delete the drain is inside, which is outstanding until it reports back.
func (*Deferrals) SetWorker ¶
func (d *Deferrals) SetWorker(worker api.HAProxyInfo)
SetWorker retires queued work; in-flight commands stay on their old connection.
type Observer ¶
type Observer interface {
DeferredDeleteDone(kind string)
DeferredDeleteDeferred(kind string)
// DeferredDeleteAbandoned is a delete the agent gave up on: the object
// stays until the next reload, which is a distinct fact from "retrying".
DeferredDeleteAbandoned(kind string)
DeferredDeleteSuperseded(kind string)
}
Observer receives deferred-delete outcomes so the server can export them.
type Program ¶
Program is the command sequence of one typed op, plus the cleanup that has to run when one of its commands fails. An open `set ssl cert` transaction wedges that certificate until a reload, so the abort is not optional.