Skip to content

Commit

Permalink
Merge pull request #2436 from weaveworks/mike/easier-added-topologies
Browse files Browse the repository at this point in the history
Reduce the number of places topologies are explicitly listed
  • Loading branch information
ekimekim authored Apr 14, 2017
2 parents 76253c3 + 18ba2c4 commit 460352d
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 335 deletions.
28 changes: 4 additions & 24 deletions probe/appclient/app_client_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,30 +73,10 @@ func TestAppClientPublish(t *testing.T) {
// marshalling->unmarshaling is not idempotent due to `json:"omitempty"`
// tags, transforming empty slices into nils. So, we make DeepEqual
// happy by setting empty `json:"omitempty"` entries to nil
rpt.Endpoint = report.MakeTopology()
rpt.Process = report.MakeTopology()
rpt.Container = report.MakeTopology()
rpt.ContainerImage = report.MakeTopology()
rpt.Pod = report.MakeTopology()
rpt.Service = report.MakeTopology()
rpt.Deployment = report.MakeTopology()
rpt.ReplicaSet = report.MakeTopology()
rpt.Host = report.MakeTopology()
rpt.Overlay = report.MakeTopology()
rpt.ECSTask = report.MakeTopology()
rpt.ECSService = report.MakeTopology()
rpt.Endpoint.Controls = nil
rpt.Process.Controls = nil
rpt.Container.Controls = nil
rpt.ContainerImage.Controls = nil
rpt.Pod.Controls = nil
rpt.Service.Controls = nil
rpt.Deployment.Controls = nil
rpt.ReplicaSet.Controls = nil
rpt.Host.Controls = nil
rpt.Overlay.Controls = nil
rpt.ECSTask.Controls = nil
rpt.ECSService.Controls = nil
rpt.WalkTopologies(func(to *report.Topology) {
*to = report.MakeTopology()
to.Controls = nil
})

s := dummyServer(t, token, id, version, rpt, done)
defer s.Close()
Expand Down
2 changes: 2 additions & 0 deletions probe/awsecs/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ func (r Reporter) Tag(rpt report.Report) (report.Report, error) {
if serviceName, ok := ecsInfo.TaskServiceMap[taskArn]; ok {
serviceID := report.MakeECSServiceNodeID(cluster, serviceName)
parentsSets = parentsSets.Add(report.ECSService, report.MakeStringSet(serviceID))
// in addition, make service parent of task
rpt.ECSTask.Nodes[taskID] = rpt.ECSTask.Nodes[taskID].WithParents(report.MakeSets().Add(report.ECSService, report.MakeStringSet(serviceID)))
}
for _, containerID := range info.ContainerIDs {
if containerNode, ok := rpt.Container.Nodes[containerID]; ok {
Expand Down
15 changes: 3 additions & 12 deletions probe/probe_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,9 @@ func TestProbe(t *testing.T) {
// tags, transforming empty slices into nils. So, we make DeepEqual
// happy by setting empty `json:"omitempty"` entries to nil
node.Metrics = nil
want.Endpoint.Controls = nil
want.Process.Controls = nil
want.Container.Controls = nil
want.ContainerImage.Controls = nil
want.Pod.Controls = nil
want.Service.Controls = nil
want.Deployment.Controls = nil
want.ReplicaSet.Controls = nil
want.Host.Controls = nil
want.Overlay.Controls = nil
want.ECSTask.Controls = nil
want.ECSService.Controls = nil
want.WalkTopologies(func(t *report.Topology) {
t.Controls = nil
})
want.Endpoint.AddNode(node)

pub := mockPublisher{make(chan report.Report, 10)}
Expand Down
13 changes: 1 addition & 12 deletions probe/topology_tagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,7 @@ func (topologyTagger) Name() string { return "Topology" }

// Tag implements Tagger
func (topologyTagger) Tag(r report.Report) (report.Report, error) {
for name, t := range map[string]*report.Topology{
report.Endpoint: &(r.Endpoint),
report.Process: &(r.Process),
report.Container: &(r.Container),
report.ContainerImage: &(r.ContainerImage),
report.Pod: &(r.Pod),
report.Service: &(r.Service),
report.ECSTask: &(r.ECSTask),
report.ECSService: &(r.ECSService),
report.Host: &(r.Host),
report.Overlay: &(r.Overlay),
} {
for name, t := range r.TopologyMap() {
for _, node := range t.Nodes {
t.AddNode(node.WithTopology(name))
}
Expand Down
63 changes: 42 additions & 21 deletions render/detailed/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,7 @@ var (
{
topologyID: report.Host,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "hosts",
Label: "Hosts",
Label: "Hosts",
Columns: []Column{
{ID: host.CPUUsage, Label: "CPU", Datatype: "number"},
{ID: host.MemoryUsage, Label: "Memory", Datatype: "number"},
Expand All @@ -145,8 +144,7 @@ var (
{
topologyID: report.Service,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "services",
Label: "Services",
Label: "Services",
Columns: []Column{
{ID: report.Pod, Label: "# Pods", Datatype: "number"},
{ID: kubernetes.IP, Label: "IP", Datatype: "ip"},
Expand All @@ -156,8 +154,7 @@ var (
{
topologyID: report.ReplicaSet,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "replica-sets",
Label: "Replica Sets",
Label: "Replica Sets",
Columns: []Column{
{ID: report.Pod, Label: "# Pods", Datatype: "number"},
{ID: kubernetes.ObservedGeneration, Label: "Observed Gen.", Datatype: "number"},
Expand All @@ -167,8 +164,7 @@ var (
{
topologyID: report.Pod,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "pods",
Label: "Pods",
Label: "Pods",

Columns: []Column{
{ID: kubernetes.State, Label: "State"},
Expand All @@ -180,8 +176,7 @@ var (
{
topologyID: report.ECSService,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "ecs-services",
Label: "Services",
Label: "Services",
Columns: []Column{
{ID: awsecs.ServiceRunningCount, Label: "Running", Datatype: "number"},
{ID: awsecs.ServiceDesiredCount, Label: "Desired", Datatype: "number"},
Expand All @@ -191,8 +186,7 @@ var (
{
topologyID: report.ECSTask,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "ecs-tasks",
Label: "Tasks",
Label: "Tasks",
Columns: []Column{
{ID: awsecs.CreatedAt, Label: "Created At", Datatype: "datetime"},
},
Expand All @@ -201,8 +195,7 @@ var (
{
topologyID: report.Container,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "containers",
Label: "Containers", Columns: []Column{
Label: "Containers", Columns: []Column{
{ID: docker.CPUTotalUsage, Label: "CPU", Datatype: "number"},
{ID: docker.MemoryUsage, Label: "Memory", Datatype: "number"},
},
Expand All @@ -211,8 +204,7 @@ var (
{
topologyID: report.Process,
NodeSummaryGroup: NodeSummaryGroup{
TopologyID: "processes",
Label: "Processes", Columns: []Column{
Label: "Processes", Columns: []Column{
{ID: process.PID, Label: "PID", Datatype: "number"},
{ID: process.CPUUsage, Label: "CPU", Datatype: "number"},
{ID: process.MemoryUsage, Label: "Memory", Datatype: "number"},
Expand Down Expand Up @@ -246,13 +238,42 @@ func children(r report.Report, n report.Node) []NodeSummaryGroup {
})

nodeSummaryGroups := []NodeSummaryGroup{}
// Apply specific group specs in the order they're listed
for _, spec := range nodeSummaryGroupSpecs {
if len(summaries[spec.topologyID]) > 0 {
sort.Sort(nodeSummariesByID(summaries[spec.TopologyID]))
group := spec.NodeSummaryGroup
group.Nodes = summaries[spec.topologyID]
nodeSummaryGroups = append(nodeSummaryGroups, group)
if len(summaries[spec.topologyID]) == 0 {
continue
}
apiTopology, ok := primaryAPITopology[spec.topologyID]
if !ok {
continue
}
sort.Sort(nodeSummariesByID(summaries[spec.topologyID]))
group := spec.NodeSummaryGroup
group.Nodes = summaries[spec.topologyID]
group.TopologyID = apiTopology
nodeSummaryGroups = append(nodeSummaryGroups, group)
delete(summaries, spec.topologyID)
}
// As a fallback, in case a topology has no group spec defined, add any remaining at the end
for topologyID, nodeSummaries := range summaries {
if len(nodeSummaries) == 0 {
continue
}
topology, ok := r.Topology(topologyID)
if !ok {
continue
}
apiTopology, ok := primaryAPITopology[topologyID]
if !ok {
continue
}
sort.Sort(nodeSummariesByID(nodeSummaries))
group := NodeSummaryGroup{
TopologyID: apiTopology,
Label: topology.LabelPlural,
Columns: []Column{},
}
nodeSummaryGroups = append(nodeSummaryGroups, group)
}

return nodeSummaryGroups
Expand Down
127 changes: 46 additions & 81 deletions render/detailed/parents.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,117 +16,82 @@ type Parent struct {
TopologyID string `json:"topologyId"`
}

func node(t report.Topology) func(string) (report.Node, bool) {
return func(id string) (report.Node, bool) {
n, ok := t.Nodes[id]
return n, ok
}
}
var (
kubernetesParentLabel = latestLookup(kubernetes.Name)

func fake(id string) (report.Node, bool) {
return report.MakeNode(id), true
}
getLabelForTopology = map[string]func(report.Node) string{
report.Container: getRenderableContainerName,
report.Pod: kubernetesParentLabel,
report.ReplicaSet: kubernetesParentLabel,
report.Deployment: kubernetesParentLabel,
report.Service: kubernetesParentLabel,
report.ECSTask: latestLookup(awsecs.TaskFamily),
report.ECSService: ecsServiceParentLabel,
report.ContainerImage: containerImageParentLabel,
report.Host: latestLookup(host.HostName),
}
)

// Parents renders the parents of this report.Node, which have been aggregated
// from the probe reports.
func Parents(r report.Report, n report.Node) (result []Parent) {
topologies := map[string]struct {
node func(id string) (report.Node, bool)
render func(report.Node) Parent
}{
report.Container: {node(r.Container), containerParent},
report.Pod: {node(r.Pod), podParent},
report.ReplicaSet: {node(r.ReplicaSet), replicaSetParent},
report.Deployment: {node(r.Deployment), deploymentParent},
report.Service: {node(r.Service), serviceParent},
report.ECSTask: {node(r.ECSTask), ecsTaskParent},
report.ECSService: {node(r.ECSService), ecsServiceParent},
report.ContainerImage: {fake, containerImageParent},
report.Host: {node(r.Host), hostParent},
}
topologyIDs := []string{}
for topologyID := range topologies {
for topologyID := range getLabelForTopology {
topologyIDs = append(topologyIDs, topologyID)
}
sort.Strings(topologyIDs)
for _, topologyID := range topologyIDs {
t := topologies[topologyID]
getLabel := getLabelForTopology[topologyID]
topology, ok := r.Topology(topologyID)
if !ok {
continue
}
parents, _ := n.Parents.Lookup(topologyID)
for _, id := range parents {
if topologyID == n.Topology && id == n.ID {
continue
}

parent, ok := t.node(id)
var parentNode report.Node
// Special case: container image parents should be empty nodes for some reason
if topologyID == report.ContainerImage {
parentNode = report.MakeNode(id)
} else {
if parent, ok := topology.Nodes[id]; ok {
parentNode = parent
} else {
continue
}
}

apiTopologyID, ok := primaryAPITopology[topologyID]
if !ok {
continue
}

result = append(result, t.render(parent))
result = append(result, Parent{
ID: id,
Label: getLabel(parentNode),
TopologyID: apiTopologyID,
})
}
}
return result
}

func containerParent(n report.Node) Parent {
label := getRenderableContainerName(n)
return Parent{
ID: n.ID,
Label: label,
TopologyID: "containers",
func latestLookup(key string) func(report.Node) string {
return func(n report.Node) string {
value, _ := n.Latest.Lookup(key)
return value
}
}

var (
podParent = kubernetesParent("pods")
replicaSetParent = kubernetesParent("replica-sets")
deploymentParent = kubernetesParent("deployments")
serviceParent = kubernetesParent("services")
)

func kubernetesParent(topology string) func(report.Node) Parent {
return func(n report.Node) Parent {
name, _ := n.Latest.Lookup(kubernetes.Name)
return Parent{
ID: n.ID,
Label: name,
TopologyID: topology,
}
}
}

func ecsTaskParent(n report.Node) Parent {
family, _ := n.Latest.Lookup(awsecs.TaskFamily)
return Parent{
ID: n.ID,
Label: family,
TopologyID: "ecs-tasks",
}
}

func ecsServiceParent(n report.Node) Parent {
func ecsServiceParentLabel(n report.Node) string {
_, name, _ := report.ParseECSServiceNodeID(n.ID)
return Parent{
ID: n.ID,
Label: name,
TopologyID: "ecs-services",
}
return name
}

func containerImageParent(n report.Node) Parent {
func containerImageParentLabel(n report.Node) string {
name, _ := report.ParseContainerImageNodeID(n.ID)
return Parent{
ID: n.ID,
Label: name,
TopologyID: "containers-by-image",
}
}

func hostParent(n report.Node) Parent {
hostName, _ := n.Latest.Lookup(host.HostName)
return Parent{
ID: n.ID,
Label: hostName,
TopologyID: "hosts",
}
return name
}
Loading

0 comments on commit 460352d

Please sign in to comment.