ubnt-freifunk-map-api/main.go
Stefan Hoffmann ff5cf755aa Bugfixing UISP 503 Errors.
Finetuning API Calls
2024-09-25 17:53:38 +02:00

200 lines
4.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/http"
"net/http/cookiejar"
"os"
"sync"
"time"
_ "git.nils.zone/nils/prettify"
)
const (
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)
func main() {
log.Printf("starting version %s...\n", version)
// parse all flags
flag.Parse()
// check if flags are set
if *configPath == "" {
log.Fatalln("Please specify path to config.json flag '-configPath'")
}
// start API processing (runs in a loop)
go func() {
if err := processAPIs(); err != nil {
log.Fatalln("API processing failed, error is: ", err)
}
tick := time.Tick(delay)
for range tick {
if err := processAPIs(); err != nil {
log.Fatalln("API processing failed, error is: ", err)
}
}
}()
// start webserver on Port 3000
serveJSON()
}
func processAPIs() error {
var nodes []node
var links []link
if conf.UISP.Enabled {
log.Println("Processing UISP")
//Process UISP RiFu Nodes
uispNodes, uispLinks, err := processUISPRiFu()
if err != nil {
return err
}
//Process UISP Routers (like EDGE Router)
uispRouters, err := processUISPRouter()
if err != nil {
return err
}
nodes = append(nodes, uispNodes...)
nodes = append(nodes, uispRouters...)
links = append(links, uispLinks...)
}
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...)
}
}
}
if conf.Meshviewer.Enabled {
log.Println("Processing Meshviewer")
mvNodes, mvLinks := getMeshviewer()
nodes = append(nodes, mvNodes...)
links = append(links, mvLinks...)
}
if conf.Gateways.Enabled {
log.Println("Processing Gateways")
//Process Static Gateways from Json
gwNodes := processGateways()
nodes = append(nodes, gwNodes...)
}
// assemble final struct
o := output{
Timestamp: time.Now().Format(iso8601),
Nodes: nodes,
Links: links,
}
// create file output
log.Println("writing json file")
if err := o.writeToFile(); err != nil {
log.Fatalln(err)
}
// we're done here
log.Println("...done")
return nil
}
func loadconfig(file string) config {
var config config
configFile, err := os.Open(file)
if err != nil {
log.Fatalln("Failed loding Config file: ", err)
}
jsonParse := json.NewDecoder(configFile)
if err := jsonParse.Decode(&config); err != nil {
log.Fatalln(err)
}
return config
}
// int to bool converter
func itob(i int) bool {
return i == 1
}
// function to get file from meshviewer
func getFile(url string) []byte {
resp, err := http.Get(url)
if err != nil {
log.Println("Error getting file from:", url)
}
data := resp.Body
byteValue, _ := io.ReadAll(data)
return byteValue
}
// get devices from devices file on webserver (config)
func getDevices(url string) devices {
// get devices from JSON file
jsonFile := getFile(url)
// read file to bytes
// variable for d
var d devices
// unmarshal to struct
err := json.Unmarshal(jsonFile, &d)
if err != nil {
fmt.Println("can´t get devices file from " + url)
log.Fatal(err)
}
return d
}
// check for MAC Adress in current Devices
func isRemoteMACpublished(mac string, devices []device) bool {
for i := range devices {
if devices[i].MAC == mac {
return true
}
}
return false
}
func serveJSON() {
fs := http.FileServer(http.Dir("./output"))
http.Handle("/", fs)
log.Println("Listening on :3000...")
err := http.ListenAndServe(":3000", nil)
if err != nil {
log.Fatalln(err)
}
}
func httpClient() *http.Client {
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatal(err)
}
client := &http.Client{Jar: jar}
return client
}