Documentation
¶
Overview ¶
Package admission is the control-plane admission framework (ADR-0063): a two-phase pipeline (mutate-all → validate-all) of single-purpose Admissions run on every resource write, after authz and before the store. It generalizes the former inline obj.Validate() admit step (ADR-0018) and opens the cross-resource/Delete extension point (ADR-0064 links consume it).
It is a near-leaf: it imports api/types, internal/auth, api/fault only — it nests under internal/controlplane but must NOT import its parent package (no cycle).
Index ¶
- func Members(ctx context.Context, r StoreReader, ns v1.NamespaceName, ...) ([]v1.Object, error)
- type Admission
- func NewBucketDeletionProtectionAdmission(r StoreReader, p BlobProber) Admission
- func NewBucketQuotaAdmission(r StoreReader, maxPerNamespace int) Admission
- func NewKVStoreDeletionProtectionAdmission(r StoreReader, p KVProber) Admission
- func NewKVStoreQuotaAdmission(r StoreReader, maxPerNamespace int) Admission
- func NewLinkDeletionProtectionAdmission(r StoreReader) Admission
- func NewLinkValidityAdmission(r StoreReader) Admission
- func NewPolicyValidityAdmission() Admission
- func NewResourceGroupDeletionProtectionAdmission(r StoreReader) Admission
- func NewSitePrefixImmutableAdmission() Admission
- func NewValidateAdmission() Admission
- func NewWorkflowRunContractAdmission(r workflowGetter) Admission
- func NewWorkflowRunPayloadAdmission(limit int64) Admission
- func NewWorkflowRunSpecImmutableAdmission() Admission
- type BlobProber
- type KVProber
- type NamespaceReading
- type Operation
- type Phase
- type Pipeline
- type Request
- type StoreReader
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Members ¶ added in v0.4.0
func Members(ctx context.Context, r StoreReader, ns v1.NamespaceName, group v1.ResourceGroupName) ([]v1.Object, error)
Members returns the members of ResourceGroup group in ns (ADR-0170 Decision 7): every object of a namespaced kind other than ResourceGroup, in ns, whose metadata.resourceGroup is group and that no controller owns (a controlled child goes with its owner). Platform-written records (WorkflowRuns, Invocations) count.
Types ¶
type Admission ¶
type Admission interface {
// Name identifies the admission in errors and ordering (stable, kebab-case).
Name() string
// Phase is Mutating or Validating.
Phase() Phase
// Handles reports whether this admission applies to the given GVK + operation.
Handles(gvk v1.GroupVersionKind, op Operation) bool
// Admit reviews req and returns the (possibly-mutated) object, or a fault error denying the write.
Admit(ctx context.Context, req Request) (v1.Object, error)
}
Admission reviews a write before it is persisted. Deterministic and side-effect-free. A Validating admission returns req.Object on allow, or a fault error (Invalid/Forbidden/Conflict/PayloadTooLarge) on deny. A Mutating admission returns the object to carry forward, or a fault error.
func NewBucketDeletionProtectionAdmission ¶
func NewBucketDeletionProtectionAdmission(r StoreReader, p BlobProber) Admission
NewBucketDeletionProtectionAdmission returns the Validating admission that protects Bucket data (ADR-0080). On Delete: Conflict if any Function.spec.blob names the bucket OR any prefix still holds objects. On Update: Conflict if a prefix removed from spec.prefixes[] is still named by some Function.spec.blob OR still holds objects. (Clone of kvstore-deletion-protection, scanning spec.blob.) The prober is optional — a nil prober skips the data-emptiness check (binding-protection still applies).
func NewBucketQuotaAdmission ¶
func NewBucketQuotaAdmission(r StoreReader, maxPerNamespace int) Admission
NewBucketQuotaAdmission returns the Validating admission that rejects creating a Bucket when its namespace already holds maxPerNamespace buckets (ADR-0080 bucket-count quota). maxPerNamespace ≤ 0 disables the quota.
func NewKVStoreDeletionProtectionAdmission ¶
func NewKVStoreDeletionProtectionAdmission(r StoreReader, p KVProber) Admission
NewKVStoreDeletionProtectionAdmission returns the Validating admission that protects KVStore data (ADR-0073). On Delete: Conflict if any Function.spec.kv names the store OR it still holds keys. On Update: Conflict if a table removed from spec.tables[] is still named by some Function.spec.kv, or if an added table still holds the data of its removed namesake (not yet reclaimed by the reconciler, which only diffs the current spec against the live data). (Clone of link-deletion-protection, scanning spec.kv.)
func NewKVStoreQuotaAdmission ¶
func NewKVStoreQuotaAdmission(r StoreReader, maxPerNamespace int) Admission
NewKVStoreQuotaAdmission returns the Validating admission that rejects creating a KVStore when its namespace already holds maxPerNamespace stores (ADR-0072 store-count quota). maxPerNamespace ≤ 0 disables the quota.
func NewLinkDeletionProtectionAdmission ¶
func NewLinkDeletionProtectionAdmission(r StoreReader) Admission
NewLinkDeletionProtectionAdmission returns the Validating admission that rejects deleting a Function that is another Function's link target (ADR-0064). It reads Request.Old.
func NewLinkValidityAdmission ¶
func NewLinkValidityAdmission(r StoreReader) Admission
NewLinkValidityAdmission returns the Validating admission that enforces ADR-0064's cross-resource link rules on Create/Update: every link target exists in the namespace, and the namespace link graph stays acyclic with the applied function (a self-link is a degenerate cycle).
func NewPolicyValidityAdmission ¶
func NewPolicyValidityAdmission() Admission
NewPolicyValidityAdmission returns the Validating admission that enforces ADR-0074's Policy rules on a Policy Create/Update: spec.cedar PARSES as Cedar and references only the curated actions + entity types (kv::read/kv::write; Function/KVStore/KVTable), and its scopes name no entity of another namespace (ADR-0177). An un-parseable, off-schema or foreign-namespace Policy is rejected (fault.Invalid) before it reaches the metastore — so the cedar driver can rely on every stored Policy compiling. (Shape cloned from the link/KV validity admissions.)
func NewResourceGroupDeletionProtectionAdmission ¶ added in v0.4.0
func NewResourceGroupDeletionProtectionAdmission(r StoreReader) Admission
NewResourceGroupDeletionProtectionAdmission returns the Validating admission that refuses deleting a ResourceGroup while it has a member (ADR-0170 Decision 7), naming up to five members and the count.
func NewSitePrefixImmutableAdmission ¶
func NewSitePrefixImmutableAdmission() Admission
NewSitePrefixImmutableAdmission returns the Validating admission that rejects any change to spec.prefix on Update. The reconciler only ever adds prefixes to the Bucket, so a changed prefix would orphan the old one with its objects (ADR-0139 Decision §7). It needs no dependencies — Old and Object are both on the Request — and it never consults Old.Status, which an apply wipes.
func NewValidateAdmission ¶
func NewValidateAdmission() Admission
NewValidateAdmission returns the built-in Validating admission that runs obj.Validate() for every kind on Create and Update.
func NewWorkflowRunContractAdmission ¶
func NewWorkflowRunContractAdmission(r workflowGetter) Admission
NewWorkflowRunContractAdmission returns the Validating admission that checks a WorkflowRun's spec.input against its parent Workflow's CACHED status.contract.input (ADR-0098) — zero registry I/O. A parent that is absent or not-yet-Ready (no cached contract) is allowed: the engine's run-start gate is the backstop, and a dangling spec.workflow is the run reconciler's concern.
func NewWorkflowRunPayloadAdmission ¶
NewWorkflowRunPayloadAdmission returns the Validating admission that rejects a WorkflowRun whose spec.input exceeds the payload cap (ADR-0094: run payloads are size-bounded control-plane metadata; larger data travels by reference on the blob substrate). limit ≤ 0 disables the cap.
func NewWorkflowRunSpecImmutableAdmission ¶ added in v0.2.1
func NewWorkflowRunSpecImmutableAdmission() Admission
NewWorkflowRunSpecImmutableAdmission returns the Validating admission that rejects an Update changing a WorkflowRun's spec.workflow, spec.input or spec.replay. The engine runs a run's spec once, so a second run applied under an existing name is rejected (ADR-0094 duplicate-run-name-rejected) instead of replacing the record of what ran; spec.paused and spec.cancel stay mutable.
type BlobProber ¶
type BlobProber interface {
// HasAny reports whether any object exists under the prefix of the namespace's bucket.
HasAny(ctx context.Context, ns v1.NamespaceName, bucket v1.ObjectName, prefix string) (bool, error)
}
BlobProber probes whether a Bucket prefix holds any objects (ADR-0080): the deletion-protection admission uses it to block deleting a bucket (or removing a prefix) that still holds data. Declared HERE (like KVProber/StoreReader) so the admission package stays a near-leaf; the wiring resolves the Bucket to the substrate view the s3gateway writes, so the key layout has one owner. Optional — a nil prober skips the data-emptiness check (binding-protection still applies).
type KVProber ¶
type KVProber interface {
// HasAny reports whether any key exists under prefix.
HasAny(ctx context.Context, prefix string) (bool, error)
}
KVProber probes whether a KVStore holds any keys (ADR-0072): the deletion-protection admission uses it to block deleting a store that still holds data. Declared HERE (like StoreReader) so the admission package stays a near-leaf; the wiring adapts the kvstore driver's List to it.
type NamespaceReading ¶ added in v0.4.0
type NamespaceReading interface {
ReadsNamespace() bool
}
NamespaceReading marks an admission that needs the namespace's admission lock (ADR-0147): two concurrent writes it admits could store a state no sequential order of them allows. The control plane holds the lock from the Old fetch through the store write.
type Phase ¶
type Phase int
Phase orders an admission: all Mutating run (threading the object), then all Validating.
type Pipeline ¶
type Pipeline struct {
// contains filtered or unexported fields
}
Pipeline runs the registered admissions for a write: all Mutating (threading the object), then all Validating. Construct once at server start with NewPipeline; it is read-only thereafter.
func NewPipeline ¶
NewPipeline registers admissions, partitioning by Phase; registration order within a phase is preserved (it is the deterministic tie-break).
func (*Pipeline) Admit ¶
Admit runs all Mutating admissions (threading req.Object — each may transform it), then all Validating ones (each sees the final object), skipping any whose Handles is false. The first fault error short-circuits. Returns the final (possibly-mutated) object.
func (*Pipeline) Handles ¶
func (p *Pipeline) Handles(gvk v1.GroupVersionKind, op Operation) bool
Handles reports whether any registered admission applies to (gvk, op) — lets a caller skip an Old-object fetch on Delete when nothing admits deletes.
func (*Pipeline) ReadsNamespace ¶ added in v0.4.0
func (p *Pipeline) ReadsNamespace(gvk v1.GroupVersionKind, op Operation) bool
ReadsNamespace reports whether any admission handling (gvk, op) implements NamespaceReading and returns true: the write must hold its namespace's admission lock (ADR-0147).
type Request ¶
type Request struct {
Operation Operation
GVK v1.GroupVersionKind
Object v1.Object
Old v1.Object
Identity auth.Identity
}
Request is one admission review. Object is the incoming desired object (nil on Delete); Old is the stored object (nil on Create; set on Update/Delete). GVK is the route's kind (authoritative, not body-derived). Identity is the authenticated caller (authz already passed).
type StoreReader ¶
type StoreReader interface {
List(ctx context.Context, gvk v1.GroupVersionKind, ns v1.NamespaceName) ([]v1.Object, error)
}
StoreReader is the read-only store view a cross-resource admission needs. It is a subset of store.Store declared here so the admission package stays a near-leaf (the wiring adapts the real store.Store to this interface).