rename some things

This commit is contained in:
davidnewhall2 2019-12-20 03:19:00 -08:00
parent de16ba2399
commit ed3bed4c7b
8 changed files with 65 additions and 58 deletions

View File

@ -55,7 +55,7 @@
# provide one and dynamic is disabled. In other words, you can just add your # provide one and dynamic is disabled. In other words, you can just add your
# controller here and delete the following section. Either works. # controller here and delete the following section. Either works.
[unifi.defaults] [unifi.defaults]
name = "https://127.0.0.1:8443" role = "https://127.0.0.1:8443"
url = "https://127.0.0.1:8443" url = "https://127.0.0.1:8443"
user = "unifipoller" user = "unifipoller"
pass = "unifipoller" pass = "unifipoller"
@ -68,7 +68,8 @@
[[unifi.controller]] [[unifi.controller]]
# Friendly name used in dashboards. Uses URL if left empty; which is fine. # Friendly name used in dashboards. Uses URL if left empty; which is fine.
# Avoid changing this later because it will live forever in your database. # Avoid changing this later because it will live forever in your database.
name = "" # Multiple controllers may share a role. This allows grouping during scrapes.
role = ""
url = "https://127.0.0.1:8443" url = "https://127.0.0.1:8443"
# Make a read-only user in the UniFi Admin Settings. # Make a read-only user in the UniFi Admin Settings.

View File

@ -24,7 +24,7 @@
"unifi": { "unifi": {
"dynamic": false, "dynamic": false,
"defaults": { "defaults": {
"name": "https://127.0.0.1:8443", "role": "https://127.0.0.1:8443",
"user": "unifipoller", "user": "unifipoller",
"pass": "unifipoller", "pass": "unifipoller",
"url": "https://127.0.0.1:8443", "url": "https://127.0.0.1:8443",
@ -35,7 +35,7 @@
}, },
"controllers": [ "controllers": [
{ {
"name": "", "role": "",
"user": "unifipoller", "user": "unifipoller",
"pass": "unifipoller", "pass": "unifipoller",
"url": "https://127.0.0.1:8443", "url": "https://127.0.0.1:8443",

View File

@ -25,7 +25,7 @@
</influxdb> </influxdb>
<unifi dynamic="false"> <unifi dynamic="false">
<default name="https://127.0.0.1:8443"> <default role="https://127.0.0.1:8443">
<site>all</site> <site>all</site>
<user>unifipoller</user> <user>unifipoller</user>
<pass>unifipoller</pass> <pass>unifipoller</pass>
@ -36,7 +36,7 @@
</default> </default>
<!-- Repeat this stanza to poll additional controllers. --> <!-- Repeat this stanza to poll additional controllers. -->
<controller name=""> <controller role="">
<site>all</site> <site>all</site>
<user>unifipoller</user> <user>unifipoller</user>
<pass>unifipoller</pass> <pass>unifipoller</pass>

View File

@ -26,7 +26,7 @@ influxdb:
unifi: unifi:
dynamic: false dynamic: false
defaults: defaults:
name: "https://127.0.0.1:8443" role: "https://127.0.0.1:8443"
user: "unifipoller" user: "unifipoller"
pass: "unifipoller" pass: "unifipoller"
url: "https://127.0.0.1:8443" url: "https://127.0.0.1:8443"
@ -36,8 +36,10 @@ unifi:
save_ids: false save_ids: false
save_sites: true save_sites: true
controllers: controllers:
- name: "" # Repeat the following stanza to poll more controllers.
- role: ""
user: "unifipoller" user: "unifipoller"
pass: "unifipoller" pass: "unifipoller"
url: "https://127.0.0.1:8443" url: "https://127.0.0.1:8443"

View File

@ -10,8 +10,8 @@ import (
) )
func (u *InputUnifi) isNill(c *Controller) bool { func (u *InputUnifi) isNill(c *Controller) bool {
u.Config.RLock() u.RLock()
defer u.Config.RUnlock() defer u.RUnlock()
return c.Unifi == nil return c.Unifi == nil
} }
@ -28,10 +28,10 @@ func (u *InputUnifi) newDynamicCntrlr(url string) (bool, *Controller) {
return false, c return false, c
} }
ccopy := u.Config.Default // copy defaults into new controller ccopy := u.Default // copy defaults into new controller
c = &ccopy c = &ccopy
u.dynamic[url] = c u.dynamic[url] = c
c.Name = url c.Role = url
c.URL = url c.URL = url
return true, c return true, c
@ -60,7 +60,7 @@ func (u *InputUnifi) collectController(c *Controller) (*poller.Metrics, error) {
u.Logf("Re-authenticating to UniFi Controller: %s", c.URL) u.Logf("Re-authenticating to UniFi Controller: %s", c.URL)
if err := u.getUnifi(c); err != nil { if err := u.getUnifi(c); err != nil {
return nil, fmt.Errorf("re-authenticating to %s: %v", c.Name, err) return nil, fmt.Errorf("re-authenticating to %s: %v", c.Role, err)
} }
} }
@ -70,8 +70,8 @@ func (u *InputUnifi) collectController(c *Controller) (*poller.Metrics, error) {
func (u *InputUnifi) pollController(c *Controller) (*poller.Metrics, error) { func (u *InputUnifi) pollController(c *Controller) (*poller.Metrics, error) {
var err error var err error
u.Config.RLock() u.RLock()
defer u.Config.RUnlock() defer u.RUnlock()
m := &poller.Metrics{TS: time.Now()} // At this point, it's the Current Check. m := &poller.Metrics{TS: time.Now()} // At this point, it's the Current Check.
@ -149,8 +149,8 @@ func (u *InputUnifi) augmentMetrics(c *Controller, metrics *poller.Metrics) *pol
// Omits requested but unconfigured sites. Grabs the full list from the // Omits requested but unconfigured sites. Grabs the full list from the
// controller and returns the sites provided in the config file. // controller and returns the sites provided in the config file.
func (u *InputUnifi) getFilteredSites(c *Controller) (unifi.Sites, error) { func (u *InputUnifi) getFilteredSites(c *Controller) (unifi.Sites, error) {
u.Config.RLock() u.RLock()
defer u.Config.RUnlock() defer u.RUnlock()
sites, err := c.Unifi.GetSites() sites, err := c.Unifi.GetSites()
if err != nil { if err != nil {

View File

@ -22,7 +22,7 @@ const (
// InputUnifi contains the running data. // InputUnifi contains the running data.
type InputUnifi struct { type InputUnifi struct {
Config *Config `json:"unifi" toml:"unifi" xml:"unifi" yaml:"unifi"` *Config `json:"unifi" toml:"unifi" xml:"unifi" yaml:"unifi"`
dynamic map[string]*Controller dynamic map[string]*Controller
sync.Mutex // to lock the map above. sync.Mutex // to lock the map above.
poller.Logger poller.Logger
@ -34,7 +34,7 @@ type Controller struct {
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"`
SaveIDS bool `json:"save_ids" toml:"save_ids" xml:"save_ids" yaml:"save_ids"` SaveIDS bool `json:"save_ids" toml:"save_ids" xml:"save_ids" yaml:"save_ids"`
SaveSites *bool `json:"save_sites" toml:"save_sites" xml:"save_sites" yaml:"save_sites"` SaveSites *bool `json:"save_sites" toml:"save_sites" xml:"save_sites" yaml:"save_sites"`
Name string `json:"name" toml:"name" xml:"name,attr" yaml:"name"` Role string `json:"role" toml:"role" xml:"role,attr" yaml:"role"`
User string `json:"user" toml:"user" xml:"user" yaml:"user"` User string `json:"user" toml:"user" xml:"user" yaml:"user"`
Pass string `json:"pass" toml:"pass" xml:"pass" yaml:"pass"` Pass string `json:"pass" toml:"pass" xml:"pass" yaml:"pass"`
URL string `json:"url" toml:"url" xml:"url" yaml:"url"` URL string `json:"url" toml:"url" xml:"url" yaml:"url"`
@ -65,8 +65,8 @@ func init() {
func (u *InputUnifi) getUnifi(c *Controller) error { func (u *InputUnifi) getUnifi(c *Controller) error {
var err error var err error
u.Config.Lock() u.Lock()
defer u.Config.Unlock() defer u.Unlock()
if c.Unifi != nil { if c.Unifi != nil {
c.Unifi.CloseIdleConnections() c.Unifi.CloseIdleConnections()
@ -94,8 +94,8 @@ func (u *InputUnifi) getUnifi(c *Controller) error {
// checkSites makes sure the list of provided sites exists on the controller. // checkSites makes sure the list of provided sites exists on the controller.
// This only runs once during initialization. // This only runs once during initialization.
func (u *InputUnifi) checkSites(c *Controller) error { func (u *InputUnifi) checkSites(c *Controller) error {
u.Config.RLock() u.RLock()
defer u.Config.RUnlock() defer u.RUnlock()
if len(c.Sites) < 1 || c.Sites[0] == "" { if len(c.Sites) < 1 || c.Sites[0] == "" {
c.Sites = []string{"all"} c.Sites = []string{"all"}
@ -113,7 +113,7 @@ func (u *InputUnifi) checkSites(c *Controller) error {
msg = append(msg, site.Name+" ("+site.Desc+")") msg = append(msg, site.Name+" ("+site.Desc+")")
} }
u.Logf("Found %d site(s) on controller %s: %v", len(msg), c.Name, strings.Join(msg, ", ")) u.Logf("Found %d site(s) on controller %s: %v", len(msg), c.Role, strings.Join(msg, ", "))
if StringInSlice("all", c.Sites) { if StringInSlice("all", c.Sites) {
c.Sites = []string{"all"} c.Sites = []string{"all"}
@ -130,7 +130,7 @@ FIRST:
continue FIRST continue FIRST
} }
} }
u.LogErrorf("Configured site not found on controller %s: %v", c.Name, s) u.LogErrorf("Configured site not found on controller %s: %v", c.Role, s)
} }
if c.Sites = keep; len(keep) < 1 { if c.Sites = keep; len(keep) < 1 {
@ -168,8 +168,8 @@ func (u *InputUnifi) setDefaults(c *Controller) {
c.URL = defaultURL c.URL = defaultURL
} }
if c.Name == "" { if c.Role == "" {
c.Name = c.URL c.Role = c.URL
} }
if c.Pass == "" { if c.Pass == "" {

View File

@ -14,36 +14,36 @@ import (
// Initialize gets called one time when starting up. // Initialize gets called one time when starting up.
// Satisfies poller.Input interface. // Satisfies poller.Input interface.
func (u *InputUnifi) Initialize(l poller.Logger) error { func (u *InputUnifi) Initialize(l poller.Logger) error {
if u.Config.Disable { if u.Disable {
l.Logf("UniFi input plugin disabled!") l.Logf("UniFi input plugin disabled!")
return nil return nil
} }
if u.setDefaults(&u.Config.Default); len(u.Config.Controllers) < 1 && !u.Config.Dynamic { if u.setDefaults(&u.Default); len(u.Controllers) < 1 && !u.Dynamic {
new := u.Config.Default // copy defaults. new := u.Default // copy defaults.
u.Config.Controllers = []*Controller{&new} u.Controllers = []*Controller{&new}
} }
if len(u.Config.Controllers) < 1 { if len(u.Controllers) < 1 {
l.Logf("No controllers configured. Polling dynamic controllers only!") l.Logf("No controllers configured. Polling dynamic controllers only!")
} }
u.dynamic = make(map[string]*Controller) u.dynamic = make(map[string]*Controller)
u.Logger = l u.Logger = l
for _, c := range u.Config.Controllers { for _, c := range u.Controllers {
u.setDefaults(c) u.setDefaults(c)
switch err := u.getUnifi(c); err { switch err := u.getUnifi(c); err {
case nil: case nil:
if err := u.checkSites(c); err != nil { if err := u.checkSites(c); err != nil {
u.LogErrorf("checking sites on %s: %v", c.Name, err) u.LogErrorf("checking sites on %s: %v", c.Role, err)
} }
u.Logf("Configured UniFi Controller at %s v%s as user %s. Sites: %v", u.Logf("Configured UniFi Controller at %s v%s as user %s. Sites: %v",
c.URL, c.Unifi.ServerVersion, c.User, c.Sites) c.URL, c.Unifi.ServerVersion, c.User, c.Sites)
default: default:
u.LogErrorf("Controller Auth or Connection failed, but continuing to retry! %s: %v", c.Name, err) u.LogErrorf("Controller Auth or Connection failed, but continuing to retry! %s: %v", c.Role, err)
} }
} }
@ -57,7 +57,7 @@ func (u *InputUnifi) Metrics() (*poller.Metrics, bool, error) {
// MetricsFrom grabs all the measurements from a UniFi controller and returns them. // MetricsFrom grabs all the measurements from a UniFi controller and returns them.
func (u *InputUnifi) MetricsFrom(filter *poller.Filter) (*poller.Metrics, bool, error) { func (u *InputUnifi) MetricsFrom(filter *poller.Filter) (*poller.Metrics, bool, error) {
if u.Config.Disable { if u.Disable {
return nil, false, nil return nil, false, nil
} }
@ -65,9 +65,20 @@ func (u *InputUnifi) MetricsFrom(filter *poller.Filter) (*poller.Metrics, bool,
metrics := &poller.Metrics{} metrics := &poller.Metrics{}
ok := false ok := false
if filter != nil && filter.Path != "" {
if !u.Dynamic {
return metrics, false, fmt.Errorf("filter path requested but dynamic lookups disabled")
}
// Attempt a dynamic metrics fetch from an unconfigured controller.
m, err := u.dynamicController(filter.Path)
return m, err == nil && m != nil, err
}
// Check if the request is for an existing, configured controller. // Check if the request is for an existing, configured controller.
for _, c := range u.Config.Controllers { for _, c := range u.Controllers {
if filter != nil && !strings.EqualFold(c.Name, filter.Term) { if filter != nil && !strings.EqualFold(c.Role, filter.Role) {
continue continue
} }
@ -88,32 +99,21 @@ func (u *InputUnifi) MetricsFrom(filter *poller.Filter) (*poller.Metrics, bool,
return metrics, ok, fmt.Errorf(strings.Join(errs, ", ")) return metrics, ok, fmt.Errorf(strings.Join(errs, ", "))
} }
if ok { return metrics, ok, nil
return metrics, true, nil
}
if filter != nil && !u.Config.Dynamic {
return metrics, false, fmt.Errorf("scrape filter match failed and dynamic lookups disabled")
}
// Attempt a dynamic metrics fetch from an unconfigured controller.
m, err := u.dynamicController(filter.Term)
return m, err == nil && m != nil, err
} }
// RawMetrics returns API output from the first configured unifi controller. // RawMetrics returns API output from the first configured unifi controller.
func (u *InputUnifi) RawMetrics(filter *poller.Filter) ([]byte, error) { func (u *InputUnifi) RawMetrics(filter *poller.Filter) ([]byte, error) {
if l := len(u.Config.Controllers); filter.Unit >= l { if l := len(u.Controllers); filter.Unit >= l {
return nil, fmt.Errorf("control number %d not found, %d controller(s) configured (0 index)", filter.Unit, l) return nil, fmt.Errorf("control number %d not found, %d controller(s) configured (0 index)", filter.Unit, l)
} }
c := u.Config.Controllers[filter.Unit] c := u.Controllers[filter.Unit]
if u.isNill(c) { if u.isNill(c) {
u.Logf("Re-authenticating to UniFi Controller: %s", c.URL) u.Logf("Re-authenticating to UniFi Controller: %s", c.URL)
if err := u.getUnifi(c); err != nil { if err := u.getUnifi(c); err != nil {
return nil, fmt.Errorf("re-authenticating to %s: %v", c.Name, err) return nil, fmt.Errorf("re-authenticating to %s: %v", c.Role, err)
} }
} }

View File

@ -129,17 +129,21 @@ func (u *promUnifi) Run(c poller.Collect) error {
// ScrapeHandler allows prometheus to scrape a single source, instead of all sources. // ScrapeHandler allows prometheus to scrape a single source, instead of all sources.
func (u *promUnifi) ScrapeHandler(w http.ResponseWriter, r *http.Request) { func (u *promUnifi) ScrapeHandler(w http.ResponseWriter, r *http.Request) {
t := &target{u: u, Filter: &poller.Filter{}} t := &target{u: u, Filter: &poller.Filter{
if t.Name = r.URL.Query().Get("input"); t.Name == "" { Name: r.URL.Query().Get("input"), // "unifi"
Path: r.URL.Query().Get("path"), // url: "https://127.0.0.1:8443"
Role: r.URL.Query().Get("role"), // configured role in up.conf.
}}
if t.Name == "" {
u.Collector.LogErrorf("input parameter missing on scrape from %v", r.RemoteAddr) u.Collector.LogErrorf("input parameter missing on scrape from %v", r.RemoteAddr)
http.Error(w, `'input' parameter must be specified (try "unifi")`, 400) http.Error(w, `'input' parameter must be specified (try "unifi")`, 400)
return return
} }
if t.Term = r.URL.Query().Get("target"); t.Term == "" { if t.Role == "" && t.Path == "" {
u.Collector.LogErrorf("target parameter missing on scrape from %v", r.RemoteAddr) u.Collector.LogErrorf("role and path parameters missing on scrape from %v", r.RemoteAddr)
http.Error(w, "'target' parameter must be specified, configured name, or unconfigured url", 400) http.Error(w, "'role' OR 'path' parameter must be specified: configured role OR unconfigured url", 400)
return return
} }