forked from hswaw/hscloud
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"code.hackerspace.pl/q3k/topo/graph"
|
|
"github.com/gobuffalo/packr"
|
|
"github.com/golang/glog"
|
|
"github.com/q3k/statusz"
|
|
)
|
|
|
|
type ServiceConfig struct {
|
|
DebugListen string
|
|
}
|
|
|
|
type Service struct {
|
|
gr *graph.Graph
|
|
config ServiceConfig
|
|
}
|
|
|
|
func NewService(gr *graph.Graph, c ServiceConfig) *Service {
|
|
return &Service{
|
|
gr: gr,
|
|
config: c,
|
|
}
|
|
}
|
|
|
|
type TopologyStatus struct {
|
|
}
|
|
|
|
const topologyFragment = `
|
|
<script src="/assets/viz.js"></script>
|
|
<script>
|
|
|
|
var viz = new Viz({ workerURL: '/assets/full.render.js' });
|
|
var xmlhttp = new XMLHttpRequest();
|
|
xmlhttp.onreadystatechange = function() {
|
|
if (this.readyState == 4 && this.status == 200) {
|
|
var dot = this.responseText;
|
|
viz.renderSVGElement(dot)
|
|
.then(function(element) {
|
|
document.body.appendChild(element);
|
|
});
|
|
}
|
|
};
|
|
xmlhttp.open('GET', '/debug/graphviz');
|
|
xmlhttp.send();
|
|
|
|
</script>
|
|
`
|
|
|
|
func (s *Service) Run() {
|
|
assets := packr.NewBox("./assets")
|
|
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(assets)))
|
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
http.Redirect(w, r, "/debug/status", http.StatusSeeOther)
|
|
})
|
|
|
|
http.HandleFunc("/debug/graphviz", func(w http.ResponseWriter, r *http.Request) {
|
|
fmt.Fprintf(w, "graph G {\n")
|
|
for _, machine := range s.gr.Machines {
|
|
fmt.Fprintf(w, " subgraph cluster%s {\n", machine.Name)
|
|
fmt.Fprintf(w, " label = %s\n", machine.Name)
|
|
for _, port := range machine.Ports {
|
|
a := machine.Name + "|" + port.Name
|
|
fmt.Fprintf(w, " %q [label = %q]\n", a, port.Name)
|
|
}
|
|
fmt.Fprintf(w, " }\n")
|
|
}
|
|
for _, sw := range s.gr.Switches {
|
|
fmt.Fprintf(w, " subgraph cluster%s {\n", sw.Name)
|
|
fmt.Fprintf(w, " label = %s\n", sw.Name)
|
|
for _, port := range sw.Ports {
|
|
a := sw.Name + "|" + port.Name
|
|
fmt.Fprintf(w, " %q [label = %q]\n", a, port.Name)
|
|
}
|
|
fmt.Fprintf(w, " }\n")
|
|
}
|
|
for _, machine := range s.gr.Machines {
|
|
for _, port := range machine.Ports {
|
|
if port.OtherEnd == nil {
|
|
continue
|
|
}
|
|
a := machine.Name + "|" + port.Name
|
|
b := port.OtherEnd.Switch.Name + "|" + port.OtherEnd.Name
|
|
fmt.Fprintf(w, " %q -- %q\n", a, b)
|
|
}
|
|
}
|
|
fmt.Fprintf(w, "}\n")
|
|
})
|
|
|
|
statusz.AddStatusPart("Topology", topologyFragment, func(ctx context.Context) interface{} {
|
|
return &TopologyStatus{}
|
|
})
|
|
glog.Infof("Debug listening on %s....", s.config.DebugListen)
|
|
http.ListenAndServe(s.config.DebugListen, nil)
|
|
}
|