Skip to content

Commit

Permalink
Support multi controller (frontend) (#376)
Browse files Browse the repository at this point in the history
  • Loading branch information
Luke Reed committed Oct 22, 2021
1 parent 540f93f commit 25481ab
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 82 deletions.
1 change: 1 addition & 0 deletions e2e/tests/99_cleanup.yaml
Expand Up @@ -10,3 +10,4 @@ testcases:
kubectl delete ns metrics-server
helm -n vpa delete vpa
kubectl delete ns vpa
kubectl delete ns statefulset-demo
22 changes: 11 additions & 11 deletions pkg/dashboard/templates/namespace.gohtml
@@ -1,11 +1,11 @@
{{define "namespace"}}
{{ $foundFirstDeployment := false }}
{{ $foundFirstWorkload := false }}

<article data-filter="{{ $.Namespace }}">
<details class="detailInfo --namespace verticalRhythm" open>
<summary class="--hideMarker">
<h2>
<span aria-label="Deployment:" class="badge detailBadge --namespace"
<span aria-label="Namespace:" class="badge detailBadge --namespace"
>Namespace</span
>
{{ $.Namespace }}
Expand All @@ -20,29 +20,29 @@
</p>
</summary>

{{ if lt (len $.Deployments) 1 }}
{{ if lt (len $.Workloads) 1 }}
<section class="detailInfo --empty">
<p>No deployments found in this namespace.</p>
<p>No workloads found in this namespace.</p>
</section>

{{ else }}
{{ range $deployment := $.Deployments }}
{{ range $workload := $.Workloads }}
<details class="detailInfo --deployment verticalRhythm"
{{ if not $foundFirstDeployment }}
{{ $foundFirstDeployment = true }} open
{{ if not $foundFirstWorkload }}
{{ $foundFirstWorkload = true }} open
{{ end }}>
<summary class="--hideMarker">
<h3>
<span aria-label="Deployment:" class="badge detailBadge --deployment"
>Deployment</span
<span aria-label="Workload:" class="badge detailBadge --deployment"
>{{ $workload.ControllerType }}</span
>
{{ $deployment.DeploymentName }}
{{ $workload.ControllerName }}
<i aria-hidden="true" class="fas fa-fw fa-angle-down --showWhenClosed"></i
><i aria-hidden="true" class="fas fa-fw fa-angle-up --showWhenOpen"></i>
</h3>
</summary>

{{ range $cName, $cSummary := $deployment.Containers }}
{{ range $cName, $cSummary := $workload.Containers }}
<details class="detailInfo --container verticalRhythm" open>
<summary class="--hideMarker">
<h4>
Expand Down
252 changes: 230 additions & 22 deletions pkg/summary/constants_test.go
Expand Up @@ -15,11 +15,11 @@
package summary

import (
appsv1 "k8s.io/api/apps/v1"
autoscalingv1 "k8s.io/api/autoscaling/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
vpav1 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1"

"github.com/fairwindsops/goldilocks/pkg/utils"
Expand Down Expand Up @@ -73,10 +73,56 @@ var testVPABasic = &vpav1.VerticalPodAutoscaler{
},
},
}
var testDeploymentBasic = &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test-basic",
Namespace: "testing",

var testDeploymentBasicUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "Deployment",
"apiVersion": "apps/v1",
"metadata": map[string]interface{}{
"name": "test-basic",
"namespace": "testing",
},
"spec": map[string]interface{}{},
},
}

var testDeploymentBasicReplicaSetUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "ReplicaSet",
"apiVersion": "apps/v1",
"metadata": map[string]interface{}{
"ownerReferences": []interface{}{
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"controller": true,
"name": "test-basic",
},
},
"name": "test-basic-0123456789",
"namespace": "testing",
},
"spec": map[string]interface{}{},
},
}

var testDeploymentBasicPodUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "Pod",
"apiVersion": "v1",
"metadata": map[string]interface{}{
"ownerReferences": []interface{}{
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"controller": true,
"name": "test-basic-0123456789",
},
},
"name": "test-basic-0123456789-01234",
"namespace": "testing",
},
"spec": map[string]interface{}{},
},
}

Expand Down Expand Up @@ -131,20 +177,30 @@ var testVPAWithReco = &vpav1.VerticalPodAutoscaler{
},
}

var testDeploymentWithReco = &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test-vpa-with-reco",
Namespace: "testing",
},
Spec: appsv1.DeploymentSpec{
Template: v1.PodTemplateSpec{
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: "container",
Resources: v1.ResourceRequirements{
Limits: targetResources,
Requests: targetResources,
var testDeploymentWithRecoUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "Deployment",
"apiVersion": "apps/v1",
"metadata": map[string]interface{}{
"name": "test-vpa-with-reco",
"namespace": "testing",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "container",
"resources": map[string]interface{}{
"limits": map[string]interface{}{
"cpu": "100m",
"memory": "100Mi",
},
"requests": map[string]interface{}{
"cpu": "100m",
"memory": "100Mi",
},
},
},
},
},
Expand All @@ -153,19 +209,171 @@ var testDeploymentWithReco = &appsv1.Deployment{
},
}

var testDeploymentWithRecoReplicaSetUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "ReplicaSet",
"apiVersion": "apps/v1",
"metadata": map[string]interface{}{
"ownerReferences": []interface{}{
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"controller": true,
"name": "test-vpa-with-reco",
},
},
"name": "test-vpa-with-reco-0123456789",
"namespace": "testing",
},
"spec": map[string]interface{}{},
},
}

var testDeploymentWithRecoPodUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "Pod",
"apiVersion": "v1",
"metadata": map[string]interface{}{
"ownerReferences": []interface{}{
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"controller": true,
"name": "test-vpa-with-reco-0123456789",
},
},
"name": "test-vpa-with-reco-0123456789-01234",
"namespace": "testing",
},
"spec": map[string]interface{}{},
},
}

// The summary of these objects

var testSummary = Summary{
Namespaces: map[string]namespaceSummary{
"testing": {
Namespace: "testing",
Deployments: map[string]deploymentSummary{
Workloads: map[string]workloadSummary{
"test-basic": {
DeploymentName: "test-basic",
ControllerName: "test-basic",
ControllerType: "Deployment",
Containers: map[string]containerSummary{},
},
"test-vpa-with-reco": {
DeploymentName: "test-vpa-with-reco",
ControllerName: "test-vpa-with-reco",
ControllerType: "Deployment",
Containers: map[string]containerSummary{
"container": {
ContainerName: "container",
LowerBound: lowerBound,
UpperBound: upperBound,
Target: targetResources,
Limits: targetResources,
Requests: targetResources,
},
},
},
},
},
},
}

// DaemonSet test and VPA

var testDaemonSettWithRecoUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "DaemonSet",
"apiVersion": "apps/v1",
"metadata": map[string]interface{}{
"name": "test-ds-with-reco",
"namespace": "testing-daemonset",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "container",
"resources": map[string]interface{}{
"limits": map[string]interface{}{
"cpu": "100m",
"memory": "100Mi",
},
"requests": map[string]interface{}{
"cpu": "100m",
"memory": "100Mi",
},
},
},
},
},
},
},
},
}

var testDaemonSetWithRecoPodUnstructured = &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "Pod",
"apiVersion": "v1",
"metadata": map[string]interface{}{
"ownerReferences": []interface{}{
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "DaemonSet",
"controller": true,
"name": "test-ds-with-reco",
},
},
"name": "test-ds-with-reco-01234",
"namespace": "testing-daemonset",
},
"spec": map[string]interface{}{},
},
}

var testDaemonSetVPAWithReco = &vpav1.VerticalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "test-ds-with-reco",
Namespace: "testing-daemonset",
Labels: utils.VPALabels,
},
Spec: vpav1.VerticalPodAutoscalerSpec{
TargetRef: &autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "DaemonSet",
Name: "test-ds-with-reco",
},
UpdatePolicy: &vpav1.PodUpdatePolicy{
UpdateMode: &updateMode,
},
},
Status: vpav1.VerticalPodAutoscalerStatus{
Recommendation: &vpav1.RecommendedPodResources{
ContainerRecommendations: []vpav1.RecommendedContainerResources{
{
ContainerName: "container",
Target: targetResources,
UpperBound: upperBound,
LowerBound: lowerBound,
},
},
},
},
}

// The summary of the daemonset

var testSummaryDaemonSet = Summary{
Namespaces: map[string]namespaceSummary{
"testing-daemonset": {
Namespace: "testing-daemonset",
Workloads: map[string]workloadSummary{
"test-ds-with-reco": {
ControllerName: "test-ds-with-reco",
ControllerType: "DaemonSet",
Containers: map[string]containerSummary{
"container": {
ContainerName: "container",
Expand Down
2 changes: 2 additions & 0 deletions pkg/summary/options.go
Expand Up @@ -12,6 +12,7 @@ type Option func(*options)
type options struct {
kubeClient *kube.ClientInstance
vpaClient *kube.VPAClientInstance
dynamicClient *kube.DynamicClientInstance
namespace string
vpaLabels map[string]string
excludedContainers sets.String
Expand All @@ -22,6 +23,7 @@ func defaultOptions() *options {
return &options{
kubeClient: kube.GetInstance(),
vpaClient: kube.GetVPAInstance(),
dynamicClient: kube.GetDynamicInstance(),
namespace: namespaceAllNamespaces,
vpaLabels: utils.VPALabels,
excludedContainers: sets.NewString(),
Expand Down

0 comments on commit 25481ab

Please sign in to comment.