Allow environment variable configuration

This commit is contained in:
David Newhall II 2019-08-25 20:00:27 -07:00
parent f328750dca
commit d3b5c56a61
4 changed files with 80 additions and 4 deletions

View File

@ -22,6 +22,27 @@ const (
defaultUnifURL = "https://127.0.0.1:8443" 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. // UnifiPoller contains the application startup data, and auth info for UniFi & Influx.
type UnifiPoller struct { type UnifiPoller struct {
Influx influx.Client Influx influx.Client

View File

@ -20,7 +20,8 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) {
if err != nil { if err != nil {
return err 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 { if err := u.CheckSites(); err != nil {
return err return err
} }
@ -46,7 +47,8 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) {
func (u *UnifiPoller) dumpSitesJSON(path, name string, sites unifi.Sites) error { func (u *UnifiPoller) dumpSitesJSON(path, name string, sites unifi.Sites) error {
for _, s := range sites { for _, s := range sites {
apiPath := fmt.Sprintf(path, s.Name) 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 { if err := u.PrintRawAPIJSON(apiPath); err != nil {
return err return err
} }

View File

@ -43,3 +43,26 @@ func (u *UnifiPoller) LogDebugf(m string, v ...interface{}) {
func (u *UnifiPoller) LogErrorf(m string, v ...interface{}) { func (u *UnifiPoller) LogErrorf(m string, v ...interface{}) {
_ = log.Output(2, fmt.Sprintf("[ERROR] "+m, v...)) _ = 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
}
}

View File

@ -7,6 +7,7 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
@ -48,6 +49,34 @@ func (f *Flag) Parse(args []string) {
_ = f.FlagSet.Parse(args) _ = 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. // GetConfig parses and returns our configuration data.
func (u *UnifiPoller) GetConfig() error { func (u *UnifiPoller) GetConfig() error {
// Preload our defaults. // Preload our defaults.
@ -57,13 +86,14 @@ func (u *UnifiPoller) GetConfig() error {
InfluxPass: defaultInfxPass, InfluxPass: defaultInfxPass,
InfluxDB: defaultInfxDb, InfluxDB: defaultInfxDb,
UnifiUser: defaultUnifUser, UnifiUser: defaultUnifUser,
UnifiPass: os.Getenv("UNIFI_PASSWORD"), UnifiPass: os.Getenv("UNIFI_PASSWORD"), // deprecated name.
UnifiBase: defaultUnifURL, UnifiBase: defaultUnifURL,
Interval: Duration{defaultInterval}, Interval: Duration{defaultInterval},
Sites: []string{"default"}, 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) 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); { switch buf, err := ioutil.ReadFile(u.Flag.ConfigFile); {
case err != nil: case err != nil:
return err return err