Querying resources
Reading data uses two verbs: list (many) and get (one), refined by four flags —
--filter (server-side narrowing), --fields (fewer fields per object), --limit (fewer
objects), and --jmespath (client-side reshaping). They compose freely.
Listing
list always returns the complete result set, not just the first page. There is no
--page/--page-size flag and no partial-results footgun where "list all customers" silently
shows only the first 10.
Under the hood, every list endpoint reports its total via an X-Result-Count response header;
list fetches pages of up to 300 (Waldur's maximum) and keeps going until it has everything,
then merges them into one array before rendering.
1 2 | |
If a page fails partway through a long fetch, the command errors — it never returns a
partial list as if it were complete — and reports how far it got, e.g. fetched 300 of 1200
item(s) before this failed.
Streaming large lists
--format ndjson prints one compact JSON object per line, and for list prints each page as
it arrives instead of fetching the complete result set first. For a large collection, the
first line appears after the first page (up to 300 items) rather than after the whole thing --
lower memory, and a consumer processing output line-by-line (an agent, jq, a shell loop)
can start before the fetch finishes:
1 2 3 4 5 | |
It composes with everything above: --filter/--fields still narrow what's fetched, and
--limit still stops early (mid-page, if needed) without fetching further pages.
The one exception is --jmespath: since a JMESPath expression can reshape or aggregate across
the entire array (sort, slice, count, ...), --format ndjson --jmespath ... falls back to
fetching the complete result first -- same as json/toon -- then prints the (possibly
already-reshaped) result one object per line. Everything still comes out as valid NDJSON; it
just isn't streamed in that combination.
Piping into something that stops reading early (| head) is safe -- the command notices and
stops fetching further pages, rather than continuing to pull data nobody will read.
get/create/update/delete under --format ndjson print their single result object as
one compact line, same shape as json without the pretty-printing.
--filter KEY=VALUE — narrow server-side
--filter (repeatable) filters on the server, so only matching rows come back over the wire.
It replaces having a dedicated flag per field — some resources have 20+ filterable fields —
with one uniform, discoverable flag:
1 2 | |
Each key is validated before any request is made, against the resource's real filter fields and their types (string / bool / int). A typo or a bad value fails locally with the list of valid keys, rather than a wasted round trip — or worse, Waldur silently ignoring an unrecognized filter and returning everything:
1 2 3 4 5 | |
Repeat a key to pass multiple values for a list-valued filter (they're OR'd server-side):
1 | |
Ambient project scope
If you've set a current project, it's
applied automatically as project_uuid to every list that supports it — no --filter
project_uuid= needed. An explicit --filter project_uuid=<other> still overrides it.
Full-text search
Many resources have a query field for full-text search. It's reached through
--filter query=<text> (not a separate flag):
1 | |
--fields — fetch fewer fields
--fields uuid,name tells the server to return only those fields, avoiding the cost of
transferring the complete object when you only need a few keys:
1 | |
table/tsv already do this automatically for their curated columns (they never fetch more
than they display). json/toon fetch the complete object by default; --fields narrows
them, and always overrides the table default when given explicitly.
Like --filter, --fields is validated locally against the field names each resource
accepts (also shown in its --help). This matters because Waldur silently ignores unknown
field names rather than rejecting them — an all-invalid --fields list would quietly fall
back to the complete object — so a typo fails loudly here instead of silently doing the wrong
thing.
--limit N — fetch fewer objects
--limit caps the number of items, for when a resource has far more results than you need:
1 | |
Beyond convenience, --limit bounds two things: how long a huge fetch takes, and the blast
radius if a page fails mid-fetch — a smaller limit means fewer requests, so a failure on a
page you never needed simply never happens.
--jmespath EXPR — reshape client-side
--jmespath runs a JMESPath expression over the already-fetched
result, client-side, before rendering — Amazon CLI's --query by another name. Use it to
project, filter, or restructure output without a separate jq step:
1 2 3 4 5 6 7 8 9 10 11 | |
--filter vs --jmespath: --filter reduces what's fetched (server-side, fewer bytes
over the wire); --jmespath reshapes what's already fetched (client-side, arbitrary
transforms). They're complementary — filter to cut the data down, then JMESPath to shape it:
1 2 3 | |
(Note: --jmespath, not --query — several resources have their own query filter field,
reached via --filter query=..., so the client-side flag is named distinctly to avoid
shadowing it.)
Getting one resource
get fetches a single resource by UUID and prints the complete object:
1 2 | |
--filter, --fields, --limit, and --jmespath are list-only. To pull specific fields
out of a single object, pipe --format json to jq, or (when you know the UUID from a list)
use list with a uuid filter and --jmespath:
1 | |