From 17b8ab87f7ab89e6066b6773fff70aad55224e6c Mon Sep 17 00:00:00 2001 From: Safwan Date: Fri, 31 Oct 2025 19:37:44 +0500 Subject: [PATCH 1/2] Add field for imagePullSecrets if image pull secrets are enabled --- pkg/processor/pod/pod.go | 10 ++++-- pkg/processor/pod/pod_test.go | 60 +++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/pkg/processor/pod/pod.go b/pkg/processor/pod/pod.go index 88adb825..669cb106 100644 --- a/pkg/processor/pod/pod.go +++ b/pkg/processor/pod/pod.go @@ -8,6 +8,7 @@ import ( "github.com/arttor/helmify/pkg/helmify" securityContext "github.com/arttor/helmify/pkg/processor/security-context" "github.com/iancoleman/strcase" + "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -50,10 +51,13 @@ func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpe } if appMeta.Config().ImagePullSecrets { - if _, defined := specMap["imagePullSecrets"]; !defined { - specMap["imagePullSecrets"] = "{{ .Values.imagePullSecrets | default list | toJson }}" - values["imagePullSecrets"] = []string{} + sourceImagePullSecrets, ok := specMap["imagePullSecrets"].([]interface{}) + if !ok { + logrus.Debug("imagePullSecrets not found in pod spec, setting empty map") + sourceImagePullSecrets = []interface{}{} } + specMap["imagePullSecrets"] = "{{ .Values.imagePullSecrets | default list | toJson }}" + values["imagePullSecrets"] = sourceImagePullSecrets } err = securityContext.ProcessContainerSecurityContext(objName, specMap, &values) diff --git a/pkg/processor/pod/pod_test.go b/pkg/processor/pod/pod_test.go index 5a2fd721..74d54492 100644 --- a/pkg/processor/pod/pod_test.go +++ b/pkg/processor/pod/pod_test.go @@ -3,6 +3,7 @@ package pod import ( "testing" + "github.com/arttor/helmify/pkg/config" "github.com/arttor/helmify/pkg/helmify" "github.com/arttor/helmify/pkg/metadata" appsv1 "k8s.io/api/apps/v1" @@ -137,6 +138,31 @@ spec: runAsNonRoot: true runAsUser: 65532 +` + strDeploymentWithImagePullSecrets = ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + imagePullSecrets: + - name: myregistrykey + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 ` ) @@ -341,5 +367,39 @@ func Test_pod_Process(t *testing.T) { }, }, tmpl) }) + t.Run("deployment without imagePullSecrets", func(t *testing.T) { + var deploy appsv1.Deployment + obj := internal.GenerateObj(strDeployment) + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) + assert.NoError(t, err) + specMap, _, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec) + assert.NoError(t, err) + + // when ImagePullSecrets is disabled in config, spec should not contain imagePullSecrets key + _, ok := specMap["imagePullSecrets"] + assert.False(t, ok) + }) + + t.Run("deployment with imagePullSecrets", func(t *testing.T) { + + var deploy appsv1.Deployment + obj := internal.GenerateObj(strDeploymentWithImagePullSecrets) + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) + assert.NoError(t, err) + // enable ImagePullSecrets in config via metadata.New + svc := metadata.New(config.Config{ImagePullSecrets: true}) + specMap, tmpl, err := ProcessSpec("nginx", svc, deploy.Spec.Template.Spec) + assert.NoError(t, err) + + // spec should contain templated imagePullSecrets + assert.Equal(t, "{{ .Values.imagePullSecrets | default list | toJson }}", specMap["imagePullSecrets"]) + + // values should contain the original imagePullSecrets slice + assert.Equal(t, helmify.Values{ + "imagePullSecrets": []interface{}{ + map[string]interface{}{"name": "myregistrykey"}, + }, + }, tmpl) + }) } From c2f86699fb258cd3b9469ca89ae62f4b4f2bec10 Mon Sep 17 00:00:00 2001 From: Safwan Date: Fri, 31 Oct 2025 20:08:14 +0500 Subject: [PATCH 2/2] Fixed test cases --- pkg/processor/pod/pod_test.go | 65 ++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/pkg/processor/pod/pod_test.go b/pkg/processor/pod/pod_test.go index 74d54492..d125edff 100644 --- a/pkg/processor/pod/pod_test.go +++ b/pkg/processor/pod/pod_test.go @@ -143,26 +143,29 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: nginx-deployment - labels: - app: nginx + name: nginx-deployment + labels: + app: nginx spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - imagePullSecrets: - - name: myregistrykey - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + args: + - --test + - --arg + ports: + - containerPort: 80 + imagePullSecrets: + - name: myregistrykey ` ) @@ -380,6 +383,22 @@ func Test_pod_Process(t *testing.T) { assert.False(t, ok) }) + t.Run("deployment with imagePullSecrets enabled but not provided in source", func(t *testing.T) { + var deploy appsv1.Deployment + obj := internal.GenerateObj(strDeployment) + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) + assert.NoError(t, err) + // enable ImagePullSecrets in config via metadata.New but source doesn't include imagePullSecrets + svc := metadata.New(config.Config{ImagePullSecrets: true}) + specMap, tmpl, err := ProcessSpec("nginx", svc, deploy.Spec.Template.Spec) + assert.NoError(t, err) + + // spec should contain templated imagePullSecrets + assert.Equal(t, "{{ .Values.imagePullSecrets | default list | toJson }}", specMap["imagePullSecrets"]) + + assert.Equal(t, []interface{}{}, tmpl["imagePullSecrets"]) + }) + t.Run("deployment with imagePullSecrets", func(t *testing.T) { var deploy appsv1.Deployment @@ -395,11 +414,9 @@ func Test_pod_Process(t *testing.T) { assert.Equal(t, "{{ .Values.imagePullSecrets | default list | toJson }}", specMap["imagePullSecrets"]) // values should contain the original imagePullSecrets slice - assert.Equal(t, helmify.Values{ - "imagePullSecrets": []interface{}{ - map[string]interface{}{"name": "myregistrykey"}, - }, - }, tmpl) + assert.Equal(t, []interface{}{ + map[string]interface{}{"name": "myregistrykey"}, + }, tmpl["imagePullSecrets"]) }) }