From b4f5f3d7d79b92f7f80e060575dcc99b7268624b Mon Sep 17 00:00:00 2001 From: thenav56 Date: Tue, 22 Apr 2025 14:32:39 +0545 Subject: [PATCH 1/2] feat(django): Use _helpers for same configurations - Add option to include custom secrets/configmap - Add support for cronjobs --- toggle/django-app/Chart.yaml | 2 +- toggle/django-app/templates/_helpers.tpl | 59 +++++++++++++++++++ .../django-app/templates/api/deployment.yaml | 19 +++--- .../templates/argo-hooks/hook-job.yaml | 24 ++++---- .../templates/celery-flower/deployment.yaml | 19 +++--- .../templates/cronjobs/deployment.yaml | 52 ++++++++++++++++ .../templates/worker-beat/deployment.yaml | 19 +++--- .../templates/worker/deployment.yaml | 24 ++++---- toggle/django-app/values-test.yaml | 26 ++++++++ toggle/django-app/values.yaml | 30 ++++++++++ 10 files changed, 226 insertions(+), 48 deletions(-) create mode 100644 toggle/django-app/templates/cronjobs/deployment.yaml diff --git a/toggle/django-app/Chart.yaml b/toggle/django-app/Chart.yaml index 17ba4c9..cce1289 100644 --- a/toggle/django-app/Chart.yaml +++ b/toggle/django-app/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: django-app description: "Helm Chart to deploy the Django application" type: application -version: 0.1.0 +version: 0.1.1 sources: - https://github.com/toggle-corp/charts diff --git a/toggle/django-app/templates/_helpers.tpl b/toggle/django-app/templates/_helpers.tpl index 93b5c0f..583abb4 100644 --- a/toggle/django-app/templates/_helpers.tpl +++ b/toggle/django-app/templates/_helpers.tpl @@ -52,3 +52,62 @@ Create the name of the configmap to be used by the django-app {{- printf "%s-env-name" (include "django-app.fullname" .) -}} {{- end -}} {{- end -}} + +{{/* +Generate image metadata +*/}} +{{- define "django-app.imageConfig" -}} +{{- $default := deepCopy .Default -}} +{{- $override := deepCopy (default dict .Override) -}} +{{- $merged := ( + merge + (dict) + $override + $default + ) +-}} +image: "{{ printf "%s:%s" $merged.name $merged.tag }}" +imagePullPolicy: {{ default "IfNotPresent" $merged.imagePullPolicy }} +{{- end }} + +{{/* +Generate resources metadata +*/}} +{{- define "django-app.resourcesConfig" -}} +{{- $default := deepCopy .Default -}} +{{- $override := deepCopy (default dict .Override) -}} +{{ + ( + merge + (dict) + $override + $default + ) | toYaml +}} +{{- end }} + +{{/* +Generate env configs for deployments +*/}} +{{- define "django-app.envConfig" -}} +- secretRef: + name: {{ template "django-app.secretname" . }} +{{- if .Values.extraSecretsName }} +- secretRef: + name: {{ .Values.extraSecretsName }} +{{- end }} +- configMapRef: + name: {{ template "django-app.envConfigMapName" . }} +{{- if .Values.extraConfigMapName }} +- configMapRef: + name: {{ .Values.extraConfigMapName }} +{{- end }} +{{- end }} + +{{/* +Generate env configs for app types +*/}} +{{- define "django-app.appTypeConfig" -}} +- name: {{ .Values.appTypeEnvName }} + value: {{ .Type | quote }} +{{- end }} diff --git a/toggle/django-app/templates/api/deployment.yaml b/toggle/django-app/templates/api/deployment.yaml index 0c9d531..f5c34c2 100644 --- a/toggle/django-app/templates/api/deployment.yaml +++ b/toggle/django-app/templates/api/deployment.yaml @@ -26,8 +26,10 @@ spec: spec: containers: - name: api - image: "{{ default .Values.api.image.name .Values.image.name }}:{{ default .Values.api.image.tag .Values.image.tag }}" - imagePullPolicy: {{ default .Values.api.image.imagePullPolicy .Values.image.imagePullPolicy }} + {{- include "django-app.imageConfig" + (dict "Default" $.Values.image "Override" $.Values.api.image) + | nindent 10 + }} command: {{- toYaml .Values.api.command | nindent 12 }} ports: @@ -37,13 +39,12 @@ spec: # TODO: livenessProbe resources: {{- toYaml .Values.api.resources | nindent 12 }} - env: - - name: DJANGO_APP_TYPE - value: web envFrom: - - secretRef: - name: {{ template "django-app.secretname" . }} - - configMapRef: - name: {{ template "django-app.envConfigMapName" . }} + {{- include "django-app.envConfig" $ | nindent 12 }} + env: + {{- include "django-app.appTypeConfig" + (dict "Values" $.Values "Type" "web" ) + | nindent 12 + }} {{- end }} diff --git a/toggle/django-app/templates/argo-hooks/hook-job.yaml b/toggle/django-app/templates/argo-hooks/hook-job.yaml index be109b9..587ed93 100644 --- a/toggle/django-app/templates/argo-hooks/hook-job.yaml +++ b/toggle/django-app/templates/argo-hooks/hook-job.yaml @@ -21,22 +21,26 @@ spec: restartPolicy: "Never" containers: - name: {{ $hookName }} - image: "{{ default $.Values.argoHook.image.name $.Values.image.name }}:{{ default $.Values.argoHook.image.tag $.Values.image.tag }}" - imagePullPolicy: {{ default $.Values.argoHook.image.imagePullPolicy $.Values.image.imagePullPolicy }} + {{- include "django-app.imageConfig" + (dict "Default" $.Values.image "Override" $.Values.argoHook.image) + | nindent 10 + }} command: {{ toYaml $hook.command | trim | nindent 12 }} {{- if $hook.args }} args: {{ toYaml $hook.args | trim | nindent 12 }} {{- end }} resources: - {{- toYaml (default $hook.resources $.Values.argoHook.resources) | nindent 12 }} - env: - - name: DJANGO_APP_TYPE - value: hook + {{- include "django-app.resourcesConfig" + (dict "Default" $.Values.argoHook.resources "Override" $hook.resources) + | nindent 12 + }} envFrom: - - secretRef: - name: {{ template "django-app.secretname" $ }} - - configMapRef: - name: {{ template "django-app.envConfigMapName" $ }} + {{- include "django-app.envConfig" $ | nindent 12 }} + env: + {{- include "django-app.appTypeConfig" + (dict "Values" $.Values "Type" "hook" ) + | nindent 12 + }} {{- end }} diff --git a/toggle/django-app/templates/celery-flower/deployment.yaml b/toggle/django-app/templates/celery-flower/deployment.yaml index bb8affd..e1d4cdd 100644 --- a/toggle/django-app/templates/celery-flower/deployment.yaml +++ b/toggle/django-app/templates/celery-flower/deployment.yaml @@ -27,21 +27,22 @@ spec: spec: containers: - name: worker - image: "{{ default .Values.worker.flower.image.name .Values.image.name }}:{{ default .Values.worker.flower.image.tag .Values.image.tag }}" - imagePullPolicy: {{ default .Values.worker.flower.image.imagePullPolicy .Values.image.imagePullPolicy }} + {{- include "django-app.imageConfig" + (dict "Default" $.Values.image "Override" $.Values.worker.flower.image) + | nindent 10 + }} command: {{- toYaml .Values.worker.flower.command | nindent 12 }} # TODO: livenessProbe resources: {{- toYaml .Values.worker.flower.resources | nindent 12 }} - env: - - name: DJANGO_APP_TYPE - value: worker envFrom: - - secretRef: - name: {{ template "django-app.secretname" . }} - - configMapRef: - name: {{ template "django-app.envConfigMapName" . }} + {{- include "django-app.envConfig" $ | nindent 12 }} + env: + {{- include "django-app.appTypeConfig" + (dict "Values" $.Values "Type" "worker" ) + | nindent 12 + }} {{- end }} {{- end }} diff --git a/toggle/django-app/templates/cronjobs/deployment.yaml b/toggle/django-app/templates/cronjobs/deployment.yaml new file mode 100644 index 0000000..e1da0c2 --- /dev/null +++ b/toggle/django-app/templates/cronjobs/deployment.yaml @@ -0,0 +1,52 @@ +{{- if .Values.cronjobs.enabled }} + +{{- range $jobName, $job := .Values.cronjobs.jobs }} + +{{- if $job.enabled }} + +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ template "django-app.fullname" $ }}-job-{{ $jobName | nospace | lower | replace "_" "-" }} + labels: + app: {{ include "django-app.fullname" $ }} + component: cronjob + jobName: {{ $jobName }} + environment: {{ $.Values.environment }} + release: {{ $.Release.Name }} +spec: + schedule: {{ $job.schedule | quote }} + concurrencyPolicy: "Forbid" + jobTemplate: + spec: + activeDeadlineSeconds: {{ default 7200 $job.timeLimit }} # 2 hours default + template: + spec: + restartPolicy: "Never" + containers: + - name: cronjob + command: + {{- toYaml $job.command | nindent 16 }} + {{- include "django-app.imageConfig" + (dict "Default" $.Values.image "Override" $.Values.cronjobs.image) + | nindent 14 + }} + resources: + {{- include "django-app.resourcesConfig" + (dict "Default" $.Values.cronjobs.defaultResources "Override" $job.resources) + | nindent 16 + }} + envFrom: + {{- include "django-app.envConfig" $ | nindent 16 }} + env: + {{- include "django-app.appTypeConfig" + (dict "Values" $.Values "Type" "cronjob" ) + | nindent 16 + }} + +{{- end }} + +{{- end }} + +{{- end }} diff --git a/toggle/django-app/templates/worker-beat/deployment.yaml b/toggle/django-app/templates/worker-beat/deployment.yaml index 743123e..a9bee3f 100644 --- a/toggle/django-app/templates/worker-beat/deployment.yaml +++ b/toggle/django-app/templates/worker-beat/deployment.yaml @@ -26,20 +26,21 @@ spec: spec: containers: - name: worker-beat - image: "{{ default .Values.worker.beat.image.name .Values.image.name }}:{{ default .Values.worker.beat.image.tag .Values.image.tag }}" - imagePullPolicy: {{ default .Values.worker.beat.image.imagePullPolicy .Values.image.imagePullPolicy }} + {{- include "django-app.imageConfig" + (dict "Default" $.Values.image "Override" $.Values.worker.beat.image) + | nindent 10 + }} command: {{- toYaml .Values.worker.beat.command | nindent 12 }} # TODO: livenessProbe resources: {{- toYaml .Values.worker.beat.resources | nindent 12 }} - env: - - name: DJANGO_APP_TYPE - value: worker envFrom: - - secretRef: - name: {{ template "django-app.secretname" . }} - - configMapRef: - name: {{ template "django-app.envConfigMapName" . }} + {{- include "django-app.envConfig" $ | nindent 12 }} + env: + {{- include "django-app.appTypeConfig" + (dict "Values" $.Values "Type" "worker" ) + | nindent 12 + }} {{- end }} diff --git a/toggle/django-app/templates/worker/deployment.yaml b/toggle/django-app/templates/worker/deployment.yaml index 98cb363..28ce3b6 100644 --- a/toggle/django-app/templates/worker/deployment.yaml +++ b/toggle/django-app/templates/worker/deployment.yaml @@ -32,22 +32,26 @@ spec: spec: containers: - name: worker - image: "{{ default $.Values.worker.image.name $.Values.image.name }}:{{ default $.Values.worker.image.tag $.Values.image.tag }}" - imagePullPolicy: {{ default $.Values.worker.image.imagePullPolicy $.Values.image.imagePullPolicy }} command: {{- toYaml $.Values.worker.queueCommandPrefix | nindent 12 }} {{- toYaml $config.celeryArgs | nindent 12 }} + {{- include "django-app.imageConfig" + (dict "Default" $.Values.image "Override" $.Values.worker.image) + | nindent 10 + }} # TODO: livenessProbe resources: - {{- toYaml $config.resources | nindent 12 }} - env: - - name: DJANGO_APP_TYPE - value: worker + {{- include "django-app.resourcesConfig" + (dict "Default" $.Values.worker.queueDefaultResources "Override" $config.resources) + | nindent 12 + }} envFrom: - - secretRef: - name: {{ template "django-app.secretname" $ }} - - configMapRef: - name: {{ template "django-app.envConfigMapName" $ }} + {{- include "django-app.envConfig" $ | nindent 12 }} + env: + {{- include "django-app.appTypeConfig" + (dict "Values" $.Values "Type" "worker" ) + | nindent 12 + }} {{- end }} diff --git a/toggle/django-app/values-test.yaml b/toggle/django-app/values-test.yaml index fbbdf91..b818fbf 100644 --- a/toggle/django-app/values-test.yaml +++ b/toggle/django-app/values-test.yaml @@ -3,6 +3,7 @@ environment: ALPHA image: name: ghcr.io/example/example tag: v1.0.1 + imagePullPolicy: IfNotPresent ingress: enabled: true @@ -77,9 +78,34 @@ argoHook: args: - "date --iso-8601 && ls" +cronjobs: + enabled: true + image: + name: ghcr.io/example/cronjob + tag: v1.cronjob + defaultResources: + requests: + cpu: "1" + memory: 1Gi + limits: + cpu: "1" + memory: 2Gi + # NOTE: Application level configuration + jobs: + "dummy": + enabled: true + schedule: "0 0 * * *" + command: ["./manage.py", "run-dummy-command"] + resources: + requests: + cpu: "2" + memory: 4Gi + +extraConfigMapName: "my-custom-envs" env: ENV_1: VALUE_1 +extraSecretsName: "my-custom-secrets" secrets: # Postgres POSTGRES_DB: "{{ $.Values.postgresql.auth.database }}" diff --git a/toggle/django-app/values.yaml b/toggle/django-app/values.yaml index 9c34f7e..df24290 100644 --- a/toggle/django-app/values.yaml +++ b/toggle/django-app/values.yaml @@ -1,5 +1,6 @@ environment: PROD +appTypeEnvName: "DJANGO_APP_TYPE" image: {} # name: # tag: @@ -146,6 +147,13 @@ worker: limits: cpu: "1" memory: 1Gi + queueDefaultResources: + requests: + cpu: "1" + memory: 1Gi + limits: + cpu: "1" + memory: 2Gi queueCommandPrefix: - "celery" - "-A" @@ -173,6 +181,26 @@ worker: cpu: "1" memory: 2Gi +cronjobs: + enabled: true + image: {} + # name: CRONJOB-SET-BY-CICD-IMAGE + # tag: CRONJOB-SET-BY-CICD-TAG + # imagePullPolicy: IfNotPresent + defaultResources: + requests: + cpu: "1" + memory: 1Gi + limits: + cpu: "1" + memory: 2Gi + # NOTE: Application level configuration + jobs: + "dummy": + schedule: "0 0 * * *" + enabled: false + command: ["./manage.py", "run-dummy-command"] + # Not required if global image are set argoHook: enabled: true @@ -199,9 +227,11 @@ argoHook: hook: PostSync command: ["./manage.py", "collectstatic", "--noinput"] +extraConfigMapName: "" # User provided name envConfigMapName: "" env: {} +extraSecretsName: "" # User provided name secretsName: "" secrets: {} # # Postgres From 14a74d6487a23f5bc2aaa4d580e3457cbab892df Mon Sep 17 00:00:00 2001 From: thenav56 Date: Wed, 23 Apr 2025 07:42:25 +0545 Subject: [PATCH 2/2] feat(cronjob): Add timeZone support --- .../django-app/templates/cronjobs/deployment.yaml | 3 +++ toggle/django-app/values-test.yaml | 14 ++++++++++++-- toggle/django-app/values.yaml | 11 ++++++----- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/toggle/django-app/templates/cronjobs/deployment.yaml b/toggle/django-app/templates/cronjobs/deployment.yaml index e1da0c2..d837312 100644 --- a/toggle/django-app/templates/cronjobs/deployment.yaml +++ b/toggle/django-app/templates/cronjobs/deployment.yaml @@ -17,6 +17,9 @@ metadata: release: {{ $.Release.Name }} spec: schedule: {{ $job.schedule | quote }} + {{- if $job.timeZone }} + timeZone: {{ $job.timeZone | quote }} + {{- end }} concurrencyPolicy: "Forbid" jobTemplate: spec: diff --git a/toggle/django-app/values-test.yaml b/toggle/django-app/values-test.yaml index b818fbf..33d2859 100644 --- a/toggle/django-app/values-test.yaml +++ b/toggle/django-app/values-test.yaml @@ -92,14 +92,24 @@ cronjobs: memory: 2Gi # NOTE: Application level configuration jobs: - "dummy": + dummy-01: enabled: true schedule: "0 0 * * *" - command: ["./manage.py", "run-dummy-command"] + command: ["./manage.py", "run-dummy-command", "01"] resources: requests: cpu: "2" memory: 4Gi + dummy-02: + enabled: true + schedule: "0 0 * * *" + timeZone: "Asia/Kathmandu" + command: ["./manage.py", "run-dummy-command", "02"] + dummy-03: + enabled: false + schedule: "* * * * *" + timeZone: "Asia/Kathmandu" + command: ["./manage.py", "run-dummy-command", "03"] extraConfigMapName: "my-custom-envs" env: diff --git a/toggle/django-app/values.yaml b/toggle/django-app/values.yaml index df24290..d9aa470 100644 --- a/toggle/django-app/values.yaml +++ b/toggle/django-app/values.yaml @@ -195,11 +195,12 @@ cronjobs: cpu: "1" memory: 2Gi # NOTE: Application level configuration - jobs: - "dummy": - schedule: "0 0 * * *" - enabled: false - command: ["./manage.py", "run-dummy-command"] + jobs: {} + # "dummy": + # schedule: "0 0 * * *" + # timeZone: "Asia/Kathmandu" + # enabled: false + # command: ["./manage.py", "run-dummy-command"] # Not required if global image are set argoHook: