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
This commit is contained in:
Mike Lang
2017-02-27 18:37:18 -08:00
parent 107a933530
commit b01e890475
2 changed files with 28 additions and 11 deletions

View File

@@ -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{

View File

@@ -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
}
}