cisco-ios-xe-wireless-go

A Go SDK for interacting with Cisco Catalyst 9800 Wireless Network Controller.

GitHub Tag Test and Build Test Coverage Go Report Card
OpenSSF Best Practices License: MIT Published

✨️ Key Features

  • 🔧 Developer Friendly: Transparent YANG model handling with all responses in JSON format
  • 🚀 Quick Integration: Get started in minutes with simple configuration and clear examples
  • 📊 Comprehensive Coverage: Access most status information and metrics available from the WNC
  • 🎯 Type-Safe Operations: Strongly-typed Go structs for all API interactions and responses
  • 📖 Comprehensive Documentation: Detailed API reference, testing guides, and best practices

📡 Supported Environment

Cisco Catalyst 9800 Wireless Network Controller running on:

  • Cisco IOS-XE 17.12.x
  • Cisco IOS-XE 17.18.x (Experimental Support: 802.11be, Cisco Spaces, URWB, WAT features)

📦 Installation

go get github.com/umatare5/cisco-ios-xe-wireless-go

🚀 Quick Start

You have to enable RESTCONF and HTTPS on the C9800 before using this SDK. Please see:

1. Generate a Basic Auth token

Encode your controller credentials as Base64.

# username:password → Base64
echo -n "admin:your-password" | base64
# Output: YWRtaW46eW91ci1wYXNzd29yZA==

2. Create a sample application

Use your controller host and token to fetch AP operational data.

package main

import (
    "context"
    "fmt"
    "os"
    "time"

    wnc "github.com/umatare5/cisco-ios-xe-wireless-go"
)

func main() {
    // Load environment variables
    controller := os.Getenv("WNC_CONTROLLER")
    token := os.Getenv("WNC_ACCESS_TOKEN")

    // Create client
    client, err := wnc.NewClient(controller, token,
        wnc.WithTimeout(30*time.Second),
        wnc.WithInsecureSkipVerify(true), // remove for production
    )
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to create client: %v\n", err)
        os.Exit(1)
    }

    // Create simple context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
    defer cancel()

    // Request AP operational data
    apData, err := client.AP().GetOperational(ctx)
    if err != nil {
        fmt.Fprintf(os.Stderr, "AP oper request failed: %v\n", err)
        os.Exit(1)
    }

    // Print AP operational data
    fmt.Printf("Successfully connected! Found %d APs\n",
        len(apData.CiscoIOSXEWirelessAccessPointOperAccessPointOperData.CAPWAPData))
}

Caution

The wnc.WithInsecureSkipVerify(true) option disables TLS certificate verification. This should only be used in development environments or when connecting to controllers with self-signed certificates. Never use this option in production environments as it compromises security.

3. Run the application with environment variables

# Set environment variables
export WNC_CONTROLLER="wnc1.example.internal"
export WNC_ACCESS_TOKEN="YWRtaW46eW91ci1wYXNzd29yZA=="

# Run the application
go run main.go

# result: Successfully connected! Found 2 APs

🌐 API Reference

This SDK provides a client to interact with the Cisco Catalyst 9800 Wireless Network Controller's RESTCONF.

Client Initialization

To create a new client, use the wnc.NewClient function with the controller address and access token.

Parameter Type Description
controller string The hostname or IP address of the WNC.
accessToken string The Base64-encoded Basic Auth token.
options... ...Option Optional client configuration options.

Client Options

There are several options to customize the client behavior.

Option Type Default Description
WithTimeout(d) time.Duration 60s Sets HTTP request timeout.
WithInsecureSkipVerify(b) bool false Skips TLS verify.
WithLogger(l) *slog.Logger slog.Default() Sets structured logger.
WithUserAgent(ua) string wnc-go-client/1.0 Custom User-Agent.

Supported Services

Please refer to the Go Reference for the complete reference.

Go Reference

The following table summarizes the supported service APIs and their capabilities.

Legend:

  • ✅️ Supported
  • 🟩 Partial Supported
  • 🟨 Experimental Supported
  • ⬜️ Not Supported
API GetOperational() GetConfig() Other Functions Notes
AFC() ✅️ ⬜️ ⬜️
AP() ✅️ ✅️ 🟩
APF() ⬜️ ✅️ ⬜️
AWIPS() ✅️ ⬜️ ⬜️
BLE() ✅️ ⬜️ ⬜️
Client() ✅️ ⬜️ ⬜️ Issue #28, #29 on 17.18.1
Controller() ⬜️ ⬜️ 🟩
CTS() ⬜️ ✅️ ⬜️
Dot11() ⬜️ ✅️ ⬜️
Dot15() ⬜️ ✅️ ⬜️
Fabric() ⬜️ ✅️ ⬜️
Flex() ⬜️ ✅️ ⬜️
General() ✅️ ✅️ ⬜️
Geolocation() ✅️ ⬜️ ⬜️
Hyperlocation() ✅️ ⬜️ ⬜️
LISP() ✅️ ⬜️ ⬜️
Location() ✅️ ✅️ ⬜️
Mcast() ✅️ ⬜️ ⬜️
MDNS() ✅️ ⬜️ ⬜️
Mesh() ✅️ ✅️ ⬜️
Mobility() ✅️ ⬜️ ⬜️
NMSP() ✅️ ⬜️ ⬜️
Radio() ⬜️ ✅️ ⬜️
RF() ⬜️ ✅️ ⬜️
RFTag() ⬜️ ⬜️ 🟩
RFID() ✅️ ✅️ ⬜️
Rogue() ✅️ ⬜️ ⬜️
RRM() ✅️ ✅️ ⬜️
Site() ✅️ ✅️ ⬜️
SiteTag() ⬜️ ⬜️ 🟩
Spaces() 🟨 ⬜️ ⬜️ Requires 17.18.1+
URWB() 🟨 🟨 ⬜️ Requires 17.18.1+
WAT() ⬜️ 🟨 ⬜️ Requires 17.18.1+
WLAN() ✅️ ✅️ ⬜️
PolicyTag() ⬜️ ⬜️ 🟩

Tip

wtpMac is the same as radioMac. WTP (Wireless Termination Point), defined in RFC 5415 denotes an AP.

🔖 Usecases

Runnable examples are available:

List Operation

Usecase 1: List Associating APs

example/list_aps/main.go lists APs managed by the controller.

Click to show example

❯ go run example/list_aps/main.go

Successfully connected! Found 2 APs

AP Name           | MAC Address         | IP Address       | Status
------------------|---------------------|------------------|-----------------
TEST-AP01         | aa:bb:ff:dd:ee:a0   | 192.168.255.11   | registered
TEST-AP02         | aa:bb:ff:dd:ee:b0   | 192.168.255.12   | registered

Usecase 2: List Associating Clients

example/list_clients/main.go lists clients associating to wireless networks.

Click to show example

❯ go run example/list_clients/main.go

Successfully connected! Found 17 clients

MAC Address           | IP Address
----------------------|----------------
08:84:9d:92:47:00     | 192.168.0.84
2a:e3:42:8f:06:c8     | 192.168.0.89
40:23:43:3e:c5:bf     | 192.168.0.62
40:80:e1:6b:11:16     | 192.168.0.92
<snip>

Usecase 3: List WLANs and BSSIDs

example/list_wlans/main.go lists WLANs and their BSSIDs.

Click to show example

❯ go run example/list_wlans/main.go

Successfully connected! Found 7 WLANs across all APs

AP Name           | AP MAC Address    | Slot | WLAN | BSSID             | SSID
------------------|-------------------|------|------|-------------------|-------------------------
TEST-AP01         | aa:bb:ff:dd:ee:a0 |    0 |    1 | aa:bb:ff:dd:ee:a1 | labo-wlan
TEST-AP01         | aa:bb:ff:dd:ee:a0 |    1 |    2 | aa:bb:ff:dd:ee:ad | labo-psk
TEST-AP01         | aa:bb:ff:dd:ee:a0 |    1 |    4 | aa:bb:ff:dd:ee:af | labo-tls
<snip>

Usecase 4: List AP Neighbors

example/list_neighbors/main.go lists neighboring APs detected by the APs.

Click to show example

❯ go run example/list_neighbors/main.go

Successfully connected! Found 11 AP neighbors

AP Name           | Slot | Neighbor BSSID    | Neighbor SSID          | RSSI  | Channel | Last Heard At
------------------|------|-------------------|------------------------|-------|---------|--------------------------
TEST-AP01         |    0 | d8:21:da:a2:30:f0 | Rogue-WiFi             |   -20 |      11 | 2025-09-12 20:24:57
TEST-AP01         |    0 | 08:10:86:bf:07:e3 | rogue-abcdef123-g      |   -62 |       4 | 2025-09-13 06:49:59
TEST-AP01         |    1 | 98:f1:99:c2:03:db | rogue-abcdef123        |   -64 |      36 | 2025-09-13 06:52:57
<snip>

Destructive Operation

Usecase 1: Reload an AP

example/reload_ap/main.go reloads a specified AP by its MAC address.

Click to show example

❯ go run example/reload_ap/main.go

=== Access Point Reload Tool ===
WARNING: This tool will restart access points causing service interruption!
Use only in controlled environments with proper authorization.

Target Controller: wnc1.example.internal
Enter AP MAC address (format: xx:xx:xx:xx:xx:xx or xx-xx-xx-xx-xx-xx): aa:bb:ff:dd:ee:a0
Target AP MAC: aa:bb:ff:dd:ee:a0
This will restart the specified Access Point(s). Type 'YES' to confirm: YES

✓ WNC client created successfully
Executing AP reload for MAC aa:bb:ff:dd:ee:a0
WARNING: AP will become unavailable and disconnect all clients during restart...

✓ AP reload command sent successfully for MAC: aa:bb:ff:dd:ee:a0
Note: AP is now restarting and will be temporarily unavailable
Clients will need to reconnect after AP restart completes

Usecase 2: Reload a Controller

example/reload_controller/main.go reloads the entire wireless controller.

Click to show example

❯ go run ./example/reload_controller/main.go

=== WNC Controller Reload Tool ===
WARNING: This tool will restart the wireless controller!
Use only in controlled environments with proper authorization.

Target Controller: wnc1.example.internal

This will restart the WNC controller. Type 'YES' to confirm: YES

✓ WNC client created successfully
Executing controller reload with reason: Manual reload via CLI tool at 2025-09-06T13:11:50+09:00
WARNING: Controller will become unavailable during restart...

✓ Controller reload command sent successfully
Note: Controller is now restarting and will be temporarily unavailable
Wait for controller to complete restart before attempting reconnection

🤝 Contributing

Please read the Contribution Guide before submitting PRs and issues and also see the following documents:

🙏 Acknowledgments

I maintain this project with the help of GitHub Copilot Coding Agent, and I'm grateful to the global developer community for their contributions to open source projects and public repositories.

📄 License

MIT

View code on GitHub

Code Exchange Community

Get help, share code, and collaborate with other developers in the Code Exchange community.View Community
Disclaimer:
Cisco provides Code Exchange for convenience and informational purposes only, with no support of any kind. This page contains information and links from third-party websites that are governed by their own separate terms. Reference to a project or contributor on this page does not imply any affiliation with or endorsement by Cisco.