diff --git a/main.go b/main.go index d9ad6d6..95fad07 100644 --- a/main.go +++ b/main.go @@ -30,13 +30,14 @@ var token = flag.String("token", "", "Defines the x-auth-token") var ucUser = flag.String("ucUser", "", "Defines the Unifi API User") var ucPass = flag.String("ucPass", "", "Defines the Unifi API Password") var version = "development" -var delay time.Duration = 60 * time.Second +var delay time.Duration = 5 * time.Second func main() { log.Printf("starting version %s...\n", version) // parse all flags flag.Parse() - // check if token is set + + // check if flags are set if *token == "" { log.Fatalln("Please specify an API token via the flag '-token'") } @@ -46,14 +47,15 @@ func main() { if *ucUser == "" { log.Fatalln("Please specify an API User via the flag '-ucUser'") } - //getFile() + // start API processing (runs in a loop) go processAPIs() - // start webserver + // start webserver on Port 3000 serveJSON() } +//switch Unifi AP Mod IDs to Names func lookupModels(model string) string { switch model { case "BZ2", "U2S48", "U2Sv2": @@ -85,6 +87,7 @@ func lookupModels(model string) string { } } +//int to bool converter func itob(i int) bool { if i == 1 { return true @@ -92,22 +95,31 @@ func itob(i int) bool { return false } -func processUcAPIs() []node { +//Unifi Controller API processing +func processUcAPIs() ([]node, []link) { + //get list of Unifi devices to display var nodes []node + var links []link d, err := getDevices("ucDevices.json") if err != nil { log.Fatalln(err) } + //call Unifi Controller ucAPI := newAPI(*ucUser, *ucPass, ucBaseURL) + //login ucAPI.ucLogin() + //get all Sites from Controller sites, err := ucAPI.ucGetSites() if err != nil { panic(err) } + //get all devices in all sites devices, err := ucAPI.ucGetDevices(sites) if err != nil { panic(err) } + + //build nodes struct for _, jsonDevice := range d.Devices { var currentDevice ucDevice var currentJSONDevice device @@ -117,6 +129,10 @@ func processUcAPIs() []node { currentJSONDevice = jsonDevice } } + if isRemoteMACpublished(jsonDevice.MAC, d.Devices) == true { + links = ucAddLink(jsonDevice, links) + } + load, err := strconv.ParseFloat(currentDevice.Sysstats.CPU, 64) if err != nil { panic(err) @@ -160,9 +176,10 @@ func processUcAPIs() []node { Model: lookupModels(currentDevice.Model), }) } - return nodes + return nodes, links } +//UNMS API processing (Richtfunk) func processUNMSAPI() ([]node, []link) { // Variables for runtime var links []link @@ -259,10 +276,12 @@ func processAPIs() { var nodes []node var links []link - unmsNodes, links := processUNMSAPI() - ucNodes := processUcAPIs() + unmsNodes, unmsLinks := processUNMSAPI() + ucNodes, ucLinks := processUcAPIs() nodes = append(nodes, unmsNodes...) nodes = append(nodes, ucNodes...) + links = append(links, unmsLinks...) + links = append(links, ucLinks...) // assemble final struct o := output{ @@ -291,6 +310,7 @@ func getFile(url string) []byte { byteValue, _ := ioutil.ReadAll(data) return byteValue } + func getDevices(file string) (devices, error) { // get devices from JSON file jsonFile := getFile("https://git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api/raw/branch/master/" + file) @@ -462,3 +482,26 @@ func (u *ucAPIData) ucGetDevices(sites []ucSite) ([]ucDevice, error) { } return s, nil } + +func ucAddLink(dev device, links []link) []link { + for i := range links { + if links[i].SourceAddr == dev.MAC { + // link already exists + return links + } + } + if dev.LinkedTo == "" { + //no LinkedTo in ucDevices.json + return links + } + links = append(links, link{ + Type: "cable", + Source: strings.ReplaceAll(dev.MAC, ":", ""), + Target: strings.ReplaceAll(dev.GatewayNexthop, ":", ""), + SourceTQ: 100, + TargetTQ: 100, + SourceAddr: dev.MAC, + TargetAddr: dev.LinkedTo, + }) + return links +} diff --git a/types.go b/types.go index 1350f29..069e28c 100644 --- a/types.go +++ b/types.go @@ -14,6 +14,7 @@ type device struct { Name string `json:"name"` MAC string `json:"mac"` GatewayNexthop string `json:"gateway_nexthop"` + LinkedTo string `json:"linked_to"` Gateway string `json:"gateway"` Domain string `json:"domain"` Location struct {