ZTNet CLI is a command-line interface tool designed to manage ZeroTier networks through ZTNet, offering comprehensive control over network operations.
Key Features:
Full REST API coverage for managing networks, members, organizations, stats, and planet files.
Named profiles enable switching between multiple ZTNet instances with ease.
Smart name resolution allows referencing networks and organizations by name instead of IDs.
Flexible output options include table, JSON, YAML, or raw formats, facilitating scripting and integration.
Hosts file export generates /etc/hosts entries from network member data.
Dry-run mode previews HTTP requests without execution, ensuring safe operations.
Automatic retries with exponential backoff handle transient errors and rate limits effectively.
Audience & Benefit:
Ideal for network administrators and DevOps engineers seeking efficient ZeroTier network management. ZTNet CLI enhances productivity by enabling automation of routine tasks, streamlining operations, and maintaining security through features like API token management and dry-run functionality. It can be installed on Windows using winget, simplifying setup.
This tool empowers users to optimize their network administration with precision and efficiency.
README
ztnet-cli
> A fast, ergonomic command-line interface for managing ZeroTier networks through ZTNet.
git clone https://github.com/JKamsker/ztnet-cli.git
cd ztnet-cli
cargo build --release
# Binary: target/release/ztnet (target/release/ztnet.exe on Windows)
Authenticate
# Point to your ZTNet instance (validated automatically)
ztnet config set 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
# Set up profiles for different environments
ztnet --profile prod config set host https://ztnet.prod.example.com
ztnet --profile prod auth set-token PROD_TOKEN
ztnet --profile staging config set 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