300 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			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
 | |
| }
 |