diff --git a/airflow/kubernetes/pod_generator.py b/airflow/kubernetes/pod_generator.py index 705c108b79da6..133f59220cc71 100644 --- a/airflow/kubernetes/pod_generator.py +++ b/airflow/kubernetes/pod_generator.py @@ -335,6 +335,10 @@ def construct_pod( - airflow.cfg - executor_config - dynamic arguments + + If a user provides a `pod_override_object`, that pod should only be able to + override the image and namespace, and not arbitrary labels / annotations of + the dynamic_pod. """ try: image = pod_override_object.spec.containers[0].image # type: ignore @@ -342,6 +346,12 @@ def construct_pod( image = kube_image except Exception: image = kube_image + try: + final_namespace = pod_override_object.metadata.namespace # type: ignore + if not final_namespace: + final_namespace = namespace + except Exception: + final_namespace = namespace annotations = { 'dag_id': dag_id, @@ -368,7 +378,7 @@ def construct_pod( dynamic_pod = k8s.V1Pod( metadata=k8s.V1ObjectMeta( - namespace=namespace, + namespace=final_namespace, annotations=annotations, name=PodGenerator.make_unique_pod_id(pod_id), labels=labels, @@ -386,7 +396,7 @@ def construct_pod( ) # Reconcile the pods starting with the first chronologically, - # Pod from the pod_template_File -> Pod from executor_config arg -> Pod from the K8s executor + # Pod from the pod_template_file -> Pod from executor_config arg -> Pod from dynamic arguments pod_list = [base_worker_pod, pod_override_object, dynamic_pod] try: diff --git a/tests/kubernetes/test_pod_generator.py b/tests/kubernetes/test_pod_generator.py index df5efb0d06c9f..6c87efa478a0e 100644 --- a/tests/kubernetes/test_pod_generator.py +++ b/tests/kubernetes/test_pod_generator.py @@ -414,7 +414,8 @@ def test_construct_pod(self, mock_uuid, config_image, expected_image): name='', resources=k8s.V1ResourceRequirements(limits={'cpu': '1m', 'memory': '1G'}) ) ] - ) + ), + metadata=k8s.V1ObjectMeta(namespace='overridden_namespace'), ) result = PodGenerator.construct_pod( @@ -435,7 +436,7 @@ def test_construct_pod(self, mock_uuid, config_image, expected_image): expected.metadata.labels['app'] = 'myapp' expected.metadata.annotations = self.annotations expected.metadata.name = 'pod_id-' + self.static_uuid.hex - expected.metadata.namespace = 'test_namespace' + expected.metadata.namespace = 'overridden_namespace' expected.spec.containers[0].args = ['command'] expected.spec.containers[0].image = expected_image expected.spec.containers[0].resources = {'limits': {'cpu': '1m', 'memory': '1G'}}