From 22402c34f7b047afd635b760171dcb658887f4ff Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 7 Apr 2016 12:01:23 +0100 Subject: [PATCH 1/4] Ensure k8s views are correctly hidden. - Filter unconnected psuedo nodes from the Pods view - Don't report these filtered nodes in stats - Fix typo in logic for hiding views --- client/app/scripts/utils/topology-utils.js | 2 +- render/filters.go | 24 ++++++++++++++++++---- render/topologies.go | 17 +++++++++------ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/client/app/scripts/utils/topology-utils.js b/client/app/scripts/utils/topology-utils.js index 5987af9bc1..0d4036feb0 100644 --- a/client/app/scripts/utils/topology-utils.js +++ b/client/app/scripts/utils/topology-utils.js @@ -55,6 +55,6 @@ export function setTopologyUrlsById(topologyUrlsById, topologies) { } export function filterHiddenTopologies(topologies) { - return topologies.filter(t => (!t.hidden_if_empty || t.stats.node_count > 0 || + return topologies.filter(t => (!t.hide_if_empty || t.stats.node_count > 0 || t.stats.filtered_nodes > 0)); } diff --git a/render/filters.go b/render/filters.go index 07745abe47..0d30774558 100644 --- a/render/filters.go +++ b/render/filters.go @@ -58,12 +58,26 @@ func ColorConnected(r Renderer) Renderer { // Filter removes nodes from a view based on a predicate. type Filter struct { Renderer - FilterFunc func(report.Node) bool + FilterFunc func(report.Node) bool + ReportFiltered bool // false means we don't report stats for how many are filtered } // MakeFilter makes a new Filter. func MakeFilter(f func(report.Node) bool, r Renderer) Renderer { - return Memoise(&Filter{r, f}) + return Memoise(&Filter{ + Renderer: r, + FilterFunc: f, + ReportFiltered: true, + }) +} + +// MakeSilentFilter makes a new Filter which does not report how many nodes it filters in Stats. +func MakeSilentFilter(f func(report.Node) bool, r Renderer) Renderer { + return Memoise(&Filter{ + Renderer: r, + FilterFunc: f, + ReportFiltered: false, + }) } // Render implements Renderer @@ -115,9 +129,11 @@ func (f *Filter) render(rpt report.Report) (report.Nodes, int) { // Stats implements Renderer func (f Filter) Stats(rpt report.Report) Stats { - _, filtered := f.render(rpt) var upstream = f.Renderer.Stats(rpt) - upstream.FilteredNodes += filtered + if f.ReportFiltered { + _, filtered := f.render(rpt) + upstream.FilteredNodes += filtered + } return upstream } diff --git a/render/topologies.go b/render/topologies.go index b7656bda41..103920852c 100644 --- a/render/topologies.go +++ b/render/topologies.go @@ -69,11 +69,10 @@ var ProcessNameRenderer = MakeMap( // but we need to be careful to ensure we only include each edge once, by only // including the ProcessRenderer once. var ContainerRenderer = MakeReduce( - MakeFilter( + MakeSilentFilter( func(n report.Node) bool { - _, inContainer := n.Latest.Lookup(docker.ContainerID) _, isConnected := n.Latest.Lookup(IsConnected) - return inContainer || isConnected + return n.Topology != Pseudo || isConnected }, MakeMap( MapProcess2Container, @@ -224,9 +223,15 @@ var HostRenderer = MakeReduce( // PodRenderer is a Renderer which produces a renderable kubernetes // graph by merging the container graph and the pods topology. var PodRenderer = MakeReduce( - MakeMap( - MapContainer2Pod, - ContainerRenderer, + MakeSilentFilter( + func(n report.Node) bool { + _, isConnected := n.Latest.Lookup(IsConnected) + return n.Topology != Pseudo || isConnected + }, + MakeMap( + MapContainer2Pod, + ColorConnected(ContainerRenderer), + ), ), SelectPod, ) From 674cb24f2ae06a97cdcb67e41282cde2d6025fa0 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 7 Apr 2016 12:23:06 +0100 Subject: [PATCH 2/4] Review feedback --- .../utils/__tests__/topology-utils-test.js | 10 +++++----- render/filters.go | 17 ++++++++--------- render/topologies.go | 6 +++--- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/client/app/scripts/utils/__tests__/topology-utils-test.js b/client/app/scripts/utils/__tests__/topology-utils-test.js index 7010bb4147..7d2e5bc144 100644 --- a/client/app/scripts/utils/__tests__/topology-utils-test.js +++ b/client/app/scripts/utils/__tests__/topology-utils-test.js @@ -108,12 +108,12 @@ describe('TopologyUtils', () => { }); describe('filterHiddenTopologies', () => { - it('should filter out empty topos that set hidden_if_empty=true', () => { + it('should filter out empty topos that set hide_if_empty=true', () => { const topos = [ - {id: 'a', hidden_if_empty: true, stats: {node_count: 0, filtered_nodes:0}}, - {id: 'b', hidden_if_empty: true, stats: {node_count: 1, filtered_nodes:0}}, - {id: 'c', hidden_if_empty: true, stats: {node_count: 0, filtered_nodes:1}}, - {id: 'd', hidden_if_empty: false, stats: {node_count: 0, filtered_nodes:0}} + {id: 'a', hide_if_empty: true, stats: {node_count: 0, filtered_nodes:0}}, + {id: 'b', hide_if_empty: true, stats: {node_count: 1, filtered_nodes:0}}, + {id: 'c', hide_if_empty: true, stats: {node_count: 0, filtered_nodes:1}}, + {id: 'd', hide_if_empty: false, stats: {node_count: 0, filtered_nodes:0}} ]; const res = TopologyUtils.filterHiddenTopologies(topos); diff --git a/render/filters.go b/render/filters.go index 0d30774558..9aa35642bf 100644 --- a/render/filters.go +++ b/render/filters.go @@ -58,25 +58,24 @@ func ColorConnected(r Renderer) Renderer { // Filter removes nodes from a view based on a predicate. type Filter struct { Renderer - FilterFunc func(report.Node) bool - ReportFiltered bool // false means we don't report stats for how many are filtered + FilterFunc func(report.Node) bool + Silent bool // true means we don't report stats for how many are filtered } // MakeFilter makes a new Filter. func MakeFilter(f func(report.Node) bool, r Renderer) Renderer { return Memoise(&Filter{ - Renderer: r, - FilterFunc: f, - ReportFiltered: true, + Renderer: r, + FilterFunc: f, }) } // MakeSilentFilter makes a new Filter which does not report how many nodes it filters in Stats. func MakeSilentFilter(f func(report.Node) bool, r Renderer) Renderer { return Memoise(&Filter{ - Renderer: r, - FilterFunc: f, - ReportFiltered: false, + Renderer: r, + FilterFunc: f, + Silent: true, }) } @@ -130,7 +129,7 @@ func (f *Filter) render(rpt report.Report) (report.Nodes, int) { // Stats implements Renderer func (f Filter) Stats(rpt report.Report) Stats { var upstream = f.Renderer.Stats(rpt) - if f.ReportFiltered { + if !f.Silent { _, filtered := f.render(rpt) upstream.FilteredNodes += filtered } diff --git a/render/topologies.go b/render/topologies.go index 103920852c..beca059745 100644 --- a/render/topologies.go +++ b/render/topologies.go @@ -228,10 +228,10 @@ var PodRenderer = MakeReduce( _, isConnected := n.Latest.Lookup(IsConnected) return n.Topology != Pseudo || isConnected }, - MakeMap( + ColorConnected(MakeMap( MapContainer2Pod, - ColorConnected(ContainerRenderer), - ), + ContainerRenderer, + )), ), SelectPod, ) From ca943684209ac47297ba7292a15b0dbd42e4352e Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 7 Apr 2016 13:14:57 +0100 Subject: [PATCH 3/4] Don't report nodes filtered out through the short-lived-connections join --- render/filters.go | 12 ++++++++++++ render/topologies.go | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/render/filters.go b/render/filters.go index 9aa35642bf..ba3ffd4267 100644 --- a/render/filters.go +++ b/render/filters.go @@ -169,6 +169,18 @@ func FilterUnconnected(r Renderer) Renderer { ) } +// SilentFilterUnconnected produces a renderer that filters unconnected nodes +// from the given renderer; nodes filtered by this are not reported in stats. +func SilentFilterUnconnected(r Renderer) Renderer { + return MakeSilentFilter( + func(node report.Node) bool { + _, ok := node.Latest.Lookup(IsConnected) + return ok + }, + ColorConnected(r), + ) +} + // FilterNoop does nothing. func FilterNoop(in Renderer) Renderer { return in diff --git a/render/topologies.go b/render/topologies.go index beca059745..3752dcac12 100644 --- a/render/topologies.go +++ b/render/topologies.go @@ -84,7 +84,7 @@ var ContainerRenderer = MakeReduce( // We need to be careful to ensure we only include each edge once. Edges brought in // by the above renders will have a pid, so its enough to filter out any nodes with // pids. - FilterUnconnected(MakeMap( + SilentFilterUnconnected(MakeMap( MapIP2Container, MakeReduce( MakeMap( From ee1b4def95badcc31b2b9561c90e0a43f1ed7bfa Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 7 Apr 2016 13:19:42 +0100 Subject: [PATCH 4/4] Make the initial procspy filter silent --- render/filters.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render/filters.go b/render/filters.go index ba3ffd4267..24de14aa2c 100644 --- a/render/filters.go +++ b/render/filters.go @@ -204,7 +204,7 @@ func FilterRunning(r Renderer) Renderer { // FilterNonProcspied removes endpoints which were not found in procspy. func FilterNonProcspied(r Renderer) Renderer { - return MakeFilter( + return MakeSilentFilter( func(node report.Node) bool { _, ok := node.Latest.Lookup(endpoint.Procspied) return ok