kv

package
v0.9.0 Latest Latest
Warning

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

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

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.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

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.kv (the binding IS the capability) and the target KVStore. fault.Forbidden when the caller has no spec.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) 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)
}

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. 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 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.kv entries, and an unbind or a delete no longer names the store it referenced.

func (*Reconciler) ReclaimDeleted added in v0.6.1

func (r *Reconciler) ReclaimDeleted(ctx context.Context) error

ReclaimDeleted drops the data of every <ns>/<store>/ prefix whose KVStore no longer exists. Reconcile reclaims a store only when it sees the store NotFound, which a delete committed before a crash or a stop never reaches (issue #708, ADR-0170 "also across a crash"). Run it before the controller and the control plane start, so no store of the same name is created meanwhile. A key whose first two segments are not DNS labels belongs to another user of the KV substrate (the eventing watermarks) 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 reaches Ready with status.tables (declared sub-domains) + status.bindings (Function.spec.kv entries referencing it), and 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
}

ReconcilerDeps configures the KindKVStore reconciler (ADR-0072/0073).

Jump to

Keyboard shortcuts

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