2026-01-05 15:47:43 -05:00
2026-01-04 13:32:09 -05:00
2026-01-05 15:47:43 -05:00
2026-01-05 15:47:43 -05:00
2026-01-05 15:47:43 -05:00
2026-01-05 15:47:43 -05:00

toughswitch

A Go client library for interacting with Ubiquiti toughswitch devices (specifically tested with ToughSwitch POE Pro (TS-8-PRO)) via their internal REST API.

⚠️ Disclaimer: This library is based on reverse-engineered API calls. It is not an official Ubiquiti product and is subject to change if the device firmware changes.

Features

  • Authentication: Handles login and session token management automatically.
  • Multi-Device Support: Manage multiple devices with a single client instance.
  • Data Retrieval:
    • System Information: Hostname, uptime, firmware version, etc.
    • Interfaces: Status, POE settings, link speed, statistics.
    • VLANs: Configuration and trunk information.
    • Services: SSH, Telnet, Web Server, NTP, SNMP, etc.
    • Statistics: Real-time throughput, errors, and resource usage.
    • Discovery: Neighbor discovery via UBNT protocol.

Installation

go get gitea.libretechconsulting.com/rmcguire/toughswitch-client/pkg/toughswitch

Usage

Basic Example

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"gitea.libretechconsulting.com/rmcguire/toughswitch-client/pkg/toughswitch"
)

func main() {
	ctx := context.Background()

	// Configure your device(s)
	configs := []toughswitch.Config{
		{
			Host:     "192.168.1.1",
			Username: "ubnt",
			Password: "password",
			Insecure: true, // Set to true if using self-signed certs
			Timeout:  10 * time.Second,
		},
	}

	// Initialize the client
	client := toughswitch.MustNew(ctx, configs)

	// Fetch system information
	deviceHost := "192.168.1.1"
	system, err := client.GetSystem(ctx, deviceHost)
	if err != nil {
		log.Fatalf("Failed to get system info: %v", err)
	}

	fmt.Printf("Connected to: %s (Timezone: %s)\n", system.Hostname, system.Timezone)

	// Fetch interfaces
	ifaces, err := client.GetInterfaces(ctx, deviceHost)
	if err != nil {
		log.Fatalf("Failed to get interfaces: %v", err)
	}

	for _, iface := range ifaces {
		fmt.Printf("Interface %s: %s (POE: %s)\n",
			iface.Identification.ID,
			iface.Status.Speed,
			iface.Port.POE,
		)
	}
}

Retrieving Statistics

stats, err := client.GetStatistics(ctx, "192.168.1.1")
if err != nil {
    log.Fatal(err)
}

for _, stat := range stats {
    // Device level stats
    fmt.Printf("CPU Usage: %d%%\n", stat.Device.CPU[0].Usage)

    // Per-interface stats
    for _, iface := range stat.Interfaces {
        fmt.Printf("[%s] Rx: %d bps, Tx: %d bps\n",
            iface.Name,
            iface.Statistics.RxRate,
            iface.Statistics.TxRate,
        )
    }
}

Working with Multiple Devices

The client is designed to handle multiple devices concurrently.

configs := []toughswitch.Config{
    {Host: "192.168.1.1", ...},
    {Host: "192.168.1.2", ...},
}
client := toughswitch.MustNew(ctx, configs)

// Get info for all configured devices in parallel
allSystems, err := client.GetAllSystems(ctx)
if err != nil {
    // Note: This returns partial results if available, check implementation
    log.Printf("Error fetching some systems: %v", err)
}

for host, sys := range allSystems {
    fmt.Printf("[%s] Hostname: %s\n", host, sys.Hostname)
}

Supported Endpoints

Method Description
GetSystem General system configuration and status
GetInterfaces Interface configuration and status
GetVLANs VLAN and Trunk configuration
GetServices State of running services (SSH, NTP, etc.)
GetStatistics Performance metrics
GetNeighbors Discovered UBNT neighbors
GetDevice Hardware and capabilities info

License

MIT

Description
Go client package and types for Ubiquiti devices that lack documented APIs or existing open-source support.
Readme 116 KiB
Languages
Go 100%