diff --git a/main.go b/main.go index e9dcd30..e8b9116 100644 --- a/main.go +++ b/main.go @@ -25,8 +25,9 @@ const ( // flags var configPath = flag.String("configPath", "config.json", "Path to config.json") var version = "development" -var delay time.Duration = 60 * time.Second +var delay time.Duration = 5 * time.Second var conf = loadconfig(*configPath) +var ucDev = getDevices(conf.Unifi.UCDevicesURL) func main() { log.Printf("starting version %s...\n", version) @@ -34,9 +35,9 @@ func main() { flag.Parse() // check if flags are set - if *configPath == "" { - log.Fatalln("Please specify path to config.json flag '-configPath'") - } + //if *configPath == "" { + // log.Fatalln("Please specify path to config.json flag '-configPath'") + //} // start API processing (runs in a loop) go processAPIs() @@ -68,10 +69,8 @@ func processUcAPIs() ([]node, []link) { //get list of Unifi devices to display var nodes []node var links []link - d, err := getDevices(conf.Unifi.UCDevicesURL) - if err != nil { - log.Fatalln(err) - } + d := getDevices(conf.Unifi.UCDevicesURL) + //call Unifi Controller ucAPI := newAPI(conf.Unifi.User, conf.Unifi.Password, conf.Unifi.APIURL) //login @@ -115,10 +114,10 @@ func processUcAPIs() ([]node, []link) { Lastseen: time.Unix(int64(currentDevice.LastSeen), 0).Format(iso8601), IsOnline: itob(currentDevice.State), IsGateway: false, - Clients: 0, + Clients: currentDevice.Users, ClientsWifi24: 0, ClientsWifi5: 0, - ClientsOther: 0, + ClientsOther: currentDevice.Users, RootFSUsage: 0, LoadAVG: load / 100, MemoryUsage: mem / 100, @@ -153,15 +152,12 @@ func processUNMSAPI() ([]node, []link) { var links []link var nodes []node - d, err := getDevices(conf.Unms.DevicesURL) - if err != nil { - log.Fatalln(err) - } + d := getDevices(conf.Unms.DevicesURL) // API CALL 1 log.Println("calling API 1") var u []unifiAPIResponse - err = callUnifiAPI("/devices", &u) + err := callUnifiAPI("/devices", &u) if err != nil { log.Fatalln(err) } @@ -254,6 +250,11 @@ func processAPIs() { nodes = append(nodes, ucNodes...) links = append(links, ucLinks...) } + if conf.Meshviewer.Enabled == true { + mvNodes, mvLinks := getMeshviewer() + nodes = append(nodes, mvNodes...) + links = append(links, mvLinks...) + } // assemble final struct o := output{ @@ -283,7 +284,7 @@ func getFile(url string) []byte { return byteValue } -func getDevices(url string) (devices, error) { +func getDevices(url string) devices { // get devices from JSON file jsonFile := getFile(url) @@ -296,7 +297,7 @@ func getDevices(url string) (devices, error) { fmt.Println("can´t get devices file from " + url) log.Fatal(err) } - return d, nil + return d } func callUnifiAPI(url string, i interface{}) error { @@ -475,3 +476,105 @@ func ucAddLink(dev device, links []link) []link { }) return links } + +func getMeshviewerJSON(url string) (mvDevices, error) { + // get devices from JSON file + jsonFile := getFile(url) + + // read file to bytes + // variable for d + var n mvDevices + //var l []link + // unmarshal to struct + err := json.Unmarshal(jsonFile, &n) + if err != nil { + fmt.Println("can´t get Meshviewer Json file from " + url) + log.Println(err) + } + return n, nil +} +func findNodeID(NodeID string) bool { + for i := range ucDev.Devices { + if ucDev.Devices[i].GatewayNexthop == NodeID { + return true + } + } + return false +} +func addmvDevices(d mvDevices) ([]node, []link) { + var nodes []node + var links []link + + for i := range d.Nodes { + mvNode := d.Nodes[i] + if findNodeID(mvNode.NodeID) == true { + mvNode.Clients = 0 + mvNode.ClientsWifi24 = 0 + mvNode.ClientsWifi5 = 0 + mvNode.ClientsOther = 0 + } + nodes = append(nodes, node{ + Firstseen: mvNode.Firstseen, + Lastseen: mvNode.Lastseen, + IsOnline: mvNode.IsOnline, + IsGateway: mvNode.IsGateway, + Clients: mvNode.Clients, + ClientsWifi24: mvNode.ClientsWifi24, + ClientsWifi5: mvNode.ClientsWifi5, + ClientsOther: mvNode.ClientsOther, + RootFSUsage: int(mvNode.RootfsUsage), + LoadAVG: mvNode.Loadavg, + MemoryUsage: mvNode.MemoryUsage, + Uptime: mvNode.Uptime, + GatewayNexthop: mvNode.GatewayNexthop, + Gateway: mvNode.Gateway, + Location: mvNode.Location, + NodeID: mvNode.NodeID, + MAC: mvNode.Mac, + Adresses: mvNode.Addresses, + Domain: mvNode.Domain, + Hostname: mvNode.Hostname, + Owner: mvNode.Owner, + Firmware: firmware{ + Base: mvNode.Firmware.Base, + Release: mvNode.Firmware.Release, + }, + Autoupdater: autoupdater{ + Enabled: mvNode.Autoupdater.Enabled, + Branch: mvNode.Autoupdater.Branch, + }, + NProc: mvNode.Nproc, + Model: mvNode.Model, + }) + } + for i := range d.Links { + mvNode := d.Links[i] + links = append(links, link{ + Type: mvNode.Type, + Source: mvNode.Source, + Target: mvNode.Target, + SourceTQ: mvNode.SourceTq, + TargetTQ: mvNode.TargetTq, + SourceAddr: mvNode.SourceAddr, + TargetAddr: mvNode.TargetAddr, + }) + } + return nodes, links +} + +func getMeshviewer() ([]node, []link) { + var nodes []node + var links []link + + for i := range conf.Meshviewer.Files { + fmt.Println("Hole Meshviewer JSON von: ", conf.Meshviewer.Files[i].URL) + m, err := getMeshviewerJSON(conf.Meshviewer.Files[i].URL) + if err != nil { + return nodes, links + } + mvNodes, mvLinks := addmvDevices(m) + nodes = append(nodes, mvNodes...) + links = append(links, mvLinks...) + } + return nodes, links +} diff --git a/types.go b/types.go index 1f69650..5180998 100644 --- a/types.go +++ b/types.go @@ -24,6 +24,13 @@ type config struct { Password string `json:"password"` UCDevicesURL string `json:"ucDevicesURL"` } `json:"unifi"` + Meshviewer struct { + Enabled bool `json:"enabled"` + Files []struct { + Name string `json:"name"` + URL string `json:"URL"` + } `json:"files"` + } `json:"meshviewer"` } type device struct { @@ -182,6 +189,7 @@ type ucDevice struct { State int `json:"state"` LastSeen int `json:"last_seen"` Uptime int `json:"uptime"` + Users int `json:"user-wlan-num_sta"` Sysstats struct { CPU string `json:"cpu"` Memory string `json:"mem"` @@ -195,6 +203,54 @@ type ucAPIData struct { client *http.Client } +type mvDevices struct { + Nodes []struct { + Firstseen string `json:"firstseen"` + Lastseen string `json:"lastseen"` + IsOnline bool `json:"is_online"` + IsGateway bool `json:"is_gateway"` + Clients int `json:"clients"` + ClientsWifi24 int `json:"clients_wifi24"` + ClientsWifi5 int `json:"clients_wifi5"` + ClientsOther int `json:"clients_other"` + RootfsUsage float64 `json:"rootfs_usage"` + Loadavg float64 `json:"loadavg"` + MemoryUsage float64 `json:"memory_usage"` + Uptime string `json:"uptime"` + GatewayNexthop string `json:"gateway_nexthop,omitempty"` + Gateway string `json:"gateway,omitempty"` + NodeID string `json:"node_id"` + Mac string `json:"mac"` + Addresses []string `json:"addresses"` + Domain string `json:"domain"` + Hostname string `json:"hostname"` + Owner string `json:"owner,omitempty"` + Location struct { + Longitude float64 `json:"longitude"` + Latitude float64 `json:"latitude"` + } `json:"location,omitempty"` + Firmware struct { + Base string `json:"base"` + Release string `json:"release"` + } `json:"firmware"` + Autoupdater struct { + Enabled bool `json:"enabled"` + Branch string `json:"branch"` + } `json:"autoupdater,omitempty"` + Nproc int `json:"nproc"` + Model string `json:"model,omitempty"` + } `json:"nodes"` + Links []struct { + Type string `json:"type"` + Source string `json:"source"` + Target string `json:"target"` + SourceTq float64 `json:"source_tq"` + TargetTq float64 `json:"target_tq"` + SourceAddr string `json:"source_addr"` + TargetAddr string `json:"target_addr"` + } `json:"links"` +} + //switch Unifi AP Mod IDs to Names func lookupModels(model string) string { switch model {