From d3b5c56a614f930c70d7f16c9828e4440d06ddb5 Mon Sep 17 00:00:00 2001 From: David Newhall II Date: Sun, 25 Aug 2019 20:00:27 -0700 Subject: [PATCH] Allow environment variable configuration --- integrations/inputunifi/unifipoller/config.go | 21 ++++++++++++ integrations/inputunifi/unifipoller/dumper.go | 6 ++-- .../inputunifi/unifipoller/helpers.go | 23 +++++++++++++ integrations/inputunifi/unifipoller/start.go | 34 +++++++++++++++++-- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/integrations/inputunifi/unifipoller/config.go b/integrations/inputunifi/unifipoller/config.go index 39eac38e..4e097b33 100644 --- a/integrations/inputunifi/unifipoller/config.go +++ b/integrations/inputunifi/unifipoller/config.go @@ -22,6 +22,27 @@ const ( defaultUnifURL = "https://127.0.0.1:8443" ) +// These are environment variables that can be used to override configuration. +// Useful for Docker users. +const ( + ENVConfigMode = "UP_POLLING_MODE" + ENVConfigInfluxDB = "UP_INFLUX_DB" + ENVConfigInfluxUser = "UP_INFLUX_USER" + ENVConfigInfluxPass = "UP_INFLUX_PASS" + ENVConfigInfluxURL = "UP_INFLUX_URL" + ENVConfigUnifiUser = "UP_UNIFI_USER" + ENVConfigUnifiPass = "UP_UNIFI_PASS" + ENVConfigUnifiBase = "UP_UNIFI_URL" + ENVConfigReAuth = "UP_REAUTHENTICATE" + ENVConfigVerifySSL = "UP_VERIFY_SSL" + ENVConfigCollectIDS = "UP_COLLECT_IDS" + ENVConfigQuiet = "UP_QUIET_MODE" + ENVConfigDebug = "UP_DEBUG_MODE" + ENVConfigInterval = "UP_POLLING_INTERVAL" + ENVConfigMaxErrors = "UP_MAX_ERRORS" + ENVConfigSites = "UP_POLL_SITES" +) + // UnifiPoller contains the application startup data, and auth info for UniFi & Influx. type UnifiPoller struct { Influx influx.Client diff --git a/integrations/inputunifi/unifipoller/dumper.go b/integrations/inputunifi/unifipoller/dumper.go index ae110ceb..01d821ef 100644 --- a/integrations/inputunifi/unifipoller/dumper.go +++ b/integrations/inputunifi/unifipoller/dumper.go @@ -20,7 +20,8 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) { if err != nil { return err } - fmt.Fprintln(os.Stderr, "[INFO] Authenticated to UniFi Controller @", u.Config.UnifiBase, "as user", u.Config.UnifiUser) + fmt.Fprintf(os.Stderr, "[INFO] Authenticated to UniFi Controller @ %v as user %v", + u.Config.UnifiBase, u.Config.UnifiUser) if err := u.CheckSites(); err != nil { return err } @@ -46,7 +47,8 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) { func (u *UnifiPoller) dumpSitesJSON(path, name string, sites unifi.Sites) error { for _, s := range sites { apiPath := fmt.Sprintf(path, s.Name) - _, _ = fmt.Fprintf(os.Stderr, "[INFO] Dumping %s: '%s' JSON for site: %s (%s):\n", name, apiPath, s.Desc, s.Name) + _, _ = fmt.Fprintf(os.Stderr, "[INFO] Dumping %s: '%s' JSON for site: %s (%s):\n", + name, apiPath, s.Desc, s.Name) if err := u.PrintRawAPIJSON(apiPath); err != nil { return err } diff --git a/integrations/inputunifi/unifipoller/helpers.go b/integrations/inputunifi/unifipoller/helpers.go index c2e0fce4..5cb2041d 100644 --- a/integrations/inputunifi/unifipoller/helpers.go +++ b/integrations/inputunifi/unifipoller/helpers.go @@ -43,3 +43,26 @@ func (u *UnifiPoller) LogDebugf(m string, v ...interface{}) { func (u *UnifiPoller) LogErrorf(m string, v ...interface{}) { _ = log.Output(2, fmt.Sprintf("[ERROR] "+m, v...)) } + +// pick returns the first non empty string in a list. +// used in a few places around this library. +func pick(strings ...string) string { + for _, s := range strings { + if s != "" { + return s + } + } + return "" +} + +// parseBool returns true/false if the string is "true" or "false", otherwise returns e value. +func parseBool(s string, e bool) bool { + switch s { + case "true", "t": + return true + case "false", "f": + return false + default: + return e + } +} diff --git a/integrations/inputunifi/unifipoller/start.go b/integrations/inputunifi/unifipoller/start.go index 145f1521..a16f105f 100644 --- a/integrations/inputunifi/unifipoller/start.go +++ b/integrations/inputunifi/unifipoller/start.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "log" "os" + "strconv" "strings" "time" @@ -48,6 +49,34 @@ func (f *Flag) Parse(args []string) { _ = f.FlagSet.Parse(args) } +// setEnvVarOptions copies environment variables into configuration values. +// This is useful for Docker users that find it easier to pass ENV variables +// that a specific configuration file. +func (u *UnifiPoller) setEnvVarOptions() { + u.Config.Mode = pick(os.Getenv(ENVConfigMode), u.Config.Mode) + u.Config.InfluxDB = pick(os.Getenv(ENVConfigInfluxDB), u.Config.InfluxDB) + u.Config.InfluxUser = pick(os.Getenv(ENVConfigInfluxUser), u.Config.InfluxUser) + u.Config.InfluxPass = pick(os.Getenv(ENVConfigInfluxPass), u.Config.InfluxPass) + u.Config.InfluxURL = pick(os.Getenv(ENVConfigInfluxURL), u.Config.InfluxURL) + u.Config.UnifiUser = pick(os.Getenv(ENVConfigUnifiUser), u.Config.UnifiUser) + u.Config.UnifiPass = pick(os.Getenv(ENVConfigUnifiPass), u.Config.UnifiPass) + u.Config.UnifiBase = pick(os.Getenv(ENVConfigUnifiBase), u.Config.UnifiBase) + u.Config.ReAuth = parseBool(os.Getenv(ENVConfigReAuth), u.Config.ReAuth) + u.Config.VerifySSL = parseBool(os.Getenv(ENVConfigVerifySSL), u.Config.VerifySSL) + u.Config.CollectIDS = parseBool(os.Getenv(ENVConfigCollectIDS), u.Config.CollectIDS) + u.Config.Quiet = parseBool(os.Getenv(ENVConfigQuiet), u.Config.Quiet) + u.Config.Debug = parseBool(os.Getenv(ENVConfigDebug), u.Config.Debug) + if e := os.Getenv(ENVConfigInterval); e != "" { + _ = u.Config.Interval.UnmarshalText([]byte(e)) + } + if e := os.Getenv(ENVConfigMaxErrors); e != "" { + u.Config.MaxErrors, _ = strconv.Atoi(e) + } + if e := os.Getenv(ENVConfigSites); e != "" { + u.Config.Sites = strings.Split(e, ",") + } +} + // GetConfig parses and returns our configuration data. func (u *UnifiPoller) GetConfig() error { // Preload our defaults. @@ -57,13 +86,14 @@ func (u *UnifiPoller) GetConfig() error { InfluxPass: defaultInfxPass, InfluxDB: defaultInfxDb, UnifiUser: defaultUnifUser, - UnifiPass: os.Getenv("UNIFI_PASSWORD"), + UnifiPass: os.Getenv("UNIFI_PASSWORD"), // deprecated name. UnifiBase: defaultUnifURL, Interval: Duration{defaultInterval}, Sites: []string{"default"}, - Quiet: u.Flag.DumpJSON != "", + Quiet: u.Flag.DumpJSON != "", //s uppress the following u.Logf line. } u.Logf("Loading Configuration File: %s", u.Flag.ConfigFile) + defer u.setEnvVarOptions() // Set env variable overrides when done here. switch buf, err := ioutil.ReadFile(u.Flag.ConfigFile); { case err != nil: return err