Commit 4a70764
committed
Four operator-UX polish changes on the safety surfaces introduced
by #173.
* #191 — Per-node prefix on the maintenance-connection warning.
Multi-node insecure apply used to print identical bare
'talm: drift verification unavailable on maintenance connection'
lines for every node with no per-node correlation. Both the
previewDrift and verifyAppliedState emission sites now wrap
through nodePrefix(nodeID); single-node case (empty nodeID)
keeps the bare line so the common UX is unchanged.
cosiPreflightContext got a fallback path to GlobalArgs.Nodes[0]
when no outgoing-context metadata is attached — the maintenance
flow (openClientPerNodeMaintenance) pins the node in GlobalArgs
but does not attach context metadata, so without the fallback
the per-node prefix collapsed to empty even when --nodes was
set explicitly. Fallback is single-element-only; multi-element
GlobalArgs.Nodes returns empty so a broken caller surfaces as
'no prefix' rather than 'wrong node prefix'.
* #190 — Configurable post-upgrade reconcile window.
The hardcoded 90s wait after talosctl upgrade returns is now
--post-upgrade-reconcile-window. Default
defaultPostUpgradeReconcileWindow = 90 * time.Second preserves
byte-identical back-compat. validatePostUpgradeReconcileWindow
rejects non-positive values at the TOP of wrapUpgradeCommand
RunE — fail-fast BEFORE any talosctl RPC fires, so an
operator's '=0s' typo cannot land a partial upgrade. The
version-mismatch hint copy and error body de-hardcode the '90s'
literal to reference 'the configured reconcile window'
(defaultPostUpgradeReconcileWindow flows through
verifyPostUpgradeVersion).
* #192 — Syntactic net-addr walker for three v1alpha1 multidoc
kinds. Validates fields the actual Talos schema emits:
* StaticHostConfig.name (IP literal; the `name` field on
this kind doubles as the IP — there is no separate
`address` field).
* NetworkRuleConfig.ingress[].subnet and .except (CIDR
shapes; no top-level matchSourceAddress[] field exists
in Talos's schema).
* WireguardConfig.peers[].endpoint (host:port; empty /
absent endpoint is a listener-only peer and NOT a
finding).
Walker runs in parallel with the Ref-based walker via
multidocNetAddrHandlers; dispatch-table disjointness with
multidocHandlers is pinned by a unit test. Integration tests
verify Phase 1 blocks on bad and passes on valid.
* #189 — Drift preview redacts secret-bearing field values by
default. secretFieldPaths allowlist with bracket-normalisation
regex; secret check fires BEFORE bothSlices in
formatFieldChangeLine so slice-shaped allowlist entries
(cluster.acceptedCAs, machine.acceptedCAs, peers) never leak
via formatSliceSetDiff. Length-disclosing redaction sentinel
(***redacted (len=N)***) preserves rotation signal without
leaking the value. Non-string secret values route through
redactValue(fmt.Sprintf("%v", value)) so int / bool rotations
still surface as different-length sentinels. Map iteration
order non-determinism is disclaimed in the godoc (no
map-shaped allowlist entry today).
New flag --show-secrets-in-drift (default off) plumbed through
previewDrift / verifyAppliedState / printDriftPreview /
formatFieldChangeLine. apply.go callers pass
applyCmdFlags.showSecretsInDrift.
absentFieldValue const hoisted so formatFieldValue and
formatSecretFieldValue stay byte-identical on the absent path
— add/remove vs rotate stays distinguishable.
Doc updates:
* README.md bullet #1 (Phase 1) now mentions the net-addr
walker; bullet #2 (Phase 2A) mentions redaction +
--show-secrets-in-drift + the per-node prefix; bullet #4
(Phase 2C) says 'the configured reconcile window' instead
of hardcoding 90s.
* docs/manual-test-plan.md gains sections C5/C6/C7 (redact,
flag opt-out, walker), D3 (per-node prefix), E3 (reconcile
window with help-text + 0s rejection), M6 (false-positive
guard for redaction), M7 (walker boundary cases). Forward-
looking 'do X, expect Y' shape with explicit regression
anchors.
* docs/apply-safety-gates-test-plan.md gets matching rows in
Phase 1 (net-addr walker), Phase 2A (redaction +
per-node prefix), and Phase 2C (reconcile window) tables.
Test coverage:
* Walker: per-kind table tests with the real schema shape,
plus TestWalkNetAddrFindings_RealSchema_StaticHostConfig
and ..._NetworkRuleConfig as schema-anchor regression pins
so a future drift back to non-existent fields fails these
tests rather than passing trivially.
* Reconcile window: validator boundary cases, flag default
one-(default)-clause pin, fail-fast ordering pin via a
sentinel originalRunE, hint-text no-hardcoded-90s pin, a
README-no-hardcoded-90s pin so README and code stay in
sync.
* Per-node prefix: maintenance message on both emission
sites, empty-nodeID bare-line guard, single-vs-multi
GlobalArgs.Nodes fallback pair.
* Redaction: exact-match, Wireguard paths, slice-rotation
no-leak (CA-list and peers shapes), bracket-normalisation,
false-prefix guard, non-secret control, opt-in flag,
non-string redaction with length-signal, absent-side
add-vs-rotate distinction.
Closes #189, closes #190, closes #191, closes #192.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
1 parent 020d209 commit 4a70764
16 files changed
Lines changed: 1981 additions & 37 deletions
File tree
- docs
- pkg
- applycheck
- commands
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
175 | | - | |
| 175 | + | |
176 | 176 | | |
177 | | - | |
| 177 | + | |
178 | 178 | | |
179 | 179 | | |
180 | 180 | | |
181 | | - | |
| 181 | + | |
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
50 | 73 | | |
51 | 74 | | |
52 | 75 | | |
| |||
78 | 101 | | |
79 | 102 | | |
80 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
81 | 107 | | |
82 | 108 | | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
83 | 126 | | |
84 | 127 | | |
85 | 128 | | |
| |||
126 | 169 | | |
127 | 170 | | |
128 | 171 | | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
129 | 175 | | |
130 | 176 | | |
131 | 177 | | |
| |||
0 commit comments