Merge the /facts/<name> and /fact-names routes #18

Merged
benvin merged 7 commits from benvin/merge-fact-routes into main 2026-09-06 22:54:26 +10:00
Member

/facts/<name> and /fact-names fell to the unmerged pass-through, so one backend's answer was served as the whole estate's and Puppetboard's fact pages lost the other backend's nodes and names.

  • Serve /facts/<name> and /facts/<name>/<value> through the /facts merge.
  • Sum an aggregate query on those paths instead of merging it by certname.
  • Serve /fact-names as a deduped, re-sorted, re-paged union of name arrays.
  • Gate provenance on the path, and list the injected name in /fact-names.
  • Synthesise that name's drilldown from one /facts merge every <value> shares.
  • Answer [] with no fan-out for a <value> naming no configured backend.
  • Reject a /fact-names order_by on any field but name.
  • Cache both alongside the merged /facts and /nodes record sets.
`/facts/<name>` and `/fact-names` fell to the unmerged pass-through, so one backend's answer was served as the whole estate's and Puppetboard's fact pages lost the other backend's nodes and names. - Serve `/facts/<name>` and `/facts/<name>/<value>` through the `/facts` merge. - Sum an aggregate query on those paths instead of merging it by certname. - Serve `/fact-names` as a deduped, re-sorted, re-paged union of name arrays. - Gate provenance on the path, and list the injected name in `/fact-names`. - Synthesise that name's drilldown from one `/facts` merge every `<value>` shares. - Answer `[]` with no fan-out for a `<value>` naming no configured backend. - Reject a `/fact-names` `order_by` on any field but `name`. - Cache both alongside the merged `/facts` and `/nodes` record sets.
unkin-agent added 1 commit 2026-09-06 15:18:57 +10:00
Merge the /facts/<name> and /fact-names routes
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
c8efa26383
Both fell to the unmerged pass-through, so one backend's answer was served
as if it were the estate's: Puppetboard's fact drilldown lost the other
backend's nodes and its facts overview lost that backend's fact names.

- Serve /facts/<name> and /facts/<name>/<value> through the /facts merge.
- Serve /fact-names as a deduped, re-sorted, re-paged union of name arrays.
- Gate provenance on the path: only /facts/<source-fact> may be injected.
- Keep the owned fact name out of /fact-names while the feature is on.
- Cache both alongside the merged /facts and /nodes record sets.
- Turn the two recorded e2e gaps into positive assertions.
unkin-agent added 1 commit 2026-09-06 15:50:51 +10:00
Sum aggregates on the /facts/<name> routes
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
cc71902a0d
An aggregate row carries no certname, so the per-certname merge collapsed
every backend's row into one bucket and served a single backend's count as
the estate's — no error, no warning, X-Backends still 2/2.

- Route an aggregate query on /facts/<name>[/<value>] to the summing path.
- List the injected fact's name in /fact-names instead of hiding it.
- Reject an order_by on any field but name, as the backends do.
unkin-agent added 1 commit 2026-09-06 16:10:02 +10:00
Synthesise the /facts/<source-fact> drilldown
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
148be4fe0f
/fact-names advertises the fact, so its drilldown must not be a dead link.

- Serve the source fact's own path from the /facts merge that produces the
  records, so certname set, owner and environment match /facts.
- Filter /facts/<source-fact>/<value> by the owning backend.
- Keep the aggregate, query-gate and disabled paths answering as before.
unkin-agent added 1 commit 2026-09-06 16:19:52 +10:00
Merge main into benvin/merge-fact-routes
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
b6e190f1f2
Main summed /facts aggregates; keep both branches' route tables and
aggregate documentation.
unkin-agent added 1 commit 2026-09-06 16:51:06 +10:00
Stop the source-fact drilldown fanning out per pinned value
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was canceled
abf565b0f6
The <value> path segment is client-supplied and reached a full unfiltered
/facts fan-out, keyed per value, so every distinct value was a fresh
whole-estate query and a fresh cache entry.

- validate <value> against the configured backend names, answering [] with
  no fan-out when it names none
- key the drilldown's fetch on the fact name alone and apply <value> to the
  shared record set, so all values share one entry and one fan-out
- report every configured backend on the no-fan-out empty response, which is
  complete rather than partial
unkin-agent added 1 commit 2026-09-06 16:53:13 +10:00
Assert the drilldown's no-fan-out path marks no partial round
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
e299f64b07
The empty answer for an unknown value never reaches a backend, so it must
leave /healthz reporting a whole estate.

- assert partial_rounds stays 0 after an unknown-value drilldown
unkin-agent added 1 commit 2026-09-06 17:10:39 +10:00
Assert the stale drilldown keeps its owner filter
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
6bf6a8024c
benvin merged commit f0f232664c into main 2026-09-06 22:54:26 +10:00
benvin deleted branch benvin/merge-fact-routes 2026-09-06 22:54:27 +10:00
Sign in to join this conversation.