This is an automated email from the ASF dual-hosted git repository.
jscheffl 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 00400a5e5ef Change job/pod role bindings rendering & refactor related
tests (#66626)
00400a5e5ef is described below
commit 00400a5e5ef4fc6772c934e8228d8e1309d864f2
Author: Przemysław Mirowski <[email protected]>
AuthorDate: Sat May 9 20:40:25 2026 +0200
Change job/pod role bindings rendering & refactor related tests (#66626)
* Simplify job/pod launcher role binding templates
* Refactor tests & render scheduler when enabled
---
chart/templates/rbac/job-launcher-rolebinding.yaml | 15 +-
chart/templates/rbac/pod-launcher-rolebinding.yaml | 15 +-
.../airflow_aux/test_job_launcher_role.py | 208 ++++++++++-------
.../airflow_aux/test_pod_launcher_role.py | 247 +++++++++++++-------
.../helm_tests/security/test_scc_rolebinding.py | 251 +++++++++++++++------
5 files changed, 466 insertions(+), 270 deletions(-)
diff --git a/chart/templates/rbac/job-launcher-rolebinding.yaml
b/chart/templates/rbac/job-launcher-rolebinding.yaml
index e5cbca8c630..f918826663b 100644
--- a/chart/templates/rbac/job-launcher-rolebinding.yaml
+++ b/chart/templates/rbac/job-launcher-rolebinding.yaml
@@ -21,9 +21,6 @@
## Airflow Job Launcher Role Binding
####################################
{{- if and .Values.rbac.create .Values.allowJobLaunching }}
-{{- $schedulerLaunchExecutors := list "LocalExecutor" "KubernetesExecutor" }}
-{{- $workerLaunchExecutors := list "CeleryExecutor" "KubernetesExecutor" }}
-{{- $executors := split "," .Values.executor }}
apiVersion: rbac.authorization.k8s.io/v1
{{- if .Values.multiNamespaceMode }}
kind: ClusterRoleBinding
@@ -58,22 +55,14 @@ roleRef:
name: {{ include "airflow.fullname" . }}-job-launcher-role
{{- end }}
subjects:
- {{- range $executor := $executors }}
- {{- $executorClass := last (splitList "." ($executor | trim)) }}
- {{- if has $executorClass $schedulerLaunchExecutors }}
+ {{- if and .Values.scheduler.enabled (or (contains "LocalExecutor"
.Values.executor) (contains "KubernetesExecutor" .Values.executor)) }}
- kind: ServiceAccount
name: {{ include "scheduler.serviceAccountName" $ }}
namespace: "{{ $.Release.Namespace }}"
- {{- break }}
{{- end }}
- {{- end }}
- {{- range $executor := $executors }}
- {{- $executorClass := last (splitList "." ($executor | trim)) }}
- {{- if has $executorClass $workerLaunchExecutors }}
+ {{- if or (contains "CeleryExecutor" .Values.executor) (contains
"KubernetesExecutor" .Values.executor) }}
- kind: ServiceAccount
name: {{ include "worker.serviceAccountName" $ }}
namespace: "{{ $.Release.Namespace }}"
- {{- break }}
- {{- end }}
{{- end }}
{{- end }}
diff --git a/chart/templates/rbac/pod-launcher-rolebinding.yaml
b/chart/templates/rbac/pod-launcher-rolebinding.yaml
index a9a3b510a43..5e71c251158 100644
--- a/chart/templates/rbac/pod-launcher-rolebinding.yaml
+++ b/chart/templates/rbac/pod-launcher-rolebinding.yaml
@@ -21,9 +21,6 @@
## Airflow Pod Launcher Role Binding
####################################
{{- if and .Values.rbac.create .Values.allowPodLaunching }}
-{{- $schedulerLaunchExecutors := list "LocalExecutor" "KubernetesExecutor" }}
-{{- $workerLaunchExecutors := list "CeleryExecutor" "KubernetesExecutor" }}
-{{- $executors := split "," .Values.executor }}
apiVersion: rbac.authorization.k8s.io/v1
{{- if .Values.multiNamespaceMode }}
kind: ClusterRoleBinding
@@ -58,23 +55,15 @@ roleRef:
name: {{ include "airflow.fullname" . }}-pod-launcher-role
{{- end }}
subjects:
- {{- range $executor := $executors }}
- {{- $executorClass := last (splitList "." ($executor | trim)) }}
- {{- if has $executorClass $schedulerLaunchExecutors }}
+ {{- if and .Values.scheduler.enabled (or (contains "LocalExecutor"
.Values.executor) (contains "KubernetesExecutor" .Values.executor)) }}
- kind: ServiceAccount
name: {{ include "scheduler.serviceAccountName" $ }}
namespace: "{{ $.Release.Namespace }}"
- {{- break }}
{{- end }}
- {{- end }}
- {{- range $executor := $executors }}
- {{- $executorClass := last (splitList "." ($executor | trim)) }}
- {{- if has $executorClass $workerLaunchExecutors }}
+ {{- if or (contains "CeleryExecutor" .Values.executor) (contains
"KubernetesExecutor" .Values.executor) }}
- kind: ServiceAccount
name: {{ include "worker.serviceAccountName" $ }}
namespace: "{{ $.Release.Namespace }}"
- {{- break }}
- {{- end }}
{{- end }}
{{- if .Values.triggerer.enabled }}
- kind: ServiceAccount
diff --git a/chart/tests/helm_tests/airflow_aux/test_job_launcher_role.py
b/chart/tests/helm_tests/airflow_aux/test_job_launcher_role.py
index 74db8dad091..acbc181ba66 100644
--- a/chart/tests/helm_tests/airflow_aux/test_job_launcher_role.py
+++ b/chart/tests/helm_tests/airflow_aux/test_job_launcher_role.py
@@ -22,114 +22,150 @@ from chart_utils.helm_template_generator import
render_chart
class TestJobLauncher:
- """Tests job launcher RBAC."""
+ @pytest.mark.parametrize(
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
+ )
+ def test_should_render(self, executor):
+ docs = render_chart(
+ values={"rbac": {"create": True}, "allowJobLaunching": True,
"executor": executor},
+ show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
+ )
+
+ assert len(docs) == 1
+ @pytest.mark.parametrize(("rbac", "allow"), [(True, False), (False, True),
(False, False)])
@pytest.mark.parametrize(
- ("executor", "rbac", "allow", "expected_accounts"),
- [
- ("KubernetesExecutor", True, True, ["scheduler", "worker"]),
- (
-
"airflow.providers.cncf.kubernetes.executors.kubernetes_executor.KubernetesExecutor",
- True,
- True,
- ["scheduler", "worker"],
- ),
- ("CeleryExecutor", True, True, ["worker"]),
- (
-
"airflow.providers.celery.executors.celery_executor.CeleryExecutor",
- True,
- True,
- ["worker"],
- ),
- ("LocalExecutor", True, True, ["scheduler"]),
- ("airflow.executors.local_executor.LocalExecutor", True, True,
["scheduler"]),
- ("LocalExecutor", False, False, []),
- ("CeleryExecutor,KubernetesExecutor", True, True, ["scheduler",
"worker"]),
- (
-
"CeleryExecutor,airflow.providers.cncf.kubernetes.executors.kubernetes_executor.KubernetesExecutor",
- True,
- True,
- ["scheduler", "worker"],
- ),
- ],
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
)
- def test_job_launcher_rolebinding(self, executor, rbac, allow,
expected_accounts):
+ def test_should_not_render(self, rbac, allow, executor):
+ docs = render_chart(
+ values={"rbac": {"create": rbac}, "allowJobLaunching": allow,
"executor": executor},
+ show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
+ )
+
+ assert len(docs) == 0
+
+ def test_multi_namespace_mode_disabled(self):
docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True}, "allowJobLaunching": True,
"multiNamespaceMode": False},
+ show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("kind", docs[0]) == "RoleBinding"
+
+ role_ref = jmespath.search("roleRef", docs[0])
+ assert role_ref["kind"] == "Role"
+ assert role_ref["name"] == "prod-job-launcher-role"
+
+ metadata = jmespath.search("metadata", docs[0])
+ assert metadata["namespace"] == "airflow"
+ assert metadata["name"] == "prod-job-launcher-rolebinding"
+ assert "namespace" not in metadata["labels"]
+
+ def test_multi_namespace_mode_enabled(self):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True}, "allowJobLaunching": True,
"multiNamespaceMode": True},
+ show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("kind", docs[0]) == "ClusterRoleBinding"
+
+ role_ref = jmespath.search("roleRef", docs[0])
+ assert role_ref["kind"] == "ClusterRole"
+ assert role_ref["name"] == "airflow-prod-job-launcher-role"
+
+ metadata = jmespath.search("metadata", docs[0])
+ assert "namespace" not in metadata
+ assert metadata["name"] == "airflow-prod-job-launcher-rolebinding"
+ assert metadata["labels"]["namespace"] == "airflow"
+
+ @pytest.mark.parametrize(
+ "executor", ["LocalExecutor", "KubernetesExecutor",
"KubernetesExecutor,LocalExecutor,CeleryExecutor"]
+ )
+ def test_scheduler_role_binding_should_exists(self, executor):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
values={
- "rbac": {"create": rbac},
- "allowJobLaunching": allow,
+ "rbac": {"create": True},
+ "allowJobLaunching": True,
"executor": executor,
+ "scheduler": {"enabled": True},
},
show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
)
- if expected_accounts:
- for idx, suffix in enumerate(expected_accounts):
- assert f"release-name-airflow-{suffix}" ==
jmespath.search(f"subjects[{idx}].name", docs[0])
- else:
- assert docs == []
+
+ assert jmespath.search("subjects[?name=='prod-airflow-scheduler'] |
[0]", docs[0]) == {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-scheduler",
+ "namespace": "airflow",
+ }
@pytest.mark.parametrize(
- ("multiNamespaceMode", "namespace", "expectedRole",
"expectedRoleBinding"),
+ ("executor", "enabled"),
[
- (
- True,
- "namespace",
- "namespace-release-name-job-launcher-role",
- "namespace-release-name-job-launcher-rolebinding",
- ),
- (
- True,
- "other-ns",
- "other-ns-release-name-job-launcher-role",
- "other-ns-release-name-job-launcher-rolebinding",
- ),
- (False, "namespace", "release-name-job-launcher-role",
"release-name-job-launcher-rolebinding"),
+ ("CeleryExecutor", False),
+ ("CeleryExecutor", True),
+ ("KubernetesExecutor", False),
+ ("LocalExecutor,CeleryExecutor", False),
],
)
- def test_job_launcher_rolebinding_multi_namespace(
- self, multiNamespaceMode, namespace, expectedRole, expectedRoleBinding
- ):
+ def test_scheduler_role_binding_should_not_exists(self, executor, enabled):
docs = render_chart(
- namespace=namespace,
- values={"allowJobLaunching": True, "multiNamespaceMode":
multiNamespaceMode},
+ name="prod",
+ values={
+ "rbac": {"create": True},
+ "allowJobLaunching": True,
+ "executor": executor,
+ "scheduler": {"enabled": enabled},
+ },
show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
)
- actualRoleBinding = jmespath.search("metadata.name", docs[0])
- assert actualRoleBinding == expectedRoleBinding
-
- actualRoleRef = jmespath.search("roleRef.name", docs[0])
- assert actualRoleRef == expectedRole
-
- actualKind = jmespath.search("kind", docs[0])
- actualRoleRefKind = jmespath.search("roleRef.kind", docs[0])
- if multiNamespaceMode:
- assert actualKind == "ClusterRoleBinding"
- assert actualRoleRefKind == "ClusterRole"
- else:
- assert actualKind == "RoleBinding"
- assert actualRoleRefKind == "Role"
+ assert jmespath.search("subjects[?name=='prod-airflow-scheduler']",
docs[0]) == []
@pytest.mark.parametrize(
- ("multiNamespaceMode", "namespace", "expectedRole"),
- [
- (True, "namespace", "namespace-release-name-job-launcher-role"),
- (True, "other-ns", "other-ns-release-name-job-launcher-role"),
- (False, "namespace", "release-name-job-launcher-role"),
- ],
+ "executor", ["CeleryExecutor", "KubernetesExecutor",
"LocalExecutor,CeleryExecutor"]
)
- def test_job_launcher_role_multi_namespace(self, multiNamespaceMode,
namespace, expectedRole):
+ def test_worker_role_binding_should_exists(self, executor):
docs = render_chart(
- namespace=namespace,
- values={"allowJobLaunching": True, "multiNamespaceMode":
multiNamespaceMode},
- show_only=["templates/rbac/job-launcher-role.yaml"],
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True}, "allowJobLaunching": True,
"executor": executor},
+ show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("subjects[?name=='prod-airflow-worker'] | [0]",
docs[0]) == {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-worker",
+ "namespace": "airflow",
+ }
+
+ def test_worker_role_binding_should_not_exists(self):
+ docs = render_chart(
+ name="prod",
+ values={"rbac": {"create": True}, "allowJobLaunching": True,
"executor": "LocalExecutor"},
+ show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
)
- actualRole = jmespath.search("metadata.name", docs[0])
- assert actualRole == expectedRole
+ assert jmespath.search("subjects[?name=='prod-airflow-worker']",
docs[0]) == []
+
+ def test_no_role_bindings(self):
+ docs = render_chart(
+ name="prod",
+ values={
+ "rbac": {"create": True},
+ "allowJobLaunching": True,
+ "executor": "LocalExecutor",
+ "scheduler": {"enabled": False},
+ },
+ show_only=["templates/rbac/job-launcher-rolebinding.yaml"],
+ )
- actualKind = jmespath.search("kind", docs[0])
- if multiNamespaceMode:
- assert actualKind == "ClusterRole"
- else:
- assert actualKind == "Role"
+ assert jmespath.search("subjects[?name=='prod-airflow-scheduler']",
docs[0]) is None
diff --git a/chart/tests/helm_tests/airflow_aux/test_pod_launcher_role.py
b/chart/tests/helm_tests/airflow_aux/test_pod_launcher_role.py
index 3645d5850cf..56bb333f238 100644
--- a/chart/tests/helm_tests/airflow_aux/test_pod_launcher_role.py
+++ b/chart/tests/helm_tests/airflow_aux/test_pod_launcher_role.py
@@ -22,114 +22,193 @@ from chart_utils.helm_template_generator import
render_chart
class TestPodLauncher:
- """Tests pod launcher."""
+ @pytest.mark.parametrize(
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
+ )
+ def test_should_render(self, executor):
+ docs = render_chart(
+ values={"rbac": {"create": True}, "allowPodLaunching": True,
"executor": executor},
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
+ assert len(docs) == 1
+
+ @pytest.mark.parametrize(("rbac", "allow"), [(True, False), (False, True),
(False, False)])
@pytest.mark.parametrize(
- ("executor", "rbac", "allow", "expected_accounts"),
- [
- ("KubernetesExecutor", True, True, ["scheduler", "worker"]),
- (
-
"airflow.providers.cncf.kubernetes.executors.kubernetes_executor.KubernetesExecutor",
- True,
- True,
- ["scheduler", "worker"],
- ),
- ("CeleryExecutor", True, True, ["worker"]),
- (
-
"airflow.providers.celery.executors.celery_executor.CeleryExecutor",
- True,
- True,
- ["worker"],
- ),
- ("LocalExecutor", True, True, ["scheduler"]),
- ("airflow.executors.local_executor.LocalExecutor", True, True,
["scheduler"]),
- ("LocalExecutor", False, False, []),
- ("CeleryExecutor,KubernetesExecutor", True, True, ["scheduler",
"worker"]),
- (
-
"CeleryExecutor,airflow.providers.cncf.kubernetes.executors.kubernetes_executor.KubernetesExecutor",
- True,
- True,
- ["scheduler", "worker"],
- ),
- ],
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
)
- def test_pod_launcher_role(self, executor, rbac, allow, expected_accounts):
+ def test_should_not_render(self, rbac, allow, executor):
docs = render_chart(
+ values={"rbac": {"create": rbac}, "allowPodLaunching": allow,
"executor": executor},
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
+
+ assert len(docs) == 0
+
+ def test_multi_namespace_mode_disabled(self):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True}, "allowPodLaunching": True,
"multiNamespaceMode": False},
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("kind", docs[0]) == "RoleBinding"
+
+ role_ref = jmespath.search("roleRef", docs[0])
+ assert role_ref["kind"] == "Role"
+ assert role_ref["name"] == "prod-pod-launcher-role"
+
+ metadata = jmespath.search("metadata", docs[0])
+ assert metadata["namespace"] == "airflow"
+ assert metadata["name"] == "prod-pod-launcher-rolebinding"
+ assert "namespace" not in metadata["labels"]
+
+ def test_multi_namespace_mode_enabled(self):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True}, "allowPodLaunching": True,
"multiNamespaceMode": True},
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("kind", docs[0]) == "ClusterRoleBinding"
+
+ role_ref = jmespath.search("roleRef", docs[0])
+ assert role_ref["kind"] == "ClusterRole"
+ assert role_ref["name"] == "airflow-prod-pod-launcher-role"
+
+ metadata = jmespath.search("metadata", docs[0])
+ assert "namespace" not in metadata
+ assert metadata["name"] == "airflow-prod-pod-launcher-rolebinding"
+ assert metadata["labels"]["namespace"] == "airflow"
+
+ @pytest.mark.parametrize(
+ "executor", ["LocalExecutor", "KubernetesExecutor",
"KubernetesExecutor,LocalExecutor,CeleryExecutor"]
+ )
+ def test_scheduler_role_binding_should_exists(self, executor):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
values={
- "rbac": {"create": rbac},
- "allowPodLaunching": allow,
+ "rbac": {"create": True},
+ "allowPodLaunching": True,
"executor": executor,
+ "scheduler": {"enabled": True},
},
show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
)
- if expected_accounts:
- for idx, suffix in enumerate(expected_accounts):
- assert f"release-name-airflow-{suffix}" ==
jmespath.search(f"subjects[{idx}].name", docs[0])
- else:
- assert docs == []
+
+ assert jmespath.search("subjects[?name=='prod-airflow-scheduler'] |
[0]", docs[0]) == {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-scheduler",
+ "namespace": "airflow",
+ }
@pytest.mark.parametrize(
- ("multiNamespaceMode", "namespace", "expectedRole",
"expectedRoleBinding"),
+ ("executor", "enabled"),
[
- (
- True,
- "namespace",
- "namespace-release-name-pod-launcher-role",
- "namespace-release-name-pod-launcher-rolebinding",
- ),
- (
- True,
- "other-ns",
- "other-ns-release-name-pod-launcher-role",
- "other-ns-release-name-pod-launcher-rolebinding",
- ),
- (False, "namespace", "release-name-pod-launcher-role",
"release-name-pod-launcher-rolebinding"),
+ ("CeleryExecutor", False),
+ ("CeleryExecutor", True),
+ ("LocalExecutor", False),
+ ("KubernetesExecutor", False),
+ ("LocalExecutor,CeleryExecutor", False),
],
)
- def test_pod_launcher_rolebinding_multi_namespace(
- self, multiNamespaceMode, namespace, expectedRole, expectedRoleBinding
- ):
+ def test_scheduler_role_binding_should_not_exists(self, executor, enabled):
docs = render_chart(
- namespace=namespace,
- values={"multiNamespaceMode": multiNamespaceMode},
+ name="prod",
+ values={
+ "rbac": {"create": True},
+ "allowPodLaunching": True,
+ "executor": executor,
+ "scheduler": {"enabled": enabled},
+ },
show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
)
- actualRoleBinding = jmespath.search("metadata.name", docs[0])
- assert actualRoleBinding == expectedRoleBinding
+ assert jmespath.search("subjects[?name=='prod-airflow-scheduler']",
docs[0]) == []
- actualRoleRef = jmespath.search("roleRef.name", docs[0])
- assert actualRoleRef == expectedRole
+ @pytest.mark.parametrize(
+ "executor", ["CeleryExecutor", "KubernetesExecutor",
"LocalExecutor,CeleryExecutor"]
+ )
+ def test_worker_role_binding_should_exists(self, executor):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True}, "allowPodLaunching": True,
"executor": executor},
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("subjects[?name=='prod-airflow-worker'] | [0]",
docs[0]) == {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-worker",
+ "namespace": "airflow",
+ }
+
+ def test_worker_role_binding_should_not_exists(self):
+ docs = render_chart(
+ name="prod",
+ values={"rbac": {"create": True}, "allowPodLaunching": True,
"executor": "LocalExecutor"},
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
- actualKind = jmespath.search("kind", docs[0])
- actualRoleRefKind = jmespath.search("roleRef.kind", docs[0])
- if multiNamespaceMode:
- assert actualKind == "ClusterRoleBinding"
- assert actualRoleRefKind == "ClusterRole"
- else:
- assert actualKind == "RoleBinding"
- assert actualRoleRefKind == "Role"
+ assert jmespath.search("subjects[?name=='prod-airflow-worker']",
docs[0]) == []
@pytest.mark.parametrize(
- ("multiNamespaceMode", "namespace", "expectedRole"),
- [
- (True, "namespace", "namespace-release-name-pod-launcher-role"),
- (True, "other-ns", "other-ns-release-name-pod-launcher-role"),
- (False, "namespace", "release-name-pod-launcher-role"),
- ],
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
+ )
+ def test_triggerer_role_binding_should_exists(self, executor):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={
+ "rbac": {"create": True},
+ "allowPodLaunching": True,
+ "executor": executor,
+ "triggerer": {"enabled": True},
+ },
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("subjects[?name=='prod-airflow-triggerer'] |
[0]", docs[0]) == {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-triggerer",
+ "namespace": "airflow",
+ }
+
+ @pytest.mark.parametrize(
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
)
- def test_pod_launcher_role_multi_namespace(self, multiNamespaceMode,
namespace, expectedRole):
+ def test_triggerer_role_binding_should_not_exists(self, executor):
docs = render_chart(
- namespace=namespace,
- values={"multiNamespaceMode": multiNamespaceMode},
- show_only=["templates/rbac/pod-launcher-role.yaml"],
+ name="prod",
+ values={
+ "rbac": {"create": True},
+ "allowPodLaunching": True,
+ "executor": executor,
+ "triggerer": {"enabled": False},
+ },
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
)
- actualRole = jmespath.search("metadata.name", docs[0])
- assert actualRole == expectedRole
+ assert jmespath.search("subjects[?name=='prod-airflow-triggerer']",
docs[0]) == []
+
+ def test_no_role_bindings(self):
+ docs = render_chart(
+ name="prod",
+ values={
+ "rbac": {"create": True},
+ "allowPodLaunching": True,
+ "executor": "LocalExecutor",
+ "scheduler": {"enabled": False},
+ "triggerer": {"enabled": False},
+ },
+ show_only=["templates/rbac/pod-launcher-rolebinding.yaml"],
+ )
- actualKind = jmespath.search("kind", docs[0])
- if multiNamespaceMode:
- assert actualKind == "ClusterRole"
- else:
- assert actualKind == "Role"
+ assert jmespath.search("subjects[?name=='prod-airflow-scheduler']",
docs[0]) is None
diff --git a/chart/tests/helm_tests/security/test_scc_rolebinding.py
b/chart/tests/helm_tests/security/test_scc_rolebinding.py
index 60fe24ade97..6c50b1cb04e 100644
--- a/chart/tests/helm_tests/security/test_scc_rolebinding.py
+++ b/chart/tests/helm_tests/security/test_scc_rolebinding.py
@@ -24,16 +24,81 @@ from chart_utils.helm_template_generator import render_chart
class TestSCCActivation:
"""Tests SCCs."""
- def test_zero_subjects_when_all_disabled(self):
+ @pytest.mark.parametrize(
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
+ )
+ def test_should_render(self, executor):
+ docs = render_chart(
+ values={"rbac": {"create": True, "createSCCRoleBinding": True},
"executor": executor},
+
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
+ )
+
+ assert len(docs) == 1
+
+ @pytest.mark.parametrize(("create", "role_binding"), [(True, False),
(False, True), (False, False)])
+ @pytest.mark.parametrize(
+ "executor",
+ ["LocalExecutor", "CeleryExecutor", "KubernetesExecutor",
"CeleryExecutor,KubernetesExecutor"],
+ )
+ def test_should_not_render(self, create, role_binding, executor):
+ docs = render_chart(
+ values={"rbac": {"create": create, "createSCCRoleBinding":
role_binding}, "executor": executor},
+
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
+ )
+
+ assert len(docs) == 0
+
+ def test_multi_namespace_mode_disabled(self):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True, "createSCCRoleBinding": True},
"multiNamespaceMode": False},
+
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("kind", docs[0]) == "RoleBinding"
+
+ metadata = jmespath.search("metadata", docs[0])
+ assert metadata["namespace"] == "airflow"
+ assert metadata["name"] == "prod-scc-rolebinding"
+ assert "namespace" not in metadata["labels"]
+
+ def test_multi_namespace_mode_enabled(self):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True, "createSCCRoleBinding": True},
"multiNamespaceMode": True},
+
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("kind", docs[0]) == "ClusterRoleBinding"
+
+ metadata = jmespath.search("metadata", docs[0])
+ assert "namespace" not in metadata
+ assert metadata["name"] == "airflow-prod-scc-rolebinding"
+ assert metadata["labels"]["namespace"] == "airflow"
+
+ def test_role_ref_default(self):
+ docs = render_chart(
+ values={"rbac": {"create": True, "createSCCRoleBinding": True}},
+
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("roleRef", docs[0]) == {
+ "apiGroup": "rbac.authorization.k8s.io",
+ "kind": "ClusterRole",
+ "name": "system:openshift:scc:anyuid",
+ }
+
+ def test_no_role_bindings(self):
docs = render_chart(
values={
- "multiNamespaceMode": False,
+ "rbac": {"create": True, "createSCCRoleBinding": True},
"executor": "LocalExecutor",
- "data": {"brokerUrlSecretName": "test"},
"cleanup": {"enabled": False},
"databaseCleanup": {"enabled": False},
"flower": {"enabled": False},
- "rbac": {"create": True, "createSCCRoleBinding": True},
"dagProcessor": {"enabled": False},
"apiServer": {"enabled": False},
"scheduler": {"enabled": False},
@@ -46,104 +111,142 @@ class TestSCCActivation:
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
)
- assert jmespath.search("kind", docs[0]) == "RoleBinding"
- assert jmespath.search("roleRef.kind", docs[0]) == "ClusterRole"
- assert jmespath.search("metadata.name", docs[0]) ==
"release-name-scc-rolebinding"
- assert jmespath.search("roleRef.name", docs[0]) ==
"system:openshift:scc:anyuid"
assert jmespath.search("subjects", docs[0]) is None
@pytest.mark.parametrize(
- ("rbac_enabled", "scc_enabled", "created"),
- [
- (False, False, False),
- (False, True, False),
- (True, True, True),
- (True, False, False),
- ],
+ "executor", ["CeleryExecutor", "KubernetesExecutor",
"LocalExecutor,CeleryExecutor"]
)
- def test_create_scc(self, rbac_enabled, scc_enabled, created):
+ def test_worker_role_binding_should_exists(self, executor):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
+ values={"rbac": {"create": True, "createSCCRoleBinding": True},
"executor": executor},
+
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("subjects[?name=='prod-airflow-worker'] | [0]",
docs[0]) == {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-worker",
+ "namespace": "airflow",
+ }
+
+ def test_worker_role_binding_should_not_exists(self):
docs = render_chart(
+ name="prod",
+ values={"rbac": {"create": True, "createSCCRoleBinding": True},
"executor": "LocalExecutor"},
+
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
+ )
+
+ assert jmespath.search("subjects[?name=='prod-airflow-worker']",
docs[0]) == []
+
+ @pytest.mark.parametrize("executor", ["CeleryExecutor",
"LocalExecutor,CeleryExecutor"])
+ def test_flower_role_binding_should_exists(self, executor):
+ docs = render_chart(
+ name="prod",
+ namespace="airflow",
values={
- "multiNamespaceMode": False,
- "cleanup": {"enabled": True},
- "databaseCleanup": {"enabled": True},
+ "rbac": {"create": True, "createSCCRoleBinding": True},
+ "executor": executor,
"flower": {"enabled": True},
- "rbac": {"create": rbac_enabled, "createSCCRoleBinding":
scc_enabled},
},
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
)
- assert bool(docs) is created
- if created:
- assert jmespath.search("kind", docs[0]) == "RoleBinding"
- assert jmespath.search("roleRef.kind", docs[0]) == "ClusterRole"
- assert jmespath.search("metadata.name", docs[0]) ==
"release-name-scc-rolebinding"
- assert jmespath.search("roleRef.name", docs[0]) ==
"system:openshift:scc:anyuid"
- assert jmespath.search("subjects | [*].name", docs[0]) == [
- "release-name-airflow-worker",
- "release-name-airflow-scheduler",
- "release-name-airflow-api-server",
- "release-name-airflow-statsd",
- "release-name-airflow-flower",
- "release-name-airflow-redis",
- "release-name-airflow-triggerer",
- "release-name-airflow-migrate-database-job",
- "release-name-airflow-create-user-job",
- "release-name-airflow-cleanup",
- "release-name-airflow-database-cleanup",
- "release-name-airflow-dag-processor",
- ]
+ assert jmespath.search("subjects[?name=='prod-airflow-flower'] | [0]",
docs[0]) == {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-flower",
+ "namespace": "airflow",
+ }
@pytest.mark.parametrize(
- ("namespace", "expected_name"),
+ ("executor", "enabled"),
[
- ("default", "default-release-name-scc-rolebinding"),
- ("other-ns", "other-ns-release-name-scc-rolebinding"),
+ ("LocalExecutor", True),
+ ("LocalExecutor", False),
+ ("KubernetesExecutor", True),
+ ("KubernetesExecutor", False),
+ ("CeleryExecutor", False),
],
)
- def test_create_scc_multinamespace(self, namespace, expected_name):
+ def test_flower_role_binding_should_not_exists(self, executor, enabled):
docs = render_chart(
- namespace=namespace,
+ name="prod",
values={
- "multiNamespaceMode": True,
- "createUserJob": {"enabled": False},
- "cleanup": {"enabled": False},
- "databaseCleanup": {"enabled": False},
- "flower": {"enabled": False},
"rbac": {"create": True, "createSCCRoleBinding": True},
+ "executor": executor,
+ "flower": {"enabled": enabled},
},
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
)
- assert jmespath.search("kind", docs[0]) == "ClusterRoleBinding"
- assert jmespath.search("roleRef.kind", docs[0]) == "ClusterRole"
- assert expected_name == jmespath.search("metadata.name", docs[0])
- assert jmespath.search("roleRef.name", docs[0]) ==
"system:openshift:scc:anyuid"
+ assert jmespath.search("subjects[?name=='prod-airflow-flower']",
docs[0]) == []
- def test_create_scc_worker_only(self):
+ @pytest.mark.parametrize(
+ "executor",
+ [
+ "LocalExecutor",
+ "KubernetesExecutor",
+ "CeleryExecutor",
+ "KubernetesExecutor,LocalExecutor,CeleryExecutor",
+ ],
+ )
+ def test_only_enable_components_role_binding_should_exists(self, executor):
docs = render_chart(
+ name="prod",
+ namespace="airflow",
values={
- "multiNamespaceMode": False,
- "createUserJob": {"enabled": False},
- "cleanup": {"enabled": False},
- "databaseCleanup": {"enabled": False},
- "flower": {"enabled": False},
- "statsd": {"enabled": False},
"rbac": {"create": True, "createSCCRoleBinding": True},
+ "executor": executor,
+ "scheduler": {"enabled": True},
+ "apiServer": {"enabled": True},
+ "statsd": {"enabled": True},
+ "redis": {"enabled": True},
+ "triggerer": {"enabled": True},
+ "migrateDatabaseJob": {"enabled": True},
+ "createUserJob": {"enabled": True},
+ "cleanup": {"enabled": True},
+ "databaseCleanup": {"enabled": True},
+ "dagProcessor": {"enabled": True},
},
show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"],
)
- assert jmespath.search("kind", docs[0]) == "RoleBinding"
- assert jmespath.search("roleRef.kind", docs[0]) == "ClusterRole"
- assert jmespath.search("metadata.name", docs[0]) ==
"release-name-scc-rolebinding"
- assert jmespath.search("roleRef.name", docs[0]) ==
"system:openshift:scc:anyuid"
- assert jmespath.search("subjects | [*].name", docs[0]) == [
- "release-name-airflow-worker",
- "release-name-airflow-scheduler",
- "release-name-airflow-api-server",
- "release-name-airflow-redis",
- "release-name-airflow-triggerer",
- "release-name-airflow-migrate-database-job",
- "release-name-airflow-dag-processor",
- ]
+ subjects = jmespath.search("subjects", docs[0])
+ assert {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-scheduler",
+ "namespace": "airflow",
+ } in subjects
+ assert {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-api-server",
+ "namespace": "airflow",
+ } in subjects
+ assert {"kind": "ServiceAccount", "name": "prod-airflow-statsd",
"namespace": "airflow"} in subjects
+ assert {"kind": "ServiceAccount", "name": "prod-airflow-redis",
"namespace": "airflow"} in subjects
+ assert {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-triggerer",
+ "namespace": "airflow",
+ } in subjects
+ assert {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-migrate-database-job",
+ "namespace": "airflow",
+ } in subjects
+ assert {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-create-user-job",
+ "namespace": "airflow",
+ } in subjects
+ assert {"kind": "ServiceAccount", "name": "prod-airflow-cleanup",
"namespace": "airflow"} in subjects
+ assert {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-database-cleanup",
+ "namespace": "airflow",
+ } in subjects
+ assert {
+ "kind": "ServiceAccount",
+ "name": "prod-airflow-dag-processor",
+ "namespace": "airflow",
+ } in subjects