This is an automated email from the ASF dual-hosted git repository.
jscheffl pushed a commit to branch chart/v1-2x-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/chart/v1-2x-test by this push:
new fc861cbf128 [chart/v1-2x-test] Add workers.celery.serviceAccount &
workers.kubernetes.serviceAccount (#64730) (#64862)
fc861cbf128 is described below
commit fc861cbf12857fbfed34d6e934706639d9d761f1
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Apr 7 22:15:25 2026 +0200
[chart/v1-2x-test] Add workers.celery.serviceAccount &
workers.kubernetes.serviceAccount (#64730) (#64862)
* Refactor Service Account workers tests
* Add workers.celery.serviceAccount & workers.kubernetes.serviceAccount
* Fix spellcheck
* Separate ServiceAccount names
* Add newsfragment
* Misc
(cherry picked from commit 59ddf5698ab7ada2edce24f284c827db5242b170)
Co-authored-by: Przemysław Mirowski
<[email protected]>
---
chart/files/pod-template-file.kubernetes-helm-yaml | 4 +
chart/newsfragments/64730.significant.rst | 1 +
chart/templates/NOTES.txt | 32 +++
chart/templates/_helpers.yaml | 25 +-
.../workers/worker-kubernetes-serviceaccount.yaml | 41 +++
chart/values.schema.json | 86 +++++-
chart/values.yaml | 137 +++++++---
.../helm_tests/airflow_aux/test_annotations.py | 99 +++++++
.../airflow_aux/test_pod_template_file.py | 19 ++
.../tests/helm_tests/airflow_core/test_worker.py | 297 ++++++++++++++++++---
.../helm_tests/airflow_core/test_worker_sets.py | 113 ++++++--
11 files changed, 742 insertions(+), 112 deletions(-)
diff --git a/chart/files/pod-template-file.kubernetes-helm-yaml
b/chart/files/pod-template-file.kubernetes-helm-yaml
index 902391cd1a9..5f067c68077 100644
--- a/chart/files/pod-template-file.kubernetes-helm-yaml
+++ b/chart/files/pod-template-file.kubernetes-helm-yaml
@@ -236,7 +236,11 @@ spec:
terminationGracePeriodSeconds: {{
.Values.workers.kubernetes.terminationGracePeriodSeconds | default
.Values.workers.terminationGracePeriodSeconds }}
tolerations: {{- toYaml $tolerations | nindent 4 }}
topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 4
}}
+ {{- if .Values.workers.kubernetes.serviceAccount.create }}
+ serviceAccountName: {{ include "worker.kubernetes.serviceAccountName" . }}
+ {{- else }}
serviceAccountName: {{ include "worker.serviceAccountName" . }}
+ {{- end }}
volumes:
{{- if .Values.dags.persistence.enabled }}
- name: dags
diff --git a/chart/newsfragments/64730.significant.rst
b/chart/newsfragments/64730.significant.rst
new file mode 100644
index 00000000000..6213c4e8f92
--- /dev/null
+++ b/chart/newsfragments/64730.significant.rst
@@ -0,0 +1 @@
+``workers.serviceAccount`` section is now deprecated in favor of
``workers.celery.serviceAccount`` and ``workers.kubernetes.serviceAccount``.
Please update your configuration accordingly.
diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt
index 104832aef2c..e8236398227 100644
--- a/chart/templates/NOTES.txt
+++ b/chart/templates/NOTES.txt
@@ -413,6 +413,38 @@ DEPRECATION WARNING:
{{- end }}
+{{- if not .Values.workers.serviceAccount.automountServiceAccountToken }}
+
+ DEPRECATION WARNING:
+ `workers.serviceAccount.automountServiceAccountToken` has been renamed to
`workers.celery.serviceAccount.automountServiceAccountToken`/`workers.kubernetes.serviceAccount.automountServiceAccountToken`.
+ Please change your values as support for the old name will be dropped in a
future release.
+
+{{- end }}
+
+{{- if not .Values.workers.serviceAccount.create }}
+
+ DEPRECATION WARNING:
+ `workers.serviceAccount.create` has been renamed to
`workers.celery.serviceAccount.create`/`workers.kubernetes.serviceAccount.create`.
+ Please change your values as support for the old name will be dropped in a
future release.
+
+{{- end }}
+
+{{- if not (empty .Values.workers.serviceAccount.name) }}
+
+ DEPRECATION WARNING:
+ `workers.serviceAccount.name` has been renamed to
`workers.celery.serviceAccount.name`/`workers.kubernetes.serviceAccount.name`.
+ Please change your values as support for the old name will be dropped in a
future release.
+
+{{- end }}
+
+{{- if not (empty .Values.workers.serviceAccount.annotations) }}
+
+ DEPRECATION WARNING:
+ `workers.serviceAccount.annotations` has been renamed to
`workers.celery.serviceAccount.annotations`/`workers.kubernetes.serviceAccount.annotations`.
+ Please change your values as support for the old name will be dropped in a
future release.
+
+{{- end }}
+
{{- if .Values.workers.keda.enabled }}
DEPRECATION WARNING:
diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml
index 5ef1759f604..a435fe6fe65 100644
--- a/chart/templates/_helpers.yaml
+++ b/chart/templates/_helpers.yaml
@@ -641,13 +641,23 @@ server_tls_key_file = /etc/pgbouncer/server.key
{{- end }}
{{- end }}
-{{/* Helper to generate service account name respecting
.Values.$section.serviceAccount flags */}}
+{{/* Helper for service account name generation */}}
+{{- define "_serviceAccountNameGen" -}}
+ {{- if .sa.create }}
+ {{- default (printf "%s-%s" (include "airflow.serviceAccountName" .)
(default .key .nameSuffix)) .sa.name | quote }}
+ {{- else }}
+ {{- default "default" .sa.name | quote }}
+ {{- end }}
+{{- end }}
+
+{{/* Helper to generate service account name respecting
.Values.$section.serviceAccount or .Values.$section.$subSection.serviceAccount
flags */}}
{{- define "_serviceAccountName" -}}
- {{- $sa := get (get .Values .key) "serviceAccount" }}
- {{- if $sa.create }}
- {{- default (printf "%s-%s" (include "airflow.serviceAccountName" .)
(default .key .nameSuffix )) $sa.name | quote }}
+ {{- if .subKey }}
+ {{- $sa := get (get (get .Values .key) .subKey) "serviceAccount" -}}
+ {{- include "_serviceAccountNameGen" (merge (dict "sa" $sa "key" .key
"nameSuffix" .nameSuffix) .) }}
{{- else }}
- {{- default "default" $sa.name | quote }}
+ {{- $sa := get (get .Values .key) "serviceAccount" }}
+ {{- include "_serviceAccountNameGen" (merge (dict "sa" $sa "key" .key
"nameSuffix" .nameSuffix) .) }}
{{- end }}
{{- end }}
@@ -700,6 +710,11 @@ server_tls_key_file = /etc/pgbouncer/server.key
{{- end }}
{{- end }}
+{{/* Create the name of the worker kubernetes service account to use */}}
+{{- define "worker.kubernetes.serviceAccountName" -}}
+ {{- include "_serviceAccountName" (merge (dict "key" "workers" "subKey"
"kubernetes" "nameSuffix" "worker-kubernetes") .) -}}
+{{- end }}
+
{{/* Create the name of the triggerer service account to use */}}
{{- define "triggerer.serviceAccountName" -}}
{{- include "_serviceAccountName" (merge (dict "key" "triggerer") .) -}}
diff --git a/chart/templates/workers/worker-kubernetes-serviceaccount.yaml
b/chart/templates/workers/worker-kubernetes-serviceaccount.yaml
new file mode 100644
index 00000000000..7530f0732d3
--- /dev/null
+++ b/chart/templates/workers/worker-kubernetes-serviceaccount.yaml
@@ -0,0 +1,41 @@
+{{/*
+ 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 Worker Kubernetes ServiceAccount
+###########################################
+{{- if and .Values.workers.kubernetes.serviceAccount.create (contains
"KubernetesExecutor" .Values.executor) }}
+apiVersion: v1
+kind: ServiceAccount
+automountServiceAccountToken: {{ or
.Values.workers.kubernetes.serviceAccount.automountServiceAccountToken (and
(not (has
.Values.workers.kubernetes.serviceAccount.automountServiceAccountToken (list
true false))) .Values.workers.serviceAccount.automountServiceAccountToken) }}
+metadata:
+ name: {{ include "worker.kubernetes.serviceAccountName" . }}
+ labels:
+ tier: airflow
+ component: worker
+ release: {{ .Release.Name }}
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ heritage: {{ .Release.Service }}
+ {{- if or .Values.labels .Values.workers.labels }}
+ {{- mustMerge .Values.workers.labels .Values.labels | toYaml | nindent 4
}}
+ {{- end }}
+ {{- with (.Values.workers.kubernetes.serviceAccount.annotations | default
.Values.workers.serviceAccount.annotations) }}
+ annotations: {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/chart/values.schema.json b/chart/values.schema.json
index df088e1bb93..05c3d6de376 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -1848,21 +1848,21 @@
}
},
"serviceAccount": {
- "description": "Create ServiceAccount for Airflow Celery
workers and pods created with pod-template-file.",
+ "description": "Create ServiceAccount for Airflow Celery
workers and pods created with pod-template-file (deprecated, use
``workers.celery.serviceAccount`` and/or ``workers.kubernetes.serviceAccount``
instead).",
"type": "object",
"properties": {
"automountServiceAccountToken": {
- "description": "Specifies if ServiceAccount's API
credentials should be mounted onto Pods",
+ "description": "Specifies if ServiceAccount's API
credentials should be mounted onto Pods (deprecated, use
``workers.celery.serviceAccount.automountServiceAccountToken`` and/or
``workers.kubernetes.serviceAccount.automountServiceAccountToken`` instead)",
"type": "boolean",
"default": true
},
"create": {
- "description": "Specifies whether a ServiceAccount
should be created.",
+ "description": "Specifies whether a ServiceAccount
should be created (deprecated, use ``workers.celery.serviceAccount.create``
and/or ``workers.kubernetes.serviceAccount.create`` instead).",
"type": "boolean",
"default": true
},
"name": {
- "description": "The name of the ServiceAccount to
use. If not set and create is true, a name is generated using the release
name.",
+ "description": "The name of the ServiceAccount to
use (deprecated, use ``workers.celery.serviceAccount.name`` and/or
``workers.kubernetes.serviceAccount.name`` instead). If not set and create is
true, a name is generated using the release name.",
"type": [
"string",
"null"
@@ -1870,7 +1870,7 @@
"default": null
},
"annotations": {
- "description": "Annotations to add to the worker
Kubernetes ServiceAccount.",
+ "description": "Annotations to add to the worker
Kubernetes ServiceAccount (deprecated, use
``workers.celery.serviceAccount.annotations`` and/or
``workers.kubernetes.serviceAccount.annotations`` instead).",
"type": "object",
"default": {},
"additionalProperties": {
@@ -2921,6 +2921,44 @@
}
}
},
+ "serviceAccount": {
+ "description": "Create ServiceAccount for Airflow
Celery workers.",
+ "type": "object",
+ "properties": {
+ "automountServiceAccountToken": {
+ "description": "Specifies if
ServiceAccount's API credentials should be mounted onto Pods.",
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "default": null
+ },
+ "create": {
+ "description": "Specifies whether a
ServiceAccount should be created.",
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "default": null
+ },
+ "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",
+ "null"
+ ],
+ "default": null
+ },
+ "annotations": {
+ "description": "Annotations to add to the
worker Kubernetes ServiceAccount.",
+ "type": "object",
+ "default": {},
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ }
+ },
"keda": {
"description": "KEDA configuration of Airflow
Celery workers.",
"type": "object",
@@ -3534,6 +3572,44 @@
}
]
},
+ "serviceAccount": {
+ "description": "Create ServiceAccount for pods
created with pod-template-file. When this section is specified, the Service
Account is created from
``templates/workers/worker-kubernetes-serviceaccount.yaml`` file.",
+ "type": "object",
+ "properties": {
+ "automountServiceAccountToken": {
+ "description": "Specifies if
ServiceAccount's API credentials should be mounted onto Pods. If not specified,
the ``workers.serviceAccount.automountServiceAccountToken`` value will be
taken.",
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "default": null
+ },
+ "create": {
+ "description": "Specifies whether a
ServiceAccount should be created. If not specified, the ServiceAccount will be
generated and used from ``templates/workers/worker-serviceaccount.yaml`` file
if ``workers.serviceAccount.create`` will be 'true'.",
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "default": null
+ },
+ "name": {
+ "description": "The name of the
ServiceAccount to use. If not set and ``create`` is 'true', a name is generated
using the release name with kubernetes dedicated name.",
+ "type": [
+ "string",
+ "null"
+ ],
+ "default": null
+ },
+ "annotations": {
+ "description": "Annotations to add to the
worker Kubernetes ServiceAccount. If not specified, the
``workers.serviceAccount.annotations`` value will be taken.",
+ "type": "object",
+ "default": {},
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ }
+ },
"kerberosSidecar": {
"description": "Kerberos sidecar for pods created
with pod-template-file.",
"type": "object",
diff --git a/chart/values.yaml b/chart/values.yaml
index e88893aaea0..67dcf229054 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -770,19 +770,36 @@ workers:
# (deprecated, use
`workers.celery.podDisruptionBudget.config.minAvailable` instead)
# minAvailable: 1
- # Create ServiceAccount for Airflow Celery workers and pods created with
pod-template-file
+ # Create Service Account for Airflow Celery workers and pods created with
pod-template-file
+ # (deprecated, use `workers.celery.serviceAccount` and/or
`workers.kubernetes.serviceAccount` instead)
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
+ # (deprecated, use
+ # `workers.celery.serviceAccount.automountServiceAccountToken` and/or
+ # `workers.kubernetes.serviceAccount.automountServiceAccountToken`
+ # instead)
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
+ # (deprecated, use
+ # `workers.celery.serviceAccount.create` and/or
+ # `workers.kubernetes.serviceAccount.create`
+ # instead)
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
+ # (deprecated, use
+ # `workers.celery.serviceAccount.name` and/or
+ # `workers.kubernetes.serviceAccount.name`
+ # instead)
name: ~
# Annotations to add to worker Kubernetes Service Account.
+ # (deprecated, use
+ # `workers.celery.serviceAccount.annotations` and/or
+ # `workers.kubernetes.serviceAccount.annotations`
+ # instead)
annotations: {}
# Allow KEDA autoscaling for Airflow Celery workers
@@ -1265,6 +1282,21 @@ workers:
maxUnavailable: ~
# minAvailable: ~
+ # Create Service Account for Airflow Celery workers
+ serviceAccount:
+ # ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
+ automountServiceAccountToken: ~
+
+ # Specifies whether a Service Account should be created
+ create: ~
+
+ # The name of the Service Account 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 for Airflow Celery workers
keda:
enabled: ~
@@ -1459,6 +1491,29 @@ workers:
# Container level Lifecycle Hooks definition for pods created with
pod-template-file
containerLifecycleHooks: {}
+ # Create Service Account for pods created with pod-template-file
+ # When this section is specified, the Service Account is created from
+ # 'templates/workers/worker-kubernetes-serviceaccount.yaml' file
+ serviceAccount:
+ # ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
+ # If not specified, the
`workers.serviceAccount.automountServiceAccountToken` value will be taken
+ automountServiceAccountToken: ~
+
+ # Specifies whether a Service Account should be created.
+ # If not specified, the Service Account will be generated and used from
+ # 'templates/workers/worker-serviceaccount.yaml' file if
`workers.serviceAccount.create`
+ # will be 'true'
+ create: ~
+
+ # The name of the Service Account to use.
+ # If not set and `create` is 'true', a name is generated using the
release name
+ # with Kubernetes dedicated name
+ name: ~
+
+ # Annotations to add to worker Kubernetes Service Account.
+ # If not specified, the `workers.serviceAccount.annotations` value will
be taken
+ annotations: {}
+
# Kerberos sidecar configuration for pods created with pod-template-file
kerberosSidecar:
# Enable kerberos sidecar
@@ -1601,16 +1656,16 @@ scheduler:
# Grace period for tasks to finish after SIGTERM is sent from Kubernetes
terminationGracePeriodSeconds: 10
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# Affects all executors that launch pods
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -1830,15 +1885,15 @@ createUserJob:
# Container level lifecycle hooks
containerLifecycleHooks: {}
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -1934,15 +1989,15 @@ migrateDatabaseJob:
# Container level lifecycle hooks
containerLifecycleHooks: {}
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -2050,10 +2105,10 @@ apiServer:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -2280,15 +2335,15 @@ webserver:
# Scaling behavior of the target in both Up and Down directions
behavior: {}
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -2494,15 +2549,15 @@ triggerer:
periodSeconds: 60
command: ~
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -2780,15 +2835,15 @@ dagProcessor:
periodSeconds: 60
command: ~
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -3012,15 +3067,15 @@ flower:
# Container level lifecycle hooks
containerLifecycleHooks: {}
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -3152,15 +3207,15 @@ statsd:
# Grace period for StatsD to finish after SIGTERM is sent from Kubernetes
terminationGracePeriodSeconds: 30
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -3257,15 +3312,15 @@ pgbouncer:
# Add custom annotations to the PgBouncer certificates secret
certificatesSecretAnnotations: {}
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -3451,15 +3506,15 @@ redis:
# Annotations for Redis Statefulset
annotations: {}
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -3671,15 +3726,15 @@ cleanup:
# cpu: 100m
# memory: 128Mi
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
@@ -3771,15 +3826,15 @@ databaseCleanup:
# cpu: 100m
# memory: 128Mi
- # Create ServiceAccount
+ # Create Service Account
serviceAccount:
# ref:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
automountServiceAccountToken: true
- # Specifies whether a ServiceAccount should be created
+ # Specifies whether a Service Account should be created
create: true
- # The name of the ServiceAccount to use.
+ # The name of the Service Account to use.
# If not set and `create` is 'true', a name is generated using the release
name
name: ~
diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_annotations.py
b/helm-tests/tests/helm_tests/airflow_aux/test_annotations.py
index 3df818effa7..2641f922fb1 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_annotations.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_annotations.py
@@ -122,6 +122,105 @@ class TestServiceAccountAnnotations:
"example": "worker",
},
),
+ (
+ {
+ "workers": {
+ "celery": {
+ "serviceAccount": {
+ "annotations": {
+ "example": "worker",
+ },
+ }
+ },
+ },
+ },
+ "templates/workers/worker-serviceaccount.yaml",
+ {
+ "example": "worker",
+ },
+ ),
+ (
+ {
+ "workers": {
+ "serviceAccount": {
+ "annotations": {
+ "worker": "example",
+ },
+ },
+ "celery": {
+ "serviceAccount": {
+ "annotations": {
+ "example": "worker",
+ },
+ }
+ },
+ },
+ },
+ "templates/workers/worker-serviceaccount.yaml",
+ {
+ "example": "worker",
+ },
+ ),
+ (
+ {
+ "executor": "KubernetesExecutor",
+ "workers": {
+ "serviceAccount": {
+ "annotations": {
+ "example": "worker",
+ },
+ },
+ "kubernetes": {"serviceAccount": {"create": True}},
+ },
+ },
+ "templates/workers/worker-kubernetes-serviceaccount.yaml",
+ {
+ "example": "worker",
+ },
+ ),
+ (
+ {
+ "executor": "KubernetesExecutor",
+ "workers": {
+ "kubernetes": {
+ "serviceAccount": {
+ "create": True,
+ "annotations": {
+ "example": "worker",
+ },
+ }
+ },
+ },
+ },
+ "templates/workers/worker-kubernetes-serviceaccount.yaml",
+ {
+ "example": "worker",
+ },
+ ),
+ (
+ {
+ "executor": "KubernetesExecutor",
+ "workers": {
+ "serviceAccount": {
+ "annotations": {
+ "worker": "example",
+ },
+ },
+ "kubernetes": {
+ "serviceAccount": {
+ "create": True,
+ "annotations": {
+ "example": "worker",
+ },
+ }
+ },
+ },
+ },
+ "templates/workers/worker-kubernetes-serviceaccount.yaml",
+ {
+ "example": "worker",
+ },
+ ),
(
{
"flower": {
diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py
b/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py
index a963638459c..d206f61c085 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py
@@ -1810,3 +1810,22 @@ class TestPodTemplateFile:
assert jmespath.search("spec.initContainers[?name=='kerberos-init'] |
[0].lifecycle", docs[0]) == {
"postStart": {"exec": {"command": ["echo", "test-release"]}}
}
+
+ def test_service_account_name_default(self):
+ docs = render_chart(
+ name="test-release",
+ show_only=["templates/pod-template-file.yaml"],
+ chart_dir=self.temp_chart_dir,
+ )
+
+ assert jmespath.search("spec.serviceAccountName", docs[0]) ==
"test-release-airflow-worker"
+
+ def test_dedicated_service_account_name_default(self):
+ docs = render_chart(
+ name="test-release",
+ values={"workers": {"kubernetes": {"serviceAccount": {"create":
True}}}},
+ show_only=["templates/pod-template-file.yaml"],
+ chart_dir=self.temp_chart_dir,
+ )
+
+ assert jmespath.search("spec.serviceAccountName", docs[0]) ==
"test-release-airflow-worker-kubernetes"
diff --git a/helm-tests/tests/helm_tests/airflow_core/test_worker.py
b/helm-tests/tests/helm_tests/airflow_core/test_worker.py
index 0032e50e06c..a247f15ca47 100644
--- a/helm-tests/tests/helm_tests/airflow_core/test_worker.py
+++ b/helm-tests/tests/helm_tests/airflow_core/test_worker.py
@@ -2327,15 +2327,141 @@ class TestWorkerService:
assert jmespath.search("metadata.labels", docs[0])["test_label"] ==
"test_label_value"
-class TestWorkerServiceAccount:
- """Tests worker service account."""
+class TestWorkerCeleryServiceAccount:
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"serviceAccount": {"create": False}},
+ {"celery": {"serviceAccount": {"create": False}}},
+ {"serviceAccount": {"create": True}, "celery": {"serviceAccount":
{"create": False}}},
+ ],
+ )
+ def test_should_not_create_service_account_when_disabled(self,
workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
+ show_only=["templates/workers/worker-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 0
+
+ def test_should_create_service_account_by_default(self):
+ docs = render_chart(
+ show_only=["templates/workers/worker-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 1
+
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"serviceAccount": {"create": True}},
+ {"celery": {"serviceAccount": {"create": True}}},
+ {"serviceAccount": {"create": False}, "celery": {"serviceAccount":
{"create": True}}},
+ ],
+ )
+ def test_should_not_create_service_account_for_local_executor(self,
workers_values):
+ docs = render_chart(
+ values={
+ "executor": "LocalExecutor",
+ "workers": workers_values,
+ },
+ show_only=["templates/workers/worker-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 0
+
+ @pytest.mark.parametrize(
+ "executor",
+ [
+ "CeleryExecutor",
+ "CeleryKubernetesExecutor",
+ "CeleryExecutor,KubernetesExecutor",
+ "KubernetesExecutor",
+ "LocalKubernetesExecutor",
+ ],
+ )
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"serviceAccount": {"create": True}},
+ {"celery": {"serviceAccount": {"create": True}}},
+ {"serviceAccount": {"create": False}, "celery": {"serviceAccount":
{"create": True}}},
+ ],
+ )
+ def test_should_create_service_account_for_specific_executors(self,
executor, workers_values):
+ docs = render_chart(
+ values={
+ "executor": executor,
+ "workers": workers_values,
+ },
+ show_only=["templates/workers/worker-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 1
+ assert jmespath.search("kind", docs[0]) == "ServiceAccount"
+
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"serviceAccount": {"create": True}},
+ {"celery": {"serviceAccount": {"create": True}}},
+ {
+ "serviceAccount": {"automountServiceAccountToken": False},
+ "celery": {"serviceAccount": {"create": True,
"automountServiceAccountToken": True}},
+ },
+ ],
+ )
+ def test_automount_service_account_token_true(self, workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
+ show_only=["templates/workers/worker-serviceaccount.yaml"],
+ )
+ assert jmespath.search("automountServiceAccountToken", docs[0]) is True
+
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"serviceAccount": {"create": True,
"automountServiceAccountToken": False}},
+ {"celery": {"serviceAccount": {"create": True,
"automountServiceAccountToken": False}}},
+ {
+ "serviceAccount": {"automountServiceAccountToken": True},
+ "celery": {"serviceAccount": {"create": True,
"automountServiceAccountToken": False}},
+ },
+ ],
+ )
+ def test_automount_service_account_token_false(self, workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
+ show_only=["templates/workers/worker-serviceaccount.yaml"],
+ )
+
+ assert jmespath.search("automountServiceAccountToken", docs[0]) is
False
+
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"serviceAccount": {"create": True, "name": "test"}},
+ {"celery": {"serviceAccount": {"create": True, "name": "test"}}},
+ {
+ "serviceAccount": {"name": "none"},
+ "celery": {"serviceAccount": {"create": True, "name": "test"}},
+ },
+ ],
+ )
+ def test_overwrite_name(self, workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
+ show_only=["templates/workers/worker-serviceaccount.yaml"],
+ )
+
+ assert jmespath.search("metadata.name", docs[0]) == "test"
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
"executor": "CeleryExecutor",
"workers": {
- "serviceAccount": {"create": True},
+ "celery": {"serviceAccount": {"create": True}},
"labels": {"test_label": "test_label_value"},
},
},
@@ -2345,55 +2471,156 @@ class TestWorkerServiceAccount:
assert "test_label" in jmespath.search("metadata.labels", docs[0])
assert jmespath.search("metadata.labels", docs[0])["test_label"] ==
"test_label_value"
+
+class TestWorkerKubernetesServiceAccount:
+ def test_should_not_create_service_account_by_default(self):
+ docs = render_chart(
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 0
+
@pytest.mark.parametrize(
- ("executor", "creates_service_account"),
+ "workers_values",
[
- ("LocalExecutor", False),
- ("CeleryExecutor", True),
- ("CeleryKubernetesExecutor", True),
- ("CeleryExecutor,KubernetesExecutor", True),
- ("KubernetesExecutor", True),
- ("LocalKubernetesExecutor", True),
+ {"serviceAccount": {"create": True}}, # Should not have effect
+ {"kubernetes": {"serviceAccount": {"create": False}}},
+ {"serviceAccount": {"create": True}, "kubernetes":
{"serviceAccount": {"create": False}}},
],
)
- def test_should_create_worker_service_account_for_specific_executors(
- self, executor, creates_service_account
- ):
+ def test_should_not_create_service_account_when_disabled(self,
workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 0
+
+ def test_should_create_service_account_when_enabled(self):
docs = render_chart(
values={
- "executor": executor,
- "workers": {
- "serviceAccount": {"create": True},
- "labels": {"test_label": "test_label_value"},
- },
+ "executor": "KubernetesExecutor",
+ "workers": {"kubernetes": {"serviceAccount": {"create":
True}}},
},
- show_only=["templates/workers/worker-serviceaccount.yaml"],
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 1
+
+ @pytest.mark.parametrize(
+ "executor",
+ [
+ "CeleryExecutor",
+ "LocalExecutor",
+ "LocalExecutor,CeleryExecutor",
+ ],
+ )
+ def test_should_not_create_service_account_non_k8s_executors(self,
executor):
+ docs = render_chart(
+ values={"executor": executor, "workers": {"kubernetes":
{"serviceAccount": {"create": True}}}},
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
)
- if creates_service_account:
- assert jmespath.search("kind", docs[0]) == "ServiceAccount"
- assert "test_label" in jmespath.search("metadata.labels", docs[0])
- assert jmespath.search("metadata.labels", docs[0])["test_label"]
== "test_label_value"
- else:
- assert docs == []
- def test_default_automount_service_account_token(self):
+ assert len(docs) == 0
+
+ @pytest.mark.parametrize(
+ "executor",
+ [
+ "CeleryKubernetesExecutor",
+ "CeleryExecutor,KubernetesExecutor",
+ "KubernetesExecutor",
+ "LocalKubernetesExecutor",
+ ],
+ )
+ def test_should_create_service_account_when_k8s_executors(self, executor):
docs = render_chart(
- values={
- "workers": {
- "serviceAccount": {"create": True},
- },
+ values={"executor": executor, "workers": {"kubernetes":
{"serviceAccount": {"create": True}}}},
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
+ )
+
+ assert len(docs) == 1
+
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"kubernetes": {"serviceAccount": {"create": True}}},
+ {"kubernetes": {"serviceAccount": {"create": True,
"automountServiceAccountToken": True}}},
+ {
+ "serviceAccount": {"automountServiceAccountToken": False},
+ "kubernetes": {"serviceAccount": {"create": True,
"automountServiceAccountToken": True}},
},
- show_only=["templates/workers/worker-serviceaccount.yaml"],
+ ],
+ )
+ def test_automount_service_account_token_true(self, workers_values):
+ docs = render_chart(
+ values={"executor": "KubernetesExecutor", "workers":
workers_values},
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
)
assert jmespath.search("automountServiceAccountToken", docs[0]) is True
- def test_overridden_automount_service_account_token(self):
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"kubernetes": {"serviceAccount": {"create": True,
"automountServiceAccountToken": False}}},
+ {
+ "serviceAccount": {"automountServiceAccountToken": True},
+ "kubernetes": {"serviceAccount": {"create": True,
"automountServiceAccountToken": False}},
+ },
+ ],
+ )
+ def test_automount_service_account_token_false(self, workers_values):
+ docs = render_chart(
+ values={"executor": "KubernetesExecutor", "workers":
workers_values},
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
+ )
+
+ assert jmespath.search("automountServiceAccountToken", docs[0]) is
False
+
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"kubernetes": {"serviceAccount": {"create": True}}},
+ {"serviceAccount": {"name": "test"}, "kubernetes":
{"serviceAccount": {"create": True}}},
+ ],
+ )
+ def test_default_name(self, workers_values):
+ docs = render_chart(
+ name="test",
+ values={"executor": "KubernetesExecutor", "workers":
workers_values},
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
+ )
+
+ assert jmespath.search("metadata.name", docs[0]) ==
"test-airflow-worker-kubernetes"
+
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {"kubernetes": {"serviceAccount": {"create": True, "name":
"test"}}},
+ {
+ "serviceAccount": {"name": "none"},
+ "kubernetes": {"serviceAccount": {"create": True, "name":
"test"}},
+ },
+ ],
+ )
+ def test_overwrite_name(self, workers_values):
+ docs = render_chart(
+ values={"executor": "KubernetesExecutor", "workers":
workers_values},
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
+ )
+
+ assert jmespath.search("metadata.name", docs[0]) == "test"
+
+ def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "executor": "KubernetesExecutor",
"workers": {
- "serviceAccount": {"create": True,
"automountServiceAccountToken": False},
+ "kubernetes": {"serviceAccount": {"create": True}},
+ "labels": {"test_label": "test_label_value"},
},
},
- show_only=["templates/workers/worker-serviceaccount.yaml"],
+
show_only=["templates/workers/worker-kubernetes-serviceaccount.yaml"],
)
- assert jmespath.search("automountServiceAccountToken", docs[0]) is
False
+
+ assert "test_label" in jmespath.search("metadata.labels", docs[0])
+ assert jmespath.search("metadata.labels", docs[0])["test_label"] ==
"test_label_value"
diff --git a/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py
b/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py
index 1d71fe813ca..d15554ab0f8 100644
--- a/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py
+++ b/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py
@@ -1205,46 +1205,100 @@ class TestWorkerSets:
assert jmespath.search("[*].metadata.name", docs) == expected
- def
test_overwrite_service_account_automount_service_account_token_disable(self):
- docs = render_chart(
- values={
- "workers": {
- "celery": {
- "enableDefault": False,
- "sets": [{"name": "test", "serviceAccount":
{"automountServiceAccountToken": False}}],
- },
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {
+ "celery": {
+ "enableDefault": False,
+ "sets": [{"name": "test", "serviceAccount": {"create":
False}}],
+ }
+ },
+ {
+ "celery": {
+ "enableDefault": False,
+ "serviceAccount": {"create": True},
+ "sets": [{"name": "test", "serviceAccount": {"create":
False}}],
}
},
+ {
+ "serviceAccount": {"create": True},
+ "celery": {
+ "enableDefault": False,
+ "sets": [{"name": "test", "serviceAccount": {"create":
False}}],
+ },
+ },
+ ],
+ )
+ def test_overwrite_service_account_create_disable(self, workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
show_only=["templates/workers/worker-serviceaccount.yaml"],
)
- assert jmespath.search("automountServiceAccountToken", docs[0]) is
False
+ assert len(docs) == 0
- def test_overwrite_service_account_create_disable(self):
- docs = render_chart(
- values={
- "workers": {
- "celery": {
- "enableDefault": False,
- "sets": [{"name": "test", "serviceAccount": {"create":
False}}],
- },
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {
+ "celery": {
+ "enableDefault": False,
+ "sets": [{"name": "test", "serviceAccount":
{"automountServiceAccountToken": False}}],
+ }
+ },
+ {
+ "celery": {
+ "enableDefault": False,
+ "serviceAccount": {"automountServiceAccountToken": True},
+ "sets": [{"name": "test", "serviceAccount":
{"automountServiceAccountToken": False}}],
}
},
+ {
+ "serviceAccount": {"automountServiceAccountToken": True},
+ "celery": {
+ "enableDefault": False,
+ "sets": [{"name": "test", "serviceAccount":
{"automountServiceAccountToken": False}}],
+ },
+ },
+ ],
+ )
+ def
test_overwrite_service_account_automount_service_account_token_disable(self,
workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
show_only=["templates/workers/worker-serviceaccount.yaml"],
)
- assert len(docs) == 0
+ assert jmespath.search("automountServiceAccountToken", docs[0]) is
False
- def test_overwrite_service_account_name(self):
- docs = render_chart(
- values={
- "workers": {
- "celery": {
- "enableDefault": False,
- "sets": [{"name": "test", "serviceAccount": {"name":
"test"}}],
- },
+ @pytest.mark.parametrize(
+ "workers_values",
+ [
+ {
+ "celery": {
+ "enableDefault": False,
+ "sets": [{"name": "test", "serviceAccount": {"name":
"test"}}],
}
},
+ {
+ "celery": {
+ "enableDefault": False,
+ "serviceAccount": {"name": "nontest"},
+ "sets": [{"name": "test", "serviceAccount": {"name":
"test"}}],
+ }
+ },
+ {
+ "serviceAccount": {"name": "nontest"},
+ "celery": {
+ "enableDefault": False,
+ "sets": [{"name": "test", "serviceAccount": {"name":
"test"}}],
+ },
+ },
+ ],
+ )
+ def test_overwrite_service_account_name(self, workers_values):
+ docs = render_chart(
+ values={"workers": workers_values},
show_only=["templates/workers/worker-serviceaccount.yaml"],
)
@@ -1264,6 +1318,13 @@ class TestWorkerSets:
"sets": [{"name": "test", "serviceAccount":
{"annotations": {"test": "echo"}}}],
},
},
+ {
+ "celery": {
+ "enableDefault": False,
+ "serviceAccount": {"annotations": {"echo": "test"}},
+ "sets": [{"name": "test", "serviceAccount":
{"annotations": {"test": "echo"}}}],
+ },
+ },
],
)
def test_overwrite_service_account_annotations(self, workers_values):