Documentation
¶
Overview ¶
Package local is the per-sandbox worker-node local API (ADR-0064): an HTTP-over-UDS surface the runtime shim calls for the synchronous fn-to-fn invoke verb (context.invoke). One listener per sandbox; the caller Ref is fixed at provisioning, so identity is connection-scoped — a request body can never name a different caller. No published SDK — reached only through the built-in shim.
It nests under the blueprint's internal/workernode node-agent component.
Index ¶
- func NewHandler(caller Ref, res Resolver, inv Invoker, authz auth.Authorizer, kv KV, blob Blob, ...) http.Handler
- func Serve(ctx context.Context, path string, h http.Handler) error
- type Blob
- type FunctionStore
- type HandlerHolder
- type Invoker
- type KV
- type Manager
- type Ref
- type Resolver
- type UpstreamError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewHandler ¶
func NewHandler(caller Ref, res Resolver, inv Invoker, authz auth.Authorizer, kv KV, blob Blob, logger *slog.Logger) http.Handler
NewHandler builds the per-sandbox local API handler: POST /invoke/{alias} (ADR-0064/0075) plus, when kv is non-nil, the KV verbs GET/PUT/DELETE /kv/{binding}/{key} + list (ADR-0069). caller is the fixed sandbox identity (connection-scoped) — the handler never reads a caller from the request. authz is the PDP (ADR-0075): after the Resolver maps the alias→target (naming; unknown alias ⇒ Forbidden), the handler asks it `link::invoke` on the target Function — a deny (a forbid Policy revoking a declared link) ⇒ Forbidden, before forwarding. The caller principal is built from the fixed Ref, never the request. Every invoke is logged through logger (the broker is the audit point): an allowed call at Info, a denial / upstream error at Warn. A nil logger defaults to slog.Default().
Types ¶
type Blob ¶
type Blob interface {
Get(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, key string) ([]byte, bool, error)
Put(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, key string, data []byte) error
Delete(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, key string) error
List(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, prefix string) ([]string, error)
SignedURL(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, key string, opts blob.SignOptions) (string, error)
}
Blob is the function-facing blob port the worker-node local API routes to — the services/blob.Facade satisfies it. The caller's namespace + function are supplied by the handler (connection-scoped from the sandbox's fixed Ref), NEVER read from the request: a function can only reach its own namespace's blob, and its binding resolution is keyed by its trustworthy fixed function identity (ADR-0127/0073).
type FunctionStore ¶
type FunctionStore interface {
Get(ctx context.Context, gvk v1.GroupVersionKind, ns v1.NamespaceName, name v1.ObjectName) (v1.Object, error)
}
FunctionStore is the read-only store access the resolver needs (a subset of store.Store).
type HandlerHolder ¶
type HandlerHolder struct {
// contains filtered or unexported fields
}
HandlerHolder is a settable http.Handler indirection. The local API Invoker is built from it BEFORE the data-plane handler exists (the reconciler is constructed before the data plane, since the data plane wraps the reconciler's activator/Endpoints); Set is called once the data plane is built. Until then it answers 503.
func (*HandlerHolder) ServeHTTP ¶
func (hh *HandlerHolder) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP delegates to the installed handler, or 503 until one is set.
func (*HandlerHolder) Set ¶
func (hh *HandlerHolder) Set(h http.Handler)
Set installs the real target handler.
type Invoker ¶
type Invoker interface {
Invoke(ctx context.Context, target Ref, input []byte, timeout time.Duration) ([]byte, error)
}
Invoker performs the synchronous call to target and returns its output bytes. On a target non-2xx (e.g. the shim's 422 input / 500 output contract failures, ADR-0058) it returns an *UpstreamError carrying that exact status+body to propagate verbatim; on a transport/cold-wake-timeout failure it returns a fault error (e.g. fault.Unavailable → 503).
func NewInvoker ¶
NewInvoker returns an Invoker that forwards through the given in-process data-plane handler.
type KV ¶
type KV interface {
Get(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, key string) ([]byte, bool, error)
Put(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, key string, value []byte) error
Delete(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, key string) error
List(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding, prefix string) ([]string, error)
}
KV is the function-facing KV port the worker-node local API routes to — the services/kv.Facade satisfies it. The caller's namespace + function are supplied by the handler (connection-scoped from the sandbox's fixed Ref), NEVER read from the request: a function can only reach its own namespace's KV, and its binding resolution is keyed by its trustworthy fixed function identity (ADR-0073).
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager provisions one per-function worker-node local API listener (ADR-0064), lazily and idempotently: SocketFor(ns, name) ensures a UDS listener for that caller is serving and returns its path — the reconciler sets it as FUNCD_INVOKE_SOCKET so the caller's shim can dial context.invoke. The caller Ref is fixed per listener (connection-scoped identity). Close() stops every listener. This is the same-node (process/containerd) provisioning; the V2 multi-node lattice is a transport swap behind the Invoker.
func NewManager ¶
func NewManager(dir string, store FunctionStore, invoker Invoker, authz auth.Authorizer, kv KV, blob Blob, logger *slog.Logger) *Manager
NewManager builds a Manager serving sockets under dir. invoker is the (possibly late-bound) data-plane forwarder; store backs link resolution; authz (nil-able) is the invoke PDP (ADR-0075) the per-sandbox handler asks link::invoke; kv (nil-able) is the function-facing KV port (ADR-0069) the per-sandbox handler routes /kv/… to; blob (nil-able) is the function-facing blob port (ADR-0127) the handler routes /blob/… to.
func (*Manager) Remove ¶
func (m *Manager) Remove(ns v1.NamespaceName, name v1.ObjectName)
Remove stops + deletes the local API listener for (ns, name), if any — called when the Function is deleted, so the socket lifecycle tracks the resource (controller-driven, not leaked).
func (*Manager) SocketFor ¶
func (m *Manager) SocketFor(ns v1.NamespaceName, name v1.ObjectName) (string, error)
SocketFor ensures the local API for (ns, name) is serving and returns its socket path. Idempotent.
type Ref ¶
type Ref struct {
Namespace v1.NamespaceName
Function v1.ObjectName
}
Ref identifies a function replica's caller identity (namespace + function).
type Resolver ¶
type Resolver interface {
Resolve(ctx context.Context, caller Ref, alias string) (target Ref, timeout time.Duration, err error)
}
Resolver maps (caller, alias) → the link target, applying the link-as-grant rule (default-deny): fault.Forbidden when the caller declares no such link. Same-namespace only (V1.1).
func NewResolver ¶
func NewResolver(s FunctionStore) Resolver
NewResolver returns the store-backed link Resolver.
type UpstreamError ¶
UpstreamError carries a target's non-2xx response so the local API propagates it verbatim — the daemon does NOT re-validate the contract (the target's shim already did, ADR-0064).
func (*UpstreamError) Error ¶
func (e *UpstreamError) Error() string