From 6ed2d7e66081a8347b064e0f69d20dd74d8486c0 Mon Sep 17 00:00:00 2001 From: Jed Cunningham Date: Wed, 18 Feb 2026 11:06:47 -0700 Subject: [PATCH] Fix webserver.defaultUser.enabled=false not honored When webserver.defaultUser.enabled was set to false, the create-user job still ran because createUserJob.enabled defaults to true and the OR condition let it through. This adds a helper template that gives the deprecated webserver.defaultUser precedence when present, only falling back to createUserJob.enabled otherwise. Also fixes NOTES.txt to display credentials from the correct source. --- chart/templates/NOTES.txt | 10 +-- chart/templates/_helpers.yaml | 13 ++++ chart/templates/jobs/create-user-job.yaml | 2 +- ...curity-context-constraint-rolebinding.yaml | 2 +- .../airflow_aux/test_create_user_job.py | 63 +++++++++++++++++++ .../security/test_scc_rolebinding.py | 29 +++++++++ 6 files changed, 110 insertions(+), 9 deletions(-) diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt index 0d4c29c7bb3d7..39614d1f454c0 100644 --- a/chart/templates/NOTES.txt +++ b/chart/templates/NOTES.txt @@ -114,14 +114,10 @@ Flower Dashboard: kubectl port-forward svc/{{ include "airflow.fullname" . {{- end }} -{{- if and .Values.webserver.defaultUser .Values.webserver.defaultUser.enabled}} +{{- if eq (include "createUserJob.isEnabled" .) "true" }} Default user (Airflow UI) Login credentials: - username: {{ .Values.createUserJob.defaultUser.username }} - password: {{ .Values.createUserJob.defaultUser.password }} -{{- else if .Values.createUserJob.enabled}} -Default user (Airflow UI) Login credentials: - username: {{ .Values.createUserJob.defaultUser.username }} - password: {{ .Values.createUserJob.defaultUser.password }} + username: {{ if .Values.webserver.defaultUser }}{{ .Values.webserver.defaultUser.username }}{{ else }}{{ .Values.createUserJob.defaultUser.username }}{{ end }} + password: {{ if .Values.webserver.defaultUser }}{{ .Values.webserver.defaultUser.password }}{{ else }}{{ .Values.createUserJob.defaultUser.password }}{{ end }} {{- end }} {{- if .Values.postgresql.enabled }} diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml index 82326ca2ead73..49106961b6c66 100644 --- a/chart/templates/_helpers.yaml +++ b/chart/templates/_helpers.yaml @@ -1168,6 +1168,19 @@ Usage: {{- $result -}} {{- end -}} +{{/* +Determine if the create-user job should be enabled. +When webserver.defaultUser is set (deprecated), it takes precedence to preserve +backwards compatibility. Otherwise, fall back to createUserJob.enabled. +*/}} +{{- define "createUserJob.isEnabled" -}} + {{- if .Values.webserver.defaultUser -}} + {{- .Values.webserver.defaultUser.enabled -}} + {{- else -}} + {{- .Values.createUserJob.enabled -}} + {{- end -}} +{{- end -}} + {{/* Convert dagBundleConfigList YAML list to JSON string for dag_bundle_config_list. This helper function converts the structured YAML format to the JSON string diff --git a/chart/templates/jobs/create-user-job.yaml b/chart/templates/jobs/create-user-job.yaml index 0a58b50ce0098..6626fb7ff5ba5 100644 --- a/chart/templates/jobs/create-user-job.yaml +++ b/chart/templates/jobs/create-user-job.yaml @@ -20,7 +20,7 @@ ########################## ## Airflow Create User Job ########################## -{{- if or (and .Values.webserver.defaultUser .Values.webserver.defaultUser.enabled) .Values.createUserJob.enabled }} +{{- if eq (include "createUserJob.isEnabled" .) "true" }} {{- $nodeSelector := or .Values.createUserJob.nodeSelector .Values.nodeSelector }} {{- $affinity := or .Values.createUserJob.affinity .Values.affinity }} {{- $tolerations := or .Values.createUserJob.tolerations .Values.tolerations }} diff --git a/chart/templates/rbac/security-context-constraint-rolebinding.yaml b/chart/templates/rbac/security-context-constraint-rolebinding.yaml index 8e01246bd564d..4754461718437 100644 --- a/chart/templates/rbac/security-context-constraint-rolebinding.yaml +++ b/chart/templates/rbac/security-context-constraint-rolebinding.yaml @@ -88,7 +88,7 @@ subjects: - kind: ServiceAccount name: {{ include "migrateDatabaseJob.serviceAccountName" . }} namespace: "{{ .Release.Namespace }}" - {{- if or (and .Values.webserver.defaultUser .Values.webserver.defaultUser.enabled) .Values.createUserJob.enabled }} + {{- if eq (include "createUserJob.isEnabled" .) "true" }} - kind: ServiceAccount name: {{ include "createUserJob.serviceAccountName" . }} namespace: "{{ .Release.Namespace }}" diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_create_user_job.py b/helm-tests/tests/helm_tests/airflow_aux/test_create_user_job.py index 91a9ab338d39b..c87f7269a5dc1 100644 --- a/helm-tests/tests/helm_tests/airflow_aux/test_create_user_job.py +++ b/helm-tests/tests/helm_tests/airflow_aux/test_create_user_job.py @@ -486,6 +486,69 @@ def test_should_create_job_when_createuserjob_enabled(self): assert len(docs) == 1 assert docs[0]["kind"] == "Job" + def test_should_not_create_job_when_deprecated_default_user_disabled(self): + """Setting webserver.defaultUser.enabled=false must suppress job even with createUserJob.enabled default.""" + docs = render_chart( + values={ + "webserver": { + "defaultUser": { + "enabled": False, + "role": "Admin", + "username": "admin", + "email": "admin@example.com", + "firstName": "admin", + "lastName": "user", + "password": "admin", + } + } + }, + show_only=["templates/jobs/create-user-job.yaml"], + ) + assert len(docs) == 0 + + def test_should_create_job_when_deprecated_default_user_enabled(self): + """Setting webserver.defaultUser.enabled=true should create the job.""" + docs = render_chart( + values={ + "webserver": { + "defaultUser": { + "enabled": True, + "role": "Admin", + "username": "admin", + "email": "admin@example.com", + "firstName": "admin", + "lastName": "user", + "password": "admin", + } + } + }, + show_only=["templates/jobs/create-user-job.yaml"], + ) + assert len(docs) == 1 + assert docs[0]["kind"] == "Job" + + def test_deprecated_default_user_enabled_overrides_createuserjob_disabled(self): + """webserver.defaultUser.enabled=true takes precedence over createUserJob.enabled=false.""" + docs = render_chart( + values={ + "createUserJob": {"enabled": False}, + "webserver": { + "defaultUser": { + "enabled": True, + "role": "Admin", + "username": "admin", + "email": "admin@example.com", + "firstName": "admin", + "lastName": "user", + "password": "admin", + } + }, + }, + show_only=["templates/jobs/create-user-job.yaml"], + ) + assert len(docs) == 1 + assert docs[0]["kind"] == "Job" + class TestCreateUserJobServiceAccount: """Tests create user job service account.""" diff --git a/helm-tests/tests/helm_tests/security/test_scc_rolebinding.py b/helm-tests/tests/helm_tests/security/test_scc_rolebinding.py index ae39752d8cfe8..e40bb909bebf0 100644 --- a/helm-tests/tests/helm_tests/security/test_scc_rolebinding.py +++ b/helm-tests/tests/helm_tests/security/test_scc_rolebinding.py @@ -128,3 +128,32 @@ def test_create_scc_worker_only(self, rbac_enabled, scc_enabled, created): assert jmespath.search("subjects[5].name", docs[0]) == "release-name-airflow-triggerer" assert jmespath.search("subjects[6].name", docs[0]) == "release-name-airflow-migrate-database-job" assert len(docs[0]["subjects"]) == 7 + + def test_deprecated_default_user_disabled_excludes_create_user_subject(self): + """webserver.defaultUser.enabled=false should exclude the create-user-job service account.""" + docs = render_chart( + values={ + "multiNamespaceMode": False, + "cleanup": {"enabled": False}, + "databaseCleanup": {"enabled": False}, + "flower": {"enabled": False}, + "statsd": {"enabled": False}, + "rbac": {"create": True, "createSCCRoleBinding": True}, + "webserver": { + "defaultUser": { + "enabled": False, + "role": "Admin", + "username": "admin", + "email": "admin@example.com", + "firstName": "admin", + "lastName": "user", + "password": "admin", + } + }, + }, + show_only=["templates/rbac/security-context-constraint-rolebinding.yaml"], + ) + + assert len(docs) == 1 + subject_names = [s["name"] for s in docs[0]["subjects"]] + assert "release-name-airflow-create-user-job" not in subject_names