Documentation
¶
Overview ¶
Package postgres is the production controlplane.Database adapter, backed by Postgres running in the cluster (ADR-0012). It implements the deploy-record seam (ADR-0007): the durable history of releases and the rollback handles, independent of cluster state. Schema changes are applied by embedded goose migrations on startup, gated to single-minor-step upgrades (ADR-0013).
It uses the pgx driver through the standard database/sql interface (not pgxpool, not the maintenance-mode lib/pq), so one *sql.DB serves both the migrations and the app. It lives under controlplane/ (not controlplane/internal) so cmd/burrowd and the managed module can wire it; it is licensed Apache-2.0 (LICENSING.md, ADR-0033).
Index ¶
- type Store
- func (s *Store) Addon(ctx context.Context, name string) (controlplane.AddonInfo, error)
- func (s *Store) Addons(ctx context.Context) ([]controlplane.AddonInfo, error)
- func (s *Store) AppEnv(ctx context.Context, app string) (map[string]string, error)
- func (s *Store) AppHook(ctx context.Context, app, env string, phase controlplane.HookPhase) ([]string, error)
- func (s *Store) AppHooks(ctx context.Context, app, env string) ([]controlplane.Hook, error)
- func (s *Store) AppendAudit(ctx context.Context, e controlplane.AuditEntry) error
- func (s *Store) Audit(ctx context.Context, filter controlplane.AuditFilter) ([]controlplane.AuditEntry, error)
- func (s *Store) AutoDeployCandidates(ctx context.Context) ([]controlplane.AppEnvRef, error)
- func (s *Store) AutoDeployLevel(ctx context.Context, app, env string) (controlplane.AutoDeployLevel, error)
- func (s *Store) AutoDeployReason(ctx context.Context, app, env string) (string, error)
- func (s *Store) Close() error
- func (s *Store) CreateEnvironment(ctx context.Context, name, namespace string) error
- func (s *Store) DeleteAddon(ctx context.Context, name string) error
- func (s *Store) DeleteAppHooks(ctx context.Context, app string) error
- func (s *Store) DeleteDependencyCheckSettings(ctx context.Context, app string) error
- func (s *Store) DeleteEnvironment(ctx context.Context, name string) error
- func (s *Store) DeleteExposure(ctx context.Context, app, env string) error
- func (s *Store) DeleteHealthEndpoints(ctx context.Context, app string) error
- func (s *Store) DeleteReleases(ctx context.Context, app string) error
- func (s *Store) DependencyChecksEnabled(ctx context.Context, app, env string) (bool, error)
- func (s *Store) DisableAutoDeploy(ctx context.Context, app, env, reason string) error
- func (s *Store) Exposure(ctx context.Context, app, env string) (controlplane.Exposure, error)
- func (s *Store) Exposures(ctx context.Context) ([]controlplane.Exposure, error)
- func (s *Store) ExtendObservationWindow(ctx context.Context, id int64, until time.Time, degraded string) error
- func (s *Store) FailBackup(ctx context.Context, id, reason, detail string) error
- func (s *Store) Failures(ctx context.Context, filter controlplane.FailureFilter) ([]controlplane.Failure, error)
- func (s *Store) GetBackup(ctx context.Context, id string) (controlplane.Backup, error)
- func (s *Store) GetEnvironment(ctx context.Context, name string) (controlplane.Environment, error)
- func (s *Store) HealthEndpoint(ctx context.Context, app, env string) (controlplane.HealthEndpoint, error)
- func (s *Store) LatestRelease(ctx context.Context, app, env string) (controlplane.Release, error)
- func (s *Store) ListBackups(ctx context.Context, app, env string) ([]controlplane.Backup, error)
- func (s *Store) ListEnvironments(ctx context.Context) ([]controlplane.Environment, error)
- func (s *Store) ListReleases(ctx context.Context, app, env string) ([]controlplane.Release, error)
- func (s *Store) ManagedApps(ctx context.Context) ([]controlplane.AppEnvRef, error)
- func (s *Store) Migrate(ctx context.Context, appVersion string) error
- func (s *Store) ObservationWindows(ctx context.Context, since time.Time, limit int) ([]controlplane.ObservationWindow, error)
- func (s *Store) OperationalConfig(ctx context.Context) (controlplane.OperationalConfig, error)
- func (s *Store) PendingBackups(ctx context.Context, before time.Time) ([]controlplane.Backup, error)
- func (s *Store) Policy(ctx context.Context) (controlplane.Policy, error)
- func (s *Store) Provider(ctx context.Context, name string) (controlplane.Provider, error)
- func (s *Store) Providers(ctx context.Context) ([]controlplane.Provider, error)
- func (s *Store) PruneLedger(ctx context.Context, before time.Time) (controlplane.LedgerPruneResult, error)
- func (s *Store) RecordBackup(ctx context.Context, b controlplane.Backup) error
- func (s *Store) RecordExposure(ctx context.Context, ex controlplane.Exposure) error
- func (s *Store) RecordFailure(ctx context.Context, obs controlplane.FailureObservation) error
- func (s *Store) Release(ctx context.Context, id string) (controlplane.Release, error)
- func (s *Store) Releases(ctx context.Context, app, env string) ([]controlplane.Release, error)
- func (s *Store) ResolveFailures(ctx context.Context, at time.Time, keep []controlplane.FailureKey, ...) error
- func (s *Store) SaveAddon(ctx context.Context, a controlplane.AddonInfo) error
- func (s *Store) SaveProvider(ctx context.Context, p controlplane.Provider) error
- func (s *Store) SaveRelease(ctx context.Context, r controlplane.Release) error
- func (s *Store) SetAppEnv(ctx context.Context, app, key, value string) error
- func (s *Store) SetAppHook(ctx context.Context, app, env string, phase controlplane.HookPhase, ...) error
- func (s *Store) SetAutoDeployLevel(ctx context.Context, app, env string, level controlplane.AutoDeployLevel) error
- func (s *Store) SetBackupStatus(ctx context.Context, id string, status controlplane.BackupStatus, ...) error
- func (s *Store) SetDependencyChecks(ctx context.Context, app, env string, enabled bool, at time.Time) error
- func (s *Store) SetGuardrail(ctx context.Context, code controlplane.GuardrailCode, ...) error
- func (s *Store) SetHealthEndpoint(ctx context.Context, ep controlplane.HealthEndpoint) error
- func (s *Store) SetLimit(ctx context.Context, code controlplane.LimitCode, value string) error
- func (s *Store) StartObservationWindow(ctx context.Context, at time.Time) (int64, error)
- func (s *Store) UnsetAppEnv(ctx context.Context, app, key string) error
- func (s *Store) UnsetAppHook(ctx context.Context, app, env string, phase controlplane.HookPhase) error
- func (s *Store) UnsetHealthEndpoint(ctx context.Context, app, env string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a Postgres-backed controlplane.Database.
func Open ¶
Open connects to the database at dsn and verifies the connection. The caller closes the Store with Close. It does not apply the schema; call Migrate for that.
func (*Store) Addon ¶
Addon returns the add-on with the given name, or ErrNotFound. The returned info has Ready false — readiness is probed live, never read from the registry.
func (*Store) Addons ¶
Addons returns all registered add-ons, name order. Each row has Ready false — readiness is a live property, probed by the caller, not stored.
func (*Store) AppEnv ¶
AppEnv returns the non-secret environment store for app (ADR-0028). An app with no env yields an empty map and no error.
func (*Store) AppHook ¶
func (s *Store) AppHook(ctx context.Context, app, env string, phase controlplane.HookPhase) ([]string, error)
AppHook returns the command app runs at phase in env (ADR-0072 §1). A phase with no row yields a nil command and no error: unset means no hook and today's behaviour exactly, so absence is the ordinary answer rather than ErrNotFound.
func (*Store) AppHooks ¶
AppHooks returns every hook configured for app in env. None yields an empty slice and no error. Rows come back in phase order so a listing is deterministic; the engine re-orders them into the order the phases fire in, which is its business and not the store's.
func (*Store) AppendAudit ¶
func (s *Store) AppendAudit(ctx context.Context, e controlplane.AuditEntry) error
AppendAudit appends one audit row (ADR-0027). The log is append-only: there is only this INSERT and the Audit SELECT — no update or delete path. The store assigns id.
func (*Store) Audit ¶
func (s *Store) Audit(ctx context.Context, filter controlplane.AuditFilter) ([]controlplane.AuditEntry, error)
Audit returns audit rows matching filter, newest first, capped by filter.Limit (a default when unset). The filter clauses are optional and ANDed; an empty filter returns the latest rows up to the cap.
func (*Store) AutoDeployCandidates ¶ added in v0.13.0
AutoDeployCandidates returns the distinct (app, environment) pairs that have at least one recorded release — the set the pull-based watcher may reconcile (ADR-0052 Phase 4b). Auto-deploy is on by default, so candidacy is "has a running release" (a version to compare a registry tag against), not "has an app_autodeploy row"; the poller reads each pair's level and skips those set to off. Rows are ordered by app then environment for a deterministic reconcile order.
func (*Store) AutoDeployLevel ¶ added in v0.13.0
func (s *Store) AutoDeployLevel(ctx context.Context, app, env string) (controlplane.AutoDeployLevel, error)
AutoDeployLevel returns app's auto-deploy level in env (ADR-0052 §2). A missing row resolves to DefaultAutoDeployLevel (off): the table holds only opt-ins, so an app runs at the default level with no row (auto-deploy is opt-in — ADR-0058).
func (*Store) AutoDeployReason ¶ added in v0.13.0
AutoDeployReason returns the stored disable reason for app in env, or "" when the level was human-set or is the default (no row) — the reason surfaced next to an off level (ADR-0052 §5).
func (*Store) CreateEnvironment ¶ added in v0.7.0
CreateEnvironment registers a named environment mapping name to namespace (ADR-0035 phase 2). The name is the primary key, so a duplicate is rejected: the INSERT ... ON CONFLICT DO NOTHING affects no rows, which is reported as an ErrInvalid-wrapped duplicate error.
func (*Store) DeleteAddon ¶
DeleteAddon removes the add-on row with the given name, or ErrNotFound if no such row exists.
func (*Store) DeleteAppHooks ¶
DeleteAppHooks removes every hook for app across every environment — the durable side of an app teardown, beside DeleteReleases. Deleting the hooks of an app that has none is a no-op.
func (*Store) DeleteDependencyCheckSettings ¶
DeleteDependencyCheckSettings removes app's recorded setting across all environments — the durable side of an app teardown.
func (*Store) DeleteEnvironment ¶
DeleteEnvironment removes the registered environment with the given name, or ErrNotFound when no such environment is registered. The default environment `prod` is stored here but is never removed: the engine rejects it before this call (ADR-0067 §2).
func (*Store) DeleteExposure ¶
DeleteExposure removes the recorded exposure for app in env. Removing one that is not recorded is a no-op: an unexpose must succeed whether or not the intent row survived.
func (*Store) DeleteHealthEndpoints ¶
DeleteHealthEndpoints removes every declared endpoint for app across all environments — the durable side of an app teardown.
func (*Store) DeleteReleases ¶
DeleteReleases removes every release record for app. Deleting the releases of an app that has none is a no-op (no RowsAffected check) — absence is fine.
func (*Store) DependencyChecksEnabled ¶
DependencyChecksEnabled reports whether the deploy-time dependency check runs for app in env.
A MISSING ROW IS TRUE. The check is Burrow's default, so a row exists only where somebody decided otherwise; this is read on every deploy, and returning ErrNotFound for the ordinary case would make the caller special-case the state every app is in.
func (*Store) DisableAutoDeploy ¶ added in v0.13.0
DisableAutoDeploy sets app's auto-deploy level in env to off and records why (e.g. "disabled by rollback") — the safety stop of ADR-0052 §5, so the watcher does not fight a deliberate downgrade. It is keyed by (app, environment) and upserts, overwriting any prior level and reason.
func (*Store) Exposure ¶
Exposure returns the recorded exposure for app in env, or ErrNotFound when the app is not published there — the read behind ADR-0076 §3's conservative default, since an exposure's port is the only container port Burrow knows for an app.
func (*Store) Exposures ¶
Exposures returns every recorded exposure, ordered by app then environment.
func (*Store) ExtendObservationWindow ¶
func (s *Store) ExtendObservationWindow(ctx context.Context, id int64, until time.Time, degraded string) error
ExtendObservationWindow advances a window's coverage and counts the sweep. A degraded note counts the sweep as incomplete and replaces the window's most recent note; a clean sweep leaves any earlier note in place, because the window is still one that had a degraded stretch in it.
Extending a window that no longer exists is ErrNotFound rather than a silent no-op: the caller's correct response is to open a fresh window, and a no-op here would have it record no coverage at all while believing it was.
func (*Store) FailBackup ¶
FailBackup marks a recorded backup failed and records the closed reason and the Burrow-authored detail beside it (ADR-0063 §7). The size is zeroed: a failed backup has no bytes anybody can restore, and leaving a length on the row would make it read like a partial success.
Neither reason nor detail may carry a secret value or a vendor response body — the caller's contract, restated here because this is the write that makes them durable.
func (*Store) Failures ¶
func (s *Store) Failures(ctx context.Context, filter controlplane.FailureFilter) ([]controlplane.Failure, error)
Failures returns ledger rows matching filter, oldest first — the order ADR-0074 §5 asks for, because the earliest first_seen in a cascade is the likeliest thing to actually fix. The filter clauses are optional and ANDed; the zero filter returns the active rows up to the cap.
func (*Store) GetEnvironment ¶ added in v0.7.0
func (s *Store) GetEnvironment(ctx context.Context, name string) (controlplane.Environment, error)
GetEnvironment returns the registered environment with the given name, or ErrNotFound.
func (*Store) HealthEndpoint ¶
func (s *Store) HealthEndpoint(ctx context.Context, app, env string) (controlplane.HealthEndpoint, error)
HealthEndpoint returns the endpoint declared for app in env, or the ZERO VALUE when none was declared. A missing row is deliberately not ErrNotFound: no endpoint is the state every app starts in (§5 is opt-in), and the deploy path reads this on every apply, so an error there would turn the ordinary case into something a caller has to special-case.
func (*Store) LatestRelease ¶
LatestRelease returns the most recently saved release for app in env, keyed per (app, environment) — env is the canonical environment name (ADR-0052 Phase 4a).
func (*Store) ListBackups ¶
ListBackups returns recorded backups, newest first. An empty app lists every app's backups and an empty env every environment's; a non-empty value restricts to that app or environment (ADR-0067 §1). No matches yields an empty slice and no error.
func (*Store) ListEnvironments ¶ added in v0.7.0
func (s *Store) ListEnvironments(ctx context.Context) ([]controlplane.Environment, error)
ListEnvironments returns the registered environments ordered by name (ADR-0035 phase 2), including the default environment `prod`, which burrowd writes here at startup (ADR-0067 §2).
func (*Store) ListReleases ¶ added in v0.13.0
ListReleases returns every release for app in env, newest first (by insertion order) — the deploy timeline the history surface reads. It reads the same rows deploys write, ordered the opposite way from Releases. Releases are keyed per (app, environment) (ADR-0052 Phase 4a), so it selects by both.
func (*Store) ManagedApps ¶
ManagedApps returns the (app, environment) pairs whose release history shows a rollout that reached the cluster — a release that was deployed, or one superseded by a later deploy, which only happens after the later one succeeded. An app whose only deploy failed before any workload was applied is deliberately excluded: it has no Deployment to be missing, and reporting one would be a false positive on the day someone is already debugging a failed deploy (ADR-0074 §6).
func (*Store) Migrate ¶
Migrate brings the database schema up to date and records appVersion as the version that last migrated it. It first enforces the single-minor-step upgrade gate (ADR-0013): if the database was last migrated by a different version, the upgrade must be exactly one minor step forward within the same major, or Migrate refuses before changing anything. Migrations are applied under a Postgres advisory lock, so concurrent control-plane replicas do not race. Migrate is safe to call on every startup; with no pending migrations it only re-stamps the version.
func (*Store) ObservationWindows ¶
func (s *Store) ObservationWindows(ctx context.Context, since time.Time, limit int) ([]controlplane.ObservationWindow, error)
ObservationWindows returns the windows whose coverage ends at or after since, oldest first. The gaps between them are what the caller is actually reading.
func (*Store) OperationalConfig ¶
func (s *Store) OperationalConfig(ctx context.Context) (controlplane.OperationalConfig, error)
OperationalConfig returns every stored operational limit value, keyed by the code it was set under — a bare code for a cluster value, `<env>.<code>` for an environment one (ADR-0068 §1). An empty table yields an empty configuration, in which every limit resolves to its built-in default.
func (*Store) PendingBackups ¶
func (s *Store) PendingBackups(ctx context.Context, before time.Time) ([]controlplane.Backup, error)
PendingBackups returns the backups still `pending` that were recorded before the cutoff, oldest first — the candidates for a Job that is gone (ADR-0074 §6). The cutoff is the caller's: it is what separates a backup still running from one nothing is going to finish.
func (*Store) Policy ¶
Policy returns the current guardrail policy: the built-in defaults with any stored guardrail dispositions overlaid (ADR-0020). An empty table yields DefaultPolicy.
func (*Store) PruneLedger ¶
func (s *Store) PruneLedger(ctx context.Context, before time.Time) (controlplane.LedgerPruneResult, error)
PruneLedger enforces the retention bound (ADR-0074 §4). It removes RESOLVED failures and elapsed coverage windows; an active failure survives however old it is, because a thing that is still broken is not history. Both deletes run in one transaction so a partial prune cannot leave the ledger and its coverage record describing different periods.
func (*Store) RecordBackup ¶
RecordBackup persists a new backup row (ADR-0032). burrowd records it pending before starting the backup Job, then SetBackupStatus moves it to completed or FailBackup to failed when the Job finishes. An existing row with the same id is overwritten. The row names the app, the claim and the path within it, the destination it is being written to, and the status — never a credential.
func (*Store) RecordExposure ¶
RecordExposure upserts the intent behind an expose, keyed by (app, environment) — what was asked for, never whether it currently works (ADR-0074 §6).
func (*Store) RecordFailure ¶
func (s *Store) RecordFailure(ctx context.Context, obs controlplane.FailureObservation) error
RecordFailure opens or extends the row for one observed failure (ADR-0074 §4). The upsert targets the PARTIAL unique index on active rows, which is what makes the whole shape work: a sighting of a failure that is already active advances last_seen and the count and leaves first_seen — the answer to "when did it start" — untouched, while a sighting of one that had been RESOLVED conflicts with nothing and opens a new row, so a thing that broke, recovered and broke again reads as two episodes rather than one long outage.
func (*Store) Releases ¶
Releases returns every release for app in env, oldest first, keyed per (app, environment).
func (*Store) ResolveFailures ¶
func (s *Store) ResolveFailures(ctx context.Context, at time.Time, keep []controlplane.FailureKey, skip []controlplane.ObjectRef) error
ResolveFailures closes every active row that is neither still observed (keep) nor unreadable (skip). Both lists arrive as text keys because Postgres compares an array of composites far less readably than an array of joined strings, and the separator cannot occur in any part.
An empty keep list resolves everything not skipped, which is correct and is the normal case once a cluster is healthy: nothing observed active means nothing is active.
func (*Store) SaveAddon ¶
SaveAddon upserts an add-on in the registry by name (ADR-0025). It records the non-secret registry entry — type, mode, backend, where it lives, and the capabilities it serves. Ready is a live property of the cluster and is never persisted; it is probed at list time.
func (*Store) SaveProvider ¶
SaveProvider upserts a provider in the registry by name (ADR-0023). It records only the non-secret registry entry; the token lives in the burrow-credentials Secret.
func (*Store) SaveRelease ¶
func (*Store) SetAppHook ¶
func (s *Store) SetAppHook(ctx context.Context, app, env string, phase controlplane.HookPhase, command []string) error
SetAppHook upserts the command app runs at phase in env, replacing any command already set there. The command arrives validated by the engine, which is the only place that knows what a runnable argv is; the store records what it is given.
func (*Store) SetAutoDeployLevel ¶ added in v0.13.0
func (s *Store) SetAutoDeployLevel(ctx context.Context, app, env string, level controlplane.AutoDeployLevel) error
SetAutoDeployLevel upserts app's auto-deploy level in env, keyed by (app, environment). It CLEARS any stored disable reason: a human setting the level (the re-enable path) removes the rollback or downgrade note, because re-enabling is a deliberate human action (ADR-0052 §5).
func (*Store) SetBackupStatus ¶
func (s *Store) SetBackupStatus(ctx context.Context, id string, status controlplane.BackupStatus, sizeBytes int64) error
SetBackupStatus updates a recorded backup's status and size (the Job-finished transition). It CLEARS any recorded failure, so a row that reaches completed cannot keep a stale reason from an earlier attempt beside it. Setting the status of an unknown backup id returns ErrNotFound.
func (*Store) SetDependencyChecks ¶
func (s *Store) SetDependencyChecks(ctx context.Context, app, env string, enabled bool, at time.Time) error
SetDependencyChecks records whether the deploy-time dependency check runs for app in env. Enabling writes a row rather than deleting one, so "somebody looked at this and left it on" and "nobody has ever thought about it" stay distinguishable.
func (*Store) SetGuardrail ¶
func (s *Store) SetGuardrail(ctx context.Context, code controlplane.GuardrailCode, disp controlplane.Disposition) error
SetGuardrail upserts one guardrail's disposition.
func (*Store) SetHealthEndpoint ¶
func (s *Store) SetHealthEndpoint(ctx context.Context, ep controlplane.HealthEndpoint) error
SetHealthEndpoint upserts the declared endpoint for an app in one environment.
func (*Store) SetLimit ¶
SetLimit upserts one operational limit's value. The value arrives validated and canonicalized by the engine, which is the only place that knows a limit's kind and bounds; the store records what it is given.
func (*Store) StartObservationWindow ¶
StartObservationWindow opens a window for one run of the observer and returns its id.
func (*Store) UnsetAppEnv ¶
UnsetAppEnv removes one env key for app. Removing a key that is not set is a no-op.
func (*Store) UnsetAppHook ¶
func (s *Store) UnsetAppHook(ctx context.Context, app, env string, phase controlplane.HookPhase) error
UnsetAppHook removes app's hook at phase in env. Removing one that is not set is a no-op.
func (*Store) UnsetHealthEndpoint ¶
UnsetHealthEndpoint removes the declared endpoint for app in env, returning it to the conservative default. Removing one that was never declared is a no-op: unset must be idempotent, since it is what a user reaches for when they are not sure what is set.