Skip to content

Commit

Permalink
Add new Renderer type to include full node data without changing node…
Browse files Browse the repository at this point in the history
… set

The nodes returned from Map2Parent are mostly empty, and need joining with their full topologies
before being useful. But we want to filter out any nodes that weren't already in the graph.

We make a new Renderer type to implement this.
We also add the missing types to the type option group
  • Loading branch information
ekimekim committed Jun 1, 2017
1 parent 18c4b20 commit 327bdb5
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
2 changes: 2 additions & 0 deletions app/api_topologies.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ func MakeRegistry() *Registry {
Options: []APITopologyOption{
{Value: report.Deployment, Label: "Deployments", filter: render.IsTopology(report.Deployment), filterPseudo: false},
{Value: report.DaemonSet, Label: "Daemonsets", filter: render.IsTopology(report.DaemonSet), filterPseudo: false},
{Value: report.ReplicaSet, Label: "Replica sets", filter: render.IsTopology(report.ReplicaSet), filterPseudo: false},
{Value: report.Pod, Label: "Pods", filter: render.IsTopology(report.Pod), filterPseudo: false},
},
}

Expand Down
23 changes: 16 additions & 7 deletions render/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,25 @@ var DaemonSetRenderer = ConditionalRenderer(renderKubernetesTopologies,
// unchanged).
// We can't simply combine the rendered graphs of the high level objects as they would never
// have connections to each other.
// We combine with all the full topologies using ReduceFirstOnly, which keeps the same
// set of nodes but merges in the full data from the other renderers.
var KubeCombinedRenderer = ConditionalRenderer(renderKubernetesTopologies,
MakeMap(
Map2Parent([]string{report.Deployment}, NoParentsKeep, "", nil),
MakeReduceFirstOnly(
MakeMap(
Map2Parent([]string{
report.ReplicaSet,
report.DaemonSet,
}, NoParentsKeep, "", nil),
PodRenderer,
Map2Parent([]string{report.Deployment}, NoParentsKeep, "", nil),
MakeReduceFirstOnly(
MakeMap(
Map2Parent([]string{
report.ReplicaSet,
report.DaemonSet,
}, NoParentsKeep, "", nil),
PodRenderer,
),
SelectReplicaSet,
SelectDaemonSet,
),
),
SelectDeployment,
),
)

Expand Down
34 changes: 34 additions & 0 deletions render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,40 @@ func (r *Reduce) Stats(rpt report.Report, dct Decorator) Stats {
return result
}

// ReduceFirstOnly renderer is a Renderer which merges together the output of several other renderers,
// including only the nodes present in the first render, but merging in info from the same nodes
// if present in the other renders.
type ReduceFirstOnly struct {
first Renderer
others []Renderer
}

// MakeReduceFirstOnly is the only sane way to produce a ReduceFirstOnly Renderer.
func MakeReduceFirstOnly(first Renderer, others ...Renderer) Renderer {
r := ReduceFirstOnly{first, others}
return Memoise(&r)
}

// Render produces a set of Nodes given a Report.
func (r *ReduceFirstOnly) Render(rpt report.Report, dct Decorator) report.Nodes {
result := r.first.Render(rpt, dct).Copy()
for _, other := range r.others {
for id, node := range other.Render(rpt, dct) {
if n, ok := result[id]; ok {
result[id] = n.Merge(node)
}
}
}
return result
}

// Stats implements Renderer
func (r *ReduceFirstOnly) Stats(rpt report.Report, dct Decorator) Stats {
// Since we're just taking more detailed data from the other renderers,
// we probably only care about the filter stats for the 'main' renderer.
return r.first.Stats(rpt, dct)
}

// Map is a Renderer which produces a set of Nodes from the set of
// Nodes produced by another Renderer.
type Map struct {
Expand Down

0 comments on commit 327bdb5

Please sign in to comment.