Skip to content

Commit

Permalink
Merge pull request #1584 from nabokihms/vpa-with-no-target-ref
Browse files Browse the repository at this point in the history
fix: avoid panic because of VPA objects without target ref
  • Loading branch information
k8s-ci-robot committed Sep 22, 2021
2 parents ef61220 + 05b3d3b commit b5228e7
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
9 changes: 9 additions & 0 deletions internal/store/verticalpodautoscaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package store
import (
"context"

autoscalingv1 "k8s.io/api/autoscaling/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -278,6 +279,14 @@ func wrapVPAFunc(f func(*autoscaling.VerticalPodAutoscaler) *metric.Family) func
metricFamily := f(vpa)
targetRef := vpa.Spec.TargetRef

// targetRef was not a mandatory field, which can lead to a nil pointer exception here.
// However, we still want to expose metrics to be able:
// * to alert about VPA objects without target refs
// * to count the right amount of VPA objects in a cluster
if targetRef == nil {
targetRef = &autoscalingv1.CrossVersionObjectReference{}
}

for _, m := range metricFamily.Metrics {
m.LabelKeys = append(descVerticalPodAutoscalerLabelsDefaultLabels, m.LabelKeys...)
m.LabelValues = append([]string{vpa.Namespace, vpa.Name, targetRef.APIVersion, targetRef.Kind, targetRef.Name}, m.LabelValues...)
Expand Down
72 changes: 70 additions & 2 deletions internal/store/verticalpodautoscaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package store
import (
"testing"

k8sautoscaling "k8s.io/api/autoscaling/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"
Expand Down Expand Up @@ -69,7 +69,7 @@ func TestVPAStore(t *testing.T) {
},
},
Spec: autoscaling.VerticalPodAutoscalerSpec{
TargetRef: &k8sautoscaling.CrossVersionObjectReference{
TargetRef: &autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment1",
Expand Down Expand Up @@ -131,6 +131,74 @@ func TestVPAStore(t *testing.T) {
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget",
},
},
{
Obj: &autoscaling.VerticalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Generation: 2,
Name: "vpa-without-target-ref",
Namespace: "ns2",
Labels: map[string]string{
"app": "foobar",
},
},
Spec: autoscaling.VerticalPodAutoscalerSpec{
UpdatePolicy: &autoscaling.PodUpdatePolicy{
UpdateMode: &updateMode,
},
ResourcePolicy: &autoscaling.PodResourcePolicy{
ContainerPolicies: []autoscaling.ContainerResourcePolicy{
{
ContainerName: "*",
MinAllowed: v1Resource("1", "4Gi"),
MaxAllowed: v1Resource("4", "8Gi"),
},
},
},
},
Status: autoscaling.VerticalPodAutoscalerStatus{
Recommendation: &autoscaling.RecommendedPodResources{
ContainerRecommendations: []autoscaling.RecommendedContainerResources{
{
ContainerName: "container1",
LowerBound: v1Resource("1", "4Gi"),
UpperBound: v1Resource("4", "8Gi"),
Target: v1Resource("3", "7Gi"),
UncappedTarget: v1Resource("6", "10Gi"),
},
},
},
},
},
Want: metadata + `
kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_maxallowed{container="*",namespace="ns2",resource="cpu",target_api_version="",target_kind="",target_name="",unit="core",verticalpodautoscaler="vpa-without-target-ref"} 4
kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_maxallowed{container="*",namespace="ns2",resource="memory",target_api_version="",target_kind="",target_name="",unit="byte",verticalpodautoscaler="vpa-without-target-ref"} 8.589934592e+09
kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_minallowed{container="*",namespace="ns2",resource="cpu",target_api_version="",target_kind="",target_name="",unit="core",verticalpodautoscaler="vpa-without-target-ref"} 1
kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_minallowed{container="*",namespace="ns2",resource="memory",target_api_version="",target_kind="",target_name="",unit="byte",verticalpodautoscaler="vpa-without-target-ref"} 4.294967296e+09
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound{container="container1",namespace="ns2",resource="cpu",target_api_version="",target_kind="",target_name="",unit="core",verticalpodautoscaler="vpa-without-target-ref"} 1
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound{container="container1",namespace="ns2",resource="memory",target_api_version="",target_kind="",target_name="",unit="byte",verticalpodautoscaler="vpa-without-target-ref"} 4.294967296e+09
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_target{container="container1",namespace="ns2",resource="cpu",target_api_version="",target_kind="",target_name="",unit="core",verticalpodautoscaler="vpa-without-target-ref"} 3
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_target{container="container1",namespace="ns2",resource="memory",target_api_version="",target_kind="",target_name="",unit="byte",verticalpodautoscaler="vpa-without-target-ref"} 7.516192768e+09
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget{container="container1",namespace="ns2",resource="cpu",target_api_version="",target_kind="",target_name="",unit="core",verticalpodautoscaler="vpa-without-target-ref"} 6
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget{container="container1",namespace="ns2",resource="memory",target_api_version="",target_kind="",target_name="",unit="byte",verticalpodautoscaler="vpa-without-target-ref"} 1.073741824e+10
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_upperbound{container="container1",namespace="ns2",resource="cpu",target_api_version="",target_kind="",target_name="",unit="core",verticalpodautoscaler="vpa-without-target-ref"} 4
kube_verticalpodautoscaler_status_recommendation_containerrecommendations_upperbound{container="container1",namespace="ns2",resource="memory",target_api_version="",target_kind="",target_name="",unit="byte",verticalpodautoscaler="vpa-without-target-ref"} 8.589934592e+09
kube_verticalpodautoscaler_labels{namespace="ns2",target_api_version="",target_kind="",target_name="",verticalpodautoscaler="vpa-without-target-ref"} 1
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Auto",verticalpodautoscaler="vpa-without-target-ref"} 0
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Initial",verticalpodautoscaler="vpa-without-target-ref"} 0
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Off",verticalpodautoscaler="vpa-without-target-ref"} 0
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Recreate",verticalpodautoscaler="vpa-without-target-ref"} 1
`,
MetricNames: []string{
"kube_verticalpodautoscaler_labels",
"kube_verticalpodautoscaler_spec_updatepolicy_updatemode",
"kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_minallowed",
"kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_maxallowed",
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound",
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_upperbound",
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_target",
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget",
},
},
}
for i, c := range cases {
c.Func = generator.ComposeMetricGenFuncs(vpaMetricFamilies(nil, nil))
Expand Down

0 comments on commit b5228e7

Please sign in to comment.