mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 18:20:27 +00:00
106 lines
2.8 KiB
Go
106 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/weaveworks/scope/render"
|
|
"github.com/weaveworks/scope/xfer"
|
|
)
|
|
|
|
// APITopologyDesc is returned in a list by the /api/topology handler.
|
|
type APITopologyDesc struct {
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
SubTopologies []APITopologyDesc `json:"sub_topologies,omitempty"`
|
|
Options map[string][]APITopologyOption `json:"options"`
|
|
Stats *topologyStats `json:"stats,omitempty"`
|
|
}
|
|
|
|
// APITopologyOption describes a ¶m=value to a given topology.
|
|
type APITopologyOption struct {
|
|
Value string `json:"value"`
|
|
Display string `json:"display"`
|
|
Default bool `json:"default,omitempty"`
|
|
}
|
|
|
|
type topologyStats struct {
|
|
NodeCount int `json:"node_count"`
|
|
NonpseudoNodeCount int `json:"nonpseudo_node_count"`
|
|
EdgeCount int `json:"edge_count"`
|
|
}
|
|
|
|
// makeTopologyList returns a handler that yields an APITopologyList.
|
|
func makeTopologyList(rep xfer.Reporter) func(w http.ResponseWriter, r *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
rpt = rep.Report()
|
|
topologies = []APITopologyDesc{}
|
|
)
|
|
for name, def := range topologyRegistry {
|
|
// Don't show sub-topologies at the top level.
|
|
if def.parent != "" {
|
|
continue
|
|
}
|
|
|
|
// Collect all sub-topologies of this one, depth=1 only.
|
|
subTopologies := []APITopologyDesc{}
|
|
for subName, subDef := range topologyRegistry {
|
|
if subDef.parent == name {
|
|
subTopologies = append(subTopologies, APITopologyDesc{
|
|
Name: subDef.human,
|
|
URL: "/api/topology/" + subName,
|
|
Options: makeTopologyOptions(subDef),
|
|
Stats: stats(subDef.renderer.Render(rpt)),
|
|
})
|
|
}
|
|
}
|
|
|
|
// Append.
|
|
topologies = append(topologies, APITopologyDesc{
|
|
Name: def.human,
|
|
URL: "/api/topology/" + name,
|
|
SubTopologies: subTopologies,
|
|
Options: makeTopologyOptions(def),
|
|
Stats: stats(def.renderer.Render(rpt)),
|
|
})
|
|
}
|
|
respondWith(w, http.StatusOK, topologies)
|
|
}
|
|
}
|
|
|
|
func makeTopologyOptions(view topologyView) map[string][]APITopologyOption {
|
|
options := map[string][]APITopologyOption{}
|
|
for param, optionVals := range view.options {
|
|
for _, optionVal := range optionVals {
|
|
options[param] = append(options[param], APITopologyOption{
|
|
Value: optionVal.value,
|
|
Display: optionVal.human,
|
|
Default: optionVal.def,
|
|
})
|
|
}
|
|
}
|
|
return options
|
|
}
|
|
|
|
func stats(r render.RenderableNodes) *topologyStats {
|
|
var (
|
|
nodes int
|
|
realNodes int
|
|
edges int
|
|
)
|
|
|
|
for _, n := range r {
|
|
nodes++
|
|
if !n.Pseudo {
|
|
realNodes++
|
|
}
|
|
edges += len(n.Adjacency)
|
|
}
|
|
|
|
return &topologyStats{
|
|
NodeCount: nodes,
|
|
NonpseudoNodeCount: realNodes,
|
|
EdgeCount: edges,
|
|
}
|
|
}
|