Documentation
¶
Overview ¶
Package kv is the KV service (ADR-0019/0072/0073): the function-facing Facade (binding-gated, <ns>/<store>/<table>/<key> prefixed, results prefix-stripped) over the kvstore.KV port, plus the KV services.TypeHandler the Service dispatcher routes type:kv to, and the KindKVStore reconciler.
ADR-0073 makes KV bindings live on the consumer (Function.spec.bindings.kv); ADR-0074 makes authorization the PDP's job: the facade resolves a caller's (function, alias) to a (store, table) — that is NAMING — then asks the PDP (auth.Authorizer) a per-object question: kv::read (get/list) or kv::write (put/del) on the KVTable. Reads are DEFAULT-DENY (need a permitting Policy); writes are governed by the built-in forbid(kv::write) unless principal == resource.owner (single-writer). A PDP deny maps to fault.Forbidden. Per-op caps + a table-scoped prefix still apply.
Index ¶
- func NewHandler() services.TypeHandler
- type Binding
- type BindingResolver
- type Facade
- func (f *Facade) CheckRead(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias string) error
- func (f *Facade) Delete(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias, key string) error
- func (f *Facade) Get(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias, key string) ([]byte, bool, error)
- func (f *Facade) List(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, ...) ([]string, error)
- func (f *Facade) Put(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias, key string, ...) error
- type FacadeDeps
- type MetaReader
- type PrefixManager
- type Quarantine
- func (q Quarantine) Expire(ctx context.Context, cutoff time.Time) ([]quarantine.Entry, error)
- func (q Quarantine) List(ctx context.Context) ([]quarantine.Entry, error)
- func (q Quarantine) Move(ctx context.Context, ref quarantine.Ref, now time.Time) (quarantine.Entry, error)
- func (q Quarantine) Return(ctx context.Context, ref quarantine.Ref, since time.Time) error
- type Reconciler
- func (r *Reconciler) MapFunction(ctx context.Context, obj v1.Object) []controller.Request
- func (r *Reconciler) Orphans(ctx context.Context) ([]string, error)
- func (r *Reconciler) Quarantine() Quarantine
- func (r *Reconciler) ReclaimDeleted(ctx context.Context, now time.Time) error
- func (r *Reconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)
- type ReconcilerDeps
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewHandler ¶
func NewHandler() services.TypeHandler
NewHandler returns the KV services.TypeHandler (Type() == ServiceTypeKV).
Types ¶
type Binding ¶
type Binding struct {
Store v1.ObjectName
Table string
Owner v1.ObjectName
MaxValueBytes int64
MaxKeyBytes int
}
Binding is the resolved KV binding for a (caller, alias) pair (ADR-0073): the target store + table, the table's owner (single writer), and the store's per-op caps — everything the facade needs to authorize + bound a call.
type BindingResolver ¶
type BindingResolver interface {
Resolve(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias string) (Binding, error)
}
BindingResolver maps a caller function + alias to its (store, table) + owner + caps (ADR-0073). It reads the caller's Function.spec.bindings.kv (the binding IS the capability) and the target KVStore. fault.Forbidden when the caller has no spec.bindings.kv entry for the alias (default-deny).
func NewResolver ¶
func NewResolver(r MetaReader) (BindingResolver, error)
NewResolver builds the metastore-backed BindingResolver. r is required.
type Facade ¶
type Facade struct {
// contains filtered or unexported fields
}
Facade is what a function calls: binding-resolved + PDP-authorized + table-prefixed KV (ADR-0074).
func NewFacade ¶
func NewFacade(d FacadeDeps) (*Facade, error)
NewFacade builds the KV facade. KV, Resolver, and Authorizer are required.
func (*Facade) CheckRead ¶ added in v0.10.0
func (f *Facade) CheckRead(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias string) error
CheckRead resolves the alias and asks the PDP kv::read on its table, as Get does, with no engine call: the dependency check of a caller's binding (ADR-0215 Decision 3).
func (*Facade) Delete ¶
func (f *Facade) Delete(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias, key string) error
Delete removes the alias's key. The PDP authorizes kv::write (owner-only via the built-in forbid).
func (*Facade) Get ¶
func (f *Facade) Get(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias, key string) ([]byte, bool, error)
Get returns the value for the alias's key. Reads are DEFAULT-DENY: the PDP must permit kv::read (a permitting Policy) on the resolved table (ADR-0074).
func (*Facade) List ¶
func (f *Facade) List(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias, prefix string) ([]string, error)
List returns the alias's keys under prefix. Like Get, listing is DEFAULT-DENY: the PDP must permit kv::read on the resolved table (ADR-0074). The <ns>/<store>/<table>/ prefix is stripped so the caller only sees its own key space.
func (*Facade) Put ¶
func (f *Facade) Put(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias, key string, value []byte) error
Put stores value under the alias's key. The PDP authorizes kv::write — the built-in forbid(kv::write) unless principal == resource.owner makes this owner-only (ADR-0074). Per-op caps next.
type FacadeDeps ¶
type FacadeDeps struct {
KV kvstore.KV
Resolver BindingResolver
Authorizer auth.Authorizer
Logger *slog.Logger
}
FacadeDeps configures the KV facade (the PEP). The BindingResolver (ADR-0073) resolves the alias→(store,table) NAMING; the Authorizer (ADR-0074) is the PDP that decides kv::read/kv::write.
type MetaReader ¶
type MetaReader interface {
Get(ctx context.Context, gvk v1.GroupVersionKind, ns v1.NamespaceName, name v1.ObjectName) (v1.Object, error)
}
MetaReader is the read-only metastore view the resolver needs (a subset of store.Store), declared here so the kv package stays near-leaf; the wiring adapts the real store.Store to it.
type PrefixManager ¶
type PrefixManager interface {
DropPrefix(prefix string) error
List(ctx context.Context, prefix string) (keys []string, err error)
Get(ctx context.Context, key string) (value []byte, found bool, err error)
Put(ctx context.Context, key string, value []byte) error
}
PrefixManager is the narrow KV-driver view the reconciler needs (ADR-0072/0073): DropPrefix reclaims a store/table prefix, and List(prefix) enumerates the live keys used to discover orphaned table sub-prefixes on a table-removal; Get and Put copy a store into the quarantine and back (ADR-0288). DropPrefix is a concrete driver method beyond the kvstore.KV port, type-asserted at wiring; declared here so the kv package depends on no driver. A driver without it ⇒ reclamation is a no-op.
type Quarantine ¶ added in v0.30.0
type Quarantine struct {
// contains filtered or unexported fields
}
Quarantine is the KV stores' quarantine.Store and quarantine.Returner: entry <ns>/<store>/<since> holds its state at .quarantine/<ns>/<store>/<since>/state and the store's keys under …/<since>/data/.
func (Quarantine) Expire ¶ added in v0.30.0
func (q Quarantine) Expire(ctx context.Context, cutoff time.Time) ([]quarantine.Entry, error)
Expire drops every entry Expired at cutoff.
func (Quarantine) List ¶ added in v0.30.0
func (q Quarantine) List(ctx context.Context) ([]quarantine.Entry, error)
List returns every entry under .quarantine/, its state read from its state key; one with data and no state reads kept.
func (Quarantine) Move ¶ added in v0.30.0
func (q Quarantine) Move(ctx context.Context, ref quarantine.Ref, now time.Time) (quarantine.Entry, error)
Move copies ref's keys into its moving entry, or a new one dated now, then drops the store's prefix and writes the entry kept (Decision 3): a crash before the drop leaves a moving entry, which the next start resumes.
func (Quarantine) Return ¶ added in v0.30.0
func (q Quarantine) Return(ctx context.Context, ref quarantine.Ref, since time.Time) error
Return copies ref's entry back into the store's prefix, then drops the entry (Decision 6). A kept entry needs an empty store; a returning one resumes.
type Reconciler ¶
type Reconciler struct {
// contains filtered or unexported fields
}
Reconciler is the controller.Reconciler for KindKVStore (ADR-0072/0073): present ⇒ Ready + status.tables/bindings + reclaim any table dropped from spec.tables[]; absent (deleted) ⇒ DropPrefix(<ns>/<name>/).
func NewReconciler ¶
func NewReconciler(d ReconcilerDeps) (*Reconciler, error)
NewReconciler builds the KVStore reconciler. Store is required; KV (the PrefixManager) is optional.
func (*Reconciler) MapFunction ¶ added in v0.2.1
func (r *Reconciler) MapFunction(ctx context.Context, obj v1.Object) []controller.Request
MapFunction is the controller.MapFunc that re-runs the reconcile of every KVStore in a changed Function's namespace: the count is of Function.spec.bindings.kv entries, and an unbind or a delete no longer names the store it referenced.
func (*Reconciler) Orphans ¶ added in v0.10.0
func (r *Reconciler) Orphans(ctx context.Context) ([]string, error)
Orphans lists what the reclaims would drop (ADR-0206 Decision 6): the prefix of each store whose KVStore does not exist, then each table prefix of a KVStore that no longer declares the table.
func (*Reconciler) Quarantine ¶ added in v0.30.0
func (r *Reconciler) Quarantine() Quarantine
Quarantine is the reconciler's quarantine.
func (*Reconciler) ReclaimDeleted ¶ added in v0.6.1
ReclaimDeleted moves into the quarantine the data of every <ns>/<store>/ prefix whose KVStore no longer exists (ADR-0288): a delete committed before a crash or a stop never reaches Reconcile's NotFound (issue #708, ADR-0170 "also across a crash"), and a restore may bring back data its metastore names no object for. Run it before the controller and the control plane start, so no store of the same name is created meanwhile. It then writes kept each moving entry with nothing left to move. A key whose first two segments are not DNS labels belongs to another user of the KV substrate (the eventing watermarks, the quarantine) and is left alone.
func (*Reconciler) Reconcile ¶
func (r *Reconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)
Reconcile converges one KVStore. A present store reports status.tables (declared sub-domains) + status.bindings (Function.spec.bindings.kv entries referencing it) and is Ready while the KV storage probe passes, else Degraded StorageUnreachable (ADR-0215 Decision 7), its status written only when it changed; any table removed from spec.tables[] but still holding data is reclaimed via DropPrefix(<ns>/<store>/<table>/); a deleted store (NotFound) reclaims its whole prefix via DropPrefix(<ns>/<store>/).
type ReconcilerDeps ¶
type ReconcilerDeps struct {
Store store.Store
KV PrefixManager // nil ⇒ delete + table-removal reclamation is a no-op
Logger *slog.Logger
// Health is the storage prober whose KV result sets the Ready condition (ADR-0215 Decision 7); nil ⇒ always Ready.
Health *health.Prober
// Hold is the platform hold (ADR-0206): while held no removed table is reclaimed; nil ⇒ never held.
Hold hold.Gate
// QuarantinePeriod is how long the quarantine keeps a moved store (storage.quarantineRetention, ADR-0288), for
// the until of its log line; 0 ⇒ until is not logged.
QuarantinePeriod time.Duration
}
ReconcilerDeps configures the KindKVStore reconciler (ADR-0072/0073).