Skip to content

Commit

Permalink
report.Upgrade: reconstruct namespaces
Browse files Browse the repository at this point in the history
Old probes do not report namespace topologies.
`report.upgradeNamespaces()` recontructs namespace topologies using the data available from other kubernetes resources.

Also, add a test.
  • Loading branch information
Roberto Bruggemann committed Dec 14, 2017
1 parent 63b0b9f commit 2a2226c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
39 changes: 38 additions & 1 deletion report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ const (

// Used when counting the number of containers
ContainersKey = "containers"

// The following constants are defined in github.com/weaveworks/scope/kubernetes,
// and are redefined to avoid import cycles.
KubernetesState = "kubernetes_state"
KubernetesName = "kubernetes_name"
KubernetesNamespace = "kubernetes_namespace"
KubernetesStateDeleted = "delete"
)

// Report is the core data type. It's produced by probes, and consumed and
Expand Down Expand Up @@ -351,7 +358,7 @@ func (r Report) Validate() error {
//
// This for now creates node's LatestControls from Controls.
func (r Report) Upgrade() Report {
return r.upgradeLatestControls().upgradePodNodes()
return r.upgradeLatestControls().upgradePodNodes().upgradeNamespaces()
}

func (r Report) upgradeLatestControls() Report {
Expand Down Expand Up @@ -419,6 +426,36 @@ func (r Report) upgradePodNodes() Report {
return r
}

func (r Report) upgradeNamespaces() Report {
if len(r.Namespace.Nodes) > 0 {
return r
}

namespaces := map[string]struct{}{}
for _, t := range []Topology{r.Pod, r.Service, r.Deployment, r.DaemonSet, r.StatefulSet, r.CronJob} {
for _, n := range t.Nodes {
if state, ok := n.Latest.Lookup(KubernetesState); ok && state == KubernetesStateDeleted {
continue
}
if namespace, ok := n.Latest.Lookup(KubernetesNamespace); ok {
namespaces[namespace] = struct{}{}
}
}
}

nodes := Nodes{}
for ns := range namespaces {
// Namespace ID
// Probes did not use to report namespace ids, but since creating a report node requires an id,
// the namespace name, which is unique, is passed to `MakeNamespaceNodeID
namespaceID := MakeNamespaceNodeID(ns)
nodes[namespaceID] = MakeNodeWith(namespaceID, map[string]string{KubernetesName: ns})
}
r.Namespace.Nodes = nodes

return r
}

// BackwardCompatible returns a new backward-compatible report.
//
// This for now creates node's Controls from LatestControls.
Expand Down
14 changes: 12 additions & 2 deletions report/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/weaveworks/common/mtime"
"github.com/weaveworks/common/test"
"github.com/weaveworks/scope/probe/kubernetes"
"github.com/weaveworks/scope/report"
s_reflect "github.com/weaveworks/scope/test/reflect"
)
Expand Down Expand Up @@ -106,8 +107,14 @@ func TestReportUpgrade(t *testing.T) {
mtime.NowForce(time.Now())
defer mtime.NowReset()
parentsWithDeployment := report.MakeSets().Add(report.Deployment, report.MakeStringSet("id"))
rsNode := report.MakeNode("bar").WithParents(parentsWithDeployment)
podNode := report.MakeNode("foo").WithControls("alive").WithParents(report.MakeSets().Add(report.ReplicaSet, report.MakeStringSet("bar")))
rsNode := report.MakeNode("bar").
WithParents(parentsWithDeployment)
namespaceName := "ns"
namespaceID := report.MakeNamespaceNodeID(namespaceName)
podNode := report.MakeNode("foo").
WithLatests(map[string]string{kubernetes.Namespace: namespaceName}).
WithControls("alive").
WithParents(report.MakeSets().Add(report.ReplicaSet, report.MakeStringSet("bar")))
controls := map[string]report.NodeControlData{
"alive": {
Dead: false,
Expand All @@ -117,9 +124,12 @@ func TestReportUpgrade(t *testing.T) {
rpt := report.MakeReport()
rpt.ReplicaSet.AddNode(rsNode)
rpt.Pod.AddNode(podNode)
namespaceNode := report.MakeNode(namespaceID).
WithLatests(map[string]string{kubernetes.Name: namespaceName})
expected := report.MakeReport()
expected.ReplicaSet.AddNode(rsNode)
expected.Pod.AddNode(expectedPodNode)
expected.Namespace.AddNode(namespaceNode)
got := rpt.Upgrade()
if !s_reflect.DeepEqual(expected, got) {
t.Error(test.Diff(expected, got))
Expand Down

0 comments on commit 2a2226c

Please sign in to comment.