Documentation
¶
Overview ¶
Package engine contains the reconcile engine: the planner (dependency DAG + waves), the level-triggered reconcile pass, prune, and the work queue.
Index ¶
- Variables
- type Engine
- func (e *Engine) DeleteObject(ctx context.Context, kind, name string) error
- func (e *Engine) DesiredKeys(objs []model.Object) (map[string]bool, error)
- func (e *Engine) Desugar(objs []model.Object) ([]model.Object, error)
- func (e *Engine) PlanPrune(ctx context.Context, desiredKeys map[string]bool, record bool) (PruneReport, error)
- func (e *Engine) PruneNow(ctx context.Context, rep PruneReport) (int, error)
- func (e *Engine) Reconcile(ctx context.Context, desired []model.Object, opts Options) ([]Result, error)
- type Options
- type Plan
- type PruneCandidate
- type PruneMode
- type PruneReport
- type Queue
- type Result
- type State
Constants ¶
This section is empty.
Variables ¶
var DefaultWaves = map[string]int{
"machine": 0,
"swarmnode": 10,
"credential": 20,
"secret": 20,
"config": 25,
"volume": 30,
"network": 40,
"dnszone": 50,
"dnsrecord": 50,
"service": 60,
"app": 60,
"ingress": 70,
"wafruleset": 70,
}
DefaultWaves orders kinds across infrastructure layers when no explicit dependsOn edge applies. Lower waves are reconciled first. Unlisted kinds default to 100.
Functions ¶
This section is empty.
Types ¶
type Engine ¶
type Engine struct {
Reg *provider.Registry
State State
Logger *slog.Logger
// PruneMode controls how far prune goes: off, dry-run (log only) or on.
PruneMode PruneMode
// PruneGrace is how long an object must stay continuously absent from the desired
// set before prune will delete it. It absorbs transient source blips: a candidate
// that reappears has its clock reset. Zero disables the grace period.
PruneGrace time.Duration
// PruneFloor is the maximum fraction of the known inventory that prune may delete
// in a single pass (0..1). A pass that would prune more is refused as a safety guard.
// Zero means "no floor" (prune anything).
PruneFloor float64
// AllowEmptyPrune permits pruning when the desired set is empty (default false).
AllowEmptyPrune bool
}
Engine reconciles a desired set of objects against registered providers.
func (*Engine) DeleteObject ¶
DeleteObject deletes a single object's live resource and removes its persisted status.
func (*Engine) DesiredKeys ¶
DesiredKeys returns the canonical key set for a desired object list, expanding high-level kinds first. Prune correctness depends on this matching exactly what Reconcile computes, so both call it.
func (*Engine) Desugar ¶
Desugar expands high-level objects (whose provider implements Desugarer) into core objects. One level of expansion is performed.
func (*Engine) PlanPrune ¶
func (e *Engine) PlanPrune(ctx context.Context, desiredKeys map[string]bool, record bool) (PruneReport, error)
PlanPrune computes the prune report for a desired key set without mutating the live world. It does record StaleSince on newly-stale objects (the grace clock has to start somewhere) unless record is false.
type Options ¶
type Options struct {
DryRun bool // compute plan only, do not Apply or prune
// Prune runs the prune stage at the engine's configured PruneMode. It is a
// per-pass opt-in: a partial apply (`crane apply -f one.yaml`) must never prune,
// because its desired set is not the whole world.
Prune bool
}
Options controls a reconcile pass.
type PruneCandidate ¶
type PruneCandidate struct {
Ref model.Ref `json:"ref"`
// StaleSince is when the object first went missing from the desired set.
StaleSince time.Time `json:"staleSince,omitempty"`
// StaleFor is StaleSince rendered as a duration for humans/JSON consumers.
StaleFor string `json:"staleFor,omitempty"`
// Eligible reports whether this candidate passes the grace period and the
// ownership check, i.e. whether prune-on would delete it right now.
Eligible bool `json:"eligible"`
// Reason explains the disposition — why it will be deleted, or why not.
Reason string `json:"reason"`
// Exists reports whether the live resource is still there. A candidate that
// no longer exists only needs its state entry dropped.
Exists bool `json:"exists"`
// Owner is the io.craneops.owner label read off the live resource, if any.
Owner string `json:"owner,omitempty"`
}
PruneCandidate is one object in the prune inventory that is no longer desired.
type PruneMode ¶
type PruneMode string
PruneMode controls how far a reconcile pass takes prune. Prune is the only destructive thing the engine does, so it is rolled out in stages rather than toggled: Off computes nothing, DryRun computes and logs the candidate set without touching the live world, and On actually deletes.
const ( // PruneOff disables prune entirely (default). PruneOff PruneMode = "off" // PruneDryRun computes the prune plan, applies every guard, and logs what // *would* be deleted — but deletes nothing. PruneDryRun PruneMode = "dry-run" // PruneOn deletes eligible stale objects. PruneOn PruneMode = "on" )
func ParsePruneMode ¶
ParsePruneMode parses a mode string, accepting the legacy boolean spellings.
func (PruneMode) Destructive ¶
Destructive reports whether the mode actually deletes.
type PruneReport ¶
type PruneReport struct {
Mode PruneMode `json:"mode"`
// Inventory is the number of objects crane knows about (the state store).
Inventory int `json:"inventory"`
// Desired is the number of objects in the source's desired set.
Desired int `json:"desired"`
// Candidates are the inventory entries absent from the desired set.
Candidates []PruneCandidate `json:"candidates,omitempty"`
// Refused, when non-empty, is why a global guard vetoed the whole prune.
Refused string `json:"refused,omitempty"`
// Grace is the configured grace period.
Grace string `json:"grace,omitempty"`
}
PruneReport is the full outcome of planning a prune. It is what `crane prune` and the dry-run log render, and it is computed identically whether prune is off, dry-run or on — so what you preview is exactly what you get.
func (PruneReport) Eligible ¶
func (r PruneReport) Eligible() []PruneCandidate
Eligible returns the candidates prune-on would act on right now.
type Queue ¶
type Queue struct {
// contains filtered or unexported fields
}
Queue is a debounced, deduplicating trigger for reconcile passes. Multiple Notify calls within the debounce window coalesce into a single pass. It is the single funnel through which all sources (git, webhook, local dir, timer, API) request work.
type Result ¶
type Result struct {
Ref model.Ref `json:"ref"`
Phase string `json:"phase"`
Actions []provider.Action `json:"actions,omitempty"`
Drifted bool `json:"drifted"`
Blocked []string `json:"blocked,omitempty"`
Error string `json:"error,omitempty"`
}
Result is the outcome for a single object in a reconcile pass.
type State ¶
type State interface {
Load(kind, name string) (model.Status, error)
Save(kind, name string, st model.Status) error
Delete(kind, name string) error
List() ([]model.Ref, error)
}
State persists per-object Status and doubles as the prune inventory: the set of known status entries is exactly the set of objects CraneOps has applied.