diff --git a/render/container.go b/render/container.go index ff0745d96..219a76d9c 100644 --- a/render/container.go +++ b/render/container.go @@ -71,7 +71,7 @@ func (c connectionJoin) Render(rpt report.Report) Nodes { } } } - ret := newJoinResults() + ret := newJoinResults(inputNodes.Nodes) // Now look at all the endpoints and see which map to IP nodes for _, m := range endpoints.Nodes { @@ -94,15 +94,11 @@ func (c connectionJoin) Render(rpt report.Report) Nodes { id, found = ipNodes[report.MakeScopedEndpointNodeID(scope, addr, port)] } if found && id != "" { // not one we blanked out earlier - ret.addChild(m, id, func(id string) report.Node { - return inputNodes.Nodes[id] - }) + // We are guaranteed to find the id, so no need to pass a node constructor. + ret.addChild(m, id, nil) } } - ret.copyUnmatched(inputNodes) - ret.fixupAdjacencies(inputNodes) - ret.fixupAdjacencies(endpoints) - return ret.result() + return ret.result(endpoints) } // FilterEmpty is a Renderer which filters out nodes which have no children diff --git a/render/host.go b/render/host.go index 93a2c1ad6..180f1115d 100644 --- a/render/host.go +++ b/render/host.go @@ -9,12 +9,11 @@ import ( // // not memoised var HostRenderer = MakeReduce( - endpoints2Hosts{}, CustomRenderer{RenderFunc: nodes2Hosts, Renderer: ProcessRenderer}, CustomRenderer{RenderFunc: nodes2Hosts, Renderer: ContainerRenderer}, CustomRenderer{RenderFunc: nodes2Hosts, Renderer: ContainerImageRenderer}, CustomRenderer{RenderFunc: nodes2Hosts, Renderer: PodRenderer}, - SelectHost, + endpoints2Hosts{}, ) // nodes2Hosts maps any Nodes to host Nodes. @@ -27,7 +26,7 @@ var HostRenderer = MakeReduce( // not have enough info to do that, and the resulting graph must be // merged with a host graph to get that info. func nodes2Hosts(nodes Nodes) Nodes { - ret := newJoinResults() + ret := newJoinResults(nil) for _, n := range nodes.Nodes { if n.Topology == Pseudo { @@ -40,8 +39,7 @@ func nodes2Hosts(nodes Nodes) Nodes { }) } } - ret.fixupAdjacencies(nodes) - return ret.result() + return ret.result(nodes) } // endpoints2Hosts takes nodes from the endpoint topology and produces @@ -51,8 +49,9 @@ type endpoints2Hosts struct { func (e endpoints2Hosts) Render(rpt report.Report) Nodes { local := LocalNetworks(rpt) + hosts := SelectHost.Render(rpt) endpoints := SelectEndpoint.Render(rpt) - ret := newJoinResults() + ret := newJoinResults(hosts.Nodes) for _, n := range endpoints.Nodes { // Nodes without a hostid are treated as pseudo nodes @@ -63,11 +62,12 @@ func (e endpoints2Hosts) Render(rpt report.Report) Nodes { } else { id := report.MakeHostNodeID(report.ExtractHostID(n)) ret.addChild(n, id, func(id string) report.Node { + // we have a hostNodeID, but no matching host node; + // create a new one rather than dropping the data return report.MakeNode(id).WithTopology(report.Host). WithLatest(report.HostNodeID, timestamp, hostNodeID) }) } } - ret.fixupAdjacencies(endpoints) - return ret.result() + return ret.result(endpoints) } diff --git a/render/process.go b/render/process.go index a4f2fdef2..f1ca648e2 100644 --- a/render/process.go +++ b/render/process.go @@ -86,7 +86,7 @@ func (e endpoints2Processes) Render(rpt report.Report) Nodes { local := LocalNetworks(rpt) processes := SelectProcess.Render(rpt) endpoints := SelectEndpoint.Render(rpt) - ret := newJoinResults() + ret := newJoinResults(processes.Nodes) for _, n := range endpoints.Nodes { // Nodes without a hostid are treated as pseudo nodes @@ -106,19 +106,14 @@ func (e endpoints2Processes) Render(rpt report.Report) Nodes { hostID, _, _ := report.ParseNodeID(hostNodeID) id := report.MakeProcessNodeID(hostID, pid) ret.addChild(n, id, func(id string) report.Node { - if processNode, found := processes.Nodes[id]; found { - return processNode - } - // we have a pid, but no matching process node; create a new one rather than dropping the data + // we have a pid, but no matching process node; + // create a new one rather than dropping the data return report.MakeNode(id).WithTopology(report.Process). WithLatest(process.PID, timestamp, pid) }) } } - ret.copyUnmatched(processes) - ret.fixupAdjacencies(processes) - ret.fixupAdjacencies(endpoints) - return ret.result() + return ret.result(endpoints) } // When there is more than one connection originating from a source @@ -150,7 +145,7 @@ func hasMoreThanOneConnection(n report.Node, endpoints report.Nodes) bool { // processes2Names maps process Nodes to Nodes for each process name. func processes2Names(processes Nodes) Nodes { - ret := newJoinResults() + ret := newJoinResults(nil) for _, n := range processes.Nodes { if n.Topology == Pseudo { @@ -162,6 +157,5 @@ func processes2Names(processes Nodes) Nodes { }) } } - ret.fixupAdjacencies(processes) - return ret.result() + return ret.result(processes) } diff --git a/render/render.go b/render/render.go index bcf4c7738..b54115f42 100644 --- a/render/render.go +++ b/render/render.go @@ -166,8 +166,13 @@ type joinResults struct { mapped map[string]string // input node ID -> output node ID } -func newJoinResults() joinResults { - return joinResults{nodes: make(report.Nodes), mapped: map[string]string{}} +func newJoinResults(inputNodes report.Nodes) joinResults { + nodes := make(report.Nodes, len(inputNodes)) + for id, n := range inputNodes { + n.Adjacency = nil // result() assumes all nodes start with no adjacencies + nodes[id] = n + } + return joinResults{nodes: nodes, mapped: map[string]string{}} } // Add m as a child of the node at id, creating a new result node if @@ -202,13 +207,14 @@ func (ret *joinResults) addChildAndChildren(m report.Node, id string, create fun // Add a copy of n straight into the results func (ret *joinResults) passThrough(n report.Node) { - n.Adjacency = nil // fixupAdjacencies assumes all nodes start with blank lists + n.Adjacency = nil // result() assumes all nodes start with no adjacencies ret.nodes[n.ID] = n ret.mapped[n.ID] = n.ID } -// Rewrite Adjacency for new nodes in ret for original nodes in input -func (ret *joinResults) fixupAdjacencies(input Nodes) { +// Rewrite Adjacency of nodes in ret mapped from original nodes in +// input, and return the result. +func (ret *joinResults) result(input Nodes) Nodes { for _, n := range input.Nodes { outID, ok := ret.mapped[n.ID] if !ok { @@ -224,17 +230,6 @@ func (ret *joinResults) fixupAdjacencies(input Nodes) { } ret.nodes[outID] = out } -} - -func (ret *joinResults) copyUnmatched(input Nodes) { - for _, n := range input.Nodes { - if _, found := ret.nodes[n.ID]; !found { - ret.nodes[n.ID] = n - } - } -} - -func (ret *joinResults) result() Nodes { return Nodes{Nodes: ret.nodes} }