# 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 the `steward` user are administrators there without a token: `sudo steward status`. * **From elsewhere**, give the server's URL and an API token: ```sh steward config set server https://dhcp.example.com:8067 steward config set token # asks for it ``` The 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](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 enable\|disable RES` | use a reservation, or keep it but ignore it | | `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](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](kea.md). ### cert Administrators only ([certificates.md](certificates.md)). | Command | | |---|---| | `cert` | the certificate: name, CA, validity, renewal, the last check | | `cert check` | check that the challenge can be published through Jarl and seen, without the CA (fails with exit code 1 if it can't) | | `cert renew [-w]` | get a new certificate now; `-w` waits and shows the result | ### 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 | | `token rotate ID\|--current [--grace 1h] [--expires 90d\|never] [--save]` | a new secret for a token, the old one working for the grace period | | `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](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 (asks for the name on a terminal) | | `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](operations.md) | | `stewardd config [--example]` | the settings in use, or a commented example | | `stewardd version` | | All take `-c FILE` for another configuration file.