Documentation
¶
Overview ¶
Package reconcile computes the 3-way plan (git desired ↔ committed baseline ↔ live ABM) for bidirectional, newest-wins sync. Phase 1 computes + reports the plan only; Phase 2 executes it.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Action ¶
type Action string
Action is the reconcile verb chosen for one config in the plan.
const ( Create Action = "create-abm" // new in git → POST Update Action = "update-abm" // changed in git → PATCH Pull Action = "pull-git" // changed in ABM → write into git PullNew Action = "pull-new-git" // new in ABM (console-created) → write into git DeleteABM Action = "delete-abm" // removed from git → DELETE (prune, gated) DeleteGit Action = "delete-git" // removed from ABM → remove git file Conflict Action = "conflict" // changed in BOTH → newest-wins (resolved at apply) )
Reconcile actions, one per planned change to a config.
type Applier ¶
type Applier interface {
CreateConfiguration(name, xml string, platforms []string) (id, updated string, err error)
UpdateConfiguration(id, name, xml string) (updated string, err error)
DeleteConfiguration(id string) error
AddBlueprintMembers(bpID, rel, memberType string, ids []string) error
RemoveBlueprintMembers(bpID, rel, memberType string, ids []string) error
}
Applier is the subset of the Apple Business write API the executor needs. It is an interface so Apply can be unit-tested with a fake — no production writes.
type Archiver ¶
type Archiver interface {
Archive(name, reason string, xml []byte, meta map[string]string) (path string, err error)
}
Archiver files a pre-overwrite live profile + sidecar (see internal/archive). Injected so Apply stays disk-free and testable; it returns the archive path.
type BlueprintAction ¶
type BlueprintAction string
BlueprintAction is the reconcile verb for a blueprint or one of its config members.
const ( Attach BlueprintAction = "attach-config" // config in git, not in ABM → POST membership Detach BlueprintAction = "detach-config" // config in ABM, not in git → DELETE membership (gated --prune) BlueprintNew BlueprintAction = "blueprint-new" // blueprint in git, not in ABM → can't auto-create (reported) BlueprintGone BlueprintAction = "blueprint-adopt" // blueprint in ABM, not in git → run seed to adopt (reported) )
Blueprint reconcile actions.
type BlueprintItem ¶
type BlueprintItem struct {
Blueprint string `json:"blueprint"`
BPID string `json:"bp_id,omitempty"`
Action BlueprintAction `json:"action"`
Config string `json:"config,omitempty"`
ConfigID string `json:"config_id,omitempty"`
Detail string `json:"detail"`
}
BlueprintItem is one planned blueprint change.
func (BlueprintItem) IsActionable ¶ added in v0.4.3
func (it BlueprintItem) IsActionable() bool
IsActionable reports whether sync can perform this item in the current run. Attach needs a known ABM config id; an empty id means the row is only an blocked until the config is created or adopted into the baseline.
type BlueprintOutcome ¶
type BlueprintOutcome struct {
Blueprint string `json:"blueprint"`
Config string `json:"config,omitempty"`
Action BlueprintAction `json:"action"`
Status string `json:"status"` // "done" | "skipped" | "error"
Detail string `json:"detail"`
}
BlueprintOutcome records what happened to one planned blueprint item.
type BlueprintPlan ¶
type BlueprintPlan struct {
Items []BlueprintItem `json:"items"`
}
BlueprintPlan is the ordered set of planned blueprint changes.
func ComputeBlueprints ¶
func ComputeBlueprints(desired map[string]gitops.BlueprintSpec, live []ab.LiveBlueprint, cfgIDByName map[string]string) *BlueprintPlan
ComputeBlueprints diffs the git blueprint manifests against live ABM blueprints, per config membership. cfgIDByName resolves a config NAME → its ABM id (built from live configs, or from the post-apply baseline so freshly-created configs resolve). A blueprint is matched by name across git and ABM.
func (*BlueprintPlan) HasChanges ¶
func (p *BlueprintPlan) HasChanges() bool
HasChanges reports whether the plan contains any items (actionable or reported).
func (*BlueprintPlan) HasReconcilableChanges ¶
func (p *BlueprintPlan) HasReconcilableChanges() bool
HasReconcilableChanges reports whether the plan has drift that sync can act on. Reported-only rows and attach rows without a config id are excluded, so --exit-on-diff does not loop forever and --apply does not confirm then skip.
func (*BlueprintPlan) ReconcilableCount ¶
func (p *BlueprintPlan) ReconcilableCount() int
ReconcilableCount is the number of items apply can perform (for a confirm prompt).
type BlueprintResult ¶
type BlueprintResult struct {
Outcomes []BlueprintOutcome `json:"outcomes"`
Writes int `json:"writes"`
Errors int `json:"errors"`
Skipped int `json:"skipped"`
}
BlueprintResult summarizes a blueprint apply run.
type Engine ¶
Engine executes a reconcile plan against a live tenant. It archives before every overwrite or delete and keeps the committed baseline exact so the next 3-way diff is correct.
func (*Engine) Apply ¶
func (e *Engine) Apply(p *Plan, desired map[string][]byte, live []ab.LiveConfig, base *state.State, opts Opts) *Result
Apply executes the plan. Every error is captured per-item in the Result (Errors count) rather than aborting the run, so independent configs still converge; the baseline (base) is mutated in place and should be saved by the caller only after Apply returns. Archiving always precedes the write it protects — if the archive fails, the write is skipped so the audit trail is never bypassed.
func (*Engine) ApplyBlueprints ¶
func (e *Engine) ApplyBlueprints(p *BlueprintPlan, opts Opts, priorWrites int) *BlueprintResult
ApplyBlueprints executes the blueprint membership plan: attach (always) and detach (only with --prune) config members via per-member POST/DELETE (the relationship is additive/merges, so this converges). priorWrites is the tenant writes already spent this run (e.g. by config apply) so --limit-writes is a single shared budget. Reported-only items (create/adopt) are surfaced as skips.
type FileStore ¶
type FileStore interface {
WriteConfig(name string, content []byte) error
RemoveConfig(name string) error
}
FileStore is the git-side profile tree (see internal/gitops). Pull writes a file; an ABM-side delete removes one.
type Item ¶
type Item struct {
Name string `json:"name"`
Action Action `json:"action"`
Detail string `json:"detail"`
}
Item is one planned change: the config name, the action, and a human-readable detail.
type Opts ¶
type Opts struct {
Prune bool // enable DeleteABM (off by default — never prune unasked)
LimitWrites int // circuit breaker: max tenant writes per run (0 = unlimited)
Platforms []string // configuredForPlatforms for newly-created configs
Progress func(string)
// GitTime resolves the git-side timestamp of a config (last commit time, else
// file mtime) for newest-wins conflict resolution. ok=false → the timestamp is
// unknown, so the conflict is skipped rather than guessed (never clobber a side
// on missing information).
GitTime func(name string) (t time.Time, ok bool)
}
Opts tunes one apply run.
type Outcome ¶
type Outcome struct {
Name string `json:"name"`
Action Action `json:"action"` // the effective action (a Conflict resolves to Update or Pull)
Status string `json:"status"` // "done" | "skipped" | "error"
Detail string `json:"detail"`
Archive string `json:"archive,omitempty"` // archive path, when one was written
}
Outcome records what happened to one planned item.
type Plan ¶
type Plan struct {
Items []Item `json:"items"`
}
Plan is the ordered set of changes the reconcile produced.
func Compute ¶
Compute diffs desired (git lib/) vs baseline (state) vs live (ABM). Only changed items are returned; unchanged configs are omitted.
func ComputeGitSourceOfTruth ¶ added in v0.4.5
func ComputeGitSourceOfTruth(desired map[string][]byte, live []ab.LiveConfig) *Plan
ComputeGitSourceOfTruth treats git as the complete desired state. Live Apple Business configs are only inspected to decide which POST/PATCH/DELETE writes are needed; live-only configs are not pulled into git.
func (*Plan) HasChanges ¶
HasChanges reports whether the plan contains any changes.
type Result ¶
type Result struct {
Outcomes []Outcome `json:"outcomes"`
Writes int `json:"writes"` // tenant writes performed (POST/PATCH/DELETE)
Errors int `json:"errors"` // items that failed
Skipped int `json:"skipped"` // items intentionally not applied (prune off / limit reached / unresolved)
}
Result summarizes an apply run.