From ff5cf755aa13351f6d1205ad67c60e1bc53af7cc Mon Sep 17 00:00:00 2001 From: Stefan Hoffmann Date: Wed, 25 Sep 2024 17:53:38 +0200 Subject: [PATCH] Bugfixing UISP 503 Errors. Finetuning API Calls --- example.config.json | 7 +++++-- main.go | 30 +++++++++++++++++++++--------- meshviewer.go | 19 +++++++++++++++++-- types.go | 19 +++++++++++-------- unifi.go | 21 +++++++++++++-------- unms.go | 8 ++++++-- 6 files changed, 73 insertions(+), 31 deletions(-) diff --git a/example.config.json b/example.config.json index 15fb8d5..2990761 100644 --- a/example.config.json +++ b/example.config.json @@ -5,14 +5,17 @@ "APItoken": "UNMS API TOKEN", "devicesURL": "https://git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api/raw/branch/master/example.devices.json" }, - "unifi": { + "unifi": [ + { + "name": "Unifi Freifunk Troisdorf", "enabled": false, "displayusers": true, "APIUrl": "https://unifi.freifunk-troisdorf.de", "user": "APIuser", "password": "PASSWORD", "ucDevicesURL": "https://git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api/raw/branch/master/example.ucDevices.json" - }, + } + ], "meshviewer": { "enabled": false, "files": [ diff --git a/main.go b/main.go index 6aa0332..ba13759 100644 --- a/main.go +++ b/main.go @@ -9,21 +9,28 @@ import ( "net/http" "net/http/cookiejar" "os" + "sync" "time" _ "git.nils.zone/nils/prettify" ) const ( - iso8601 = "2006-01-02T15:04:05-0700" + iso8601 = "2006-01-02T15:04:05-0700" + fetchInterval = 1 * time.Minute ) // flags +var ( + lastFetchTime time.Time + cacheMutex sync.Mutex + cacheNodes []node + cacheLinks []link +) var configPath = flag.String("configPath", "config.json", "Path to config.json") var version = "development" var delay time.Duration = 60 * time.Second var conf = loadconfig(*configPath) -var ucDev = getDevices(conf.Unifi.UCDevicesURL) func main() { log.Printf("starting version %s...\n", version) @@ -71,14 +78,19 @@ func processAPIs() error { nodes = append(nodes, uispRouters...) links = append(links, uispLinks...) } - if conf.Unifi.Enabled { - log.Println("Processing Unifi") - //Process Unifi Nodes - unifiNodes, _, err := processUnifiAPI() - if err != nil { - return err + if len(conf.Unifi) > 0 { + log.Println("Anazahl der Unifi Server:", len(conf.Unifi)) + for i := range conf.Unifi { + if conf.Unifi[i].Enabled { + log.Println("Processing Unifi-Server: ", conf.Unifi[i].Name) + //Process Unifi Nodes + unifiNodes, _, err := processUnifiAPI(i) + if err != nil { + return err + } + nodes = append(nodes, unifiNodes...) + } } - nodes = append(nodes, unifiNodes...) } if conf.Meshviewer.Enabled { log.Println("Processing Meshviewer") diff --git a/meshviewer.go b/meshviewer.go index 5b02038..b3fb409 100644 --- a/meshviewer.go +++ b/meshviewer.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "log" + "time" ) func getMeshviewerJSON(url string) (mvDevices, error) { @@ -129,17 +130,31 @@ func addmvDevices(d mvDevices) ([]node, []link) { } func getMeshviewer() ([]node, []link) { + cacheMutex.Lock() + defer cacheMutex.Unlock() + + // Überprüfen, ob die Daten kürzlich aktualisiert wurden + if time.Since(lastFetchTime) < fetchInterval { + return cacheNodes, cacheLinks + } + var nodes []node var links []link for i := range conf.Meshviewer.Files { m, err := getMeshviewerJSON(conf.Meshviewer.Files[i].URL) if err != nil { - return nodes, links + return cacheNodes, cacheLinks } mvNodes, mvLinks := addmvDevices(m) nodes = append(nodes, mvNodes...) links = append(links, mvLinks...) } - return nodes, links + + // Cache aktualisieren + cacheNodes = nodes + cacheLinks = links + lastFetchTime = time.Now() + + return cacheNodes, cacheLinks } diff --git a/types.go b/types.go index 4ec914a..c7dbd7d 100644 --- a/types.go +++ b/types.go @@ -23,14 +23,7 @@ type config struct { DevicesURL string `json:"devicesURL"` RouterURL string `json:"routerURL"` } `json:"unms"` - Unifi struct { - Enabled bool `json:"enabled"` - DisplayUsers bool `json:"displayusers"` - APIURL string `json:"APIUrl"` - User string `json:"user"` - Password string `json:"password"` - UCDevicesURL string `json:"ucDevicesURL"` - } `json:"unifi"` + Unifi []UnifiServer `json:"unifi"` Meshviewer struct { Enabled bool `json:"enabled"` Files []struct { @@ -44,6 +37,16 @@ type config struct { } `json:"gateways"` } +type UnifiServer struct { + Name string `json:"name"` + Enabled bool `json:"enabled"` + DisplayUsers bool `json:"displayusers"` + APIURL string `json:"APIUrl"` + User string `json:"user"` + Password string `json:"password"` + UCDevicesURL string `json:"ucDevicesURL"` +} + type device struct { Name string `json:"name"` FQDN string `json:"fqdn"` diff --git a/unifi.go b/unifi.go index 9d0463b..f00a385 100644 --- a/unifi.go +++ b/unifi.go @@ -15,14 +15,14 @@ import ( ) // Unifi Controller API processing -func processUnifiAPI() ([]node, []link, error) { +func processUnifiAPI(s int) ([]node, []link, error) { //get list of Unifi devices to display var nodes []node var links []link - d := getDevices(conf.Unifi.UCDevicesURL) + d := getDevices(conf.Unifi[s].UCDevicesURL) //call Unifi Controller - ucAPI := UnifiNewAPI(conf.Unifi.User, conf.Unifi.Password, conf.Unifi.APIURL) + ucAPI := UnifiNewAPI(conf.Unifi[s].User, conf.Unifi[s].Password, conf.Unifi[s].APIURL) //login if err := ucAPI.ucLogin(); err != nil { return nil, nil, err @@ -49,12 +49,14 @@ func processUnifiAPI() ([]node, []link, error) { currentJSONDevice = jsonDevice } } + if isRemoteMACpublished(jsonDevice.MAC, d.Devices) { //hier muss gecheckt werden ob der link valide ist if checkMeshviewerLink(jsonDevice.LinkedTo) { links = UnifiAddLink(jsonDevice, links) } } + isOnline := currentDevice.State == 1 var load float64 var mem float64 @@ -78,7 +80,7 @@ func processUnifiAPI() ([]node, []link, error) { var model = lookupModels(currentDevice.Model) var clients int - if conf.Unifi.DisplayUsers { + if conf.Unifi[s].DisplayUsers { clients = currentDevice.Users } @@ -130,7 +132,7 @@ func processUnifiAPI() ([]node, []link, error) { } // INFLUX STOP - + //log.Println(currentDevice.Mac) nodes = append(nodes, node{ Firstseen: "0", Lastseen: time.Unix(int64(currentDevice.LastSeen), 0).Format(iso8601), @@ -268,9 +270,12 @@ func UnifiAddLink(dev device, links []link) []link { } func findNodeID(NodeID string) bool { - for i := range ucDev.Devices { - if ucDev.Devices[i].GatewayNexthop == NodeID { - return true + for s := range conf.Unifi { + ucDev := getDevices(conf.Unifi[s].UCDevicesURL) + for i := range ucDev.Devices { + if ucDev.Devices[i].GatewayNexthop == NodeID { + return true + } } } return false diff --git a/unms.go b/unms.go index 52ec7cc..0a28940 100644 --- a/unms.go +++ b/unms.go @@ -33,6 +33,7 @@ func processUISPRiFu() ([]node, []link, error) { } for i := range d.Devices { + time.Sleep(time.Second) var dev unifiAPIResponse var currentDevice device for j := range u { @@ -104,6 +105,7 @@ func processUISPRiFu() ([]node, []link, error) { } func processUISPRouter() ([]node, error) { + time.Sleep(time.Second) // Variables for runtime var nodes []node d := getDevices(conf.UISP.RouterURL) @@ -234,11 +236,12 @@ func processUISPRouter() ([]node, error) { } func UnmsCallAPI(url string, i any) error { + time.Sleep(time.Second) request, err := http.NewRequest(http.MethodGet, conf.UISP.UnmsAPIURL+url, nil) if err != nil { return errors.New(fmt.Sprint("can't set request", conf.UISP.UnmsAPIURL+url)) } - log.Println(conf.UISP.UnmsAPIURL + url) + //log.Println(conf.UISP.UnmsAPIURL + url) request.Header.Set("x-auth-token", conf.UISP.APItoken) client := &http.Client{} response, err := client.Do(request) @@ -246,7 +249,8 @@ func UnmsCallAPI(url string, i any) error { return fmt.Errorf("can't get request %s with x-auth-token %s", conf.UISP.UnmsAPIURL+url, conf.UISP.APItoken) } if response.StatusCode != 200 { - log.Fatalln("Can't call UNMS API, check token and URL. HTTP Status: ", response.StatusCode) + log.Println("Can't call UNMS API, check token and URL. Skipping device. HTTP Status: ", response.StatusCode) + return nil } data, err := ioutil.ReadAll(response.Body) defer response.Body.Close()