158 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
package inputunifi
 | 
						|
 | 
						|
/* This file contains the three poller.Input interface methods. */
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	"github.com/unifi-poller/poller"
 | 
						|
	"github.com/unifi-poller/unifi"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	errDynamicLookupsDisabled = fmt.Errorf("filter path requested but dynamic lookups disabled")
 | 
						|
	errControllerNumNotFound  = fmt.Errorf("controller number not found")
 | 
						|
	errNoFilterKindProvided   = fmt.Errorf("must provide filter: devices, clients, other")
 | 
						|
)
 | 
						|
 | 
						|
// Initialize gets called one time when starting up.
 | 
						|
// Satisfies poller.Input interface.
 | 
						|
func (u *InputUnifi) Initialize(l poller.Logger) error {
 | 
						|
	if u.Config == nil {
 | 
						|
		u.Config = &Config{Disable: true}
 | 
						|
	}
 | 
						|
 | 
						|
	if u.Disable {
 | 
						|
		l.Logf("UniFi input plugin disabled or missing configuration!")
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	if u.setDefaults(&u.Default); len(u.Controllers) == 0 && !u.Dynamic {
 | 
						|
		u.Controllers = []*Controller{&u.Default}
 | 
						|
	}
 | 
						|
 | 
						|
	if len(u.Controllers) == 0 {
 | 
						|
		l.Logf("No controllers configured. Polling dynamic controllers only!")
 | 
						|
	}
 | 
						|
 | 
						|
	u.dynamic = make(map[string]*Controller)
 | 
						|
	u.Logger = l
 | 
						|
 | 
						|
	for i, c := range u.Controllers {
 | 
						|
		switch err := u.getUnifi(u.setControllerDefaults(c)); err {
 | 
						|
		case nil:
 | 
						|
			if err := u.checkSites(c); err != nil {
 | 
						|
				u.LogErrorf("checking sites on %s: %v", c.Role, err)
 | 
						|
			}
 | 
						|
 | 
						|
			u.Logf("Configured UniFi Controller %d:", i+1)
 | 
						|
			u.Logf("   => Version: %s", c.Unifi.ServerVersion)
 | 
						|
		default:
 | 
						|
			u.LogErrorf("Controller %d Auth or Connection failed, but continuing to retry! %v", i, err)
 | 
						|
		}
 | 
						|
 | 
						|
		u.Logf("   => URL: %s", c.URL)
 | 
						|
		u.Logf("   => Username: %s (has password: %v)", c.User, c.Pass != "")
 | 
						|
		u.Logf("   => Role: %s", c.Role)
 | 
						|
		u.Logf("   => Hash PII: %v", *c.HashPII)
 | 
						|
		u.Logf("   => Verify SSL: %v", *c.VerifySSL)
 | 
						|
		u.Logf("   => Save DPI: %v", *c.SaveDPI)
 | 
						|
		u.Logf("   => Save IDS: %v", *c.SaveIDS)
 | 
						|
		u.Logf("   => Save Sites: %v", *c.SaveSites)
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Metrics grabs all the measurements from a UniFi controller and returns them.
 | 
						|
func (u *InputUnifi) Metrics() (*poller.Metrics, bool, error) {
 | 
						|
	return u.MetricsFrom(nil)
 | 
						|
}
 | 
						|
 | 
						|
// MetricsFrom grabs all the measurements from a UniFi controller and returns them.
 | 
						|
func (u *InputUnifi) MetricsFrom(filter *poller.Filter) (*poller.Metrics, bool, error) {
 | 
						|
	if u.Disable {
 | 
						|
		return nil, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	errs := []string{}
 | 
						|
	metrics := &poller.Metrics{}
 | 
						|
	ok := false
 | 
						|
 | 
						|
	if filter != nil && filter.Path != "" {
 | 
						|
		if !u.Dynamic {
 | 
						|
			return metrics, false, errDynamicLookupsDisabled
 | 
						|
		}
 | 
						|
 | 
						|
		// 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.
 | 
						|
	for _, c := range u.Controllers {
 | 
						|
		if filter != nil && !strings.EqualFold(c.Role, filter.Role) {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		m, err := u.collectController(c)
 | 
						|
		if err != nil {
 | 
						|
			errs = append(errs, err.Error())
 | 
						|
		}
 | 
						|
 | 
						|
		if m == nil {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		ok = true
 | 
						|
		metrics = poller.AppendMetrics(metrics, m)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(errs) > 0 {
 | 
						|
		return metrics, ok, fmt.Errorf(strings.Join(errs, ", ")) // nolint: goerr113
 | 
						|
	}
 | 
						|
 | 
						|
	return metrics, ok, nil
 | 
						|
}
 | 
						|
 | 
						|
// RawMetrics returns API output from the first configured unifi controller.
 | 
						|
func (u *InputUnifi) RawMetrics(filter *poller.Filter) ([]byte, error) {
 | 
						|
	if l := len(u.Controllers); filter.Unit >= l {
 | 
						|
		return nil, errors.Wrapf(errControllerNumNotFound, "%d controller(s) configured, '%d'", l, filter.Unit)
 | 
						|
	}
 | 
						|
 | 
						|
	c := u.Controllers[filter.Unit]
 | 
						|
	if u.isNill(c) {
 | 
						|
		u.Logf("Re-authenticating to UniFi Controller: %s", c.URL)
 | 
						|
 | 
						|
		if err := u.getUnifi(c); err != nil {
 | 
						|
			return nil, errors.Wrapf(err, "re-authenticating to %s", c.Role)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if err := u.checkSites(c); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	sites, err := u.getFilteredSites(c)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	switch filter.Kind {
 | 
						|
	case "d", "device", "devices":
 | 
						|
		return u.dumpSitesJSON(c, unifi.APIDevicePath, "Devices", sites)
 | 
						|
	case "client", "clients", "c":
 | 
						|
		return u.dumpSitesJSON(c, unifi.APIClientPath, "Clients", sites)
 | 
						|
	case "other", "o":
 | 
						|
		_, _ = fmt.Fprintf(os.Stderr, "[INFO] Dumping Path '%s':\n", filter.Path)
 | 
						|
		return c.Unifi.GetJSON(filter.Path)
 | 
						|
	default:
 | 
						|
		return []byte{}, errNoFilterKindProvided
 | 
						|
	}
 | 
						|
}
 |