From b01e8904758a77bbedb4d9298e6ac63bc6542808 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Mon, 27 Feb 2017 18:37:18 -0800 Subject: [PATCH] When k8s present, allow filtering of containers by namespace To facilitate this, we replace the existing functionality of updateFilters which sets k8s topologies to have the filters [namespace, managed], to instead append the namespace filter to any existing. This lets it apply to both k8s and container topologies without overwriting existing container filters. We instead set the managed filter in the static definition. This however has the side effect that the ordering of the namespace filter and the managed filter in k8s topologies has been reversed, so it reads: Show Unmanaged | Hide Unmanaged foo | bar | default | baz | All Namespaces instead of: foo | bar | default | baz | All Namespaces Show Unmanaged | Hide Unmanaged --- app/api_topologies.go | 24 +++++++++++++++--------- render/filters.go | 15 +++++++++++++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/app/api_topologies.go b/app/api_topologies.go index ecc44fc85..faa3160aa 100644 --- a/app/api_topologies.go +++ b/app/api_topologies.go @@ -80,21 +80,23 @@ func updateFilters(rpt report.Report, topologies []APITopologyDesc) []APITopolog ns = append(ns, namespace) } sort.Strings(ns) - for i, t := range topologies { - if t.id == podsID || t.id == servicesID || t.id == deploymentsID || t.id == replicaSetsID { - topologies[i] = updateTopologyFilters(t, []APITopologyOptionGroup{ - kubernetesFilters(ns...), unmanagedFilter, - }) + if len(ns) > 0 { // We only want to apply k8s filters when we have k8s-related nodes + for i, t := range topologies { + if t.id == containersID || t.id == containersByImageID || t.id == containersByHostnameID || t.id == podsID || t.id == servicesID || t.id == deploymentsID || t.id == replicaSetsID { + topologies[i] = mergeTopologyFilters(t, []APITopologyOptionGroup{ + kubernetesFilters(ns...), + }) + } } } return topologies } -// updateTopologyFilters recursively sets the options on a topology description -func updateTopologyFilters(t APITopologyDesc, options []APITopologyOptionGroup) APITopologyDesc { - t.Options = options +// mergeTopologyFilters recursively merges in new options on a topology description +func mergeTopologyFilters(t APITopologyDesc, options []APITopologyOptionGroup) APITopologyDesc { + t.Options = append(t.Options, options...) for i, sub := range t.SubTopologies { - t.SubTopologies[i] = updateTopologyFilters(sub, options) + t.SubTopologies[i] = mergeTopologyFilters(sub, options) } return t } @@ -200,6 +202,7 @@ func MakeRegistry() *Registry { renderer: render.PodRenderer, Name: "Pods", Rank: 3, + Options: []APITopologyOptionGroup{unmanagedFilter}, HideIfEmpty: true, }, APITopologyDesc{ @@ -207,6 +210,7 @@ func MakeRegistry() *Registry { parent: podsID, renderer: render.ReplicaSetRenderer, Name: "replica sets", + Options: []APITopologyOptionGroup{unmanagedFilter}, HideIfEmpty: true, }, APITopologyDesc{ @@ -214,6 +218,7 @@ func MakeRegistry() *Registry { parent: podsID, renderer: render.DeploymentRenderer, Name: "deployments", + Options: []APITopologyOptionGroup{unmanagedFilter}, HideIfEmpty: true, }, APITopologyDesc{ @@ -221,6 +226,7 @@ func MakeRegistry() *Registry { parent: podsID, renderer: render.PodServiceRenderer, Name: "services", + Options: []APITopologyOptionGroup{unmanagedFilter}, HideIfEmpty: true, }, APITopologyDesc{ diff --git a/render/filters.go b/render/filters.go index da39e0c44..7897cd173 100644 --- a/render/filters.go +++ b/render/filters.go @@ -10,6 +10,10 @@ import ( "github.com/weaveworks/scope/report" ) +const ( + k8sNamespaceLabel = "io.kubernetes.pod.namespace" +) + // PreciousNodeRenderer ensures a node is never filtered out by decorators type PreciousNodeRenderer struct { PreciousNodeID string @@ -254,7 +258,7 @@ func IsApplication(n report.Node) bool { if roleLabel == "system" { return false } - namespace, _ := n.Latest.Lookup(docker.LabelPrefix + "io.kubernetes.pod.namespace") + namespace, _ := n.Latest.Lookup(docker.LabelPrefix + k8sNamespaceLabel) if namespace == "kube-system" { return false } @@ -293,7 +297,14 @@ func IsNotPseudo(n report.Node) bool { // IsNamespace checks if the node is a pod/service in the specified namespace func IsNamespace(namespace string) FilterFunc { return func(n report.Node) bool { - gotNamespace, _ := n.Latest.Lookup(kubernetes.Namespace) + tryKeys := []string{kubernetes.Namespace, docker.LabelPrefix + k8sNamespaceLabel} + gotNamespace := "" + for _, key := range tryKeys { + if value, ok := n.Latest.Lookup(key); ok { + gotNamespace = value + break + } + } return namespace == gotNamespace } }