From c7af02776f84ee3b650d9216676b3a64e0b53f53 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 21 Jan 2015 21:03:16 +0000 Subject: [PATCH] Obtain status info in JSON format --- router/json.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ weaver/main.go | 5 ++++ 2 files changed, 83 insertions(+) create mode 100644 router/json.go diff --git a/router/json.go b/router/json.go new file mode 100644 index 00000000..12382272 --- /dev/null +++ b/router/json.go @@ -0,0 +1,78 @@ +package router + +import ( + "encoding/json" + "fmt" + "time" +) + +func (router *Router) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Name, Interface string + Macs *MacCache + Peers *Peers + Routes *Routes + }{router.Ourself.Name.String(), fmt.Sprintf("%v", router.Iface), router.Macs, router.Peers, router.Routes}) + // leaving out ConectionMaker due to async complexities +} + +func (cache *MacCache) MarshalJSON() ([]byte, error) { + type cacheEntry struct { + Mac string + PeerName PeerName + LastSeen time.Time + } + entries := make([]*cacheEntry, 0) + for key, entry := range cache.table { + entries = append(entries, &cacheEntry{intmac(key).String(), entry.peer.Name, entry.lastSeen}) + } + return json.Marshal(entries) +} + +func (peers *Peers) MarshalJSON() ([]byte, error) { + ps := make([]*Peer, 0) + peers.ForEach(func(_ PeerName, peer *Peer) { ps = append(ps, peer) }) + return json.Marshal(ps) +} + +func (routes *Routes) MarshalJSON() ([]byte, error) { + routes.RLock() + defer routes.RUnlock() + type uni struct { + Dest, Via PeerName + } + type broad struct { + Source PeerName + Via []PeerName + } + var r struct { + Unicast []*uni + Broadcast []*broad + } + for name, hop := range routes.unicast { + r.Unicast = append(r.Unicast, &uni{name, hop}) + } + for name, hops := range routes.broadcast { + r.Broadcast = append(r.Broadcast, &broad{name, hops}) + } + return json.Marshal(r) +} + +func (peer *Peer) MarshalJSON() ([]byte, error) { + conns := make([]Connection, 0) + peer.ForEachConnection(func(remoteName PeerName, conn Connection) { + conns = append(conns, conn) + }) + return json.Marshal(struct { + Name string + Connections []Connection + }{peer.Name.String(), conns}) +} + +func (conn *RemoteConnection) MarshalJSON() ([]byte, error) { + return json.Marshal(struct{ RemoteName, TcpAddr string }{conn.Remote().Name.String(), conn.RemoteTCPAddr()}) +} + +func (name PeerName) MarshalJSON() ([]byte, error) { + return json.Marshal(name.String()) +} diff --git a/weaver/main.go b/weaver/main.go index de62f30b..ce0a8290 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -145,6 +145,11 @@ func handleHttp(router *weave.Router) { io.WriteString(w, fmt.Sprintln("Encryption", encryption)) io.WriteString(w, router.Status()) }) + http.HandleFunc("/status-json", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + json, _ := router.MarshalJSON() + w.Write(json) + }) http.HandleFunc("/connect", func(w http.ResponseWriter, r *http.Request) { peer := r.FormValue("peer") if addr, err := net.ResolveTCPAddr("tcp4", weave.NormalisePeerAddr(peer)); err == nil {