applycheck

package
v0.28.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package applycheck implements the apply-time safety gates: extracting host-resource references from a rendered Talos MachineConfig, evaluating disk selectors against a host snapshot, and diffing two MachineConfig snapshots by (kind, name) identity. The walker is YAML-only; no Talos machinery types leak through its surface, so the package can be exercised from contract tests without standing up a Talos client.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatChange

func FormatChange(c *Change) string

FormatChange returns a one-line, grep-friendly representation of one Change. Used by the preflight hook to write the drift preview to stderr; tests pin the format.

Types

type Change

type Change struct {
	ID     DocID
	Op     ChangeOp
	Fields []FieldChange
}

Change is one entry in the per-doc diff between two MachineConfig snapshots. Fields is non-empty only when Op == OpUpdate.

func Diff

func Diff(current, desired []byte) ([]Change, error)

Diff parses current and desired MachineConfig bytes and returns every per-document difference. Equal documents are included as OpEqual so callers can render an unchanged section if they want; pass FilterChanged to drop them.

The diff is doc-structural, not byte-level: re-serializing either side with different key ordering or whitespace produces the same Diff output. Talos-mutated leaf fields (cert hashes etc.) currently land as OpUpdate entries with FieldChange path pinpointing what differs; an allowlist will be layered on later (see open question in #172).

func FilterChanged

func FilterChanged(changes []Change) []Change

FilterChanged returns the subset of changes whose op is not OpEqual. Useful when the operator only wants to see drift, not pinned doc counts.

type ChangeOp

type ChangeOp int

ChangeOp classifies a per-document diff between two MachineConfig snapshots.

const (
	// OpAdd: doc present in desired, absent in current.
	OpAdd ChangeOp = iota
	// OpRemove: doc present in current, absent in desired (the leftover
	// class — eth1 lingering after migration to eth0).
	OpRemove
	// OpUpdate: doc present on both sides with field-level differences.
	OpUpdate
	// OpEqual: doc present on both sides, structurally identical.
	OpEqual
)

func (ChangeOp) String

func (o ChangeOp) String() string

String renders the op as a single-character glyph for the drift preview output.

type DiskInfo

type DiskInfo struct {
	DevPath    string // /dev/sda
	Model      string
	Serial     string
	WWID       string
	Modalias   string
	UUID       string
	Transport  string // sata / nvme / scsi / mmc / virtio / ...
	BusPath    string
	Size       uint64 // bytes
	Rotational bool
	Readonly   bool
	CDROM      bool
	Symlinks   []string
}

DiskInfo describes one host block device. Fields mirror Talos's block.Disk COSI resource shape verbatim — InstallDiskSelector.type (an enum: ssd/hdd/nvme/sd) is NOT a stored field but a derived predicate over Transport + Rotational, mirrored in matchSelector. CDROM and Readonly devices are excluded by Talos's install-disk resolution; matchSelector mirrors that exclusion.

Symlinks captures the alternate path forms Talos exposes for the same device (/dev/disk/by-id/wwn-…, /dev/disk/by-path/pci-…, /dev/disk/by-diskseq/…); RefKindDiskLiteral validation accepts any of these as equivalent to DevPath, because by-id paths are the recommended stable form for `machine.install.disk` and an operator using them is doing the right thing.

type DiskSelector

type DiskSelector struct {
	Size     string `yaml:"size,omitempty"`
	Name     string `yaml:"name,omitempty"`
	Model    string `yaml:"model,omitempty"`
	Serial   string `yaml:"serial,omitempty"`
	Modalias string `yaml:"modalias,omitempty"`
	UUID     string `yaml:"uuid,omitempty"`
	WWID     string `yaml:"wwid,omitempty"`
	Type     string `yaml:"type,omitempty"`
	BusPath  string `yaml:"busPath,omitempty"`
}

DiskSelector mirrors the Talos v1alpha1 InstallDiskSelector schema (also used by UserVolumeConfig provisioning). Fields are left as raw strings so the walker stays YAML-only; the evaluator interprets each.

func (*DiskSelector) IsZero

func (s *DiskSelector) IsZero() bool

IsZero reports whether the selector has no fields set; the walker uses this to avoid emitting empty selector refs.

type DocID

type DocID struct {
	Kind string
	Name string
}

DocID is the structural identity used to pair up documents across the current/desired snapshots. v1.12 multi-doc keys by (kind, name). v1.11 nested form is collapsed into a synthetic DocID{Kind: "MachineConfig", Name: ""} so the root config doc participates in the diff.

type FieldChange

type FieldChange struct {
	Path   string
	Old    any
	New    any
	HasOld bool
	HasNew bool
}

FieldChange describes a single leaf-level difference between matched documents. Only populated for ChangeOp.OpUpdate. Path is the YAML dotted accessor inside the document.

HasOld / HasNew distinguish "field missing on this side" from "field present with literal nil/null value": a YAML leaf with value `~` (or `null`) is a legitimate value, not a missing field, and the diff has to be able to render it differently.

type Finding

type Finding struct {
	Ref      Ref
	Severity Severity
	Reason   string
	Hint     string
}

Finding is one validation result for one Ref. ValidateRefs returns one Finding per Ref; clean refs produce no findings.

func ValidateRefs

func ValidateRefs(refs []Ref, snapshot HostSnapshot) []Finding

ValidateRefs checks each Ref against the host snapshot:

  • RefKindLink: name must match an entry in snapshot.Links exactly. Mismatch is a blocker.
  • RefKindDiskLiteral: name must equal a DiskInfo.DevPath in snapshot.Disks. Mismatch is a blocker.
  • RefKindDiskSelector: selector must match >= 1 disk. Zero matches is a blocker. Multiple matches is a warning (install picks the first match — operators usually want to narrow the selector).

ValidateRefs collects every finding in a single pass; callers can show them all at once instead of one-at-a-time.

func WalkNetAddrFindings

func WalkNetAddrFindings(rendered []byte) ([]Finding, error)

WalkNetAddrFindings parses the rendered MachineConfig bytes and returns a Finding for every malformed net-addr field in the three kinds registered above. Pure syntactic — no host snapshot required — so the walker runs in Phase 1 alongside (not inside) the Ref-based walker.

Empty input and YAML decode of a nil document are no-ops; an actual YAML parse error is wrapped and returned. Unknown kinds are ignored so future Talos kinds and vendor extensions do not trip the gate.

func (*Finding) IsBlocker

func (f *Finding) IsBlocker() bool

IsBlocker returns true when the finding fails the apply.

type HostSnapshot

type HostSnapshot struct {
	Links []string
	Disks []DiskInfo
}

HostSnapshot captures the host-side resource inventory the validator compares declared refs against. Fields are populated from COSI `links` and `disks` reads at apply time; tests construct fakes directly.

type Ref

type Ref struct {
	Kind     RefKind
	Name     string       // populated for RefKindLink and RefKindDiskLiteral
	Selector DiskSelector // populated for RefKindDiskSelector (zero value otherwise)
	Source   string       // human-readable JSONPath pointing at the offending field
}

Ref is a host-side reference the walker found in the rendered MachineConfig.

func WalkRefs

func WalkRefs(rendered []byte) ([]Ref, error)

WalkRefs parses the rendered MachineConfig bytes and returns every host-resource reference it contains. Both the v1.11 nested machine.network.interfaces[] form and the v1.12 multi-doc form (LinkConfig / BondConfig / VLANConfig / BridgeConfig / Layer2VIPConfig plus UserVolumeConfig.provisioning.diskSelector) are supported. Unknown documents are ignored.

type RefKind

type RefKind int

RefKind classifies a host-resource reference extracted from a rendered MachineConfig.

const (
	// RefKindLink is a host network link by name (eth0, bond0, vlan tag, ...).
	RefKindLink RefKind = iota
	// RefKindDiskLiteral is an install/extra disk identified by a literal
	// device path (machine.install.disk: /dev/sda).
	RefKindDiskLiteral
	// RefKindDiskSelector is an install/user-volume disk identified by a
	// selector (size, model, serial, wwid, modalias, type, busPath).
	RefKindDiskSelector
)

type Severity

type Severity int

Severity classifies a finding's blocker status.

const (
	// SeverityBlocker fails the apply.
	SeverityBlocker Severity = iota
	// SeverityWarning prints the finding but does not block.
	SeverityWarning
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL