This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new ba631cd556d Chart: Make Airflow 3.0.0 default Airflow version (#49593)
ba631cd556d is described below
commit ba631cd556d2799f086f52bf0f0f9544f1be8744
Author: Kaxil Naik <[email protected]>
AuthorDate: Wed Apr 23 23:32:35 2025 +0530
Chart: Make Airflow 3.0.0 default Airflow version (#49593)
---
chart/Chart.yaml | 20 +-
chart/README.md | 2 +-
chart/newsfragments/49593.significant.rst | 3 +
chart/values.schema.json | 4 +-
chart/values.yaml | 4 +-
.../helm_tests/airflow_aux/test_airflow_common.py | 5 +
.../helm_tests/airflow_aux/test_annotations.py | 37 +++-
.../airflow_aux/test_basic_helm_chart.py | 235 ++++++++++++++-------
.../tests/helm_tests/airflow_core/test_env.py | 41 +++-
.../helm_tests/airflow_core/test_scheduler.py | 4 +-
.../helm_tests/other/test_git_sync_scheduler.py | 23 +-
.../helm_tests/other/test_git_sync_webserver.py | 8 +-
helm-tests/tests/helm_tests/security/test_rbac.py | 8 +-
.../helm_tests/webserver/test_hpa_webserver.py | 4 +
.../tests/helm_tests/webserver/test_ingress_web.py | 33 ++-
.../helm_tests/webserver/test_pdb_webserver.py | 1 +
.../tests/helm_tests/webserver/test_webserver.py | 116 +++++++---
17 files changed, 377 insertions(+), 171 deletions(-)
diff --git a/chart/Chart.yaml b/chart/Chart.yaml
index 68ab297edaa..143b2860a1d 100644
--- a/chart/Chart.yaml
+++ b/chart/Chart.yaml
@@ -20,7 +20,7 @@
apiVersion: v2
name: airflow
version: 1.17.0-dev
-appVersion: 2.10.5
+appVersion: 3.0.0
description: The official Helm chart to deploy Apache Airflow, a platform to
programmatically author, schedule, and monitor workflows
home: https://airflow.apache.org/
@@ -47,23 +47,23 @@ annotations:
url: https://airflow.apache.org/docs/helm-chart/1.17.0/
artifacthub.io/screenshots: |
- title: DAGs View
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/dags.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/dags.png
- title: Datasets View
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/datasets.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/datasets.png
- title: Grid View
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/grid.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/grid.png
- title: Graph View
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/graph.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/graph.png
- title: Calendar View
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/calendar.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/calendar.png
- title: Variable View
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/variable_hidden.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/variable_hidden.png
- title: Gantt Chart
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/gantt.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/gantt.png
- title: Task Duration
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/duration.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/duration.png
- title: Code View
- url:
https://airflow.apache.org/docs/apache-airflow/2.10.5/_images/code.png
+ url:
https://airflow.apache.org/docs/apache-airflow/3.0.0/_images/code.png
artifacthub.io/changes: |
- description: Allow passing custom env to log groomer sidecar containers
kind: added
diff --git a/chart/README.md b/chart/README.md
index 262d0455429..cff3c6bb655 100644
--- a/chart/README.md
+++ b/chart/README.md
@@ -40,7 +40,7 @@ cluster using the [Helm](https://helm.sh) package manager.
* Supported AWS executors with AWS provider version ``8.21.0+``:
* ``airflow.providers.amazon.aws.executors.batch.AwsBatchExecutor``
* ``airflow.providers.amazon.aws.executors.ecs.AwsEcsExecutor``
-* Supported Airflow version: ``1.10+``, ``2.0+``
+* Supported Airflow version: ``1.10+``, ``2.0+``, ``3.0+``
* Supported database backend: ``PostgreSQL``, ``MySQL``
* Autoscaling for ``CeleryExecutor`` provided by KEDA
* ``PostgreSQL`` and ``PgBouncer`` with a battle-tested configuration
diff --git a/chart/newsfragments/49593.significant.rst
b/chart/newsfragments/49593.significant.rst
new file mode 100644
index 00000000000..6979c9ffeed
--- /dev/null
+++ b/chart/newsfragments/49593.significant.rst
@@ -0,0 +1,3 @@
+Default Airflow image is updated to ``3.0.0``
+
+The default Airflow image that is used with the Chart is now ``3.0.0``,
previously it was ``2.10.5``.
diff --git a/chart/values.schema.json b/chart/values.schema.json
index 8c168e7d7aa..93036cac30e 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -78,7 +78,7 @@
"defaultAirflowTag": {
"description": "Default airflow tag to deploy.",
"type": "string",
- "default": "2.10.5",
+ "default": "3.0.0",
"x-docsSection": "Common"
},
"defaultAirflowDigest": {
@@ -93,7 +93,7 @@
"airflowVersion": {
"description": "Airflow version (Used to make some decisions based
on Airflow Version being deployed).",
"type": "string",
- "default": "2.10.5",
+ "default": "3.0.0",
"x-docsSection": "Common"
},
"securityContext": {
diff --git a/chart/values.yaml b/chart/values.yaml
index a029360f0ac..9066cbbb7f2 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -68,13 +68,13 @@ airflowHome: /opt/airflow
defaultAirflowRepository: apache/airflow
# Default airflow tag to deploy
-defaultAirflowTag: "2.10.5"
+defaultAirflowTag: "3.0.0"
# Default airflow digest. If specified, it takes precedence over tag
defaultAirflowDigest: ~
# Airflow version (Used to make some decisions based on Airflow Version being
deployed)
-airflowVersion: "2.10.5"
+airflowVersion: "3.0.0"
# Images
images:
diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
b/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
index 9b72bba9d87..78b43d02f73 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
@@ -156,6 +156,7 @@ class TestAirflowCommon:
"templates/scheduler/scheduler-deployment.yaml",
"templates/workers/worker-deployment.yaml",
"templates/webserver/webserver-deployment.yaml",
+ "templates/api-server/api-server-deployment.yaml",
"templates/flower/flower-deployment.yaml",
"templates/triggerer/triggerer-deployment.yaml",
"templates/dag-processor/dag-processor-deployment.yaml",
@@ -163,6 +164,7 @@ class TestAirflowCommon:
],
)
+ # Objects in show_only are 8 but only one of Webserver or API server
is created so we have 7 objects
assert len(k8s_objects) == 7
for k8s_object in k8s_objects:
@@ -220,10 +222,12 @@ class TestAirflowCommon:
"templates/triggerer/triggerer-deployment.yaml",
"templates/dag-processor/dag-processor-deployment.yaml",
"templates/webserver/webserver-deployment.yaml",
+ "templates/api-server/api-server-deployment.yaml",
"templates/workers/worker-deployment.yaml",
],
)
+ # Objects in show_only are 13 but only one of Webserver or API server
is created so we have 12 objects
assert len(k8s_objects) == 12
for k8s_object in k8s_objects:
@@ -385,6 +389,7 @@ class TestAirflowCommon:
"templates/scheduler/scheduler-deployment.yaml",
"templates/workers/worker-deployment.yaml",
"templates/webserver/webserver-deployment.yaml",
+ "templates/api-server/api-server-deployment.yaml",
"templates/triggerer/triggerer-deployment.yaml",
"templates/dag-processor/dag-processor-deployment.yaml",
],
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 47eb1a3313f..6c0d4788da3 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_annotations.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_annotations.py
@@ -73,17 +73,17 @@ class TestServiceAccountAnnotations:
),
(
{
- "webserver": {
+ "apiServer": {
"serviceAccount": {
"annotations": {
- "example": "webserver",
+ "example": "api-server",
},
},
},
},
- "templates/webserver/webserver-serviceaccount.yaml",
+ "templates/api-server/api-server-serviceaccount.yaml",
{
- "example": "webserver",
+ "example": "api-server",
},
),
(
@@ -243,6 +243,27 @@ class TestServiceAccountAnnotations:
assert k in obj["metadata"]["annotations"]
assert v == obj["metadata"]["annotations"][k]
+ def test_annotations_on_webserver(self):
+ """Test annotations are added on webserver for Airflow 1 & 2"""
+ k8s_objects = render_chart(
+ values={
+ "airflowVersion": "2.10.0",
+ "webserver": {
+ "serviceAccount": {
+ "annotations": {
+ "example": "webserver",
+ },
+ },
+ },
+ },
+ show_only=["templates/webserver/webserver-serviceaccount.yaml"],
+ )
+
+ assert len(k8s_objects) == 1
+ obj = k8s_objects[0]
+
+ assert obj["metadata"]["annotations"] == {"example": "webserver"}
+
@pytest.mark.parametrize(
"values,show_only,expected_annotations",
@@ -262,15 +283,15 @@ class TestServiceAccountAnnotations:
),
(
{
- "webserver": {
+ "apiServer": {
"podAnnotations": {
- "example": "webserver",
+ "example": "api-server",
},
},
},
- "templates/webserver/webserver-deployment.yaml",
+ "templates/api-server/api-server-deployment.yaml",
{
- "example": "webserver",
+ "example": "api-server",
},
),
(
diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py
b/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py
index d926de50b0c..00ff40799e3 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py
@@ -27,16 +27,13 @@ import pytest
from chart_utils.helm_template_generator import render_chart
from packaging.version import parse as parse_version
-OBJECT_COUNT_IN_BASIC_DEPLOYMENT = 35
-
-DEFAULT_OBJECTS_STD_NAMING = {
+OBJECTS_STD_NAMING = {
("ServiceAccount", "test-basic-airflow-create-user-job"),
("ServiceAccount", "test-basic-airflow-migrate-database-job"),
("ServiceAccount", "test-basic-airflow-redis"),
("ServiceAccount", "test-basic-airflow-scheduler"),
("ServiceAccount", "test-basic-airflow-statsd"),
("ServiceAccount", "test-basic-airflow-triggerer"),
- ("ServiceAccount", "test-basic-airflow-webserver"),
("ServiceAccount", "test-basic-airflow-worker"),
("Secret", "test-basic-airflow-metadata"),
("Secret", "test-basic-broker-url"),
@@ -53,13 +50,11 @@ DEFAULT_OBJECTS_STD_NAMING = {
("Service", "test-basic-airflow-redis"),
("Service", "test-basic-airflow-statsd"),
("Service", "test-basic-airflow-triggerer"),
- ("Service", "test-basic-airflow-webserver"),
("Service", "test-basic-airflow-worker"),
("Service", "test-basic-postgresql"),
("Service", "test-basic-postgresql-hl"),
("Deployment", "test-basic-airflow-scheduler"),
("Deployment", "test-basic-airflow-statsd"),
- ("Deployment", "test-basic-airflow-webserver"),
("StatefulSet", "test-basic-airflow-redis"),
("StatefulSet", "test-basic-airflow-worker"),
("StatefulSet", "test-basic-airflow-triggerer"),
@@ -68,6 +63,29 @@ DEFAULT_OBJECTS_STD_NAMING = {
("Job", "test-basic-airflow-run-airflow-migrations"),
}
+# Airflow 3.0.0+ has a new API server that replaces the webserver & mandatory
dag processor
+DEFAULT_OBJECTS_STD_NAMING = OBJECTS_STD_NAMING.union(
+ {
+ ("Service", "test-basic-airflow-api-server"),
+ ("Deployment", "test-basic-airflow-api-server"),
+ ("Deployment", "test-basic-airflow-dag-processor"),
+ ("ServiceAccount", "test-basic-airflow-api-server"),
+ ("ServiceAccount", "test-basic-airflow-dag-processor"),
+ }
+)
+
+OBJECT_COUNT_IN_BASIC_DEPLOYMENT = len(DEFAULT_OBJECTS_STD_NAMING)
+
+AIRFLOW2_OBJECTS_STD_NAMING = OBJECTS_STD_NAMING.union(
+ {
+ ("Service", "test-basic-airflow-webserver"),
+ ("Deployment", "test-basic-airflow-webserver"),
+ ("ServiceAccount", "test-basic-airflow-webserver"),
+ }
+)
+
+OBJECT_COUNT_IN_AF2_BASIC_DEPLOYMENT = len(AIRFLOW2_OBJECTS_STD_NAMING)
+
class TestBaseChartTest:
"""Tests basic helm chart tests."""
@@ -78,9 +96,16 @@ class TestBaseChartTest:
return values
def _get_object_count(self, version):
- if version == "2.3.2" or version == "default":
- return OBJECT_COUNT_IN_BASIC_DEPLOYMENT + 1
- return OBJECT_COUNT_IN_BASIC_DEPLOYMENT
+ if self._is_airflow_3_or_above(version):
+ return OBJECT_COUNT_IN_BASIC_DEPLOYMENT
+
+ if version == "2.3.2":
+ return OBJECT_COUNT_IN_AF2_BASIC_DEPLOYMENT + 1
+
+ return OBJECT_COUNT_IN_AF2_BASIC_DEPLOYMENT
+
+ def _is_airflow_3_or_above(self, version):
+ return version == "default" or (parse_version(version) >=
parse_version("3.0.0"))
@pytest.mark.parametrize("version", ["2.3.2", "2.4.0", "3.0.0", "default"])
def test_basic_deployments(self, version):
@@ -136,7 +161,7 @@ class TestBaseChartTest:
}
if version == "2.3.2":
expected.add(("Secret", "test-basic-result-backend"))
- if version != "default" and parse_version(version) >=
parse_version("3.0.0"):
+ if self._is_airflow_3_or_above(version):
expected.update(
(
("Deployment", "test-basic-api-server"),
@@ -180,7 +205,7 @@ class TestBaseChartTest:
actual = {(x["kind"], x["metadata"]["name"]) for x in k8s_objects}
assert actual == DEFAULT_OBJECTS_STD_NAMING
- @pytest.mark.parametrize("version", ["2.3.2", "2.4.0", "default"])
+ @pytest.mark.parametrize("version", ["2.3.2", "3.0.0", "default"])
def test_basic_deployment_with_standalone_dag_processor(self, version):
k8s_objects = render_chart(
"test-basic",
@@ -207,7 +232,6 @@ class TestBaseChartTest:
("ServiceAccount", "test-basic-statsd"),
("ServiceAccount", "test-basic-triggerer"),
("ServiceAccount", "test-basic-dag-processor"),
- ("ServiceAccount", "test-basic-webserver"),
("ServiceAccount", "test-basic-worker"),
("Secret", "test-basic-metadata"),
("Secret", "test-basic-broker-url"),
@@ -225,13 +249,11 @@ class TestBaseChartTest:
("Service", "test-basic-postgresql"),
("Service", "test-basic-redis"),
("Service", "test-basic-statsd"),
- ("Service", "test-basic-webserver"),
("Service", "test-basic-worker"),
("Deployment", "test-basic-scheduler"),
("Deployment", "test-basic-statsd"),
(self.default_trigger_obj(version), "test-basic-triggerer"),
("Deployment", "test-basic-dag-processor"),
- ("Deployment", "test-basic-webserver"),
("StatefulSet", "test-basic-postgresql"),
("StatefulSet", "test-basic-redis"),
("StatefulSet", "test-basic-worker"),
@@ -240,8 +262,23 @@ class TestBaseChartTest:
}
if version == "2.3.2":
expected.add(("Secret", "test-basic-result-backend"))
- if version == "default":
- expected.add(("Service", "test-basic-triggerer"))
+ if self._is_airflow_3_or_above(version):
+ expected.update(
+ {
+ ("Service", "test-basic-triggerer"),
+ ("Deployment", "test-basic-api-server"),
+ ("Service", "test-basic-api-server"),
+ ("ServiceAccount", "test-basic-api-server"),
+ }
+ )
+ else:
+ expected.update(
+ {
+ ("Service", "test-basic-webserver"),
+ ("Deployment", "test-basic-webserver"),
+ ("ServiceAccount", "test-basic-webserver"),
+ }
+ )
assert list_of_kind_names_tuples == expected
assert len(k8s_objects) == len(expected)
for k8s_object in k8s_objects:
@@ -257,9 +294,8 @@ class TestBaseChartTest:
f"Missing label test-label on {k8s_name}. Current labels:
{labels}"
)
- @pytest.mark.parametrize("version", ["2.3.2", "2.4.0", "default"])
+ @pytest.mark.parametrize("version", ["2.3.2", "2.4.0", "3.0.0", "default"])
def test_basic_deployment_without_default_users(self, version):
- expected_object_count_in_basic_deployment =
self._get_object_count(version)
k8s_objects = render_chart(
"test-basic",
values=self._get_values_with_version(
@@ -270,11 +306,9 @@ class TestBaseChartTest:
(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 len(k8s_objects) == expected_object_count_in_basic_deployment -
2
- @pytest.mark.parametrize("version", ["2.3.2", "2.4.0", "default"])
+ @pytest.mark.parametrize("version", ["2.3.2", "2.4.0", "3.0.0"])
def test_basic_deployment_without_statsd(self, version):
- expected_object_count_in_basic_deployment =
self._get_object_count(version)
k8s_objects = render_chart(
"test-basic",
values=self._get_values_with_version(values={"statsd": {"enabled":
False}}, version=version),
@@ -287,17 +321,19 @@ class TestBaseChartTest:
assert ("Service", "test-basic-statsd") not in
list_of_kind_names_tuples
assert ("Deployment", "test-basic-statsd") not in
list_of_kind_names_tuples
- assert len(k8s_objects) == expected_object_count_in_basic_deployment -
4
-
- def test_network_policies_are_valid(self):
+ @pytest.mark.parametrize("airflow_version", ["2.10.0", "3.0.0", "default"])
+ def test_network_policies_are_valid(self, airflow_version):
k8s_objects = render_chart(
- "test-basic",
- {
- "networkPolicies": {"enabled": True},
- "executor": "CeleryExecutor",
- "flower": {"enabled": True},
- "pgbouncer": {"enabled": True},
- },
+ name="test-basic",
+ values=self._get_values_with_version(
+ values={
+ "networkPolicies": {"enabled": True},
+ "executor": "CeleryExecutor",
+ "flower": {"enabled": True},
+ "pgbouncer": {"enabled": True},
+ },
+ version=airflow_version,
+ ),
)
kind_names_tuples = {
(k8s_object["kind"], k8s_object["metadata"]["name"]) for
k8s_object in k8s_objects
@@ -309,43 +345,56 @@ class TestBaseChartTest:
("NetworkPolicy", "test-basic-pgbouncer-policy"),
("NetworkPolicy", "test-basic-scheduler-policy"),
("NetworkPolicy", "test-basic-statsd-policy"),
- ("NetworkPolicy", "test-basic-webserver-policy"),
("NetworkPolicy", "test-basic-worker-policy"),
]
+
+ if self._is_airflow_3_or_above(airflow_version):
+ expected_kind_names += [
+ ("NetworkPolicy", "test-basic-api-server-policy"),
+ ]
+ else:
+ expected_kind_names += [
+ ("NetworkPolicy", "test-basic-webserver-policy"),
+ ]
+
for kind_name in expected_kind_names:
assert kind_name in kind_names_tuples
- def test_labels_are_valid(self):
+ @pytest.mark.parametrize("airflow_version", ["2.10.0", "3.0.0", "default"])
+ def test_labels_are_valid(self, airflow_version):
"""Test labels are correctly applied on all objects created by this
chart."""
release_name = "test-basic"
- k8s_objects = render_chart(
- name=release_name,
- values={
- "labels": {"label1": "value1", "label2": "value2"},
- "executor": "CeleryExecutor",
- "data": {
- "resultBackendConnection": {
- "user": "someuser",
- "pass": "somepass",
- "host": "somehost",
- "protocol": "postgresql",
- "port": 7777,
- "db": "somedb",
- "sslmode": "allow",
- }
- },
- "pgbouncer": {"enabled": True},
- "redis": {"enabled": True},
- "ingress": {"enabled": True},
- "networkPolicies": {"enabled": True},
- "cleanup": {"enabled": True},
- "flower": {"enabled": True},
- "dagProcessor": {"enabled": True},
- "logs": {"persistence": {"enabled": True}},
- "dags": {"persistence": {"enabled": True}},
- "postgresql": {"enabled": False}, # We won't check the
objects created by the postgres chart
+
+ values = {
+ "labels": {"label1": "value1", "label2": "value2"},
+ "executor": "CeleryExecutor",
+ "data": {
+ "resultBackendConnection": {
+ "user": "someuser",
+ "pass": "somepass",
+ "host": "somehost",
+ "protocol": "postgresql",
+ "port": 7777,
+ "db": "somedb",
+ "sslmode": "allow",
+ }
},
- )
+ "pgbouncer": {"enabled": True},
+ "redis": {"enabled": True},
+ "ingress": {"enabled": True},
+ "networkPolicies": {"enabled": True},
+ "cleanup": {"enabled": True},
+ "flower": {"enabled": True},
+ "dagProcessor": {"enabled": True},
+ "logs": {"persistence": {"enabled": True}},
+ "dags": {"persistence": {"enabled": True}},
+ "postgresql": {"enabled": False}, # We won't check the objects
created by the postgres chart
+ }
+
+ if airflow_version != "default":
+ values["airflowVersion"] = airflow_version
+
+ k8s_objects = render_chart(name=release_name, values=values)
kind_k8s_obj_labels_tuples = {
(k8s_object["metadata"]["name"], k8s_object["kind"]):
k8s_object["metadata"]["labels"]
for k8s_object in k8s_objects
@@ -363,7 +412,6 @@ class TestBaseChartTest:
(f"{release_name}-airflow-redis", "ServiceAccount", "redis"),
(f"{release_name}-airflow-scheduler", "ServiceAccount",
"scheduler"),
(f"{release_name}-airflow-statsd", "ServiceAccount", "statsd"),
- (f"{release_name}-airflow-webserver", "ServiceAccount",
"webserver"),
(f"{release_name}-airflow-worker", "ServiceAccount", "worker"),
(f"{release_name}-airflow-triggerer", "ServiceAccount",
"triggerer"),
(f"{release_name}-airflow-dag-processor", "ServiceAccount",
"dag-processor"),
@@ -396,11 +444,7 @@ class TestBaseChartTest:
(f"{release_name}-statsd", "Deployment", "statsd"),
(f"{release_name}-statsd", "Service", "statsd"),
(f"{release_name}-statsd-policy", "NetworkPolicy",
"statsd-policy"),
- (f"{release_name}-webserver", "Deployment", "webserver"),
(f"{release_name}-webserver-secret-key", "Secret", "webserver"),
- (f"{release_name}-webserver", "Service", "webserver"),
- (f"{release_name}-webserver-policy", "NetworkPolicy",
"airflow-webserver-policy"),
- (f"{release_name}-ingress", "Ingress", "airflow-ingress"),
(f"{release_name}-worker", "Service", "worker"),
(f"{release_name}-worker", "StatefulSet", "worker"),
(f"{release_name}-worker-policy", "NetworkPolicy",
"airflow-worker-policy"),
@@ -409,6 +453,22 @@ class TestBaseChartTest:
(f"{release_name}-logs", "PersistentVolumeClaim", "logs-pvc"),
(f"{release_name}-dags", "PersistentVolumeClaim", "dags-pvc"),
]
+
+ if self._is_airflow_3_or_above(airflow_version):
+ kind_names_tuples += [
+ (f"{release_name}-api-server", "Service", "api-server"),
+ (f"{release_name}-api-server-policy", "NetworkPolicy",
"airflow-api-server-policy"),
+ (f"{release_name}-api-server", "Deployment", "api-server"),
+ ]
+ else:
+ kind_names_tuples += [
+ (f"{release_name}-airflow-webserver", "ServiceAccount",
"webserver"),
+ (f"{release_name}-webserver", "Deployment", "webserver"),
+ (f"{release_name}-webserver", "Service", "webserver"),
+ (f"{release_name}-webserver-policy", "NetworkPolicy",
"airflow-webserver-policy"),
+ (f"{release_name}-ingress", "Ingress", "airflow-ingress"),
+ ]
+
for k8s_object_name, kind, component in kind_names_tuples:
expected_labels = {
"label1": "value1",
@@ -465,30 +525,41 @@ class TestBaseChartTest:
}
assert dict_of_labels_in_job_templates.get(k8s_object_name) ==
expected_labels
- def test_annotations_on_airflow_pods_in_deployment(self):
+ @pytest.mark.parametrize("airflow_version", ["2.10.0", "3.0.0", "default"])
+ def test_annotations_on_airflow_pods_in_deployment(self, airflow_version):
"""
Test Annotations are correctly applied.
- Verifies all pods created Scheduler, Webserver & Worker deployments.
+ Verifies all pods created Scheduler, Webserver/API-server & Worker
deployments.
"""
release_name = "test-basic"
+
+ show_only = [
+ "templates/scheduler/scheduler-deployment.yaml",
+ "templates/workers/worker-deployment.yaml",
+ "templates/triggerer/triggerer-deployment.yaml",
+ "templates/dag-processor/dag-processor-deployment.yaml",
+ "templates/flower/flower-deployment.yaml",
+ "templates/jobs/create-user-job.yaml",
+ "templates/jobs/migrate-database-job.yaml",
+ ]
+
+ if self._is_airflow_3_or_above(airflow_version):
+ show_only += ["templates/api-server/api-server-deployment.yaml"]
+ else:
+ show_only += ["templates/webserver/webserver-deployment.yaml"]
+
k8s_objects = render_chart(
name=release_name,
- values={
- "airflowPodAnnotations": {"test-annotation/safe-to-evict":
"true"},
- "flower": {"enabled": True},
- "dagProcessor": {"enabled": True},
- },
- show_only=[
- "templates/scheduler/scheduler-deployment.yaml",
- "templates/workers/worker-deployment.yaml",
- "templates/webserver/webserver-deployment.yaml",
- "templates/triggerer/triggerer-deployment.yaml",
- "templates/dag-processor/dag-processor-deployment.yaml",
- "templates/flower/flower-deployment.yaml",
- "templates/jobs/create-user-job.yaml",
- "templates/jobs/migrate-database-job.yaml",
- ],
+ values=self._get_values_with_version(
+ values={
+ "airflowPodAnnotations": {"test-annotation/safe-to-evict":
"true"},
+ "flower": {"enabled": True},
+ "dagProcessor": {"enabled": True},
+ },
+ version=airflow_version,
+ ),
+ show_only=show_only,
)
# pod_template_file is tested separately as it has extra setup steps
diff --git a/helm-tests/tests/helm_tests/airflow_core/test_env.py
b/helm-tests/tests/helm_tests/airflow_core/test_env.py
index d0f47d8d385..3b4121a9503 100644
--- a/helm-tests/tests/helm_tests/airflow_core/test_env.py
+++ b/helm-tests/tests/helm_tests/airflow_core/test_env.py
@@ -17,25 +17,46 @@
from __future__ import annotations
import jmespath
+import pytest
from chart_utils.helm_template_generator import render_chart
-def test_should_add_airflow_home():
[email protected](
+ ["airflow_version", "template_yaml"],
+ [
+ ("2.10.0", "templates/webserver/webserver-deployment.yaml"),
+ ("3.0.0", "templates/api-server/api-server-deployment.yaml"),
+ ("default", "templates/api-server/api-server-deployment.yaml"),
+ ],
+)
+def test_should_add_airflow_home(airflow_version, template_yaml):
exp_path = "/not/even/a/real/path"
- docs = render_chart(
- values={"airflowHome": exp_path},
- show_only=["templates/webserver/webserver-deployment.yaml"],
- )
+ values = {"airflowHome": exp_path}
+
+ if airflow_version != "default":
+ values["airflowVersion"] = airflow_version
+
+ docs = render_chart(values=values, show_only=[template_yaml])
+
assert {"name": "AIRFLOW_HOME", "value": exp_path} in jmespath.search(
"spec.template.spec.containers[0].env", docs[0]
)
-def test_should_add_airflow_home_notset():
- docs = render_chart(
- values={},
- show_only=["templates/webserver/webserver-deployment.yaml"],
- )
[email protected](
+ ["airflow_version", "template_yaml"],
+ [
+ ("2.10.0", "templates/webserver/webserver-deployment.yaml"),
+ ("3.0.0", "templates/api-server/api-server-deployment.yaml"),
+ ("default", "templates/api-server/api-server-deployment.yaml"),
+ ],
+)
+def test_should_add_airflow_home_notset(airflow_version, template_yaml):
+ values = {}
+ if airflow_version != "default":
+ values["airflowVersion"] = airflow_version
+
+ docs = render_chart(values=values, show_only=[template_yaml])
assert {"name": "AIRFLOW_HOME", "value": "/opt/airflow"} in
jmespath.search(
"spec.template.spec.containers[0].env", docs[0]
)
diff --git a/helm-tests/tests/helm_tests/airflow_core/test_scheduler.py
b/helm-tests/tests/helm_tests/airflow_core/test_scheduler.py
index 340cfe35714..b743d6d64b9 100644
--- a/helm-tests/tests/helm_tests/airflow_core/test_scheduler.py
+++ b/helm-tests/tests/helm_tests/airflow_core/test_scheduler.py
@@ -746,9 +746,9 @@ class TestScheduler:
{"gitSync": {"enabled": True}, "persistence": {"enabled": True}},
],
)
- def test_dags_gitsync_sidecar_and_init_container(self, dags_values):
+ def test_dags_gitsync_sidecar_and_init_container_with_airflow_2(self,
dags_values):
docs = render_chart(
- values={"dags": dags_values},
+ values={"dags": dags_values, "airflowVersion": "2.10.4"},
show_only=["templates/scheduler/scheduler-deployment.yaml"],
)
diff --git a/helm-tests/tests/helm_tests/other/test_git_sync_scheduler.py
b/helm-tests/tests/helm_tests/other/test_git_sync_scheduler.py
index 0d8e7b4e29f..9b5c6429811 100644
--- a/helm-tests/tests/helm_tests/other/test_git_sync_scheduler.py
+++ b/helm-tests/tests/helm_tests/other/test_git_sync_scheduler.py
@@ -21,11 +21,11 @@ from chart_utils.helm_template_generator import render_chart
class TestGitSyncSchedulerTest:
- """Test git sync scheduler."""
+ """Test git sync scheduler. This is ignored when Airflow >=3 or a separate
dag processor is used."""
def test_should_add_dags_volume(self):
docs = render_chart(
- values={"dags": {"gitSync": {"enabled": True}}},
+ values={"airflowVersion": "2.10.5", "dags": {"gitSync":
{"enabled": True}}},
show_only=["templates/scheduler/scheduler-deployment.yaml"],
)
@@ -53,6 +53,7 @@ class TestGitSyncSchedulerTest:
def test_validate_the_git_sync_container_spec(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"images": {
"gitSync": {
"repository": "test-registry/test-repo",
@@ -115,6 +116,7 @@ class TestGitSyncSchedulerTest:
def test_validate_the_git_sync_container_spec_if_wait_specified(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"images": {
"gitSync": {
"repository": "test-registry/test-repo",
@@ -178,6 +180,7 @@ class TestGitSyncSchedulerTest:
def test_validate_if_ssh_params_are_added(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"dags": {
"gitSync": {
"enabled": True,
@@ -186,7 +189,7 @@ class TestGitSyncSchedulerTest:
"knownHosts": None,
"branch": "test-branch",
}
- }
+ },
},
show_only=["templates/scheduler/scheduler-deployment.yaml"],
)
@@ -217,12 +220,13 @@ class TestGitSyncSchedulerTest:
def test_validate_if_ssh_params_are_added_with_git_ssh_key(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"dags": {
"gitSync": {
"enabled": True,
"sshKey": "dummy-ssh-key",
}
- }
+ },
},
show_only=["templates/scheduler/scheduler-deployment.yaml"],
)
@@ -265,13 +269,14 @@ class TestGitSyncSchedulerTest:
def test_should_set_username_and_pass_env_variables(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"dags": {
"gitSync": {
"enabled": True,
"credentialsSecret": "user-pass-secret",
"sshKeySecret": None,
}
- }
+ },
},
show_only=["templates/scheduler/scheduler-deployment.yaml"],
)
@@ -297,7 +302,10 @@ class TestGitSyncSchedulerTest:
def
test_should_set_the_volume_claim_correctly_when_using_an_existing_claim(self):
docs = render_chart(
- values={"dags": {"persistence": {"enabled": True, "existingClaim":
"test-claim"}}},
+ values={
+ "airflowVersion": "2.10.5",
+ "dags": {"persistence": {"enabled": True, "existingClaim":
"test-claim"}},
+ },
show_only=["templates/scheduler/scheduler-deployment.yaml"],
)
@@ -334,6 +342,7 @@ class TestGitSyncSchedulerTest:
def test_extra_volume_and_git_sync_extra_volume_mount(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"executor": "CeleryExecutor",
"scheduler": {
"extraVolumes": [{"name": "test-volume-{{ .Values.executor
}}", "emptyDir": {}}],
@@ -363,6 +372,7 @@ class TestGitSyncSchedulerTest:
def test_should_add_env(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"dags": {
"gitSync": {
"enabled": True,
@@ -380,6 +390,7 @@ class TestGitSyncSchedulerTest:
def test_resources_are_configurable(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"dags": {
"gitSync": {
"enabled": True,
diff --git a/helm-tests/tests/helm_tests/other/test_git_sync_webserver.py
b/helm-tests/tests/helm_tests/other/test_git_sync_webserver.py
index 23403481be0..7ce406d3d32 100644
--- a/helm-tests/tests/helm_tests/other/test_git_sync_webserver.py
+++ b/helm-tests/tests/helm_tests/other/test_git_sync_webserver.py
@@ -62,7 +62,10 @@ class TestGitSyncWebserver:
def test_should_have_service_account_defined(self):
docs = render_chart(
- values={"dags": {"gitSync": {"enabled": True}, "persistence":
{"enabled": True}}},
+ values={
+ "airflowVersion": "2.10.0",
+ "dags": {"gitSync": {"enabled": True}, "persistence":
{"enabled": True}},
+ },
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -158,6 +161,7 @@ class TestGitSyncWebserver:
def test_validate_sshkeysecret_not_added_when_persistence_is_enabled(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.4",
"dags": {
"gitSync": {
"enabled": True,
@@ -167,7 +171,7 @@ class TestGitSyncWebserver:
"branch": "test-branch",
},
"persistence": {"enabled": True},
- }
+ },
},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
diff --git a/helm-tests/tests/helm_tests/security/test_rbac.py
b/helm-tests/tests/helm_tests/security/test_rbac.py
index f3e9f3fea1b..6271e7cfafc 100644
--- a/helm-tests/tests/helm_tests/security/test_rbac.py
+++ b/helm-tests/tests/helm_tests/security/test_rbac.py
@@ -103,8 +103,10 @@ class TestRBAC:
values["airflowVersion"] = version
return values
- @staticmethod
- def _get_object_tuples(version, sa: bool = True):
+ def _is_airflow_3_or_above(self, version):
+ return version == "default" or (parse_version(version) >=
parse_version("3.0.0"))
+
+ def _get_object_tuples(self, version, sa: bool = True):
tuples = copy(DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES)
if version in {"default", "3.0.0"}:
tuples.append(("Service", "test-rbac-triggerer"))
@@ -113,7 +115,7 @@ class TestRBAC:
tuples.append(("Deployment", "test-rbac-triggerer"))
if version == "2.3.2":
tuples.append(("Secret", "test-rbac-result-backend"))
- if version != "default" and parse_version(version) >=
parse_version("3.0.0"):
+ if self._is_airflow_3_or_above(version):
tuples.extend(
(
("Service", "test-rbac-api-server"),
diff --git a/helm-tests/tests/helm_tests/webserver/test_hpa_webserver.py
b/helm-tests/tests/helm_tests/webserver/test_hpa_webserver.py
index 56528a1cc02..e110b0d9640 100644
--- a/helm-tests/tests/helm_tests/webserver/test_hpa_webserver.py
+++ b/helm-tests/tests/helm_tests/webserver/test_hpa_webserver.py
@@ -35,6 +35,7 @@ class TestWebserverHPA:
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"hpa": {"enabled": True},
"labels": {"test_label": "test_label_value"},
@@ -57,6 +58,7 @@ class TestWebserverHPA:
"""Verify minimum and maximum replicas."""
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"hpa": {
"enabled": True,
@@ -80,6 +82,7 @@ class TestWebserverHPA:
}
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"hpa": {
"enabled": True,
@@ -126,6 +129,7 @@ class TestWebserverHPA:
def test_should_use_hpa_metrics(self, metrics, expected_metrics):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"hpa": {"enabled": True, **({"metrics": metrics} if
metrics else {})},
},
diff --git a/helm-tests/tests/helm_tests/webserver/test_ingress_web.py
b/helm-tests/tests/helm_tests/webserver/test_ingress_web.py
index f873e1e1e70..d796e2396d7 100644
--- a/helm-tests/tests/helm_tests/webserver/test_ingress_web.py
+++ b/helm-tests/tests/helm_tests/webserver/test_ingress_web.py
@@ -26,27 +26,33 @@ class TestIngressWeb:
def test_should_pass_validation_with_just_ingress_enabled_v1(self):
render_chart(
- values={"ingress": {"web": {"enabled": True}}},
+ values={"ingress": {"web": {"enabled": True}}, "airflowVersion":
"2.10.5"},
show_only=["templates/webserver/webserver-ingress.yaml"],
) # checks that no validation exception is raised
def test_should_pass_validation_with_just_ingress_enabled_v1beta1(self):
render_chart(
- values={"ingress": {"web": {"enabled": True}}},
+ values={"ingress": {"web": {"enabled": True}}, "airflowVersion":
"2.10.5"},
show_only=["templates/webserver/webserver-ingress.yaml"],
kubernetes_version="1.16.0",
) # checks that no validation exception is raised
def test_should_allow_more_than_one_annotation(self):
docs = render_chart(
- values={"ingress": {"web": {"enabled": True, "annotations": {"aa":
"bb", "cc": "dd"}}}},
+ values={
+ "airflowVersion": "2.10.5",
+ "ingress": {"web": {"enabled": True, "annotations": {"aa":
"bb", "cc": "dd"}}},
+ },
show_only=["templates/webserver/webserver-ingress.yaml"],
)
assert jmespath.search("metadata.annotations", docs[0]) == {"aa":
"bb", "cc": "dd"}
def test_should_set_ingress_class_name(self):
docs = render_chart(
- values={"ingress": {"web": {"enabled": True, "ingressClassName":
"foo"}}},
+ values={
+ "airflowVersion": "2.10.5",
+ "ingress": {"web": {"enabled": True, "ingressClassName":
"foo"}},
+ },
show_only=["templates/webserver/webserver-ingress.yaml"],
)
assert jmespath.search("spec.ingressClassName", docs[0]) == "foo"
@@ -54,6 +60,7 @@ class TestIngressWeb:
def test_should_ingress_hosts_objs_have_priority_over_host(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"ingress": {
"web": {
"enabled": True,
@@ -67,7 +74,7 @@ class TestIngressWeb:
],
"host": "old-host",
},
- }
+ },
},
show_only=["templates/webserver/webserver-ingress.yaml"],
)
@@ -87,6 +94,7 @@ class TestIngressWeb:
def test_should_ingress_hosts_strs_have_priority_over_host(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"ingress": {
"web": {
"enabled": True,
@@ -94,7 +102,7 @@ class TestIngressWeb:
"hosts": ["*.a-host", "b-host", "c-host", "d-host"],
"host": "old-host",
},
- }
+ },
},
show_only=["templates/webserver/webserver-ingress.yaml"],
)
@@ -106,13 +114,14 @@ class TestIngressWeb:
def test_should_ingress_deprecated_host_and_top_level_tls_still_work(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"ingress": {
"web": {
"enabled": True,
"tls": {"enabled": True, "secretName": "supersecret"},
"host": "old-host",
},
- }
+ },
},
show_only=["templates/webserver/webserver-ingress.yaml"],
)
@@ -125,11 +134,12 @@ class TestIngressWeb:
def test_should_ingress_host_entry_not_exist(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"ingress": {
"web": {
"enabled": True,
}
- }
+ },
},
show_only=["templates/webserver/webserver-ingress.yaml"],
)
@@ -148,7 +158,7 @@ class TestIngressWeb:
],
)
def test_ingress_created(self, global_value, web_value, expected):
- values = {"ingress": {}}
+ values = {"airflowVersion": "2.10.5", "ingress": {}}
if global_value is not None:
values["ingress"]["enabled"] = global_value
if web_value is not None:
@@ -161,6 +171,7 @@ class TestIngressWeb:
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"ingress": {"enabled": True},
"webserver": {
"labels": {"test_label": "test_label_value"},
@@ -174,6 +185,7 @@ class TestIngressWeb:
def test_can_ingress_hosts_be_templated(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"testValues": {
"scalar": "aa",
"list": ["bb", "cc"],
@@ -206,7 +218,7 @@ class TestIngressWeb:
def test_backend_service_name(self):
docs = render_chart(
- values={"ingress": {"web": {"enabled": True}}},
+ values={"airflowVersion": "2.10.5", "ingress": {"web": {"enabled":
True}}},
show_only=["templates/webserver/webserver-ingress.yaml"],
)
@@ -218,6 +230,7 @@ class TestIngressWeb:
def test_backend_service_name_with_fullname_override(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"fullnameOverride": "test-basic",
"useStandardNaming": True,
"ingress": {"web": {"enabled": True}},
diff --git a/helm-tests/tests/helm_tests/webserver/test_pdb_webserver.py
b/helm-tests/tests/helm_tests/webserver/test_pdb_webserver.py
index 7e425eae441..46b57ea923b 100644
--- a/helm-tests/tests/helm_tests/webserver/test_pdb_webserver.py
+++ b/helm-tests/tests/helm_tests/webserver/test_pdb_webserver.py
@@ -39,6 +39,7 @@ class TestWebserverPdb:
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"podDisruptionBudget": {"enabled": True},
"labels": {"test_label": "test_label_value"},
diff --git a/helm-tests/tests/helm_tests/webserver/test_webserver.py
b/helm-tests/tests/helm_tests/webserver/test_webserver.py
index 60ba6747248..c0822bd2b9d 100644
--- a/helm-tests/tests/helm_tests/webserver/test_webserver.py
+++ b/helm-tests/tests/helm_tests/webserver/test_webserver.py
@@ -24,6 +24,19 @@ from chart_utils.helm_template_generator import render_chart
class TestWebserverDeployment:
"""Tests webserver deployment."""
+ def test_airflow_3(self):
+ """
+ Webserver does not exist in airflow 3.0.0
+
+ For example, user may be disabled when using webserver and having it
deployed on another host.
+ """
+ docs = render_chart(
+ values={"webserver": {"enabled": True}},
+ show_only=["templates/webserver/webserver-deployment.yaml"],
+ )
+
+ assert len(docs) == 0
+
def test_can_be_disabled(self):
"""
Webserver should be able to be disabled if the users desires.
@@ -31,7 +44,7 @@ class TestWebserverDeployment:
For example, user may be disabled when using webserver and having it
deployed on another host.
"""
docs = render_chart(
- values={"webserver": {"enabled": False}},
+ values={"airflowVersion": "2.10.5", "webserver": {"enabled":
False}},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -40,6 +53,7 @@ class TestWebserverDeployment:
def test_should_remove_replicas_field(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"hpa": {"enabled": True},
},
@@ -51,6 +65,7 @@ class TestWebserverDeployment:
def test_should_not_remove_replicas_field(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"hpa": {"enabled": False},
},
@@ -62,9 +77,10 @@ class TestWebserverDeployment:
def
test_should_add_host_header_to_liveness_and_readiness_and_startup_probes(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"config": {
"webserver": {"base_url":
"https://example.com:21222/mypath/path"},
- }
+ },
},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -82,9 +98,10 @@ class TestWebserverDeployment:
def
test_should_add_path_to_liveness_and_readiness_and_startup_probes(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"config": {
"webserver": {"base_url":
"https://example.com:21222/mypath/path"},
- }
+ },
},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -107,7 +124,7 @@ class TestWebserverDeployment:
[(8, 10), (10, 8), (8, None), (None, 10), (None, None)],
)
def test_revision_history_limit(self, revision_history_limit,
global_revision_history_limit):
- values = {"webserver": {}}
+ values = {"webserver": {}, "airflowVersion": "2.10.5"}
if revision_history_limit:
values["webserver"]["revisionHistoryLimit"] =
revision_history_limit
if global_revision_history_limit:
@@ -119,7 +136,13 @@ class TestWebserverDeployment:
expected_result = revision_history_limit if revision_history_limit
else global_revision_history_limit
assert jmespath.search("spec.revisionHistoryLimit", docs[0]) ==
expected_result
- @pytest.mark.parametrize("values", [{"config": {"webserver": {"base_url":
""}}}, {}])
+ @pytest.mark.parametrize(
+ "values",
+ [
+ {"airflowVersion": "2.10.5", "config": {"webserver": {"base_url":
""}}},
+ {"airflowVersion": "2.10.5"},
+ ],
+ )
def test_should_not_contain_host_header(self, values):
print(values)
docs = render_chart(values=values,
show_only=["templates/webserver/webserver-deployment.yaml"])
@@ -140,11 +163,12 @@ class TestWebserverDeployment:
def test_should_use_templated_base_url_for_probes(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"config": {
"webserver": {
"base_url": "https://{{ .Release.Name
}}.com:21222/mypath/{{ .Release.Name }}/path"
},
- }
+ },
},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -166,11 +190,12 @@ class TestWebserverDeployment:
def
test_should_add_scheme_to_liveness_and_readiness_and_startup_probes(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"livenessProbe": {"scheme": "HTTPS"},
"readinessProbe": {"scheme": "HTTPS"},
"startupProbe": {"scheme": "HTTPS"},
- }
+ },
},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -187,7 +212,7 @@ class TestWebserverDeployment:
def
test_should_add_volume_and_volume_mount_when_exist_webserver_config(self):
docs = render_chart(
- values={"webserver": {"webserverConfig": "CSRF_ENABLED = True"}},
+ values={"webserver": {"webserverConfig": "CSRF_ENABLED = True"},
"airflowVersion": "2.10.5"},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -206,6 +231,7 @@ class TestWebserverDeployment:
def test_should_add_extra_containers(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"executor": "CeleryExecutor",
"webserver": {
"extraContainers": [
@@ -224,6 +250,7 @@ class TestWebserverDeployment:
def test_should_template_extra_containers(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"executor": "CeleryExecutor",
"webserver": {
"extraContainers": [{"name": "{{ .Release.Name
}}-test-container"}],
@@ -239,6 +266,7 @@ class TestWebserverDeployment:
def test_should_add_extraEnvs(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"env": [
{"name": "TEST_ENV_1", "value": "test_env_1"},
@@ -271,6 +299,7 @@ class TestWebserverDeployment:
def test_should_add_extra_volume_and_extra_volume_mount(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"extraVolumes": [{"name": "test-volume-{{ .Chart.Name }}",
"emptyDir": {}}],
"extraVolumeMounts": [
@@ -294,6 +323,7 @@ class TestWebserverDeployment:
def test_should_add_global_volume_and_global_volume_mount(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"volumes": [{"name": "test-volume", "emptyDir": {}}],
"volumeMounts": [{"name": "test-volume", "mountPath":
"/opt/test"}],
},
@@ -309,6 +339,7 @@ class TestWebserverDeployment:
def test_should_add_extraEnvs_to_wait_for_migration_container(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"waitForMigrations": {
"env": [{"name": "TEST_ENV_1", "value": "test_env_1"}],
@@ -344,6 +375,7 @@ class TestWebserverDeployment:
def test_disable_wait_for_migration(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"waitForMigrations": {"enabled": False},
},
@@ -358,6 +390,7 @@ class TestWebserverDeployment:
def test_should_add_extra_init_containers(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"extraInitContainers": [
{"name": "test-init-container", "image":
"test-registry/test-repo:test-tag"}
@@ -375,6 +408,7 @@ class TestWebserverDeployment:
def test_should_template_extra_init_containers(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"extraInitContainers": [{"name": "{{ .Release.Name
}}-init-container"}],
},
@@ -389,6 +423,7 @@ class TestWebserverDeployment:
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"labels": {"test_label": "test_label_value"},
},
@@ -402,6 +437,7 @@ class TestWebserverDeployment:
def test_should_create_valid_affinity_tolerations_and_node_selector(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"affinity": {
"nodeAffinity": {
@@ -420,7 +456,7 @@ class TestWebserverDeployment:
{"key": "dynamic-pods", "operator": "Equal", "value":
"true", "effect": "NoSchedule"}
],
"nodeSelector": {"diskType": "ssd"},
- }
+ },
},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -453,7 +489,9 @@ class TestWebserverDeployment:
)
def test_should_create_default_affinity(self):
- docs =
render_chart(show_only=["templates/webserver/webserver-deployment.yaml"])
+ docs = render_chart(
+ values={"airflowVersion": "2.10.5"},
show_only=["templates/webserver/webserver-deployment.yaml"]
+ )
assert jmespath.search(
"spec.template.spec.affinity.podAntiAffinity."
@@ -485,6 +523,7 @@ class TestWebserverDeployment:
}
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"affinity": expected_affinity,
"tolerations": [
@@ -538,20 +577,6 @@ class TestWebserverDeployment:
"spec.template.spec.topologySpreadConstraints[0]", docs[0]
)
- def test_scheduler_name(self):
- docs = render_chart(
- values={"schedulerName": "airflow-scheduler"},
- show_only=["templates/webserver/webserver-deployment.yaml"],
- )
-
- assert (
- jmespath.search(
- "spec.template.spec.schedulerName",
- docs[0],
- )
- == "airflow-scheduler"
- )
-
@pytest.mark.parametrize(
"log_persistence_values, expected_claim_name",
[
@@ -562,7 +587,7 @@ class TestWebserverDeployment:
)
def test_logs_persistence_adds_volume_and_mount(self,
log_persistence_values, expected_claim_name):
docs = render_chart(
- values={"logs": {"persistence": log_persistence_values}},
+ values={"airflowVersion": "2.10.5", "logs": {"persistence":
log_persistence_values}},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -618,6 +643,7 @@ class TestWebserverDeployment:
def test_webserver_resources_are_configurable(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"resources": {
"limits": {"cpu": "200m", "memory": "128Mi"},
@@ -653,6 +679,7 @@ class TestWebserverDeployment:
def test_webserver_security_contexts_are_configurable(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"securityContexts": {
"pod": {
@@ -685,6 +712,7 @@ class TestWebserverDeployment:
def test_webserver_security_context_legacy(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"securityContext": {
"fsGroup": 1000,
@@ -706,6 +734,7 @@ class TestWebserverDeployment:
def test_webserver_resources_are_not_added_by_default(self):
docs = render_chart(
+ values={"airflowVersion": "2.10.5"},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
assert jmespath.search("spec.template.spec.containers[0].resources",
docs[0]) == {}
@@ -731,7 +760,7 @@ class TestWebserverDeployment:
def test_update_strategy(self):
expected_strategy = {"type": "RollingUpdate", "rollingUpdate":
{"maxUnavailable": 1}}
docs = render_chart(
- values={"webserver": {"strategy": expected_strategy}},
+ values={"airflowVersion": "2.10.5", "webserver": {"strategy":
expected_strategy}},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -739,7 +768,8 @@ class TestWebserverDeployment:
def test_no_airflow_local_settings(self):
docs = render_chart(
- values={"airflowLocalSettings": None},
show_only=["templates/webserver/webserver-deployment.yaml"]
+ values={"airflowVersion": "2.10.5", "airflowLocalSettings": None},
+ show_only=["templates/webserver/webserver-deployment.yaml"],
)
volume_mounts =
jmespath.search("spec.template.spec.containers[0].volumeMounts", docs[0])
assert "airflow_local_settings.py" not in str(volume_mounts)
@@ -748,7 +778,7 @@ class TestWebserverDeployment:
def test_airflow_local_settings(self):
docs = render_chart(
- values={"airflowLocalSettings": "# Well hello!"},
+ values={"airflowVersion": "2.10.5", "airflowLocalSettings": "#
Well hello!"},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
volume_mount = {
@@ -761,7 +791,9 @@ class TestWebserverDeployment:
assert volume_mount in
jmespath.search("spec.template.spec.initContainers[0].volumeMounts", docs[0])
def test_default_command_and_args(self):
- docs =
render_chart(show_only=["templates/webserver/webserver-deployment.yaml"])
+ docs = render_chart(
+ values={"airflowVersion": "2.10.5"},
show_only=["templates/webserver/webserver-deployment.yaml"]
+ )
assert jmespath.search("spec.template.spec.containers[0].command",
docs[0]) is None
assert jmespath.search("spec.template.spec.containers[0].args",
docs[0]) == [
@@ -774,7 +806,7 @@ class TestWebserverDeployment:
@pytest.mark.parametrize("args", [None, ["custom", "args"]])
def test_command_and_args_overrides(self, command, args):
docs = render_chart(
- values={"webserver": {"command": command, "args": args}},
+ values={"airflowVersion": "2.10.5", "webserver": {"command":
command, "args": args}},
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -783,7 +815,10 @@ class TestWebserverDeployment:
def test_command_and_args_overrides_are_templated(self):
docs = render_chart(
- values={"webserver": {"command": ["{{ .Release.Name }}"], "args":
["{{ .Release.Service }}"]}},
+ values={
+ "airflowVersion": "2.10.5",
+ "webserver": {"command": ["{{ .Release.Name }}"], "args": ["{{
.Release.Service }}"]},
+ },
show_only=["templates/webserver/webserver-deployment.yaml"],
)
@@ -872,6 +907,7 @@ class TestWebserverDeployment:
def test_should_add_component_specific_annotations(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"annotations": {"test_annotation":
"test_annotation_value"},
},
@@ -884,6 +920,7 @@ class TestWebserverDeployment:
def test_webserver_pod_hostaliases(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"hostAliases": [{"ip": "127.0.0.1", "hostnames":
["foo.local"]}],
},
@@ -897,6 +934,7 @@ class TestWebserverDeployment:
def test_should_add_annotations_to_webserver_configmap(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"webserverConfig": "CSRF_ENABLED = True # {{
.Release.Name }}",
"configMapAnnotations": {"test_annotation":
"test_annotation_value"},
@@ -911,8 +949,8 @@ class TestWebserverDeployment:
@pytest.mark.parametrize(
"webserver_values, expected",
[
- ({}, 30),
- ({"webserver": {"terminationGracePeriodSeconds": 1200}}, 1200),
+ ({"airflowVersion": "2.10.5"}, 30),
+ ({"airflowVersion": "2.10.5", "webserver":
{"terminationGracePeriodSeconds": 1200}}, 1200),
],
)
def test_webserver_termination_grace_period_seconds(self,
webserver_values, expected):
@@ -928,6 +966,7 @@ class TestWebserverService:
def test_default_service(self):
docs = render_chart(
+ values={"airflowVersion": "2.10.5"},
show_only=["templates/webserver/webserver-service.yaml"],
)
@@ -944,6 +983,7 @@ class TestWebserverService:
def test_overrides(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"ports": {"airflowUI": 9000},
"webserver": {
"service": {
@@ -987,6 +1027,7 @@ class TestWebserverService:
def test_ports_overrides(self, ports, expected_ports):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {"service": {"ports": ports}},
},
show_only=["templates/webserver/webserver-service.yaml"],
@@ -997,6 +1038,7 @@ class TestWebserverService:
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"labels": {"test_label": "test_label_value"},
},
@@ -1022,6 +1064,7 @@ class TestWebserverService:
def test_nodeport_service(self, ports, expected_ports):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"service": {
"type": "NodePort",
@@ -1081,6 +1124,7 @@ class TestWebserverNetworkPolicy:
def test_defaults(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"networkPolicies": {"enabled": True},
"webserver": {
"networkPolicy": {
@@ -1119,6 +1163,7 @@ class TestWebserverNetworkPolicy:
def test_ports_overrides(self, ports, expected_ports):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"networkPolicies": {"enabled": True},
"webserver": {
"networkPolicy": {
@@ -1137,6 +1182,7 @@ class TestWebserverNetworkPolicy:
def test_deprecated_from_param(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"networkPolicies": {"enabled": True},
"webserver": {
"extraNetworkPolicies": [{"namespaceSelector":
{"matchLabels": {"release": "myrelease"}}}]
@@ -1152,6 +1198,7 @@ class TestWebserverNetworkPolicy:
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"networkPolicies": {"enabled": True},
"webserver": {
"labels": {"test_label": "test_label_value"},
@@ -1169,6 +1216,7 @@ class TestWebserverServiceAccount:
def test_should_add_component_specific_labels(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"serviceAccount": {"create": True},
"labels": {"test_label": "test_label_value"},
@@ -1182,6 +1230,7 @@ class TestWebserverServiceAccount:
def test_default_automount_service_account_token(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"serviceAccount": {"create": True},
},
@@ -1193,6 +1242,7 @@ class TestWebserverServiceAccount:
def test_overridden_automount_service_account_token(self):
docs = render_chart(
values={
+ "airflowVersion": "2.10.5",
"webserver": {
"serviceAccount": {"create": True,
"automountServiceAccountToken": False},
},