Shuffle things around a bit more.
This commit is contained in:
		
							parent
							
								
									e780cf093f
								
							
						
					
					
						commit
						2fd001bb6c
					
				|  | @ -0,0 +1,183 @@ | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"log" | ||||||
|  | 	"strconv" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	influx "github.com/influxdata/influxdb/client/v2" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ClientResponse marshalls the payload from the controller.
 | ||||||
|  | type ClientResponse struct { | ||||||
|  | 	Clients []Client `json:"data"` | ||||||
|  | 	Meta    struct { | ||||||
|  | 		Rc string `json:"rc"` | ||||||
|  | 	} `json:"meta"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DpiStat is for deep packet inspection stats.
 | ||||||
|  | // Does not seem to exist in Unifi 5.7.20.
 | ||||||
|  | type DpiStat struct { | ||||||
|  | 	App       int64 | ||||||
|  | 	Cat       int64 | ||||||
|  | 	RxBytes   int64 | ||||||
|  | 	RxPackets int64 | ||||||
|  | 	TxBytes   int64 | ||||||
|  | 	TxPackets int64 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Client defines all the data a connected-network client contains.
 | ||||||
|  | type Client struct { | ||||||
|  | 	ID                  string    `json:"_id"` | ||||||
|  | 	IsGuestByUAP        bool      `json:"_is_guest_by_uap"` | ||||||
|  | 	IsGuestByUGW        bool      `json:"_is_guest_by_ugw"` | ||||||
|  | 	IsGuestByUSW        bool      `json:"_is_guest_by_usw"` | ||||||
|  | 	LastSeenByUAP       int64     `json:"_last_seen_by_uap"` | ||||||
|  | 	LastSeenByUGW       int64     `json:"_last_seen_by_ugw"` | ||||||
|  | 	LastSeenByUSW       int64     `json:"_last_seen_by_usw"` | ||||||
|  | 	UptimeByUAP         int64     `json:"_uptime_by_uap"` | ||||||
|  | 	UptimeByUGW         int64     `json:"_uptime_by_ugw"` | ||||||
|  | 	UptimeByUSW         int64     `json:"_uptime_by_usw"` | ||||||
|  | 	ApMac               string    `json:"ap_mac"` | ||||||
|  | 	AssocTime           int64     `json:"assoc_time"` | ||||||
|  | 	Authorized          bool      `json:"authorized"` | ||||||
|  | 	Bssid               string    `json:"bssid"` | ||||||
|  | 	BytesR              int64     `json:"bytes-r"` | ||||||
|  | 	Ccq                 int64     `json:"ccq"` | ||||||
|  | 	Channel             int       `json:"channel"` | ||||||
|  | 	DpiStats            []DpiStat `json:"dpi_stats"` | ||||||
|  | 	DpiStatsLastUpdated int64     `json:"dpi_stats_last_updated"` | ||||||
|  | 	Essid               string    `json:"essid"` | ||||||
|  | 	FirstSeen           int64     `json:"first_seen"` | ||||||
|  | 	FixedIP             string    `json:"fixed_ip"` | ||||||
|  | 	Hostname            string    `json:"hostname"` | ||||||
|  | 	GwMac               string    `json:"gw_mac"` | ||||||
|  | 	IdleTime            int64     `json:"idle_time"` | ||||||
|  | 	IP                  string    `json:"ip"` | ||||||
|  | 	Is11R               bool      `json:"is_11r"` | ||||||
|  | 	IsGuest             bool      `json:"is_guest"` | ||||||
|  | 	IsWired             bool      `json:"is_wired"` | ||||||
|  | 	LastSeen            int64     `json:"last_seen"` | ||||||
|  | 	LatestAssocTime     int64     `json:"latest_assoc_time"` | ||||||
|  | 	Mac                 string    `json:"mac"` | ||||||
|  | 	Name                string    `json:"name"` | ||||||
|  | 	Network             string    `json:"network"` | ||||||
|  | 	NetworkID           string    `json:"network_id"` | ||||||
|  | 	Noise               int64     `json:"noise"` | ||||||
|  | 	Note                string    `json:"note"` | ||||||
|  | 	Noted               bool      `json:"noted"` | ||||||
|  | 	Oui                 string    `json:"oui"` | ||||||
|  | 	PowersaveEnabled    bool      `json:"powersave_enabled"` | ||||||
|  | 	QosPolicyApplied    bool      `json:"qos_policy_applied"` | ||||||
|  | 	Radio               string    `json:"radio"` | ||||||
|  | 	RadioName           string    `json:"radio_name"` | ||||||
|  | 	RadioProto          string    `json:"radio_proto"` | ||||||
|  | 	RoamCount           int64     `json:"roam_count"` | ||||||
|  | 	Rssi                int64     `json:"rssi"` | ||||||
|  | 	RxBytes             int64     `json:"rx_bytes"` | ||||||
|  | 	RxBytesR            int64     `json:"rx_bytes-r"` | ||||||
|  | 	RxPackets           int64     `json:"rx_packets"` | ||||||
|  | 	RxRate              int64     `json:"rx_rate"` | ||||||
|  | 	Signal              int64     `json:"signal"` | ||||||
|  | 	SiteID              string    `json:"site_id"` | ||||||
|  | 	SwDepth             int       `json:"sw_depth"` | ||||||
|  | 	SwMac               string    `json:"sw_mac"` | ||||||
|  | 	SwPort              int       `json:"sw_port"` | ||||||
|  | 	TxBytes             int64     `json:"tx_bytes"` | ||||||
|  | 	TxBytesR            int64     `json:"tx_bytes-r"` | ||||||
|  | 	TxPackets           int64     `json:"tx_packets"` | ||||||
|  | 	TxPower             int64     `json:"tx_power"` | ||||||
|  | 	TxRate              int64     `json:"tx_rate"` | ||||||
|  | 	Uptime              int64     `json:"uptime"` | ||||||
|  | 	UserID              string    `json:"user_id"` | ||||||
|  | 	UserGroupID         string    `json:"usergroup_id"` | ||||||
|  | 	UseFixedIP          bool      `json:"use_fixedip"` | ||||||
|  | 	Vlan                int       `json:"vlan"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Point generates a client's datapoint for InfluxDB.
 | ||||||
|  | func (c Client) Point() *influx.Point { | ||||||
|  | 	if c.Name == "" && c.Hostname != "" { | ||||||
|  | 		c.Name = c.Hostname | ||||||
|  | 	} else if c.Hostname == "" && c.Name != "" { | ||||||
|  | 		c.Hostname = c.Name | ||||||
|  | 	} else if c.Hostname == "" && c.Name == "" { | ||||||
|  | 		c.Hostname = "-no-name-" | ||||||
|  | 		c.Name = "-no-name-" | ||||||
|  | 	} | ||||||
|  | 	tags := map[string]string{ | ||||||
|  | 		"id":                 c.ID, | ||||||
|  | 		"mac":                c.Mac, | ||||||
|  | 		"user_id":            c.UserID, | ||||||
|  | 		"site_id":            c.SiteID, | ||||||
|  | 		"ip":                 c.IP, | ||||||
|  | 		"fixed_ip":           c.FixedIP, | ||||||
|  | 		"essid":              c.Essid, | ||||||
|  | 		"bssid":              c.Bssid, | ||||||
|  | 		"network":            c.Network, | ||||||
|  | 		"network_id":         c.NetworkID, | ||||||
|  | 		"usergroup_id":       c.UserGroupID, | ||||||
|  | 		"ap_mac":             c.ApMac, | ||||||
|  | 		"gw_mac":             c.GwMac, | ||||||
|  | 		"sw_mac":             c.SwMac, | ||||||
|  | 		"sw_port":            strconv.Itoa(c.SwPort), | ||||||
|  | 		"oui":                c.Oui, | ||||||
|  | 		"name":               c.Name, | ||||||
|  | 		"hostname":           c.Hostname, | ||||||
|  | 		"radio_name":         c.RadioName, | ||||||
|  | 		"radio":              c.Radio, | ||||||
|  | 		"radio_proto":        c.RadioProto, | ||||||
|  | 		"authorized":         strconv.FormatBool(c.Authorized), | ||||||
|  | 		"is_11r":             strconv.FormatBool(c.Is11R), | ||||||
|  | 		"is_wired":           strconv.FormatBool(c.IsWired), | ||||||
|  | 		"is_guest":           strconv.FormatBool(c.IsGuest), | ||||||
|  | 		"is_guest_by_uap":    strconv.FormatBool(c.IsGuestByUAP), | ||||||
|  | 		"is_guest_by_ugw":    strconv.FormatBool(c.IsGuestByUGW), | ||||||
|  | 		"is_guest_by_usw":    strconv.FormatBool(c.IsGuestByUSW), | ||||||
|  | 		"noted":              strconv.FormatBool(c.Noted), | ||||||
|  | 		"powersave_enabled":  strconv.FormatBool(c.PowersaveEnabled), | ||||||
|  | 		"qos_policy_applied": strconv.FormatBool(c.QosPolicyApplied), | ||||||
|  | 		"use_fixedip":        strconv.FormatBool(c.UseFixedIP), | ||||||
|  | 		"channel":            strconv.Itoa(c.Channel), | ||||||
|  | 		"vlan":               strconv.Itoa(c.Vlan), | ||||||
|  | 	} | ||||||
|  | 	fields := map[string]interface{}{ | ||||||
|  | 		"dpi_stats_last_updated": c.DpiStatsLastUpdated, | ||||||
|  | 		"last_seen_by_uap":       c.LastSeenByUAP, | ||||||
|  | 		"last_seen_by_ugw":       c.LastSeenByUGW, | ||||||
|  | 		"last_seen_by_usw":       c.LastSeenByUSW, | ||||||
|  | 		"uptime_by_uap":          c.UptimeByUAP, | ||||||
|  | 		"uptime_by_ugw":          c.UptimeByUGW, | ||||||
|  | 		"uptime_by_usw":          c.UptimeByUSW, | ||||||
|  | 		"assoc_time":             c.AssocTime, | ||||||
|  | 		"bytes_r":                c.BytesR, | ||||||
|  | 		"ccq":                    c.Ccq, | ||||||
|  | 		"first_seen":             c.FirstSeen, | ||||||
|  | 		"idle_time":              c.IdleTime, | ||||||
|  | 		"last_seen":              c.LastSeen, | ||||||
|  | 		"latest_assoc_time":      c.LatestAssocTime, | ||||||
|  | 		"noise":                  c.Noise, | ||||||
|  | 		"note":                   c.Note, | ||||||
|  | 		"roam_count":             c.RoamCount, | ||||||
|  | 		"rssi":                   c.Rssi, | ||||||
|  | 		"rx_bytes":               c.RxBytes, | ||||||
|  | 		"rx_bytes_r":             c.RxBytesR, | ||||||
|  | 		"rx_packets":             c.RxPackets, | ||||||
|  | 		"rx_rate":                c.RxRate, | ||||||
|  | 		"signal":                 c.Signal, | ||||||
|  | 		"tx_bytes":               c.TxBytes, | ||||||
|  | 		"tx_bytes_r":             c.TxBytesR, | ||||||
|  | 		"tx_packets":             c.TxPackets, | ||||||
|  | 		"tx_power":               c.TxPower, | ||||||
|  | 		"tx_rate":                c.TxRate, | ||||||
|  | 		"uptime":                 c.Uptime, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pt, err := influx.NewPoint("clients", tags, fields, time.Now()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Println("Error creating point:", err) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return pt | ||||||
|  | } | ||||||
|  | @ -10,16 +10,14 @@ const ( | ||||||
| 	LoginPath = "/api/login" | 	LoginPath = "/api/login" | ||||||
| 	// ClientPath is Unifi Clients API Path
 | 	// ClientPath is Unifi Clients API Path
 | ||||||
| 	ClientPath = "/api/s/default/stat/sta" | 	ClientPath = "/api/s/default/stat/sta" | ||||||
|  | 	// DevicePath is where we get data about Unifi devices.
 | ||||||
|  | 	DevicePath = "/api/s/default/stat/device" | ||||||
|  | 	// NetworkPath contains network-configuration data. Not really graphable.
 | ||||||
|  | 	NetworkPath = "/api/s/default/rest/networkconf" | ||||||
|  | 	// UserGroupPath contains usergroup configurations.
 | ||||||
|  | 	UserGroupPath = "/api/s/default/rest/usergroup" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ClientResponse marshalls the payload from the controller.
 |  | ||||||
| type ClientResponse struct { |  | ||||||
| 	Clients []Client `json:"data"` |  | ||||||
| 	Meta    struct { |  | ||||||
| 		Rc string `json:"rc"` |  | ||||||
| 	} `json:"meta"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Config represents the data needed to poll a controller and report to influxdb.
 | // Config represents the data needed to poll a controller and report to influxdb.
 | ||||||
| type Config struct { | type Config struct { | ||||||
| 	Interval   time.Duration `json:"interval",toml:"interval",yaml:"interval"` | 	Interval   time.Duration `json:"interval",toml:"interval",yaml:"interval"` | ||||||
|  | @ -32,83 +30,3 @@ type Config struct { | ||||||
| 	UnifiBase  string        `json:"unifi_url",toml:"unifi_url",yaml:"unifi_url"` | 	UnifiBase  string        `json:"unifi_url",toml:"unifi_url",yaml:"unifi_url"` | ||||||
| 	uniClient  *http.Client | 	uniClient  *http.Client | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // DpiStat is for deep packet inspection stats.
 |  | ||||||
| // Does not seem to exist in Unifi 5.7.20.
 |  | ||||||
| type DpiStat struct { |  | ||||||
| 	App       int64 |  | ||||||
| 	Cat       int64 |  | ||||||
| 	RxBytes   int64 |  | ||||||
| 	RxPackets int64 |  | ||||||
| 	TxBytes   int64 |  | ||||||
| 	TxPackets int64 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Client defines all the data a connected-network client contains.
 |  | ||||||
| type Client struct { |  | ||||||
| 	ID                  string    `json:"_id"` |  | ||||||
| 	IsGuestByUAP        bool      `json:"_is_guest_by_uap"` |  | ||||||
| 	IsGuestByUGW        bool      `json:"_is_guest_by_ugw"` |  | ||||||
| 	IsGuestByUSW        bool      `json:"_is_guest_by_usw"` |  | ||||||
| 	LastSeenByUAP       int64     `json:"_last_seen_by_uap"` |  | ||||||
| 	LastSeenByUGW       int64     `json:"_last_seen_by_ugw"` |  | ||||||
| 	LastSeenByUSW       int64     `json:"_last_seen_by_usw"` |  | ||||||
| 	UptimeByUAP         int64     `json:"_uptime_by_uap"` |  | ||||||
| 	UptimeByUGW         int64     `json:"_uptime_by_ugw"` |  | ||||||
| 	UptimeByUSW         int64     `json:"_uptime_by_usw"` |  | ||||||
| 	ApMac               string    `json:"ap_mac"` |  | ||||||
| 	AssocTime           int64     `json:"assoc_time"` |  | ||||||
| 	Authorized          bool      `json:"authorized"` |  | ||||||
| 	Bssid               string    `json:"bssid"` |  | ||||||
| 	BytesR              int64     `json:"bytes-r"` |  | ||||||
| 	Ccq                 int64     `json:"ccq"` |  | ||||||
| 	Channel             int       `json:"channel"` |  | ||||||
| 	DpiStats            []DpiStat `json:"dpi_stats"` |  | ||||||
| 	DpiStatsLastUpdated int64     `json:"dpi_stats_last_updated"` |  | ||||||
| 	Essid               string    `json:"essid"` |  | ||||||
| 	FirstSeen           int64     `json:"first_seen"` |  | ||||||
| 	FixedIP             string    `json:"fixed_ip"` |  | ||||||
| 	Hostname            string    `json:"hostname"` |  | ||||||
| 	GwMac               string    `json:"gw_mac"` |  | ||||||
| 	IdleTime            int64     `json:"idle_time"` |  | ||||||
| 	IP                  string    `json:"ip"` |  | ||||||
| 	Is11R               bool      `json:"is_11r"` |  | ||||||
| 	IsGuest             bool      `json:"is_guest"` |  | ||||||
| 	IsWired             bool      `json:"is_wired"` |  | ||||||
| 	LastSeen            int64     `json:"last_seen"` |  | ||||||
| 	LatestAssocTime     int64     `json:"latest_assoc_time"` |  | ||||||
| 	Mac                 string    `json:"mac"` |  | ||||||
| 	Name                string    `json:"name"` |  | ||||||
| 	Network             string    `json:"network"` |  | ||||||
| 	NetworkID           string    `json:"network_id"` |  | ||||||
| 	Noise               int64     `json:"noise"` |  | ||||||
| 	Note                string    `json:"note"` |  | ||||||
| 	Noted               bool      `json:"noted"` |  | ||||||
| 	Oui                 string    `json:"oui"` |  | ||||||
| 	PowersaveEnabled    bool      `json:"powersave_enabled"` |  | ||||||
| 	QosPolicyApplied    bool      `json:"qos_policy_applied"` |  | ||||||
| 	Radio               string    `json:"radio"` |  | ||||||
| 	RadioName           string    `json:"radio_name"` |  | ||||||
| 	RadioProto          string    `json:"radio_proto"` |  | ||||||
| 	RoamCount           int64     `json:"roam_count"` |  | ||||||
| 	Rssi                int64     `json:"rssi"` |  | ||||||
| 	RxBytes             int64     `json:"rx_bytes"` |  | ||||||
| 	RxBytesR            int64     `json:"rx_bytes-r"` |  | ||||||
| 	RxPackets           int64     `json:"rx_packets"` |  | ||||||
| 	RxRate              int64     `json:"rx_rate"` |  | ||||||
| 	Signal              int64     `json:"signal"` |  | ||||||
| 	SiteID              string    `json:"site_id"` |  | ||||||
| 	SwDepth             int       `json:"sw_depth"` |  | ||||||
| 	SwMac               string    `json:"sw_mac"` |  | ||||||
| 	SwPort              int       `json:"sw_port"` |  | ||||||
| 	TxBytes             int64     `json:"tx_bytes"` |  | ||||||
| 	TxBytesR            int64     `json:"tx_bytes-r"` |  | ||||||
| 	TxPackets           int64     `json:"tx_packets"` |  | ||||||
| 	TxPower             int64     `json:"tx_power"` |  | ||||||
| 	TxRate              int64     `json:"tx_rate"` |  | ||||||
| 	Uptime              int64     `json:"uptime"` |  | ||||||
| 	UserID              string    `json:"user_id"` |  | ||||||
| 	UserGroupID         string    `json:"usergroup_id"` |  | ||||||
| 	UseFixedIP          bool      `json:"use_fixedip"` |  | ||||||
| 	Vlan                int       `json:"vlan"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -5,104 +5,16 @@ import ( | ||||||
| 	"crypto/tls" | 	"crypto/tls" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"io" |  | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"log" | 	"log" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/http/cookiejar" | 	"net/http/cookiejar" | ||||||
| 	"os" | 	"os" | ||||||
| 	"strconv" |  | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	influx "github.com/influxdata/influxdb/client/v2" | 	influx "github.com/influxdata/influxdb/client/v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Point generates a client's datapoint for InfluxDB.
 |  | ||||||
| func (c Client) Point() *influx.Point { |  | ||||||
| 	if c.Name == "" && c.Hostname != "" { |  | ||||||
| 		c.Name = c.Hostname |  | ||||||
| 	} else if c.Hostname == "" && c.Name != "" { |  | ||||||
| 		c.Hostname = c.Name |  | ||||||
| 	} else if c.Hostname == "" && c.Name == "" { |  | ||||||
| 		c.Hostname = "-no-name-" |  | ||||||
| 		c.Name = "-no-name-" |  | ||||||
| 	} |  | ||||||
| 	tags := map[string]string{ |  | ||||||
| 		"id":                 c.ID, |  | ||||||
| 		"mac":                c.Mac, |  | ||||||
| 		"user_id":            c.UserID, |  | ||||||
| 		"site_id":            c.SiteID, |  | ||||||
| 		"ip":                 c.IP, |  | ||||||
| 		"fixed_ip":           c.FixedIP, |  | ||||||
| 		"essid":              c.Essid, |  | ||||||
| 		"bssid":              c.Bssid, |  | ||||||
| 		"network":            c.Network, |  | ||||||
| 		"network_id":         c.NetworkID, |  | ||||||
| 		"usergroup_id":       c.UserGroupID, |  | ||||||
| 		"ap_mac":             c.ApMac, |  | ||||||
| 		"gw_mac":             c.GwMac, |  | ||||||
| 		"sw_mac":             c.SwMac, |  | ||||||
| 		"sw_port":            strconv.Itoa(c.SwPort), |  | ||||||
| 		"oui":                c.Oui, |  | ||||||
| 		"name":               c.Name, |  | ||||||
| 		"hostname":           c.Hostname, |  | ||||||
| 		"radio_name":         c.RadioName, |  | ||||||
| 		"radio":              c.Radio, |  | ||||||
| 		"radio_proto":        c.RadioProto, |  | ||||||
| 		"authorized":         strconv.FormatBool(c.Authorized), |  | ||||||
| 		"is_11r":             strconv.FormatBool(c.Is11R), |  | ||||||
| 		"is_wired":           strconv.FormatBool(c.IsWired), |  | ||||||
| 		"is_guest":           strconv.FormatBool(c.IsGuest), |  | ||||||
| 		"is_guest_by_uap":    strconv.FormatBool(c.IsGuestByUAP), |  | ||||||
| 		"is_guest_by_ugw":    strconv.FormatBool(c.IsGuestByUGW), |  | ||||||
| 		"is_guest_by_usw":    strconv.FormatBool(c.IsGuestByUSW), |  | ||||||
| 		"noted":              strconv.FormatBool(c.Noted), |  | ||||||
| 		"powersave_enabled":  strconv.FormatBool(c.PowersaveEnabled), |  | ||||||
| 		"qos_policy_applied": strconv.FormatBool(c.QosPolicyApplied), |  | ||||||
| 		"use_fixedip":        strconv.FormatBool(c.UseFixedIP), |  | ||||||
| 		"channel":            strconv.Itoa(c.Channel), |  | ||||||
| 		"vlan":               strconv.Itoa(c.Vlan), |  | ||||||
| 	} |  | ||||||
| 	fields := map[string]interface{}{ |  | ||||||
| 		"dpi_stats_last_updated": c.DpiStatsLastUpdated, |  | ||||||
| 		"last_seen_by_uap":       c.LastSeenByUAP, |  | ||||||
| 		"last_seen_by_ugw":       c.LastSeenByUGW, |  | ||||||
| 		"last_seen_by_usw":       c.LastSeenByUSW, |  | ||||||
| 		"uptime_by_uap":          c.UptimeByUAP, |  | ||||||
| 		"uptime_by_ugw":          c.UptimeByUGW, |  | ||||||
| 		"uptime_by_usw":          c.UptimeByUSW, |  | ||||||
| 		"assoc_time":             c.AssocTime, |  | ||||||
| 		"bytes_r":                c.BytesR, |  | ||||||
| 		"ccq":                    c.Ccq, |  | ||||||
| 		"first_seen":             c.FirstSeen, |  | ||||||
| 		"idle_time":              c.IdleTime, |  | ||||||
| 		"last_seen":              c.LastSeen, |  | ||||||
| 		"latest_assoc_time":      c.LatestAssocTime, |  | ||||||
| 		"noise":                  c.Noise, |  | ||||||
| 		"note":                   c.Note, |  | ||||||
| 		"roam_count":             c.RoamCount, |  | ||||||
| 		"rssi":                   c.Rssi, |  | ||||||
| 		"rx_bytes":               c.RxBytes, |  | ||||||
| 		"rx_bytes_r":             c.RxBytesR, |  | ||||||
| 		"rx_packets":             c.RxPackets, |  | ||||||
| 		"rx_rate":                c.RxRate, |  | ||||||
| 		"signal":                 c.Signal, |  | ||||||
| 		"tx_bytes":               c.TxBytes, |  | ||||||
| 		"tx_bytes_r":             c.TxBytesR, |  | ||||||
| 		"tx_packets":             c.TxPackets, |  | ||||||
| 		"tx_power":               c.TxPower, |  | ||||||
| 		"tx_rate":                c.TxRate, |  | ||||||
| 		"uptime":                 c.Uptime, |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pt, err := influx.NewPoint("clients", tags, fields, time.Now()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		log.Println("Error creating point:", err) |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return pt |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func main() { | func main() { | ||||||
| 	config := GetConfig() | 	config := GetConfig() | ||||||
| 	if err := config.AuthController(); err != nil { | 	if err := config.AuthController(); err != nil { | ||||||
|  | @ -122,6 +34,48 @@ func main() { | ||||||
| 	config.PollUnifiController(infdb) | 	config.PollUnifiController(infdb) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // GetConfig parses and returns our configuration data.
 | ||||||
|  | func GetConfig() Config { | ||||||
|  | 	// TODO: A real config file.
 | ||||||
|  | 	var err error | ||||||
|  | 	config := Config{ | ||||||
|  | 		InfluxAddr: os.Getenv("INFLUXDB_ADDR"), | ||||||
|  | 		InfluxUser: os.Getenv("INFLUXDB_USERNAME"), | ||||||
|  | 		InfluxPass: os.Getenv("INFLUXDB_PASSWORD"), | ||||||
|  | 		InfluxDB:   os.Getenv("INFLUXDB_DATABASE"), | ||||||
|  | 		UnifiUser:  os.Getenv("UNIFI_USERNAME"), | ||||||
|  | 		UnifiPass:  os.Getenv("UNIFI_PASSWORD"), | ||||||
|  | 		UnifiBase:  "https://" + os.Getenv("UNIFI_ADDR") + ":" + os.Getenv("UNIFI_PORT"), | ||||||
|  | 	} | ||||||
|  | 	if config.Interval, err = time.ParseDuration(os.Getenv("INTERVAL")); err != nil { | ||||||
|  | 		log.Println("Invalid Interval, defaulting to 15 seconds.") | ||||||
|  | 		config.Interval = time.Duration(time.Second * 15) | ||||||
|  | 	} | ||||||
|  | 	return config | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AuthController creates a http.Client with authenticated cookies.
 | ||||||
|  | // Used to make additional, authenticated requests to the APIs.
 | ||||||
|  | func (c *Config) AuthController() error { | ||||||
|  | 	json := `{"username": "` + c.UnifiUser + `","password": "` + c.UnifiPass + `"}` | ||||||
|  | 	jar, err := cookiejar.New(nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	c.uniClient = &http.Client{ | ||||||
|  | 		Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}, | ||||||
|  | 		Jar:       jar, | ||||||
|  | 	} | ||||||
|  | 	if req, err := c.uniRequest(LoginPath, json); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} else if resp, err := c.uniClient.Do(req); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} else if resp.StatusCode != http.StatusOK { | ||||||
|  | 		return errors.New("Error Authenticating with Unifi Controller") | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // PollUnifiController runs forever, polling and pushing.
 | // PollUnifiController runs forever, polling and pushing.
 | ||||||
| func (c *Config) PollUnifiController(infdb influx.Client) { | func (c *Config) PollUnifiController(infdb influx.Client) { | ||||||
| 	ticker := time.NewTicker(c.Interval) | 	ticker := time.NewTicker(c.Interval) | ||||||
|  | @ -150,30 +104,10 @@ func (c *Config) PollUnifiController(infdb influx.Client) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetConfig parses and returns our configuration data.
 |  | ||||||
| func GetConfig() Config { |  | ||||||
| 	// TODO: A real config file.
 |  | ||||||
| 	var err error |  | ||||||
| 	config := Config{ |  | ||||||
| 		InfluxAddr: os.Getenv("INFLUXDB_ADDR"), |  | ||||||
| 		InfluxUser: os.Getenv("INFLUXDB_USERNAME"), |  | ||||||
| 		InfluxPass: os.Getenv("INFLUXDB_PASSWORD"), |  | ||||||
| 		InfluxDB:   os.Getenv("INFLUXDB_DATABASE"), |  | ||||||
| 		UnifiUser:  os.Getenv("UNIFI_USERNAME"), |  | ||||||
| 		UnifiPass:  os.Getenv("UNIFI_PASSWORD"), |  | ||||||
| 		UnifiBase:  "https://" + os.Getenv("UNIFI_ADDR") + ":" + os.Getenv("UNIFI_PORT"), |  | ||||||
| 	} |  | ||||||
| 	if config.Interval, err = time.ParseDuration(os.Getenv("INTERVAL")); err != nil { |  | ||||||
| 		log.Println("Invalid Interval, defaulting to 15 seconds.") |  | ||||||
| 		config.Interval = time.Duration(time.Second * 15) |  | ||||||
| 	} |  | ||||||
| 	return config |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetUnifiClients returns a response full of clients' data from the Unifi Controller.
 | // GetUnifiClients returns a response full of clients' data from the Unifi Controller.
 | ||||||
| func (c *Config) GetUnifiClients() ([]Client, error) { | func (c *Config) GetUnifiClients() ([]Client, error) { | ||||||
| 	response := &ClientResponse{} | 	response := &ClientResponse{} | ||||||
| 	if req, err := uniRequest("GET", c.UnifiBase+ClientPath, nil); err != nil { | 	if req, err := c.uniRequest(ClientPath, ""); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if resp, err := c.uniClient.Do(req); err != nil { | 	} else if resp, err := c.uniClient.Do(req); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
|  | @ -187,33 +121,15 @@ func (c *Config) GetUnifiClients() ([]Client, error) { | ||||||
| 	return response.Clients, nil | 	return response.Clients, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AuthController creates a http.Client with authenticated cookies.
 | // uniRequest is a small helper function that adds an Accept header.
 | ||||||
| // Used to make additional, authenticated requests to the APIs.
 | func (c *Config) uniRequest(url string, params string) (req *http.Request, err error) { | ||||||
| func (c *Config) AuthController() error { | 	if params != "" { | ||||||
| 	json := bytes.NewBufferString(`{"username": "` + c.UnifiUser + `","password": "` + c.UnifiPass + `"}`) | 		req, err = http.NewRequest("POST", c.UnifiBase+url, bytes.NewBufferString(params)) | ||||||
| 	jar, err := cookiejar.New(nil) | 	} else { | ||||||
| 	if err != nil { | 		req, err = http.NewRequest("GET", c.UnifiBase+url, nil) | ||||||
| 		return err |  | ||||||
| 	} | 	} | ||||||
| 	c.uniClient = &http.Client{ | 	if err == nil { | ||||||
| 		Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}, | 		req.Header.Add("Accept", "application/json") | ||||||
| 		Jar:       jar, |  | ||||||
| 	} | 	} | ||||||
| 	if req, err := uniRequest("POST", c.UnifiBase+LoginPath, json); err != nil { | 	return | ||||||
| 		return err |  | ||||||
| 	} else if resp, err := c.uniClient.Do(req); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} else if resp.StatusCode != http.StatusOK { |  | ||||||
| 		return errors.New("Error Authenticating with Unifi Controller") |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func uniRequest(method string, url string, data io.Reader) (*http.Request, error) { |  | ||||||
| 	req, err := http.NewRequest(method, url, data) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	req.Header.Add("Accept", "application/json") |  | ||||||
| 	return req, nil |  | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue