From f67ca55d445bb456d01484f47bea54809427a73d Mon Sep 17 00:00:00 2001 From: immanuwell Date: Thu, 28 May 2026 08:55:34 +0400 Subject: [PATCH] fix(deployment): guard nil Spec.Replicas before dereference --- internal/store/deployment.go | 18 +++++++++++------- internal/store/deployment_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/internal/store/deployment.go b/internal/store/deployment.go index 2c98250f98..e9f75b0ffb 100644 --- a/internal/store/deployment.go +++ b/internal/store/deployment.go @@ -271,12 +271,16 @@ func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] basemetrics.STABLE, "", wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { + ms := []*metric.Metric{} + + if d.Spec.Replicas != nil { + ms = append(ms, &metric.Metric{ + Value: float64(*d.Spec.Replicas), + }) + } + return &metric.Family{ - Metrics: []*metric.Metric{ - { - Value: float64(*d.Spec.Replicas), - }, - }, + Metrics: ms, } }), ), @@ -303,7 +307,7 @@ func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] basemetrics.STABLE, "", wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { - if d.Spec.Strategy.RollingUpdate == nil { + if d.Spec.Strategy.RollingUpdate == nil || d.Spec.Replicas == nil { return &metric.Family{} } @@ -328,7 +332,7 @@ func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] basemetrics.STABLE, "", wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { - if d.Spec.Strategy.RollingUpdate == nil { + if d.Spec.Strategy.RollingUpdate == nil || d.Spec.Replicas == nil { return &metric.Family{} } diff --git a/internal/store/deployment_test.go b/internal/store/deployment_test.go index c062729aeb..cb1e416a2d 100644 --- a/internal/store/deployment_test.go +++ b/internal/store/deployment_test.go @@ -316,6 +316,35 @@ func TestDeploymentStore(t *testing.T) { kube_deployment_status_replicas_updated{deployment="deployment-without-owner",namespace="ns5"} 0 `, }, + { + Obj: &v1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-nil-replicas", + Namespace: "ns6", + }, + Spec: v1.DeploymentSpec{ + Strategy: v1.DeploymentStrategy{ + RollingUpdate: &v1.RollingUpdateDeployment{ + MaxUnavailable: &depl1MaxUnavailable, + MaxSurge: &depl1MaxSurge, + }, + }, + }, + }, + Want: ` + # HELP kube_deployment_spec_replicas [STABLE] Number of desired pods for a deployment. + # TYPE kube_deployment_spec_replicas gauge + # HELP kube_deployment_spec_strategy_rollingupdate_max_unavailable [STABLE] Maximum number of unavailable replicas during a rolling update of a deployment. + # TYPE kube_deployment_spec_strategy_rollingupdate_max_unavailable gauge + # HELP kube_deployment_spec_strategy_rollingupdate_max_surge [STABLE] Maximum number of replicas that can be scheduled above the desired number of replicas during a rolling update of a deployment. + # TYPE kube_deployment_spec_strategy_rollingupdate_max_surge gauge + `, + MetricNames: []string{ + "kube_deployment_spec_replicas", + "kube_deployment_spec_strategy_rollingupdate_max_unavailable", + "kube_deployment_spec_strategy_rollingupdate_max_surge", + }, + }, } for i, c := range cases { c.Func = generator.ComposeMetricGenFuncs(deploymentMetricFamilies(c.AllowAnnotationsList, nil))