From 3209d65d525df157bf6ec9b77949b718db3a4ccd Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Tue, 27 Jun 2017 18:49:24 +0100 Subject: [PATCH] filter out unconnected pseudo nodes on the outside The change is necessitated by the removal of procspied/ebpf endpoint filtering in the renderers, as a result of which the odd conntracked-only, unconnected pseudo node can sneak through. This new way of doing things also makes renderers more composable and robust, and more directly reflects the objective: - in the process topologies, filter out all unconnected nodes - in all other topologies, filter out unconnected pseudo nodes --- app/api_topologies.go | 24 ++++++++++++------------ render/container.go | 4 ++-- render/filters.go | 17 ++++++++++++++++- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/app/api_topologies.go b/app/api_topologies.go index e4c6eafaf..684801e45 100644 --- a/app/api_topologies.go +++ b/app/api_topologies.go @@ -227,7 +227,7 @@ func MakeRegistry() *Registry { }, APITopologyDesc{ id: containersID, - renderer: render.ContainerWithImageNameRenderer, + renderer: render.FilterUnconnectedPseudo(render.ContainerWithImageNameRenderer), Name: "Containers", Rank: 2, Options: containerFilters, @@ -235,20 +235,20 @@ func MakeRegistry() *Registry { APITopologyDesc{ id: containersByHostnameID, parent: containersID, - renderer: render.ContainerHostnameRenderer, + renderer: render.FilterUnconnectedPseudo(render.ContainerHostnameRenderer), Name: "by DNS name", Options: containerFilters, }, APITopologyDesc{ id: containersByImageID, parent: containersID, - renderer: render.ContainerImageRenderer, + renderer: render.FilterUnconnectedPseudo(render.ContainerImageRenderer), Name: "by image", Options: containerFilters, }, APITopologyDesc{ id: podsID, - renderer: render.PodRenderer, + renderer: render.FilterUnconnectedPseudo(render.PodRenderer), Name: "Pods", Rank: 3, Options: []APITopologyOptionGroup{unmanagedFilter}, @@ -257,7 +257,7 @@ func MakeRegistry() *Registry { APITopologyDesc{ id: replicaSetsID, parent: podsID, - renderer: render.ReplicaSetRenderer, + renderer: render.FilterUnconnectedPseudo(render.ReplicaSetRenderer), Name: "replica sets", Options: []APITopologyOptionGroup{unmanagedFilter}, HideIfEmpty: true, @@ -265,7 +265,7 @@ func MakeRegistry() *Registry { APITopologyDesc{ id: kubeControllersID, parent: podsID, - renderer: render.KubeControllerRenderer, + renderer: render.FilterUnconnectedPseudo(render.KubeControllerRenderer), Name: "controllers", Options: []APITopologyOptionGroup{unmanagedFilter, k8sControllersTypeFilter}, HideIfEmpty: true, @@ -273,14 +273,14 @@ func MakeRegistry() *Registry { APITopologyDesc{ id: servicesID, parent: podsID, - renderer: render.PodServiceRenderer, + renderer: render.FilterUnconnectedPseudo(render.PodServiceRenderer), Name: "services", Options: []APITopologyOptionGroup{unmanagedFilter}, HideIfEmpty: true, }, APITopologyDesc{ id: ecsTasksID, - renderer: render.ECSTaskRenderer, + renderer: render.FilterUnconnectedPseudo(render.ECSTaskRenderer), Name: "Tasks", Rank: 3, Options: []APITopologyOptionGroup{unmanagedFilter}, @@ -289,14 +289,14 @@ func MakeRegistry() *Registry { APITopologyDesc{ id: ecsServicesID, parent: ecsTasksID, - renderer: render.ECSServiceRenderer, + renderer: render.FilterUnconnectedPseudo(render.ECSServiceRenderer), Name: "services", Options: []APITopologyOptionGroup{unmanagedFilter}, HideIfEmpty: true, }, APITopologyDesc{ id: swarmServicesID, - renderer: render.SwarmServiceRenderer, + renderer: render.FilterUnconnectedPseudo(render.SwarmServiceRenderer), Name: "services", Rank: 3, Options: []APITopologyOptionGroup{unmanagedFilter}, @@ -304,14 +304,14 @@ func MakeRegistry() *Registry { }, APITopologyDesc{ id: hostsID, - renderer: render.HostRenderer, + renderer: render.FilterUnconnectedPseudo(render.HostRenderer), Name: "Hosts", Rank: 4, }, APITopologyDesc{ id: weaveID, parent: hostsID, - renderer: render.WeaveRenderer, + renderer: render.FilterUnconnectedPseudo(render.WeaveRenderer), Name: "Weave Net", }, ) diff --git a/render/container.go b/render/container.go index 81e426771..e50673ad1 100644 --- a/render/container.go +++ b/render/container.go @@ -68,13 +68,13 @@ func ConnectionJoin(r Renderer, toIPs func(report.Node) []string) Renderer { return result } - return FilterUnconnected(MakeMap( + return MakeMap( ipToNode, MakeReduce( MakeMap(nodeToIP, r), mapEndpoint2IP, ), - )) + ) } func ipToNode(n report.Node, _ report.Networks) report.Nodes { diff --git a/render/filters.go b/render/filters.go index 1bd8520c2..bfc235a16 100644 --- a/render/filters.go +++ b/render/filters.go @@ -215,7 +215,7 @@ func Complement(f FilterFunc) FilterFunc { // FilterUnconnected produces a renderer that filters unconnected nodes // from the given renderer func FilterUnconnected(r Renderer) Renderer { - return MakeFilter( + return MakeFilterPseudo( func(node report.Node) bool { _, ok := node.Latest.Lookup(IsConnected) return ok @@ -224,6 +224,21 @@ func FilterUnconnected(r Renderer) Renderer { ) } +// FilterUnconnectedPseudo produces a renderer that filters +// unconnected pseudo nodes from the given renderer +func FilterUnconnectedPseudo(r Renderer) Renderer { + return MakeFilterPseudo( + func(node report.Node) bool { + if !IsPseudoTopology(node) { + return true + } + _, ok := node.Latest.Lookup(IsConnected) + return ok + }, + ColorConnected(r), + ) +} + // Noop allows all nodes through func Noop(_ report.Node) bool { return true }