Add UXG, UDM storage, minor lint fixups.
This commit is contained in:
parent
bfe80a59e1
commit
e1be3246f1
|
|
@ -73,7 +73,7 @@ func (u *Unifi) GetAlarms(sites []*Site) ([]*Alarm, error) {
|
||||||
// GetAlarmsSite retreives the Alarms for a single Site.
|
// GetAlarmsSite retreives the Alarms for a single Site.
|
||||||
func (u *Unifi) GetAlarmsSite(site *Site) ([]*Alarm, error) {
|
func (u *Unifi) GetAlarmsSite(site *Site) ([]*Alarm, error) {
|
||||||
if site == nil || site.Name == "" {
|
if site == nil || site.Name == "" {
|
||||||
return nil, errNoSiteProvided
|
return nil, ErrNoSiteProvided
|
||||||
}
|
}
|
||||||
|
|
||||||
u.DebugLog("Polling Controller for Alarms, site %s (%s)", site.Name, site.Desc)
|
u.DebugLog("Polling Controller for Alarms, site %s (%s)", site.Name, site.Desc)
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ func (u *Unifi) GetAnomalies(sites []*Site, timeRange ...time.Time) ([]*Anomaly,
|
||||||
// GetAnomaliesSite retreives the Anomalies for a single Site.
|
// GetAnomaliesSite retreives the Anomalies for a single Site.
|
||||||
func (u *Unifi) GetAnomaliesSite(site *Site, timeRange ...time.Time) ([]*Anomaly, error) {
|
func (u *Unifi) GetAnomaliesSite(site *Site, timeRange ...time.Time) ([]*Anomaly, error) {
|
||||||
if site == nil || site.Name == "" {
|
if site == nil || site.Name == "" {
|
||||||
return nil, errNoSiteProvided
|
return nil, ErrNoSiteProvided
|
||||||
}
|
}
|
||||||
|
|
||||||
u.DebugLog("Polling Controller for Anomalies, site %s (%s)", site.Name, site.Desc)
|
u.DebugLog("Polling Controller for Anomalies, site %s (%s)", site.Name, site.Desc)
|
||||||
|
|
@ -119,7 +119,7 @@ func makeAnomalyParams(scale string, timeRange ...time.Time) (string, error) {
|
||||||
end := timeRange[1].Unix() * int64(time.Microsecond)
|
end := timeRange[1].Unix() * int64(time.Microsecond)
|
||||||
out = append(out, "end="+strconv.FormatInt(end, 10), "start="+strconv.FormatInt(start, 10))
|
out = append(out, "end="+strconv.FormatInt(end, 10), "start="+strconv.FormatInt(start, 10))
|
||||||
default:
|
default:
|
||||||
return "", errInvalidTimeRange
|
return "", ErrInvalidTimeRange
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(out) == 0 {
|
if len(out) == 0 {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,12 @@ func (u *Unifi) parseDevices(data []json.RawMessage, siteName string) *Devices {
|
||||||
dev.Name = strings.TrimSpace(pick(dev.Name, dev.Mac))
|
dev.Name = strings.TrimSpace(pick(dev.Name, dev.Mac))
|
||||||
devices.UDMs = append(devices.UDMs, dev)
|
devices.UDMs = append(devices.UDMs, dev)
|
||||||
}
|
}
|
||||||
|
case "uxg":
|
||||||
|
dev := &UXG{SiteName: siteName, SourceName: u.URL}
|
||||||
|
if u.unmarshalDevice(assetType, r, dev) == nil {
|
||||||
|
dev.Name = strings.TrimSpace(pick(dev.Name, dev.Mac))
|
||||||
|
devices.UXGs = append(devices.UXGs, dev)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
u.ErrorLog("unknown asset type - %v - skipping", assetType)
|
u.ErrorLog("unknown asset type - %v - skipping", assetType)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,17 @@ type DPIData struct {
|
||||||
TxBytes int64 `json:"tx_bytes"`
|
TxBytes int64 `json:"tx_bytes"`
|
||||||
RxPackets int64 `json:"rx_packets"`
|
RxPackets int64 `json:"rx_packets"`
|
||||||
TxPackets int64 `json:"tx_packets"`
|
TxPackets int64 `json:"tx_packets"`
|
||||||
|
Clients []*DPIClient `json:"clients,omitempty"`
|
||||||
|
KnownClients FlexInt `json:"known_clients,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DPIClient data is sometimes included in ByApp output.
|
||||||
|
type DPIClient struct {
|
||||||
|
Mac string `json:"mac"`
|
||||||
|
RxBytes FlexInt `json:"rx_bytes"`
|
||||||
|
TxBytes FlexInt `json:"tx_bytes"`
|
||||||
|
RxPackets FlexInt `json:"rx_packets"`
|
||||||
|
TxPackets FlexInt `json:"tx_packets"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DPIMap allows binding methods to the DPICat and DPIApps variables.
|
// DPIMap allows binding methods to the DPICat and DPIApps variables.
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errNoSiteProvided = fmt.Errorf("site must not be nil or empty")
|
ErrNoSiteProvided = fmt.Errorf("site must not be nil or empty")
|
||||||
errInvalidTimeRange = fmt.Errorf("only 0, 1 or 2 times may be provided to timeRange")
|
ErrInvalidTimeRange = fmt.Errorf("only 0, 1 or 2 times may be provided to timeRange")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -35,7 +35,7 @@ func (u *Unifi) GetEvents(sites []*Site, hours time.Duration) ([]*Event, error)
|
||||||
// GetSiteEvents retrieves the last 1 hour's worth of events from a single site.
|
// GetSiteEvents retrieves the last 1 hour's worth of events from a single site.
|
||||||
func (u *Unifi) GetSiteEvents(site *Site, hours time.Duration) ([]*Event, error) {
|
func (u *Unifi) GetSiteEvents(site *Site, hours time.Duration) ([]*Event, error) {
|
||||||
if site == nil || site.Name == "" {
|
if site == nil || site.Name == "" {
|
||||||
return nil, errNoSiteProvided
|
return nil, ErrNoSiteProvided
|
||||||
}
|
}
|
||||||
|
|
||||||
if hours < time.Hour {
|
if hours < time.Hour {
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ func (u *Unifi) GetIDS(sites []*Site, timeRange ...time.Time) ([]*IDS, error) {
|
||||||
// Events between start and end are returned. End defaults to time.Now().
|
// Events between start and end are returned. End defaults to time.Now().
|
||||||
func (u *Unifi) GetIDSSite(site *Site, timeRange ...time.Time) ([]*IDS, error) {
|
func (u *Unifi) GetIDSSite(site *Site, timeRange ...time.Time) ([]*IDS, error) {
|
||||||
if site == nil || site.Name == "" {
|
if site == nil || site.Name == "" {
|
||||||
return nil, errNoSiteProvided
|
return nil, ErrNoSiteProvided
|
||||||
}
|
}
|
||||||
|
|
||||||
u.DebugLog("Polling Controller for IDS Events, site %s (%s)", site.Name, site.Desc)
|
u.DebugLog("Polling Controller for IDS Events, site %s (%s)", site.Name, site.Desc)
|
||||||
|
|
@ -126,12 +126,15 @@ func makeEventParams(timeRange ...time.Time) (string, error) {
|
||||||
rp.Start = timeRange[0].Unix() * int64(time.Microsecond)
|
rp.Start = timeRange[0].Unix() * int64(time.Microsecond)
|
||||||
rp.End = timeRange[1].Unix() * int64(time.Microsecond)
|
rp.End = timeRange[1].Unix() * int64(time.Microsecond)
|
||||||
default:
|
default:
|
||||||
return "", errInvalidTimeRange
|
return "", ErrInvalidTimeRange
|
||||||
}
|
}
|
||||||
|
|
||||||
params, err := json.Marshal(&rp)
|
params, err := json.Marshal(&rp)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("json marshal: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return string(params), err
|
return string(params), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type idsList []*IDS
|
type idsList []*IDS
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var ErrDPIDataBug = fmt.Errorf("dpi data table contains more than 1 item; please open a bug report")
|
||||||
errDPIDataBug = fmt.Errorf("dpi data table contains more than 1 item; please open a bug report")
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetSites returns a list of configured sites on the UniFi controller.
|
// GetSites returns a list of configured sites on the UniFi controller.
|
||||||
func (u *Unifi) GetSites() ([]*Site, error) {
|
func (u *Unifi) GetSites() ([]*Site, error) {
|
||||||
|
|
@ -53,7 +51,7 @@ func (u *Unifi) GetSiteDPI(sites []*Site) ([]*DPITable, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if l := len(response.Data); l > 1 {
|
if l := len(response.Data); l > 1 {
|
||||||
return nil, errDPIDataBug
|
return nil, ErrDPIDataBug
|
||||||
} else if l == 0 {
|
} else if l == 0 {
|
||||||
u.DebugLog("Site DPI data missing! Is DPI enabled in UniFi controller? Site %s (%s) ", site.Name, site.Desc)
|
u.DebugLog("Site DPI data missing! Is DPI enabled in UniFi controller? Site %s (%s) ", site.Name, site.Desc)
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
@ -79,6 +80,7 @@ type Devices struct {
|
||||||
USGs []*USG
|
USGs []*USG
|
||||||
USWs []*USW
|
USWs []*USW
|
||||||
UDMs []*UDM
|
UDMs []*UDM
|
||||||
|
UXGs []*UXG
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the data passed into our library. This configures things and allows
|
// Config is the data passed into our library. This configures things and allows
|
||||||
|
|
@ -91,6 +93,7 @@ type Config struct {
|
||||||
New bool
|
New bool
|
||||||
ErrorLog Logger
|
ErrorLog Logger
|
||||||
DebugLog Logger
|
DebugLog Logger
|
||||||
|
Timeout time.Duration // how long to wait for replies, default: forever.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unifi is what you get in return for providing a password! Unifi represents
|
// Unifi is what you get in return for providing a password! Unifi represents
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,7 @@ type UDM struct {
|
||||||
LastSeen FlexInt `json:"last_seen"`
|
LastSeen FlexInt `json:"last_seen"`
|
||||||
AdoptableWhenUpgraded FlexBool `json:"adoptable_when_upgraded"`
|
AdoptableWhenUpgraded FlexBool `json:"adoptable_when_upgraded"`
|
||||||
Cfgversion string `json:"cfgversion"`
|
Cfgversion string `json:"cfgversion"`
|
||||||
ConfigNetwork struct {
|
ConfigNetwork *ConfigNetwork `json:"config_network"`
|
||||||
Type string `json:"type"`
|
|
||||||
IP string `json:"ip"`
|
|
||||||
} `json:"config_network"`
|
|
||||||
VwireTable []interface{} `json:"vwire_table"`
|
VwireTable []interface{} `json:"vwire_table"`
|
||||||
Dot1XPortctrlEnabled FlexBool `json:"dot1x_portctrl_enabled"`
|
Dot1XPortctrlEnabled FlexBool `json:"dot1x_portctrl_enabled"`
|
||||||
JumboframeEnabled FlexBool `json:"jumboframe_enabled"`
|
JumboframeEnabled FlexBool `json:"jumboframe_enabled"`
|
||||||
|
|
@ -49,16 +46,9 @@ type UDM struct {
|
||||||
InformIP string `json:"inform_ip"`
|
InformIP string `json:"inform_ip"`
|
||||||
RequiredVersion string `json:"required_version"`
|
RequiredVersion string `json:"required_version"`
|
||||||
BoardRev FlexInt `json:"board_rev"`
|
BoardRev FlexInt `json:"board_rev"`
|
||||||
EthernetTable []struct {
|
EthernetTable []*EthernetTable `json:"ethernet_table"`
|
||||||
Mac string `json:"mac"`
|
|
||||||
NumPort FlexInt `json:"num_port"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"ethernet_table"`
|
|
||||||
PortTable []Port `json:"port_table"`
|
PortTable []Port `json:"port_table"`
|
||||||
EthernetOverrides []struct {
|
EthernetOverrides []*EthernetOverrides `json:"ethernet_overrides"`
|
||||||
Ifname string `json:"ifname"`
|
|
||||||
Networkgroup string `json:"networkgroup"`
|
|
||||||
} `json:"ethernet_overrides"`
|
|
||||||
UsgCaps FlexInt `json:"usg_caps"`
|
UsgCaps FlexInt `json:"usg_caps"`
|
||||||
HasSpeaker FlexBool `json:"has_speaker"`
|
HasSpeaker FlexBool `json:"has_speaker"`
|
||||||
HasEth1 FlexBool `json:"has_eth1"`
|
HasEth1 FlexBool `json:"has_eth1"`
|
||||||
|
|
@ -96,7 +86,7 @@ type UDM struct {
|
||||||
Uplink Uplink `json:"uplink"`
|
Uplink Uplink `json:"uplink"`
|
||||||
ConnectRequestIP string `json:"connect_request_ip"`
|
ConnectRequestIP string `json:"connect_request_ip"`
|
||||||
ConnectRequestPort string `json:"connect_request_port"`
|
ConnectRequestPort string `json:"connect_request_port"`
|
||||||
DownlinkTable []interface{} `json:"downlink_table"`
|
DownlinkTable []*DownlinkTable `json:"downlink_table"`
|
||||||
WlangroupIDNa string `json:"wlangroup_id_na"`
|
WlangroupIDNa string `json:"wlangroup_id_na"`
|
||||||
WlangroupIDNg string `json:"wlangroup_id_ng"`
|
WlangroupIDNg string `json:"wlangroup_id_ng"`
|
||||||
BandsteeringMode string `json:"bandsteering_mode"`
|
BandsteeringMode string `json:"bandsteering_mode"`
|
||||||
|
|
@ -110,6 +100,7 @@ type UDM struct {
|
||||||
PortconfID string `json:"portconf_id"`
|
PortconfID string `json:"portconf_id"`
|
||||||
} `json:"port_overrides"`
|
} `json:"port_overrides"`
|
||||||
Stat UDMStat `json:"stat"`
|
Stat UDMStat `json:"stat"`
|
||||||
|
Storage []*Storage `json:"storage"`
|
||||||
TxBytes FlexInt `json:"tx_bytes"`
|
TxBytes FlexInt `json:"tx_bytes"`
|
||||||
RxBytes FlexInt `json:"rx_bytes"`
|
RxBytes FlexInt `json:"rx_bytes"`
|
||||||
Bytes FlexInt `json:"bytes"`
|
Bytes FlexInt `json:"bytes"`
|
||||||
|
|
@ -131,7 +122,19 @@ type UDM struct {
|
||||||
NumHandheld FlexInt `json:"num_handheld"` // USG
|
NumHandheld FlexInt `json:"num_handheld"` // USG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EthernetOverrides struct {
|
||||||
|
Ifname string `json:"ifname"`
|
||||||
|
Networkgroup string `json:"networkgroup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthernetTable struct {
|
||||||
|
Mac string `json:"mac"`
|
||||||
|
NumPort FlexInt `json:"num_port"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
// NetworkTable is the list of networks on a gateway.
|
// NetworkTable is the list of networks on a gateway.
|
||||||
|
// Not all gateways have all features.
|
||||||
type NetworkTable []struct {
|
type NetworkTable []struct {
|
||||||
ID string `json:"_id"`
|
ID string `json:"_id"`
|
||||||
AttrNoDelete FlexBool `json:"attr_no_delete"`
|
AttrNoDelete FlexBool `json:"attr_no_delete"`
|
||||||
|
|
@ -150,6 +153,7 @@ type NetworkTable []struct {
|
||||||
Dhcpdv6Enabled FlexBool `json:"dhcpdv6_enabled"`
|
Dhcpdv6Enabled FlexBool `json:"dhcpdv6_enabled"`
|
||||||
Ipv6RaEnabled FlexBool `json:"ipv6_ra_enabled"`
|
Ipv6RaEnabled FlexBool `json:"ipv6_ra_enabled"`
|
||||||
LteLanEnabled FlexBool `json:"lte_lan_enabled"`
|
LteLanEnabled FlexBool `json:"lte_lan_enabled"`
|
||||||
|
AutoScaleEnabled FlexBool `json:"auto_scale_enabled"`
|
||||||
Networkgroup string `json:"networkgroup"`
|
Networkgroup string `json:"networkgroup"`
|
||||||
DhcpdLeasetime FlexInt `json:"dhcpd_leasetime"`
|
DhcpdLeasetime FlexInt `json:"dhcpd_leasetime"`
|
||||||
DhcpdDNSEnabled FlexBool `json:"dhcpd_dns_enabled"`
|
DhcpdDNSEnabled FlexBool `json:"dhcpd_dns_enabled"`
|
||||||
|
|
@ -167,6 +171,9 @@ type NetworkTable []struct {
|
||||||
IsGuest FlexBool `json:"is_guest"`
|
IsGuest FlexBool `json:"is_guest"`
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Up FlexBool `json:"up"`
|
Up FlexBool `json:"up"`
|
||||||
|
ActiveDhcpLeaseCount int `json:"active_dhcp_lease_count"`
|
||||||
|
GatewayInterfaceName string `json:"gateway_interface_name"`
|
||||||
|
DPIStatsTable *DPITable `json:"dpistats_table"`
|
||||||
NumSta FlexInt `json:"num_sta"`
|
NumSta FlexInt `json:"num_sta"`
|
||||||
RxBytes FlexInt `json:"rx_bytes"`
|
RxBytes FlexInt `json:"rx_bytes"`
|
||||||
RxPackets FlexInt `json:"rx_packets"`
|
RxPackets FlexInt `json:"rx_packets"`
|
||||||
|
|
@ -174,6 +181,15 @@ type NetworkTable []struct {
|
||||||
TxPackets FlexInt `json:"tx_packets"`
|
TxPackets FlexInt `json:"tx_packets"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Storage is hard drive into for a device with storage.
|
||||||
|
type Storage struct {
|
||||||
|
MountPoint string `json:"mount_point"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Size FlexInt `json:"size"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Used FlexInt `json:"used"`
|
||||||
|
}
|
||||||
|
|
||||||
type Temperature struct {
|
type Temperature struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package unifi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -18,13 +19,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"golang.org/x/net/publicsuffix"
|
"golang.org/x/net/publicsuffix"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errAuthenticationFailed = fmt.Errorf("authentication failed")
|
ErrAuthenticationFailed = fmt.Errorf("authentication failed")
|
||||||
errInvalidStatusCode = fmt.Errorf("invalid status code from server")
|
ErrInvalidStatusCode = fmt.Errorf("invalid status code from server")
|
||||||
|
ErrNoParams = fmt.Errorf("requedted PUT with no parameters")
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewUnifi creates a http.Client with authenticated cookies.
|
// NewUnifi creates a http.Client with authenticated cookies.
|
||||||
|
|
@ -46,8 +47,10 @@ func NewUnifi(config *Config) (*Unifi, error) {
|
||||||
config.DebugLog = discardLogs
|
config.DebugLog = discardLogs
|
||||||
}
|
}
|
||||||
|
|
||||||
u := &Unifi{Config: config,
|
u := &Unifi{
|
||||||
|
Config: config,
|
||||||
Client: &http.Client{
|
Client: &http.Client{
|
||||||
|
Timeout: config.Timeout,
|
||||||
Jar: jar,
|
Jar: jar,
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: !config.VerifySSL}, // nolint: gosec
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: !config.VerifySSL}, // nolint: gosec
|
||||||
|
|
@ -64,7 +67,7 @@ func NewUnifi(config *Config) (*Unifi, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := u.GetServerData(); err != nil {
|
if err := u.GetServerData(); err != nil {
|
||||||
return u, errors.Wrap(err, "unable to get server version")
|
return u, fmt.Errorf("unable to get server version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return u, nil
|
return u, nil
|
||||||
|
|
@ -91,8 +94,8 @@ func (u *Unifi) Login() error {
|
||||||
req.URL, time.Since(start).Round(time.Millisecond), resp.ContentLength)
|
req.URL, time.Since(start).Round(time.Millisecond), resp.ContentLength)
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return errors.Wrapf(errAuthenticationFailed, "(user: %s): %s (status: %s)",
|
return fmt.Errorf("(user: %s): %s (status: %s): %w",
|
||||||
u.User, req.URL, resp.Status)
|
u.User, req.URL, resp.Status, ErrAuthenticationFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -185,39 +188,44 @@ func (u *Unifi) PutData(apiPath string, v interface{}, params ...string) error {
|
||||||
// Use this if you're unmarshalling UniFi data into custom types.
|
// Use this if you're unmarshalling UniFi data into custom types.
|
||||||
// And if you're doing that... sumbut a pull request with your new struct. :)
|
// And if you're doing that... sumbut a pull request with your new struct. :)
|
||||||
// This is a helper method that is exposed for convenience.
|
// This is a helper method that is exposed for convenience.
|
||||||
func (u *Unifi) UniReq(apiPath string, params string) (req *http.Request, err error) {
|
func (u *Unifi) UniReq(apiPath string, params string) (*http.Request, error) {
|
||||||
|
var (
|
||||||
|
req *http.Request
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
switch apiPath = u.path(apiPath); params {
|
switch apiPath = u.path(apiPath); params {
|
||||||
case "":
|
case "":
|
||||||
req, err = http.NewRequest("GET", u.URL+apiPath, nil)
|
req, err = http.NewRequest(http.MethodGet, u.URL+apiPath, nil)
|
||||||
default:
|
default:
|
||||||
req, err = http.NewRequest("POST", u.URL+apiPath, bytes.NewBufferString(params))
|
req, err = http.NewRequest(http.MethodPost, u.URL+apiPath, bytes.NewBufferString(params))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, fmt.Errorf("creating request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
u.setHeaders(req, params)
|
u.setHeaders(req, params)
|
||||||
|
|
||||||
return
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UniReqPut is the Put call equivalent to UniReq
|
// UniReqPut is the Put call equivalent to UniReq
|
||||||
func (u *Unifi) UniReqPut(apiPath string, params string) (req *http.Request, err error) {
|
func (u *Unifi) UniReqPut(apiPath string, params string) (*http.Request, error) {
|
||||||
switch apiPath = u.path(apiPath); params {
|
if params == "" {
|
||||||
case "":
|
return nil, ErrNoParams
|
||||||
err = fmt.Errorf("Put with no parameters. Use UniReq()")
|
|
||||||
default:
|
|
||||||
req, err = http.NewRequest("PUT", u.URL+apiPath, bytes.NewBufferString(params))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apiPath = u.path(apiPath)
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPut, u.URL+apiPath, bytes.NewBufferString(params)) //nolint:noctx
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, fmt.Errorf("creating request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
u.setHeaders(req, params)
|
u.setHeaders(req, params)
|
||||||
|
|
||||||
return
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetJSON returns the raw JSON from a path. This is useful for debugging.
|
// GetJSON returns the raw JSON from a path. This is useful for debugging.
|
||||||
|
|
@ -242,7 +250,17 @@ func (u *Unifi) PutJSON(apiPath string, params ...string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Unifi) do(req *http.Request) ([]byte, error) {
|
func (u *Unifi) do(req *http.Request) ([]byte, error) {
|
||||||
resp, err := u.Do(req)
|
var (
|
||||||
|
cancel func()
|
||||||
|
ctx = context.Background()
|
||||||
|
)
|
||||||
|
|
||||||
|
if u.Config.Timeout != 0 {
|
||||||
|
ctx, cancel = context.WithTimeout(ctx, u.Config.Timeout)
|
||||||
|
defer cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := u.Do(req.WithContext(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -260,7 +278,7 @@ func (u *Unifi) do(req *http.Request) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
err = errors.Wrapf(errInvalidStatusCode, "%s: %s", req.URL, resp.Status)
|
err = fmt.Errorf("%s: %s: %w", req.URL, resp.Status, ErrInvalidStatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return body, err
|
return body, err
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,8 @@ type USG struct {
|
||||||
ID string `json:"_id"`
|
ID string `json:"_id"`
|
||||||
Adopted FlexBool `json:"adopted"`
|
Adopted FlexBool `json:"adopted"`
|
||||||
Cfgversion string `json:"cfgversion"`
|
Cfgversion string `json:"cfgversion"`
|
||||||
ConfigNetwork struct {
|
ConfigNetwork *ConfigNetwork `json:"config_network"`
|
||||||
Type string `json:"type"`
|
EthernetTable []*EthernetTable `json:"ethernet_table"`
|
||||||
IP string `json:"ip"`
|
|
||||||
} `json:"config_network"`
|
|
||||||
EthernetTable []struct {
|
|
||||||
Mac string `json:"mac"`
|
|
||||||
NumPort FlexInt `json:"num_port"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"ethernet_table"`
|
|
||||||
FwCaps FlexInt `json:"fw_caps"`
|
FwCaps FlexInt `json:"fw_caps"`
|
||||||
InformIP string `json:"inform_ip"`
|
InformIP string `json:"inform_ip"`
|
||||||
InformURL string `json:"inform_url"`
|
InformURL string `json:"inform_url"`
|
||||||
|
|
@ -37,10 +30,7 @@ type USG struct {
|
||||||
UsgCaps FlexInt `json:"usg_caps"`
|
UsgCaps FlexInt `json:"usg_caps"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
RequiredVersion string `json:"required_version"`
|
RequiredVersion string `json:"required_version"`
|
||||||
EthernetOverrides []struct {
|
EthernetOverrides []*EthernetOverrides `json:"ethernet_overrides"`
|
||||||
Ifname string `json:"ifname"`
|
|
||||||
Networkgroup string `json:"networkgroup"`
|
|
||||||
} `json:"ethernet_overrides"`
|
|
||||||
HwCaps FlexInt `json:"hw_caps"`
|
HwCaps FlexInt `json:"hw_caps"`
|
||||||
BoardRev FlexInt `json:"board_rev"`
|
BoardRev FlexInt `json:"board_rev"`
|
||||||
Unsupported FlexBool `json:"unsupported"`
|
Unsupported FlexBool `json:"unsupported"`
|
||||||
|
|
@ -114,12 +104,15 @@ type Uplink struct {
|
||||||
Nameservers []string `json:"nameservers"`
|
Nameservers []string `json:"nameservers"`
|
||||||
Netmask string `json:"netmask"`
|
Netmask string `json:"netmask"`
|
||||||
NumPort FlexInt `json:"num_port"`
|
NumPort FlexInt `json:"num_port"`
|
||||||
|
Media string `json:"media"`
|
||||||
|
PortIdx FlexInt `json:"port_idx"`
|
||||||
RxBytes FlexInt `json:"rx_bytes"`
|
RxBytes FlexInt `json:"rx_bytes"`
|
||||||
RxBytesR FlexInt `json:"rx_bytes-r"`
|
RxBytesR FlexInt `json:"rx_bytes-r"`
|
||||||
RxDropped FlexInt `json:"rx_dropped"`
|
RxDropped FlexInt `json:"rx_dropped"`
|
||||||
RxErrors FlexInt `json:"rx_errors"`
|
RxErrors FlexInt `json:"rx_errors"`
|
||||||
RxMulticast FlexInt `json:"rx_multicast"`
|
RxMulticast FlexInt `json:"rx_multicast"`
|
||||||
RxPackets FlexInt `json:"rx_packets"`
|
RxPackets FlexInt `json:"rx_packets"`
|
||||||
|
RxRate FlexInt `json:"rx_rate"`
|
||||||
Speed FlexInt `json:"speed"`
|
Speed FlexInt `json:"speed"`
|
||||||
SpeedtestLastrun FlexInt `json:"speedtest_lastrun,omitempty"`
|
SpeedtestLastrun FlexInt `json:"speedtest_lastrun,omitempty"`
|
||||||
SpeedtestPing FlexInt `json:"speedtest_ping,omitempty"`
|
SpeedtestPing FlexInt `json:"speedtest_ping,omitempty"`
|
||||||
|
|
@ -129,6 +122,7 @@ type Uplink struct {
|
||||||
TxDropped FlexInt `json:"tx_dropped"`
|
TxDropped FlexInt `json:"tx_dropped"`
|
||||||
TxErrors FlexInt `json:"tx_errors"`
|
TxErrors FlexInt `json:"tx_errors"`
|
||||||
TxPackets FlexInt `json:"tx_packets"`
|
TxPackets FlexInt `json:"tx_packets"`
|
||||||
|
TxRate FlexInt `json:"tx_rate"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Up FlexBool `json:"up"`
|
Up FlexBool `json:"up"`
|
||||||
Uptime FlexInt `json:"uptime"`
|
Uptime FlexInt `json:"uptime"`
|
||||||
|
|
@ -140,7 +134,7 @@ type Uplink struct {
|
||||||
type Wan struct {
|
type Wan struct {
|
||||||
Autoneg FlexBool `json:"autoneg"`
|
Autoneg FlexBool `json:"autoneg"`
|
||||||
BytesR FlexInt `json:"bytes-r"`
|
BytesR FlexInt `json:"bytes-r"`
|
||||||
DNS []string `json:"dns"`
|
DNS []string `json:"dns"` // may be deprecated
|
||||||
Enable FlexBool `json:"enable"`
|
Enable FlexBool `json:"enable"`
|
||||||
FlowctrlRx FlexBool `json:"flowctrl_rx"`
|
FlowctrlRx FlexBool `json:"flowctrl_rx"`
|
||||||
FlowctrlTx FlexBool `json:"flowctrl_tx"`
|
FlowctrlTx FlexBool `json:"flowctrl_tx"`
|
||||||
|
|
@ -164,7 +158,9 @@ type Wan struct {
|
||||||
RxErrors FlexInt `json:"rx_errors"`
|
RxErrors FlexInt `json:"rx_errors"`
|
||||||
RxMulticast FlexInt `json:"rx_multicast"`
|
RxMulticast FlexInt `json:"rx_multicast"`
|
||||||
RxPackets FlexInt `json:"rx_packets"`
|
RxPackets FlexInt `json:"rx_packets"`
|
||||||
|
RxRate FlexInt `json:"rx_rate"`
|
||||||
Speed FlexInt `json:"speed"`
|
Speed FlexInt `json:"speed"`
|
||||||
|
SpeedCaps FlexInt `json:"speed_caps"`
|
||||||
TxBroadcast FlexInt `json:"tx_broadcast"`
|
TxBroadcast FlexInt `json:"tx_broadcast"`
|
||||||
TxBytes FlexInt `json:"tx_bytes"`
|
TxBytes FlexInt `json:"tx_bytes"`
|
||||||
TxBytesR FlexInt `json:"tx_bytes-r"`
|
TxBytesR FlexInt `json:"tx_bytes-r"`
|
||||||
|
|
@ -172,6 +168,7 @@ type Wan struct {
|
||||||
TxErrors FlexInt `json:"tx_errors"`
|
TxErrors FlexInt `json:"tx_errors"`
|
||||||
TxMulticast FlexInt `json:"tx_multicast"`
|
TxMulticast FlexInt `json:"tx_multicast"`
|
||||||
TxPackets FlexInt `json:"tx_packets"`
|
TxPackets FlexInt `json:"tx_packets"`
|
||||||
|
TxRate FlexInt `json:"tx_rate"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Up FlexBool `json:"up"`
|
Up FlexBool `json:"up"`
|
||||||
}
|
}
|
||||||
|
|
@ -182,6 +179,7 @@ type SpeedtestStatus struct {
|
||||||
Rundate FlexInt `json:"rundate"`
|
Rundate FlexInt `json:"rundate"`
|
||||||
Runtime FlexInt `json:"runtime"`
|
Runtime FlexInt `json:"runtime"`
|
||||||
ServerDesc string `json:"server_desc,omitempty"`
|
ServerDesc string `json:"server_desc,omitempty"`
|
||||||
|
Server *SpeedtestServer `json:"server"`
|
||||||
StatusDownload FlexInt `json:"status_download"`
|
StatusDownload FlexInt `json:"status_download"`
|
||||||
StatusPing FlexInt `json:"status_ping"`
|
StatusPing FlexInt `json:"status_ping"`
|
||||||
StatusSummary FlexInt `json:"status_summary"`
|
StatusSummary FlexInt `json:"status_summary"`
|
||||||
|
|
@ -190,6 +188,22 @@ type SpeedtestStatus struct {
|
||||||
XputUpload FlexInt `json:"xput_upload"`
|
XputUpload FlexInt `json:"xput_upload"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SpeedtestServer struct {
|
||||||
|
Cc string `json:"cc"`
|
||||||
|
City string `json:"city"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
Lat FlexInt `json:"lat"`
|
||||||
|
Lon FlexInt `json:"lon"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
ProviderURL string `json:"provider_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigNetwork comes from gateways.
|
||||||
|
type ConfigNetwork struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
IP string `json:"ip"`
|
||||||
|
}
|
||||||
|
|
||||||
// SystemStats is system info for a UDM, USG, USW.
|
// SystemStats is system info for a UDM, USG, USW.
|
||||||
type SystemStats struct {
|
type SystemStats struct {
|
||||||
CPU FlexInt `json:"cpu"`
|
CPU FlexInt `json:"cpu"`
|
||||||
|
|
@ -233,6 +247,7 @@ type Gw struct {
|
||||||
LanTxBytes FlexInt `json:"lan-tx_bytes"`
|
LanTxBytes FlexInt `json:"lan-tx_bytes"`
|
||||||
LanRxDropped FlexInt `json:"lan-rx_dropped"`
|
LanRxDropped FlexInt `json:"lan-rx_dropped"`
|
||||||
WanRxErrors FlexInt `json:"wan-rx_errors,omitempty"`
|
WanRxErrors FlexInt `json:"wan-rx_errors,omitempty"`
|
||||||
|
LanRxErrors FlexInt `json:"lan-rx_errors,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON unmarshalls 5.10 or 5.11 formatted Gateway Stat data.
|
// UnmarshalJSON unmarshalls 5.10 or 5.11 formatted Gateway Stat data.
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,7 @@ type USW struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
RequiredVersion string `json:"required_version"`
|
RequiredVersion string `json:"required_version"`
|
||||||
SwitchCaps struct {
|
SwitchCaps *SwitchCaps `json:"switch_caps"`
|
||||||
FeatureCaps FlexInt `json:"feature_caps"`
|
|
||||||
MaxMirrorSessions FlexInt `json:"max_mirror_sessions"`
|
|
||||||
MaxAggregateSessions FlexInt `json:"max_aggregate_sessions"`
|
|
||||||
} `json:"switch_caps"`
|
|
||||||
HwCaps FlexInt `json:"hw_caps"`
|
HwCaps FlexInt `json:"hw_caps"`
|
||||||
Unsupported FlexBool `json:"unsupported"`
|
Unsupported FlexBool `json:"unsupported"`
|
||||||
UnsupportedReason FlexInt `json:"unsupported_reason"`
|
UnsupportedReason FlexInt `json:"unsupported_reason"`
|
||||||
|
|
@ -97,6 +93,22 @@ type USW struct {
|
||||||
GuestNumSta FlexInt `json:"guest-num_sta"`
|
GuestNumSta FlexInt `json:"guest-num_sta"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SwitchCaps struct {
|
||||||
|
FeatureCaps FlexInt `json:"feature_caps"`
|
||||||
|
MaxMirrorSessions FlexInt `json:"max_mirror_sessions"`
|
||||||
|
MaxAggregateSessions FlexInt `json:"max_aggregate_sessions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MacTable is a newer feature on some switched ports.
|
||||||
|
type MacTable struct {
|
||||||
|
Age int64 `json:"age"`
|
||||||
|
Authorized FlexBool `json:"authorized"`
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
IP string `json:"ip"`
|
||||||
|
LastReachable int64 `json:"lastReachable"`
|
||||||
|
Mac string `json:"mac"`
|
||||||
|
}
|
||||||
|
|
||||||
// Port is a physical connection on a USW or UDM.
|
// Port is a physical connection on a USW or UDM.
|
||||||
type Port struct {
|
type Port struct {
|
||||||
AggregatedBy FlexBool `json:"aggregated_by"`
|
AggregatedBy FlexBool `json:"aggregated_by"`
|
||||||
|
|
@ -113,11 +125,13 @@ type Port struct {
|
||||||
Ifname string `json:"ifname,omitempty"`
|
Ifname string `json:"ifname,omitempty"`
|
||||||
IsUplink FlexBool `json:"is_uplink"`
|
IsUplink FlexBool `json:"is_uplink"`
|
||||||
Mac string `json:"mac,omitempty"`
|
Mac string `json:"mac,omitempty"`
|
||||||
|
MacTable []MacTable `json:"mac_table,omitempty"`
|
||||||
Jumbo FlexBool `json:"jumbo,omitempty"`
|
Jumbo FlexBool `json:"jumbo,omitempty"`
|
||||||
Masked FlexBool `json:"masked"`
|
Masked FlexBool `json:"masked"`
|
||||||
Media string `json:"media"`
|
Media string `json:"media"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
NetworkName string `json:"network_name,omitempty"`
|
NetworkName string `json:"network_name,omitempty"`
|
||||||
|
Netmask string `json:"netmask,omitempty"`
|
||||||
NumPort int `json:"num_port,omitempty"`
|
NumPort int `json:"num_port,omitempty"`
|
||||||
OpMode string `json:"op_mode"`
|
OpMode string `json:"op_mode"`
|
||||||
PoeCaps FlexInt `json:"poe_caps"`
|
PoeCaps FlexInt `json:"poe_caps"`
|
||||||
|
|
@ -130,6 +144,7 @@ type Port struct {
|
||||||
PoeVoltage FlexInt `json:"poe_voltage,omitempty"`
|
PoeVoltage FlexInt `json:"poe_voltage,omitempty"`
|
||||||
PortDelta struct {
|
PortDelta struct {
|
||||||
TimeDelta int64 `json:"time_delta"`
|
TimeDelta int64 `json:"time_delta"`
|
||||||
|
TimeDeltaActivity int64 `json:"time_delta_activity"`
|
||||||
} `json:"port_delta,omitempty"`
|
} `json:"port_delta,omitempty"`
|
||||||
PortIdx FlexInt `json:"port_idx"`
|
PortIdx FlexInt `json:"port_idx"`
|
||||||
PortPoe FlexBool `json:"port_poe"`
|
PortPoe FlexBool `json:"port_poe"`
|
||||||
|
|
@ -141,6 +156,7 @@ type Port struct {
|
||||||
RxErrors FlexInt `json:"rx_errors"`
|
RxErrors FlexInt `json:"rx_errors"`
|
||||||
RxMulticast FlexInt `json:"rx_multicast"`
|
RxMulticast FlexInt `json:"rx_multicast"`
|
||||||
RxPackets FlexInt `json:"rx_packets"`
|
RxPackets FlexInt `json:"rx_packets"`
|
||||||
|
RxRate FlexInt `json:"rx_rate,omitempty"`
|
||||||
Satisfaction FlexInt `json:"satisfaction,omitempty"`
|
Satisfaction FlexInt `json:"satisfaction,omitempty"`
|
||||||
SfpFound FlexBool `json:"sfp_found,omitempty"`
|
SfpFound FlexBool `json:"sfp_found,omitempty"`
|
||||||
Speed FlexInt `json:"speed"`
|
Speed FlexInt `json:"speed"`
|
||||||
|
|
@ -154,6 +170,7 @@ type Port struct {
|
||||||
TxErrors FlexInt `json:"tx_errors"`
|
TxErrors FlexInt `json:"tx_errors"`
|
||||||
TxMulticast FlexInt `json:"tx_multicast"`
|
TxMulticast FlexInt `json:"tx_multicast"`
|
||||||
TxPackets FlexInt `json:"tx_packets"`
|
TxPackets FlexInt `json:"tx_packets"`
|
||||||
|
TxRate FlexInt `json:"tx_rate,omitempty"`
|
||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
Up FlexBool `json:"up"`
|
Up FlexBool `json:"up"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue