Add sites support. This changes the interface.

This commit is contained in:
David Newhall II 2019-04-15 01:21:24 -07:00
parent 258c97fa79
commit e15602ccfa
2 changed files with 62 additions and 34 deletions

View File

@ -13,14 +13,16 @@ import (
) )
const ( const (
// SiteList is the path to the api site list.
SiteList string = "/api/self/sites"
// ClientPath is Unifi Clients API Path // ClientPath is Unifi Clients API Path
ClientPath string = "/api/s/default/stat/sta" ClientPath string = "/api/s/%s/stat/sta"
// DevicePath is where we get data about Unifi devices. // DevicePath is where we get data about Unifi devices.
DevicePath string = "/api/s/default/stat/device" DevicePath string = "/api/s/%s/stat/device"
// NetworkPath contains network-configuration data. Not really graphable. // NetworkPath contains network-configuration data. Not really graphable.
NetworkPath string = "/api/s/default/rest/networkconf" NetworkPath string = "/api/s/%s/rest/networkconf"
// UserGroupPath contains usergroup configurations. // UserGroupPath contains usergroup configurations.
UserGroupPath string = "/api/s/default/rest/usergroup" UserGroupPath string = "/api/s/%s/rest/usergroup"
// LoginPath is Unifi Controller Login API Path // LoginPath is Unifi Controller Login API Path
LoginPath string = "/api/login" LoginPath string = "/api/login"
) )

View File

@ -2,57 +2,83 @@ package unifi
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"strings"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// GetClients returns a response full of clients' data from the Unifi Controller. // GetClients returns a response full of clients' data from the Unifi Controller.
func (u *Unifi) GetClients() (*Clients, error) { func (u *Unifi) GetClients(sites []string) (*Clients, error) {
var response struct { var data []UCL
Clients []UCL `json:"data"` for _, site := range sites {
var response struct {
Data []UCL `json:"data"`
}
clientPath := fmt.Sprintf(ClientPath, site)
if err := u.GetData(clientPath, &response); err != nil {
return nil, err
}
data = append(data, response.Data...)
} }
req, err := u.UniReq(ClientPath, "") return &Clients{UCLs: data}, nil
if err != nil {
return nil, errors.Wrap(err, "c.UniReq(ClientPath)")
}
resp, err := u.Do(req)
if err != nil {
return nil, errors.Wrap(err, "c.Do(req)")
}
defer func() {
_ = resp.Body.Close()
}()
if body, err := ioutil.ReadAll(resp.Body); err != nil {
return nil, errors.Wrap(err, "ioutil.ReadAll(resp.Body)")
} else if err = json.Unmarshal(body, &response); err != nil {
return nil, errors.Wrap(err, "json.Unmarshal([]UCL)")
}
return &Clients{UCLs: response.Clients}, nil
} }
// GetDevices returns a response full of devices' data from the Unifi Controller. // GetDevices returns a response full of devices' data from the Unifi Controller.
func (u *Unifi) GetDevices() (*Devices, error) { func (u *Unifi) GetDevices(sites []string) (*Devices, error) {
var response struct { var data []json.RawMessage
Data []json.RawMessage `json:"data"` for _, site := range sites {
var response struct {
Data []json.RawMessage `json:"data"`
}
devicePath := fmt.Sprintf(DevicePath, site)
if err := u.GetData(devicePath, &response); err != nil {
return nil, err
}
data = append(data, response.Data...)
} }
req, err := u.UniReq(DevicePath, "") return u.parseDevices(data), nil
}
// GetSites returns a list of configured sites on the Unifi controller.
func (u *Unifi) GetSites() ([]string, error) {
var response struct {
Data []struct {
// This is the only field we need. There are others.
Name string `json:"name"`
} `json:"data"`
}
if err := u.GetData(SiteList, &response); err != nil {
return nil, err
}
var output []string
for i := range response.Data {
output = append(output, response.Data[i].Name)
}
u.dLogf("Found %d sites: %v", len(output), strings.Join(output, ","))
return output, nil
}
// GetData makes a unifi request and unmarshal the response into a provided pointer.
func (u *Unifi) GetData(methodPath string, v interface{}) error {
req, err := u.UniReq(methodPath, "")
if err != nil { if err != nil {
return nil, errors.Wrap(err, "c.UniReq(DevicePath)") return errors.Wrapf(err, "c.UniReq(%v)", methodPath)
} }
resp, err := u.Do(req) resp, err := u.Do(req)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "c.Do(req)") return errors.Wrapf(err, "c.Do(%v)", methodPath)
} }
defer func() { defer func() {
_ = resp.Body.Close() _ = resp.Body.Close()
}() }()
if body, err := ioutil.ReadAll(resp.Body); err != nil { if body, err := ioutil.ReadAll(resp.Body); err != nil {
return nil, errors.Wrap(err, "ioutil.ReadAll(resp.Body)") return errors.Wrapf(err, "ioutil.ReadAll(%v)", methodPath)
} else if err = json.Unmarshal(body, &response); err != nil { } else if err = json.Unmarshal(body, v); err != nil {
return nil, errors.Wrap(err, "json.Unmarshal([]json.RawMessage)") return errors.Wrapf(err, "json.Unmarshal(%v)", methodPath)
} }
return u.parseDevices(response.Data), nil return nil
} }
// parseDevices parses the raw JSON from the Unifi Controller into device structures. // parseDevices parses the raw JSON from the Unifi Controller into device structures.