Recipes & tips
Worked examples that combine the pieces from the previous pages, followed by a grab-bag of things worth knowing.
Recipes
Switch between environments safely
Set up a profile per instance once, then pin one for a whole terminal session so you can't fire a command at the wrong place:
1 2 3 4 5 6 7 | |
Build a report from a shell loop
--format tsv is made for while read loops — no jq, no header to skip:
1 2 3 | |
For anything structured, --format json piped to jq — or --jmespath to skip jq
entirely:
1 2 3 | |
Provision a VPC end-to-end
A complete, CLI-only lifecycle for an OpenStack tenant (VPC):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Instances need a few things a VPC doesn't
An instance order references a flavor, an image, and a subnet, which live inside a
tenant. Look the first two up with openstack flavor list / openstack image list (see
below); the CLI can also list/get the tenant's networks, subnets, and security groups, but
it doesn't expose network creation — provision a tenant without the
skip_creation_of_default_* attributes to get a default network + subnet you can point an
instance at.
Pick a flavor and image for an instance
Flavors and images are read-only catalog data scoped to a tenant. The flavor filters accept range comparisons, so "smallest flavor that meets my requirements" is one call — no client-side filtering needed:
1 2 3 4 5 6 7 | |
ram/disk are in MB. Each also takes __lte (and an exact cores=/ram=/disk=), so you
can bracket a range from both ends. Feed the chosen rows' url fields straight into an
instance provision body:
1 2 3 4 | |
SSH into an instance
There's no dedicated ssh command — Waldur doesn't broker a tunnel or manage private keys
(it only stores the public key's name/fingerprint), so there's nothing for a wrapper to add
over the system ssh binary beyond looking up the address. That's one --jmespath away:
1 | |
Swap the username for whatever the instance's image actually uses (ubuntu, centos,
cloud-user, ...) — the API doesn't expose it. If the instance has no floating IP (no public
address, or you're not on the same network as its internal_ips), there's no way in via
SSH at all; waldur-cli openstack instance get <uuid> --web opens its HomePort page, which
may offer a browser-based console instead.
Clean up in bulk from a filtered list
delete and every bodyless action verb read UUIDs from stdin when none are given as
arguments, and list --format ndjson emits one JSON object per line -- so filtering and
acting compose directly, no jq -r .uuid in between:
1 2 3 4 5 6 7 | |
Each UUID is attempted independently -- one failure is reported to stderr and the rest of
the batch still runs, with the command only exiting non-zero afterward if something failed.
Sanity-check first with --dry-run (add it to the second command in the pipeline) or by
piping through --jmespath for a quick count before committing to the real thing.
Feed live inventory to an LLM
Minimise tokens: fetch only the fields that matter, and render as TOON.
1 2 3 | |
Tips & tricks
-
--generate-skeletonis the fastest way to learn a request body. Before writing anycreate/update/provisionJSON, generate the skeleton — it lists every writable field with a typed placeholder, straight from the live schema. -
Filter on the server, shape on the client.
--filtercuts bytes over the wire;--jmespathrestructures what's left. Reach for--filterfirst (it's cheaper), then--jmespathfor the exact shape. -
--fieldsspeeds up big lists. For a resource with large objects,--fields uuid,namecan dramatically cut transfer time — the server sends only what you ask for. -
--format ndjsonfor big lists. It streams -- printing each page as it arrives -- so a largeliststarts producing output immediately instead of going quiet until every page is fetched. Pipes straight intojq -c, a shellwhile readloop, or an agent processing results incrementally. -
--filter query=<text>is full-text search. On resources that support it (customers, projects, users, …), thequeryfilter searches across fields, unlike the exact-match field filters. -
schemaemits an OpenAPI-for-the-CLI. If you're building an LLM agent that driveswaldur-cli, parsing--helptext is fragile.waldur-cli schemaoutputs a complete JSON description of the command surface — paths, parameters, typed filter keys, and request skeletons — that frameworks can directly ingest as a tool specification. Use--compactif you have a tight context budget and only need paths and descriptions. -
apiis the escape hatch for anything not wired up as a typed command yet.waldur-cli api <METHOD> <PATH>calls any endpoint directly, using the same--api-url/--token/--profilecredentials as everything else — same transport (retries,--http-timeout,--debugtracing), no schema validation:
1 2 3 | |
Useful for a Waldur endpoint the CLI hasn't generated a command for yet, or quick
one-off debugging — a malformed --request only fails server-side, the same as curl
would. For anything the CLI does have a typed command for, prefer that instead: it
validates the request locally and gets --fields/--filter/--order/table output for
free.
-
whoamibefore anything destructive. One command confirms which instance and identity your credentials currently resolve to — cheap insurance before adelete/terminate. -
--dry-runbefore a mutation you're unsure of. It validates and prints the exact request (with any defaults filled in) without sending it — see Managing resources. Great for building up acreate/provisionbody iteratively, or confirming a scripteddeletetargets what you think it does. -
--debugshows the actual requests. One line per HTTP call (method, URL, status, timing) on stderr, regardless of--format— invaluable for understanding what a command does or diagnosing a server-side rejection. See Troubleshooting. -
stdout is always clean. Errors and
--debuggo to stderr; stdout only ever carries successful output. So... 2>/dev/nullor... > out.jsonalways gives you exactly the result, and a failed command never pollutes a pipe with half a result. -
Install shell completions. Tab-completion for groups, resources, verbs, and flags makes the three-level command tree far quicker to navigate — see Troubleshooting.
-
Update easily. Run
waldur-cli updateto seamlessly download and install the latest release from GitHub, avoiding manual un-tarring or re-running installer scripts. -
--no-waitfor fire-and-forget provisioning. Submitting many orders?--no-waitreturns each order immediately;marketplace order wait <uuid> --jmespath "state=='done'"(or any resource's ownwait) picks up the polling later, from the same script or a different one entirely -- see Waiting on anything, not just orders.