Documentation
¶
Overview ¶
Package store builds the storage ports once, from configuration, for the apps to be handed: the one place that knows which adapter backs them.
Everything else names the interfaces of internal/port. The adapter is chosen by the `ports.adapter` key of the configuration file: `legacy` (the default, today's ConfigMaps, Secrets and Valkey, unchanged), `memory` or `dynamodb`.
Index ¶
- Constants
- Variables
- func RequireSharedLease(shared, unsafeLocal bool) error
- type Backend
- type Config
- type FlagTable
- type KubeNeed
- type Stores
- func (s *Stores) ClientSecretPort() port.Secrets
- func (s *Stores) Close()
- func (s *Stores) FlagTables() ([]FlagTable, error)
- func (s *Stores) ForModule(own port.Module, peers ...port.Module) (port.Set, error)
- func (s *Stores) LeaseState() (state port.State, shared bool)
- func (s *Stores) Maintenance() *maintenance.Gate
- func (s *Stores) MaintenanceOf(m port.Module) *maintenance.Gate
- func (s *Stores) Name() string
- func (s *Stores) Readiness() any
- func (s *Stores) SecretsPlace() (adapter, root string)
Constants ¶
const ( AdapterLegacy = "legacy" AdapterMemory = "memory" // AdapterDynamoDB keeps State, the session index and the trigger in one // DynamoDB table. AdapterDynamoDB = "dynamodb" )
The adapters `ports.adapter` names.
const BlobS3 = "s3"
BlobS3 is the adapter `ports.blob.adapter` names. It replaces one port and composes with any `ports.adapter`.
Variables ¶
var ErrLocalLease = errors.New("the tick leases are held in this process only, so a running controller " +
"would not be kept off the same target and both could act on it (duplicate invites or removals): " +
"this is safe once a shared State exists (docs/decisions/0029, B3). Scale the controller to 0 and " +
"pass --unsafe-local-lease to run the tick anyway")
ErrLocalLease is the refusal of a one-shot tick whose lease would not exclude the running controller.
Functions ¶
func RequireSharedLease ¶
RequireSharedLease refuses a one-shot tick when its lease State is not shared with the controller's, unless the operator opted in.
Types ¶
type Config ¶
type Config struct {
Adapter string
// Release prefixes the objects' names and the Valkey keys.
Release string
Kube KubeNeed
// Blob replaces the port of the same name; nil keeps what Adapter brings.
Blob *config.PortsBlob
// DynamoDB is the table of the `dynamodb` adapter: Table on layout v4,
// Tables (one per module) on layout v5.
DynamoDB dynamoport.Config
// Module is the module this process runs, and Peers the modules whose
// tables it may read (ADR 0072). They matter on layout v5 only: the State
// is then Module's own table, a write of another module's key is refused,
// and each peer is a read-only view. The composition root of each binary
// sets them; an empty Module on layout v5 is the whole-estate view of the
// migration and the backup (the router over every table).
Module port.Module
Peers []port.Module
// NoTrigger is set by a module that never notifies a controller (the backup
// and the restore): the plan's `trigger` adapter is not built for it. The
// aws-serverless preset names `invoke`, which needs the controller functions
// only the issuer's document names, and would stop such a module at start.
NoTrigger bool
// Secrets delivers the secrets the document names (the Valkey password):
// the composition root sets it after FromServe. Nil delivers none.
Secrets secrets.Source
// SecretsRoot is the serve document's `secrets.root` when its source is
// ssm: the root the `ssm` Secrets adapter takes.
SecretsRoot string
// SecretsKMSKey is the serve document's `secrets.kmsKeyId` when its source
// is ssm: the key the `ssm` Secrets adapter encrypts what it writes with.
SecretsKMSKey string
// Secrets layout (ADR 0041): the serve document's `secrets.layout`,
// `.region`, `.endpoint` and `.grace` when its source is ssm. The layout
// is v4 (the Secrets port is over it, internal/secretstore) or v5 (ADR
// 0072, [Stores.V5]); the two do not mix with the other layout's tables.
SecretsLayout string
SecretsSSM bool
SecretsRegion string
SecretsEndpoint string
SecretsGrace time.Duration
// SecretsReadCache is `secrets.readCache`; nil is not set.
SecretsReadCache *time.Duration
// OpenState opens the backend of the v4 stores (storage/state/ssm over the
// service's retryer, openSSMState).
// Nil is that backend.
OpenState secretstore.Opener
// Cloudflare and Instance are the service document's `cloudflare` section
// and the instance name; the Blob mints its own R2 credentials from a
// preset of it (`ports.blob.s3.credentials.preset`). Nil when the blob uses
// a static document, which needs neither.
Cloudflare *config.Cloudflare
Instance string
// CloudflareDial opens a Cloudflare account; nil is the real client.
CloudflareDial minter.Dialer
// contains filtered or unexported fields
}
Config is what Open needs.
func FromRoster ¶
FromRoster reads what the two controllers share. A controller's reports and links are objects in its namespace, so it requires the cluster.
func (Config) As ¶ added in v1.75.0
As is the Config of a process that runs module own and reads the tables of peers (ADR 0072). It matters on layout v5, where the State is the module's own table; on layout v4 there is one table and it changes nothing.
func (Config) OpenDry ¶ added in v1.76.0
OpenDry builds what Open builds, as a deploy's check does: nothing it reaches mutates. The adapter table is resolved and validated, and State, the blobs, the secrets and the trigger are constructed from their settings, so a setting a function needs and the document lacks is refused here as it is at start. A DynamoDB table is bound and never created, and a blob whose credentials a Cloudflare preset mints is validated and left unopened, because opening it would mint. The Stores are the caller's to Close. An adapter that needs a cluster (the Kubernetes build's own) is planned and not opened, and the Stores are nil.
func (Config) Plan ¶ added in v1.75.0
Plan is the adapter table Open would build the ports from, resolved and validated, with nothing opened: a document's adapter choices can be checked without reaching the stores they name.
func (*Config) SetSecrets ¶ added in v1.74.0
SetSecrets carries the service document's `secrets` section (the `ssm` source: root, KMS key, layout, region, endpoint, grace) into the config. A controller assembled from the service document calls it too, so it sees the same layout the service does. Any other source sets nothing.
type FlagTable ¶ added in v1.75.0
type FlagTable struct {
// Module names the table's module; empty for the one table of layout v4.
Module port.Module
State port.State
}
FlagTable is one State that holds a maintenance flag: a module's own table on layout v5, or the one table of layout v4 (Module is then empty).
type KubeNeed ¶
type KubeNeed int
KubeNeed says how much a process needs the namespace's objects.
const ( // KubeNone opens nothing: a hub with `store: memory`. KubeNone KubeNeed = iota // KubeOptional tries, and goes on without when this is not a cluster: an // issuer proving recovery against one it may not be running in. KubeOptional // KubeRequired stops the start when this is not a cluster. KubeRequired )
How much a process needs the cluster.
type Stores ¶
type Stores struct {
// Ports is every port, over the chosen adapter.
Ports port.Set
// Backend is today's storage as it was opened: what the `legacy` adapter
// is made of, and, with any adapter, the cluster's own objects that stay the
// cluster's (the token review, the declared OAuth client). The domain stores
// (a connected workspace and its credential, an organisation, a person's
// link, the Slack records) are on Ports for every adapter but `legacy`
// (internal/portstore), and in the ConfigMaps and Secrets this reaches for
// `legacy`. It is nil with the memory adapter, which has none.
Backend *Backend
// Adapter is the state adapter's name.
Adapter string
// Plan is the resolved adapter per concern, for the packages that wire a
// concern this package does not.
Plan port.Table
// SecretsRoot is the root the secrets are kept under when the source is
// ssm (/sluis/<instance>), and empty for another source.
SecretsRoot string
// Secrets delivers the secrets the document names, by name: what the
// composition root put in Config.Secrets. Nil delivers none.
Secrets secrets.Source
// V4 is the installation's secrets on layout v4: Internal and External
// over one state store. Nil when the secrets are not the ssm source's.
V4 *secretstore.Stores
// V5 is the installation's secrets on layout v5: module first (ADR 0072).
// Nil unless `secrets.layout: v5`; V4 is then nil, and the Secrets port
// is not set: a caller reads its module's names from V5. The callers move
// to it module by module.
V5 *secretstore.StoresV5
// ClientSecrets is the Secrets port of the generated clients' records
// (external/oidc/<id>) on layout v5, where Ports.Secrets is not set. Nil on
// layout v4; [Stores.ClientSecretPort] picks the one in force.
ClientSecrets port.Secrets
// Tables is the table of each module on layout v5, nil on layout v4 and
// with any other adapter. Router, on it, is the one State over all of them
// that the migration and the backup use.
Tables *dynamoport.Tables
Shared bool
// Usable is whether the State, Index and snapshot Blob ports work at all:
// the memory adapter, and the legacy one with a Valkey. Without them a
// caller keeps its own process-local store, as it always has.
Usable bool
// contains filtered or unexported fields
}
Stores is the ports, built once.
func (*Stores) ClientSecretPort ¶ added in v1.75.0
ClientSecretPort is the Secrets port that holds the generated clients' records: Stores.ClientSecrets on layout v5, the Secrets port otherwise.
func (*Stores) FlagTables ¶ added in v1.75.0
FlagTables are the States that hold the maintenance flag of this installation: one per module on layout v5, where each module reads the flag of its own table, and one on layout v4. The legacy adapter holds no flag and has none.
func (*Stores) ForModule ¶ added in v1.75.0
ForModule is the ports of module own with read-only views of peers, out of the tables or the memory stores this was opened over. It is how a process that hosts several modules (the issuer's function, until a provider leaves it) gives each its own table: the issuer's State is the oidc table, and a module it hosts writes its own. On layout v4 there is one table and no module to split by, so it is the Ports unchanged. The Blob, Identity and Secrets are the process's, observed once.
func (*Stores) LeaseState ¶
LeaseState is the State the controllers take their tick leases from, and whether it is shared by every replica. A lease is only exclusive across processes when the State is: the legacy adapter keeps leases in Valkey, so without one a controller holds its leases in its own memory and a second replica would not be kept off (docs/concepts/sluis/ports.md, "The legacy adapter").
func (*Stores) Maintenance ¶ added in v1.75.0
func (s *Stores) Maintenance() *maintenance.Gate
Maintenance is the gate over the maintenance flag in this process's own State: the table of the module it serves, where the restore function sets it. Nil, which never refuses, with no usable shared State, and with the legacy adapter, which holds no such record.
func (*Stores) MaintenanceOf ¶ added in v1.75.0
func (s *Stores) MaintenanceOf(m port.Module) *maintenance.Gate
MaintenanceOf is the gate over module m's own table, for a process that hosts several modules (the issuer's function). On layout v4 there is one table, so it is Stores.Maintenance.
func (*Stores) SecretsPlace ¶ added in v1.76.0
SecretsPlace is the secrets adapter and the root it keeps them under, for a page that tells a person where a secret is: the adapter the plan resolved and the `root` its settings name, or the serve document's `secrets.root`. Both are empty where no secrets adapter was chosen.