diff --git a/chart/files/pod-template-file.kubernetes-helm-yaml b/chart/files/pod-template-file.kubernetes-helm-yaml index 1a937308ad2..02f8b0fff81 100644 --- a/chart/files/pod-template-file.kubernetes-helm-yaml +++ b/chart/files/pod-template-file.kubernetes-helm-yaml @@ -87,7 +87,7 @@ spec: nodeSelector: {{ toYaml .Values.nodeSelector | nindent 4 }} affinity: {{ toYaml .Values.affinity | nindent 4 }} tolerations: {{ toYaml .Values.tolerations | nindent 4 }} - serviceAccountName: '{{ .Release.Name }}-worker' + serviceAccountName: {{ include "worker.serviceAccountName" . }} volumes: {{- if .Values.dags.persistence.enabled }} - name: dags diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml index 71ba8b25993..2f1641b011b 100644 --- a/chart/templates/_helpers.yaml +++ b/chart/templates/_helpers.yaml @@ -15,6 +15,25 @@ # specific language governing permissions and limitations # under the License. +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "airflow.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + + {{/* Standard Airflow environment variables */}} {{- define "standard_airflow_environment" }} # Hard Coded Airflow Envs @@ -372,6 +391,116 @@ server_tls_key_file = /etc/pgbouncer/server.key {{ (printf "%s-airflow-config" .Release.Name) }} {{- end }} +{{/* +Create the name of the webserver service account to use +*/}} +{{- define "webserver.serviceAccountName" -}} +{{- if .Values.webserver.serviceAccount.create -}} + {{ default (printf "%s-webserver" (include "airflow.fullname" .)) .Values.webserver.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.webserver.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the redis service account to use +*/}} +{{- define "redis.serviceAccountName" -}} +{{- if .Values.redis.serviceAccount.create -}} + {{ default (printf "%s-redis" (include "airflow.fullname" .)) .Values.redis.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.redis.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the flower service account to use +*/}} +{{- define "flower.serviceAccountName" -}} +{{- if .Values.flower.serviceAccount.create -}} + {{ default (printf "%s-flower" (include "airflow.fullname" .)) .Values.flower.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.flower.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the scheduler service account to use +*/}} +{{- define "scheduler.serviceAccountName" -}} +{{- if .Values.scheduler.serviceAccount.create -}} + {{ default (printf "%s-scheduler" (include "airflow.fullname" .)) .Values.scheduler.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.scheduler.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the statsd service account to use +*/}} +{{- define "statsd.serviceAccountName" -}} +{{- if .Values.statsd.serviceAccount.create -}} + {{ default (printf "%s-statsd" (include "airflow.fullname" .)) .Values.statsd.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.statsd.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the create user job service account to use +*/}} +{{- define "createUserJob.serviceAccountName" -}} +{{- if .Values.createUserJob.serviceAccount.create -}} + {{ default (printf "%s-create-user-job" (include "airflow.fullname" .)) .Values.createUserJob.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.createUserJob.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the migrate database job service account to use +*/}} +{{- define "migrateDatabaseJob.serviceAccountName" -}} +{{- if .Values.migrateDatabaseJob.serviceAccount.create -}} + {{ default (printf "%s-migrate-database-job" (include "airflow.fullname" .)) .Values.migrateDatabaseJob.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.migrateDatabaseJob.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the worker service account to use +*/}} +{{- define "worker.serviceAccountName" -}} +{{- if .Values.workers.serviceAccount.create -}} + {{ default (printf "%s-worker" (include "airflow.fullname" .)) .Values.workers.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.workers.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the pgbouncer service account to use +*/}} +{{- define "pgbouncer.serviceAccountName" -}} +{{- if .Values.pgbouncer.serviceAccount.create -}} + {{ default (printf "%s-pgbouncer" (include "airflow.fullname" .)) .Values.pgbouncer.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.pgbouncer.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the cleanup service account to use +*/}} +{{- define "cleanup.serviceAccountName" -}} +{{- if .Values.cleanup.serviceAccount.create -}} + {{ default (printf "%s-cleanup" (include "airflow.fullname" .)) .Values.cleanup.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.cleanup.serviceAccount.name }} +{{- end -}} +{{- end -}} + {{ define "wait-for-migrations-command" }} {{/* From Airflow 2.0.0 this can become [airflow, db, check-migrations] */}} - python diff --git a/chart/templates/cleanup/cleanup-cronjob.yaml b/chart/templates/cleanup/cleanup-cronjob.yaml index 4bfc10eb79c..36e32f43501 100644 --- a/chart/templates/cleanup/cleanup-cronjob.yaml +++ b/chart/templates/cleanup/cleanup-cronjob.yaml @@ -54,7 +54,7 @@ spec: {{ toYaml $affinity | indent 12 }} tolerations: {{ toYaml $tolerations | indent 12 }} - serviceAccountName: {{ .Release.Name }}-cleanup + serviceAccountName: {{ include "cleanup.serviceAccountName" . }} {{- if or .Values.registry.secretName .Values.registry.connection }} imagePullSecrets: - name: {{ template "registry_secret" . }} diff --git a/chart/templates/cleanup/cleanup-serviceaccount.yaml b/chart/templates/cleanup/cleanup-serviceaccount.yaml index 6ef3aec0725..7f7363547e8 100644 --- a/chart/templates/cleanup/cleanup-serviceaccount.yaml +++ b/chart/templates/cleanup/cleanup-serviceaccount.yaml @@ -18,17 +18,21 @@ ################################ ## Airflow Cleanup ServiceAccount ################################# -{{- if and .Values.rbacEnabled .Values.cleanup.enabled }} +{{- if and .Values.cleanup.serviceAccount.create .Values.cleanup.enabled }} kind: ServiceAccount apiVersion: v1 metadata: - name: {{ .Release.Name }}-cleanup + name: {{ include "cleanup.serviceAccountName" . }} labels: tier: airflow release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} -{{- with .Values.labels }} -{{ toYaml . | indent 4 }} -{{- end }} + {{- with .Values.labels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.cleanup.serviceAccount.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} {{- end }} diff --git a/chart/templates/flower/flower-deployment.yaml b/chart/templates/flower/flower-deployment.yaml index e346e730c29..5910c25514f 100644 --- a/chart/templates/flower/flower-deployment.yaml +++ b/chart/templates/flower/flower-deployment.yaml @@ -61,6 +61,7 @@ spec: {{ toYaml $affinity | indent 8 }} tolerations: {{ toYaml $tolerations | indent 8 }} + serviceAccountName: {{ include "flower.serviceAccountName" . }} restartPolicy: Always securityContext: runAsUser: {{ .Values.uid }} diff --git a/chart/templates/flower/flower-serviceaccount.yaml b/chart/templates/flower/flower-serviceaccount.yaml new file mode 100644 index 00000000000..e9fb8b329ae --- /dev/null +++ b/chart/templates/flower/flower-serviceaccount.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +###################################### +## Airflow Flower ServiceAccount +###################################### +{{- if and (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) .Values.flower.serviceAccount.create }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ include "flower.serviceAccountName" . }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.flower.serviceAccount.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/templates/jobs/create-user-job-serviceaccount.yaml b/chart/templates/jobs/create-user-job-serviceaccount.yaml new file mode 100644 index 00000000000..d27fb269e97 --- /dev/null +++ b/chart/templates/jobs/create-user-job-serviceaccount.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +########################################### +## Airflow Create User Job ServiceAccount +########################################### +{{- if and .Values.createUserJob.serviceAccount.create .Values.webserver.defaultUser.enabled }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ include "createUserJob.serviceAccountName" . }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.createUserJob.serviceAccount.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/templates/create-user-job.yaml b/chart/templates/jobs/create-user-job.yaml similarity index 97% rename from chart/templates/create-user-job.yaml rename to chart/templates/jobs/create-user-job.yaml index af041796b4f..ea88ef124f2 100644 --- a/chart/templates/create-user-job.yaml +++ b/chart/templates/jobs/create-user-job.yaml @@ -56,6 +56,7 @@ spec: {{ toYaml $affinity | indent 8 }} tolerations: {{ toYaml $tolerations | indent 8 }} + serviceAccountName: {{ include "createUserJob.serviceAccountName" . }} {{- if or .Values.registry.secretName .Values.registry.connection }} imagePullSecrets: - name: {{ template "registry_secret" . }} diff --git a/chart/templates/jobs/migrate-database-job-serviceaccount.yaml b/chart/templates/jobs/migrate-database-job-serviceaccount.yaml new file mode 100644 index 00000000000..b94bfbb3f5c --- /dev/null +++ b/chart/templates/jobs/migrate-database-job-serviceaccount.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +############################################# +## Airflow Migrate Database Job ServiceAccount +############################################## +{{- if .Values.migrateDatabaseJob.serviceAccount.create }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ include "migrateDatabaseJob.serviceAccountName" . }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.migrateDatabaseJob.serviceAccount.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/templates/migrate-database-job.yaml b/chart/templates/jobs/migrate-database-job.yaml similarity index 97% rename from chart/templates/migrate-database-job.yaml rename to chart/templates/jobs/migrate-database-job.yaml index bbcc67a99d7..36fbc6db58a 100644 --- a/chart/templates/migrate-database-job.yaml +++ b/chart/templates/jobs/migrate-database-job.yaml @@ -55,6 +55,7 @@ spec: {{ toYaml $affinity | indent 8 }} tolerations: {{ toYaml $tolerations | indent 8 }} + serviceAccountName: {{ include "migrateDatabaseJob.serviceAccountName" . }} {{- if or .Values.registry.secretName .Values.registry.connection }} imagePullSecrets: - name: {{ template "registry_secret" . }} diff --git a/chart/templates/pgbouncer/pgbouncer-deployment.yaml b/chart/templates/pgbouncer/pgbouncer-deployment.yaml index c7dd2ea7e49..be0539e9f54 100644 --- a/chart/templates/pgbouncer/pgbouncer-deployment.yaml +++ b/chart/templates/pgbouncer/pgbouncer-deployment.yaml @@ -65,6 +65,9 @@ spec: {{ toYaml $affinity | indent 8 }} tolerations: {{ toYaml $tolerations | indent 8 }} + serviceAccountName: {{ include "pgbouncer.serviceAccountName" . }} + securityContext: + runAsUser: {{ .Values.pgbouncer.uid }} restartPolicy: Always {{- if or .Values.registry.secretName .Values.registry.connection }} imagePullSecrets: diff --git a/chart/templates/pgbouncer/pgbouncer-serviceaccount.yaml b/chart/templates/pgbouncer/pgbouncer-serviceaccount.yaml new file mode 100644 index 00000000000..5e25cab8919 --- /dev/null +++ b/chart/templates/pgbouncer/pgbouncer-serviceaccount.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +###################################### +## Airflow Pgbouncer ServiceAccount +###################################### +{{- if and .Values.pgbouncer.serviceAccount.create .Values.pgbouncer.enabled }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ include "pgbouncer.serviceAccountName" . }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.pgbouncer.serviceAccount.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/templates/rbac/pod-cleanup-role.yaml b/chart/templates/rbac/pod-cleanup-role.yaml index 58f76e60452..dd7d9a33713 100644 --- a/chart/templates/rbac/pod-cleanup-role.yaml +++ b/chart/templates/rbac/pod-cleanup-role.yaml @@ -18,7 +18,7 @@ ################################ ## Airflow Cleanup Role ################################# -{{- if and .Values.rbacEnabled .Values.cleanup.enabled }} +{{- if and .Values.rbac.create .Values.cleanup.enabled }} kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: diff --git a/chart/templates/rbac/pod-cleanup-rolebinding.yaml b/chart/templates/rbac/pod-cleanup-rolebinding.yaml index 0d09b87bb44..c2d084eaad4 100644 --- a/chart/templates/rbac/pod-cleanup-rolebinding.yaml +++ b/chart/templates/rbac/pod-cleanup-rolebinding.yaml @@ -18,7 +18,7 @@ ################################ ## Airflow Cleanup Role Binding ################################# -{{- if and .Values.rbacEnabled .Values.cleanup.enabled }} +{{- if and .Values.rbac.create .Values.cleanup.enabled }} kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: @@ -37,6 +37,6 @@ roleRef: name: {{ .Release.Name }}-cleanup-role subjects: - kind: ServiceAccount - name: {{ .Release.Name }}-cleanup + name: {{ include "cleanup.serviceAccountName" . }} namespace: {{ .Release.Namespace }} {{- end }} diff --git a/chart/templates/rbac/pod-launcher-role.yaml b/chart/templates/rbac/pod-launcher-role.yaml index b78c1b52f6f..b31344e928e 100644 --- a/chart/templates/rbac/pod-launcher-role.yaml +++ b/chart/templates/rbac/pod-launcher-role.yaml @@ -18,7 +18,7 @@ ################################ ## Airflow Pod Launcher Role ################################# -{{- if and .Values.rbacEnabled .Values.allowPodLaunching }} +{{- if and .Values.rbac.create .Values.allowPodLaunching }} {{- if .Values.multiNamespaceMode }} kind: ClusterRole {{- else }} diff --git a/chart/templates/rbac/pod-launcher-rolebinding.yaml b/chart/templates/rbac/pod-launcher-rolebinding.yaml index 1248c7333f2..8160d04a172 100644 --- a/chart/templates/rbac/pod-launcher-rolebinding.yaml +++ b/chart/templates/rbac/pod-launcher-rolebinding.yaml @@ -18,7 +18,7 @@ ################################ ## Airflow Pod Launcher Role Binding ################################# -{{- if and .Values.rbacEnabled .Values.allowPodLaunching }} +{{- if and .Values.rbac.create .Values.allowPodLaunching }} {{- $schedulerLaunchExecutors := list "LocalExecutor" "KubernetesExecutor" "CeleryKubernetesExecutor" }} {{- $workerLaunchExecutors := list "CeleryExecutor" "KubernetesExecutor" "CeleryKubernetesExecutor" }} {{- if .Values.multiNamespaceMode }} @@ -51,12 +51,12 @@ roleRef: subjects: {{- if has .Values.executor $schedulerLaunchExecutors }} - kind: ServiceAccount - name: {{ .Release.Name }}-scheduler + name: {{ include "scheduler.serviceAccountName" . }} namespace: {{ .Release.Namespace }} {{- end }} {{- if has .Values.executor $workerLaunchExecutors }} - kind: ServiceAccount - name: {{ .Release.Name }}-worker + name: {{ include "worker.serviceAccountName" . }} namespace: {{ .Release.Namespace }} {{- end }} {{- end }} diff --git a/chart/templates/rbac/pod-log-reader-role.yaml b/chart/templates/rbac/pod-log-reader-role.yaml index 76bc5bb537c..7dc6387dd17 100644 --- a/chart/templates/rbac/pod-log-reader-role.yaml +++ b/chart/templates/rbac/pod-log-reader-role.yaml @@ -18,7 +18,7 @@ ################################ ## Airflow Pod Reader Role ################################# -{{- if and .Values.rbacEnabled .Values.webserver.allowPodLogReading }} +{{- if and .Values.rbac.create .Values.webserver.allowPodLogReading }} {{- if .Values.multiNamespaceMode }} kind: ClusterRole {{- else }} diff --git a/chart/templates/rbac/pod-log-reader-rolebinding.yaml b/chart/templates/rbac/pod-log-reader-rolebinding.yaml index 25371eb5e04..9b50e061367 100644 --- a/chart/templates/rbac/pod-log-reader-rolebinding.yaml +++ b/chart/templates/rbac/pod-log-reader-rolebinding.yaml @@ -18,7 +18,7 @@ ################################ ## Airflow Pod Reader Role Binding ################################# -{{- if and .Values.rbacEnabled .Values.webserver.allowPodLogReading }} +{{- if and .Values.rbac.create .Values.webserver.allowPodLogReading }} {{- if .Values.multiNamespaceMode }} kind: ClusterRoleBinding {{- else }} diff --git a/chart/templates/redis/redis-serviceaccount.yaml b/chart/templates/redis/redis-serviceaccount.yaml new file mode 100644 index 00000000000..aabe62ad6f2 --- /dev/null +++ b/chart/templates/redis/redis-serviceaccount.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +###################################### +## Airflow Redis ServiceAccount +###################################### +{{- if and .Values.redis.enabled .Values.redis.serviceAccount.create (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ include "redis.serviceAccountName" . }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.redis.serviceAccount.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/templates/redis/redis-statefulset.yaml b/chart/templates/redis/redis-statefulset.yaml index 9375384bcf3..044eedb0bff 100644 --- a/chart/templates/redis/redis-statefulset.yaml +++ b/chart/templates/redis/redis-statefulset.yaml @@ -62,6 +62,7 @@ spec: {{ toYaml $affinity | indent 8 }} tolerations: {{ toYaml $tolerations | indent 8 }} + serviceAccountName: {{ include "redis.serviceAccountName" . }} {{- if or .Values.registry.secretName .Values.registry.connection }} imagePullSecrets: - name: {{ template "registry_secret" . }} diff --git a/chart/templates/scheduler/scheduler-deployment.yaml b/chart/templates/scheduler/scheduler-deployment.yaml index 89fc5b95f07..54ee0a9d4fb 100644 --- a/chart/templates/scheduler/scheduler-deployment.yaml +++ b/chart/templates/scheduler/scheduler-deployment.yaml @@ -86,7 +86,7 @@ spec: {{ toYaml $tolerations | indent 8 }} restartPolicy: Always terminationGracePeriodSeconds: 10 - serviceAccountName: {{ .Release.Name }}-scheduler + serviceAccountName: {{ include "scheduler.serviceAccountName" . }} securityContext: runAsUser: {{ .Values.uid }} fsGroup: {{ .Values.gid }} diff --git a/chart/templates/scheduler/scheduler-serviceaccount.yaml b/chart/templates/scheduler/scheduler-serviceaccount.yaml index 2d61c768f68..11c98067332 100644 --- a/chart/templates/scheduler/scheduler-serviceaccount.yaml +++ b/chart/templates/scheduler/scheduler-serviceaccount.yaml @@ -18,11 +18,11 @@ ################################ ## Airflow Scheduler ServiceAccount ################################# -{{- if .Values.rbacEnabled }} +{{- if .Values.scheduler.serviceAccount.create }} kind: ServiceAccount apiVersion: v1 metadata: - name: {{ .Release.Name }}-scheduler + name: {{ include "scheduler.serviceAccountName" . }} labels: tier: airflow release: {{ .Release.Name }} @@ -31,7 +31,7 @@ metadata: {{- with .Values.labels }} {{ toYaml . | nindent 4 }} {{- end }} - {{- with .Values.scheduler.serviceAccountAnnotations }} + {{- with .Values.scheduler.serviceAccount.annotations }} annotations: {{- range $key, $value := . }} {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} diff --git a/chart/templates/statsd/statsd-deployment.yaml b/chart/templates/statsd/statsd-deployment.yaml index a63117e353a..e14e224e66a 100644 --- a/chart/templates/statsd/statsd-deployment.yaml +++ b/chart/templates/statsd/statsd-deployment.yaml @@ -62,6 +62,9 @@ spec: {{ toYaml $affinity | indent 8 }} tolerations: {{ toYaml $tolerations | indent 8 }} + serviceAccountName: {{ include "statsd.serviceAccountName" . }} + securityContext: + runAsUser: {{ .Values.statsd.uid }} restartPolicy: Always {{- if or .Values.registry.secretName .Values.registry.connection }} imagePullSecrets: diff --git a/chart/templates/statsd/statsd-serviceaccount.yaml b/chart/templates/statsd/statsd-serviceaccount.yaml new file mode 100644 index 00000000000..8f11c666913 --- /dev/null +++ b/chart/templates/statsd/statsd-serviceaccount.yaml @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +###################################### +## Airflow StatsD ServiceAccount +###################################### +{{- if and .Values.statsd.enabled .Values.statsd.serviceAccount.create }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ include "statsd.serviceAccountName" . }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.statsd.serviceAccount.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/templates/webserver/webserver-deployment.yaml b/chart/templates/webserver/webserver-deployment.yaml index 7344f81848d..ca236948660 100644 --- a/chart/templates/webserver/webserver-deployment.yaml +++ b/chart/templates/webserver/webserver-deployment.yaml @@ -65,7 +65,7 @@ spec: {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} {{- end }} spec: - serviceAccountName: {{ .Release.Name }}-webserver + serviceAccountName: {{ include "webserver.serviceAccountName" . }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} affinity: diff --git a/chart/templates/webserver/webserver-serviceaccount.yaml b/chart/templates/webserver/webserver-serviceaccount.yaml index e42d767c1e2..bb3b9818950 100644 --- a/chart/templates/webserver/webserver-serviceaccount.yaml +++ b/chart/templates/webserver/webserver-serviceaccount.yaml @@ -18,10 +18,11 @@ ###################################### ## Airflow Webserver ServiceAccount ###################################### +{{- if .Values.webserver.serviceAccount.create }} kind: ServiceAccount apiVersion: v1 metadata: - name: {{ .Release.Name }}-webserver + name: {{ include "webserver.serviceAccountName" . }} labels: tier: airflow release: {{ .Release.Name }} @@ -30,7 +31,8 @@ metadata: {{- with .Values.labels }} {{ toYaml . | nindent 4 }} {{- end }} - {{- with .Values.webserver.serviceAccountAnnotations }} + {{- with .Values.webserver.serviceAccount.annotations }} annotations: {{ toYaml . | nindent 4 }} {{- end }} +{{- end }} diff --git a/chart/templates/workers/worker-deployment.yaml b/chart/templates/workers/worker-deployment.yaml index 24bd1a80b2f..b51cedaac6f 100644 --- a/chart/templates/workers/worker-deployment.yaml +++ b/chart/templates/workers/worker-deployment.yaml @@ -89,7 +89,7 @@ spec: {{- end }} terminationGracePeriodSeconds: {{ .Values.workers.terminationGracePeriodSeconds }} restartPolicy: Always - serviceAccountName: {{ .Release.Name }}-worker + serviceAccountName: {{ include "worker.serviceAccountName" . }} securityContext: runAsUser: {{ .Values.uid }} fsGroup: {{ .Values.gid }} diff --git a/chart/templates/workers/worker-serviceaccount.yaml b/chart/templates/workers/worker-serviceaccount.yaml index d7ed9270092..f42056467c9 100644 --- a/chart/templates/workers/worker-serviceaccount.yaml +++ b/chart/templates/workers/worker-serviceaccount.yaml @@ -18,11 +18,11 @@ ################################ ## Airflow Worker ServiceAccount ################################# -{{- if .Values.rbacEnabled }} +{{- if and .Values.workers.serviceAccount.create (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} kind: ServiceAccount apiVersion: v1 metadata: - name: {{ .Release.Name }}-worker + name: {{ include "worker.serviceAccountName" . }} labels: tier: airflow release: {{ .Release.Name }} @@ -31,7 +31,7 @@ metadata: {{- with .Values.labels }} {{ toYaml . | nindent 4 }} {{- end }} - {{- with .Values.workers.serviceAccountAnnotations}} + {{- with .Values.workers.serviceAccount.annotations}} annotations: {{ toYaml . | nindent 4 }} {{- end }} diff --git a/chart/tests/test_annotations.py b/chart/tests/test_annotations.py new file mode 100644 index 00000000000..899d697131a --- /dev/null +++ b/chart/tests/test_annotations.py @@ -0,0 +1,138 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import unittest + +from tests.helm_template_generator import render_chart + +# Values for each service mapped to the 'example' +# key annotation +CUSTOM_ANNOTATION_VALUES = ( + CUSTOM_SCHEDULER_ANNOTATION, + CUSTOM_WEBSERVER_ANNOTATION, + CUSTOM_WORKER_ANNOTATION, + CUSTOM_CLEANUP_ANNOTATION, + CUSTOM_FLOWER_ANNOTATION, + CUSTOM_PGBOUNCER_ANNOTATION, + CUSTOM_STATSD_ANNOTATION, + CUSTOM_CREATE_USER_JOB_ANNOTATION, + CUSTOM_MIGRATE_DATABASE_JOB_ANNOTATION, + CUSTOM_REDIS_ANNOTATION, +) = ( + "scheduler", + "webserver", + "worker", + "cleanup", + "flower", + "pgbouncer", + "statsd", + "createuser", + "migratedb", + "redis", +) + + +class AnnotationsTest(unittest.TestCase): + def test_service_account_annotations(self): + k8s_objects = render_chart( + values={ + "cleanup": { + "enabled": True, + "serviceAccount": { + "annotations": { + "example": CUSTOM_CLEANUP_ANNOTATION, + }, + }, + }, + "scheduler": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_SCHEDULER_ANNOTATION, + }, + }, + }, + "webserver": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_WEBSERVER_ANNOTATION, + }, + }, + }, + "workers": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_WORKER_ANNOTATION, + }, + }, + }, + "flower": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_FLOWER_ANNOTATION, + }, + }, + }, + "statsd": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_STATSD_ANNOTATION, + }, + }, + }, + "redis": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_REDIS_ANNOTATION, + }, + }, + }, + "pgbouncer": { + "enabled": True, + "serviceAccount": { + "annotations": { + "example": CUSTOM_PGBOUNCER_ANNOTATION, + }, + }, + }, + "createUserJob": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_CREATE_USER_JOB_ANNOTATION, + }, + }, + }, + "migrateDatabaseJob": { + "serviceAccount": { + "annotations": { + "example": CUSTOM_MIGRATE_DATABASE_JOB_ANNOTATION, + }, + }, + }, + "executor": "CeleryExecutor", # create worker deployment + }, + ) + + list_of_annotation_values_in_objects = [ + k8s_object['metadata']['annotations']['example'] + for k8s_object in k8s_objects + if k8s_object['kind'] == "ServiceAccount" + ] + + self.assertCountEqual( + list_of_annotation_values_in_objects, + CUSTOM_ANNOTATION_VALUES, + ) diff --git a/chart/tests/test_basic_helm_chart.py b/chart/tests/test_basic_helm_chart.py index 7619e180953..c6951f686c4 100644 --- a/chart/tests/test_basic_helm_chart.py +++ b/chart/tests/test_basic_helm_chart.py @@ -24,7 +24,7 @@ from tests.helm_template_generator import render_chart -OBJECT_COUNT_IN_BASIC_DEPLOYMENT = 30 +OBJECT_COUNT_IN_BASIC_DEPLOYMENT = 35 class TestBaseChartTest(unittest.TestCase): @@ -36,13 +36,19 @@ def test_basic_deployments(self): 'metadata': 'AA', }, 'labels': {"TEST-LABEL": "TEST-VALUE"}, + "fullnameOverride": "TEST-BASIC", }, ) list_of_kind_names_tuples = [ (k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects ] assert list_of_kind_names_tuples == [ + ('ServiceAccount', 'TEST-BASIC-flower'), + ('ServiceAccount', 'TEST-BASIC-create-user-job'), + ('ServiceAccount', 'TEST-BASIC-migrate-database-job'), + ('ServiceAccount', 'TEST-BASIC-redis'), ('ServiceAccount', 'TEST-BASIC-scheduler'), + ('ServiceAccount', 'TEST-BASIC-statsd'), ('ServiceAccount', 'TEST-BASIC-webserver'), ('ServiceAccount', 'TEST-BASIC-worker'), ('Secret', 'TEST-BASIC-postgresql'), @@ -89,7 +95,7 @@ def test_basic_deployment_without_default_users(self): (k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects ] assert ('Job', 'TEST-BASIC-create-user') not in list_of_kind_names_tuples - assert OBJECT_COUNT_IN_BASIC_DEPLOYMENT - 1 == len(k8s_objects) + assert OBJECT_COUNT_IN_BASIC_DEPLOYMENT - 2 == len(k8s_objects) def test_network_policies_are_valid(self): k8s_objects = render_chart( diff --git a/chart/tests/test_create_user_job.py b/chart/tests/test_create_user_job.py index eb471976d52..5e89db9be32 100644 --- a/chart/tests/test_create_user_job.py +++ b/chart/tests/test_create_user_job.py @@ -24,6 +24,6 @@ class CreateUserJobTest(unittest.TestCase): def test_should_run_by_default(self): - docs = render_chart(show_only=["templates/create-user-job.yaml"]) + docs = render_chart(show_only=["templates/jobs/create-user-job.yaml"]) assert "create-user" == jmespath.search("spec.template.spec.containers[0].name", docs[0]) assert 50000 == jmespath.search("spec.template.spec.securityContext.runAsUser", docs[0]) diff --git a/chart/tests/test_git_sync_webserver.py b/chart/tests/test_git_sync_webserver.py index d599be47128..9f5a830eea9 100644 --- a/chart/tests/test_git_sync_webserver.py +++ b/chart/tests/test_git_sync_webserver.py @@ -59,7 +59,9 @@ def test_should_have_service_account_defined(self): show_only=["templates/webserver/webserver-deployment.yaml"], ) - assert "RELEASE-NAME-webserver" == jmespath.search("spec.template.spec.serviceAccountName", docs[0]) + assert "RELEASE-NAME-airflow-webserver" == jmespath.search( + "spec.template.spec.serviceAccountName", docs[0] + ) @parameterized.expand([(True,), (False,)]) def test_git_sync_with_exclude_webserver(self, exclude_webserver): diff --git a/chart/tests/test_migrate_database_job.py b/chart/tests/test_migrate_database_job.py index d1e92251324..d3521ced568 100644 --- a/chart/tests/test_migrate_database_job.py +++ b/chart/tests/test_migrate_database_job.py @@ -27,7 +27,7 @@ class MigrateDatabaseJobTest(unittest.TestCase): def test_should_run_by_default(self): docs = render_chart( values={}, - show_only=["templates/migrate-database-job.yaml"], + show_only=["templates/jobs/migrate-database-job.yaml"], ) assert re.search("Job", docs[0]["kind"]) diff --git a/chart/tests/test_pod_launcher_role.py b/chart/tests/test_pod_launcher_role.py index 00659b48132..dfe81d9fd62 100644 --- a/chart/tests/test_pod_launcher_role.py +++ b/chart/tests/test_pod_launcher_role.py @@ -36,7 +36,7 @@ class PodLauncherTest(unittest.TestCase): def test_pod_launcher_role(self, executor, rbac, allow, expected_accounts): docs = render_chart( values={ - "rbacEnabled": rbac, + "rbac": {"create": rbac}, "allowPodLaunching": allow, "executor": executor, }, @@ -44,6 +44,6 @@ def test_pod_launcher_role(self, executor, rbac, allow, expected_accounts): ) if expected_accounts: for idx, suffix in enumerate(expected_accounts): - assert f"RELEASE-NAME-{suffix}" == jmespath.search(f"subjects[{idx}].name", docs[0]) + assert f"RELEASE-NAME-airflow-{suffix}" == jmespath.search(f"subjects[{idx}].name", docs[0]) else: assert [] == docs diff --git a/chart/tests/test_rbac.py b/chart/tests/test_rbac.py new file mode 100644 index 00000000000..6fe646480a7 --- /dev/null +++ b/chart/tests/test_rbac.py @@ -0,0 +1,297 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import unittest + +import jmespath + +from tests.helm_template_generator import render_chart + +DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES = [ + ('Secret', 'TEST-RBAC-postgresql'), + ('Secret', 'TEST-RBAC-airflow-metadata'), + ('Secret', 'TEST-RBAC-airflow-result-backend'), + ('Secret', 'TEST-RBAC-pgbouncer-config'), + ('Secret', 'TEST-RBAC-pgbouncer-stats'), + ('ConfigMap', 'TEST-RBAC-airflow-config'), + ('Service', 'TEST-RBAC-postgresql-headless'), + ('Service', 'TEST-RBAC-postgresql'), + ('Service', 'TEST-RBAC-statsd'), + ('Service', 'TEST-RBAC-webserver'), + ('Service', 'TEST-RBAC-flower'), + ('Service', 'TEST-RBAC-pgbouncer'), + ('Service', 'TEST-RBAC-redis'), + ('Service', 'TEST-RBAC-worker'), + ('Deployment', 'TEST-RBAC-scheduler'), + ('Deployment', 'TEST-RBAC-statsd'), + ('Deployment', 'TEST-RBAC-webserver'), + ('Deployment', 'TEST-RBAC-flower'), + ('Deployment', 'TEST-RBAC-pgbouncer'), + ('StatefulSet', 'TEST-RBAC-postgresql'), + ('StatefulSet', 'TEST-RBAC-redis'), + ('StatefulSet', 'TEST-RBAC-worker'), + ('Secret', 'TEST-RBAC-broker-url'), + ('Secret', 'TEST-RBAC-fernet-key'), + ('Secret', 'TEST-RBAC-redis-password'), + ('Job', 'TEST-RBAC-create-user'), + ('Job', 'TEST-RBAC-run-airflow-migrations'), + ('CronJob', 'TEST-RBAC-cleanup'), +] + +RBAC_ENABLED_KIND_NAME_TUPLES = [ + ('Role', 'TEST-RBAC-pod-launcher-role'), + ('Role', 'TEST-RBAC-cleanup-role'), + ('Role', 'TEST-RBAC-pod-log-reader-role'), + ('RoleBinding', 'TEST-RBAC-pod-launcher-rolebinding'), + ('RoleBinding', 'TEST-RBAC-pod-log-reader-rolebinding'), + ('RoleBinding', 'TEST-RBAC-cleanup-rolebinding'), +] + +SERVICE_ACCOUNT_NAME_TUPLES = [ + ('ServiceAccount', 'TEST-RBAC-cleanup'), + ('ServiceAccount', 'TEST-RBAC-scheduler'), + ('ServiceAccount', 'TEST-RBAC-webserver'), + ('ServiceAccount', 'TEST-RBAC-worker'), + ('ServiceAccount', 'TEST-RBAC-pgbouncer'), + ('ServiceAccount', 'TEST-RBAC-flower'), + ('ServiceAccount', 'TEST-RBAC-statsd'), + ('ServiceAccount', 'TEST-RBAC-create-user-job'), + ('ServiceAccount', 'TEST-RBAC-migrate-database-job'), + ('ServiceAccount', 'TEST-RBAC-redis'), +] + +CUSTOM_SERVICE_ACCOUNT_NAMES = ( + CUSTOM_SCHEDULER_NAME, + CUSTOM_WEBSERVER_NAME, + CUSTOM_WORKER_NAME, + CUSTOM_CLEANUP_NAME, + CUSTOM_FLOWER_NAME, + CUSTOM_PGBOUNCER_NAME, + CUSTOM_STATSD_NAME, + CUSTOM_CREATE_USER_JOBS_NAME, + CUSTOM_MIGRATE_DATABASE_JOBS_NAME, + CUSTOM_REDIS_NAME, +) = ( + "TestScheduler", + "TestWebserver", + "TestWorker", + "TestCleanup", + "TestFlower", + "TestPGBouncer", + "TestStatsd", + "TestCreateUserJob", + "TestMigrateDatabaseJob", + "TestRedis", +) + + +class RBACTest(unittest.TestCase): + def test_deployments_no_rbac_no_sa(self): + k8s_objects = render_chart( + "TEST-RBAC", + values={ + "fullnameOverride": "TEST-RBAC", + "rbac": {"create": False}, + "cleanup": { + "enabled": True, + "serviceAccount": { + "create": False, + }, + }, + "pgbouncer": { + "enabled": True, + "serviceAccount": { + "create": False, + }, + }, + "redis": {"serviceAccount": {"create": False}}, + "scheduler": {"serviceAccount": {"create": False}}, + "webserver": {"serviceAccount": {"create": False}}, + "workers": {"serviceAccount": {"create": False}}, + "statsd": {"serviceAccount": {"create": False}}, + "createUserJob": {"serviceAccount": {"create": False}}, + "migrateDatabaseJob": {"serviceAccount": {"create": False}}, + "flower": {"serviceAccount": {"create": False}}, + }, + ) + list_of_kind_names_tuples = [ + (k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects + ] + + self.assertCountEqual( + list_of_kind_names_tuples, + DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES, + ) + + def test_deployments_no_rbac_with_sa(self): + k8s_objects = render_chart( + "TEST-RBAC", + values={ + "fullnameOverride": "TEST-RBAC", + "rbac": {"create": False}, + "cleanup": {"enabled": True}, + "pgbouncer": {"enabled": True}, + }, + ) + list_of_kind_names_tuples = [ + (k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects + ] + real_list_of_kind_names = DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES + SERVICE_ACCOUNT_NAME_TUPLES + self.assertCountEqual( + list_of_kind_names_tuples, + real_list_of_kind_names, + ) + + def test_deployments_with_rbac_no_sa(self): + k8s_objects = render_chart( + "TEST-RBAC", + values={ + "fullnameOverride": "TEST-RBAC", + "cleanup": { + "enabled": True, + "serviceAccount": { + "create": False, + }, + }, + "scheduler": {"serviceAccount": {"create": False}}, + "webserver": {"serviceAccount": {"create": False}}, + "workers": {"serviceAccount": {"create": False}}, + "flower": {"serviceAccount": {"create": False}}, + "statsd": {"serviceAccount": {"create": False}}, + "redis": {"serviceAccount": {"create": False}}, + "pgbouncer": { + "enabled": True, + "serviceAccount": { + "create": False, + }, + }, + "createUserJob": {"serviceAccount": {"create": False}}, + "migrateDatabaseJob": {"serviceAccount": {"create": False}}, + }, + ) + list_of_kind_names_tuples = [ + (k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects + ] + real_list_of_kind_names = DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES + RBAC_ENABLED_KIND_NAME_TUPLES + self.assertCountEqual( + list_of_kind_names_tuples, + real_list_of_kind_names, + ) + + def test_deployments_with_rbac_with_sa(self): + k8s_objects = render_chart( + "TEST-RBAC", + values={ + "fullnameOverride": "TEST-RBAC", + "cleanup": {"enabled": True}, + "pgbouncer": {"enabled": True}, + }, + ) + list_of_kind_names_tuples = [ + (k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects + ] + real_list_of_kind_names = ( + DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES + + SERVICE_ACCOUNT_NAME_TUPLES + + RBAC_ENABLED_KIND_NAME_TUPLES + ) + self.assertCountEqual( + list_of_kind_names_tuples, + real_list_of_kind_names, + ) + + def test_service_account_custom_names(self): + k8s_objects = render_chart( + "TEST-RBAC", + values={ + "fullnameOverride": "TEST-RBAC", + "cleanup": { + "enabled": True, + "serviceAccount": { + "name": CUSTOM_CLEANUP_NAME, + }, + }, + "scheduler": {"serviceAccount": {"name": CUSTOM_SCHEDULER_NAME}}, + "webserver": {"serviceAccount": {"name": CUSTOM_WEBSERVER_NAME}}, + "workers": {"serviceAccount": {"name": CUSTOM_WORKER_NAME}}, + "flower": {"serviceAccount": {"name": CUSTOM_FLOWER_NAME}}, + "statsd": {"serviceAccount": {"name": CUSTOM_STATSD_NAME}}, + "redis": {"serviceAccount": {"name": CUSTOM_REDIS_NAME}}, + "pgbouncer": { + "enabled": True, + "serviceAccount": { + "name": CUSTOM_PGBOUNCER_NAME, + }, + }, + "createUserJob": {"serviceAccount": {"name": CUSTOM_CREATE_USER_JOBS_NAME}}, + "migrateDatabaseJob": {"serviceAccount": {"name": CUSTOM_MIGRATE_DATABASE_JOBS_NAME}}, + }, + ) + list_of_sa_names = [ + k8s_object['metadata']['name'] + for k8s_object in k8s_objects + if k8s_object['kind'] == "ServiceAccount" + ] + self.assertCountEqual( + list_of_sa_names, + CUSTOM_SERVICE_ACCOUNT_NAMES, + ) + + def test_service_account_custom_names_in_objects(self): + k8s_objects = render_chart( + "TEST-RBAC", + values={ + "fullnameOverride": "TEST-RBAC", + "cleanup": { + "enabled": True, + "serviceAccount": { + "name": CUSTOM_CLEANUP_NAME, + }, + }, + "scheduler": {"serviceAccount": {"name": CUSTOM_SCHEDULER_NAME}}, + "webserver": {"serviceAccount": {"name": CUSTOM_WEBSERVER_NAME}}, + "workers": {"serviceAccount": {"name": CUSTOM_WORKER_NAME}}, + "flower": {"serviceAccount": {"name": CUSTOM_FLOWER_NAME}}, + "statsd": {"serviceAccount": {"name": CUSTOM_STATSD_NAME}}, + "redis": {"serviceAccount": {"name": CUSTOM_REDIS_NAME}}, + "pgbouncer": { + "enabled": True, + "serviceAccount": { + "name": CUSTOM_PGBOUNCER_NAME, + }, + }, + "createUserJob": {"serviceAccount": {"name": CUSTOM_CREATE_USER_JOBS_NAME}}, + "migrateDatabaseJob": {"serviceAccount": {"name": CUSTOM_MIGRATE_DATABASE_JOBS_NAME}}, + }, + ) + list_of_sa_names_in_objects = [] + for k8s_object in k8s_objects: + name = ( + jmespath.search("spec.template.spec.serviceAccountName", k8s_object) + or jmespath.search( + "spec.jobTemplate.spec.template.spec.serviceAccountName", + k8s_object, + ) + or None + ) + if name and name not in list_of_sa_names_in_objects: + list_of_sa_names_in_objects.append(name) + + self.assertCountEqual( + list_of_sa_names_in_objects, + CUSTOM_SERVICE_ACCOUNT_NAMES, + ) diff --git a/chart/values.schema.json b/chart/values.schema.json index 90d708102a4..7d6f724c3a6 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -3,6 +3,14 @@ "description": "Default values for airflow. Declare variables to be passed into your templates.", "type": "object", "properties": { + "fullnameOverride": { + "description": "Provide a name to substitute for the full names of resources", + "type": "string" + }, + "nameOverride": { + "description": "Override the name of the chart", + "type": "string" + }, "uid": { "description": "User of airflow user.", "type": "integer" @@ -154,9 +162,15 @@ "description": "Extra annotations to apply to all Airflow pods.", "type": "object" }, - "rbacEnabled": { + "rbac": { "description": "Enable RBAC (default on most clusters these days).", - "type": "boolean" + "type": "object", + "properties": { + "create": { + "description": "Specifies whether RBAC resources should be created.", + "type": "boolean" + } + } }, "executor": { "description": "Airflow executor.", @@ -576,6 +590,24 @@ "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a Deployment.", "type": ["null", "object"] }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the worker kubernetes service account.", + "type": "object" + } + } + }, "keda": { "description": "KEDA configuration.", "type": "object", @@ -652,10 +684,6 @@ "description": "This setting tells Kubernetes that it's ok to evict when it wants to scale a node down.", "type": "boolean" }, - "serviceAccountAnnotations": { - "description": "Annotations to add to the worker kubernetes service account.", - "type": "object" - }, "extraContainers": { "description": "Launch additional containers into workers.", "type": "array" @@ -721,6 +749,24 @@ "description": "Airflow 2.0 allows users to run multiple schedulers. This feature is only recommended for Mysql 8+ and postgres", "type": "integer" }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the scheduler kubernetes service account.", + "type": "object" + } + } + }, "podDisruptionBudget": { "description": "Scheduler pod disruption budget.", "type": "object", @@ -757,10 +803,6 @@ "description": "This setting tells Kubernetes that its ok to evict when it wants to scale a node down.", "type": "boolean" }, - "serviceAccountAnnotations": { - "description": "Annotations to add to the scheduler kubernetes service account.", - "type": "object" - }, "extraContainers": { "description": "Launch additional containers into scheduler.", "type": "array" @@ -790,6 +832,56 @@ } } }, + "createUserJob": { + "description": "Airflow job to create a user settings.", + "type": "object", + "additionalProperties": false, + "properties": { + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the create user job kubernetes service account.", + "type": "object" + } + } + } + } + }, + "migrateDatabaseJob": { + "description": "Airflow job to migrate databases settings.", + "type": "object", + "additionalProperties": false, + "properties": { + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the migrate database job kubernetes service account.", + "type": "object" + } + } + } + } + }, "webserver": { "description": "Airflow webserver settings.", "type": "object", @@ -849,6 +941,24 @@ "description": "How many Airflow webserver replicas should run.", "type": "integer" }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the webserver kubernetes service account.", + "type": "object" + } + } + }, "extraNetworkPolicies": { "description": "Additional network policies as needed.", "type": "array" @@ -925,10 +1035,6 @@ } } }, - "serviceAccountAnnotations": { - "description": "Annotations to add to the webserver kubernetes service account.", - "type": "object" - }, "nodeSelector": { "description": "Select certain nodes for airflow pods.", "type": "object", @@ -994,6 +1100,24 @@ } } }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the worker kubernetes service account.", + "type": "object" + } + } + }, "nodeSelector": { "description": "Select certain nodes for airflow pods.", "type": "object", @@ -1038,6 +1162,28 @@ } } }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the worker kubernetes service account.", + "type": "object" + } + } + }, + "uid": { + "description": "statsd run as user parameter.", + "type": "integer" + }, "nodeSelector": { "description": "Select certain nodes for airflow pods.", "type": "object", @@ -1166,6 +1312,24 @@ } } }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the worker kubernetes service account.", + "type": "object" + } + } + }, "nodeSelector": { "description": "Select certain nodes for airflow pods.", "type": "object", @@ -1180,6 +1344,10 @@ "tolerations": { "description": "Select certain nodes for airflow pods.", "type": "array" + }, + "uid": { + "description": "pgbouncer run as user parameter.", + "type": "integer" } } }, @@ -1250,6 +1418,24 @@ "description": "Select certain nodes for airflow pods.", "type": "object" }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the worker kubernetes service account.", + "type": "object" + } + } + }, "tolerations": { "description": "Select certain nodes for airflow pods.", "type": "array" @@ -1370,6 +1556,24 @@ "tolerations": { "description": "Select certain nodes for airflow pods.", "type": "array" + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean" + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": "string" + }, + "annotations": { + "description": "Annotations to add to the cleanup cronjob kubernetes service account.", + "type": "object" + } + } } } }, diff --git a/chart/values.yaml b/chart/values.yaml index 7d02f13d200..179da191242 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -19,6 +19,12 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. +# Provide a name to substitute for the full names of resources +fullnameOverride: "" + +# Provide a name to substitute for the name of the chart +nameOverride: "" + # User and group of airflow user uid: 50000 gid: 0 @@ -106,7 +112,9 @@ networkPolicies: airflowPodAnnotations: {} # Enable RBAC (default on most clusters these days) -rbacEnabled: true +rbac: + # Specifies whether RBAC resources should be created + create: true # Airflow executor # Options: LocalExecutor, CeleryExecutor, KubernetesExecutor, CeleryKubernetesExecutor @@ -309,6 +317,17 @@ workers: maxSurge: "100%" maxUnavailable: "50%" + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to worker kubernetes service account. + annotations: {} + # Allow KEDA autoscaling. # Persistence.enabled must be set to false to use KEDA. keda: @@ -362,8 +381,6 @@ workers: # This setting tells kubernetes that its ok to evict # when it wants to scale a node down. safeToEvict: true - # Annotations to add to worker kubernetes service account. - serviceAccountAnnotations: {} # Launch additional containers into worker. extraContainers: [] @@ -399,6 +416,18 @@ scheduler: # Airflow 2.0 allows users to run multiple schedulers, # However this feature is only recommended for MySQL 8+ and Postgres replicas: 1 + + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to scheduler kubernetes service account. + annotations: {} + # Scheduler pod disruption budget podDisruptionBudget: enabled: false @@ -423,9 +452,6 @@ scheduler: # when it wants to scale a node down. safeToEvict: true - # Annotations to add to scheduler kubernetes service account. - serviceAccountAnnotations: {} - # Launch additional containers into scheduler. extraContainers: [] @@ -438,6 +464,33 @@ scheduler: affinity: {} tolerations: [] +# Airflow create user job settings +createUserJob: + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to create user kubernetes service account. + annotations: {} + +# Airflow database migration job settings +migrateDatabaseJob: + + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to migrate database job kubernetes service account. + annotations: {} + # Airflow webserver settings webserver: allowPodLogReading: true @@ -456,6 +509,17 @@ webserver: # Number of webservers replicas: 1 + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to webserver kubernetes service account. + annotations: {} + # Additional network policies as needed extraNetworkPolicies: [] @@ -502,9 +566,6 @@ webserver: ## service annotations annotations: {} - # Annotations to add to webserver kubernetes service account. - serviceAccountAnnotations: {} - # Select certain nodes for airflow webserver pods. nodeSelector: {} affinity: {} @@ -525,6 +586,17 @@ flower: # cpu: 100m # memory: 128Mi + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to worker kubernetes service account. + annotations: {} + # A secret containing the connection secretName: ~ @@ -543,6 +615,18 @@ flower: # Statsd settings statsd: enabled: true + + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to worker kubernetes service account. + annotations: {} + # Additional network policies as needed extraNetworkPolicies: [] resources: {} @@ -564,10 +648,24 @@ statsd: # Additional mappings for statsd exporter. extraMappings: [] + uid: 65534 + # Pgbouncer settings pgbouncer: # Enable pgbouncer enabled: false + + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to worker kubernetes service account. + annotations: {} + # Additional network policies as needed extraNetworkPolicies: [] @@ -638,11 +736,24 @@ pgbouncer: affinity: {} tolerations: [] + uid: 65534 + # Configuration for the redis provisioned by the chart redis: enabled: true terminationGracePeriodSeconds: 600 + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to worker kubernetes service account. + annotations: {} + persistence: # Enable persistent volumes enabled: true @@ -732,6 +843,17 @@ cleanup: affinity: {} tolerations: [] + # Create ServiceAccount + serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + # name: + + # Annotations to add to cleanup cronjob kubernetes service account. + annotations: {} + # Configuration for postgresql subchart # Not recommended for production postgresql: diff --git a/docs/helm-chart/parameters-ref.rst b/docs/helm-chart/parameters-ref.rst index d1646e944f0..f6a5097d6c6 100644 --- a/docs/helm-chart/parameters-ref.rst +++ b/docs/helm-chart/parameters-ref.rst @@ -27,6 +27,12 @@ The following tables lists the configurable parameters of the Airflow chart and * - Parameter - Description - Default + * - ``fullnameOverride`` + - Provide a name to substitute for the full names of resources + - ``~`` + * - ``nameOverride`` + - Override the name of the chart + - ``~`` * - ``uid`` - UID to run airflow pods under - ``1`` @@ -66,9 +72,9 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``airflowHome`` - Location of airflow home directory - ``1`` - * - ``rbacEnabled`` + * - ``rbac.create`` - Deploy pods with Kubernetes RBAC enabled - - ``1`` + - ``true`` * - ``executor`` - Airflow executor (eg SequentialExecutor, LocalExecutor, CeleryExecutor, KubernetesExecutor) - ``1`` @@ -258,9 +264,15 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``workers.safeToEvict`` - Allow Kubernetes to evict worker pods if needed (node downscaling) - ``1`` - * - ``workers.serviceAccountAnnotations`` + * - ``workers.serviceAccount.create`` + - Create ServiceAccount for workers + - ``true`` + * - ``workers.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``workers.serviceAccount.annotations`` - Annotations to add to worker kubernetes service account - - ``1`` + - ``{}`` * - ``workers.extraVolumes`` - Mount additional volumes into worker - ``1`` @@ -312,9 +324,15 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``scheduler.safeToEvict`` - Allow Kubernetes to evict scheduler pods if needed (node downscaling) - ``1`` - * - ``scheduler.serviceAccountAnnotations`` + * - ``scheduler.serviceAccount.create`` + - Create ServiceAccount for scheduler + - ``true`` + * - ``scheduler.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``scheduler.serviceAccount.annotations`` - Annotations to add to scheduler kubernetes service account - - ``1`` + - ``{}`` * - ``scheduler.extraVolumes`` - Mount additional volumes into scheduler - ``1`` @@ -384,6 +402,15 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``webserver.tolerations`` - Toleration labels for pod assignment - ``1`` + * - ``webserver.serviceAccount.create`` + - Create ServiceAccount for webserver + - ``true`` + * - ``webserver.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``webserver.serviceAccount.annotations`` + - Annotations to add to webserver kubernetes service account + - ``{}`` * - ``flower.enabled`` - Enable flower - ``1`` @@ -396,6 +423,15 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``flower.tolerations`` - Toleration labels for pod assignment - ``1`` + * - ``flower.serviceAccount.create`` + - Create ServiceAccount for flower + - ``true`` + * - ``flower.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``flower.serviceAccount.annotations`` + - Annotations to add to flower kubernetes service account + - ``{}`` * - ``statsd.nodeSelector`` - Node labels for pod assignment - ``1`` @@ -408,6 +444,15 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``statsd.extraMappings`` - Additional mappings for statsd exporter - ``1`` + * - ``statsd.serviceAccount.create`` + - Create ServiceAccount for statsd + - ``true`` + * - ``statsd.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``statsd.serviceAccount.annotations`` + - Annotations to add to statsd kubernetes service account + - ``{}`` * - ``pgbouncer.nodeSelector`` - Node labels for pod assignment - ``1`` @@ -420,6 +465,15 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``pgbouncer.configSecretName`` - Name of existing PgBouncer config secret - ``~`` + * - ``pgbouncer.serviceAccount.create`` + - Create ServiceAccount for PgBouncer + - ``true`` + * - ``pgbouncer.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``pgbouncer.serviceAccount.annotations`` + - Annotations to add to PgBouncer kubernetes service account + - ``{}`` * - ``redis.enabled`` - Enable the redis provisioned by the chart - ``1`` @@ -465,6 +519,15 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``redis.tolerations`` - Toleration labels for pod assignment - ``1`` + * - ``redis.serviceAccount.create`` + - Create ServiceAccount for redis + - ``true`` + * - ``redis.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``redis.serviceAccount.annotations`` + - Annotations to add to redis kubernetes service account + - ``{}`` * - ``cleanup.nodeSelector`` - Node labels for pod assignment - ``1`` @@ -474,6 +537,33 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``cleanup.tolerations`` - Toleration labels for pod assignment - ``1`` + * - ``cleanup.serviceAccount.create`` + - Create ServiceAccount for cleanup pods + - ``true`` + * - ``cleanup.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``cleanup.serviceAccount.annotations`` + - Annotations to add to cleanup cronjob kubernetes service account + - ``{}`` + * - ``createUserJob.serviceAccount.create`` + - Create ServiceAccount for create user job + - ``true`` + * - ``createUserJob.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``createUserJob.serviceAccount.annotations`` + - Annotations to add to ``createUserJob`` kubernetes service account + - ``{}`` + * - ``migrateDatabaseJob.serviceAccount.create`` + - Create ServiceAccount for migrate database job + - ``true`` + * - ``migrateDatabaseJob.serviceAccount.name`` + - Name of ServiceAccount. If not set and create is true, a name is generated using the release name. + - ``~`` + * - ``migrateDatabaseJob.serviceAccount.annotations`` + - Annotations to add to ``migrateDatabaseJob`` kubernetes service account + - ``{}`` * - ``dags.persistence.*`` - Dag persistence configuration - Please refer to ``values.yaml`` @@ -486,9 +576,6 @@ The following tables lists the configurable parameters of the Airflow chart and * - ``multiNamespaceMode`` - Whether the KubernetesExecutor can launch pods in multiple namespaces - ``1`` - * - ``serviceAccountAnnottions.*`` - - Map of annotations for worker, webserver, scheduler kubernetes service accounts - - ``{}``