Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add k8s combined view #2552

Merged
merged 9 commits into from
Jun 27, 2017
32 changes: 17 additions & 15 deletions app/api_topologies.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ const (
containersByImageID = "containers-by-image"
podsID = "pods"
replicaSetsID = "replica-sets"
deploymentsID = "deployments"
daemonsetsID = "daemonsets"
kubeControllersID = "kube-controllers"
servicesID = "services"
hostsID = "hosts"
weaveID = "weave"
Expand Down Expand Up @@ -120,7 +119,7 @@ func updateKubeFilters(rpt report.Report, topologies []APITopologyDesc) []APITop
sort.Strings(ns)
topologies = append([]APITopologyDesc{}, topologies...) // Make a copy so we can make changes safely
for i, t := range topologies {
if t.id == containersID || t.id == podsID || t.id == servicesID || t.id == deploymentsID || t.id == replicaSetsID || t.id == daemonsetsID {
if t.id == containersID || t.id == podsID || t.id == servicesID || t.id == replicaSetsID || t.id == kubeControllersID {
topologies[i] = mergeTopologyFilters(t, []APITopologyOptionGroup{
namespaceFilters(ns, "All Namespaces"),
})
Expand Down Expand Up @@ -196,6 +195,17 @@ func MakeRegistry() *Registry {
},
}

k8sControllersTypeFilter := APITopologyOptionGroup{
ID: "grouptype",
Default: "",

This comment was marked as abuse.

SelectType: "union",
NoneLabel: "All Types",
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},
},
}

// Topology option labels should tell the current state. The first item must
// be the verb to get to that state
registry.Add(
Expand Down Expand Up @@ -253,19 +263,11 @@ func MakeRegistry() *Registry {
HideIfEmpty: true,
},
APITopologyDesc{
id: deploymentsID,
parent: podsID,
renderer: render.DeploymentRenderer,
Name: "deployments",
Options: []APITopologyOptionGroup{unmanagedFilter},
HideIfEmpty: true,
},
APITopologyDesc{
id: daemonsetsID,
id: kubeControllersID,
parent: podsID,
renderer: render.DaemonSetRenderer,
Name: "daemonsets",
Options: []APITopologyOptionGroup{unmanagedFilter},
renderer: render.KubeControllerRenderer,
Name: "controllers",
Options: []APITopologyOptionGroup{unmanagedFilter, k8sControllersTypeFilter},
HideIfEmpty: true,
},
APITopologyDesc{
Expand Down
12 changes: 9 additions & 3 deletions client/app/scripts/charts/node-shapes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import {
pathElement,
circleElement,
rectangleElement,
cloudShapeProps,
circleShapeProps,
triangleShapeProps,
squareShapeProps,
pentagonShapeProps,
hexagonShapeProps,
heptagonShapeProps,
octagonShapeProps,
cloudShapeProps,
} from '../utils/node-shape-utils';


Expand Down Expand Up @@ -69,8 +72,11 @@ function NodeShape(shapeType, shapeElement, shapeProps, { id, highlighted, color
);
}

export const NodeShapeCloud = props => NodeShape('cloud', pathElement, cloudShapeProps, props);
export const NodeShapeCircle = props => NodeShape('circle', circleElement, circleShapeProps, props);
export const NodeShapeTriangle = props => NodeShape('triangle', pathElement, triangleShapeProps, props);
export const NodeShapeSquare = props => NodeShape('square', rectangleElement, squareShapeProps, props);
export const NodeShapePentagon = props => NodeShape('pentagon', pathElement, pentagonShapeProps, props);
export const NodeShapeHexagon = props => NodeShape('hexagon', pathElement, hexagonShapeProps, props);
export const NodeShapeHeptagon = props => NodeShape('heptagon', pathElement, heptagonShapeProps, props);
export const NodeShapeSquare = props => NodeShape('square', rectangleElement, squareShapeProps, props);
export const NodeShapeOctagon = props => NodeShape('octagon', pathElement, octagonShapeProps, props);
export const NodeShapeCloud = props => NodeShape('cloud', pathElement, cloudShapeProps, props);
10 changes: 8 additions & 2 deletions client/app/scripts/charts/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,26 @@ import { NODE_BASE_SIZE } from '../constants/styles';
import NodeShapeStack from './node-shape-stack';
import NodeNetworksOverlay from './node-networks-overlay';
import {
NodeShapeCloud,
NodeShapeCircle,

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

NodeShapeTriangle,
NodeShapeSquare,
NodeShapePentagon,
NodeShapeHexagon,
NodeShapeHeptagon,
NodeShapeOctagon,
NodeShapeCloud,
} from './node-shapes';


const labelWidth = 1.2 * NODE_BASE_SIZE;
const nodeShapes = {
circle: NodeShapeCircle,
triangle: NodeShapeTriangle,
square: NodeShapeSquare,
pentagon: NodeShapePentagon,
hexagon: NodeShapeHexagon,
heptagon: NodeShapeHeptagon,
square: NodeShapeSquare,
octagon: NodeShapeOctagon,
cloud: NodeShapeCloud,
};

Expand Down
7 changes: 5 additions & 2 deletions client/app/scripts/utils/node-shape-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ function curvedUnitPolygonPath(n) {
]));
}

export const circleShapeProps = { r: 1 };
export const triangleShapeProps = { d: curvedUnitPolygonPath(3) };
export const squareShapeProps = { width: 1.8, height: 1.8, rx: 0.4, ry: 0.4, x: -0.9, y: -0.9 };
export const heptagonShapeProps = { d: curvedUnitPolygonPath(7) };
export const pentagonShapeProps = { d: curvedUnitPolygonPath(5) };
export const hexagonShapeProps = { d: curvedUnitPolygonPath(6) };
export const heptagonShapeProps = { d: curvedUnitPolygonPath(7) };
export const octagonShapeProps = { d: curvedUnitPolygonPath(8) };
export const cloudShapeProps = { d: UNIT_CLOUD_PATH };
export const circleShapeProps = { r: 1 };
2 changes: 1 addition & 1 deletion client/app/scripts/utils/topology-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { shownNodesSelector, shownResourceTopologyIdsSelector } from '../selecto
const TOPOLOGY_DISPLAY_PRIORITY = [
'ecs-services',
'ecs-tasks',
'kube-controllers',
'services',
'deployments',
'replica-sets',
'pods',
'containers',
Expand Down
1 change: 1 addition & 0 deletions probe/kubernetes/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ func (d *daemonSet) GetNode() report.Node {
DesiredReplicas: fmt.Sprint(d.Status.DesiredNumberScheduled),
Replicas: fmt.Sprint(d.Status.CurrentNumberScheduled),
MisscheduledReplicas: fmt.Sprint(d.Status.NumberMisscheduled),
NodeType: "Daemon Set",

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

})
}
1 change: 1 addition & 0 deletions probe/kubernetes/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ func (d *deployment) GetNode(probeID string) report.Node {
UnavailableReplicas: fmt.Sprint(d.Status.UnavailableReplicas),
Strategy: string(d.Spec.Strategy.Type),
report.ControlProbeID: probeID,
NodeType: "Deployment",
}).WithLatestActiveControls(ScaleUp, ScaleDown)
}
3 changes: 3 additions & 0 deletions probe/kubernetes/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
ObservedGeneration = "kubernetes_observed_generation"
Replicas = "kubernetes_replicas"
DesiredReplicas = "kubernetes_desired_replicas"
NodeType = "kubernetes_node_type"
)

// Exposed for testing
Expand All @@ -46,6 +47,7 @@ var (
ServiceMetricTemplates = PodMetricTemplates

DeploymentMetadataTemplates = report.MetadataTemplates{
NodeType: {ID: NodeType, Label: "Type", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
ObservedGeneration: {ID: ObservedGeneration, Label: "Observed Gen.", From: report.FromLatest, Datatype: "number", Priority: 4},
Expand All @@ -67,6 +69,7 @@ var (
ReplicaSetMetricTemplates = PodMetricTemplates

DaemonSetMetadataTemplates = report.MetadataTemplates{
NodeType: {ID: NodeType, Label: "Type", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
Created: {ID: Created, Label: "Created", From: report.FromLatest, Datatype: "datetime", Priority: 3},
DesiredReplicas: {ID: DesiredReplicas, Label: "Desired Replicas", From: report.FromLatest, Datatype: "number", Priority: 4},
Expand Down
16 changes: 13 additions & 3 deletions render/detailed/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ var primaryAPITopology = map[string]string{
report.ContainerImage: "containers-by-image",
report.Pod: "pods",
report.ReplicaSet: "replica-sets",
report.Deployment: "deployments",
report.DaemonSet: "daemonsets",
report.Deployment: "kube-controllers",
report.DaemonSet: "kube-controllers",
report.Service: "services",
report.ECSTask: "ecs-tasks",
report.ECSService: "ecs-services",
Expand Down Expand Up @@ -257,13 +257,23 @@ func podNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) {
return base, true
}

var podGroupNodeTypeName = map[string]string{
report.Deployment: "Deployment",
report.DaemonSet: "Daemon Set",
}

func podGroupNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) {
base = addKubernetesLabelAndRank(base, n)
base.Stack = true

// NB: pods are the highest aggregation level for which we display
// counts.
base.LabelMinor = pluralize(n.Counters, report.Pod, "pod", "pods")
count := pluralize(n.Counters, report.Pod, "pod", "pods")
if typeName, ok := podGroupNodeTypeName[n.Topology]; ok {
base.LabelMinor = fmt.Sprintf("%s of %s", typeName, count)
} else {
base.LabelMinor = count
}

return base, true
}
Expand Down
28 changes: 8 additions & 20 deletions render/ecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,20 @@ import (

// ECSTaskRenderer is a Renderer for Amazon ECS tasks.
var ECSTaskRenderer = ConditionalRenderer(renderECSTopologies,
MakeMap(
PropagateSingleMetrics(report.Container),
MakeReduce(
MakeMap(
Map2Parent(report.ECSTask, 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(report.ECSService, "", nil),
ECSTaskRenderer,
),
SelectECSService,
),
renderParents(
report.ECSTask, []string{report.ECSService}, NoParentsDrop, "", nil,
ECSTaskRenderer,
),
)

Expand Down
17 changes: 11 additions & 6 deletions render/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,6 @@ func IsNotPseudo(n report.Node) bool {
return n.Topology != Pseudo || strings.HasSuffix(n.ID, TheInternetID) || strings.HasPrefix(n.ID, ServiceNodeIDPrefix)
}

// IsPseudoTopology returns true if the node is in a pseudo topology,
// mimicing the check performed by MakeFilter() instead of the more complex check in IsNotPseudo()
func IsPseudoTopology(n report.Node) bool {
return n.Topology == Pseudo
}

// IsNamespace checks if the node is a pod/service in the specified namespace
func IsNamespace(namespace string) FilterFunc {
return func(n report.Node) bool {
Expand All @@ -336,6 +330,17 @@ func IsNamespace(namespace string) FilterFunc {
}
}

// IsTopology checks if the node is from a particular report topology
func IsTopology(topology string) FilterFunc {
return func(n report.Node) bool {
return n.Topology == topology
}
}

// IsPseudoTopology returns true if the node is in a pseudo topology,
// mimicing the check performed by MakeFilter() instead of the more complex check in IsNotPseudo()
var IsPseudoTopology = IsTopology(Pseudo)

var systemContainerNames = map[string]struct{}{
"weavescope": {},
"weavedns": {},
Expand Down
Loading