Skip to content

Commit b5228e7

Browse files
authored
Merge pull request #1584 from nabokihms/vpa-with-no-target-ref
fix: avoid panic because of VPA objects without target ref
2 parents ef61220 + 05b3d3b commit b5228e7

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

internal/store/verticalpodautoscaler.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package store
1919
import (
2020
"context"
2121

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

282+
// targetRef was not a mandatory field, which can lead to a nil pointer exception here.
283+
// However, we still want to expose metrics to be able:
284+
// * to alert about VPA objects without target refs
285+
// * to count the right amount of VPA objects in a cluster
286+
if targetRef == nil {
287+
targetRef = &autoscalingv1.CrossVersionObjectReference{}
288+
}
289+
281290
for _, m := range metricFamily.Metrics {
282291
m.LabelKeys = append(descVerticalPodAutoscalerLabelsDefaultLabels, m.LabelKeys...)
283292
m.LabelValues = append([]string{vpa.Namespace, vpa.Name, targetRef.APIVersion, targetRef.Kind, targetRef.Name}, m.LabelValues...)

internal/store/verticalpodautoscaler_test.go

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package store
1919
import (
2020
"testing"
2121

22-
k8sautoscaling "k8s.io/api/autoscaling/v1"
22+
autoscalingv1 "k8s.io/api/autoscaling/v1"
2323
v1 "k8s.io/api/core/v1"
2424
"k8s.io/apimachinery/pkg/api/resource"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -69,7 +69,7 @@ func TestVPAStore(t *testing.T) {
6969
},
7070
},
7171
Spec: autoscaling.VerticalPodAutoscalerSpec{
72-
TargetRef: &k8sautoscaling.CrossVersionObjectReference{
72+
TargetRef: &autoscalingv1.CrossVersionObjectReference{
7373
APIVersion: "apps/v1",
7474
Kind: "Deployment",
7575
Name: "deployment1",
@@ -131,6 +131,74 @@ func TestVPAStore(t *testing.T) {
131131
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget",
132132
},
133133
},
134+
{
135+
Obj: &autoscaling.VerticalPodAutoscaler{
136+
ObjectMeta: metav1.ObjectMeta{
137+
Generation: 2,
138+
Name: "vpa-without-target-ref",
139+
Namespace: "ns2",
140+
Labels: map[string]string{
141+
"app": "foobar",
142+
},
143+
},
144+
Spec: autoscaling.VerticalPodAutoscalerSpec{
145+
UpdatePolicy: &autoscaling.PodUpdatePolicy{
146+
UpdateMode: &updateMode,
147+
},
148+
ResourcePolicy: &autoscaling.PodResourcePolicy{
149+
ContainerPolicies: []autoscaling.ContainerResourcePolicy{
150+
{
151+
ContainerName: "*",
152+
MinAllowed: v1Resource("1", "4Gi"),
153+
MaxAllowed: v1Resource("4", "8Gi"),
154+
},
155+
},
156+
},
157+
},
158+
Status: autoscaling.VerticalPodAutoscalerStatus{
159+
Recommendation: &autoscaling.RecommendedPodResources{
160+
ContainerRecommendations: []autoscaling.RecommendedContainerResources{
161+
{
162+
ContainerName: "container1",
163+
LowerBound: v1Resource("1", "4Gi"),
164+
UpperBound: v1Resource("4", "8Gi"),
165+
Target: v1Resource("3", "7Gi"),
166+
UncappedTarget: v1Resource("6", "10Gi"),
167+
},
168+
},
169+
},
170+
},
171+
},
172+
Want: metadata + `
173+
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
174+
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
175+
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
176+
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
177+
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
178+
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
179+
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
180+
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
181+
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
182+
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
183+
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
184+
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
185+
kube_verticalpodautoscaler_labels{namespace="ns2",target_api_version="",target_kind="",target_name="",verticalpodautoscaler="vpa-without-target-ref"} 1
186+
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Auto",verticalpodautoscaler="vpa-without-target-ref"} 0
187+
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Initial",verticalpodautoscaler="vpa-without-target-ref"} 0
188+
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Off",verticalpodautoscaler="vpa-without-target-ref"} 0
189+
kube_verticalpodautoscaler_spec_updatepolicy_updatemode{namespace="ns2",target_api_version="",target_kind="",target_name="",update_mode="Recreate",verticalpodautoscaler="vpa-without-target-ref"} 1
190+
`,
191+
MetricNames: []string{
192+
"kube_verticalpodautoscaler_labels",
193+
"kube_verticalpodautoscaler_spec_updatepolicy_updatemode",
194+
"kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_minallowed",
195+
"kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_maxallowed",
196+
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound",
197+
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_upperbound",
198+
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_target",
199+
"kube_verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget",
200+
},
201+
},
134202
}
135203
for i, c := range cases {
136204
c.Func = generator.ComposeMetricGenFuncs(vpaMetricFamilies(nil, nil))

0 commit comments

Comments
 (0)