Skip to content

Commit

Permalink
Merge pull request #2552 from weaveworks/mike/k8s/combined-view
Browse files Browse the repository at this point in the history
add k8s combined view
  • Loading branch information
ekimekim authored Jun 27, 2017
2 parents 286e481 + f7913ab commit 716a5df
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 144 deletions.
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: "",
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,
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",
})
}
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

0 comments on commit 716a5df

Please sign in to comment.