From f7913ab550c51ea1541865a53bbe51edcc4063c0 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Thu, 15 Jun 2017 17:32:01 -0700 Subject: [PATCH] Rewrite renderers for k8s/ecs/swarm to abstract common parts Since all the renderers were doing almost-exactly the same thing, we abstract that out into a common function. --- render/ecs.go | 28 ++++--------- render/pod.go | 107 +++++++++++++++++++++--------------------------- render/swarm.go | 16 +++----- 3 files changed, 59 insertions(+), 92 deletions(-) diff --git a/render/ecs.go b/render/ecs.go index 6ec86df99..81b11a700 100644 --- a/render/ecs.go +++ b/render/ecs.go @@ -6,32 +6,20 @@ import ( // ECSTaskRenderer is a Renderer for Amazon ECS tasks. var ECSTaskRenderer = ConditionalRenderer(renderECSTopologies, - MakeMap( - PropagateSingleMetrics(report.Container), - MakeReduce( - MakeMap( - Map2Parent([]string{report.ECSTask}, NoParentsPseudo, UnmanagedID, nil), - MakeFilter( - IsRunning, - ContainerWithImageNameRenderer, - ), - ), - SelectECSTask, + renderParents( + report.Container, []string{report.ECSTask}, NoParentsPseudo, UnmanagedID, nil, + MakeFilter( + IsRunning, + ContainerWithImageNameRenderer, ), ), ) // ECSServiceRenderer is a Renderer for Amazon ECS services. var ECSServiceRenderer = ConditionalRenderer(renderECSTopologies, - MakeMap( - PropagateSingleMetrics(report.ECSTask), - MakeReduce( - MakeMap( - Map2Parent([]string{report.ECSService}, NoParentsDrop, "", nil), - ECSTaskRenderer, - ), - SelectECSService, - ), + renderParents( + report.ECSTask, []string{report.ECSService}, NoParentsDrop, "", nil, + ECSTaskRenderer, ), ) diff --git a/render/pod.go b/render/pod.go index 4028ca707..ccdb0dc1a 100644 --- a/render/pod.go +++ b/render/pod.go @@ -43,22 +43,18 @@ var PodRenderer = ConditionalRenderer(renderKubernetesTopologies, state, ok := n.Latest.Lookup(kubernetes.State) return (!ok || state != kubernetes.StateDeleted) }, - MakeMap( - PropagateSingleMetrics(report.Container), - MakeReduce( - MakeMap( - Map2Parent([]string{report.Pod}, NoParentsPseudo, UnmanagedID, nil), - MakeFilter( - ComposeFilterFuncs( - IsRunning, - Complement(isPauseContainer), - ), - ContainerWithImageNameRenderer, + MakeReduce( + renderParents( + report.Container, []string{report.Pod}, NoParentsPseudo, UnmanagedID, nil, + MakeFilter( + ComposeFilterFuncs( + IsRunning, + Complement(isPauseContainer), ), + ContainerWithImageNameRenderer, ), - ConnectionJoin(SelectPod, MapPod2IP), - SelectPod, ), + ConnectionJoin(SelectPod, MapPod2IP), ), ), ) @@ -66,30 +62,18 @@ var PodRenderer = ConditionalRenderer(renderKubernetesTopologies, // PodServiceRenderer is a Renderer which produces a renderable kubernetes services // graph by merging the pods graph and the services topology. var PodServiceRenderer = ConditionalRenderer(renderKubernetesTopologies, - MakeMap( - PropagateSingleMetrics(report.Pod), - MakeReduce( - MakeMap( - Map2Parent([]string{report.Service}, NoParentsDrop, "", nil), - PodRenderer, - ), - SelectService, - ), + renderParents( + report.Pod, []string{report.Service}, NoParentsDrop, "", nil, + PodRenderer, ), ) // ReplicaSetRenderer is a Renderer which produces a renderable kubernetes replica sets // graph by merging the pods graph and the replica sets topology. var ReplicaSetRenderer = ConditionalRenderer(renderKubernetesTopologies, - MakeMap( - PropagateSingleMetrics(report.Pod), - MakeReduce( - MakeMap( - Map2Parent([]string{report.ReplicaSet}, NoParentsDrop, "", nil), - PodRenderer, - ), - SelectReplicaSet, - ), + renderParents( + report.Pod, []string{report.ReplicaSet}, NoParentsDrop, "", nil, + PodRenderer, ), ) @@ -100,41 +84,42 @@ var ReplicaSetRenderer = ConditionalRenderer(renderKubernetesTopologies, // We can't simply combine the rendered graphs of the high level objects as they would never // have connections to each other. var KubeControllerRenderer = ConditionalRenderer(renderKubernetesTopologies, - MakeReduce( - // Include full deployment topology - MakeFilter( - // Filter out any remaining unmatched replica sets - Complement(IsTopology(report.ReplicaSet)), - MakeMap( - // Include pod metrics previously mapped to replica sets, in deployments - PropagateSingleMetrics(report.ReplicaSet), - MakeMap( - // Map replica sets to deployments, leaving unmatched replica sets and anything else unchanged - Map2Parent([]string{report.Deployment}, NoParentsKeep, "", mapPodCounts), - MakeReduce( - // Include full replica set and daemonset topologies - MakeMap( - // Include pod metrics in mapped nodes - PropagateSingleMetrics(report.Pod), - MakeMap( - // Transform pods to replica sets, daemonsets and 'unmanaged' - Map2Parent([]string{ - report.ReplicaSet, - report.DaemonSet, - }, NoParentsPseudo, UnmanagedID, nil), - PodRenderer, - ), - ), - SelectReplicaSet, - SelectDaemonSet, - ), - ), + MakeFilter( + // Filter out any remaining unmatched replica sets + Complement(IsTopology(report.ReplicaSet)), + renderParents( + report.ReplicaSet, []string{report.Deployment}, NoParentsKeep, "", mapPodCounts, + renderParents( + report.Pod, []string{report.ReplicaSet, report.DaemonSet}, + NoParentsPseudo, UnmanagedID, nil, + PodRenderer, ), ), - SelectDeployment, ), ) +// renderParents produces a 'standard' renderer for mapping from some child topology to some parent topologies, +// by taking a child renderer, mapping to parents, propagating single metrics, and joining with full parent topology. +// Most options are as per Map2Parent. +func renderParents(childTopology string, parentTopologies []string, noParentsAction noParentsActionEnum, + noParentsPseudoID string, modifyMappedNode func(parent, original report.Node) report.Node, + childRenderer Renderer) Renderer { + selectors := make([]Renderer, len(parentTopologies)) + for i, topology := range parentTopologies { + selectors[i] = TopologySelector(topology) + } + return MakeReduce(append( + selectors, + MakeMap( + PropagateSingleMetrics(childTopology), + MakeMap( + Map2Parent(parentTopologies, noParentsAction, noParentsPseudoID, modifyMappedNode), + childRenderer, + ), + ), + )...) +} + func mapPodCounts(parent, original report.Node) report.Node { // When mapping ReplicaSets to Deployments, we want to propagate the Pods counter if count, ok := original.Counters.Lookup(report.Pod); ok { diff --git a/render/swarm.go b/render/swarm.go index 8385ac0d3..4aecced10 100644 --- a/render/swarm.go +++ b/render/swarm.go @@ -6,17 +6,11 @@ import ( // SwarmServiceRenderer is a Renderer for Docker Swarm services var SwarmServiceRenderer = ConditionalRenderer(renderSwarmTopologies, - MakeMap( - PropagateSingleMetrics(report.Container), - MakeReduce( - MakeMap( - Map2Parent([]string{report.SwarmService}, NoParentsPseudo, UnmanagedID, nil), - MakeFilter( - IsRunning, - ContainerWithImageNameRenderer, - ), - ), - SelectSwarmService, + renderParents( + report.Container, []string{report.SwarmService}, NoParentsPseudo, UnmanagedID, nil, + MakeFilter( + IsRunning, + ContainerWithImageNameRenderer, ), ), )