Use a config file instead of env vars.
This commit is contained in:
parent
74c64be507
commit
bb0e3ccfd8
17
.env.example
17
.env.example
|
|
@ -1,17 +0,0 @@
|
|||
UNIFI_ADDR="107.170.232.179"
|
||||
UNIFI_PORT="8443"
|
||||
# Go to Settings -> Admins and add (or use) a read-only user for this.
|
||||
UNIFI_USERNAME="username"
|
||||
UNIFI_PASSWORD="password"
|
||||
|
||||
# Can be 1m15s for 1 minute 0 seconds, 15s for 15 seconds, etc.
|
||||
INTERVAL="15s"
|
||||
|
||||
INFLUXDB_ADDR="http://hostname:8086"
|
||||
INFLUXDB_DATABASE="unifi"
|
||||
INFLUXDB_USERNAME="unifi"
|
||||
INFLUXDB_PASSWORD="password"
|
||||
|
||||
export UNIFI_ADDR UNIFI_PORT UNIFI_USERNAME UNIFI_PASSWORD
|
||||
export INTERVAL
|
||||
export INFLUXDB_ADDR INFLUXDB_DATABASE INFLUXDB_USERNAME INFLUXDB_PASSWORD
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
.env
|
||||
/up.conf
|
||||
/unifi-poller
|
||||
/*.1.gz
|
||||
/*.1
|
||||
|
|
|
|||
|
|
@ -21,6 +21,26 @@
|
|||
"Comment": "v1.5.0-149-g14dcc5d",
|
||||
"Rev": "14dcc5d6e7a6b15e17aba7b104b8ad0ca6c91ad2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/naoina/go-stringutil",
|
||||
"Comment": "v0.1.0",
|
||||
"Rev": "6b638e95a32d0c1131db0e7fe83775cbea4a0d0b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/naoina/toml",
|
||||
"Comment": "v0.1.0",
|
||||
"Rev": "751171607256bb66e64c9f0220c00662420c38e9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/naoina/toml/ast",
|
||||
"Comment": "v0.1.0",
|
||||
"Rev": "751171607256bb66e64c9f0220c00662420c38e9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ogier/pflag",
|
||||
"Comment": "v0.0.1-7-g45c278a",
|
||||
"Rev": "45c278ab3607870051a2ea9040bb85fcb8557481"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pkg/errors",
|
||||
"Comment": "v0.8.0-6-g2b3a18b",
|
||||
|
|
|
|||
16
README.md
16
README.md
|
|
@ -1,20 +1,12 @@
|
|||
# Unifi
|
||||
|
||||
Collect your Unifi Controller Client data and send it to an InfluxDB instance.
|
||||
Collect your Unifi Controller Client data and send it to an InfluxDB instance. Grafana dashboard included.
|
||||
|
||||

|
||||
|
||||
## Deploying
|
||||
## Installation
|
||||
|
||||
|
||||
Clone the repository and using `.env.example` create your own `.env` file with your Unifi GUI and InfluxDB credentials.
|
||||
|
||||
|
||||
Set your environment variables before running:
|
||||
|
||||
```
|
||||
source .env ; ./unifi-poller
|
||||
```
|
||||
[See the Wiki!](https://github.com/davidnewhall/unifi-poller/wiki/Installation)
|
||||
|
||||
## Copyright & License
|
||||
Copyright © 2016 Garrett Bjerkhoel. See [MIT-LICENSE](http://github.com/dewski/unifi/blob/master/MIT-LICENSE) for details.
|
||||
Copyright © 2016 Garrett Bjerkhoel. See [MIT-LICENSE](MIT-LICENSE) for details.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Version will be injected at build time.
|
||||
var Version = "v0.1"
|
||||
|
||||
const (
|
||||
// LoginPath is Unifi Controller Login API Path
|
||||
LoginPath = "/api/login"
|
||||
|
|
@ -17,6 +20,7 @@ const (
|
|||
// UserGroupPath contains usergroup configurations.
|
||||
UserGroupPath = "/api/s/default/rest/usergroup"
|
||||
// App defaults in case they're missing from the config.
|
||||
defaultConfFile = "/usr/local/etc/unifi-poller/up.conf"
|
||||
defaultInterval = 30 * time.Second
|
||||
defaultInfxDb = "unifi"
|
||||
defaultInfxUser = "unifi"
|
||||
|
|
@ -28,13 +32,28 @@ const (
|
|||
|
||||
// Config represents the data needed to poll a controller and report to influxdb.
|
||||
type Config struct {
|
||||
Interval time.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"`
|
||||
InfluxURL string `json:"influx_url" toml:"influx_addr" xml:"influx_addr" yaml:"influx_addr"`
|
||||
InfluxUser string `json:"influx_user" toml:"influx_user" xml:"influx_user" yaml:"influx_user"`
|
||||
InfluxPass string `json:"influx_pass" toml:"influx_pass" xml:"influx_pass" yaml:"influx_pass"`
|
||||
InfluxDB string `json:"influx_db" toml:"influx_db" xml:"influx_db" yaml:"influx_db"`
|
||||
UnifiUser string `json:"unifi_user" toml:"unifi_user" xml:"unifi_user" yaml:"unifi_user"`
|
||||
UnifiPass string `json:"unifi_pass" toml:"unifi_pass" xml:"unifi_pass" yaml:"unifi_pass"`
|
||||
UnifiBase string `json:"unifi_url" toml:"unifi_url" xml:"unifi_url" yaml:"unifi_url"`
|
||||
Interval Dur `json:"interval" toml:"interval" xml:"interval" yaml:"interval"`
|
||||
InfluxURL string `json:"influx_url" toml:"influx_url" xml:"influx_url" yaml:"influx_url"`
|
||||
InfluxUser string `json:"influx_user" toml:"influx_user" xml:"influx_user" yaml:"influx_user"`
|
||||
InfluxPass string `json:"influx_pass" toml:"influx_pass" xml:"influx_pass" yaml:"influx_pass"`
|
||||
InfluxDB string `json:"influx_db" toml:"influx_db" xml:"influx_db" yaml:"influx_db"`
|
||||
UnifiUser string `json:"unifi_user" toml:"unifi_user" xml:"unifi_user" yaml:"unifi_user"`
|
||||
UnifiPass string `json:"unifi_pass" toml:"unifi_pass" xml:"unifi_pass" yaml:"unifi_pass"`
|
||||
UnifiBase string `json:"unifi_url" toml:"unifi_url" xml:"unifi_url" yaml:"unifi_url"`
|
||||
uniClient *http.Client
|
||||
}
|
||||
|
||||
// Dur is used to UnmarshalTOML into a time.Duration value.
|
||||
type Dur struct {
|
||||
value time.Duration
|
||||
}
|
||||
|
||||
// UnmarshalTOML parses a duration type from a config file.
|
||||
func (v *Dur) UnmarshalTOML(data []byte) error {
|
||||
unquoted := string(data[1 : len(data)-1])
|
||||
dur, err := time.ParseDuration(unquoted)
|
||||
if err == nil {
|
||||
v.value = dur
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
|
|
@ -12,15 +13,36 @@ import (
|
|||
"time"
|
||||
|
||||
influx "github.com/influxdata/influxdb/client/v2"
|
||||
"github.com/naoina/toml"
|
||||
flg "github.com/ogier/pflag"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config := GetConfig()
|
||||
flg.Usage = func() {
|
||||
fmt.Println("Usage: unifi-poller [--config=filepath] [--debug] [--version]")
|
||||
flg.PrintDefaults()
|
||||
}
|
||||
configFile := flg.StringP("config", "c", defaultConfFile, "Poller Config File (TOML Format)")
|
||||
debug := flg.BoolP("debug", "D", false, "Turn on the Spam (default false)")
|
||||
version := flg.BoolP("version", "v", false, "Print the version and exit.")
|
||||
flg.Parse()
|
||||
if *version {
|
||||
fmt.Println("unifi-poller version:", Version)
|
||||
os.Exit(0) // don't run anything else.
|
||||
}
|
||||
if log.SetFlags(0); *debug {
|
||||
log.SetFlags(log.Lshortfile | log.Lmicroseconds | log.Ldate)
|
||||
}
|
||||
config, errc := GetConfig(*configFile)
|
||||
if errc != nil {
|
||||
flg.Usage()
|
||||
log.Fatalln("Config Error:", errc)
|
||||
}
|
||||
if err := config.AuthController(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Println("Authenticated to Unifi Controller", config.UnifiBase, "as user", config.UnifiUser)
|
||||
log.Println("Authenticated to Unifi Controller @", config.UnifiBase, "as user", config.UnifiUser)
|
||||
|
||||
infdb, err := influx.NewHTTPClient(influx.HTTPConfig{
|
||||
Addr: config.InfluxURL,
|
||||
|
|
@ -31,28 +53,30 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
log.Println("Logging Unifi Metrics to InfluXDB @", config.InfluxURL, "as user", config.InfluxUser)
|
||||
log.Println("Polling Unifi Controller, interval:", config.Interval)
|
||||
log.Println("Polling Unifi Controller, interval:", config.Interval.value)
|
||||
config.PollUnifiController(infdb)
|
||||
}
|
||||
|
||||
// GetConfig parses and returns our configuration data.
|
||||
func GetConfig() Config {
|
||||
// TODO: A real config file.
|
||||
interval, err := time.ParseDuration(os.Getenv("INTERVAL"))
|
||||
if err != nil {
|
||||
log.Println("Invalid Interval, defaulting to", defaultInterval)
|
||||
interval = time.Duration(defaultInterval)
|
||||
}
|
||||
return Config{
|
||||
InfluxURL: os.Getenv("INFLUXDB_URL"),
|
||||
InfluxUser: os.Getenv("INFLUXDB_USERNAME"),
|
||||
InfluxPass: os.Getenv("INFLUXDB_PASSWORD"),
|
||||
InfluxDB: os.Getenv("INFLUXDB_DATABASE"),
|
||||
UnifiUser: os.Getenv("UNIFI_USERNAME"),
|
||||
func GetConfig(configFile string) (Config, error) {
|
||||
// Preload our defaults.
|
||||
config := Config{
|
||||
InfluxURL: defaultInfxURL,
|
||||
InfluxUser: defaultInfxUser,
|
||||
InfluxPass: defaultInfxPass,
|
||||
InfluxDB: defaultInfxDb,
|
||||
UnifiUser: defaultUnifUser,
|
||||
UnifiPass: os.Getenv("UNIFI_PASSWORD"),
|
||||
UnifiBase: "https://" + os.Getenv("UNIFI_ADDR") + ":" + os.Getenv("UNIFI_PORT"),
|
||||
Interval: interval,
|
||||
UnifiBase: defaultUnifURL,
|
||||
Interval: Dur{value: defaultInterval},
|
||||
}
|
||||
if buf, err := ioutil.ReadFile(configFile); err != nil {
|
||||
return config, err
|
||||
// This is where the defaults in the config variable are overwritten.
|
||||
} else if err := toml.Unmarshal(buf, &config); err != nil {
|
||||
return config, errors.Wrap(err, "invalid config")
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// AuthController creates a http.Client with authenticated cookies.
|
||||
|
|
@ -80,7 +104,7 @@ func (c *Config) AuthController() error {
|
|||
|
||||
// PollUnifiController runs forever, polling and pushing.
|
||||
func (c *Config) PollUnifiController(infdb influx.Client) {
|
||||
ticker := time.NewTicker(c.Interval)
|
||||
ticker := time.NewTicker(c.Interval.value)
|
||||
for range ticker.C {
|
||||
clients, err := c.GetUnifiClients()
|
||||
if err != nil {
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 909 KiB After Width: | Height: | Size: 246 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
# 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.
|
||||
interval = "30s"
|
||||
|
||||
# InfluxDB does not require auth by default, so the user/password are probably unimportant.
|
||||
influx_url = "http://127.0.0.1:8086"
|
||||
influx_user = "unifi"
|
||||
influx_pass = "unifi"
|
||||
# Be sure to create this database.
|
||||
influx_db = "unifi"
|
||||
|
||||
# Make a read-only user in the Unifi Admin Settings.
|
||||
unifi_user = "influxdb"
|
||||
unifi_pass = "4BB9345C-2341-48D7-99F5-E01B583FF77F"
|
||||
unifi_url = "https://127.0.0.1:8443"
|
||||
Loading…
Reference in New Issue