Repository navigation
Show Argo's own per-resource verdicts from argocd-server on Argo CD 3, with or without a token - #1751
Conversation
…r on Argo CD 3 When the Application doesn't carry per-resource health (appTree mode) and argocd-server can be reached — the integration connected, or an install that allows anonymous read — Radar asks the server for Argo's verdicts and shows those instead of its own read: a plain GET first, resource-tree when the GET answers without health. The answer must be about the same Application (UID) and the app must deploy to this cluster. Argo's verdicts are authoritative for the whole app: Radar's topology fill is cleared for kinds Argo has no check for, the issues-engine overlay doesn't run, and the notice doesn't show. Refusals are cached and unconfigured discovery is throttled so a polling page never hammers an install that says no.
…a superseded answer Argo CD 3.0's GET-side health inference keys the tree cache by bare app name, so an Application outside Argo's namespace could be handed a same-named app's verdicts. The plain GET now only establishes identity and mode; in appTree mode the health comes from resource-tree, which every 3.x scopes correctly. The cache write checks the manager generation under the lock so a reset mid-fetch discards the answer instead of caching it under the new connection.
PR Summary by QodoUse argocd-server health verdicts for Argo CD 3 resource trees
AI Description
Diagram
High-Level Assessment
Files changed (15)
|
Code Review by Qodo
1.
|
A tree error is no answer (never the GET's mis-scoped inline health); a healthless tree is an answer and clears every declared node, whatever it carried before; an answer must prove identity (empty UID is rejected); insights prefer the API overlay over a stale inline value; the anonymous read throttle drops on context switch; the fetch generation is taken before the probe can fail; a caller's own cancellation is never cached as a miss; API health strings are normalized to the node vocabulary.
… API overlay drops the CR's stale message
…d argocd-server certificate The reachability probe and the anonymous read send no token, so there is nothing on the wire to protect; skipping TLS verification for them lets the zero-setup path reach the default in-cluster install. Clients that carry the token still honour argoCdInsecureTls, and the certificate hint now appears where the token would first be sent.
|
ⓘ Your Qodo trial ends soon. Ask your workspace admin to set up billing to keep reviews running after the trial. Manage billing |
…wers; the page says when a configured one doesn't A reachable argocd-server that refuses reads is not an integration: the manager now hides a tokenless client from Get() until an anonymous read has succeeded, so Settings never reports Connected on a server that 401s and the capabilities probe stops firing managed-resources calls through it. Once anonymous reads work, the connection is the integration — Settings says "Connected · no token needed" and the diff and revision-metadata gates accept it. With the integration configured and no usable answer, the insights summary carries why (token rejected, requires a token, unreachable, timed out, another install answering, unknown app) and the notice says so with a link to Settings instead of quietly showing Radar's read. A configured server that fails to connect is throttled like unconfigured discovery, so a bad URL costs one probe per retry interval rather than one per page open. The notice's "connect Radar to your Argo CD server" clause is host-injected through the layout's onOpenSettings (standalone opens Settings → Argo CD; embedded hosts get only the Argo-side knob), and the Argo CD Settings section now names per-resource health alongside the diff.
…onfigured connection that didn't answer
…nnecting, Settings says why a connection failed, the notice leads with the failure
Connecting Argo CD in Settings now invalidates the GitOps queries, so the
detail page that sent the user there shows Argo's verdicts when they get
back instead of the notice that sent them. The Argo CD status carries the
last probe failure in plain words ("Radar couldn't connect to Argo CD: the
server couldn't be reached."), so the section the notice links to says
what is wrong rather than nothing. When a configured connection didn't
deliver, the notice leads with that and why, and only then says what the
rows below are meanwhile — the user who set it up doesn't need the Argo
CD 3 history first.
…s when reads work anonymously, and starts at the token when nothing is set up
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ae31263. Configure here.
…d as the connection's failure
The Argo CD section in Settings only reported a connection in two cases: the line that appears right after clicking Connect, and (since #1751) the anonymous-read case. A working token-backed connection showed nothing in the pane itself — only the Overview row said "Connected". Someone opening the section to check on the integration saw a URL field and a token field and had to go back to Overview to learn it was fine. The pane now carries the same check-mark line the anonymous case has, reading "Connected to Argo CD at <address>." whenever the status endpoint reports a live token-backed connection; the anonymous wording is unchanged and the two are exclusive. The transient "Connected — applied, no restart needed" line after a Connect click still takes precedence. Testing: `make tsc`. Copy-only addition on an existing pattern; no visual capture. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Settings UI copy and prop wiring only; no changes to Argo CD integration APIs or credential handling. > > **Overview** > The **Argo CD** settings section now surfaces an in-pane success line when the status API reports a **token-backed** live connection, matching what Overview already showed. > > A new **`connectedAddress`** prop is passed from `useArgoStatus` (when `connected` and not `anonymous`) through `ArgoCDConfigField` into `ArgoCDEditableField`. The existing green check banner (previously only for anonymous read access) also appears for authenticated connections with copy **"Connected to Argo CD at …"**; anonymous wording is unchanged and the two cases stay mutually exclusive. The transient **"Connected — applied, no restart needed"** line after **Connect & save** still wins while local apply state is `connected`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0c9753d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->

Fast-follow to #1743. On Argo CD 3 the Application object no longer carries per-resource health, so Radar showed its own read of each resource, labelled as Radar's. argocd-server still has Argo's verdicts in its own cache. When Radar can reach it — with the integration connected, or with no setup at all on installs that serve reads anonymously — it now shows those instead, and the page looks exactly like it does on Argo CD 2.x: Argo's per-resource health, no notice, no "Found by Radar" markers. When it can't, the page says why and how to get there.
What changes
Argo's verdicts from argocd-server. For an Application in
appTreemode that deploys to this cluster, Radar asks the Argo CD API server for the Application (GET /api/v1/applications/{name}, no refresh) to establish identity and mode, then reads per-resource health from itsresource-tree. The tree is the source rather than the GET's own inlined health because Argo CD 3.0's GET-side inference keys the tree cache by bare app name, which can hand an Application outside Argo's namespace a same-named app's verdicts; the tree is scoped correctly on every 3.x. The answer is accepted only when its UID matches the local Application, so a different Argo install serving a same-named app is ignored.Argo's answer is the whole answer. When it arrives, declared nodes take Argo's health with
healthSource: controllerApi, Radar's topology fill is cleared for kinds Argo has no check for, the issues-engine overlay doesn't run, and the notice doesn't show.resourceHealthFromApion the insights summary andhealthFromApion the tree tell consumers so.With a token, or without one. With the Argo CD integration connected (Settings → Argo CD), the existing client and token are used. With nothing configured, this read path runs the existing argocd-server discovery and asks without credentials. A client that carries no token skips TLS verification, so the probe and the credential-free read reach the default in-cluster argocd-server with its self-signed certificate; every client that sends the token still honours
argoCdInsecureTls, and a certificate the token-bearing client can't verify is reported with that setting named. Radar never sends credentials it wasn't given; refusals are cached per app for 15s, and discovery or a failed connect is throttled to once per retry interval, so a polling detail page never hammers an install that says no.A tokenless connection counts only once it answers. A reachable argocd-server that refuses reads is not an integration: it stays "Not connected" in Settings and never lights the diff. Once an anonymous read has succeeded (
users.anonymous.enabledwith a default role that can read applications), that connection is the integration — Settings shows "Connected · no token needed" with a line explaining when a token or URL still matters, and the Git-rendered diff and revision metadata work over it too.A configured connection that doesn't deliver says so. With the integration set up and no usable answer — token rejected, requires a token, server unreachable, request timed out, a different install answering, unknown app, or anything else — the insights summary carries the reason (
resourceHealthApiError) and the notice leads with it: "Radar couldn't read Argo's per-resource health from your Argo CD server: the server couldn't be reached. Check Argo CD in Settings." The Argo CD status carries the same failure in plain words, so the Settings section the notice links to shows what's wrong.The way out, from the page. When Radar found nothing to mark on a Degraded app, the notice offers connecting Radar to argocd-server first and the
persistknob second. The Settings clause is host-injected through the layout'sonOpenSettings: standalone Radar renders it as a link that opens the Argo CD section (and focuses the token field when nothing is set up); an embedded host without that page gets only the Argo-side knob. Connecting in Settings refreshes the GitOps queries, so the page the user came from shows Argo's verdicts when they get back. The Argo CD Settings section names per-resource health alongside the diff.Docs.
docs/gitops.mddescribes the three health sources and the connection semantics; radar-docs counterpart is skyhook-dev/radar-docs#95, to merge together.Testing
go testin both modules (client; manager: cache, negative cache, throttle for unconfigured and configured failures, anonymous-connection gating, TLS modes, probe-failure reporting; overlay: identity, mode, remote, clearing Radar fill, failure carrying, reason phrasing; status endpoint),make tsc, k8s-ui vitest (3684).users.anonymous.enabled+policy.default: role:readonly→ Argo's verdicts withcontrollerApi(Widget Degraded via its Lua check with Argo's message, Deployment Progressing, Gadget no verdict), no notice, Settings connected + anonymous, diff capability lit.inferResourcesStatusHealth).Notes
Note
Medium Risk
Adds outbound calls to argocd-server on GitOps detail (including unconfigured anonymous discovery) and changes when the integration counts as connected; core auth paths are extended but bounded by caching, UID checks, and existing probe guards.
Overview
On Argo CD 3 (
appTreemode), Radar can now show Argo’s per-resource health from argocd-server instead of defaulting to Radar’s own cluster read. The GitOps detail path callsApplicationHealthCached: GET the Application for UID/mode, thenresource-treewhen health isn’t persisted on the CR (tree is authoritative in appTree; mis-scoped GET inference is not used as fallback). Successful answers overlay the tree withcontrollerApihealth, skip the Radar issues overlay, and hide the “Found by Radar” notice.The Argo CD manager also supports credential-free reads when nothing is configured: discover argocd-server, probe/read without a token (tokenless clients skip TLS verify for self-signed in-cluster certs). A reachable server that 401s is not “connected”; after a successful anonymous read, Settings shows “Connected · no token needed” and diff/revision metadata work like a normal integration. Health fetches are 15s cached (including failures), with throttled retries so 2s polling doesn’t hammer refusals or failed discovery.
When integration is configured but health can’t be fetched, the UI surfaces
resourceHealthApiErrorand a notice with Settings remediation; anonymous/unconfigured failures fall through to Radar’s read quietly. Settings gains probe failure reasons, anonymous status, token focus on connect, and GitOps query invalidation after saving Argo CD config.Reviewed by Cursor Bugbot for commit 94f71ca. Bugbot is set up for automated code reviews on this repo. Configure here.