Repository navigation
Header chip and GitOps write guard read the manager answer - #2341
Conversation
âĶlse winner Radar names an object's GitOps manager from two kinds of evidence that can disagree: managers' status lists, and the object's own tracking labels and annotations. View.Manager weighs both for an object and, when its own evidence doesn't settle it, for its nearest controller ancestor, and sums them up as shared, disagree, agree, listed, claimed, unknown or none. A disagreement stays one; none means no evidence in what Radar reads, not unmanaged. Claims are parsed in full, every candidate kept, a copied tracking ID marked. The answer reaches the wire as relationships.ownership.manager; existing fields are unchanged.
âĶanager answer A Deployment copies a Helm release's annotations onto its ReplicaSets, so on an object a controller owns that claim is inherited like an instance label: it no longer stops the walk short of a list naming the Deployment. A cluster-scoped object's tracking ID is compared without the namespace Argo CD writes into it. An access check Radar couldn't make keeps an answer from being none. The answer keeps the claims of the objects it walked past and says which controller reference it couldn't follow.
A controller of a kind discovery can't map left the answer's stop without the owner it names. The reference on the object the walk reached names it, as the primary owner's does.
get_resource and diagnose now carry resourceContext.manager: which GitOps managers' status lists name the resource, what its metadata claims and what checking each claim found, the state they sum up to, and the controller ancestor whose evidence answers when the resource's own doesn't. The owner-only ownership answer resource contexts use now also answers the manager: one recorder lookup per object on the controller chain, still no search for children.
Checking a stale claim read every object the claimed manager's list names, just to report that the list omits the claimant; a large Application made that thousands of reads per answer.
âĶwhat none means With via answering, the resource's own claims and those of the objects in between now come through as alsoClaimed, each on its object: inherited metadata that didn't settle the question isn't disproven. get_resource's description says none is not unmanaged and disagree means check both; the catalog budget rises by 50 bytes for it. The docs name the unchecked check and the Helm precedence.
A tracking ID naming argocd/shop and an instance label naming shop made a claimed answer with no lead, as if they named two managers; the one that says its namespace now leads. An Application identity whose name holds an underscore, which Kubernetes names can't, makes no claim.
A controller that is gone, was replaced or is an Event ends the chain: no manager above it was missed, so an object nothing names reads none, not unknown.
Only an owner Radar couldn't read or decide, or a looping or overlong chain, leaves a manager above it unread and warrants the conservative warning; a gone or replaced owner ends the chain with an answer.
A claim its manager's list confirms read as a second line about the same manager; it now joins the list's line. Claims copied from another object, as the tracking annotation a ReplicaSet inherits from its Deployment, add nothing and are left out; a claim that disagrees is said first.
âĶount one Application once A Pod managed through its Deployment now says via Deployment on the chip, not only in the tooltip. An opt-out on the target's own annotations, as Flux's reconcile: disabled, holds for an unconfirmed claim too. A tracking ID and an instance label naming one Application are one candidate, not two.
A ReplicaSet carries its Deployment's Helm release annotations; with a plain Helm Deployment they made each ReplicaSet edit warn as if a GitOps tool might revert it, rather than note that it is generated from the Deployment.
âĶ by list state A Pod whose ReplicaSet's instance label names an Application, under a Deployment with no evidence, answered none: the walk passed the only claim it found. The nearest ancestor claim now answers, as claimed via that ancestor, when the object's own metadata claims nothing. Argo CD's annotation+label tracking cuts the instance label to 63 characters; such a label now names the tracking ID's Application instead of a second one that doesn't exist. Checking a claim against a manager whose list omits the object read and sorted the whole list. ReadSession.Membership reads only the list's state.
âĶto ownership/manager-context
get_resource and diagnose added a warning naming the manager the object's metadata claims beside a manager answer that weighs those claims against the managers' lists; when they disagreed, the two said different things. With a manager answer the metadata warning is left out. Claims of objects the walk passed now reach alsoClaimed without Via too.
âĶownership/manager-chip-guard
âĶt an unconfirmed answer - A list alone (listed) can name an object its manager doesn't sync: a copy carrying another object's tracking ID, or a CRD a HelmRelease skips. It now gives may-revert, and the chip says Listed by. - The write-evidence response says when the server couldn't answer what manages the live object (managerUnavailable); the client owner hint and the cached answer are then not used. A failed evidence request leaves a cached answer that names a manager unconfirmed. - The dialog checks every cached answer against the live object, including none and unknown. - A native Helm release's annotations beside an Argo CD or Kustomization lead mean an adopted install; that manager's exemption no longer waives the release's next upgrade or rollback. - Generated-from-parent notes say what the evidence says of the parent. - A chip with several candidates opens a menu naming each and what names it; a chip without a link is focusable, so its tooltip is reachable by keyboard. The remote reason says Radar can't confirm the destination.
âĶcopied tracking IDs The manager answer covers Argo CD, Flux and Helm metadata, not a controller named only by app.kubernetes.io/managed-by (cert-manager, operators): that warning is now kept beside the answer. A tracking ID copied from another object no longer raises the warning on any path.
âĶownership/manager-chip-guard
âĶto ownership/manager-context
âĶownership/manager-chip-guard
âĶidate - A listed answer's reason no longer carries a will-recreate or will-overwrite promise under a may-revert verdict: it says the list names the object and a sync may apply it. - Generated-from-parent notes for a parent the managers disagree on say which manager its metadata names and which lists it. - The chip's menu names every candidate; one whose label names no namespace is shown without a link.
âĶto ownership/manager-context
âĶownership/manager-chip-guard
âĶto ownership/manager-context
âĶownership/manager-chip-guard
âĶname A copied Argo CD tracking ID was detected first and then dropped, which also hid an independent controller its labels name (cert-manager). The detector now skips the copied ID and keeps looking. AnswerOwner's comment says it answers the manager too.
âĶownership/manager-chip-guard
A claimed answer whose only candidate had no lead (an unfamiliar state from a newer Radar) or was a manager kind this UI doesn't map fell through to no warning. It now asks for an acknowledgement like any unconfirmed claim; a native Helm lead keeps its own rules.
The listed rewrite replaced the whole reason, dropping what the field evidence said (an ignore rule that only affects comparison, a suspended manager) and naming the Application twice. It now says once that Radar can't confirm a sync applies the object, then gives the original reason under 'If one does:'.
The answered path dropped the warning when the detector's first hit was a claim the answer covers, hiding an independent controller label behind it (an own Argo CD tracking ID beside a cert-manager label), and treated Helm named by labels alone as covered though the answer only reads the release annotation. The detector now lists every manager the metadata names, marks the ones the answer weighs, and the answered path warns about the first it doesn't. Resource-context comments say what Build reads and what the compact answer keeps.
âĶownership/manager-chip-guard
- Tracked by says up front that Radar hasn't confirmed the manager the metadata names; claims passed on the way show without via too. - The manager's sync status shows on the chip only for agree, where it is this resource's manager; beside a list alone it read as the resource's own state. - An informational note on a list-only answer says Listed by, as the chip does, not Managed by. - The list-only warning leads with what Radar can't confirm, then the field evidence under 'If it does:'. - A CronJob's Job delete says the CronJob can still create new Jobs.
âĶownership/manager-chip-guard
When the answer came from an ancestor above the CronJob, the note said that ancestor could create new Jobs on its schedule.
ownership.md holds the rules, with the states as a table. The MCP section keeps what an agent needs and links there. The drawer chip bullet says what each state shows, and the write warning's rules become one table of answer by operation instead of two paragraphs.
PR Summary by QodoUse manager answers for the header chip and GitOps write guard
AI Description
Diagram
High-Level Assessment
Files changed (19)
|
Code Review by Qodo
1.
|
âĶr's checks - A positive answer whose lead is a manager kind this UI doesn't map (from a newer Radar) now asks for an acknowledgement, as a claim does. - A delete through a fallback via whose walk couldn't read its chain keeps the warning, unless a controller recreates the object. - When the live answer names a different manager than the cached one, the cached manager's verification and status no longer carry over to the dialog's link.
This is #2325's change, reopened against
main. #2325 merged into its stacked base branch after #2320 had already merged, so none of it reachedmain. Same code as #2325's final head, with currentmainmerged in, plus shorter docs:docs/ownership.mdholds the manager-answer rules (states as a table), thedocs/mcp.mdsection keeps what an agent needs, and thedocs/gitops.mdwrite-warning rules are one table of answer by operation.Problem
The header chip and the GitOps write guard decide "which manager owns this" in the browser:
So the chip and the warning could name a manager whose list doesn't include the object, or miss a second manager whose list does.
Change
Chip. When the server sends
relationships.ownership.manager(#2319), the chip reads it: no browser inheritance, no guess by name. With an older Radar backend the chip behaves exactly as before; Radar Hub runs the newest UI against older Radars.With several candidates (disagree, shared, several claims) the chip opens a menu naming each and what names it (its status, its metadata or both); with one it opens that manager. A chip without a link is focusable, so keyboard users reach its tooltip.
Related Resources' Managed By group is hidden only when the chip says exactly what it would.
Write guard.
POST /api/gitops/write-evidencecomputes the manager answer itself, as the caller, reading the live target's metadata, and returns it asmanager. Its lead decides which manager's policy applies. The client's owner is only a hint when the server has no ownership answer for the kind. When the server computed one and couldn't finish (the object was replaced since the cache saw it, the cache isn't ready),managerUnavailablesays why, and neither the hint nor the cached answer is used: the dialog warns and asks for an acknowledgement.noneandunknown: an object adopted since the cache saw it has a manager the cache doesn't. One request per guarded dialog. A failed request leaves a cached answer that names a manager unconfirmed (acknowledgement); a cachednonestays quiet.agree). A list alone (listed) gives "may revert", saying Radar can't confirm a sync applies the object, then the field evidence under "If one does:";kubectl create job --from) runs once: deleting it doesn't say its controller recreates it;managerin the evidence (older Radar): verdicts as before.Verification
Tests. Classifier tests cover each rule above, including:
Chip tests cover every state's wording, plural names, and the group-hiding rule. Hook tests check the evidence query fires for ambiguous and inherited answers and that the server's answer wins over the client's. Server tests check
managerin the response and that the server's lead overrides a conflicting client owner. A live-overlay test covers live metadata, a replaced UID, a cache switch and restricted access.Checks.
make tscis clean. Frontend: 5,290+ tests across the UI package, 64 hook tests in the app. Go:pkg/...,internal/k8s,internal/server,internal/mcp.Live on a test cluster: