From 7d261d0ca054cb684da4f9412853b46515b0c45a Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Wed, 20 Dec 2017 13:15:13 +0000 Subject: [PATCH 1/3] don't map image adjacencies to hosts it's just wrong --- render/host.go | 18 +++++++++++++++--- render/render.go | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/render/host.go b/render/host.go index 180f1115d..4d5ca7f4a 100644 --- a/render/host.go +++ b/render/host.go @@ -32,11 +32,23 @@ func nodes2Hosts(nodes Nodes) Nodes { if n.Topology == Pseudo { continue // Don't propagate pseudo nodes - we do this in endpoints2Hosts } + isImage := n.Topology == report.ContainerImage hostIDs, _ := n.Parents.Lookup(report.Host) for _, id := range hostIDs { - ret.addChild(n, id, func(id string) report.Node { - return report.MakeNode(id).WithTopology(report.Host) - }) + if isImage { + // We need to treat image nodes specially because they + // aggregate adjacencies of containers across multiple + // hosts, and hence mapping these adjacencies to host + // adjacencies would produce edges that aren't present + // in reality. + ret.addUnmappedChild(n, id, func(id string) report.Node { + return report.MakeNode(id).WithTopology(report.Host) + }) + } else { + ret.addChild(n, id, func(id string) report.Node { + return report.MakeNode(id).WithTopology(report.Host) + }) + } } } return ret.result(nodes) diff --git a/render/render.go b/render/render.go index 48bd250d7..26b30b075 100644 --- a/render/render.go +++ b/render/render.go @@ -185,6 +185,20 @@ func (ret *joinResults) add(m report.Node, n report.Node) { } } +// Add m as a child of the node at id, creating a new result node if +// not already there. +func (ret *joinResults) addUnmappedChild(m report.Node, id string, create func(string) report.Node) { + result, exists := ret.nodes[id] + if !exists { + result = create(id) + } + result.Children = result.Children.Add(m) + if m.Topology != report.Endpoint { // optimisation: we never look at endpoint counts + result.Counters = result.Counters.Add(m.Topology, 1) + } + ret.nodes[id] = result +} + // Add m as a child of the node at id, creating a new result node if // not already there, and updating the mapping from old ID to new ID. func (ret *joinResults) addChild(m report.Node, id string, create func(string) report.Node) { From 9713a156c7064a1ad7c383136b9492c7750da87d Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Wed, 20 Dec 2017 18:17:26 +0000 Subject: [PATCH 2/3] refactor: extract helper --- render/host.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/render/host.go b/render/host.go index 4d5ca7f4a..1e1e0b0a9 100644 --- a/render/host.go +++ b/render/host.go @@ -16,6 +16,10 @@ var HostRenderer = MakeReduce( endpoints2Hosts{}, ) +func newHostNode(id string) report.Node { + return report.MakeNode(id).WithTopology(report.Host) +} + // nodes2Hosts maps any Nodes to host Nodes. // // If this function is given a node without a hostname @@ -41,13 +45,9 @@ func nodes2Hosts(nodes Nodes) Nodes { // hosts, and hence mapping these adjacencies to host // adjacencies would produce edges that aren't present // in reality. - ret.addUnmappedChild(n, id, func(id string) report.Node { - return report.MakeNode(id).WithTopology(report.Host) - }) + ret.addUnmappedChild(n, id, newHostNode) } else { - ret.addChild(n, id, func(id string) report.Node { - return report.MakeNode(id).WithTopology(report.Host) - }) + ret.addChild(n, id, newHostNode) } } } @@ -76,7 +76,7 @@ func (e endpoints2Hosts) Render(rpt report.Report) Nodes { 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). + return newHostNode(id). WithLatest(report.HostNodeID, timestamp, hostNodeID) }) } From 724ea0c2306a7ae2318c0283fc86e2173337e306 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Wed, 20 Dec 2017 18:41:29 +0000 Subject: [PATCH 3/3] refactor: extract common code of joinResults.addChild variants --- render/render.go | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/render/render.go b/render/render.go index 26b30b075..c8b80138f 100644 --- a/render/render.go +++ b/render/render.go @@ -176,12 +176,11 @@ func newJoinResults(inputNodes report.Nodes) joinResults { return joinResults{nodes: nodes, mapped: map[string]string{}, multi: map[string][]string{}} } -func (ret *joinResults) add(m report.Node, n report.Node) { - ret.nodes[n.ID] = n - if _, ok := ret.mapped[m.ID]; !ok { - ret.mapped[m.ID] = n.ID +func (ret *joinResults) mapChild(from, to string) { + if _, ok := ret.mapped[from]; !ok { + ret.mapped[from] = to } else { - ret.multi[m.ID] = append(ret.multi[m.ID], n.ID) + ret.multi[from] = append(ret.multi[from], to) } } @@ -202,35 +201,24 @@ func (ret *joinResults) addUnmappedChild(m report.Node, id string, create func(s // Add m as a child of the node at id, creating a new result node if // not already there, and updating the mapping from old ID to new ID. func (ret *joinResults) addChild(m report.Node, id string, create func(string) report.Node) { - result, exists := ret.nodes[id] - if !exists { - result = create(id) - } - result.Children = result.Children.Add(m) - if m.Topology != report.Endpoint { // optimisation: we never look at endpoint counts - result.Counters = result.Counters.Add(m.Topology, 1) - } - ret.add(m, result) + ret.addUnmappedChild(m, id, create) + ret.mapChild(m.ID, id) } // Like addChild, but also add m's children. func (ret *joinResults) addChildAndChildren(m report.Node, id string, create func(string) report.Node) { - result, exists := ret.nodes[id] - if !exists { - result = create(id) - } - result.Children = result.Children.Add(m) + ret.addUnmappedChild(m, id, create) + result := ret.nodes[id] result.Children = result.Children.Merge(m.Children) - if m.Topology != report.Endpoint { // optimisation: we never look at endpoint counts - result.Counters = result.Counters.Add(m.Topology, 1) - } - ret.add(m, result) + ret.nodes[id] = result + ret.mapChild(m.ID, id) } // Add a copy of n straight into the results func (ret *joinResults) passThrough(n report.Node) { n.Adjacency = nil // result() assumes all nodes start with no adjacencies - ret.add(n, n) + ret.nodes[n.ID] = n + ret.mapChild(n.ID, n.ID) } // Rewrite Adjacency of nodes in ret mapped from original nodes in