Skip to content

Commit 1474ad8

Browse files
Merge pull request #209 from unpoller/feat/topology-endpoint
feat: add network topology endpoint support
2 parents 6a82252 + e5497c4 commit 1474ad8

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

topology.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package unifi
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
// GetTopology returns network topology data for all provided sites.
9+
// Uses the v2 API endpoint: GET /proxy/network/v2/api/site/{site}/topology
10+
func (u *Unifi) GetTopology(sites []*Site) ([]*Topology, error) {
11+
topologies := make([]*Topology, 0)
12+
13+
for _, site := range sites {
14+
path := fmt.Sprintf(APITopologyPath, site.Name)
15+
16+
body, err := u.GetJSON(path)
17+
if err != nil {
18+
return nil, fmt.Errorf("failed to fetch topology for site %s: %w", site.SiteName, err)
19+
}
20+
21+
var topo Topology
22+
if err := json.Unmarshal(body, &topo); err != nil {
23+
return nil, fmt.Errorf("failed to parse topology for site %s: %w", site.SiteName, err)
24+
}
25+
26+
topo.SiteName = site.SiteName
27+
topo.SourceName = u.URL
28+
topologies = append(topologies, &topo)
29+
}
30+
31+
return topologies, nil
32+
}
33+
34+
// TopologyVertex represents a node in the network topology (device or client).
35+
type TopologyVertex struct {
36+
AllowedInVisualProgramming bool `json:"allowedInVisualProgramming"`
37+
Default bool `json:"default"`
38+
Mac string `json:"mac"`
39+
Model string `json:"model"`
40+
Name string `json:"name"`
41+
State FlexInt `json:"state"`
42+
Type string `json:"type"` // DEVICE or CLIENT
43+
UnifiDevice bool `json:"unifiDevice"`
44+
WifiRadios []TopologyRadio `json:"wifiRadios"`
45+
}
46+
47+
// TopologyRadio represents a WiFi radio on a device vertex.
48+
type TopologyRadio struct {
49+
Channel FlexInt `json:"channel"`
50+
Protocol string `json:"protocol"` // ax, ac, n, g
51+
RadioBand string `json:"radioBand"` // ng (2.4GHz), na (5GHz), 6e (6GHz)
52+
}
53+
54+
// TopologyEdge represents a connection between two vertices in the topology.
55+
type TopologyEdge struct {
56+
Channel FlexInt `json:"channel"`
57+
DownlinkMac string `json:"downlinkMac"`
58+
DownlinkPortNumber FlexInt `json:"downlinkPortNumber"`
59+
Duplex string `json:"duplex"` // FULL_DUPLEX, HALF_DUPLEX
60+
Essid string `json:"essid"`
61+
ExperienceScore FlexInt `json:"experienceScore"`
62+
NetworkID string `json:"networkId"`
63+
Protocol string `json:"protocol"` // ax, ac, n, g
64+
RadioBand string `json:"radioBand"` // ng, na, 6e
65+
RateMbps FlexInt `json:"rateMbps"`
66+
Type string `json:"type"` // WIRED or WIRELESS
67+
UplinkMac string `json:"uplinkMac"`
68+
UplinkPortNumber FlexInt `json:"uplinkPortNumber"`
69+
}
70+
71+
// Topology represents the full network topology for a site.
72+
type Topology struct {
73+
Edges []TopologyEdge `json:"edges"`
74+
HasUnknownSwitch bool `json:"has_unknown_switch"`
75+
Vertices []TopologyVertex `json:"vertices"`
76+
77+
SiteName string `json:"-"`
78+
SourceName string `json:"-"`
79+
}

types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ const (
187187
APIFirewallPoliciesPath string = "/proxy/network/v2/api/site/%s/firewall-policies"
188188
// APIWANSLAsPath returns WAN SLA monitoring data (latency, packet loss, jitter).
189189
APIWANSLAsPath string = "/proxy/network/v2/api/site/%s/wan-slas"
190+
// APITopologyPath returns network topology data (vertices and edges) for a site.
191+
APITopologyPath string = "/proxy/network/v2/api/site/%s/topology"
190192
// APISysinfoPath returns controller system info and health (UniFi OS).
191193
APISysinfoPath string = "/api/s/%s/stat/sysinfo"
192194
)

0 commit comments

Comments
 (0)