From 2055bb425ecb2d709583cf73f37385024497d705 Mon Sep 17 00:00:00 2001 From: Daniel Gellert Date: Sat, 8 Jun 2024 12:19:00 +0200 Subject: [PATCH] feat(chart): allow valueFrom in env config of components (#40095) --- chart/templates/_helpers.yaml | 26 ++ chart/values.schema.json | 320 +++++++++++++++++- .../airflow_aux/test_create_user_job.py | 20 +- .../airflow_aux/test_pod_template_file.py | 24 +- helm_tests/airflow_core/test_dag_processor.py | 20 +- helm_tests/airflow_core/test_scheduler.py | 20 +- helm_tests/airflow_core/test_triggerer.py | 20 +- helm_tests/airflow_core/test_worker.py | 20 +- helm_tests/other/test_flower.py | 20 +- helm_tests/webserver/test_webserver.py | 20 +- 10 files changed, 486 insertions(+), 24 deletions(-) diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml index 59a28fd9b7df4..df60f130b9138 100644 --- a/chart/templates/_helpers.yaml +++ b/chart/templates/_helpers.yaml @@ -1015,10 +1015,36 @@ capabilities: {{- $env := index . 1 -}} {{- range $i, $config := $env }} - name: {{ $config.name }} + {{- if $config.value }} value: {{ $config.value | quote }} + {{- else if $config.valueFrom }} + valueFrom: + {{- if $config.valueFrom.secretKeyRef }} + secretKeyRef: + name: {{ $config.valueFrom.secretKeyRef.name }} + key: {{ $config.valueFrom.secretKeyRef.key }} + {{- else if $config.valueFrom.configMapKeyRef }} + configMapKeyRef: + name: {{ $config.valueFrom.configMapKeyRef.name }} + key: {{ $config.valueFrom.configMapKeyRef.key }} + {{- end }} + {{- end }} {{- if or (eq $.Values.executor "KubernetesExecutor") (eq $.Values.executor "LocalKubernetesExecutor") (eq $.Values.executor "CeleryKubernetesExecutor") }} - name: AIRFLOW__KUBERNETES_ENVIRONMENT_VARIABLES__{{ $config.name }} + {{- if $config.value }} value: {{ $config.value | quote }} + {{- else if $config.valueFrom }} + valueFrom: + {{- if $config.valueFrom.secretKeyRef }} + secretKeyRef: + name: {{ $config.valueFrom.secretKeyRef.name }} + key: {{ $config.valueFrom.secretKeyRef.key }} + {{- else if $config.valueFrom.configMapKeyRef }} + configMapKeyRef: + name: {{ $config.valueFrom.configMapKeyRef.name }} + key: {{ $config.valueFrom.configMapKeyRef.key }} + {{- end }} + {{- end }} {{- end }} {{- end }} {{- end }} diff --git a/chart/values.schema.json b/chart/values.schema.json index 9e7a819aef1a0..8fe66ab8c1b9d 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -2144,11 +2144,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } @@ -2692,11 +2728,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } @@ -3163,11 +3235,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } @@ -3646,11 +3754,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } @@ -3951,11 +4095,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } @@ -4959,11 +5139,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } @@ -5452,11 +5668,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } @@ -7071,11 +7323,47 @@ }, "value": { "type": "string" + }, + "valueFrom": { + "type": "object", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "anyOf": [ + { + "required": [ + "configMapKeyRef" + ] + }, + { + "required": [ + "secretKeyRef" + ] + } + ] } }, "required": [ - "name", - "value" + "name" + ], + "anyOf": [ + { + "required": [ + "value" + ] + }, + { + "required": [ + "valueFrom" + ] + } ], "additionalProperties": false } diff --git a/helm_tests/airflow_aux/test_create_user_job.py b/helm_tests/airflow_aux/test_create_user_job.py index 6ee458bcbbce2..fb90d7c59958c 100644 --- a/helm_tests/airflow_aux/test_create_user_job.py +++ b/helm_tests/airflow_aux/test_create_user_job.py @@ -228,7 +228,17 @@ def test_should_add_extraEnvs(self): docs = render_chart( values={ "createUserJob": { - "env": [{"name": "TEST_ENV_1", "value": "test_env_1"}], + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ], }, }, show_only=["templates/jobs/create-user-job.yaml"], @@ -237,6 +247,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.template.spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) def test_should_enable_custom_env(self): docs = render_chart( diff --git a/helm_tests/airflow_aux/test_pod_template_file.py b/helm_tests/airflow_aux/test_pod_template_file.py index 821634751219f..1efccbf4106d4 100644 --- a/helm_tests/airflow_aux/test_pod_template_file.py +++ b/helm_tests/airflow_aux/test_pod_template_file.py @@ -767,7 +767,21 @@ def test_should_add_pod_labels(self): def test_should_add_extraEnvs(self): docs = render_chart( - values={"workers": {"env": [{"name": "TEST_ENV_1", "value": "test_env_1"}]}}, + values={ + "workers": { + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ] + } + }, show_only=["templates/pod-template-file.yaml"], chart_dir=self.temp_chart_dir, ) @@ -775,6 +789,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.containers[0].env", docs[0]) def test_should_add_component_specific_labels(self): docs = render_chart( diff --git a/helm_tests/airflow_core/test_dag_processor.py b/helm_tests/airflow_core/test_dag_processor.py index 31256b4095cf9..9ecf06d36c389 100644 --- a/helm_tests/airflow_core/test_dag_processor.py +++ b/helm_tests/airflow_core/test_dag_processor.py @@ -203,7 +203,17 @@ def test_should_add_extraEnvs(self): values={ "dagProcessor": { "enabled": True, - "env": [{"name": "TEST_ENV_1", "value": "test_env_1"}], + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ], }, }, show_only=["templates/dag-processor/dag-processor-deployment.yaml"], @@ -212,6 +222,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.template.spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) def test_should_add_extraEnvs_to_wait_for_migration_container(self): docs = render_chart( diff --git a/helm_tests/airflow_core/test_scheduler.py b/helm_tests/airflow_core/test_scheduler.py index eef2f8756426d..3fb7f6754d8d5 100644 --- a/helm_tests/airflow_core/test_scheduler.py +++ b/helm_tests/airflow_core/test_scheduler.py @@ -169,7 +169,17 @@ def test_should_add_extraEnvs(self): docs = render_chart( values={ "scheduler": { - "env": [{"name": "TEST_ENV_1", "value": "test_env_1"}], + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ], }, }, show_only=["templates/scheduler/scheduler-deployment.yaml"], @@ -178,6 +188,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.template.spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) def test_should_add_extraEnvs_to_wait_for_migration_container(self): docs = render_chart( diff --git a/helm_tests/airflow_core/test_triggerer.py b/helm_tests/airflow_core/test_triggerer.py index a684e0f334394..0d8c4dd8206bc 100644 --- a/helm_tests/airflow_core/test_triggerer.py +++ b/helm_tests/airflow_core/test_triggerer.py @@ -191,7 +191,17 @@ def test_should_add_extraEnvs(self): docs = render_chart( values={ "triggerer": { - "env": [{"name": "TEST_ENV_1", "value": "test_env_1"}], + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ], } }, show_only=["templates/triggerer/triggerer-deployment.yaml"], @@ -200,6 +210,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.template.spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) def test_should_add_extraEnvs_to_wait_for_migration_container(self): docs = render_chart( diff --git a/helm_tests/airflow_core/test_worker.py b/helm_tests/airflow_core/test_worker.py index bbfea0be6848b..af370f3d9a5ea 100644 --- a/helm_tests/airflow_core/test_worker.py +++ b/helm_tests/airflow_core/test_worker.py @@ -182,7 +182,17 @@ def test_should_add_extraEnvs(self): docs = render_chart( values={ "workers": { - "env": [{"name": "TEST_ENV_1", "value": "test_env_1"}], + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ], }, }, show_only=["templates/workers/worker-deployment.yaml"], @@ -191,6 +201,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.template.spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) def test_should_add_extraEnvs_to_wait_for_migration_container(self): docs = render_chart( diff --git a/helm_tests/other/test_flower.py b/helm_tests/other/test_flower.py index b88fd25ef329b..0f2f2dd66b76e 100644 --- a/helm_tests/other/test_flower.py +++ b/helm_tests/other/test_flower.py @@ -305,7 +305,17 @@ def test_should_add_extraEnvs(self): values={ "flower": { "enabled": True, - "env": [{"name": "TEST_ENV_1", "value": "test_env_1"}], + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ], } }, show_only=["templates/flower/flower-deployment.yaml"], @@ -314,6 +324,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.template.spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) def test_should_add_component_specific_labels(self): docs = render_chart( diff --git a/helm_tests/webserver/test_webserver.py b/helm_tests/webserver/test_webserver.py index 364a7e4b1607f..3d348042110e8 100644 --- a/helm_tests/webserver/test_webserver.py +++ b/helm_tests/webserver/test_webserver.py @@ -219,7 +219,17 @@ def test_should_add_extraEnvs(self): docs = render_chart( values={ "webserver": { - "env": [{"name": "TEST_ENV_1", "value": "test_env_1"}], + "env": [ + {"name": "TEST_ENV_1", "value": "test_env_1"}, + { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + }, + { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + }, + ], }, }, show_only=["templates/webserver/webserver-deployment.yaml"], @@ -228,6 +238,14 @@ def test_should_add_extraEnvs(self): assert {"name": "TEST_ENV_1", "value": "test_env_1"} in jmespath.search( "spec.template.spec.containers[0].env", docs[0] ) + assert { + "name": "TEST_ENV_2", + "valueFrom": {"secretKeyRef": {"name": "my-secret", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) + assert { + "name": "TEST_ENV_3", + "valueFrom": {"configMapKeyRef": {"name": "my-config-map", "key": "my-key"}}, + } in jmespath.search("spec.template.spec.containers[0].env", docs[0]) def test_should_add_extra_volume_and_extra_volume_mount(self): docs = render_chart(