api

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

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

View Source
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.
	PasswordUnavailable bool   `json:"password_unavailable,omitempty"`
	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

type CreateTokenRequest struct {
	Name string `json:"name"`
	Role string `json:"role"`
}

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

type MaskScript struct {
	Name string `json:"name"`
	SQL  string `json:"sql"`
}

MaskScript is one per-source masking statement, applied in order inside every new/reset branch before it is marked ready.

type Ready

type Ready func(ctx context.Context) error

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) Handler

func (s *Server) Handler() http.Handler

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

func (s *Server) SetProxyEndpoint(host string, port int)

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.

func (*Server) WaitMutations

func (s *Server) WaitMutations(ctx context.Context) error

WaitMutations blocks until every in-flight mutation has returned or ctx is done (then it returns ctx.Err()).

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.

type Usage

type Usage struct {
	Bytes int64 `json:"bytes"`
}

Usage is the body of GET /v1/branches/{name}/usage: the branch's rw-layer disk usage in bytes.

Jump to

Keyboard shortcuts

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