From 286dbb238a93211ea7fa72e940564855e36e80ed Mon Sep 17 00:00:00 2001 From: Etrik Patricella Date: Fri, 16 Feb 2024 09:49:09 -0500 Subject: [PATCH 1/4] fix: handle differing indent levels for jobTemplate vs temlpate --- pkg/processor/pod/pod.go | 27 +++++++++++++++++++-------- test_data/sample-app.yaml | 29 ++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/pkg/processor/pod/pod.go b/pkg/processor/pod/pod.go index 09979ab..8b20b85 100644 --- a/pkg/processor/pod/pod.go +++ b/pkg/processor/pod/pod.go @@ -16,7 +16,18 @@ import ( const imagePullPolicyTemplate = "{{ .Values.%[1]s.%[2]s.imagePullPolicy }}" const envValue = "{{ quote .Values.%[1]s.%[2]s.%[3]s.%[4]s }}" +func CalculateBaseIndent(resourceType string) int { + switch resourceType { + case "cronJob", "job": + return 4 // Adjusting for the deeper nesting within a JobTemplate + default: + return 0 // Regular Template + } +} + func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpec) (map[string]interface{}, helmify.Values, error) { + baseIndent := CalculateBaseIndent(objName) + values, err := processPodSpec(objName, appMeta, &spec) if err != nil { return nil, nil, err @@ -39,12 +50,12 @@ func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpe return nil, nil, fmt.Errorf("%w: unable to convert podSpec to map", err) } - specMap, values, err = processNestedContainers(specMap, objName, values, "containers") + specMap, values, err = processNestedContainers(specMap, objName, values, "containers", baseIndent) if err != nil { return nil, nil, err } - specMap, values, err = processNestedContainers(specMap, objName, values, "initContainers") + specMap, values, err = processNestedContainers(specMap, objName, values, "initContainers", baseIndent) if err != nil { return nil, nil, err } @@ -63,7 +74,7 @@ func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpe // process nodeSelector if presented: if spec.NodeSelector != nil { - err = unstructured.SetNestedField(specMap, fmt.Sprintf(`{{- toYaml .Values.%s.nodeSelector | nindent 8 }}`, objName), "nodeSelector") + err = unstructured.SetNestedField(specMap, fmt.Sprintf(`{{- toYaml .Values.%s.nodeSelector | nindent %d }}`, objName, 8+baseIndent), "nodeSelector") if err != nil { return nil, nil, err } @@ -76,14 +87,14 @@ func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpe return specMap, values, nil } -func processNestedContainers(specMap map[string]interface{}, objName string, values map[string]interface{}, containerKey string) (map[string]interface{}, map[string]interface{}, error) { +func processNestedContainers(specMap map[string]interface{}, objName string, values map[string]interface{}, containerKey string, baseIndent int) (map[string]interface{}, map[string]interface{}, error) { containers, _, err := unstructured.NestedSlice(specMap, containerKey) if err != nil { return nil, nil, err } if len(containers) > 0 { - containers, values, err = processContainers(objName, values, containerKey, containers) + containers, values, err = processContainers(objName, values, containerKey, containers, baseIndent) if err != nil { return nil, nil, err } @@ -97,7 +108,7 @@ func processNestedContainers(specMap map[string]interface{}, objName string, val return specMap, values, nil } -func processContainers(objName string, values helmify.Values, containerType string, containers []interface{}) ([]interface{}, helmify.Values, error) { +func processContainers(objName string, values helmify.Values, containerType string, containers []interface{}, baseIndent int) ([]interface{}, helmify.Values, error) { for i := range containers { containerName := strcase.ToLowerCamel((containers[i].(map[string]interface{})["name"]).(string)) res, exists, err := unstructured.NestedMap(values, objName, containerName, "resources") @@ -105,7 +116,7 @@ func processContainers(objName string, values helmify.Values, containerType stri return nil, nil, err } if exists && len(res) > 0 { - err = unstructured.SetNestedField(containers[i].(map[string]interface{}), fmt.Sprintf(`{{- toYaml .Values.%s.%s.resources | nindent 10 }}`, objName, containerName), "resources") + err = unstructured.SetNestedField(containers[i].(map[string]interface{}), fmt.Sprintf(`{{- toYaml .Values.%s.%s.resources | nindent %d }}`, objName, containerName, 10+baseIndent), "resources") if err != nil { return nil, nil, err } @@ -116,7 +127,7 @@ func processContainers(objName string, values helmify.Values, containerType stri return nil, nil, err } if exists && len(args) > 0 { - err = unstructured.SetNestedField(containers[i].(map[string]interface{}), fmt.Sprintf(`{{- toYaml .Values.%[1]s.%[2]s.args | nindent 8 }}`, objName, containerName), "args") + err = unstructured.SetNestedField(containers[i].(map[string]interface{}), fmt.Sprintf(`{{- toYaml .Values.%[1]s.%[2]s.args | nindent %d }}`, objName, containerName, 8+baseIndent), "args") if err != nil { return nil, nil, err } diff --git a/test_data/sample-app.yaml b/test_data/sample-app.yaml index a80e04e..cfc7841 100644 --- a/test_data/sample-app.yaml +++ b/test_data/sample-app.yaml @@ -205,7 +205,7 @@ data: name: default-oneperhost-pod-template spec: templates: - podTemplates: + podTemplates: - name: default-oneperhost-pod-template distribution: "OnePerHost" --- @@ -266,7 +266,18 @@ spec: - name: pi image: perl:5.34.0 command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + args: + - "date; echo Hello from the Kubernetes cluster" + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "200m" + memory: "256Mi" restartPolicy: Never + nodeSelector: + disktype: ssd backoffLimit: 4 --- apiVersion: batch/v1 @@ -283,11 +294,19 @@ spec: - name: hello image: busybox:1.28 imagePullPolicy: IfNotPresent - command: - - /bin/sh - - -c - - date; echo Hello from the Kubernetes cluster + command: ["/bin/sh", "-c"] + args: + - "date; echo Hello from the Kubernetes cluster" + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "200m" + memory: "256Mi" restartPolicy: OnFailure + nodeSelector: + disktype: ssd --- apiVersion: v1 kind: Service From f1f443de7615e60771c23191de691c7ab3c640e5 Mon Sep 17 00:00:00 2001 From: Etrik Patricella Date: Fri, 16 Feb 2024 15:22:33 -0500 Subject: [PATCH 2/4] fix: use proper reference to Kind --- pkg/processor/daemonset/daemonset.go | 5 +++-- pkg/processor/deployment/deployment.go | 2 +- pkg/processor/job/cron.go | 9 +++++---- pkg/processor/job/job.go | 9 +++++---- pkg/processor/pod/pod.go | 6 +++--- pkg/processor/pod/pod_test.go | 8 ++++---- pkg/processor/statefulset/statefulset.go | 5 +++-- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/pkg/processor/daemonset/daemonset.go b/pkg/processor/daemonset/daemonset.go index 851abe3..5e9eed6 100644 --- a/pkg/processor/daemonset/daemonset.go +++ b/pkg/processor/daemonset/daemonset.go @@ -2,11 +2,12 @@ package daemonset import ( "fmt" - "github.com/arttor/helmify/pkg/processor/pod" "io" "strings" "text/template" + "github.com/arttor/helmify/pkg/processor/pod" + "github.com/arttor/helmify/pkg/helmify" "github.com/arttor/helmify/pkg/processor" yamlformat "github.com/arttor/helmify/pkg/yaml" @@ -98,7 +99,7 @@ func (d daemonset) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstru } nameCamel := strcase.ToLowerCamel(name) - specMap, podValues, err := pod.ProcessSpec(nameCamel, appMeta, dae.Spec.Template.Spec) + specMap, podValues, err := pod.ProcessSpec(nameCamel, appMeta, dae.Spec.Template.Spec, dae.TypeMeta.Kind) if err != nil { return true, nil, err } diff --git a/pkg/processor/deployment/deployment.go b/pkg/processor/deployment/deployment.go index b96f7b0..2561c00 100644 --- a/pkg/processor/deployment/deployment.go +++ b/pkg/processor/deployment/deployment.go @@ -115,7 +115,7 @@ func (d deployment) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstr } nameCamel := strcase.ToLowerCamel(name) - specMap, podValues, err := pod.ProcessSpec(nameCamel, appMeta, depl.Spec.Template.Spec) + specMap, podValues, err := pod.ProcessSpec(nameCamel, appMeta, depl.Spec.Template.Spec, depl.TypeMeta.Kind) if err != nil { return true, nil, err } diff --git a/pkg/processor/job/cron.go b/pkg/processor/job/cron.go index 1baf186..aea7a43 100644 --- a/pkg/processor/job/cron.go +++ b/pkg/processor/job/cron.go @@ -2,18 +2,19 @@ package job import ( "fmt" + "io" + "strings" + "text/template" + "github.com/arttor/helmify/pkg/helmify" "github.com/arttor/helmify/pkg/processor" "github.com/arttor/helmify/pkg/processor/pod" yamlformat "github.com/arttor/helmify/pkg/yaml" "github.com/iancoleman/strcase" - "io" batchv1 "k8s.io/api/batch/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "strings" - "text/template" ) var cronTempl, _ = template.New("cron").Parse( @@ -105,7 +106,7 @@ func (p cron) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructure } // process job pod template: - podSpecMap, podValues, err := pod.ProcessSpec(nameCamelCase, appMeta, jobObj.Spec.JobTemplate.Spec.Template.Spec) + podSpecMap, podValues, err := pod.ProcessSpec(nameCamelCase, appMeta, jobObj.Spec.JobTemplate.Spec.Template.Spec, jobObj.TypeMeta.Kind) if err != nil { return true, nil, err } diff --git a/pkg/processor/job/job.go b/pkg/processor/job/job.go index 5f1ec53..692678a 100644 --- a/pkg/processor/job/job.go +++ b/pkg/processor/job/job.go @@ -2,18 +2,19 @@ package job import ( "fmt" + "io" + "strings" + "text/template" + "github.com/arttor/helmify/pkg/helmify" "github.com/arttor/helmify/pkg/processor" "github.com/arttor/helmify/pkg/processor/pod" yamlformat "github.com/arttor/helmify/pkg/yaml" "github.com/iancoleman/strcase" - "io" batchv1 "k8s.io/api/batch/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "strings" - "text/template" ) var jobTempl, _ = template.New("job").Parse( @@ -104,7 +105,7 @@ func (p job) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } } // process job pod template: - podSpecMap, podValues, err := pod.ProcessSpec(nameCamelCase, appMeta, jobObj.Spec.Template.Spec) + podSpecMap, podValues, err := pod.ProcessSpec(nameCamelCase, appMeta, jobObj.Spec.Template.Spec, jobObj.TypeMeta.Kind) if err != nil { return true, nil, err } diff --git a/pkg/processor/pod/pod.go b/pkg/processor/pod/pod.go index 8b20b85..1199c5f 100644 --- a/pkg/processor/pod/pod.go +++ b/pkg/processor/pod/pod.go @@ -18,15 +18,15 @@ const envValue = "{{ quote .Values.%[1]s.%[2]s.%[3]s.%[4]s }}" func CalculateBaseIndent(resourceType string) int { switch resourceType { - case "cronJob", "job": + case "CronJob", "Job": return 4 // Adjusting for the deeper nesting within a JobTemplate default: return 0 // Regular Template } } -func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpec) (map[string]interface{}, helmify.Values, error) { - baseIndent := CalculateBaseIndent(objName) +func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpec, kind string) (map[string]interface{}, helmify.Values, error) { + baseIndent := CalculateBaseIndent(kind) values, err := processPodSpec(objName, appMeta, &spec) if err != nil { diff --git a/pkg/processor/pod/pod_test.go b/pkg/processor/pod/pod_test.go index c55b4fc..3f997d0 100644 --- a/pkg/processor/pod/pod_test.go +++ b/pkg/processor/pod/pod_test.go @@ -118,7 +118,7 @@ func Test_pod_Process(t *testing.T) { var deploy appsv1.Deployment obj := internal.GenerateObj(strDeployment) err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) - specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec) + specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec, deploy.TypeMeta.Kind) assert.NoError(t, err) assert.Equal(t, map[string]interface{}{ @@ -162,7 +162,7 @@ func Test_pod_Process(t *testing.T) { var deploy appsv1.Deployment obj := internal.GenerateObj(strDeploymentWithNoArgs) err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) - specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec) + specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec, deploy.TypeMeta.Kind) assert.NoError(t, err) assert.Equal(t, map[string]interface{}{ @@ -201,7 +201,7 @@ func Test_pod_Process(t *testing.T) { var deploy appsv1.Deployment obj := internal.GenerateObj(strDeploymentWithTagAndDigest) err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) - specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec) + specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec, deploy.TypeMeta.Kind) assert.NoError(t, err) assert.Equal(t, map[string]interface{}{ @@ -240,7 +240,7 @@ func Test_pod_Process(t *testing.T) { var deploy appsv1.Deployment obj := internal.GenerateObj(strDeploymentWithPort) err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) - specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec) + specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec, deploy.TypeMeta.Kind) assert.NoError(t, err) assert.Equal(t, map[string]interface{}{ diff --git a/pkg/processor/statefulset/statefulset.go b/pkg/processor/statefulset/statefulset.go index 1091151..0fcc11f 100644 --- a/pkg/processor/statefulset/statefulset.go +++ b/pkg/processor/statefulset/statefulset.go @@ -2,11 +2,12 @@ package statefulset import ( "fmt" - "github.com/arttor/helmify/pkg/processor/pod" "io" "strings" "text/template" + "github.com/arttor/helmify/pkg/processor/pod" + "github.com/arttor/helmify/pkg/helmify" "github.com/arttor/helmify/pkg/processor" yamlformat "github.com/arttor/helmify/pkg/yaml" @@ -108,7 +109,7 @@ func (d statefulset) Process(appMeta helmify.AppMetadata, obj *unstructured.Unst } // process pod spec: - podSpecMap, podValues, err := pod.ProcessSpec(nameCamel, appMeta, ssSpec.Template.Spec) + podSpecMap, podValues, err := pod.ProcessSpec(nameCamel, appMeta, ssSpec.Template.Spec, ss.TypeMeta.Kind) if err != nil { return true, nil, err } From 8ff4eef253ea59a15956289147a455641e9cc30d Mon Sep 17 00:00:00 2001 From: Etrik Patricella Date: Sat, 24 Feb 2024 15:31:54 -0500 Subject: [PATCH 3/4] fix: update examples --- examples/app/templates/batch-job.yaml | 6 ++++-- examples/app/templates/cron-job.yaml | 7 ++++--- examples/app/values.yaml | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/examples/app/templates/batch-job.yaml b/examples/app/templates/batch-job.yaml index d85dbbd..b7f9bd9 100644 --- a/examples/app/templates/batch-job.yaml +++ b/examples/app/templates/batch-job.yaml @@ -9,7 +9,8 @@ spec: template: spec: containers: - - command: + - args: {{- toYaml .Values.batchJob.pi.args | nindent 12 }} + command: - perl - -Mbignum=bpi - -wle @@ -20,5 +21,6 @@ spec: image: {{ .Values.batchJob.pi.image.repository }}:{{ .Values.batchJob.pi.image.tag | default .Chart.AppVersion }} name: pi - resources: {} + resources: {{- toYaml .Values.batchJob.pi.resources | nindent 14 }} + nodeSelector: {{- toYaml .Values.batchJob.nodeSelector | nindent 12 }} restartPolicy: Never \ No newline at end of file diff --git a/examples/app/templates/cron-job.yaml b/examples/app/templates/cron-job.yaml index 453b05a..3c76d10 100644 --- a/examples/app/templates/cron-job.yaml +++ b/examples/app/templates/cron-job.yaml @@ -10,10 +10,10 @@ spec: template: spec: containers: - - command: + - args: {{- toYaml .Values.cronJob.hello.args | nindent 12 }} + command: - /bin/sh - -c - - date; echo Hello from the Kubernetes cluster env: - name: KUBERNETES_CLUSTER_DOMAIN value: {{ quote .Values.kubernetesClusterDomain }} @@ -21,6 +21,7 @@ spec: | default .Chart.AppVersion }} imagePullPolicy: {{ .Values.cronJob.hello.imagePullPolicy }} name: hello - resources: {} + resources: {{- toYaml .Values.cronJob.hello.resources | nindent 14 }} + nodeSelector: {{- toYaml .Values.cronJob.nodeSelector | nindent 12 }} restartPolicy: OnFailure schedule: {{ .Values.cronJob.schedule | quote }} \ No newline at end of file diff --git a/examples/app/values.yaml b/examples/app/values.yaml index 6f23e91..e496b2c 100644 --- a/examples/app/values.yaml +++ b/examples/app/values.yaml @@ -1,15 +1,37 @@ batchJob: backoffLimit: 4 + nodeSelector: + disktype: ssd pi: + args: + - date; echo Hello from the Kubernetes cluster image: repository: perl tag: 5.34.0 + resources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi cronJob: hello: + args: + - date; echo Hello from the Kubernetes cluster image: repository: busybox tag: "1.28" imagePullPolicy: IfNotPresent + resources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi + nodeSelector: + disktype: ssd schedule: '* * * * *' fluentdElasticsearch: fluentdElasticsearch: From 703fb690db08309f01b5cf64a536c5d4e9193fd5 Mon Sep 17 00:00:00 2001 From: Etrik Patricella Date: Sat, 24 Feb 2024 15:58:13 -0500 Subject: [PATCH 4/4] fix: make private --- pkg/processor/pod/pod.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/processor/pod/pod.go b/pkg/processor/pod/pod.go index 1199c5f..fece146 100644 --- a/pkg/processor/pod/pod.go +++ b/pkg/processor/pod/pod.go @@ -16,17 +16,8 @@ import ( const imagePullPolicyTemplate = "{{ .Values.%[1]s.%[2]s.imagePullPolicy }}" const envValue = "{{ quote .Values.%[1]s.%[2]s.%[3]s.%[4]s }}" -func CalculateBaseIndent(resourceType string) int { - switch resourceType { - case "CronJob", "Job": - return 4 // Adjusting for the deeper nesting within a JobTemplate - default: - return 0 // Regular Template - } -} - func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpec, kind string) (map[string]interface{}, helmify.Values, error) { - baseIndent := CalculateBaseIndent(kind) + baseIndent := calculateBaseIndent(kind) values, err := processPodSpec(objName, appMeta, &spec) if err != nil { @@ -108,6 +99,15 @@ func processNestedContainers(specMap map[string]interface{}, objName string, val return specMap, values, nil } +func calculateBaseIndent(resourceType string) int { + switch resourceType { + case "CronJob", "Job": + return 4 // Adjusting for the deeper nesting within a JobTemplate + default: + return 0 // Regular Template + } +} + func processContainers(objName string, values helmify.Values, containerType string, containers []interface{}, baseIndent int) ([]interface{}, helmify.Values, error) { for i := range containers { containerName := strcase.ToLowerCamel((containers[i].(map[string]interface{})["name"]).(string))