From f21cf472ccba8005a55f715605fe7cc33e639ece Mon Sep 17 00:00:00 2001 From: Roland Schilter Date: Wed, 12 Jul 2017 12:30:17 +0200 Subject: [PATCH] Avoid global by passing metricsGraphURL down --- app/api_report_test.go | 2 +- app/api_topologies.go | 12 +++++----- app/api_topologies_test.go | 4 ++-- app/api_topology.go | 11 ++++----- app/router.go | 8 +++---- prog/app.go | 8 +++---- render/detailed/connections.go | 12 +++++----- render/detailed/links.go | 25 +++++---------------- render/detailed/links_test.go | 19 +++------------- render/detailed/node.go | 14 ++++++------ render/detailed/node_test.go | 8 +++---- render/detailed/summary.go | 40 ++++++++++++++++++--------------- render/detailed/summary_test.go | 6 ++--- 13 files changed, 73 insertions(+), 96 deletions(-) diff --git a/app/api_report_test.go b/app/api_report_test.go index 1d7bd2b69..c1da6f800 100644 --- a/app/api_report_test.go +++ b/app/api_report_test.go @@ -14,7 +14,7 @@ import ( func topologyServer() *httptest.Server { router := mux.NewRouter().SkipClean(true) - app.RegisterTopologyRoutes(router, app.StaticCollector(fixture.Report), map[string]bool{"foo_capability": true}) + app.RegisterTopologyRoutes(router, app.StaticCollector(fixture.Report), map[string]bool{"foo_capability": true}, "") return httptest.NewServer(router) } diff --git a/app/api_topologies.go b/app/api_topologies.go index 42a62f8e1..a56a24385 100644 --- a/app/api_topologies.go +++ b/app/api_topologies.go @@ -548,17 +548,17 @@ func (r *Registry) RendererForTopology(topologyID string, values url.Values, rpt return topology.renderer, nil, nil } -type reporterHandler func(context.Context, Reporter, http.ResponseWriter, *http.Request) +type reporterHandler func(context.Context, Reporter, string, http.ResponseWriter, *http.Request) -func captureReporter(rep Reporter, f reporterHandler) CtxHandlerFunc { +func captureReporter(rep Reporter, metricsGraphURL string, f reporterHandler) CtxHandlerFunc { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) { - f(ctx, rep, w, r) + f(ctx, rep, metricsGraphURL, w, r) } } -type rendererHandler func(context.Context, render.Renderer, render.Decorator, report.Report, http.ResponseWriter, *http.Request) +type rendererHandler func(context.Context, render.Renderer, render.Decorator, report.Report, string, http.ResponseWriter, *http.Request) -func (r *Registry) captureRenderer(rep Reporter, f rendererHandler) CtxHandlerFunc { +func (r *Registry) captureRenderer(rep Reporter, metricGraphsURL string, f rendererHandler) CtxHandlerFunc { return func(ctx context.Context, w http.ResponseWriter, req *http.Request) { var ( topologyID = mux.Vars(req)["topology"] @@ -579,6 +579,6 @@ func (r *Registry) captureRenderer(rep Reporter, f rendererHandler) CtxHandlerFu respondWith(w, http.StatusInternalServerError, err) return } - f(ctx, renderer, decorator, rpt, w, req) + f(ctx, renderer, decorator, rpt, metricGraphsURL, w, req) } } diff --git a/app/api_topologies_test.go b/app/api_topologies_test.go index a817eb796..71c690639 100644 --- a/app/api_topologies_test.go +++ b/app/api_topologies_test.go @@ -183,14 +183,14 @@ func getTestContainerLabelFilterTopologySummary(t *testing.T, exclude bool) (det return nil, err } - return detailed.Summaries(fixture.Report, renderer.Render(fixture.Report, decorator)), nil + return detailed.Summaries(fixture.Report, renderer.Render(fixture.Report, decorator), ""), nil } func TestAPITopologyAddsKubernetes(t *testing.T) { router := mux.NewRouter() c := app.NewCollector(1 * time.Minute) app.RegisterReportPostHandler(c, router) - app.RegisterTopologyRoutes(router, c, map[string]bool{"foo_capability": true}) + app.RegisterTopologyRoutes(router, c, map[string]bool{"foo_capability": true}, "") ts := httptest.NewServer(router) defer ts.Close() diff --git a/app/api_topology.go b/app/api_topology.go index 173e275b9..a29f052d1 100644 --- a/app/api_topology.go +++ b/app/api_topology.go @@ -29,14 +29,14 @@ type APINode struct { } // Full topology. -func handleTopology(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, w http.ResponseWriter, r *http.Request) { +func handleTopology(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, metricsGraphURL string, w http.ResponseWriter, r *http.Request) { respondWith(w, http.StatusOK, APITopology{ - Nodes: detailed.Summaries(report, renderer.Render(report, decorator)), + Nodes: detailed.Summaries(report, renderer.Render(report, decorator), metricsGraphURL), }) } // Individual nodes. -func handleNode(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, w http.ResponseWriter, r *http.Request) { +func handleNode(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, metricsGraphURL string, w http.ResponseWriter, r *http.Request) { var ( vars = mux.Vars(r) topologyID = vars["topology"] @@ -49,13 +49,14 @@ func handleNode(ctx context.Context, renderer render.Renderer, decorator render. http.NotFound(w, r) return } - respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, report, rendered, node)}) + respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, report, rendered, node, metricsGraphURL)}) } // Websocket for the full topology. func handleWebsocket( ctx context.Context, rep Reporter, + metricsGraphURL string, w http.ResponseWriter, r *http.Request, ) { @@ -123,7 +124,7 @@ func handleWebsocket( log.Errorf("Error generating report: %v", err) return } - newTopo := detailed.Summaries(report, renderer.Render(report, decorator)) + newTopo := detailed.Summaries(report, renderer.Render(report, decorator), metricsGraphURL) diff := detailed.TopoDiff(previousTopo, newTopo) previousTopo = newTopo diff --git a/app/router.go b/app/router.go index 414f45f99..05999d293 100644 --- a/app/router.go +++ b/app/router.go @@ -91,7 +91,7 @@ func gzipHandler(h http.HandlerFunc) http.HandlerFunc { } // RegisterTopologyRoutes registers the various topology routes with a http mux. -func RegisterTopologyRoutes(router *mux.Router, r Reporter, capabilities map[string]bool) { +func RegisterTopologyRoutes(router *mux.Router, r Reporter, capabilities map[string]bool, metricsGraphURL string) { get := router.Methods("GET").Subrouter() get.HandleFunc("/api", gzipHandler(requestContextDecorator(apiHandler(r, capabilities)))) @@ -99,15 +99,15 @@ func RegisterTopologyRoutes(router *mux.Router, r Reporter, capabilities map[str gzipHandler(requestContextDecorator(topologyRegistry.makeTopologyList(r)))) get. HandleFunc("/api/topology/{topology}", - gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, handleTopology)))). + gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, metricsGraphURL, handleTopology)))). Name("api_topology_topology") get. HandleFunc("/api/topology/{topology}/ws", - requestContextDecorator(captureReporter(r, handleWebsocket))). // NB not gzip! + requestContextDecorator(captureReporter(r, metricsGraphURL, handleWebsocket))). // NB not gzip! Name("api_topology_topology_ws") get. MatcherFunc(URLMatcher("/api/topology/{topology}/{id}")).HandlerFunc( - gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, handleNode)))). + gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, metricsGraphURL, handleNode)))). Name("api_topology_topology_id") get.HandleFunc("/api/report", gzipHandler(requestContextDecorator(makeRawReportHandler(r)))) diff --git a/prog/app.go b/prog/app.go index 2647ddb41..f78054c9b 100644 --- a/prog/app.go +++ b/prog/app.go @@ -28,7 +28,6 @@ import ( "github.com/weaveworks/scope/common/weave" "github.com/weaveworks/scope/common/xfer" "github.com/weaveworks/scope/probe/docker" - "github.com/weaveworks/scope/render/detailed" "github.com/weaveworks/weave/common" ) @@ -52,7 +51,7 @@ func init() { } // Router creates the mux for all the various app components. -func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.PipeRouter, externalUI bool, capabilities map[string]bool) http.Handler { +func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.PipeRouter, externalUI bool, capabilities map[string]bool, metricsGraphURL string) http.Handler { router := mux.NewRouter().SkipClean(true) // We pull in the http.DefaultServeMux to get the pprof routes @@ -62,7 +61,7 @@ func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.RegisterReportPostHandler(collector, router) app.RegisterControlRoutes(router, controlRouter) app.RegisterPipeRoutes(router, pipeRouter) - app.RegisterTopologyRoutes(router, collector, capabilities) + app.RegisterTopologyRoutes(router, collector, capabilities, metricsGraphURL) uiHandler := http.FileServer(GetFS(externalUI)) router.PathPrefix("/ui").Name("static").Handler( @@ -217,7 +216,6 @@ func appMain(flags appFlags) { setLogLevel(flags.logLevel) setLogFormatter(flags.logPrefix) runtime.SetBlockProfileRate(flags.blockProfileRate) - detailed.SetMetricsGraphURL(flags.metricsGraphURL) defer log.Info("app exiting") rand.Seed(time.Now().UnixNano()) @@ -299,7 +297,7 @@ func appMain(flags appFlags) { capabilities := map[string]bool{ xfer.HistoricReportsCapability: collector.HasHistoricReports(), } - handler := router(collector, controlRouter, pipeRouter, flags.externalUI, capabilities) + handler := router(collector, controlRouter, pipeRouter, flags.externalUI, capabilities, flags.metricsGraphURL) if flags.logHTTP { handler = middleware.Log{ LogRequestHeaders: flags.logHTTPHeaders, diff --git a/render/detailed/connections.go b/render/detailed/connections.go index b89ebb723..337e565ac 100644 --- a/render/detailed/connections.go +++ b/render/detailed/connections.go @@ -121,13 +121,13 @@ func internetAddr(node report.Node, ep report.Node) (string, bool) { return addr, true } -func (c *connectionCounters) rows(r report.Report, ns report.Nodes, includeLocal bool) []Connection { +func (c *connectionCounters) rows(r report.Report, ns report.Nodes, includeLocal bool, metricsGraphURL string) []Connection { output := []Connection{} for row, count := range c.counts { // Use MakeNodeSummary to render the id and label of this node // TODO(paulbellamy): Would be cleaner if we hade just a // MakeNodeID(ns[row.remoteNodeID]). As we don't need the whole summary. - summary, _ := MakeNodeSummary(r, ns[row.remoteNodeID]) + summary, _ := MakeNodeSummary(r, ns[row.remoteNodeID], metricsGraphURL) connection := Connection{ ID: fmt.Sprintf("%s-%s-%s-%s", row.remoteNodeID, row.remoteAddr, row.localAddr, row.port), NodeID: summary.ID, @@ -162,7 +162,7 @@ func (c *connectionCounters) rows(r report.Report, ns report.Nodes, includeLocal return output } -func incomingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes) ConnectionsSummary { +func incomingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes, metricsGraphURL string) ConnectionsSummary { localEndpointIDs, localEndpointIDCopies := endpointChildIDsAndCopyMapOf(n) counts := newConnectionCounters() @@ -188,11 +188,11 @@ func incomingConnectionsSummary(topologyID string, r report.Report, n report.Nod TopologyID: topologyID, Label: "Inbound", Columns: columnHeaders, - Connections: counts.rows(r, ns, isInternetNode(n)), + Connections: counts.rows(r, ns, isInternetNode(n), metricsGraphURL), } } -func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes) ConnectionsSummary { +func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes, metricsGraphURL string) ConnectionsSummary { localEndpoints := endpointChildrenOf(n) counts := newConnectionCounters() @@ -220,7 +220,7 @@ func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Nod TopologyID: topologyID, Label: "Outbound", Columns: columnHeaders, - Connections: counts.rows(r, ns, isInternetNode(n)), + Connections: counts.rows(r, ns, isInternetNode(n), metricsGraphURL), } } diff --git a/render/detailed/links.go b/render/detailed/links.go index 3de365e23..fa9084d4a 100644 --- a/render/detailed/links.go +++ b/render/detailed/links.go @@ -15,7 +15,7 @@ import ( // MetricLink describes a URL referencing a metric. type MetricLink struct { // References the metric id - ID string `json:"id,omitempty"` + ID string `json:"id"` Label string `json:"label"` URL string `json:"url"` Priority int `json:"priority"` @@ -25,9 +25,6 @@ type MetricLink struct { const urlQueryVarName = ":query" var ( - // As configured by the user - metricsGraphURL = "" - // Available metric links linkTemplates = []MetricLink{ {ID: docker.CPUTotalUsage, Label: "CPU", Priority: 1}, @@ -105,22 +102,10 @@ var ( } ) -// SetMetricsGraphURL sets the URL we deduce our eventual metric link from. -// Supports placeholders such as `:orgID` and `:query`. An empty url disables -// this feature. If the `:query` part is missing, a JSON version will be -// appended, see `queryParamsAsJSON()` for more info. -func SetMetricsGraphURL(url string) { - metricsGraphURL = url -} - // NodeMetricLinks returns the links of a node. The links are collected // by a predefined set but filtered depending on whether a query // is configured or not for the particular topology. func NodeMetricLinks(_ report.Report, n report.Node) []MetricLink { - if metricsGraphURL == "" { - return nil - } - queries := topologyQueries[n.Topology] if len(queries) == 0 { return nil @@ -137,8 +122,10 @@ func NodeMetricLinks(_ report.Report, n report.Node) []MetricLink { } // RenderMetricLinks executes the templated links by supplying the node summary as data. +// `metricsGraphURL` supports placeholders such as `:orgID` and `:query`. If the `:query` +// part is missing, a JSON version will be appended, see `queryParamsAsJSON()` for more info. // It returns the modified summary. -func RenderMetricLinks(summary NodeSummary, n report.Node) NodeSummary { +func RenderMetricLinks(summary NodeSummary, n report.Node, metricsGraphURL string) NodeSummary { queries := topologyQueries[n.Topology] if len(queries) == 0 || len(summary.MetricLinks) == 0 { return summary @@ -157,7 +144,7 @@ func RenderMetricLinks(summary NodeSummary, n report.Node) NodeSummary { continue } - link.URL = buildURL(bs.String()) + link.URL = buildURL(bs.String(), metricsGraphURL) links = append(links, link) } summary.MetricLinks = links @@ -167,7 +154,7 @@ func RenderMetricLinks(summary NodeSummary, n report.Node) NodeSummary { // buildURL puts together the URL by looking at the configured // `metricsGraphURL`. -func buildURL(query string) string { +func buildURL(query, metricsGraphURL string) string { if strings.Contains(metricsGraphURL, urlQueryVarName) { return strings.Replace(metricsGraphURL, urlQueryVarName, url.PathEscape(query), -1) } diff --git a/render/detailed/links_test.go b/render/detailed/links_test.go index 5bb4e3704..29328d7d2 100644 --- a/render/detailed/links_test.go +++ b/render/detailed/links_test.go @@ -16,21 +16,12 @@ var ( sampleUnknownNode = report.MakeNode("???").WithTopology("foo") ) -func TestNodeMetricLinks_DefaultDisabled(t *testing.T) { - links := detailed.NodeMetricLinks(sampleReport, samplePodNode) - assert.Nil(t, links) -} - func TestNodeMetricLinks_UnknownTopology(t *testing.T) { - detailed.SetMetricsGraphURL("/foo") - links := detailed.NodeMetricLinks(sampleReport, sampleUnknownNode) assert.Nil(t, links) } func TestNodeMetricLinks(t *testing.T) { - detailed.SetMetricsGraphURL("/foo") - defer detailed.SetMetricsGraphURL("") expected := []detailed.MetricLink{ {ID: docker.CPUTotalUsage, Label: "CPU", Priority: 1, URL: ""}, {ID: docker.MemoryUsage, Label: "Memory", Priority: 2, URL: ""}, @@ -43,16 +34,14 @@ func TestNodeMetricLinks(t *testing.T) { func TestRenderMetricLinks_UnknownTopology(t *testing.T) { summary := detailed.NodeSummary{} - result := detailed.RenderMetricLinks(summary, sampleUnknownNode) + result := detailed.RenderMetricLinks(summary, sampleUnknownNode, "") assert.Equal(t, summary, result) } func TestRenderMetricLinks_Pod(t *testing.T) { - detailed.SetMetricsGraphURL("/prom/:orgID/notebook/new") - defer detailed.SetMetricsGraphURL("") summary := detailed.NodeSummary{Label: "woo", MetricLinks: detailed.NodeMetricLinks(sampleReport, samplePodNode)} - result := detailed.RenderMetricLinks(summary, samplePodNode) + result := detailed.RenderMetricLinks(summary, samplePodNode, "/prom/:orgID/notebook/new") assert.Equal(t, "/prom/:orgID/notebook/new/%7B%22cells%22:%5B%7B%22queries%22:%5B%22sum%28rate%28container_cpu_usage_seconds_total%7Bpod_name=%5C%22woo%5C%22%7D%5B1m%5D%29%29%22%5D%7D%5D%7D", result.MetricLinks[0].URL) @@ -62,11 +51,9 @@ func TestRenderMetricLinks_Pod(t *testing.T) { } func TestRenderMetricLinks_QueryReplacement(t *testing.T) { - detailed.SetMetricsGraphURL("/foo/:orgID/bar?q=:query") - defer detailed.SetMetricsGraphURL("") summary := detailed.NodeSummary{Label: "boo", MetricLinks: detailed.NodeMetricLinks(sampleReport, samplePodNode)} - result := detailed.RenderMetricLinks(summary, samplePodNode) + result := detailed.RenderMetricLinks(summary, samplePodNode, "/foo/:orgID/bar?q=:query") assert.Equal(t, "/foo/:orgID/bar?q=sum%28rate%28container_cpu_usage_seconds_total%7Bpod_name=%22boo%22%7D%5B1m%5D%29%29", result.MetricLinks[0].URL) diff --git a/render/detailed/node.go b/render/detailed/node.go index 8e211b813..1481d99d8 100644 --- a/render/detailed/node.go +++ b/render/detailed/node.go @@ -80,15 +80,15 @@ func (c *ControlInstance) CodecDecodeSelf(decoder *codec.Decoder) { // MakeNode transforms a renderable node to a detailed node. It uses // aggregate metadata, plus the set of origin node IDs, to produce tables. -func MakeNode(topologyID string, r report.Report, ns report.Nodes, n report.Node) Node { - summary, _ := MakeNodeSummary(r, n) +func MakeNode(topologyID string, r report.Report, ns report.Nodes, n report.Node, metricsGraphURL string) Node { + summary, _ := MakeNodeSummary(r, n, metricsGraphURL) return Node{ NodeSummary: summary, Controls: controls(r, n), - Children: children(r, n), + Children: children(r, n, metricsGraphURL), Connections: []ConnectionsSummary{ - incomingConnectionsSummary(topologyID, r, n, ns), - outgoingConnectionsSummary(topologyID, r, n, ns), + incomingConnectionsSummary(topologyID, r, n, ns, metricsGraphURL), + outgoingConnectionsSummary(topologyID, r, n, ns, metricsGraphURL), }, } } @@ -181,13 +181,13 @@ var nodeSummaryGroupSpecs = []struct { }, } -func children(r report.Report, n report.Node) []NodeSummaryGroup { +func children(r report.Report, n report.Node, metricsGraphURL string) []NodeSummaryGroup { summaries := map[string][]NodeSummary{} n.Children.ForEach(func(child report.Node) { if child.ID == n.ID { return } - summary, ok := MakeNodeSummary(r, child) + summary, ok := MakeNodeSummary(r, child, metricsGraphURL) if !ok { return } diff --git a/render/detailed/node_test.go b/render/detailed/node_test.go index d7c213ae4..b61229759 100644 --- a/render/detailed/node_test.go +++ b/render/detailed/node_test.go @@ -18,7 +18,7 @@ import ( ) func child(t *testing.T, r render.Renderer, id string) detailed.NodeSummary { - s, ok := detailed.MakeNodeSummary(fixture.Report, r.Render(fixture.Report, nil)[id]) + s, ok := detailed.MakeNodeSummary(fixture.Report, r.Render(fixture.Report, nil)[id], "") if !ok { t.Fatalf("Expected node %s to be summarizable, but wasn't", id) } @@ -32,7 +32,7 @@ func connectionID(nodeID string, addr string) string { func TestMakeDetailedHostNode(t *testing.T) { renderableNodes := render.HostRenderer.Render(fixture.Report, nil) renderableNode := renderableNodes[fixture.ClientHostNodeID] - have := detailed.MakeNode("hosts", fixture.Report, renderableNodes, renderableNode) + have := detailed.MakeNode("hosts", fixture.Report, renderableNodes, renderableNode, "") containerImageNodeSummary := child(t, render.ContainerImageRenderer, expected.ClientContainerImageNodeID) containerNodeSummary := child(t, render.ContainerRenderer, fixture.ClientContainerNodeID) @@ -183,7 +183,7 @@ func TestMakeDetailedContainerNode(t *testing.T) { if !ok { t.Fatalf("Node not found: %s", id) } - have := detailed.MakeNode("containers", fixture.Report, renderableNodes, renderableNode) + have := detailed.MakeNode("containers", fixture.Report, renderableNodes, renderableNode, "") serverProcessNodeSummary := child(t, render.ProcessRenderer, fixture.ServerProcessNodeID) serverProcessNodeSummary.Linkable = true @@ -313,7 +313,7 @@ func TestMakeDetailedPodNode(t *testing.T) { if !ok { t.Fatalf("Node not found: %s", id) } - have := detailed.MakeNode("pods", fixture.Report, renderableNodes, renderableNode) + have := detailed.MakeNode("pods", fixture.Report, renderableNodes, renderableNode, "") containerNodeSummary := child(t, render.ContainerWithImageNameRenderer, fixture.ServerContainerNodeID) serverProcessNodeSummary := child(t, render.ProcessRenderer, fixture.ServerProcessNodeID) diff --git a/render/detailed/summary.go b/render/detailed/summary.go index 5a0a8d115..697e7ecdd 100644 --- a/render/detailed/summary.go +++ b/render/detailed/summary.go @@ -103,20 +103,21 @@ var primaryAPITopology = map[string]string{ } // MakeNodeSummary summarizes a node, if possible. -func MakeNodeSummary(r report.Report, n report.Node) (NodeSummary, bool) { +func MakeNodeSummary(r report.Report, n report.Node, metricsGraphURL string) (NodeSummary, bool) { + metricLinks := metricsGraphURL != "" if renderer, ok := renderers[n.Topology]; ok { // Skip (and don't fall through to fallback) if renderer maps to nil if renderer != nil { - summary, b := renderer(baseNodeSummary(r, n), n) - return RenderMetricLinks(summary, n), b + summary, b := renderer(baseNodeSummary(r, n, metricLinks), n) + return RenderMetricLinks(summary, n, metricsGraphURL), b } } else if _, ok := r.Topology(n.Topology); ok { - summary := baseNodeSummary(r, n) + summary := baseNodeSummary(r, n, metricLinks) summary.Label = n.ID // This is unlikely to look very good, but is a reasonable fallback return summary, true } if strings.HasPrefix(n.Topology, "group:") { - return groupNodeSummary(baseNodeSummary(r, n), r, n) + return groupNodeSummary(baseNodeSummary(r, n, metricLinks), r, n) } return NodeSummary{}, false } @@ -132,19 +133,22 @@ func (n NodeSummary) SummarizeMetrics() NodeSummary { return n } -func baseNodeSummary(r report.Report, n report.Node) NodeSummary { +func baseNodeSummary(r report.Report, n report.Node, metricLinks bool) NodeSummary { t, _ := r.Topology(n.Topology) - return NodeSummary{ - ID: n.ID, - Shape: t.GetShape(), - Linkable: true, - Metadata: NodeMetadata(r, n), - Metrics: NodeMetrics(r, n), - MetricLinks: NodeMetricLinks(r, n), - Parents: Parents(r, n), - Tables: NodeTables(r, n), - Adjacency: n.Adjacency, + ns := NodeSummary{ + ID: n.ID, + Shape: t.GetShape(), + Linkable: true, + Metadata: NodeMetadata(r, n), + Metrics: NodeMetrics(r, n), + Parents: Parents(r, n), + Tables: NodeTables(r, n), + Adjacency: n.Adjacency, } + if metricLinks { + ns.MetricLinks = NodeMetricLinks(r, n) + } + return ns } func pseudoNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) { @@ -373,11 +377,11 @@ func (s nodeSummariesByID) Less(i, j int) bool { return s[i].ID < s[j].ID } type NodeSummaries map[string]NodeSummary // Summaries converts RenderableNodes into a set of NodeSummaries -func Summaries(r report.Report, rns report.Nodes) NodeSummaries { +func Summaries(r report.Report, rns report.Nodes, metricsGraphURL string) NodeSummaries { result := NodeSummaries{} for id, node := range rns { - if summary, ok := MakeNodeSummary(r, node); ok { + if summary, ok := MakeNodeSummary(r, node, metricsGraphURL); ok { for i, m := range summary.Metrics { summary.Metrics[i] = m.Summary() } diff --git a/render/detailed/summary_test.go b/render/detailed/summary_test.go index e4a5ad72d..4bf843bc4 100644 --- a/render/detailed/summary_test.go +++ b/render/detailed/summary_test.go @@ -21,7 +21,7 @@ import ( func TestSummaries(t *testing.T) { { // Just a convenient source of some rendered nodes - have := detailed.Summaries(fixture.Report, render.ProcessRenderer.Render(fixture.Report, nil)) + have := detailed.Summaries(fixture.Report, render.ProcessRenderer.Render(fixture.Report, nil), "") // The ids of the processes rendered above expectedIDs := []string{ fixture.ClientProcess1NodeID, @@ -51,7 +51,7 @@ func TestSummaries(t *testing.T) { input := fixture.Report.Copy() input.Process.Nodes[fixture.ClientProcess1NodeID].Metrics[process.CPUUsage] = metric - have := detailed.Summaries(input, render.ProcessRenderer.Render(input, nil)) + have := detailed.Summaries(input, render.ProcessRenderer.Render(input, nil), "") node, ok := have[fixture.ClientProcess1NodeID] if !ok { @@ -184,7 +184,7 @@ func TestMakeNodeSummary(t *testing.T) { }, } for _, testcase := range testcases { - have, ok := detailed.MakeNodeSummary(fixture.Report, testcase.input) + have, ok := detailed.MakeNodeSummary(fixture.Report, testcase.input, "") if ok != testcase.ok { t.Errorf("%s: MakeNodeSummary failed: expected ok value to be: %v", testcase.name, testcase.ok) continue