vpn-status/server.go

112 lines
2.3 KiB
Go

package main
import (
"fmt"
"net/http"
"html/template"
"os"
"os/exec"
"regexp"
"strconv"
"bytes"
"encoding/json"
)
var indexTemplate = template.Must(template.ParseFiles("html/index.html"))
var nodeList = []string{"higgsboson.vpn","turingmachine.vpn"}
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
type IndexPage struct {
Title string
Nodes []string
}
type Status int
const (
On Status = iota
Off
Slow
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
indexTemplate.Execute(w, &IndexPage{Title: "VPN Node Status", Nodes: nodeList})
}
func ping(node string) (int64) {
cmd := exec.Command("fping", "-e", node)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err == nil {
match := regexp.MustCompile("\\d+").Find(out.Bytes())
if (match != nil) {
time, _ := strconv.ParseInt(string(match), 10, 0);
return time;
}
return -1
} else {
return -1
}
}
type NodeStatus struct {
Domain string
Status string
Ping int64
}
const lenPath = len("/status/")
func statusHandler(w http.ResponseWriter, r *http.Request) {
node := r.URL.Path[lenPath:];
if ! stringInSlice(node, nodeList) {
w.WriteHeader(http.StatusNotFound)
} else {
var state string
elapsed := ping(node);
if elapsed == -1 {
state = "DOWN"
} else if elapsed > 200 {
state = "SLOW"
} else {
state = "UP"
}
status := &NodeStatus{Domain: node, Status: state, Ping: elapsed}
s, err := json.Marshal(status)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Printf("error while serializing json %s", err)
} else {
w.Write(s)
}
}
}
func main() {
config, err := os.Open("./nodes.json")
if err != nil {
fmt.Printf("Cannot open nodes.json: '%s'", err)
os.Exit(1);
}
jsonParser := json.NewDecoder(config)
if err = jsonParser.Decode(&nodeList); err != nil {
fmt.Printf("parsing config file: '%s'", err.Error())
os.Exit(1);
}
http.HandleFunc("/status/", statusHandler)
http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets/"))))
http.HandleFunc("/", indexHandler)
fmt.Printf("Running on http://0.0.0.0:8080\n")
http.ListenAndServe(":8080", nil)
}