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 }