go-anta (Golang ANTA) is a high-performance network testing framework inspired by the Python ANTA project. It provides automated testing capabilities for network devices, particularly Arista EOS devices, with support for concurrent test execution, flexible inventory management, Netbox integration, and comprehensive reporting.
- High Performance: Concurrent test execution across multiple devices with configurable parallelism
- Dynamic Inventory: Native Netbox integration for source-of-truth driven testing
- Flexible Device Targeting: Advanced filtering with hostname, wildcard, range, and index-based selection
- Multiple Output Formats: Table, CSV, JSON, and Markdown reporting
- Smart Caching: Command result caching to reduce device load and improve performance
- Comprehensive Logging: Structured logging with configurable levels for troubleshooting
- Dry Run Mode: Preview operations without making changes
- Secure: TLS support with certificate validation options
- Modular Architecture: Pluggable test system with easy-to-extend design
- Installation
- Quick Start
- Inventory Management
- Device Connectivity
- Running Tests
- Netbox Integration
- Device Filtering
- Test Catalog
- Output Formats
- Logging and Debugging
- Available Tests
- Configuration
- Go 1.21 or later
- Access to Arista EOS devices with eAPI enabled
- Optional: Netbox instance for dynamic inventory
# Clone the repository
git clone https://github.com/fluidstackio/go-anta.git
cd go-anta
# Build the binary
make build
# Verify installation
./bin/go-anta --help- Create an inventory file (
inventory.yaml):
devices:
- name: "leaf1"
host: "192.168.1.10"
username: "admin"
password: "admin123"
tags: ["leaf", "datacenter"]
insecure: true # Skip TLS verification for lab environments- Create a test catalog (
catalog.yaml):
tests:
- name: "VerifyUptime"
module: "system"
inputs:
minimum_uptime: 3600 # 1 hour in seconds- Run the tests:
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml# Set environment variables
export NETBOX_URL=https://netbox.example.com
export NETBOX_TOKEN=$TOKEN
export DEVICE_USERNAME=admin
export DEVICE_PASSWORD=admin123
# Run tests directly from Netbox
./bin/go-anta nrfu \
--netbox-query "site=datacenter1,platform=eos" \
-C catalog.yamlBefore running tests, preview your inventory to ensure the correct devices are targeted:
# Show inventory from file
./bin/go-anta inventory -i inventory.yaml
# Show inventory from Netbox
./bin/go-anta inventory \
--netbox-url https://netbox.example.com \
--netbox-token $TOKEN \
--netbox-query "site=dc1"
# Show inventory with additional metadata
./bin/go-anta inventory -i inventory.yaml --show-tags --show-extra
# Export inventory in different formats
./bin/go-anta inventory -i inventory.yaml -f json
./bin/go-anta inventory -i inventory.yaml -f yaml
./bin/go-anta inventory -i inventory.yaml -f count # Just show device count# Verify Netbox query returns expected devices
./bin/go-anta inventory \
--netbox-url https://netbox.fluidstack.io \
--netbox-token $TOKEN \
--netbox-query "site_id=14&manufacturer_id=35&platform_id=5" \
--show-tags
# Export Netbox devices to static inventory file
./bin/go-anta inventory \
--netbox-url https://netbox.example.com \
--netbox-token $TOKEN \
--netbox-query "site=dc1&status=active" \
-f yaml > netbox-devices.yamlVerify devices are reachable before running tests:
# Check connectivity to devices in inventory
./bin/go-anta check -i inventory.yaml
# Dry-run mode - show inventory without connecting
./bin/go-anta check -i inventory.yaml --no-connect
# Check devices from Netbox
./bin/go-anta check \
--netbox-url https://netbox.example.com \
--netbox-token $TOKEN \
--netbox-query "site=dc1"
# Override credentials
./bin/go-anta check -i inventory.yaml \
--device-username admin \
--device-password newpasswordExample Output:
Checking 3 devices...
Checking leaf1 (192.168.1.10)... âś… Connected (Model: DCS-7050SX-64)
Checking leaf2 (192.168.1.11)... âś… Connected (Model: DCS-7050SX-64)
Checking spine1 (192.168.1.1)... ❌ Failed: connection timeout
Summary: 2 successful, 1 failed
The nrfu command is the primary testing interface:
# Dry-run to see what would be tested
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --dry-run
# Run actual tests
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml
# Run with verbose logging
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -v
# Run with specific concurrency
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -j 20| Option | Short | Description | Example |
|---|---|---|---|
--inventory |
-i |
Inventory file path | -i devices.yaml |
--catalog |
-C |
Test catalog file path (required) | -C tests.yaml |
--netbox-url |
Netbox URL (or use NETBOX_URL env var) | --netbox-url https://netbox.example.com |
|
--netbox-token |
Netbox API token (or use NETBOX_TOKEN env var) | --netbox-token abc123 |
|
--netbox-query |
Netbox query filter | --netbox-query "site=dc1,role=leaf" |
|
--device-username |
Device username override | --device-username admin |
|
--device-password |
Device password override | --device-password secret |
|
--tags |
-t |
Filter devices by tags | -t production,spine |
--devices |
-d |
Filter specific devices | -d leaf1,leaf2 |
--limit |
Advanced device limiting | --limit "leaf*" |
|
--tests |
-T |
Filter specific tests | -T VerifyBGPPeers |
--concurrency |
-j |
Max concurrent connections | -j 20 |
--format |
-f |
Output format | -f json |
--output |
-o |
Output file path | -o results.json |
--hide |
Hide results by status | --hide success,skipped |
|
--dry-run |
Show what would run without executing | --dry-run |
|
--ignore-status |
Always return exit code 0 | --ignore-status |
|
--verbose |
-v |
Enable verbose logging | -v |
--log-level |
Set specific log level | --log-level debug |
go-anta provides native integration with Netbox for dynamic inventory management.
export NETBOX_URL=https://netbox.example.com
export NETBOX_TOKEN=$TOKEN
export NETBOX_INSECURE=true # Skip TLS verification if needed
export DEVICE_USERNAME=admin
export DEVICE_PASSWORD=admin123
export DEVICE_ENABLE_PASSWORD=enable123 # Optionalgo-anta supports two query formats:
Use exact Netbox API parameters with IDs:
# Query by IDs (most precise)
--netbox-query "site_id=14&manufacturer_id=35&platform_id=5"
# Mix IDs and other filters
--netbox-query "site_id=14&platform=eos&status=active"
# Complex queries
--netbox-query "site_id=14&manufacturer_id=35&platform_id=5&role_id=12&status=active"Use slug-based filtering:
# Filter by site and platform
--netbox-query "site=datacenter1,platform=eos"
# Filter by multiple criteria
--netbox-query "site=dc1,role=leaf,manufacturer=arista,status=active"
# Filter by tags
--netbox-query "site=dc1,tag=production"| Field | Slug Format | ID Format | Description |
|---|---|---|---|
| Site | site=slug |
site_id=123 |
Site location |
| Role | role=slug |
role_id=123 |
Device role |
| Device Type | device_type=slug |
device_type_id=123 |
Hardware model |
| Manufacturer | manufacturer=slug |
manufacturer_id=123 |
Device manufacturer |
| Platform | platform=slug |
platform_id=123 |
Network OS platform |
| Status | status=active |
Device status | |
| Tenant | tenant=slug |
tenant_id=123 |
Tenant assignment |
| Region | region=slug |
region_id=123 |
Geographic region |
| Name | name=hostname |
Exact hostname match | |
| Name Contains | name_contains=text |
Hostname substring | |
| Tags | tag=production |
Device tags |
# Test all leaf switches in a specific datacenter
./bin/go-anta nrfu \
--netbox-url https://netbox.fluidstack.io \
--netbox-token $NETBOX_TOKEN \
--netbox-query "site_id=14&role=leaf&status=active" \
-C catalog.yaml
# Test all Arista devices in production
./bin/go-anta nrfu \
--netbox-url https://netbox.fluidstack.io \
--netbox-token $NETBOX_TOKEN \
--netbox-query "manufacturer=arista,tag=production" \
-C catalog.yaml \
--hide success
# Dry-run with device preview
./bin/go-anta nrfu \
--netbox-url https://netbox.fluidstack.io \
--netbox-token $NETBOX_TOKEN \
--netbox-query "site_id=14&manufacturer_id=35&platform_id=5" \
-C catalog.yaml \
--dry-run
# Test specific tenant's devices
./bin/go-anta nrfu \
--netbox-url https://netbox.fluidstack.io \
--netbox-token $NETBOX_TOKEN \
--netbox-query "tenant=customer1,status=active" \
-C catalog.yaml \
--device-username customer1_admin \
--device-password customer1_passgo-anta provides powerful device filtering capabilities to target specific subsets of your inventory.
# Filter by device names
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -d "leaf1,leaf2,spine1"
# Filter by tags
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -t "production,spine"
# Combine multiple filters
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -d "leaf1,leaf2" -t "production"The --limit flag provides sophisticated device selection:
# Target specific device
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "wdl-200-50-r101-eth-leaf-01" \
-C catalog.yaml# Target multiple specific devices
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "leaf01,leaf02,spine01" \
-C catalog.yaml# Target first device (index 0)
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "0" \
-C catalog.yaml
# Target third device (index 2)
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "2" \
-C catalog.yaml# Target first 3 devices (indices 0-2)
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "0-2" \
-C catalog.yaml
# Target devices 5-10
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "4-9" \
-C catalog.yaml# Target all leaf switches
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "leaf*" \
-C catalog.yaml
# Target all devices containing "spine"
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "*spine*" \
-C catalog.yaml
# Target devices with specific pattern
./bin/go-anta nrfu \
--netbox-query "site_id=14" \
--limit "dc1-*-leaf-*" \
-C catalog.yaml# Step 1: Preview inventory
./bin/go-anta inventory \
--netbox-query "site_id=14&manufacturer_id=35" \
--show-tags
# Step 2: Target specific devices for testing
./bin/go-anta nrfu \
--netbox-query "site_id=14&manufacturer_id=35" \
--limit "*leaf*" \
-C catalog.yaml \
--dry-run
# Step 3: Run actual tests
./bin/go-anta nrfu \
--netbox-query "site_id=14&manufacturer_id=35" \
--limit "*leaf*" \
-C catalog.yamlEach test in the catalog follows this structure:
tests:
- name: "TestName" # Must match test implementation
module: "module_name" # Test module (connectivity, hardware, routing, system)
categories: ["category"] # Optional: for grouping and filtering
tags: ["tag"] # Optional: for additional filtering
inputs: # Test-specific parameters
parameter1: value1
parameter2: value2tests:
# System Health Tests
- name: "VerifyUptime"
module: "system"
categories: ["health"]
inputs:
minimum_uptime: 86400 # 24 hours
- name: "VerifyEOSVersion"
module: "system"
categories: ["compliance"]
inputs:
minimum_version: "4.25.0"
- name: "VerifyNTP"
module: "system"
categories: ["time"]
inputs:
servers:
- server: "0.pool.ntp.org"
synchronized: true
# Hardware Tests
- name: "VerifyTemperature"
module: "hardware"
categories: ["environmental"]
inputs:
check_temp_sensors: true
failure_margin: 5
- name: "VerifyTransceivers"
module: "hardware"
categories: ["optics"]
inputs:
check_manufacturer: true
check_temperature: true
# Connectivity Tests
- name: "VerifyReachability"
module: "connectivity"
categories: ["basic"]
inputs:
hosts:
- destination: "8.8.8.8"
vrf: "default"
reachable: true
repeat: 2
- name: "VerifyLLDPNeighbors"
module: "connectivity"
categories: ["topology"]
inputs:
interfaces:
- interface: "Ethernet1"
neighbor_device: "spine1"
neighbor_port: "Ethernet1"
# Routing Tests
- name: "VerifyBGPPeers"
module: "routing"
categories: ["bgp"]
inputs:
peers:
- peer: "10.0.0.1"
state: "Established"
asn: 65001Clean, readable format perfect for console output:
./bin/go-anta nrfu -i inventory.yaml -C catalog.yamlDevice Test Status Message Duration
------------------------------------------------------------------------
leaf1 VerifyUptime âś… SUCCESS - 0.15s
leaf1 VerifyBGPPeers ❌ FAILURE Peer 10.0.0.1 down 0.23s
leaf2 VerifyUptime âś… SUCCESS - 0.12s
------------------------------------------------------------------------
Summary: Total: 3 | Success: 2 | Failure: 1 | Error: 0 | Skipped: 0
Structured data perfect for automation and integration:
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -f json -o results.json{
"results": [
{
"test_name": "VerifyUptime",
"device_name": "leaf1",
"status": 1,
"message": "",
"duration": 150000000,
"timestamp": "2024-01-15T10:30:00Z",
"categories": ["system"]
}
],
"statistics": {
"total": 3,
"success": 2,
"failure": 1,
"error": 0,
"skipped": 0
}
}Great for spreadsheet analysis:
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -f csv -o results.csvPerfect for documentation and reports:
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -f markdown -o report.md# Hide successful tests to focus on issues
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --hide success
# Hide successful and skipped tests
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --hide success,skipped
# Show only failures and errors
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --hide success,skippedBy default, go-anta only shows warnings and errors. Enable more detailed logging as needed:
# Quiet mode (warnings and errors only) - default
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml
# Verbose mode (debug level)
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -v
# Specific log levels
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --log-level info
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --log-level debug
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --log-level error# Enable verbose logging to see connection details
./bin/go-anta check -i inventory.yaml -v
# Test connectivity to specific device
./bin/go-anta check -i inventory.yaml --limit "problematic-device" -v
# Debug with maximum logging
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml --limit "device1" --log-level debugDefault (Warning level):
Summary: 2 successful, 0 failed
Verbose mode:
time="14:51:56" level=info msg="Connecting to device leaf1 (192.168.1.10:443)"
time="14:51:56" level=debug msg="Creating HTTP request for leaf1 to https://192.168.1.10:443/command-api"
time="14:51:56" level=info msg="Successfully connected to leaf1 (Model: DCS-7050SX-64)"
Validates EOS software version meets requirements.
- name: "VerifyEOSVersion"
module: "system"
inputs:
minimum_version: "4.25.0" # Minimum acceptable version
# OR specify exact versions:
versions:
- "4.28.0F"
- "4.27.3F"Ensures system uptime meets minimum requirements.
- name: "VerifyUptime"
module: "system"
inputs:
minimum_uptime: 86400 # Seconds (24 hours)Verifies NTP synchronization status and server configuration.
- name: "VerifyNTP"
module: "system"
inputs:
servers:
- server: "0.pool.ntp.org"
synchronized: true
stratum: 2 # Optional max stratumMonitors system temperature sensors for overheating conditions.
- name: "VerifyTemperature"
module: "hardware"
inputs:
check_temp_sensors: true
failure_margin: 5 # Degrees from overheat thresholdValidates optical transceiver health and specifications.
- name: "VerifyTransceivers"
module: "hardware"
inputs:
check_manufacturer: true
manufacturers:
- "Arista Networks"
- "Finisar"
check_temperature: true
check_voltage: trueVerifies hardware inventory meets minimum specifications.
- name: "VerifyInventory"
module: "hardware"
inputs:
minimum_memory: 8192 # MB
minimum_flash: 4096 # MB
required_modules:
- "DCS-7280SR-48C6"Tests network connectivity to specified destinations.
- name: "VerifyReachability"
module: "connectivity"
inputs:
hosts:
- destination: "8.8.8.8"
vrf: "default" # Optional, defaults to "default"
reachable: true # Expected reachability state
- destination: "192.168.255.1"
vrf: "management"
reachable: true
repeat: 2 # Optional: number of pings
size: 100 # Optional: packet size in bytesValidates LLDP neighbor relationships and topology.
- name: "VerifyLLDPNeighbors"
module: "connectivity"
inputs:
interfaces:
- interface: "Ethernet1"
neighbor_device: "spine1"
neighbor_port: "Ethernet1"
- interface: "Ethernet2"
neighbor_device: "spine2"
neighbor_port: "Ethernet1"Validates BGP peer status and configuration.
- name: "VerifyBGPPeers"
module: "routing"
inputs:
peers:
- peer: "10.0.0.1"
state: "Established"
asn: 65001
vrf: "default" # Optional VRF
- peer: "10.0.0.2"
state: "Established"
asn: 65002Verifies OSPF neighbor adjacencies and states.
- name: "VerifyOSPFNeighbors"
module: "routing"
inputs:
neighbors:
- interface: "Ethernet1"
state: "Full"
router_id: "1.1.1.1" # Optional router ID verification
instance: "1" # Optional OSPF instanceValidates static route configuration and next-hops.
- name: "VerifyStaticRoutes"
module: "routing"
inputs:
routes:
- prefix: "0.0.0.0/0"
next_hop: "192.168.1.1"
vrf: "default"
- prefix: "10.0.0.0/8"
next_hop: "192.168.1.2"
vrf: "default"Create detailed device inventories with flexible credential management:
# inventory.yaml
devices:
- name: "spine1"
host: "10.0.0.1"
port: 443 # Default: 443
username: "admin"
password: "admin123"
enable_password: "enable123" # Optional
tags: ["spine", "production"]
timeout: "30s" # Default: 30s
insecure: false # Default: false
# Network-based discovery
networks:
- network: "192.168.100.0/24"
username: "admin"
password: "admin123"
tags: ["management"]
insecure: true
# Range-based discovery
ranges:
- start: "10.0.1.1"
end: "10.0.1.10"
username: "admin"
password: "admin123"
tags: ["lab"]Create .go-anta.yaml for application-wide settings:
# .go-anta.yaml
log:
level: "info" # debug, info, warn, error
file: "go-anta.log" # Optional log file
format: "text" # text, json
device:
timeout: "30s"
max_connections: 100
retry_attempts: 3
retry_delay: "5s"
test:
max_concurrency: 10
cache_ttl: "60s"
cache_size: 128
reporter:
default_format: "table"
output_file: ""
netbox:
url: "https://netbox.example.com"
token: "your-token-here"
insecure: false
timeout: "30s"go-anta supports extensive environment variable configuration:
# Netbox Configuration
export NETBOX_URL=https://netbox.example.com
export NETBOX_TOKEN=your-api-token
export NETBOX_INSECURE=true
# Device Credentials
export DEVICE_USERNAME=admin
export DEVICE_PASSWORD=admin123
export DEVICE_ENABLE_PASSWORD=enable123
# Application Settings (prefix with go-anta_)
export go-anta_LOG_LEVEL=debug
export go-anta_DEVICE_TIMEOUT=60s
export go-anta_TEST_CONCURRENCY=20-
Connection Timeouts
# Increase timeout ./bin/go-anta check -i inventory.yaml --log-level debug -
TLS Certificate Errors
# In inventory file devices: - name: "device1" host: "192.168.1.10" insecure: true # Skip certificate verification
-
Authentication Failures
# Override credentials ./bin/go-anta check -i inventory.yaml \ --device-username admin \ --device-password newpassword -
Netbox Query Issues
# Test query separately ./bin/go-anta inventory \ --netbox-url $NETBOX_URL \ --netbox-token $NETBOX_TOKEN \ --netbox-query "your-query" \ -f count
Use the included debug tools:
# Build debug tool
go build -o debug cmd/debug/main.go
# Test network connectivity
./debug 192.168.1.10# Increase concurrency for faster execution
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -j 50
# Reduce concurrency for stability
./bin/go-anta nrfu -i inventory.yaml -C catalog.yaml -j 5
# Use caching to improve performance
# (Enabled by default, disable with --no-cache if needed)Contributions are welcome! This project follows standard Go development practices:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
git clone https://github.com/fluidstackio/go-anta.git
cd go-anta
go mod tidy
make test
make buildThis project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by the ANTA project from the Arista community
- Built for the Arista EOS platform and ecosystem
- Special thanks to the network automation community for their contributions and feedback
# Full production spine-leaf validation
./bin/go-anta nrfu \
--netbox-url https://netbox.fluidstack.io \
--netbox-token $PROD_TOKEN \
--netbox-query "site=prod-dc1,status=active" \
-C production-catalog.yaml \
-j 25 \
--format json \
--output prod-validation-$(date +%Y%m%d).json \
--hide success# Quick staging verification
./bin/go-anta nrfu \
--netbox-query "site=staging,tag=ready-for-prod" \
-C staging-catalog.yaml \
--limit "*leaf*" \
-v# Pre-maintenance check
./bin/go-anta check \
--netbox-query "site=dc1,tenant=customer1" \
--device-username maint_user \
--device-password $MAINT_PASSWORD
# Post-maintenance validation
./bin/go-anta nrfu \
--netbox-query "site=dc1,tenant=customer1" \
-C post-maint-catalog.yaml \
--format markdown \
--output maintenance-report.md