Skip to content
Thomas Mangin edited this page Jun 24, 2026 · 14 revisions

Pre-Alpha. This page describes behavior that may change.

The CLI is a network OS shell, not a Unix wrapper. You connect over SSH, you get tab completion driven by the YANG schema, and the workflow is the one operators of JunOS or Cisco IOS already know: edit, diff, commit, rollback. This is the long version of the CLI tour.

The four entry points

ze cli                              # Interactive shell
ze cli -c "peer list"               # One-shot command, exits after
ze show peer upstream detail        # Read-only query, safe in scripts
ze start --cli                      # Start daemon + interactive CLI attached
ze debug show | ze format match reactor  # Offline pipe formatting
ze start --web-only                 # Start daemon with web UI only (no SSH CLI)

ze cli is the interactive path. ze cli -c runs a single command and exits, with a non-zero exit code on error so it composes with shell pipelines. ze show is the read-only subset: it cannot mutate state, which is exactly what you want in a monitoring script. ze start --cli starts the daemon and immediately drops into an interactive CLI session attached to it. ze format brings the YANG pipe operators (json, table, match, count, resolve, origin, first, last) to any command's output offline: pipe through ze format json or ze format match <pattern>. ze start --web-only starts the daemon with the web UI but without the SSH CLI server.

Interactive launcher (no arguments)

Run ze with no arguments in an interactive terminal and it opens a hierarchical, navigable menu of every command instead of printing static help. The launcher groups commands by section, lets you drill into subcommands, and returns the command you select so you can run it.

ze                                  # Interactive command menu (TTY only)
Behaviour Detail
TTY detection The menu opens only when stdin is a terminal. When piped or scripted, ze prints static help and exits with status 1.
Grouping Commands are listed under section headers. The Operations section also folds in YANG-dispatched verbs, sorted alphabetically.
Drill-down Entries with subcommands show a > arrow; selecting one descends a level. A breadcrumb at the top shows where you are.
Type-to-filter Typing narrows the visible entries by name prefix. The filter is shown at the bottom.
Keys Up/Down navigate, Enter selects (or descends), Left/Backspace go back a level, Esc clears the filter then quits.

The launcher renders in an alternate screen and uses the semantic color system below (structure magenta for the ze title and section headers, identity cyan for command names, blue for the breadcrumb, gray for descriptions and hints).

Color system

Every terminal surface (the launcher, help output, autocomplete, the config editor, the BGP dashboard, ping and traceroute monitors, and structured logs) shares one semantic palette. The rule is consistency: the same color always means the same thing, so you read meaning, not decoration. Hierarchy comes from weight (normal, dim, bold), not hue.

There are seven foreground roles, the practical ceiling before colors stop carrying meaning. The palette is dark-terminal-first and uses ANSI 256-color codes (not true-color) for maximum compatibility, including SSH sessions over constrained links. It degrades automatically: 16-color terminals get the base ANSI mapping, monochrome terminals get bold and dim only.

Role Meaning Color Used for
structure "what kind of thing am I looking at?" 205 magenta Headers, section titles, prompt path, mode indicators
identity "what can I type or act on?" 73 cyan Commands, keywords, completion entries
value "what is the system telling me?" 82 green Data values, counts, addresses, ASNs, route counts
caution "something is off, not broken" 214 orange Warnings, flags, non-default or degraded state
danger "something is broken, act now" 196 red Errors, down state, validation failures
muted "background info, skip on fast scan" 241 gray Descriptions, secondary text, timestamps, hints
context "where am I?" 33 blue Navigation breadcrumb, current path, positional info

Two modifiers layer on top of a role rather than acting as roles: bold for emphasis (selected row, active state) and a paired dark background for inline validation and selected-row highlight.

SSH sessions render the same TUI as local sessions. The Wish middleware detects terminal capabilities per connection and the 256-color codes degrade automatically, so no separate palette is needed.

A handful of ze show subcommands run locally without touching the daemon at all (version, bgp decode, bgp encode, env, schema, yang, data (ls, cat, registered), config (dump, diff, history, ls, cat, fmt), interface). The rest go through the SSH server built into the Ze process.

Connecting

The SSH server is part of the daemon. ze init walks you through username, password, host, and port the first time. Defaults are 127.0.0.1:2222 with an auto-generated ED25519 host key. Credentials live in the Ze database (database.zefs) with bcrypt-hashed passwords.

Override the host or port from the environment when you talk to a remote daemon:

export ZE_SSH_HOST=10.0.0.1
export ZE_SSH_PORT=2222
ze cli

Commands

The full list lives in reference/command-reference.md. The most-used groups are these.

Peer commands

peer list
peer * show
peer <selector> teardown <code>
peer <selector> capabilities
peer <selector> pause
peer <selector> resume
set bgp peer <name> with <config>
del bgp peer <name>
bgp summary

The peer selector takes * (all peers), an exact IP, a peer name, an ASN (as65001), an IP exclusion (!<IP>), or a comma-separated list of IPs.

Route and RIB commands

peer <sel> update text <attrs> nlri <family> <op> <prefix>
peer <sel> update hex <hex>
rib routes received [peer] [family]
rib routes sent     [peer] [family]
rib clear-in        [peer] [family]
rib clear-out       [peer] [family]
rib inject  <peer> <family> <prefix> [attrs...]
rib withdraw <peer> <family> <prefix>
rib rpf <family> <source-addr>

rib inject takes a peer label, not a live session, so you can prime the Adj-RIB-In without anyone connected.

Commit windows

The commit workflow lets you batch multiple route operations into one named transaction.

commit start <name>
commit end <name>
commit eor <name>
commit rollback <name>
commit show <name>
commit withdraw <name>
commit list

Config editor verbs

deactivate <path>               # Mark a node inactive (kept in file, skipped at apply)
activate <path>                 # Clear inactive flag
insert <path> before <ref>      # Insert into an ordered list
rename <old> <new>              # Rename a keyed list entry
copy <src> <dst>                # Copy a keyed list entry

deactivate and activate work on both containers and leaf nodes. An inactive node is kept in the config file but skipped at apply time.

Host, diagnostics, RPKI, monitor, daemon

show host [cpu|nic|memory|dmi|thermal|storage|kernel|platform|all]
show health                     # Component health registry
show policy list                # BGP filter types and named instances
show policy chain <peer>        # Effective BGP filter chain for a peer
show policy-routes              # Policy-based routing rules (PBR)
show static                     # Static routes with BFD status
show interface rate             # Per-interface rate tracking
show bmp sessions               # BMP receiver sessions
show bmp peers                  # BMP monitored peers
show bmp collectors             # BMP sender collector status
show bmp rib                    # BMP monitored routes
show rr status                  # Route reflector running state
show rr peers                   # Route reflector peer states
show ipsec tunnels              # IPsec tunnel status
show ipsec sa                   # Active IKE and Child SA details
show pki certificates           # Loaded certificates with expiry
rpki status
rpki cache
rpki roa
rpki aspa                       # ASPA records and validation state
show dns lookup <name>          # DNS resolution
show dns cache list             # Cache entries with TTL
show dns cache stats            # Hit/miss statistics
clear dns cache                 # Flush the DNS cache
show system sockets             # TCP/UDP socket state (replaces ss)
show system kernel-log          # Kernel log (replaces dmesg)
show system goroutines          # Goroutine dump
show system file-descriptors    # FD counts and limits
show system profile cpu         # CPU pprof profile
show system profile heap        # Heap pprof profile
show system memory-map          # Process memory map
show tcp-check <ip> <port>      # TCP connectivity probe
show traceroute <target>        # ICMP path trace
show capture interface <iface>  # Live packet capture (replaces tcpdump)
show crashes                    # Panic crash reports
show debug                      # Live debug module state (YANG-dispatched)
show class-of-service           # CoS profiles and assignments
show bgp irr                    # IRR filter status per ASN
monitor ping <target>           # Continuous ping with live stats
monitor traceroute <target>     # mtr-style continuous traceroute
monitor system netlink all      # Kernel route/link/address changes
monitor interface rate          # Live interface rate tracking
bgp monitor                     # Live event stream (see Monitoring)
bgp monitor peer <addr> event update direction received
daemon shutdown
route-refresh <family>
help
help command                    # Self-documenting command catalog
help command --json             # Machine-readable catalog
command-list
command-help <name>

Pipes

The shell understands a small set of network OS pipe operators. They are not Unix pipes.

Pipe Effect
| json Render the structured response as JSON.
| table Render as a table.
| match <regex> Drop rows that do not match.
| count Just the row count.
| no-more Disable paging on long output.
| log Scrollback output for streaming commands (monitor ping, monitor traceroute).
| first N Keep only the first N items. Server-side early termination when supported by the command.
| last N Keep only the last N items (trailing window).
| origin Annotate IP addresses with ASN names via Team Cymru. Useful with traceroute.
| resolve Annotate IP addresses with reverse DNS hostnames.

| json is the one that matters most for scripting. The output is the same JSON envelope every other Ze surface produces, so you can pipe it through jq and get the same fields you would see from the REST API. Pipes compose: monitor traceroute <target> | log | origin adds one line per round with ASN annotations.

Default output format

The display format pipes (| text, | table, | json, | yaml, | ndjson) override the default for one command. You can change the default itself. The config sets it once for all sessions:

environment {
    cli {
        format {
            default text;        # text (default), table, json, yaml, or ndjson
        }
    }
}

A session override is set cli format <value> in operational mode; set cli format with no argument prints the current format. An explicit display pipe on a command always wins over the configured or session default, so show peer list | json is JSON regardless of the default.

Command-owned filters

Some pipe segments are owned by the command rather than the shell. show bgp rib | received, show bgp rib | advertised, and show bgp rib | peer <selector> are folded into server-side arguments so the daemon does the filtering and streams only the matching rows, instead of the shell filtering a full response after the fact. Display and transform pipes (json, table, resolve, origin, and so on) stay client-side. In interactive mode the whole pipe chain is validated up front against each command's declared filter metadata, so an unsupported or misspelled filter is rejected before the command runs rather than after it has already produced output.

Interactive features

In ze cli, tab completion works on every position: command verbs, peer names, address families, log levels. History is persisted across sessions. Ctrl-C cancels the current command, Ctrl-D exits. The prompt reflects your current edit context (ze[bgp peer upstream]#).

Operational command arguments are YANG-typed. The schema that drives completion also declares the type, range, and pattern of each argument, so the same validation that catches a bad value in the config editor catches a bad value typed at an operational command. A family argument that no peer has negotiated, or a port outside 1-65535, is rejected against the schema before the command is dispatched.

Show convention

Read-only queries follow the show <noun> ... convention with the selector after the noun: show peer detail <selector>, show peer capabilities <selector>, show summary, and show summary <afi>/<safi> for a per-family summary. The family argument on show summary is checked against the families peers have actually negotiated, and an unknown or un-negotiated family rejects with the set of families currently reachable on the running daemon.

Session transcript

Ze can record a local transcript of ze cli and ze config edit sessions, capturing both the commands you type and their output. Transcripts are written to $XDG_DATA_HOME/ze/transcripts/, which is useful for recovering what you did after a disconnect. Writes are best-effort and never block the CLI: if the transcript cannot be written, the session continues normally.

Enable it in config or via the environment:

environment {
    cli {
        transcript enabled;
    }
}

The equivalent environment variable is ze.cli.transcript.

Signals

ze signal is the SSH-based control surface for the daemon process itself, separate from the in-shell commands above.

Command Effect
ze signal reload Reload the on-disk config.
ze signal stop Graceful shutdown without the GR marker.
ze signal restart Graceful restart with the GR marker.
ze signal status Dump daemon status.
ze signal quit Goroutine dump and exit.

The same actions are available as Unix signals: SIGHUP reloads, SIGTERM and SIGINT shut down gracefully, SIGUSR1 triggers a status callback logged at Warn level via the structured logger, SIGQUIT dumps goroutines (mapped to ze signal quit).

See also

Adapted from main/docs/guide/cli.md, main/docs/features/api-commands.md, main/docs/guide/operations.md, main/docs/guide/command-reference.md, and main/docs/architecture/cli/color-system.md.

Home

About

First Steps

Configuration

Operation

Interfaces

Plugins

Plugin Development

Chaos Testing

Blueprints

Development

Reference

Clone this wiki locally