Files
steward/docs/cli.md
T
abrown38andClaude Opus 5.5 3c0808591f Steward 0.1.0 (in development): a DHCPv4 server with a web UI, API and CLI
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>
2026-10-14 12:14:07 +01:00

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 the steward user 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 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). 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.