Documentation
¶
Overview ¶
Package recorder turns live Kubernetes observations — audit webhook posts, admission reviews, and native watch events — into mutationlab.Record values in the store. Each recorder attributes a record to a scenario so the corpus stays isolated even when audit batches arrive late and cross scenario boundaries.
Index ¶
Constants ¶
const RejectLabel = "mutationlab.configbutler.ai/reject"
RejectLabel marks an object the default RejectByLabel policy must record-and-reject; set it to "true". This is how Row 12 deterministically produces "admission saw a write that never persisted" without depending on a second webhook's ordering.
const ScenarioLabel = "mutationlab.configbutler.ai/scenario"
ScenarioLabel is stamped on every lab object so watch/audit/admission records can be attributed to a scenario from the label even for name-less requests.
Variables ¶
This section is empty.
Functions ¶
func RejectByLabel ¶
func RejectByLabel(_ *admissionv1.AdmissionRequest, labels map[string]string) (bool, string)
RejectByLabel rejects a request when its object carries RejectLabel=true.
Types ¶
type Admission ¶
type Admission struct {
// contains filtered or unexported fields
}
Admission is the lab's validating admission recorder. It allows by default but can record-and-reject per its RejectPolicy. The lab includes admission precisely because it is tempting — it sees the user and object before the write — and the corpus's job is to show why that temptation is a trap.
func NewAdmission ¶
func NewAdmission(s *store.Store, policy RejectPolicy) *Admission
NewAdmission returns an Admission recorder using the given reject policy (RejectByLabel is the usual choice; pass nil to always allow).
type Audit ¶
type Audit struct {
// contains filtered or unexported fields
}
Audit records kube-apiserver audit-webhook EventList posts into the store.
type Conversion ¶
type Conversion struct {
// contains filtered or unexported fields
}
Conversion is the lab's CRD conversion webhook recorder. The apiserver calls it to convert the lab's two-version Widget custom resource between v1 and v2 (Row 14). It records each ConversionReview — so the corpus shows the apiserver's conversion contract — and performs the field rename the two schemas differ by (v1 spec.sizeBytes:int <-> v2 spec.size:string), which is what makes the submitted / stored / served shapes genuinely diverge.
func NewConversion ¶
func NewConversion(s *store.Store) *Conversion
NewConversion returns a Conversion recorder backed by the given store.
func (*Conversion) ServeHTTP ¶
func (c *Conversion) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP decodes one ConversionReview, records it, converts each object to the desired version, and returns the converted objects.
type RejectPolicy ¶
type RejectPolicy func(req *admissionv1.AdmissionRequest, labels map[string]string) (reject bool, message string)
RejectPolicy decides whether the admission recorder record-and-rejects a request. It is given the decoded request and the labels of the admitted object.
type Watch ¶
type Watch struct {
// contains filtered or unexported fields
}
Watch records native watch events. It is expected to be the strongest source for "what object state exists or disappeared" — and, per the lab's central hypothesis, to carry the full object precisely where the audit body goes shallow. It is not expected to know the user who caused the change.
type WatchProbe ¶
type WatchProbe struct {
// contains filtered or unexported fields
}
WatchProbe opens short-lived, scenario-scoped watches for transport rows the background recorder cannot reliably attribute or trigger.
func NewWatchProbe ¶
func NewWatchProbe(client dynamic.Interface) *WatchProbe
NewWatchProbe returns a targeted watch transport prober.
func (*WatchProbe) Probe ¶
func (p *WatchProbe) Probe(ctx context.Context, req WatchProbeRequest) ([]mutationlab.Record, error)
Probe captures the requested watch transport event(s). Returned records are tagged with req.Scenario because transport-only watch events, especially BOOKMARK and ERROR, do not carry scenario labels themselves.
type WatchProbeMode ¶
type WatchProbeMode string
WatchProbeMode selects the transport behavior a watch probe should capture.
const ( // WatchProbeBookmark captures the bookmark shape from a streaming list watch. WatchProbeBookmark WatchProbeMode = "bookmark" // WatchProbeExpired captures the Status payload for an expired resourceVersion. WatchProbeExpired WatchProbeMode = "expired" // WatchProbeReplay captures the full SendInitialEvents replay window — every // initial synthetic ADDED plus the terminating initial-events-end BOOKMARK — // using the exact transport internal/watch/target_watch.go opens. It exists to // document the replay watermark: a create-then-modify performed before the // watch opens is delivered as the single collapsed ADDED at the post-modify // resourceVersion, not as a distinct CREATE then MODIFIED, and it lands inside // the replay window (before the bookmark) where the product files it as an // unattributed baseline rather than an attributable per-event commit. WatchProbeReplay WatchProbeMode = "replay" )
type WatchProbeRequest ¶
type WatchProbeRequest struct {
Scenario string
Mode WatchProbeMode
GVR schema.GroupVersionResource
Namespace string
LabelSelector string
}
WatchProbeRequest describes one targeted watch transport capture.