2013-10-03 22:19:10 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"html/template"
|
|
|
|
"os"
|
2013-10-04 12:58:58 +00:00
|
|
|
"os/exec"
|
2013-10-03 22:19:10 +00:00
|
|
|
"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)
|
2013-10-04 12:58:58 +00:00
|
|
|
fmt.Printf("Running on http://0.0.0.0:8080\n")
|
2013-10-03 22:19:10 +00:00
|
|
|
http.ListenAndServe(":8080", nil)
|
|
|
|
}
|