ztnet 0.1.9

ZTNet CLI — manage ZeroTier networks via ZTNet
ztnet-0.1.9 is not a library.

ztnet-cli

A fast, ergonomic command-line interface for managing ZeroTier networks through ZTNet.

$ ztnet network list --json
[
  { "nwid": "abcdef1234567890", "name": "my-network", "private": true }
]

Features

  • Full REST API coverage — networks, members, orgs, stats, planet files
  • Named profiles — switch between multiple ZTNet instances with auth profiles use
  • Host-bound credentials — stored tokens/sessions are only used for their configured host
  • Smart name resolution — reference networks and orgs by name, not just ID
  • Flexible output — table, JSON, YAML, or raw for scripting
  • Hosts file export — generate /etc/hosts entries from network members
  • Raw API escape hatch — call any endpoint with api get /api/v1/...
  • Dry-run mode — preview HTTP requests without sending them
  • Automatic retries — exponential backoff on transient errors and rate limits
  • Shell completions — bash, zsh, fish, PowerShell, elvish

Quickstart

Install

# Clone and build from source
git clone https://github.com/JKamsker/ztnet-cli.git
cd ztnet-cli
cargo build --release

# Binary is at target/release/ztnet (or ztnet.exe on Windows)

Authenticate

# Point to your ZTNet instance (required before storing creds)
ztnet config set profiles.default.host https://ztnet.example.com

# Save your API token (grab it from ZTNet web UI -> Account -> API tokens)
ztnet auth set-token YOUR_API_TOKEN

# Or read from stdin to keep it out of shell history
echo "YOUR_API_TOKEN" | ztnet auth set-token --stdin

# Verify it works
ztnet auth test

Core commands

# List all your networks
ztnet network list

# Create a new network
ztnet network create --name "dev-network"

# List members of a network (by name!)
ztnet member list dev-network

# Authorize a member
ztnet member authorize dev-network abc1234567

# Export hosts file for DNS
ztnet export hosts dev-network --zone ztnet.local

# Get output as JSON for scripting
ztnet network list --json

Command overview

Command Description
auth Manage API tokens, profiles, and test connectivity
config View and edit configuration, set defaults
user Create platform users (admin/bootstrap)
org List and inspect organizations
network Create, list, get, and update networks
member List, authorize, deauthorize, and manage members
stats Fetch admin statistics
planet Download custom planet files
export Generate hosts files, CSV, or JSON from members
api Raw HTTP requests to any endpoint
trpc Call tRPC procedures (experimental)
completion Generate shell completion scripts

Global flags

-H, --host <URL>        ZTNet base URL
-t, --token <TOKEN>     API token
--profile <NAME>        Config profile to use (default: "default")
--org <ORG>             Organization scope (ID or name)
--network <NETWORK>     Default network (ID or name)
-o, --output <FMT>      Output format: table, json, yaml, raw
--json                  Shortcut for --output json
--dry-run               Print the HTTP request without sending it
--timeout <DURATION>    HTTP timeout (default: 30s)
--retries <N>           Retry count for transient errors (default: 3)
-y, --yes               Skip confirmation prompts
-v, --verbose           Increase log verbosity
--no-color              Disable ANSI colors
--quiet                 Suppress interactive output

Configuration

Config lives in a TOML file with named profiles:

Platform Path
Linux ~/.config/ztnet/config.toml
macOS ~/Library/Application Support/ztnet/config.toml
Windows %APPDATA%\ztnet\config.toml
active_profile = "default"

[profiles.default]
host = "https://ztnet.example.com"
token = "your-api-token"
output = "table"

[profiles.staging]
host = "https://staging.ztnet.example.com"
token = "staging-token"

Precedence: CLI flags > environment variables > config file > defaults.

See docs/configuration.md for the full reference.

Documentation

Document Description
Configuration Profiles, environment variables, config file format, precedence rules
Command Reference Every command, subcommand, flag, and option
API Reference Endpoint mapping, authentication, HTTP client behavior, exit codes
Development Building from source, Docker setup, smoke tests, architecture

Shell completions

# Bash
ztnet completion bash > ~/.local/share/bash-completion/completions/ztnet

# Zsh
ztnet completion zsh > ~/.zfunc/_ztnet

# Fish
ztnet completion fish > ~/.config/fish/completions/ztnet.fish

# PowerShell
ztnet completion powershell >> $PROFILE

Examples

Multi-profile workflow

# Set up profiles for different environments
ztnet config set profiles.prod.host https://ztnet.prod.example.com
ztnet --profile prod auth set-token PROD_TOKEN

ztnet config set profiles.staging.host https://ztnet.staging.example.com
ztnet --profile staging auth set-token STAGING_TOKEN

# Optionally set defaults per host (used when you pass --host without --profile)
ztnet auth hosts set-default https://ztnet.prod.example.com prod
ztnet auth hosts set-default https://ztnet.staging.example.com staging

# Switch between them
ztnet auth profiles use prod
ztnet network list

ztnet auth profiles use staging
ztnet network list

Organization-scoped operations

# Set a default org so you don't have to pass --org every time
ztnet config context set --org my-org

# Now all commands use that org
ztnet network list
ztnet network create --name "team-network"
ztnet member list team-network

Scripting with JSON

# Get all network IDs
ztnet network list --ids-only

# Pipe member data into jq
ztnet member list my-network --json | jq '.[].name'

# Authorize all unauthorized members
for id in $(ztnet member list my-net --unauthorized --json | jq -r '.[].id'); do
  ztnet member authorize my-net "$id"
done

Export hosts file

# Generate /etc/hosts entries
ztnet export hosts my-network --zone ztnet.local > /tmp/ztnet-hosts

# Or as JSON for further processing
ztnet export hosts my-network --zone ztnet.local --format json

Dry-run and debugging

# See exactly what HTTP request would be made
ztnet --dry-run network list

# GET http://localhost:3000/api/v1/network
# x-ztnet-auth: sk_1…abcd

License

AGPL-3.0-only (see LICENSE)