Add web server update pieces
This commit is contained in:
		
							parent
							
								
									57470c3073
								
							
						
					
					
						commit
						cbb4893970
					
				| 
						 | 
					@ -0,0 +1,131 @@
 | 
				
			||||||
 | 
					package inputunifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
 | 
						"github.com/unifi-poller/unifi"
 | 
				
			||||||
 | 
						"github.com/unifi-poller/webserver"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Event collection. Events are also sent to the webserver for display. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (u *InputUnifi) collectControllerEvents(c *Controller) ([]interface{}, error) {
 | 
				
			||||||
 | 
						var (
 | 
				
			||||||
 | 
							logs    = []interface{}{}
 | 
				
			||||||
 | 
							newLogs []interface{}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get the sites we care about.
 | 
				
			||||||
 | 
						sites, err := u.getFilteredSites(c)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, errors.Wrap(err, "unifi.GetSites()")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						type caller func([]interface{}, []*unifi.Site, *Controller) ([]interface{}, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, call := range []caller{u.collectIDS, u.collectAnomalies, u.collectAlarms, u.collectEvents} {
 | 
				
			||||||
 | 
							if newLogs, err = call(logs, sites, c); err != nil {
 | 
				
			||||||
 | 
								return logs, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							logs = append(logs, newLogs...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return logs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (u *InputUnifi) collectAlarms(logs []interface{}, sites []*unifi.Site, c *Controller) ([]interface{}, error) {
 | 
				
			||||||
 | 
						if *c.SaveAlarms {
 | 
				
			||||||
 | 
							events, err := c.Unifi.GetAlarms(sites)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return logs, errors.Wrap(err, "unifi.GetAlarms()")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, e := range events {
 | 
				
			||||||
 | 
								logs = append(logs, e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								webserver.NewInputEvent(PluginName, c.URL+" alarms", &webserver.Event{Ts: e.Datetime, Msg: e.Msg,
 | 
				
			||||||
 | 
									Tags: map[string]string{"key": e.Key, "site_id": e.SiteID, "site_name": e.SiteName, "source": e.SourceName},
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return logs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (u *InputUnifi) collectAnomalies(logs []interface{}, sites []*unifi.Site, c *Controller) ([]interface{}, error) {
 | 
				
			||||||
 | 
						if *c.SaveAnomal {
 | 
				
			||||||
 | 
							events, err := c.Unifi.GetAnomalies(sites, time.Now().Add(-time.Hour))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return logs, errors.Wrap(err, "unifi.GetAnomalies()")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, e := range events {
 | 
				
			||||||
 | 
								logs = append(logs, e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								webserver.NewInputEvent(PluginName, c.URL+" anomalies", &webserver.Event{Ts: e.Datetime, Msg: e.Anomaly,
 | 
				
			||||||
 | 
									Tags: map[string]string{"site_name": e.SiteName, "source": e.SourceName},
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return logs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (u *InputUnifi) collectEvents(logs []interface{}, sites []*unifi.Site, c *Controller) ([]interface{}, error) {
 | 
				
			||||||
 | 
						if *c.SaveEvents {
 | 
				
			||||||
 | 
							events, err := c.Unifi.GetEvents(sites, time.Hour)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return logs, errors.Wrap(err, "unifi.GetEvents()")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, e := range events {
 | 
				
			||||||
 | 
								e := redactEvent(e, c.HashPII)
 | 
				
			||||||
 | 
								logs = append(logs, e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								webserver.NewInputEvent(PluginName, c.URL+" events", &webserver.Event{Msg: e.Msg, Ts: e.Datetime,
 | 
				
			||||||
 | 
									Tags: map[string]string{"key": e.Key, "site_id": e.SiteID, "site_name": e.SiteName, "source": e.SourceName},
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return logs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (u *InputUnifi) collectIDS(logs []interface{}, sites []*unifi.Site, c *Controller) ([]interface{}, error) {
 | 
				
			||||||
 | 
						if *c.SaveIDS {
 | 
				
			||||||
 | 
							events, err := c.Unifi.GetIDS(sites, time.Now().Add(-time.Hour))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return logs, errors.Wrap(err, "unifi.GetIDS()")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, e := range events {
 | 
				
			||||||
 | 
								logs = append(logs, e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								webserver.NewInputEvent(PluginName, c.URL+" ids", &webserver.Event{Ts: e.Datetime, Msg: e.Msg,
 | 
				
			||||||
 | 
									Tags: map[string]string{"key": e.Key, "site_id": e.SiteID, "site_name": e.SiteName, "source": e.SourceName},
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return logs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// redactEvent attempts to mask personally identying information from log messages.
 | 
				
			||||||
 | 
					// This currently misses the "msg" value entirely and leaks PII information.
 | 
				
			||||||
 | 
					func redactEvent(e *unifi.Event, hash *bool) *unifi.Event {
 | 
				
			||||||
 | 
						if !*hash {
 | 
				
			||||||
 | 
							return e
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// metrics.Events[i].Msg <-- not sure what to do here.
 | 
				
			||||||
 | 
						e.DestIPGeo = unifi.IPGeo{}
 | 
				
			||||||
 | 
						e.SourceIPGeo = unifi.IPGeo{}
 | 
				
			||||||
 | 
						e.Host = RedactNamePII(e.Host, hash)
 | 
				
			||||||
 | 
						e.Hostname = RedactNamePII(e.Hostname, hash)
 | 
				
			||||||
 | 
						e.DstMAC = RedactMacPII(e.DstMAC, hash)
 | 
				
			||||||
 | 
						e.SrcMAC = RedactMacPII(e.SrcMAC, hash)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return e
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -82,62 +82,6 @@ func (u *InputUnifi) collectController(c *Controller) (*poller.Metrics, error) {
 | 
				
			||||||
	return metrics, err
 | 
						return metrics, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (u *InputUnifi) collectControllerEvents(c *Controller) ([]interface{}, error) {
 | 
					 | 
				
			||||||
	logs := []interface{}{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get the sites we care about.
 | 
					 | 
				
			||||||
	sites, err := u.getFilteredSites(c)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, errors.Wrap(err, "unifi.GetSites()")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if *c.SaveAnomal {
 | 
					 | 
				
			||||||
		anom, err := c.Unifi.GetAnomalies(sites, time.Now().Add(-time.Hour))
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, errors.Wrap(err, "unifi.GetAnomalies()")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, a := range anom {
 | 
					 | 
				
			||||||
			logs = append(logs, a)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if *c.SaveAlarms {
 | 
					 | 
				
			||||||
		alarms, err := c.Unifi.GetAlarms(sites)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, errors.Wrap(err, "unifi.GetAlarms()")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, a := range alarms {
 | 
					 | 
				
			||||||
			logs = append(logs, a)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if *c.SaveEvents {
 | 
					 | 
				
			||||||
		events, err := c.Unifi.GetEvents(sites, time.Hour)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, errors.Wrap(err, "unifi.GetEvents()")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, e := range events {
 | 
					 | 
				
			||||||
			logs = append(logs, redactEvent(e, c.HashPII))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if *c.SaveIDS {
 | 
					 | 
				
			||||||
		events, err := c.Unifi.GetIDS(sites, time.Now().Add(-time.Hour))
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, errors.Wrap(err, "unifi.GetIDS()")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, e := range events {
 | 
					 | 
				
			||||||
			logs = append(logs, e)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return logs, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u *InputUnifi) pollController(c *Controller) (*poller.Metrics, error) {
 | 
					func (u *InputUnifi) pollController(c *Controller) (*poller.Metrics, error) {
 | 
				
			||||||
	u.RLock()
 | 
						u.RLock()
 | 
				
			||||||
	defer u.RUnlock()
 | 
						defer u.RUnlock()
 | 
				
			||||||
| 
						 | 
					@ -169,6 +113,8 @@ func (u *InputUnifi) pollController(c *Controller) (*poller.Metrics, error) {
 | 
				
			||||||
		return nil, errors.Wrapf(err, "unifi.GetDevices(%s)", c.URL)
 | 
							return nil, errors.Wrapf(err, "unifi.GetDevices(%s)", c.URL)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer updateWeb(m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return u.augmentMetrics(c, m), nil
 | 
						return u.augmentMetrics(c, m), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -257,24 +203,6 @@ func extractDevices(metrics *Metrics) (*poller.Metrics, map[string]string, map[s
 | 
				
			||||||
	return m, devices, bssdIDs
 | 
						return m, devices, bssdIDs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// redactEvent attempts to mask personally identying information from log messages.
 | 
					 | 
				
			||||||
// This currently misses the "msg" value entirely and leaks PII information.
 | 
					 | 
				
			||||||
func redactEvent(e *unifi.Event, hash *bool) *unifi.Event {
 | 
					 | 
				
			||||||
	if !*hash {
 | 
					 | 
				
			||||||
		return e
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// metrics.Events[i].Msg <-- not sure what to do here.
 | 
					 | 
				
			||||||
	e.DestIPGeo = unifi.IPGeo{}
 | 
					 | 
				
			||||||
	e.SourceIPGeo = unifi.IPGeo{}
 | 
					 | 
				
			||||||
	e.Host = RedactNamePII(e.Host, hash)
 | 
					 | 
				
			||||||
	e.Hostname = RedactNamePII(e.Hostname, hash)
 | 
					 | 
				
			||||||
	e.DstMAC = RedactMacPII(e.DstMAC, hash)
 | 
					 | 
				
			||||||
	e.SrcMAC = RedactMacPII(e.SrcMAC, hash)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return e
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RedactNamePII converts a name string to an md5 hash (first 24 chars only).
 | 
					// RedactNamePII converts a name string to an md5 hash (first 24 chars only).
 | 
				
			||||||
// Useful for maskiing out personally identifying information.
 | 
					// Useful for maskiing out personally identifying information.
 | 
				
			||||||
func RedactNamePII(pii string, hash *bool) string {
 | 
					func RedactNamePII(pii string, hash *bool) string {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,13 @@ module github.com/unifi-poller/inputunifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
go 1.14
 | 
					go 1.14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace github.com/unifi-poller/webserver => ../webserver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace github.com/unifi-poller/poller => ../poller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/pkg/errors v0.9.1
 | 
						github.com/pkg/errors v0.9.1
 | 
				
			||||||
	github.com/unifi-poller/poller v0.0.8-0.20200621214016-5d1ed3324a46
 | 
						github.com/unifi-poller/poller v0.0.8-0.20200626082958-a9a7092a5684
 | 
				
			||||||
	github.com/unifi-poller/unifi v0.0.6-0.20200625090439-421046871a37
 | 
						github.com/unifi-poller/unifi v0.0.6-0.20200625090439-421046871a37
 | 
				
			||||||
 | 
						github.com/unifi-poller/webserver v0.0.0-20200628114213-2b89a50ff1c0
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 | 
				
			||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
					github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
				
			||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
					github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
				
			||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 | 
					github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 | 
				
			||||||
 | 
					github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
 | 
				
			||||||
 | 
					github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 | 
				
			||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
					github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
				
			||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
					github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
				
			||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 | 
					github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 | 
				
			||||||
| 
						 | 
					@ -108,6 +110,7 @@ github.com/unifi-poller/unifi v0.0.5-0.20200622073824-4a29471d80f6/go.mod h1:L1k
 | 
				
			||||||
github.com/unifi-poller/unifi v0.0.6-0.20200625090439-421046871a37 h1:T2y8JWkjZd1vz2ZKu4vmmAk9s6PUwupuTldwhfww5xY=
 | 
					github.com/unifi-poller/unifi v0.0.6-0.20200625090439-421046871a37 h1:T2y8JWkjZd1vz2ZKu4vmmAk9s6PUwupuTldwhfww5xY=
 | 
				
			||||||
github.com/unifi-poller/unifi v0.0.6-0.20200625090439-421046871a37/go.mod h1:L1kMRH2buZhB31vZnRC1im7Tk/4uD3ET4biwl2faYy8=
 | 
					github.com/unifi-poller/unifi v0.0.6-0.20200625090439-421046871a37/go.mod h1:L1kMRH2buZhB31vZnRC1im7Tk/4uD3ET4biwl2faYy8=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
					golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
				
			||||||
 | 
					golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
					golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
				
			||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 | 
					golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 | 
				
			||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 | 
					golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,8 +14,10 @@ import (
 | 
				
			||||||
	"github.com/unifi-poller/unifi"
 | 
						"github.com/unifi-poller/unifi"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PluginName is the name of this input plugin.
 | 
				
			||||||
 | 
					const PluginName = "unifi"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	PluginName  = "unifi" // PluginName is the name of this input plugin.
 | 
					 | 
				
			||||||
	defaultURL  = "https://127.0.0.1:8443"
 | 
						defaultURL  = "https://127.0.0.1:8443"
 | 
				
			||||||
	defaultUser = "unifipoller"
 | 
						defaultUser = "unifipoller"
 | 
				
			||||||
	defaultPass = "unifipoller"
 | 
						defaultPass = "unifipoller"
 | 
				
			||||||
| 
						 | 
					@ -27,7 +29,7 @@ type InputUnifi struct {
 | 
				
			||||||
	*Config    `json:"unifi" toml:"unifi" xml:"unifi" yaml:"unifi"`
 | 
						*Config    `json:"unifi" toml:"unifi" xml:"unifi" yaml:"unifi"`
 | 
				
			||||||
	dynamic    map[string]*Controller
 | 
						dynamic    map[string]*Controller
 | 
				
			||||||
	sync.Mutex // to lock the map above.
 | 
						sync.Mutex // to lock the map above.
 | 
				
			||||||
	poller.Logger
 | 
						Logger     poller.Logger
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Controller represents the configuration for a UniFi Controller.
 | 
					// Controller represents the configuration for a UniFi Controller.
 | 
				
			||||||
| 
						 | 
					@ -44,7 +46,7 @@ type Controller struct {
 | 
				
			||||||
	User       string       `json:"user" toml:"user" xml:"user" yaml:"user"`
 | 
						User       string       `json:"user" toml:"user" xml:"user" yaml:"user"`
 | 
				
			||||||
	Pass       string       `json:"pass" toml:"pass" xml:"pass" yaml:"pass"`
 | 
						Pass       string       `json:"pass" toml:"pass" xml:"pass" yaml:"pass"`
 | 
				
			||||||
	URL        string       `json:"url" toml:"url" xml:"url" yaml:"url"`
 | 
						URL        string       `json:"url" toml:"url" xml:"url" yaml:"url"`
 | 
				
			||||||
	Sites      []string     `json:"sites,omitempty" toml:"sites,omitempty" xml:"site" yaml:"sites"`
 | 
						Sites      []string     `json:"sites" toml:"sites" xml:"site" yaml:"sites"`
 | 
				
			||||||
	Unifi      *unifi.Unifi `json:"-" toml:"-" xml:"-" yaml:"-"`
 | 
						Unifi      *unifi.Unifi `json:"-" toml:"-" xml:"-" yaml:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,6 +59,7 @@ type Config struct {
 | 
				
			||||||
	Controllers  []*Controller `json:"controllers" toml:"controller" xml:"controller" yaml:"controllers"`
 | 
						Controllers  []*Controller `json:"controllers" toml:"controller" xml:"controller" yaml:"controllers"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Metrics is simply a useful container for everything.
 | 
				
			||||||
type Metrics struct {
 | 
					type Metrics struct {
 | 
				
			||||||
	TS         time.Time
 | 
						TS         time.Time
 | 
				
			||||||
	Sites      []*unifi.Site
 | 
						Sites      []*unifi.Site
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ import (
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
	"github.com/unifi-poller/poller"
 | 
						"github.com/unifi-poller/poller"
 | 
				
			||||||
	"github.com/unifi-poller/unifi"
 | 
						"github.com/unifi-poller/unifi"
 | 
				
			||||||
 | 
						"github.com/unifi-poller/webserver"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
| 
						 | 
					@ -53,6 +54,8 @@ func (u *InputUnifi) Initialize(l poller.Logger) error {
 | 
				
			||||||
		u.logController(c)
 | 
							u.logController(c)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						webserver.UpdateInput(&webserver.Input{Name: PluginName, Config: formatConfig(u.Config)})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,185 @@
 | 
				
			||||||
 | 
					package inputunifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/unifi-poller/unifi"
 | 
				
			||||||
 | 
						"github.com/unifi-poller/webserver"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This code reformats our data to be displayed on the built-in web interface. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func updateWeb(metrics *Metrics) {
 | 
				
			||||||
 | 
						webserver.UpdateInput(&webserver.Input{
 | 
				
			||||||
 | 
							Sites:   formatSites(metrics.Sites),
 | 
				
			||||||
 | 
							Clients: formatClients(metrics.Clients),
 | 
				
			||||||
 | 
							Devices: formatDevices(metrics.Devices),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func formatConfig(config *Config) *Config {
 | 
				
			||||||
 | 
						return &Config{
 | 
				
			||||||
 | 
							Default:     *formatControllers([]*Controller{&config.Default})[0],
 | 
				
			||||||
 | 
							Disable:     config.Disable,
 | 
				
			||||||
 | 
							Dynamic:     config.Dynamic,
 | 
				
			||||||
 | 
							Controllers: formatControllers(config.Controllers),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func formatControllers(controllers []*Controller) []*Controller {
 | 
				
			||||||
 | 
						fixed := []*Controller{}
 | 
				
			||||||
 | 
						for _, c := range controllers {
 | 
				
			||||||
 | 
							fixed = append(fixed, &Controller{
 | 
				
			||||||
 | 
								VerifySSL:  c.VerifySSL,
 | 
				
			||||||
 | 
								SaveAnomal: c.SaveAnomal,
 | 
				
			||||||
 | 
								SaveAlarms: c.SaveAlarms,
 | 
				
			||||||
 | 
								SaveEvents: c.SaveEvents,
 | 
				
			||||||
 | 
								SaveIDS:    c.SaveIDS,
 | 
				
			||||||
 | 
								SaveDPI:    c.SaveDPI,
 | 
				
			||||||
 | 
								HashPII:    c.HashPII,
 | 
				
			||||||
 | 
								SaveSites:  c.SaveSites,
 | 
				
			||||||
 | 
								User:       c.User,
 | 
				
			||||||
 | 
								Pass:       strconv.FormatBool(c.Pass != ""),
 | 
				
			||||||
 | 
								URL:        c.URL,
 | 
				
			||||||
 | 
								Sites:      c.Sites,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fixed
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func formatSites(sites []*unifi.Site) (s webserver.Sites) {
 | 
				
			||||||
 | 
						for _, site := range sites {
 | 
				
			||||||
 | 
							s = append(s, &webserver.Site{
 | 
				
			||||||
 | 
								ID:     site.ID,
 | 
				
			||||||
 | 
								Name:   site.Name,
 | 
				
			||||||
 | 
								Desc:   site.Desc,
 | 
				
			||||||
 | 
								Source: site.SourceName,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func formatClients(clients []*unifi.Client) (c webserver.Clients) {
 | 
				
			||||||
 | 
						for _, client := range clients {
 | 
				
			||||||
 | 
							clientType, deviceMAC := "unknown", "unknown"
 | 
				
			||||||
 | 
							if client.ApMac != "" {
 | 
				
			||||||
 | 
								clientType = "wireless"
 | 
				
			||||||
 | 
								deviceMAC = client.ApMac
 | 
				
			||||||
 | 
							} else if client.SwMac != "" {
 | 
				
			||||||
 | 
								clientType = "wired"
 | 
				
			||||||
 | 
								deviceMAC = client.SwMac
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if deviceMAC == "" {
 | 
				
			||||||
 | 
								deviceMAC = client.GwMac
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							c = append(c, &webserver.Client{
 | 
				
			||||||
 | 
								Name:      client.Name,
 | 
				
			||||||
 | 
								SiteID:    client.SiteID,
 | 
				
			||||||
 | 
								Source:    client.SourceName,
 | 
				
			||||||
 | 
								MAC:       client.Mac,
 | 
				
			||||||
 | 
								IP:        client.IP,
 | 
				
			||||||
 | 
								Type:      clientType,
 | 
				
			||||||
 | 
								DeviceMAC: deviceMAC,
 | 
				
			||||||
 | 
								Since:     time.Unix(client.FirstSeen, 0),
 | 
				
			||||||
 | 
								Last:      time.Unix(client.LastSeen, 0),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func formatDevices(devices *unifi.Devices) (d webserver.Devices) {
 | 
				
			||||||
 | 
						for _, device := range devices.UAPs {
 | 
				
			||||||
 | 
							d = append(d, &webserver.Device{
 | 
				
			||||||
 | 
								Name:    device.Name,
 | 
				
			||||||
 | 
								SiteID:  device.SiteID,
 | 
				
			||||||
 | 
								Source:  device.SourceName,
 | 
				
			||||||
 | 
								MAC:     device.Mac,
 | 
				
			||||||
 | 
								IP:      device.IP,
 | 
				
			||||||
 | 
								Type:    device.Type,
 | 
				
			||||||
 | 
								Model:   device.Model,
 | 
				
			||||||
 | 
								Version: device.Version,
 | 
				
			||||||
 | 
								Config:  nil,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, device := range devices.UDMs {
 | 
				
			||||||
 | 
							d = append(d, &webserver.Device{
 | 
				
			||||||
 | 
								Name:    device.Name,
 | 
				
			||||||
 | 
								SiteID:  device.SiteID,
 | 
				
			||||||
 | 
								Source:  device.SourceName,
 | 
				
			||||||
 | 
								MAC:     device.Mac,
 | 
				
			||||||
 | 
								IP:      device.IP,
 | 
				
			||||||
 | 
								Type:    device.Type,
 | 
				
			||||||
 | 
								Model:   device.Model,
 | 
				
			||||||
 | 
								Version: device.Version,
 | 
				
			||||||
 | 
								Config:  nil,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, device := range devices.USWs {
 | 
				
			||||||
 | 
							d = append(d, &webserver.Device{
 | 
				
			||||||
 | 
								Name:    device.Name,
 | 
				
			||||||
 | 
								SiteID:  device.SiteID,
 | 
				
			||||||
 | 
								Source:  device.SourceName,
 | 
				
			||||||
 | 
								MAC:     device.Mac,
 | 
				
			||||||
 | 
								IP:      device.IP,
 | 
				
			||||||
 | 
								Type:    device.Type,
 | 
				
			||||||
 | 
								Model:   device.Model,
 | 
				
			||||||
 | 
								Version: device.Version,
 | 
				
			||||||
 | 
								Config:  nil,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, device := range devices.USGs {
 | 
				
			||||||
 | 
							d = append(d, &webserver.Device{
 | 
				
			||||||
 | 
								Name:    device.Name,
 | 
				
			||||||
 | 
								SiteID:  device.SiteID,
 | 
				
			||||||
 | 
								Source:  device.SourceName,
 | 
				
			||||||
 | 
								MAC:     device.Mac,
 | 
				
			||||||
 | 
								IP:      device.IP,
 | 
				
			||||||
 | 
								Type:    device.Type,
 | 
				
			||||||
 | 
								Model:   device.Model,
 | 
				
			||||||
 | 
								Version: device.Version,
 | 
				
			||||||
 | 
								Config:  nil,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return d
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Logf logs a message.
 | 
				
			||||||
 | 
					func (u *InputUnifi) Logf(msg string, v ...interface{}) {
 | 
				
			||||||
 | 
						webserver.NewInputEvent(PluginName, PluginName, &webserver.Event{
 | 
				
			||||||
 | 
							Ts:   time.Now(),
 | 
				
			||||||
 | 
							Msg:  fmt.Sprintf(msg, v...),
 | 
				
			||||||
 | 
							Tags: map[string]string{"type": "info"},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						u.Logger.Logf(msg, v...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LogErrorf logs an error message.
 | 
				
			||||||
 | 
					func (u *InputUnifi) LogErrorf(msg string, v ...interface{}) {
 | 
				
			||||||
 | 
						webserver.NewInputEvent(PluginName, PluginName, &webserver.Event{
 | 
				
			||||||
 | 
							Ts:   time.Now(),
 | 
				
			||||||
 | 
							Msg:  fmt.Sprintf(msg, v...),
 | 
				
			||||||
 | 
							Tags: map[string]string{"type": "error"},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						u.Logger.LogErrorf(msg, v...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LogDebugf logs a debug message.
 | 
				
			||||||
 | 
					func (u *InputUnifi) LogDebugf(msg string, v ...interface{}) {
 | 
				
			||||||
 | 
						webserver.NewInputEvent(PluginName, PluginName, &webserver.Event{
 | 
				
			||||||
 | 
							Ts:   time.Now(),
 | 
				
			||||||
 | 
							Msg:  fmt.Sprintf(msg, v...),
 | 
				
			||||||
 | 
							Tags: map[string]string{"type": "debug"},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						u.Logger.LogDebugf(msg, v...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue