Repository navigation
v1.7.6 — filter nodes by fact
Which nodes are Ubuntu 22.04
That question had no answer anywhere. The node list filtered on certname, environment, status and staleness only, and a classification group gives a count and one exemplar certname — which answers how many, never which ones.
The Nodes page now takes fact rows:
os.name is Ubuntu
os.release.major is 22.04
…and returns the node list itself — sortable, paginated, with the report status and environment already there.
The operator vocabulary is the same one classification rules use — is, is not, matches, is one of, is reported, is not reported — so there is one grammar to learn, and a filter that finds a set of nodes reads like the rule that would classify them. The path picker is fed by the same source as classification, carrying per-path coverage counts, so a fact nothing reports can be seen for what it is before anybody filters on it.
Queried through PuppetDB, not the local projection
ManagedNode holds an allow-listed subset of facts, chosen for rule evaluation (ADR-0004). Filtering there would have answered questions about a fraction of the facts while looking authoritative.
Facts arrive as an inventory subquery on the nodes endpoint rather than by querying inventory directly, because the node list needs nodes fields — report status, the three environment columns — which inventory does not carry. The Nodes page already depended on PuppetDB, so nothing new breaks when it is unavailable.
Two details that matter:
is notrequires the fact to exist first. A bare!=reports a node missing the fact as "not equal to X" — it has no opinion, and conflating those is how a filter quietly loses machines.- The fact path becomes a field name, the one position a typed query builder cannot protect, so its grammar is constrained by schema and a test asserts a hostile string survives as a value and closes nothing.
Fixed: the Matching rules row
The fact path and value collapsed to slivers while the operator took the whole line. Select carries w-full in its base classes — correct in a form column, wrong in a flex row, where width: 100% makes it demand the whole container while flex-basis: 0 siblings get what is left.
Upgrading
No migrations.
Next
Phase 2 — save, name and share a filter (private by default). Phase 3 — CSV export.