| 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) |
| } |