Merge branch 'master' of ../mysqlunifi into merge-them-all
This commit is contained in:
		
						commit
						1480ac947f
					
				|  | @ -0,0 +1,3 @@ | ||||||
|  | /mysqlunifi | ||||||
|  | /*.so | ||||||
|  | /go.sum | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | language: go | ||||||
|  | go: | ||||||
|  | - 1.15.x | ||||||
|  | before_install: | ||||||
|  |   # download super-linter: golangci-lint | ||||||
|  | - curl -sL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin latest | ||||||
|  | script: | ||||||
|  | - golangci-lint run --enable-all -D gochecknoinits,exhaustivestruct,nlreturn,forbidigo,goerr113 | ||||||
|  | - go test ./... | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | MIT LICENSE. | ||||||
|  | Copyright (c) 2018-2020 David Newhall II | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  | a copy of this software and associated documentation files (the | ||||||
|  | "Software"), to deal in the Software without restriction, including | ||||||
|  | without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  | distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  | permit persons to whom the Software is furnished to do so, subject to | ||||||
|  | the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be | ||||||
|  | included in all copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||||
|  | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||||
|  | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||||
|  | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | # MYSQL Output Plugin Example | ||||||
|  | 
 | ||||||
|  | This plugin is not finished and did not get finished for the release of poller v2. | ||||||
|  | Sorry about that. I'll try to get it working soon! 2/4/20 | ||||||
|  | 
 | ||||||
|  | The code here, and the dynamic plugin provided shows an example of how you can | ||||||
|  | write your own output for unifi-poller. This plugin records some very basic | ||||||
|  | data about clients on a unifi network into a mysql database. | ||||||
|  | 
 | ||||||
|  | You could write outputs that do... anything. An example: They could compare current | ||||||
|  | connected clients to a previous list (in a db, or stored in memory), and send a | ||||||
|  | notification if it changes. The possibilities are endless. | ||||||
|  | 
 | ||||||
|  | You must compile your plugin using the unifi-poller source for the version you're | ||||||
|  | using. In other words, to build a plugin for version 2.0.1, do this: | ||||||
|  | ``` | ||||||
|  | mkdir -p $GOPATH/src/github.com/unifi-poller | ||||||
|  | cd $GOPATH/src/github.com/unifi-poller | ||||||
|  | 
 | ||||||
|  | git clone git@github.com:unifi-poller/unifi-poller.git | ||||||
|  | cd unifi-poller | ||||||
|  | 
 | ||||||
|  | git checkout v2.0.1 | ||||||
|  | 
 | ||||||
|  | cp -r <your plugin> plugins/ | ||||||
|  | GOOS=linux make plugins | ||||||
|  | ``` | ||||||
|  | The plugin you copy in *must* have a `main.go` file for `make plugins` to build it. | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | /* Everything in this file runs after the config is unmarshalled and we've | ||||||
|  |    verified the configuration for the poller. */ | ||||||
|  | 
 | ||||||
|  | func (p *plugin) runCollector() error { | ||||||
|  | 	p.Logf("mysql plugin is not finished") | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | module github.com/unifi-poller/mysqlunifi | ||||||
|  | 
 | ||||||
|  | go 1.15 | ||||||
|  | 
 | ||||||
|  | require ( | ||||||
|  | 	github.com/unifi-poller/poller v0.0.0-20210315075554-47d92433b172 | ||||||
|  | 	golift.io/cnfg v0.0.7 | ||||||
|  | ) | ||||||
|  | @ -0,0 +1,97 @@ | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	"github.com/unifi-poller/poller" | ||||||
|  | 	"golift.io/cnfg" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Only capital (exported) members are unmarshaled when passed into poller.NewOutput().
 | ||||||
|  | type plugin struct { | ||||||
|  | 	*Config `json:"mysql" toml:"mysql" xml:"mysql" yaml:"mysql"` | ||||||
|  | 	poller.Collect | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Config represents the data that is unmarshalled from the up.conf config file for this plugins.
 | ||||||
|  | // See up.conf.example.mysql for sample input data.
 | ||||||
|  | type Config struct { | ||||||
|  | 	Disable  bool          `json:"disable" toml:"disable" xml:"disable" yaml:"disable"` | ||||||
|  | 	Interval cnfg.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"` | ||||||
|  | 	Host     string        `json:"host" toml:"host" xml:"host" yaml:"host"` | ||||||
|  | 	User     string        `json:"user" toml:"user" xml:"user" yaml:"user"` | ||||||
|  | 	Pass     string        `json:"pass" toml:"pass" xml:"pass" yaml:"pass"` | ||||||
|  | 	DB       string        `json:"db" toml:"db" xml:"db" yaml:"db"` | ||||||
|  | 	Devices  []Device      `json:"devices" toml:"devices" xml:"device" yaml:"devices"` | ||||||
|  | 	Clients  *Clients      `json:"clients" toml:"clients" xml:"clients" yaml:"clients"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Device represents the configuration to save a devices' data.
 | ||||||
|  | // Type is one of uap, usw, ugw, udm.
 | ||||||
|  | // Table represents the mysql table name we save these fields to.
 | ||||||
|  | // Fields is a map of api response data key -> mysql column.
 | ||||||
|  | type Device struct { | ||||||
|  | 	Type   string            `json:"type" toml:"type" xml:"type" yaml:"type"` | ||||||
|  | 	Table  string            `json:"table" toml:"table" xml:"table" yaml:"table"` | ||||||
|  | 	Fields map[string]string `json:"fields" toml:"fields" xml:"field" yaml:"fields"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Clients represents the configuration to save clients' data.
 | ||||||
|  | // Table represents the mysql table name we save these fields to.
 | ||||||
|  | // Fields is a map of api response data key -> mysql column.
 | ||||||
|  | type Clients struct { | ||||||
|  | 	Table  string            `json:"table" toml:"table" xml:"table" yaml:"table"` | ||||||
|  | 	Fields map[string]string `json:"fields" toml:"fields" xml:"field" yaml:"fields"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	u := &plugin{Config: &Config{}} | ||||||
|  | 
 | ||||||
|  | 	poller.NewOutput(&poller.Output{ | ||||||
|  | 		Name:   "mysql", | ||||||
|  | 		Config: u, // pass in the struct *above* your config (so it can see the struct tags).
 | ||||||
|  | 		Method: u.Run, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Run gets called by poller core code. Return when the plugin stops working or has an error.
 | ||||||
|  | // In other words, don't run your code in a go routine, it already is.
 | ||||||
|  | func (p *plugin) Run(c poller.Collect) error { | ||||||
|  | 	if p.Collect = c; c == nil || p.Config == nil || p.Disable { | ||||||
|  | 		return nil // no config or disabled, bail out.
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := p.validateConfig(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return p.runCollector() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // validateConfig checks input sanity.
 | ||||||
|  | func (p *plugin) validateConfig() error { | ||||||
|  | 	if p.Interval.Duration == 0 { | ||||||
|  | 		return fmt.Errorf("must provide a polling interval") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.Clients == nil && len(p.Devices) == 0 { | ||||||
|  | 		return fmt.Errorf("must configure client or device collection; both empty") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, d := range p.Devices { | ||||||
|  | 		if len(d.Fields) == 0 { | ||||||
|  | 			return fmt.Errorf("no fields defined for device type %s, table %s", d.Type, d.Table) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.Clients != nil && p.Clients.Fields == nil { | ||||||
|  | 		return fmt.Errorf("no fields defined for clients; if you don't want to store client data, remove it from the config") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // main() is required, but it shouldn't do much as it's not used in plugin mode.
 | ||||||
|  | func main() { | ||||||
|  | 	fmt.Println("this is a unifi-poller plugin; not an application") | ||||||
|  | } | ||||||
|  | @ -0,0 +1,34 @@ | ||||||
|  | [poller] | ||||||
|  |   debug   = true | ||||||
|  |   plugins = ["/path/to/mysql.so"] | ||||||
|  | 
 | ||||||
|  | [mysql] | ||||||
|  |   interval = "30s" | ||||||
|  |   host     = "127.0.0.1:3306" | ||||||
|  |   user     = "unifipoller" | ||||||
|  |   pass     = "unifipoller" | ||||||
|  |   db       = "unifipoller" | ||||||
|  | 
 | ||||||
|  | [mysql.clients] | ||||||
|  |   table = "client_records" | ||||||
|  |   [mysql.clients.fields] | ||||||
|  |     tx_bytes = "tx-bytes" | ||||||
|  |     rx_bytes = "rx-bytes" | ||||||
|  | 
 | ||||||
|  | [[mysql.devices]] | ||||||
|  |   type  = "uap" | ||||||
|  |   table = "uap_records" | ||||||
|  |   [mysql.devices.fields] | ||||||
|  |     tx_bytes = "tx-bytes" | ||||||
|  |     rx_bytes = "rx-bytes" | ||||||
|  | 
 | ||||||
|  | [[mysql.devices]] | ||||||
|  |   type  = "ugw" | ||||||
|  |   table = "usg_records" | ||||||
|  |   [mysql.devices.fields] | ||||||
|  |     wan_bytes = "wan_bytes" | ||||||
|  | 
 | ||||||
|  | [unifi.defaults] | ||||||
|  |   url        = "https://127.0.0.1:8443" | ||||||
|  |   user       = "unifipoller" | ||||||
|  |   pass       = "4BB9345C-2341-48D7-99F5-E01B583FF77F" | ||||||
		Loading…
	
		Reference in New Issue