Merge pull request #102 from davidnewhall/dn2_updates

Add reauth feature, remove errors library.
This commit is contained in:
David Newhall II 2019-08-25 13:24:15 -07:00 committed by GitHub
commit 99768a66c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 83 additions and 56 deletions

9
Gopkg.lock generated
View File

@ -21,14 +21,6 @@
pruneopts = "UT" pruneopts = "UT"
revision = "fc22c7df067eefd070157f157893fbce961d6359" revision = "fc22c7df067eefd070157f157893fbce961d6359"
[[projects]]
digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b"
name = "github.com/pkg/errors"
packages = ["."]
pruneopts = "UT"
revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
version = "v0.8.1"
[[projects]] [[projects]]
digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2" digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2"
name = "github.com/spf13/pflag" name = "github.com/spf13/pflag"
@ -59,7 +51,6 @@
input-imports = [ input-imports = [
"github.com/BurntSushi/toml", "github.com/BurntSushi/toml",
"github.com/influxdata/influxdb1-client/v2", "github.com/influxdata/influxdb1-client/v2",
"github.com/pkg/errors",
"github.com/spf13/pflag", "github.com/spf13/pflag",
"golift.io/unifi", "golift.io/unifi",
"gopkg.in/yaml.v2", "gopkg.in/yaml.v2",

View File

@ -147,6 +147,12 @@ is provided so the application can be easily adapted to any environment.
by default because most controllers do not have this enabled. It also by default because most controllers do not have this enabled. It also
creates a lot of new metrics from controllers with a lot of IDS entries. creates a lot of new metrics from controllers with a lot of IDS entries.
reauthenticate default: false
Setting this parameter to true will make UniFi Poller send a new login
request on every interval. This generates a new cookie. Some controller
or reverse proxy configurations require this. Do not enable it unless
your configuration causes the poller to be logged out after some time.
verify_ssl default: false verify_ssl default: false
If your UniFi controller has a valid SSL certificate, you can enable If your UniFi controller has a valid SSL certificate, you can enable
this option to validate it. Otherwise, any SSL certificate is valid. this option to validate it. Otherwise, any SSL certificate is valid.

View File

@ -5,20 +5,20 @@
# If the controller has more than one site, specify which sites to poll here. # If the controller has more than one site, specify which sites to poll here.
# Set this to ["default"] to poll only the first site on the controller. # Set this to ["default"] to poll only the first site on the controller.
# A setting of ["all"] will poll all sites; this works if you only have 1 site too. # A setting of ["all"] will poll all sites; this works if you only have 1 site too.
#sites = ["all"] sites = ["all"]
# The UniFi Controller only updates traffic stats about every 30 seconds. # The UniFi Controller only updates traffic stats about every 30 seconds.
# Setting this to something lower may lead to "zeros" in your data. You've been warned. # Setting this to something lower may lead to "zeros" in your data. You've been warned.
#interval = "30s" interval = "30s"
# Turns on line numbers, microsecond logging, and a per-device log. # Turns on line numbers, microsecond logging, and a per-device log.
# The default is false, but I personally leave this on at home (four devices). # The default is false, but I personally leave this on at home (four devices).
# This may be noisy if you have a lot of devices. It adds one line per device. # This may be noisy if you have a lot of devices. It adds one line per device.
#debug = false debug = false
# Turns off per-interval logs. Only startup and error logs will be emitted. # Turns off per-interval logs. Only startup and error logs will be emitted.
# Recommend enabling debug with this setting for better error logging. # Recommend enabling debug with this setting for better error logging.
#quiet = false quiet = false
# Which mode to run this application in. The default mode is "influx". Providing # Which mode to run this application in. The default mode is "influx". Providing
# an invalid mode will also result in "influx". In this default mode the application # an invalid mode will also result in "influx". In this default mode the application
@ -29,32 +29,39 @@
# Lambda mode makes the application exit after collecting and reporting metrics # Lambda mode makes the application exit after collecting and reporting metrics
# to InfluxDB one time. This mode requires an external process like an AWS Lambda # to InfluxDB one time. This mode requires an external process like an AWS Lambda
# or a simple crontab to keep the timings accurate on UniFi Poller run intervals. # or a simple crontab to keep the timings accurate on UniFi Poller run intervals.
#mode = "influx" mode = "influx"
# If the poller experiences an error from the UniFi controller or from InfluxDB # If the poller experiences an error from the UniFi controller or from InfluxDB
# it will exit. If you do not want it to exit, change max_errors to -1. You can # it will exit. If you do not want it to exit, change max_errors to -1. You can
# adjust the config to tolerate more errors by setting this to a higher value. # adjust the config to tolerate more errors by setting this to a higher value.
# Recommend setting this between 0 and 5. See man page for more explanation. # Recommend setting this between 0 and 5. See man page for more explanation.
#max_errors = 0 max_errors = 0
# InfluxDB does not require auth by default, so the user/password are probably unimportant. # InfluxDB does not require auth by default, so the user/password are probably unimportant.
#influx_url = "http://127.0.0.1:8086" influx_url = "http://127.0.0.1:8086"
#influx_user = "unifi" influx_user = "unifi"
#influx_pass = "unifi" influx_pass = "unifi"
# Be sure to create this database. # Be sure to create this database.
#influx_db = "unifi" influx_db = "unifi"
# Make a read-only user in the UniFi Admin Settings. # Make a read-only user in the UniFi Admin Settings.
#unifi_user = "influxdb" unifi_user = "influxdb"
# You may also set env variable UNIFI_PASSWORD instead of putting this in the config. # You may also set env variable UNIFI_PASSWORD instead of putting this in the config.
unifi_pass = "4BB9345C-2341-48D7-99F5-E01B583FF77F" unifi_pass = "4BB9345C-2341-48D7-99F5-E01B583FF77F"
#unifi_url = "https://127.0.0.1:8443" unifi_url = "https://127.0.0.1:8443"
# Enable collection of Intrusion Detection System Data. # Enable collection of Intrusion Detection System Data.
# Only useful if IDS or IPS are enabled on one of the sites. # Only useful if IDS or IPS are enabled on one of the sites.
#collect_ids = false collect_ids = false
# If your UniFi controller has a valid SSL certificate, you can enable # Some controllers or reverse proxy configurations do not allow cookies to be
# this option to validate it. Otherwise, any SSL certificate is valid. # re-user on every request (every interval). This setting provides a workaround
# If you don't know if you have a valid SSL cert, then you don't have one. # That causes the poller to re-auth (login) to the controller on every interval.
#verify_ssl = false # Only enable this if you get login errors after 30 seconds. This will generate
# a few more requests to your controller every interval.
reauthenticate = false
# If your UniFi controller has a valid SSL certificate (like lets encrypt),
# you can enable this option to validate it. Otherwise, any SSL certificate is
# valid. If you don't know if you have a valid SSL cert, then you don't have one.
verify_ssl = false

View File

@ -13,5 +13,6 @@
"unifi_pass": "", "unifi_pass": "",
"unifi_url": "https://127.0.0.1:8443", "unifi_url": "https://127.0.0.1:8443",
"collect_ids": false, "collect_ids": false,
"reauthenticate": false,
"verify_ssl": false "verify_ssl": false
} }

View File

@ -77,6 +77,14 @@
--> -->
<collect_ids>false</collect_ids> <collect_ids>false</collect_ids>
<!-- <!--
# Some controllers or reverse proxy configurations do not allow cookies to be
# re-user on every request (every interval). This setting provides a workaround
# That causes the poller to re-auth (login) to the controller on every interval.
# Only enable this if you get login errors after 30 seconds. This will generate
# a few more requests to your controller every interval.
-->
<reauthenticate>false</reauthenticate>
<!--
# If your UniFi controller has a valid SSL certificate, you can enable # If your UniFi controller has a valid SSL certificate, you can enable
# this option to validate it. Otherwise, any SSL certificate is valid. # this option to validate it. Otherwise, any SSL certificate is valid.
--> -->

View File

@ -54,6 +54,13 @@ unifi_url: "https://127.0.0.1:8443"
# Only useful if IDS or IPS are enabled on one of the sites. # Only useful if IDS or IPS are enabled on one of the sites.
collect_ids: false collect_ids: false
# Some controllers or reverse proxy configurations do not allow cookies to be
# re-user on every request (every interval). This setting provides a workaround
# That causes the poller to re-auth (login) to the controller on every interval.
# Only enable this if you get login errors after 30 seconds. This will generate
# a few more requests to your controller every interval.
reauthenticate: false
# If your UniFi controller has a valid SSL certificate, you can enable # If your UniFi controller has a valid SSL certificate, you can enable
# this option to validate it. Otherwise, any SSL certificate is valid. # this option to validate it. Otherwise, any SSL certificate is valid.
verify_ssl: false verify_ssl: false

View File

@ -60,6 +60,7 @@ type Config struct {
Quiet bool `json:"quiet,_omitempty" toml:"quiet,_omitempty" xml:"quiet" yaml:"quiet"` Quiet bool `json:"quiet,_omitempty" toml:"quiet,_omitempty" xml:"quiet" yaml:"quiet"`
VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"` VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"`
CollectIDS bool `json:"collect_ids" toml:"collect_ids" xml:"collect_ids" yaml:"collect_ids"` CollectIDS bool `json:"collect_ids" toml:"collect_ids" xml:"collect_ids" yaml:"collect_ids"`
ReAuth bool `json:"reauthenticate" toml:"reauthenticate" xml:"reauthenticate" yaml:"reauthenticate"`
Mode string `json:"mode" toml:"mode" xml:"mode" yaml:"mode"` Mode string `json:"mode" toml:"mode" xml:"mode" yaml:"mode"`
InfluxURL string `json:"influx_url,_omitempty" toml:"influx_url,_omitempty" xml:"influx_url" yaml:"influx_url"` InfluxURL string `json:"influx_url,_omitempty" toml:"influx_url,_omitempty" xml:"influx_url" yaml:"influx_url"`
InfluxUser string `json:"influx_user,_omitempty" toml:"influx_user,_omitempty" xml:"influx_user" yaml:"influx_user"` InfluxUser string `json:"influx_user,_omitempty" toml:"influx_user,_omitempty" xml:"influx_user" yaml:"influx_user"`

View File

@ -5,7 +5,6 @@ import (
"os" "os"
"strings" "strings"
"github.com/pkg/errors"
"golift.io/unifi" "golift.io/unifi"
) )
@ -35,7 +34,7 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) {
_, _ = fmt.Fprintf(os.Stderr, "[INFO] Dumping Path '%s':\n", apiPath) _, _ = fmt.Fprintf(os.Stderr, "[INFO] Dumping Path '%s':\n", apiPath)
return u.PrintRawAPIJSON(apiPath) return u.PrintRawAPIJSON(apiPath)
default: default:
return errors.New("must provide filter: devices, clients, other") return fmt.Errorf("must provide filter: devices, clients, other")
} }
} }

View File

@ -12,10 +12,9 @@ import (
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
influx "github.com/influxdata/influxdb1-client/v2" influx "github.com/influxdata/influxdb1-client/v2"
"github.com/pkg/errors" "github.com/spf13/pflag"
flag "github.com/spf13/pflag"
"golift.io/unifi" "golift.io/unifi"
yaml "gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
// Start begins the application from a CLI. // Start begins the application from a CLI.
@ -36,7 +35,7 @@ func Start() error {
// ParseFlags runs the parser. // ParseFlags runs the parser.
func (u *UnifiPoller) ParseFlags(args []string) { func (u *UnifiPoller) ParseFlags(args []string) {
u.Flag = flag.NewFlagSet("unifi-poller", flag.ExitOnError) u.Flag = pflag.NewFlagSet("unifi-poller", pflag.ExitOnError)
u.Flag.Usage = func() { u.Flag.Usage = func() {
fmt.Println("Usage: unifi-poller [--config=filepath] [--version]") fmt.Println("Usage: unifi-poller [--config=filepath] [--version]")
u.Flag.PrintDefaults() u.Flag.PrintDefaults()
@ -91,9 +90,11 @@ func (u *UnifiPoller) Run() (err error) {
if err = u.GetUnifi(); err != nil { if err = u.GetUnifi(); err != nil {
return err return err
} }
u.Logf("Polling UniFi Controller at %s v%s as user %s. Sites: %v", u.UnifiBase, u.ServerVersion, u.UnifiUser, u.Sites)
if err = u.GetInfluxDB(); err != nil { if err = u.GetInfluxDB(); err != nil {
return err return err
} }
u.Logf("Logging Measurements to InfluxDB at %s as user %s", u.InfluxURL, u.InfluxUser)
switch strings.ToLower(u.Mode) { switch strings.ToLower(u.Mode) {
case "influxlambda", "lambdainflux", "lambda_influx", "influx_lambda": case "influxlambda", "lambdainflux", "lambda_influx", "influx_lambda":
u.LogDebugf("Lambda Mode Enabled") u.LogDebugf("Lambda Mode Enabled")
@ -112,9 +113,8 @@ func (u *UnifiPoller) GetInfluxDB() (err error) {
Password: u.InfluxPass, Password: u.InfluxPass,
}) })
if err != nil { if err != nil {
return errors.Wrap(err, "influxdb") return fmt.Errorf("influxdb: %v", err)
} }
u.Logf("Logging Measurements to InfluxDB at %s as user %s", u.InfluxURL, u.InfluxUser)
return nil return nil
} }
@ -123,14 +123,12 @@ func (u *UnifiPoller) GetUnifi() (err error) {
// Create an authenticated session to the Unifi Controller. // Create an authenticated session to the Unifi Controller.
u.Unifi, err = unifi.NewUnifi(u.UnifiUser, u.UnifiPass, u.UnifiBase, u.VerifySSL) u.Unifi, err = unifi.NewUnifi(u.UnifiUser, u.UnifiPass, u.UnifiBase, u.VerifySSL)
if err != nil { if err != nil {
return errors.Wrap(err, "unifi controller") return fmt.Errorf("unifi controller: %v", err)
} }
u.Unifi.ErrorLog = u.LogErrorf // Log all errors. u.Unifi.ErrorLog = u.LogErrorf // Log all errors.
u.Unifi.DebugLog = u.LogDebugf // Log debug messages. u.Unifi.DebugLog = u.LogDebugf // Log debug messages.
u.Logf("Authenticated to UniFi Controller at %s version %s as user %s", u.UnifiBase, u.ServerVersion, u.UnifiUser)
if err := u.CheckSites(); err != nil { if err := u.CheckSites(); err != nil {
return err return err
} }
u.Logf("Polling UniFi Controller Sites: %v", u.Sites)
return nil return nil
} }

View File

@ -7,7 +7,6 @@ import (
"time" "time"
influx "github.com/influxdata/influxdb1-client/v2" influx "github.com/influxdata/influxdb1-client/v2"
"github.com/pkg/errors"
"golift.io/unifi" "golift.io/unifi"
) )
@ -49,9 +48,19 @@ func (u *UnifiPoller) PollController() error {
log.Println("[INFO] Everything checks out! Poller started, interval:", u.Interval.Round(time.Second)) log.Println("[INFO] Everything checks out! Poller started, interval:", u.Interval.Round(time.Second))
ticker := time.NewTicker(u.Interval.Round(time.Second)) ticker := time.NewTicker(u.Interval.Round(time.Second))
for u.LastCheck = range ticker.C { for u.LastCheck = range ticker.C {
var err error
if u.ReAuth {
// Some users need to re-auth every interval because the cookie times out.
if err = u.GetUnifi(); err != nil {
u.LogError(err, "re-authenticating")
}
}
if err == nil {
// Only run this if the authentication procedure didn't return error.
_ = u.CollectAndReport() _ = u.CollectAndReport()
}
if u.MaxErrors >= 0 && u.errorCount > u.MaxErrors { if u.MaxErrors >= 0 && u.errorCount > u.MaxErrors {
return errors.Errorf("reached maximum error count, stopping poller (%d > %d)", u.errorCount, u.MaxErrors) return fmt.Errorf("reached maximum error count, stopping poller (%d > %d)", u.errorCount, u.MaxErrors)
} }
} }
return nil return nil
@ -131,7 +140,7 @@ func (u *UnifiPoller) ReportMetrics(metrics *Metrics) error {
} }
err := u.Write(metrics.BatchPoints) err := u.Write(metrics.BatchPoints)
if err != nil { if err != nil {
return errors.Wrap(err, "influxdb.Write(points)") return fmt.Errorf("influxdb.Write(points): %v", err)
} }
var fields, points int var fields, points int
for _, p := range metrics.Points() { for _, p := range metrics.Points() {