def test_import_local_settings_without_syspath(self, log_mock):
     """
     Tests that an ImportError is raised in import_local_settings
     if there is no airflow_local_settings module on the syspath.
     """
     from airflow import settings
     settings.import_local_settings()
     log_mock.assert_called_with("Failed to import airflow_local_settings.", exc_info=True)
Exemple #2
0
    def test_custom_policy(self):
        with SettingsContext(SETTINGS_FILE_CUSTOM_POLICY,
                             "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()

            task_instance = MagicMock()
            task_instance.owner = 'airflow'
            with self.assertRaises(AirflowClusterPolicyViolation):
                settings.task_must_have_owners(task_instance)  # pylint: disable=no-member
    def test_import_with_dunder_all_not_specified(self):
        """
        Tests that if __all__ is specified in airflow_local_settings,
        only module attributes specified within are imported.
        """
        with SettingsContext(SETTINGS_FILE_POLICY_WITH_DUNDER_ALL, "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()  # pylint: ignore

            with self.assertRaises(AttributeError):
                settings.not_policy()
Exemple #4
0
    def test_policy_function(self):
        """
        Tests that task instances are mutated by the policy
        function in airflow_local_settings.
        """
        with SettingsContext(SETTINGS_FILE_POLICY, "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()

            task_instance = MagicMock()
            settings.test_policy(task_instance)  # pylint: disable=no-member

            assert task_instance.run_as_user == "myself"
    def test_pod_mutation_hook(self):
        """
        Tests that pods are mutated by the pod_mutation_hook
        function in airflow_local_settings.
        """
        with SettingsContext(SETTINGS_FILE_POD_MUTATION_HOOK, "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()  # pylint: ignore

            pod = Pod(image="ubuntu", envs={}, cmds=['echo "1"'])
            settings.pod_mutation_hook(pod)

            assert pod.namespace == 'airflow-tests'
    def test_import_with_dunder_all(self):
        """
        Tests that if __all__ is specified in airflow_local_settings,
        only module attributes specified within are imported.
        """
        with SettingsContext(SETTINGS_FILE_POLICY_WITH_DUNDER_ALL, "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()  # pylint: ignore

            task_instance = MagicMock()
            settings.test_policy(task_instance)

            assert task_instance.run_as_user == "myself"
Exemple #7
0
    def test_pod_mutation_hook(self):
        """
        Tests that pods are mutated by the pod_mutation_hook
        function in airflow_local_settings.
        """
        with SettingsContext(SETTINGS_FILE_POD_MUTATION_HOOK,
                             "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()

            pod = MagicMock()
            settings.pod_mutation_hook(pod)

            assert pod.namespace == 'airflow-tests'
    def test_pod_mutation_v1_pod(self):
        with SettingsContext(SETTINGS_FILE_POD_MUTATION_HOOK_V1_POD,
                             "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()  # pylint: ignore
            from airflow.kubernetes.pod_launcher import PodLauncher

            self.mock_kube_client = Mock()
            self.pod_launcher = PodLauncher(kube_client=self.mock_kube_client)
            pod = pod_generator.PodGenerator(image="myimage",
                                             cmds=["foo"],
                                             namespace="baz",
                                             volume_mounts=[{
                                                 "name": "foo",
                                                 "mountPath": "/mnt",
                                                 "subPath": "/",
                                                 "readOnly": True
                                             }],
                                             volumes=[{
                                                 "name": "foo"
                                             }]).gen_pod()

            sanitized_pod_pre_mutation = api_client.sanitize_for_serialization(
                pod)

            self.assertEqual(
                sanitized_pod_pre_mutation, {
                    'apiVersion': 'v1',
                    'kind': 'Pod',
                    'metadata': {
                        'namespace': 'baz'
                    },
                    'spec': {
                        'containers': [{
                            'args': [],
                            'command': ['foo'],
                            'env': [],
                            'envFrom': [],
                            'image':
                            'myimage',
                            'name':
                            'base',
                            'ports': [],
                            'volumeMounts': [{
                                'mountPath': '/mnt',
                                'name': 'foo',
                                'readOnly': True,
                                'subPath': '/'
                            }]
                        }],
                        'hostNetwork':
                        False,
                        'imagePullSecrets': [],
                        'volumes': [{
                            'name': 'foo'
                        }]
                    }
                })

            # Apply Pod Mutation Hook
            pod = self.pod_launcher._mutate_pod_backcompat(pod)

            sanitized_pod_post_mutation = api_client.sanitize_for_serialization(
                pod)
            self.assertEqual(
                sanitized_pod_post_mutation, {
                    'apiVersion': 'v1',
                    'kind': 'Pod',
                    'metadata': {
                        'namespace': 'airflow-tests'
                    },
                    'spec': {
                        'containers': [{
                            'args': [],
                            'command': ['foo'],
                            'env': [{
                                'name': 'TEST_USER',
                                'value': 'ADMIN'
                            }],
                            'envFrom': [],
                            'image':
                            'test-image',
                            'name':
                            'base',
                            'ports': [{
                                'containerPort': 8080
                            }, {
                                'containerPort': 8081
                            }],
                            'volumeMounts': [{
                                'mountPath': '/mnt',
                                'name': 'foo',
                                'readOnly': True,
                                'subPath': '/'
                            }, {
                                'mountPath': '/opt/airflow/secrets/',
                                'name': 'airflow-secrets-mount',
                                'readOnly': True
                            }]
                        }],
                        'hostNetwork':
                        False,
                        'imagePullSecrets': [],
                        'volumes': [{
                            'name': 'foo'
                        }, {
                            'name': 'airflow-secrets-mount',
                            'secret': {
                                'secretName': 'airflow-test-secrets'
                            }
                        }]
                    }
                })
    def test_pod_mutation_to_k8s_pod(self):
        with SettingsContext(SETTINGS_FILE_POD_MUTATION_HOOK,
                             "airflow_local_settings"):
            from airflow import settings
            settings.import_local_settings()  # pylint: ignore
            from airflow.kubernetes.pod_launcher import PodLauncher

            self.mock_kube_client = Mock()
            self.pod_launcher = PodLauncher(kube_client=self.mock_kube_client)
            init_container = k8s.V1Container(name="init-container",
                                             volume_mounts=[
                                                 k8s.V1VolumeMount(
                                                     mount_path="/tmp",
                                                     name="init-secret")
                                             ])
            pod = pod_generator.PodGenerator(
                image="foo",
                name="bar",
                namespace="baz",
                image_pull_policy="Never",
                init_containers=[init_container],
                cmds=["foo"],
                args=["/bin/sh", "-c", "touch /tmp/healthy"],
                tolerations=[{
                    'effect': 'NoSchedule',
                    'key': 'static-pods',
                    'operator': 'Equal',
                    'value': 'true'
                }],
                volume_mounts=[{
                    "name": "foo",
                    "mountPath": "/mnt",
                    "subPath": "/",
                    "readOnly": True
                }],
                security_context=k8s.V1PodSecurityContext(fs_group=0,
                                                          run_as_user=1),
                volumes=[k8s.V1Volume(name="foo")]).gen_pod()

            sanitized_pod_pre_mutation = api_client.sanitize_for_serialization(
                pod)
            self.assertEqual(
                sanitized_pod_pre_mutation,
                {
                    'apiVersion': 'v1',
                    'kind': 'Pod',
                    'metadata': {
                        'name': mock.ANY,
                        'namespace': 'baz'
                    },
                    'spec': {
                        'containers': [{
                            'args': ['/bin/sh', '-c', 'touch /tmp/healthy'],
                            'command': ['foo'],
                            'env': [],
                            'envFrom': [],
                            'image':
                            'foo',
                            'imagePullPolicy':
                            'Never',
                            'name':
                            'base',
                            'ports': [],
                            'volumeMounts': [{
                                'mountPath': '/mnt',
                                'name': 'foo',
                                'readOnly': True,
                                'subPath': '/'
                            }]
                        }],
                        'initContainers': [{
                            'name':
                            'init-container',
                            'volumeMounts': [{
                                'mountPath': '/tmp',
                                'name': 'init-secret'
                            }]
                        }],
                        'hostNetwork':
                        False,
                        'imagePullSecrets': [],
                        'tolerations': [{
                            'effect': 'NoSchedule',
                            'key': 'static-pods',
                            'operator': 'Equal',
                            'value': 'true'
                        }],
                        'volumes': [{
                            'name': 'foo'
                        }],
                        'securityContext': {
                            'fsGroup': 0,
                            'runAsUser': 1
                        }
                    }
                },
            )

            # Apply Pod Mutation Hook
            pod = self.pod_launcher._mutate_pod_backcompat(pod)

            sanitized_pod_post_mutation = api_client.sanitize_for_serialization(
                pod)

            self.assertEqual(
                sanitized_pod_post_mutation, {
                    "apiVersion": "v1",
                    "kind": "Pod",
                    'metadata': {
                        'labels': {
                            'test_label': 'test_value'
                        },
                        'name': mock.ANY,
                        'namespace': 'airflow-tests'
                    },
                    'spec': {
                        'affinity': {
                            'nodeAffinity': {
                                'requiredDuringSchedulingIgnoredDuringExecution':
                                {
                                    'nodeSelectorTerms': [{
                                        'matchExpressions': [{
                                            'key': 'test/dynamic-pods',
                                            'operator': 'In',
                                            'values': ['true']
                                        }]
                                    }]
                                }
                            }
                        },
                        'containers': [{
                            'args': ['/bin/sh', '-c', 'touch /tmp/healthy2'],
                            'command': ['foo'],
                            'env': [{
                                'name': 'TEST_USER',
                                'value': 'ADMIN'
                            }],
                            'image':
                            'my_image',
                            'imagePullPolicy':
                            'Never',
                            'name':
                            'base',
                            'ports': [{
                                'containerPort': 8080
                            }, {
                                'containerPort': 8081
                            }],
                            'resources': {
                                'limits': {
                                    'nvidia.com/gpu': '200G'
                                },
                                'requests': {
                                    'cpu': '200Mi',
                                    'memory': '2G'
                                }
                            },
                            'volumeMounts': [{
                                'mountPath': '/mnt',
                                'name': 'foo',
                                'readOnly': True,
                                'subPath': '/'
                            }, {
                                'mountPath': '/opt/airflow/secrets/',
                                'name': 'airflow-secrets-mount',
                                'readOnly': True
                            }]
                        }],
                        'hostNetwork':
                        False,
                        'imagePullSecrets': [],
                        'initContainers': [{
                            'name':
                            'init-container',
                            'securityContext': {
                                'runAsGroup': 50000,
                                'runAsUser': 50000
                            },
                            'volumeMounts': [{
                                'mountPath': '/tmp',
                                'name': 'init-secret'
                            }]
                        }],
                        'tolerations': [{
                            'effect': 'NoSchedule',
                            'key': 'static-pods',
                            'operator': 'Equal',
                            'value': 'true'
                        }, {
                            'effect': 'NoSchedule',
                            'key': 'dynamic-pods',
                            'operator': 'Equal',
                            'value': 'true'
                        }],
                        'volumes': [
                            {
                                'name': 'airflow-secrets-mount',
                                'secret': {
                                    'secretName': 'airflow-test-secrets'
                                }
                            },
                            {
                                'name': 'bar'
                            },
                            {
                                'name': 'foo'
                            },
                        ],
                        'securityContext': {
                            'runAsUser': 1
                        }
                    }
                })