diff --git a/example.json b/example.json index 08121fc..e3fca68 100644 --- a/example.json +++ b/example.json @@ -1,9 +1,9 @@ { - "timestamp": "2020-12-29T18:46:27+0100", + "timestamp": "2020-12-31T12:19:04+0100", "nodes": [ { "firstseen": "2020-01-20T17:38:03+0000", - "lastseen": "2020-12-29T17:46:00+0000", + "lastseen": "2020-12-31T11:18:07+0000", "is_online": true, "is_gateway": false, "clients": 0, @@ -11,9 +11,9 @@ "clients_wifi5": 0, "clients_other": 0, "rootfs_usage": 0, - "loadavg": 0.03, - "memory_usage": 0.66, - "uptime": "2020-11-22T14:02:11+0000", + "loadavg": 0.26, + "memory_usage": 0.67, + "uptime": "2020-11-22T14:02:12+0000", "gateway_nexthop": "18e8292f7de6", "gateway": "a28cae6ff604", "location": { @@ -41,7 +41,7 @@ }, { "firstseen": "2020-05-05T20:08:20+0000", - "lastseen": "2020-12-29T17:46:08+0000", + "lastseen": "2020-12-31T11:18:26+0000", "is_online": true, "is_gateway": false, "clients": 0, @@ -49,9 +49,9 @@ "clients_wifi5": 0, "clients_other": 0, "rootfs_usage": 0, - "loadavg": 0.02, + "loadavg": 0.25, "memory_usage": 0.68, - "uptime": "2020-10-24T21:47:31+0000", + "uptime": "2020-10-24T21:47:32+0000", "gateway_nexthop": "18e8292f7de6", "gateway": "a28cae6ff604", "location": { @@ -83,8 +83,8 @@ "type": "wifi", "source": "18e8298ec64d", "target": "18e829dcc37e", - "source_tq": 0.315, - "target_tq": 0.315, + "source_tq": 0.345, + "target_tq": 0.345, "source_addr": "18:e8:29:8e:c6:4d", "target_addr": "18:e8:29:dc:c3:7e" } diff --git a/main.go b/main.go index d1a62e2..4f4359f 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,9 @@ package main import ( "encoding/json" + "errors" "flag" + "fmt" "io/ioutil" "log" "net/http" @@ -27,19 +29,27 @@ func main() { // check if token is set if *token == "" { - log.Println("Please specify an API token via the flag '-token'") - os.Exit(1) + log.Fatalln("Please specify an API token via the flag '-token'") } + log.Println("starting...") + // Variables for runtime var links []link var nodes []node - d := getDevices() + d, err := getDevices() + if err != nil { + log.Fatalln(err) + } // API CALL 1 + log.Println("calling API 1") var u []unifiAPIResponse - callUnifiAPI("/devices", &u) + err = callUnifiAPI("/devices", &u) + if err != nil { + log.Fatalln(err) + } for i := range d.Devices { var dev unifiAPIResponse @@ -51,26 +61,23 @@ func main() { } } - // fmt.Println(time.Now().Format(iso8601)) var isOnline bool = false if dev.Overview.Status == "active" { isOnline = true } - - // uptime := dev.Identification.Started.Format(iso8601) - // nodeID := strings.ReplaceAll(dev.Identification.MAC, ":", "") // END OF API CALL 1 // API CALL 2 + log.Println("calling API 2 for device", d.Devices[i].Name) var details unifiAPIDetails callUnifiAPI("/devices/erouters/"+dev.Identification.ID, &details) // END OF API CALL 2 // API CALL 3 + log.Println("calling API 3 for device", d.Devices[i].Name) var airmaxes []unifiAPIAirmax callUnifiAPI("/devices/airmaxes/"+dev.Identification.ID+"/stations", &airmaxes) // check if remote mac address is part of our published network - // if isRemoteMACpublished() for i := range airmaxes { if isRemoteMACpublished(airmaxes[i].DeviceIdentification.MAC, d.Devices) == true { links = addLink(dev, airmaxes[i], links) @@ -89,8 +96,8 @@ func main() { ClientsWifi5: 0, ClientsOther: 0, RootFSUsage: 0, - LoadAVG: details.Overview.CPU/100, - MemoryUsage: details.Overview.RAM/100, + LoadAVG: details.Overview.CPU / 100, + MemoryUsage: details.Overview.RAM / 100, Uptime: dev.Identification.Started.Format(iso8601), GatewayNexthop: currentDevice.GatewayNexthop, Gateway: currentDevice.Gateway, @@ -122,14 +129,18 @@ func main() { } // create file output + log.Println("writing json file") writeJSONtoFile(o) + + // we're done here + log.Println("...done") } -func getDevices() devices { +func getDevices() (devices, error) { // get devices from JSON file jsonFile, err := os.Open("devices.json") if err != nil { - panic(err) + return devices{}, errors.New("can't open devices.json") } defer jsonFile.Close() @@ -140,28 +151,37 @@ func getDevices() devices { var d devices // unmarshal to struct json.Unmarshal(byteValue, &d) - return d + return d, nil } -func callUnifiAPI(url string, i interface{}) { +func callUnifiAPI(url string, i interface{}) error { request, err := http.NewRequest(http.MethodGet, baseURL+url, nil) if err != nil { - panic(err) + return errors.New(fmt.Sprint("can't set request", baseURL+url)) } request.Header.Set("x-auth-token", *token) client := &http.Client{} response, err := client.Do(request) if err != nil { - panic(err) + return fmt.Errorf("can't get request %s with x-auth-token %s", baseURL+url, *token) } data, err := ioutil.ReadAll(response.Body) + defer response.Body.Close() if err != nil { - panic(err) + return fmt.Errorf("can't read response body: %+v", response.Body) } - // fmt.Println(string(data)) + // try to fetch errors + var a apiResponse + json.Unmarshal(data, &a) + if a.StatusCode != 0 { + return fmt.Errorf("got following errorcode from API: %d %s %s", a.StatusCode, a.Error, a.Message) + } + + // no error occurred, unmarshal to struct json.Unmarshal(data, &i) + return nil } func isRemoteMACpublished(mac string, devices []device) bool { @@ -192,17 +212,18 @@ func addLink(dev unifiAPIResponse, airmaxes unifiAPIAirmax, links []link) []link return links } -func writeJSONtoFile(o output) { +func writeJSONtoFile(o output) error { file, err := json.MarshalIndent(o, "", " ") if err != nil { - panic(err) + return fmt.Errorf("can't marshal to json: %+v", o) } // write to file err = ioutil.WriteFile("example.json", file, 0644) if err != nil { - panic(err) + return fmt.Errorf("can't write to json file example.json") } + return nil } func getAddresses(ip string) []string { diff --git a/types.go b/types.go index 060badd..8b4831b 100644 --- a/types.go +++ b/types.go @@ -110,3 +110,9 @@ type output struct { Nodes []node `json:"nodes"` Links []link `json:"links"` } + +type apiResponse struct { + StatusCode int `json:"statusCode"` + Error string `json:"error"` + Message string `json:"message"` +}