fix(client create): don't mint over a live client when the cluster UID read fails (#158)#159
Conversation
…ails (#158) The RFC-0001 §7.2 adopt-backfill ran only inside `if clusterID != ""`, so a kube-system UID read that failed for a reason OTHER than unreachability (RBAC on namespaces, a transient API error) skipped live-client detection entirely and minted a duplicate — orphaning the live install. Worst under --yes. adoptLiveInClusterClient already detects the live client (readInClusterClient) independently of the UID; only the anchor backfill needs it. So run adopt unconditionally and, when clusterID == "" but a live owned client is found, adopt it as-is (no backfill Patch, no anchor-mismatch check) and warn that the idempotency anchor was left unstamped. A genuinely-unreachable cluster fails detection too and still falls through to a non-anchored mint — unchanged. Adds a regression test (UID read fails + live owned client ⇒ pure adopt, no mint, no PATCH) and stubs readInClusterClient in the cancel test that bypasses withClientBackend (adopt now always calls it). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
cc @saadqbal @LukasWodka — post-merge review. The core fix is correct and safe to keep: live-client discovery genuinely doesn't need the UID, the switch-case ordering is right (empty-UID case before backfill/mismatch), the existing guards hold on the new path ( 🟡 Medium: the UID-fail path silently masks the different-cluster mismatch guardWhen the UID is readable and the live client is anchored to a different cluster, the code hard-errors ("anchored to a different cluster … check you're targeting the right cluster", Concretely: a client Deployment restored from backup onto a rebuilt cluster still carries the old cluster's anchor in the backend. The failure mode that causes the UID read to fail (broken RBAC after a cluster rebuild) correlates with exactly that restored-cluster scenario the mismatch guard exists for. Cheap mitigation: in the new case, when ⚪ Low: contradictory user-facing hints in the adopt-without-backfill flowWhen ⚪ Low: test coverage gaps on the newly-reachable pathsThe new test covers the happy path well (no POST, no PATCH, active client adopted). But the gate removal makes two other paths newly reachable with changed behavior, neither pinned by a test:
Also minor: the test captures Nits
What's good
🤖 Generated with Claude Code |
Closes #158. Fixes the High-sev R7 gap Cursor Bugbot flagged on the promote PR (#155,
internal/cli/client.go:267).Problem
The §7.2 adopt-backfill ran only inside
if clusterID != "".readClusterID(kube-system UID) needs a reachable cluster and RBAC on namespaces/kube-system. If it failed for a reason other than unreachability — RBAC forbidden, transient API error — with a tracebloc client already live on the cluster, the whole adopt block was skipped andclient createminted a duplicate, orphaning the live client (worst under--yes).Fix
adoptLiveInClusterClientalready detects the live client viareadInClusterClient, independently of the UID — only the backfill needs it. So:clusterID != ""gate).clusterID == ""but a live owned client is found: adopt it as-is — no backfillPATCH, no anchor-mismatch check — and warn that the idempotency anchor was left unstamped (point --kubeconfig/--context at a cluster where kube-system is readable to stamp it). No mint.listErrfail-closed, cross-account refusal, different-cluster mismatch (only meaningful when the UID is known).Tests
readInClusterClientin the cancel test that bypasseswithClientBackend(adopt now always calls it).go build/vet/test ./...green.Once this lands on develop I'll re-cut the promote (#155) so main gets it and the Bugbot thread there resolves.
Note
Medium Risk
Changes provisioning idempotency when cluster UID is unreadable but a live client exists; wrong adoption could affect the wrong machine credential, though ownership checks and no-mint-over-live invariant remain.
Overview
Fixes #158: when kube-system UID read fails (RBAC, transient errors) but a tracebloc client is already running,
client createno longer skips R7 adopt-backfill and mints a duplicate.runClientCreatealways callsadoptLiveInClusterClient(removed theclusterID != ""gate). Live-client discovery usesreadInClusterClientand does not depend on the anchor; only backfill needs the UID.adoptLiveInClusterClientadds aclusterID == ""branch: if an owned in-cluster client exists, adopt it withoutPatchClientClusterIDor anchor-mismatch checks, and hint that the idempotency anchor was left unstamped. Cross-account refusal and list fail-closed behavior are unchanged.Tests add
TestClientCreate_R7_UIDReadFailsAdoptsLiveand stubreadInClusterClientin the verbose install cancel test so adopt does not hit a real kubeconfig.Reviewed by Cursor Bugbot for commit 97c745a. Bugbot is set up for automated code reviews on this repo. Configure here.