kube

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package kube is the production controlplane.Kubernetes adapter, built on the official client-go SDK (ADR-0011). It translates the workload seam into Kubernetes Deployments and reads their status, scales, streams logs, and deletes them. It is a thin translation layer — no orchestration logic, which lives in the engine. v0.1 supports only WorkloadDeployment.

It lives under controlplane/ (not controlplane/internal) so cmd/burrowd and the managed module can wire it; it is licensed Apache-2.0.

Index

Constants

View Source
const DefaultCredentialsSecret = "burrow-credentials"

DefaultCredentialsSecret is the one Secret in the control-plane namespace that holds every vendor token, one key per provider (ADR-0023).

View Source
const PostgresPasswordKey = "password"

PostgresPasswordKey is the key under which the superuser password is stored in PostgresSecretName.

View Source
const PostgresSecretName = "burrow-postgres"

PostgresSecretName is the Secret in the add-on namespace that holds the generated superuser password (ADR-0031). It lives in the add-on namespace — not the control-plane credentials Secret — because a pod can only mount a Secret in its own namespace.

View Source
const PostgresSuperuser = "burrow_admin"

PostgresSuperuser is the fixed superuser role burrowd provisions the add-on Postgres instance with and connects as to run admin SQL (ADR-0031). It is deliberately not the built-in "postgres" role: a distinct, Burrow-owned admin role keeps the boundary clear.

Variables

This section is empty.

Functions

func ConfigFromKubeconfig

func ConfigFromKubeconfig(path string) (*rest.Config, error)

ConfigFromKubeconfig builds a REST config from an explicit kubeconfig file path. It is used by the integration tests, which point at a disposable cluster rather than the ambient one.

func DetectCapabilities

func DetectCapabilities(ctx context.Context, client kubernetes.Interface) (controlplane.ClusterCapabilities, error)

DetectCapabilities reads a cluster's capabilities read-only over the given clientset (ADR-0034): the ingress controller and its IngressClasses, the default and all StorageClasses, the cloud provider (from node providerIDs/labels), and cert-manager (via API-group discovery), and infers LoadBalancer support from the provider. It performs only get/list reads and API-group discovery — it never writes. It is a free function so the same detection runs whether driven by the kubeconfig client (install) or burrowd's in-cluster client (live). The returned report omits the DNS capability, which is a control-plane registry fact filled by the engine.

func LoadConfig

func LoadConfig() (*rest.Config, error)

LoadConfig resolves the cluster connection the way a control plane should: the in-cluster service account when running inside Kubernetes, otherwise the ambient kubeconfig (KUBECONFIG or ~/.kube/config). burrowd uses this.

Types

type Adapter

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

Adapter operates Burrow workloads in a single app namespace, and provisions add-ons in a separate add-on namespace (ADR-0025) so backing services don't mix with user workloads.

func New

func New(client kubernetes.Interface, namespace string) *Adapter

New returns an Adapter over the given clientset and namespace (defaulting to "default"). Tests inject a fake clientset; production injects a real one (see NewFromConfig).

func NewFromConfig

func NewFromConfig(cfg *rest.Config, namespace string) (*Adapter, error)

NewFromConfig builds an Adapter from a REST config and namespace.

func (*Adapter) AddonReady

func (a *Adapter) AddonReady(ctx context.Context, name string) (bool, error)

AddonReady reports whether the named add-on's backing Deployment is available (ADR-0025). Readiness is a live property of the cluster — the registry of what add-ons exist lives in the database — so this is a cheap single-Deployment probe. A missing Deployment is reported as not ready (false, nil); only a real API error is returned.

func (*Adapter) ApplyWorkload

func (a *Adapter) ApplyWorkload(ctx context.Context, spec controlplane.WorkloadSpec) error

func (*Adapter) DeleteAddon

func (a *Adapter) DeleteAddon(ctx context.Context, name string) error

func (*Adapter) DeleteWorkload

func (a *Adapter) DeleteWorkload(ctx context.Context, app string) error

func (*Adapter) DeployAddon

func (*Adapter) Expose

func (a *Adapter) Expose(ctx context.Context, spec controlplane.ExposeSpec) error

func (*Adapter) ExposureStatus

func (a *Adapter) ExposureStatus(ctx context.Context, app string) (controlplane.ExposureStatus, error)

func (*Adapter) ListWorkloads

func (a *Adapter) ListWorkloads(ctx context.Context) ([]controlplane.WorkloadStatus, error)

func (*Adapter) Logs

func (*Adapter) RestartWorkload

func (a *Adapter) RestartWorkload(ctx context.Context, app string, at time.Time) error

RestartWorkload bumps app's pod-template restarted-at annotation to at, triggering a rolling update so a running app picks up a secret change that envFrom reads only at pod start (ADR-0028). A missing Deployment is ErrNotFound — nothing running to roll.

func (*Adapter) RunBackupJob

func (a *Adapter) RunBackupJob(ctx context.Context, app, backupID string) (int64, error)

RunBackupJob pg_dumps app's database to the backup PVC via a one-shot Job and waits for it to finish (ADR-0032). The dump command names no host or password — those come from libpq env, the password via secretKeyRef. The container also writes the dump's byte size to the termination-log so burrowd can read size_bytes from the pod's terminated state without mounting the volume.

func (*Adapter) RunRestoreJob

func (a *Adapter) RunRestoreJob(ctx context.Context, app, backupID string) error

RunRestoreJob pg_restores app's dump from the backup PVC into its database via a one-shot Job and waits for it (ADR-0032). --clean --if-exists replaces current contents. Like backup, the command names no host or password.

func (*Adapter) ScaleWorkload

func (a *Adapter) ScaleWorkload(ctx context.Context, app string, replicas int32) error

func (*Adapter) SecretKeys

func (a *Adapter) SecretKeys(ctx context.Context, app string) ([]string, error)

SecretKeys returns the env-var names in app's per-app Secret, sorted, never the values (ADR-0028/0004). A missing Secret is an app with no secrets set: empty slice, no error.

func (*Adapter) SetSecretValue

func (a *Adapter) SetSecretValue(ctx context.Context, app, key, value string) error

SetSecretValue upserts key=value into app's per-app Secret (controlplane.AppSecretName(app)) in the app namespace, creating the Secret (Opaque, Burrow labels) if absent (ADR-0029). The value arrives here over burrowd's authenticated control-plane API and is written to the Kubernetes Secret; it never reaches a log, the audit log, Postgres, or MCP (ADR-0029/0004). The returned error names the app and key only, never the value. It retries on conflict since a concurrent set/unset can race the resourceVersion.

func (*Adapter) Unexpose

func (a *Adapter) Unexpose(ctx context.Context, app string) error

func (*Adapter) UnsetSecretKey

func (a *Adapter) UnsetSecretKey(ctx context.Context, app, key string) error

UnsetSecretKey removes one key from app's per-app Secret (get, delete the key, update). A missing Secret or a missing key is a no-op, not an error. The value never crosses here — the caller passes only the key name (ADR-0004).

func (*Adapter) WithAddonNamespace

func (a *Adapter) WithAddonNamespace(ns string) *Adapter

WithAddonNamespace sets the namespace Burrow deploys add-ons (and their collectors) into, kept separate from the app namespace and the credential-holding control-plane namespace (ADR-0025). An empty value leaves the default. Returns the Adapter for chaining.

func (*Adapter) WorkloadStatus

func (a *Adapter) WorkloadStatus(ctx context.Context, app string) (controlplane.WorkloadStatus, error)

type Credentials

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

Credentials is the production controlplane.Credentials adapter: it reads and writes vendor tokens in the single burrow-credentials Secret in the control-plane namespace (ADR-0023, ADR-0030). It reads on every call so a rotated token is picked up without a restart, and it writes a token value the engine received over burrowd's authenticated control-plane API. burrowd's Role grants `get` and `update` on exactly this one object, so this is its sole access to a Secret's contents.

func NewCredentials

func NewCredentials(client kubernetes.Interface, namespace, secret string) *Credentials

NewCredentials returns a Credentials reader over the given clientset, control-plane namespace, and Secret name (defaulting to burrow-credentials). Tests inject a fake clientset; production injects a real one (see NewCredentialsFromConfig).

func NewCredentialsFromConfig

func NewCredentialsFromConfig(cfg *rest.Config, namespace, secret string) (*Credentials, error)

NewCredentialsFromConfig builds a Credentials reader from a REST config.

func (*Credentials) SetToken

func (c *Credentials) SetToken(ctx context.Context, key, value string) error

SetToken upserts key=value into burrow-credentials, creating the Secret (Opaque) if absent so the command works against an install that has not yet created it (ADR-0030). The value arrives over burrowd's authenticated control-plane API and is written straight to the Secret; it never reaches a log, Postgres, or an API response — the returned error names the key only, never the value. It retries on conflict since a concurrent set can race the resourceVersion.

func (*Credentials) Token

func (c *Credentials) Token(ctx context.Context, key string) (string, error)

Token returns the token stored under key, or ErrNotFound when the Secret or the key is absent.

type PostgresProvisioner

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

PostgresProvisioner is the production controlplane.DatabaseProvisioner: it connects to the installed Postgres add-on as the burrow_admin superuser and gives each app its own database and login role (ADR-0031). It reads the superuser password from the burrow-postgres Secret in the add-on namespace through a Kubernetes client (a pod can only mount a Secret in its own namespace, so the password lives there), and reaches the instance in-cluster at burrow-postgres.<addon-ns>.svc:5432. It holds no long-lived database handle — it opens a short-lived connection per operation so a rotated superuser password is always picked up.

func NewPostgresProvisioner

func NewPostgresProvisioner(client kubernetes.Interface, addonNamespace string) *PostgresProvisioner

NewPostgresProvisioner returns a provisioner over the given clientset and add-on namespace.

func NewPostgresProvisionerFromConfig

func NewPostgresProvisionerFromConfig(cfg *rest.Config, addonNamespace string) (*PostgresProvisioner, error)

NewPostgresProvisionerFromConfig builds a provisioner from a REST config.

func (*PostgresProvisioner) DropAppDatabase

func (p *PostgresProvisioner) DropAppDatabase(ctx context.Context, app string) error

DropAppDatabase drops app's database and login role from the shared instance (ADR-0031). It validates app and quotes identifiers before any SQL. Dropping an already-absent database or role is a no-op (IF EXISTS), not an error. The database is dropped WITH (FORCE) so live sessions do not block teardown.

func (*PostgresProvisioner) EnsureAppDatabase

func (p *PostgresProvisioner) EnsureAppDatabase(ctx context.Context, app string) (string, error)

EnsureAppDatabase provisions (idempotently) an isolated database and login role for app and returns its DATABASE_URL with a freshly generated password (ADR-0031). It validates app against the strict identifier pattern and quotes every identifier BEFORE any SQL runs. On a fresh attach it CREATEs the role and database and locks the database down to that role; on a re-attach (role or database already present) it ALTERs the role's password to rotate, so the returned URL is always current. The returned connection string is a SECRET value — the caller writes it straight into the app's Secret and never logs, audits, or returns it.

func (*PostgresProvisioner) WithAdminEndpoint

func (p *PostgresProvisioner) WithAdminEndpoint(hostPort string) *PostgresProvisioner

WithAdminEndpoint overrides the host:port the provisioner dials for admin SQL (see adminEndpoint). It is for tests that reach the instance through a port-forward; production leaves it unset.

type Prober

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

Prober is the production controlplane.ClusterProber: it detects a cluster's read-only capabilities over a client-go clientset (ADR-0034). It wraps the same clientset burrowd already holds, so the live read needs only the narrow read-only ClusterRole the install grants (get/list on nodes, storageclasses, ingressclasses) plus API-group discovery (no RBAC). It never writes.

func NewProber

func NewProber(client kubernetes.Interface) *Prober

NewProber returns a Prober over the given clientset.

func NewProberFromConfig

func NewProberFromConfig(cfg *rest.Config) (*Prober, error)

NewProberFromConfig builds a Prober from a REST config — burrowd's in-cluster config, so the live capability read uses the narrow read-only ClusterRole the install grants (ADR-0034).

func (*Prober) DetectCapabilities

func (p *Prober) DetectCapabilities(ctx context.Context) (controlplane.ClusterCapabilities, error)

DetectCapabilities reads the cluster's capabilities read-only.

Jump to

Keyboard shortcuts

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