159 lines
3.9 KiB
Go
159 lines
3.9 KiB
Go
package inputunifi
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/unpoller/unifi"
|
|
"github.com/unpoller/unpoller/pkg/webserver"
|
|
)
|
|
|
|
/* Event collection. Events are also sent to the webserver for display. */
|
|
|
|
func (u *InputUnifi) collectControllerEvents(c *Controller) ([]any, error) {
|
|
if u.isNill(c) {
|
|
u.Logf("Re-authenticating to UniFi Controller: %s", c.URL)
|
|
|
|
if err := u.getUnifi(c); err != nil {
|
|
return nil, fmt.Errorf("re-authenticating to %s: %w", c.URL, err)
|
|
}
|
|
}
|
|
|
|
var (
|
|
logs = []any{}
|
|
newLogs []any
|
|
)
|
|
|
|
// Get the sites we care about.
|
|
sites, err := u.getFilteredSites(c)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unifi.GetSites(): %w", err)
|
|
}
|
|
|
|
type caller func([]any, []*unifi.Site, *Controller) ([]any, 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 []any, sites []*unifi.Site, c *Controller) ([]any, error) {
|
|
if *c.SaveAlarms {
|
|
for _, s := range sites {
|
|
events, err := c.Unifi.GetAlarmsSite(s)
|
|
if err != nil {
|
|
return logs, fmt.Errorf("unifi.GetAlarms(): %w", err)
|
|
}
|
|
|
|
for _, e := range events {
|
|
logs = append(logs, e)
|
|
|
|
webserver.NewInputEvent(PluginName, s.ID+"_alarms", &webserver.Event{
|
|
Ts: e.Datetime, Msg: e.Msg, Tags: map[string]string{
|
|
"type": "alarm", "key": e.Key, "site_id": e.SiteID,
|
|
"site_name": e.SiteName, "source": e.SourceName,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return logs, nil
|
|
}
|
|
|
|
func (u *InputUnifi) collectAnomalies(logs []any, sites []*unifi.Site, c *Controller) ([]any, error) {
|
|
if *c.SaveAnomal {
|
|
for _, s := range sites {
|
|
events, err := c.Unifi.GetAnomaliesSite(s)
|
|
if err != nil {
|
|
return logs, fmt.Errorf("unifi.GetAnomalies(): %w", err)
|
|
}
|
|
|
|
for _, e := range events {
|
|
logs = append(logs, e)
|
|
|
|
webserver.NewInputEvent(PluginName, s.ID+"_anomalies", &webserver.Event{
|
|
Ts: e.Datetime, Msg: e.Anomaly, Tags: map[string]string{
|
|
"type": "anomaly", "site_name": e.SiteName, "source": e.SourceName,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return logs, nil
|
|
}
|
|
|
|
func (u *InputUnifi) collectEvents(logs []any, sites []*unifi.Site, c *Controller) ([]any, error) {
|
|
if *c.SaveEvents {
|
|
for _, s := range sites {
|
|
events, err := c.Unifi.GetSiteEvents(s, time.Hour)
|
|
if err != nil {
|
|
return logs, fmt.Errorf("unifi.GetEvents(): %w", err)
|
|
}
|
|
|
|
for _, e := range events {
|
|
e := redactEvent(e, c.HashPII)
|
|
logs = append(logs, e)
|
|
|
|
webserver.NewInputEvent(PluginName, s.ID+"_events", &webserver.Event{
|
|
Msg: e.Msg, Ts: e.Datetime, Tags: map[string]string{
|
|
"type": "event", "key": e.Key, "site_id": e.SiteID,
|
|
"site_name": e.SiteName, "source": e.SourceName,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return logs, nil
|
|
}
|
|
|
|
func (u *InputUnifi) collectIDS(logs []any, sites []*unifi.Site, c *Controller) ([]any, error) {
|
|
if *c.SaveIDS {
|
|
for _, s := range sites {
|
|
events, err := c.Unifi.GetIDSSite(s)
|
|
if err != nil {
|
|
return logs, fmt.Errorf("unifi.GetIDS(): %w", err)
|
|
}
|
|
|
|
for _, e := range events {
|
|
logs = append(logs, e)
|
|
|
|
webserver.NewInputEvent(PluginName, s.ID+"_ids", &webserver.Event{
|
|
Ts: e.Datetime, Msg: e.Msg, Tags: map[string]string{
|
|
"type": "ids", "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
|
|
}
|