Documentation
¶
Overview ¶
Package api is branchd's REST control plane: a thin JSON layer over the engine. stdlib net/http only; routes use Go 1.22 method patterns. All /v1 routes require the bearer token; /healthz does not.
Index ¶
Constants ¶
const DefaultStuckTimeout = 10 * time.Minute
DefaultStuckTimeout is the fallback cutoff for reconcile's stuck-row pass.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Branch ¶
type Branch struct {
Name string `json:"name"`
Source string `json:"source"`
// Parent is the branch this one was created from (branch-from-branch);
// "" when created directly from the source.
Parent string `json:"parent,omitempty"`
State string `json:"state"`
Host string `json:"host"`
Port int `json:"port"`
User string `json:"user"`
// Password is the branch's own rotated password — present only when
// branchd runs with --rotate-branch-credentials; otherwise the branch
// inherits the source's credentials and the field is omitted.
Password string `json:"password,omitempty"`
// PasswordUnavailable is true when the branch has a rotated password that
// branchd's at-rest key cannot decrypt (the key changed since it was
// stored); password is then omitted. Reset the branch to mint a new one.
Database string `json:"database"`
// ProxyDatabase is the database param to use when connecting through the
// wire-protocol router: dbname@branch.
ProxyDatabase string `json:"proxy_database"`
ExpiresAt string `json:"expires_at,omitempty"`
CreatedAt string `json:"created_at"`
// ProxyHost and ProxyPort locate the wire-protocol router, as advertised
// by branchd's --advertise-proxy-addr (the port defaults to --pg-addr's).
// ProxyHost is omitted when branchd knows no client-reachable name:
// clients then use the API host. Both are absent from older servers.
ProxyHost string `json:"proxy_host,omitempty"`
ProxyPort int `json:"proxy_port,omitempty"`
}
type CreateBranchRequest ¶
type CreateBranchRequest struct {
Name string `json:"name"`
Source string `json:"source,omitempty"`
Parent string `json:"parent,omitempty"`
TTLSeconds int `json:"ttl_seconds"`
}
CreateBranchRequest creates a branch off a source (Source) or off another branch (Parent) — exactly one of the two must be set.
type CreateSourceRequest ¶
type CreateSourceRequest struct {
Name string `json:"name"`
Host string `json:"host"`
Port int `json:"port"`
User string `json:"user"`
Database string `json:"database"`
Network string `json:"network"`
PGVersion string `json:"pg_version"`
Password string `json:"password"`
// Via selects the seeding method: "basebackup" (default) or "dump".
Via string `json:"via,omitempty"`
// DumpSchemas scopes a via=dump seed to the given schemas (empty = the
// whole database). Only valid with via=dump.
DumpSchemas []string `json:"dump_schemas,omitempty"`
// Image overrides the container image for the seed helpers and every
// branch (default postgres:<pg_version>), e.g. postgis/postgis:17-3.5.
// It must match the source's extensions, locales and libc.
Image string `json:"image,omitempty"`
}
type CreateTokenRequest ¶
CreateTokenRequest mints an API token with the given name and role (admin|operator|viewer). The plaintext token is returned once in the response and never recoverable afterwards.
type CreateTokenResponse ¶
type CreateTokenResponse struct {
Token string `json:"token"`
}
CreateTokenResponse carries the freshly minted plaintext token (shown once).
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
}
ErrorResponse is the body of every non-2xx /v1 response.
type LeaderGate ¶
type LeaderGate struct {
// contains filtered or unexported fields
}
LeaderGate is the HA mutating-route gate: the leadership flag the leader-election orchestration flips. It defaults to leader=true so that with leader election OFF (docker/local, single instance) every instance is always the leader and mutating routes behave normally. When false, mutating /v1 routes return 503 "not leader" while reads, /healthz, /readyz and /metrics keep serving.
Each stretch of leadership is a term with its own context. Mutations admitted during a term run on a context derived from it, so losing leadership cancels every saga the deposed leader still has in flight (their compensations run on a detached context) instead of letting it keep writing next to the new leader.
func (*LeaderGate) IsLeader ¶
func (g *LeaderGate) IsLeader() bool
IsLeader reports whether this instance currently holds leadership.
func (*LeaderGate) Observe ¶
func (g *LeaderGate) Observe(fn func(leader bool))
Observe registers fn to be called with the new value on every leadership change, and once immediately with the current value (branchd wires the pgoverlay_leader gauge here). fn runs under the gate's lock, in order, and must not call back into the gate.
func (*LeaderGate) Set ¶
func (g *LeaderGate) Set(leader bool)
Set flips the leadership flag (called from the election callbacks). Opening the gate starts a new term; closing it ends the current term, cancelling the mutations admitted during it. Setting the current value is a no-op.
type MaskScript ¶
MaskScript is one per-source masking statement, applied in order inside every new/reset branch before it is marked ready.
type Ready ¶
Ready reports whether branchd can serve traffic: the registry is reachable and the container driver responds. Returns nil when ready, an error otherwise. branchd supplies a closure; tests inject a fake.
type RefreshSourceRequest ¶
type RefreshSourceRequest struct {
Password string `json:"password"`
}
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func New ¶
func New(eng *engine.Engine, reg *registry.Registry, token string, metricsHandler http.Handler, ready Ready, stuckTimeout time.Duration) *Server
New builds the API server. metricsHandler serves /metrics (promhttp over the metrics registry) and ready backs /readyz; both may be nil (then /metrics 404s and /readyz reports ready iff the handler is wired). branchd always passes both. stuckTimeout is the reconcile cutoff for stuck creating/ resetting rows (0 → DefaultStuckTimeout).
func (*Server) CancelMutations ¶
func (s *Server) CancelMutations()
CancelMutations cancels every in-flight mutation's context. The sagas then run their compensations (on a detached context) and return; use WaitMutations to wait for that. branchd calls it when the shutdown drain budget runs out.
func (*Server) LeaderGate ¶
func (s *Server) LeaderGate() *LeaderGate
LeaderGate exposes the HA mutating-route gate so branchd's leader-election orchestration can flip it on gaining/losing leadership. With leader election off it stays leader=true (single-instance default) and is never touched.
func (*Server) SetProxyEndpoint ¶
SetProxyEndpoint sets the router address advertised in branch responses, so `pgb connect` and other clients stop guessing "<API host>:6432". host may be "" (clients fall back to the API host); port 0 advertises no port. Call it before serving.
func (*Server) StopAdmitting ¶
func (s *Server) StopAdmitting()
StopAdmitting makes the API refuse new mutations with 503 "shutting down"; mutations already in flight continue. branchd calls it on SIGTERM.
type Source ¶
type Source struct {
Name string `json:"name"`
PGVersion string `json:"pg_version"`
Host string `json:"host"`
Port int `json:"port"`
User string `json:"user"`
Database string `json:"database"`
Network string `json:"network,omitempty"`
// Via is the seeding method: "basebackup" (pg_basebackup) or "dump"
// (pg_dump — managed Postgres without REPLICATION privilege).
Via string `json:"via"`
DumpSchemas []string `json:"dump_schemas,omitempty"`
State string `json:"state"`
Generation int `json:"generation"`
CreatedAt string `json:"created_at"`
// Image is the source's image override for its branches and seed
// helpers; omitted when the default postgres:<pg_version> is used.
Image string `json:"image,omitempty"`
}
type Token ¶
type Token struct {
Name string `json:"name"`
Role string `json:"role"`
CreatedAt string `json:"created_at"`
}
Token is a stored token's metadata — never the plaintext or its hash.
type Transition ¶
type Transition struct {
FromState string `json:"from_state"`
ToState string `json:"to_state"`
Reason string `json:"reason"`
Actor string `json:"actor"`
At string `json:"at"`
}
Transition is one entry of a branch's audit history: a recorded state change, its reason, the actor that caused it ("name (role)", the env-token sentinel, or "system:reconcile" for daemon-initiated changes), and when it happened.