This is an automated email from the ASF dual-hosted git repository.

Miretpl pushed a commit to branch chart/v1-2x-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/chart/v1-2x-test by this push:
     new 509c2fed309 [chart/v1-2x-test] Allow configuring key names in database 
credential secrets (#69954) (#70646)
509c2fed309 is described below

commit 509c2fed309640c7732d4f657dbf698111544bda
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Jul 28 23:23:00 2026 +0200

    [chart/v1-2x-test] Allow configuring key names in database credential 
secrets (#69954) (#70646)
    
    * Allow configuring key names in database credential secrets
    
    The chart hardcoded 'key: connection' in the secretKeyRef for the metadata, 
result backend, and broker URL env vars, so externally managed secrets using a 
different key (e.g. CloudNativePG's 'uri') could not be used with 
metadataSecretName and friends.
    
    Add data.metadataSecretKey, data.resultBackendSecretKey and 
data.brokerUrlSecretKey, defaulting to 'connection'. The custom key only 
applies when the corresponding *SecretName is provided, since chart-created 
secrets always write the 'connection' key.
    
    * Address review comments: clarify values and docs wording
    (cherry picked from commit dc75103d64cb2213ed2eed7c4dec40a755e585bf)
    
    Co-authored-by: Preetham Sanji 
<[email protected]>
---
 chart/docs/production-guide.rst                    | 15 ++++
 chart/templates/_helpers.yaml                      | 32 +++++++-
 chart/values.schema.json                           | 25 ++++++
 chart/values.yaml                                  | 11 +++
 .../helm_tests/airflow_aux/test_airflow_common.py  | 95 ++++++++++++++++++++++
 5 files changed, 174 insertions(+), 4 deletions(-)

diff --git a/chart/docs/production-guide.rst b/chart/docs/production-guide.rst
index 402088692eb..22f2f88923c 100644
--- a/chart/docs/production-guide.rst
+++ b/chart/docs/production-guide.rst
@@ -88,6 +88,21 @@ After secret creation, configure the chart to use the secret:
    data:
      metadataSecretName: mydatabase
 
+If your secret stores the connection string under a key other than 
``connection`` (for
+example, `CloudNativePG <https://cloudnative-pg.io/>`_ generates credential 
secrets with
+the connection URI under the ``uri`` key), set ``metadataSecretKey`` 
accordingly:
+
+.. code-block:: yaml
+   :caption: values.yaml
+
+   data:
+     metadataSecretName: mydatabase-app
+     metadataSecretKey: uri
+
+Similarly, ``resultBackendSecretKey`` and ``brokerUrlSecretKey`` configure the 
key names
+used with ``resultBackendSecretName`` and ``brokerUrlSecretName``. All of 
these default to
+``connection`` and only apply when the corresponding secret name is provided.
+
 .. _production-guide:pgbouncer:
 
 Metadata DB Cleanup
diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml
index 2f8bd7822cb..04f5516567a 100644
--- a/chart/templates/_helpers.yaml
+++ b/chart/templates/_helpers.yaml
@@ -75,14 +75,14 @@ If release name contains chart name it will be used as a 
full name.
     valueFrom:
       secretKeyRef:
         name: {{ template "airflow_metadata_secret" . }}
-        key: connection
+        key: {{ template "airflow_metadata_secret_key" . }}
   {{- end }}
   {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW_CONN_AIRFLOW_DB }}
   - name: AIRFLOW_CONN_AIRFLOW_DB
     valueFrom:
       secretKeyRef:
         name: {{ template "airflow_metadata_secret" . }}
-        key: connection
+        key: {{ template "airflow_metadata_secret_key" . }}
   {{- end }}
   {{- $kedaEnabled := .Values.workers.keda.enabled }}
   {{- $kedaUsePgBouncer := .Values.workers.keda.usePgbouncer }}
@@ -127,14 +127,14 @@ If release name contains chart name it will be used as a 
full name.
     valueFrom:
       secretKeyRef:
         name: {{ template "airflow_result_backend_secret" . }}
-        key: connection
+        key: {{ template "airflow_result_backend_secret_key" . }}
     {{- end }}
     {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__CELERY__BROKER_URL }}
   - name: AIRFLOW__CELERY__BROKER_URL
     valueFrom:
       secretKeyRef:
         name: {{ template "airflow_broker_url_secret" . }}
-        key: connection
+        key: {{ template "airflow_broker_url_secret_key" . }}
     {{- end }}
   {{- end }}
   {{- if and .Values.elasticsearch.enabled 
.Values.enableBuiltInSecretEnvVars.AIRFLOW__ELASTICSEARCH__HOST }}
@@ -486,6 +486,30 @@ If release name contains chart name it will be used as a 
full name.
   {{- default (printf "%s-result-backend" (include "airflow.fullname" .)) 
.Values.data.resultBackendSecretName }}
 {{- end }}
 
+{{- define "airflow_metadata_secret_key" -}}
+  {{- if .Values.data.metadataSecretName -}}
+    {{- .Values.data.metadataSecretKey | default "connection" -}}
+  {{- else -}}
+    connection
+  {{- end -}}
+{{- end }}
+
+{{- define "airflow_result_backend_secret_key" -}}
+  {{- if .Values.data.resultBackendSecretName -}}
+    {{- .Values.data.resultBackendSecretKey | default "connection" -}}
+  {{- else -}}
+    connection
+  {{- end -}}
+{{- end }}
+
+{{- define "airflow_broker_url_secret_key" -}}
+  {{- if .Values.data.brokerUrlSecretName -}}
+    {{- .Values.data.brokerUrlSecretKey | default "connection" -}}
+  {{- else -}}
+    connection
+  {{- end -}}
+{{- end }}
+
 {{- define "airflow_pod_template_file" -}}
   {{- printf "%s/pod_templates" .Values.airflowHome }}
 {{- end }}
diff --git a/chart/values.schema.json b/chart/values.schema.json
index e57cacdb7f0..236f63c8e2d 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -1447,6 +1447,14 @@
                     ],
                     "default": null
                 },
+                "metadataSecretKey": {
+                    "description": "Key in the metadata connection secret 
containing the connection string. Only used when `metadataSecretName` is set.",
+                    "type": [
+                        "string",
+                        "null"
+                    ],
+                    "default": null
+                },
                 "resultBackendSecretName": {
                     "description": "Result backend connection string secret.",
                     "type": [
@@ -1455,6 +1463,14 @@
                     ],
                     "default": null
                 },
+                "resultBackendSecretKey": {
+                    "description": "Key in the result backend connection 
secret containing the connection string. Only used when 
`resultBackendSecretName` is set.",
+                    "type": [
+                        "string",
+                        "null"
+                    ],
+                    "default": null
+                },
                 "brokerUrlSecretName": {
                     "description": "Redis broker URL secret.",
                     "type": [
@@ -1464,6 +1480,15 @@
                     "x-docsSection": "Redis",
                     "default": null
                 },
+                "brokerUrlSecretKey": {
+                    "description": "Key in the broker URL secret containing 
the broker URL. Only used when `brokerUrlSecretName` is set.",
+                    "type": [
+                        "string",
+                        "null"
+                    ],
+                    "x-docsSection": "Redis",
+                    "default": null
+                },
                 "metadataConnection": {
                     "description": "Metadata connection configuration.",
                     "type": "object",
diff --git a/chart/values.yaml b/chart/values.yaml
index b9d4b708510..7d848823458 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -511,13 +511,24 @@ data:
   #   postgresql+psycopg2://airflow:password@postgres/airflow
   metadataSecretName: ~
 
+  # When `metadataSecretName` is set, the key in that secret contains the 
connection string.
+  # Useful when the secret is managed externally, e.g. CloudNativePG stores 
the URI under the "uri" key.
+  metadataSecretKey: ~
+
   # If not set, falls back to metadataSecretName. The secret must contain 
'connection' key which is
   # a base64-encoded connection string, e.g.:
   #   postgresql+psycopg2://user:password@host/db
   resultBackendSecretName: ~
 
+  # When `resultBackendSecretName` is set, the key in that secret contains the 
result backend
+  # connection string.
+  resultBackendSecretKey: ~
+
   brokerUrlSecretName: ~
 
+  # When `brokerUrlSecretName` is set, the key in that secret contains the 
broker URL.
+  brokerUrlSecretKey: ~
+
   # If `metadataSecretName` is not specified, pass connection values below
   metadataConnection:
     user: postgres
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 adf348afa34..0f786a77fba 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
@@ -654,3 +654,98 @@ class TestAirflowCommon:
 
         for doc in docs:
             assert matcher(doc) == enable_service_links
+
+
+class TestDatabaseSecretKeys:
+    """Tests for configurable key names in database credential secrets."""
+
+    @staticmethod
+    def _secret_refs(doc):
+        env = jmespath.search("spec.template.spec.containers[0].env", doc)
+        return {
+            e["name"]: e["valueFrom"]["secretKeyRef"]
+            for e in env
+            if e.get("valueFrom", {}).get("secretKeyRef")
+        }
+
+    def test_metadata_secret_key_defaults_to_connection(self):
+        docs = render_chart(
+            values={"data": {"metadataSecretName": "my-metadata-secret"}},
+            show_only=["templates/scheduler/scheduler-deployment.yaml"],
+        )
+        refs = self._secret_refs(docs[0])
+        assert refs["AIRFLOW__DATABASE__SQL_ALCHEMY_CONN"]["key"] == 
"connection"
+        assert refs["AIRFLOW_CONN_AIRFLOW_DB"]["key"] == "connection"
+
+    def test_metadata_secret_key_custom(self):
+        docs = render_chart(
+            values={"data": {"metadataSecretName": "cnpg-cluster-app", 
"metadataSecretKey": "uri"}},
+            show_only=["templates/scheduler/scheduler-deployment.yaml"],
+        )
+        refs = self._secret_refs(docs[0])
+        for var in ("AIRFLOW__DATABASE__SQL_ALCHEMY_CONN", 
"AIRFLOW_CONN_AIRFLOW_DB"):
+            assert refs[var]["name"] == "cnpg-cluster-app"
+            assert refs[var]["key"] == "uri"
+
+    def test_metadata_secret_key_ignored_for_chart_created_secret(self):
+        docs = render_chart(
+            values={"data": {"metadataSecretKey": "uri"}},
+            show_only=["templates/scheduler/scheduler-deployment.yaml"],
+        )
+        refs = self._secret_refs(docs[0])
+        assert refs["AIRFLOW__DATABASE__SQL_ALCHEMY_CONN"]["key"] == 
"connection"
+        assert refs["AIRFLOW_CONN_AIRFLOW_DB"]["key"] == "connection"
+
+    def test_result_backend_secret_key_custom(self):
+        docs = render_chart(
+            values={
+                "executor": "CeleryExecutor",
+                "data": {"resultBackendSecretName": "my-rb-secret", 
"resultBackendSecretKey": "uri"},
+            },
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+        refs = self._secret_refs(docs[0])
+        assert refs["AIRFLOW__CELERY__RESULT_BACKEND"]["name"] == 
"my-rb-secret"
+        assert refs["AIRFLOW__CELERY__RESULT_BACKEND"]["key"] == "uri"
+
+    def test_result_backend_secret_key_ignored_for_chart_created_secret(self):
+        docs = render_chart(
+            values={
+                "executor": "CeleryExecutor",
+                "data": {
+                    "resultBackendConnection": {
+                        "user": "postgres",
+                        "pass": "postgres",
+                        "protocol": "postgresql",
+                        "host": "example",
+                        "port": 5432,
+                        "db": "postgres",
+                        "sslmode": "disable",
+                    },
+                    "resultBackendSecretKey": "uri",
+                },
+            },
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+        refs = self._secret_refs(docs[0])
+        assert refs["AIRFLOW__CELERY__RESULT_BACKEND"]["key"] == "connection"
+
+    def test_broker_url_secret_key_custom(self):
+        docs = render_chart(
+            values={
+                "executor": "CeleryExecutor",
+                "data": {"brokerUrlSecretName": "my-broker-secret", 
"brokerUrlSecretKey": "url"},
+            },
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+        refs = self._secret_refs(docs[0])
+        assert refs["AIRFLOW__CELERY__BROKER_URL"]["name"] == 
"my-broker-secret"
+        assert refs["AIRFLOW__CELERY__BROKER_URL"]["key"] == "url"
+
+    def test_broker_url_secret_key_ignored_for_chart_created_secret(self):
+        docs = render_chart(
+            values={"executor": "CeleryExecutor", "data": 
{"brokerUrlSecretKey": "url"}},
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+        refs = self._secret_refs(docs[0])
+        assert refs["AIRFLOW__CELERY__BROKER_URL"]["key"] == "connection"

Reply via email to