unpoller_unpoller/core/unifi/devmgr.go

300 lines
9.1 KiB
Go

package unifi
import (
"encoding/json"
"fmt"
)
// Known commands that can be sent to device manager. All of these are implemented.
//nolint:lll // https://ubntwiki.com/products/software/unifi-controller/api#callable
const (
DevMgrPowerCycle = "power-cycle" // mac = switch mac (required), port_idx = PoE port to cycle (required)
DevMgrAdopt = "adopt" // mac = device mac (required)
DevMgrRestart = "restart" // mac = device mac (required)
DevMgrForceProvision = "force-provision" // mac = device mac (required)
DevMgrSpeedTest = "speedtest" // Start a speed test
DevMgrSpeedTestStatus = "speedtest-status" // Get current state of the speed test
DevMgrSetLocate = "set-locate" // mac = device mac (required): blink unit to locate
DevMgrUnsetLocate = "unset-locate" // mac = device mac (required): led to normal state
DevMgrUpgrade = "upgrade" // mac = device mac (required): upgrade firmware
DevMgrUpgradeExternal = "upgrade-external" // mac = device mac (required), url = firmware URL (required)
DevMgrMigrate = "migrate" // mac = device mac (required), inform_url = New Inform URL for device (required)
DevMgrCancelMigrate = "cancel-migrate" // mac = device mac (required)
DevMgrSpectrumScan = "spectrum-scan" // mac = AP mac (required): trigger RF scan
)
// devMgrCmd is the type marshalled and sent to APIDevMgrPath.
type devMgrCmd struct {
Cmd string `json:"cmd"` // Required.
Mac string `json:"mac"` // Device MAC (required for most, but not all).
URL string `json:"url,omitempty"` // External Upgrade only.
Inform string `json:"inform_url,omitempty"` // Migration only.
Port int `json:"port_idx,omitempty"` // Power Cycle only.
}
// devMgrCommandReply is for commands with a return value.
func (s *Site) devMgrCommandReply(cmd *devMgrCmd) ([]byte, error) {
data, err := json.Marshal(cmd)
if err != nil {
return nil, fmt.Errorf("json marshal: %w", err)
}
b, err := s.controller.GetJSON(fmt.Sprintf(APIDevMgrPath, s.Name), string(data))
if err != nil {
return nil, fmt.Errorf("controller: %w", err)
}
return b, nil
}
// devMgrCommandSimple is for commands with no return value.
func (s *Site) devMgrCommandSimple(cmd *devMgrCmd) error {
_, err := s.devMgrCommandReply(cmd)
return err
}
// PowerCycle shuts off the PoE and turns it back on for a specific port.
// Get a USW from the device list to call this.
func (u *USW) PowerCycle(portIndex int) error {
return u.site.devMgrCommandSimple(&devMgrCmd{
Cmd: DevMgrPowerCycle,
Mac: u.Mac,
Port: portIndex,
})
}
// ScanRF begins a spectrum scan on an access point.
func (u *UAP) ScanRF() error {
return u.site.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrSpectrumScan, Mac: u.Mac})
}
// Restart a device by MAC address on your site.
func (s *Site) Restart(mac string) error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrRestart, Mac: mac})
}
// Restart an access point.
func (u *UAP) Restart() error {
return u.site.Restart(u.Mac)
}
// Restart a switch.
func (u *USW) Restart() error {
return u.site.Restart(u.Mac)
}
// Restart a security gateway.
func (u *USG) Restart() error {
return u.site.Restart(u.Mac)
}
// Restart a dream machine.
func (u *UDM) Restart() error {
return u.site.Restart(u.Mac)
}
// Restart a 10Gb security gateway.
func (u *UXG) Restart() error {
return u.site.Restart(u.Mac)
}
// Locate a device by MAC address on your site. This makes it blink.
func (s *Site) Locate(mac string) error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrSetLocate, Mac: mac})
}
// Locate an access point.
func (u *UAP) Locate() error {
return u.site.Locate(u.Mac)
}
// Locate a switch.
func (u *USW) Locate() error {
return u.site.Locate(u.Mac)
}
// Locate a security gateway.
func (u *USG) Locate() error {
return u.site.Locate(u.Mac)
}
// Locate a dream machine.
func (u *UDM) Locate() error {
return u.site.Locate(u.Mac)
}
// Locate a 10Gb security gateway.
func (u *UXG) Locate() error {
return u.site.Locate(u.Mac)
}
// Unlocate a device by MAC address on your site. This makes it stop blinking.
func (s *Site) Unlocate(mac string) error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrUnsetLocate, Mac: mac})
}
// Unlocate an access point (stop blinking).
func (u *UAP) Unlocate() error {
return u.site.Unlocate(u.Mac)
}
// Unlocate a switch (stop blinking).
func (u *USW) Unlocate() error {
return u.site.Unlocate(u.Mac)
}
// Unlocate a security gateway (stop blinking).
func (u *USG) Unlocate() error {
return u.site.Unlocate(u.Mac)
}
// Unlocate a dream machine (stop blinking).
func (u *UDM) Unlocate() error {
return u.site.Unlocate(u.Mac)
}
// Unlocate a 10Gb security gateway (stop blinking).
func (u *UXG) Unlocate() error {
return u.site.Unlocate(u.Mac)
}
// Provision force provisions a device by MAC address on your site.
func (s *Site) Provision(mac string) error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrForceProvision, Mac: mac})
}
// Provision an access point forcefully.
func (u *UAP) Provision() error {
return u.site.Provision(u.Mac)
}
// Provision a switch forcefully.
func (u *USW) Provision() error {
return u.site.Provision(u.Mac)
}
// Provision a security gateway forcefully.
func (u *USG) Provision() error {
return u.site.Provision(u.Mac)
}
// Provision a dream machine forcefully.
func (u *UDM) Provision() error {
return u.site.Provision(u.Mac)
}
// Provision a 10Gb security gateway forcefully.
func (u *UXG) Provision() error {
return u.site.Provision(u.Mac)
}
// Upgrade starts a firmware upgrade on a device by MAC address on your site.
// URL is optional. If URL is not "" an external upgrade is performed.
func (s *Site) Upgrade(mac string, url string) error {
if url == "" {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrUpgrade, Mac: mac})
}
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrUpgradeExternal, Mac: mac, URL: url})
}
// Upgrade firmware on an access point.
// URL is optional. If URL is not "" an external upgrade is performed.
func (u *UAP) Upgrade(url string) error {
return u.site.Upgrade(u.Mac, url)
}
// Upgrade firmware on a switch.
// URL is optional. If URL is not "" an external upgrade is performed.
func (u *USW) Upgrade(url string) error {
return u.site.Upgrade(u.Mac, url)
}
// Upgrade firmware on a security gateway.
// URL is optional. If URL is not "" an external upgrade is performed.
func (u *USG) Upgrade(url string) error {
return u.site.Upgrade(u.Mac, url)
}
// Upgrade firmware on a dream machine.
// URL is optional. If URL is not "" an external upgrade is performed.
func (u *UDM) Upgrade(url string) error {
return u.site.Upgrade(u.Mac, url)
}
// Upgrade formware on a 10Gb security gateway.
// URL is optional. If URL is not "" an external upgrade is performed.
func (u *UXG) Upgrade(url string) error {
return u.site.Upgrade(u.Mac, url)
}
// Migrate sends a device to another controller's URL.
// Probably does not work on devices with built-in controllers like UDM & UXG.
func (s *Site) Migrate(mac string, url string) error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrMigrate, Mac: mac, Inform: url})
}
// Migrate sends an access point to another controller's URL.
func (u *UAP) Migrate(url string) error {
return u.site.Migrate(u.Mac, url)
}
// Migrate sends a switch to another controller's URL.
func (u *USW) Migrate(url string) error {
return u.site.Migrate(u.Mac, url)
}
// Migrate sends a security gateway to another controller's URL.
func (u *USG) Migrate(url string) error {
return u.site.Migrate(u.Mac, url)
}
// Migrate sends a 10Gb gateway to another controller's URL.
func (u *UXG) Migrate(url string) error {
return u.site.Migrate(u.Mac, url)
}
// CancelMigrate stops a migration in progress.
// Probably does not work on devices with built-in controllers like UDM & UXG.
func (s *Site) CancelMigrate(mac string) error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrCancelMigrate, Mac: mac})
}
// CancelMigrate stops an access point migration in progress.
func (u *UAP) CancelMigrate() error {
return u.site.CancelMigrate(u.Mac)
}
// CancelMigrate stops a switch migration in progress.
func (u *USW) CancelMigrate() error {
return u.site.CancelMigrate(u.Mac)
}
// CancelMigrate stops a security gateway migration in progress.
func (u *USG) CancelMigrate() error {
return u.site.CancelMigrate(u.Mac)
}
// CancelMigrate stops 10Gb gateway a migration in progress.
func (u *UXG) CancelMigrate() error {
return u.site.CancelMigrate(u.Mac)
}
// Adopt a device by MAC address to your site.
func (s *Site) Adopt(mac string) error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrAdopt, Mac: mac})
}
// SpeedTest begins a speed test on a site.
func (s *Site) SpeedTest() error {
return s.devMgrCommandSimple(&devMgrCmd{Cmd: DevMgrSpeedTest})
}
// SpeedTestStatus returns the raw response for the status of a speed test.
// XXX: marshal the response into a data structure. This method will change!
func (s *Site) SpeedTestStatus() ([]byte, error) {
body, err := s.devMgrCommandReply(&devMgrCmd{Cmd: DevMgrSpeedTestStatus})
// marshal into struct here.
return body, err
}