Help us shape the future of Go! Take the 2026 Go Developer Survey

pgbinding

package
v0.4.2 Latest Latest
Warning

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

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

Documentation

Overview

Package pgbinding defines how a consumer service binds to an existing Karakoram PostgreSQL cluster: the control plane creates the consumer's databases and one least-privilege owning login role on the source, seals the role password, and blocks source deletion while the binding exists. See docs/adr/0045-postgres-bindings.md.

Index

Constants

View Source
const (
	TLSVerifyFull = "verify-full"
	TLSVerifyCA   = "verify-ca"
)

TLS mode values reported in Connection.TLS.Mode.

View Source
const (
	PhasePending   = "pending"
	PhaseRunning   = "running"
	PhaseCompleted = "completed"
	PhaseFailed    = "failed"
)

Backup and operation phases reported by BackupBinder.

View Source
const MaxDatabases = 8

MaxDatabases bounds the databases one binding may own.

Variables

View Source
var ErrSharedSource = errors.New("postgres binding source is shared by other consumers")

ErrSharedSource rejects a restore through a binding whose source serves other consumers unless the caller explicitly acknowledges the impact.

View Source
var ErrSourceUnavailable = errors.New("postgres binding source unavailable")

ErrSourceUnavailable reports a source that does not exist, is being deleted, is not a PostgreSQL provider, or is outside a consumer's major-version range.

Functions

func BindingID

func BindingID(r Request) string

BindingID returns the stable, URL-safe identity of a consumer/source pair. Empty namespaces mean "default". Database, extension and version requests do not affect identity. Cleanup must Release this ID even if Ensure never succeeded.

Types

type Access

type Access interface {
	postgres.Access
	EnsureBindingRole(context.Context, *engine.Context, string, int) error
	VerifyBindingRole(context.Context, *engine.Context, string) (uint32, error)
	OwnBindingDatabase(context.Context, *engine.Context, postgres.Database) error
	BindingEndpoint(context.Context, *engine.Context) (string, []byte, error)
}

type BackupBinder

type BackupBinder interface {
	Backup(ctx context.Context, bindingID, backupType, idempotencyKey string) (BackupRef, error)
	BackupStatus(ctx context.Context, bindingID, backupID string) (State, error)
	Restore(ctx context.Context, bindingID, backupID, idempotencyKey string, acknowledgeShared bool) (OperationRef, error)
	OperationStatus(ctx context.Context, bindingID, operationID string) (State, error)
}

BackupBinder is an optional Service extension that lets a consumer request and observe backups and in-place restores of its source without owning it. Backup is idempotent by idempotencyKey. Restore returns ErrSharedSource for a shared source unless acknowledgeShared is true; it is destructive for every consumer of the source.

type BackupRef

type BackupRef struct{ ID string }

BackupRef identifies a source backup created through a binding.

type Connection

type Connection struct {
	BindingID string
	// Host and Port address the source's stable writer endpoint.
	Host      string
	Port      int
	Databases []string
	Username  string
	// PasswordSecretRef names the sealed password; resolve it only in-process
	// through Service.Password and never return it through an API read.
	PasswordSecretRef string
	TLS               TLS
	// MaxConnections is the role's connection limit; zero means unlimited.
	MaxConnections int
	// CredentialGeneration increases on every password rotation. Consumers
	// compare it in Sync and re-render/roll their configuration on change.
	CredentialGeneration int64
	// Shared reports other consumers bound to the same source; ConsumerCount
	// includes this binding. In-place restores and major upgrades of the source
	// affect every bound consumer.
	Shared        bool
	ConsumerCount int
}

Connection is the resolved, non-secret connection material of a binding.

type Manager

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

func New

func New(o Options) *Manager

func (*Manager) Backup

func (m *Manager) Backup(ctx context.Context, id, kind, key string) (BackupRef, error)

func (*Manager) BackupStatus

func (m *Manager) BackupStatus(ctx context.Context, id, backupID string) (State, error)

func (*Manager) Ensure

func (m *Manager) Ensure(ctx context.Context, r Request) (Connection, error)

func (*Manager) OperationStatus

func (m *Manager) OperationStatus(ctx context.Context, id, operationID string) (State, error)

func (*Manager) Password

func (m *Manager) Password(ctx context.Context, ref string) (string, error)

func (*Manager) Release

func (m *Manager) Release(ctx context.Context, id string, keepData bool) error

func (*Manager) Resolve

func (m *Manager) Resolve(ctx context.Context, id string) (Connection, error)

func (*Manager) Restore

func (m *Manager) Restore(ctx context.Context, id, backupID, key string, ack bool) (OperationRef, error)

func (*Manager) Rotate

func (m *Manager) Rotate(ctx context.Context, id string) (Connection, error)

type OperationRef

type OperationRef struct{ ID string }

OperationRef identifies a source operation started through a binding.

type Options

type Options struct {
	Store   *store.Store
	Source  func(context.Context, domain.ClusterRef) (*engine.Context, Access, error)
	Trigger func(domain.ClusterRef)
}

Options supplies source-specific contexts, never the consumer's credentials. Trigger must enqueue immediately, not defer a single request-local trigger.

type Request

type Request struct {
	// ConsumerKind is the consumer provider, e.g. "keycloak", "temporal", "openbao".
	ConsumerKind      string
	ConsumerNamespace string
	ConsumerName      string
	SourceNamespace   string
	SourceCluster     string
	// Databases are created on the source and owned by the binding role (>=1, same cluster).
	Databases []string
	// Extensions are created in every bound database; each must be available on the source.
	Extensions []string
	// MinMajor and MaxMajor bound the PostgreSQL majors the consumer supports;
	// zero means unbounded. The source's major upgrades honour MaxMajor.
	MinMajor, MaxMajor int
}

Request asks for a binding of one consumer to one source cluster. Ensure is idempotent for the same (consumer, source) identity; changing Databases or Extensions of an existing binding is additive.

func (Request) Admits

func (r Request) Admits(major int) bool

Admits reports whether a source major satisfies the request's range.

func (Request) Validate

func (r Request) Validate() error

Validate checks a request's syntax; source existence and extension availability are checked by the Service.

type Service

type Service interface {
	Ensure(context.Context, Request) (Connection, error)
	Resolve(ctx context.Context, bindingID string) (Connection, error)
	// Release removes the binding. Unless keepData, the bound databases and role
	// are dropped on the source after the consumer's runtimes are gone; with
	// keepData the databases remain and the role is disabled (NOLOGIN).
	Release(ctx context.Context, bindingID string, keepData bool) error
	Password(ctx context.Context, ref string) (string, error)
}

Service manages bindings. Implementations are safe for concurrent use.

type State

type State struct {
	Phase       string
	CompletedAt time.Time
	Error       string
}

State is the observed progress of a backup or operation.

type TLS

type TLS struct {
	Mode  string
	CAPEM []byte
}

TLS carries the trust material a consumer needs to verify the source endpoint.

Jump to

Keyboard shortcuts

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