Subnets served per interface, pools, reservations, options at three levels, leases in SQLite saved before the ACK, ping and decline conflict checks, validated changes with history and undo, users and tokens, an audit log, a Kea importer, a sandboxed systemd unit and Debian packages. Tested with real udhcpc and dhcpcd clients in Docker (scripts/e2e.sh). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.6 KiB
The steward CLI
steward talks to stewardd's REST API. steward help COMMAND describes
each command and its flags.
Connecting
-
On the server, with nothing configured, the CLI uses stewardd's local socket,
/run/steward/steward.sock. Root and thestewarduser are administrators there without a token:sudo steward status. -
From elsewhere, give the server's URL and an API token:
steward config set server https://dhcp.example.com:8067 steward config set token # asks for itThe settings are in
~/.config/steward/config.yaml(on macOS~/Library/Application Support/steward/config.yaml, on Windows%AppData%\steward\config.yaml).
| Flag | Environment | |
|---|---|---|
-s, --server URL |
STEWARD_SERVER |
the server; local for the local socket |
--token TOKEN or @FILE |
STEWARD_TOKEN |
the API token |
--config FILE |
STEWARD_CLI_CONFIG |
the CLI's configuration file |
STEWARD_SOCKET |
the local socket's path | |
--insecure, --ca-cert FILE |
TLS: skip the check, or trust another CA | |
-n, --dry-run |
check and show a change without making it | |
-o, --output FORMAT |
table (default), json, yaml or id |
|
-q, --quiet |
print only errors (and the IDs of new objects) |
Exit codes: 0 ok, 1 error, 3 not authenticated or not allowed, 4 not found, 5 conflict, 6 invalid or refused by validation, 7 server error.
Changes
Every change is checked as a whole first. A refused change says why and gives the problem's code (validation.md). A saved one says its history entry, and any new warnings:
$ steward subnet add 10.0.20.0/24 --interface eth0.20 --name iot --pool 10.0.20.100-10.0.20.200
created subnet iot (10.0.20.0/24)
saved (history 2; undo with 'steward history undo 2')
warning: subnet iot (10.0.20.0/24): this server has no interface eth0.20 (it has eth0, lo); the subnet is served once it appears [interface_unknown]
-n shows what would change without changing it.
Commands
status
steward status: the version, each interface and whether it is served
(and why not), each subnet's pool use, leases by state, DHCP messages
since the start, and problems.
subnet
| Command | |
|---|---|
subnet list |
subnets, with interface, pools, use, reservations, lease time |
subnet show SUBNET |
one subnet; SUBNET is its ID, name or prefix |
subnet add PREFIX --interface IFACE [--name N] [--pool A-B]... [--lease-time 12h] [--option NAME=VALUE]... [--comment C] |
add one |
subnet update SUBNET [--name] [--interface] [--prefix] [--pool]... [--add-pool] [--remove-pool] [--lease-time 1h|default] [--option NAME=VALUE]... [--unset-option NAME]... [--comment] |
change what is given |
subnet enable|disable SUBNET |
answer its clients, or not |
subnet delete SUBNET [-y] |
delete it and its reservations |
--pool replaces the pools; --add-pool and --remove-pool change one.
--option sets an option and keeps the others; --unset-option removes
one. An option Steward doesn't know: --option 224:string=hello.
reservation
| Command | |
|---|---|
reservation list [--subnet SUBNET] |
reservations, and whether each client is online |
reservation show RES |
RES is its ID, address or MAC address |
reservation add IP MAC [--hostname H] [--client-id HEX] [--option NAME=VALUE]... [--comment C] |
- for MAC with --client-id |
reservation update RES [--ip] [--mac] [--client-id] [--hostname] [--option]... [--unset-option]... [--comment] |
|
reservation delete RES |
lease
| Command | |
|---|---|
lease list [--subnet S] [--state STATE] [--interface I] [--search TEXT] [-a] |
active and held-back leases; -a all |
lease show IP |
one lease |
lease reserve IP [--hostname H] |
make the address its client's reservation |
lease delete IP [-y] |
free the address at once |
activity
steward activity [--mac MAC] [--interface I] [--limit N] [-f]: the latest
DHCP messages, received and sent, oldest first. -f keeps watching, which
is useful while a device tries to get an address:
11:02:13.120 eth0 DHCPDISCOVER 3c:22:fb:11:22:33 - adams-macbook
11:02:13.622 eth0 DHCPOFFER 3c:22:fb:11:22:33 10.0.10.150 adams-macbook
11:02:13.630 eth0 DHCPREQUEST 3c:22:fb:11:22:33 10.0.10.150 adams-macbook
11:02:13.631 eth0 DHCPACK 3c:22:fb:11:22:33 10.0.10.150 adams-macbook
NO ADDRESS means the pools on that interface are full, and CONFLICT
an address that answered the ping check. A DHCPNAK says why it was
sent.
settings and options
| Command | |
|---|---|
settings show |
|
settings set [--lease-time 1d] [--ping-check on|off] [--ping-timeout 500ms] [--decline-hold 24h] [--authoritative on|off] [--option NAME=VALUE]... [--unset-option NAME]... |
|
option list |
the options Steward knows (options.md) |
interface list |
the server's interfaces, their addresses and subnets |
history
| Command | |
|---|---|
history list [--limit N] |
changes, newest first |
history show ID |
each object's fields before and after |
history undo ID |
apply the change backwards (refused if something it touched has changed since) |
import
steward import kea CONFIG [--leases FILE]... [--interface PREFIX=IFACE]... [--replace]:
see kea.md.
users, tokens, audit
| Command | |
|---|---|
whoami |
who you are to the server, and what you may do |
user list|add|update|delete |
users (administrators); user add NAME --role operator |
token list [--all], token create NAME [--role R] [--grant G]... [--expires 90d] [--user U] [--save], token revoke ID |
API tokens |
password |
change your password |
audit [--user U] [--action PREFIX] [--search TEXT] |
the audit log |
config show, config set server|token|insecure|ca_cert [VALUE] |
this CLI's settings |
permissions.md explains roles and grants.
stewardd
The daemon's own commands work on the database directly, as root or the
steward user (sudo -u steward stewardd ...):
| Command | |
|---|---|
stewardd serve |
run (the systemd unit does) |
stewardd init [-u NAME] [--token] |
create the database and the first administrator |
stewardd user add NAME [--admin], user password NAME, user token NAME TOKEN-NAME |
when the API can't be used |
stewardd check |
check the configuration against this machine's interfaces |
stewardd backup [FILE], stewardd restore FILE |
operations.md |
stewardd config [--example] |
the settings in use, or a commented example |
stewardd version |
All take -c FILE for another configuration file.