From 58ab921e9183e92fbc8501795c1047aea5c4b700 Mon Sep 17 00:00:00 2001 From: Anas Khan Date: Tue, 14 Jul 2026 13:38:49 +0530 Subject: [PATCH] fix: guard against nil spec.replicas in deployment analyzer (#1683) The Deployment analyzer dereferenced *deployment.Spec.Replicas without a nil check. Spec.Replicas is a *int32 and, although the API server usually defaults it to 1, a Deployment object whose replicas field is explicitly unset (nil) panics the analyze run with a nil pointer dereference. Guard the comparison with a nil check, mirroring the sibling StatefulSet analyzer which already checks Spec.Replicas != nil before dereferencing. Add a regression test that analyzes a Deployment with nil Spec.Replicas and asserts Analyze does not panic. Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com> Co-authored-by: Alex Jones <1235925+AlexsJones@users.noreply.github.com> --- pkg/analyzer/deployment.go | 2 +- pkg/analyzer/deployment_test.go | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/pkg/analyzer/deployment.go b/pkg/analyzer/deployment.go index 5ece4e5c..df33b0db 100644 --- a/pkg/analyzer/deployment.go +++ b/pkg/analyzer/deployment.go @@ -54,7 +54,7 @@ func (d DeploymentAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) for _, deployment := range deployments.Items { var failures []common.Failure - if *deployment.Spec.Replicas != deployment.Status.ReadyReplicas { + if deployment.Spec.Replicas != nil && *deployment.Spec.Replicas != deployment.Status.ReadyReplicas { if deployment.Status.Replicas > *deployment.Spec.Replicas { doc := apiDoc.GetApiDocV2("spec.replicas") diff --git a/pkg/analyzer/deployment_test.go b/pkg/analyzer/deployment_test.go index d7486351..9e214949 100644 --- a/pkg/analyzer/deployment_test.go +++ b/pkg/analyzer/deployment_test.go @@ -74,6 +74,48 @@ func TestDeploymentAnalyzer(t *testing.T) { assert.Equal(t, analysisResults[0].Name, "default/example") } +func TestDeploymentAnalyzerNilReplicas(t *testing.T) { + // A Deployment with an unset spec.replicas (nil) must not panic the analyzer. + clientset := fake.NewSimpleClientset(&appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + }, + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "example-container", + Image: "nginx", + }, + }, + }, + }, + }, + Status: appsv1.DeploymentStatus{ + Replicas: 2, + AvailableReplicas: 1, + }, + }) + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + + deploymentAnalyzer := DeploymentAnalyzer{} + analysisResults, err := deploymentAnalyzer.Analyze(config) + if err != nil { + t.Error(err) + } + assert.Equal(t, len(analysisResults), 0) +} + func TestDeploymentAnalyzerNamespaceFiltering(t *testing.T) { clientset := fake.NewSimpleClientset( &appsv1.Deployment{