def test_init_environment_using_git_sync_ssh_with_known_hosts(self):
        # Tests the init environment created with git-sync SSH authentication option is correct
        # with known hosts file
        self.kube_config.airflow_configmap = 'airflow-configmap'
        self.kube_config.git_ssh_key_secret_name = 'airflow-secrets'
        self.kube_config.git_ssh_known_hosts_configmap_name = 'airflow-configmap'
        self.kube_config.dags_volume_claim = None
        self.kube_config.dags_volume_host = None
        self.kube_config.dags_in_image = None

        worker_config = WorkerConfiguration(self.kube_config)
        init_containers = worker_config._get_init_containers()

        self.assertTrue(init_containers)  # check not empty
        env = init_containers[0].env

        self.assertIn(k8s.V1EnvVar(name='GIT_SSH_KEY_FILE', value='/etc/git-secret/ssh'), env)
        self.assertIn(k8s.V1EnvVar(name='GIT_KNOWN_HOSTS', value='true'), env)
        self.assertIn(k8s.V1EnvVar(
            name='GIT_SSH_KNOWN_HOSTS_FILE',
            value='/etc/git-secret/known_hosts'
        ), env)
        self.assertIn(k8s.V1EnvVar(name='GIT_SYNC_SSH', value='true'), env)
示例#2
0
    def test_make_pod_git_sync_rev(self):
        # Tests the pod created with git_sync_credentials_secret will get into the init container
        self.kube_config.git_sync_rev = 'sampletag'
        self.kube_config.dags_volume_claim = None
        self.kube_config.dags_volume_host = None
        self.kube_config.dags_in_image = None
        self.kube_config.worker_fs_group = None
        self.kube_config.git_dags_folder_mount_point = 'dags'
        self.kube_config.git_sync_dest = 'repo'
        self.kube_config.git_subpath = 'path'

        worker_config = WorkerConfiguration(self.kube_config)

        pod = worker_config.as_pod()

        rev_env = k8s.V1EnvVar(
            name='GIT_SYNC_REV',
            value=self.kube_config.git_sync_rev,
        )

        self.assertIn(
            rev_env, pod.spec.init_containers[0].env,
            'The git_sync_rev env did not get into the init container')
    def test_make_pod_git_sync_credentials_secret(self):
        # Tests the pod created with git_sync_credentials_secret will get into the init container
        self.kube_config.git_sync_credentials_secret = 'airflow-git-creds-secret'
        self.kube_config.dags_volume_claim = None
        self.kube_config.dags_volume_host = None
        self.kube_config.dags_in_image = None
        self.kube_config.worker_fs_group = None
        self.kube_config.git_dags_folder_mount_point = 'dags'
        self.kube_config.git_sync_dest = 'repo'
        self.kube_config.git_subpath = 'path'

        worker_config = WorkerConfiguration(self.kube_config)

        pod = worker_config.as_pod()

        username_env = k8s.V1EnvVar(
            name='GIT_SYNC_USERNAME',
            value_from=k8s.V1EnvVarSource(
                secret_key_ref=k8s.V1SecretKeySelector(
                    name=self.kube_config.git_sync_credentials_secret,
                    key='GIT_SYNC_USERNAME')
            )
        )
        password_env = k8s.V1EnvVar(
            name='GIT_SYNC_PASSWORD',
            value_from=k8s.V1EnvVarSource(
                secret_key_ref=k8s.V1SecretKeySelector(
                    name=self.kube_config.git_sync_credentials_secret,
                    key='GIT_SYNC_PASSWORD')
            )
        )

        self.assertIn(username_env, pod.spec.init_containers[0].env,
                      'The username env for git credentials did not get into the init container')

        self.assertIn(password_env, pod.spec.init_containers[0].env,
                      'The password env for git credentials did not get into the init container')
示例#4
0
    def test_make_pod_with_executor_config(self):
        self.kube_config.dags_folder = 'dags'
        worker_config = WorkerConfiguration(self.kube_config)
        config_pod = PodGenerator(
            image='',
            affinity=self.affinity_config,
            tolerations=self.tolerations_config,
        ).gen_pod()

        pod = worker_config.make_pod("default", str(uuid.uuid4()),
                                     "test_pod_id", "test_dag_id",
                                     "test_task_id", str(datetime.utcnow()), 1,
                                     "bash -c 'ls /'")

        result = PodGenerator.reconcile_pods(pod, config_pod)

        self.assertTrue(result.spec.affinity['podAntiAffinity'] is not None)
        self.assertEqual(
            'app', result.spec.affinity['podAntiAffinity']
            ['requiredDuringSchedulingIgnoredDuringExecution'][0]
            ['labelSelector']['matchExpressions'][0]['key'])

        self.assertEqual(2, len(result.spec.tolerations))
        self.assertEqual('prod', result.spec.tolerations[1]['key'])
示例#5
0
    def test_worker_git_dags(self):
        # Tests persistence volume config created when `git_repo` is set
        self.kube_config.dags_volume_claim = None
        self.kube_config.dags_volume_host = None
        self.kube_config.dags_folder = '/usr/local/airflow/dags'
        self.kube_config.worker_dags_folder = '/usr/local/airflow/dags'

        self.kube_config.git_sync_container_repository = 'gcr.io/google-containers/git-sync-amd64'
        self.kube_config.git_sync_container_tag = 'v2.0.5'
        self.kube_config.git_sync_container = 'gcr.io/google-containers/git-sync-amd64:v2.0.5'
        self.kube_config.git_sync_init_container_name = 'git-sync-clone'
        self.kube_config.git_subpath = 'dags_folder'
        self.kube_config.git_sync_root = '/git'
        self.kube_config.git_sync_run_as_user = 65533
        self.kube_config.git_dags_folder_mount_point = '/usr/local/airflow/dags/repo/dags_folder'

        worker_config = WorkerConfiguration(self.kube_config)
        volumes = worker_config._get_volumes()
        volume_mounts = worker_config._get_volume_mounts()

        dag_volume = [volume for volume in volumes if volume.name == 'airflow-dags']
        dag_volume_mount = [mount for mount in volume_mounts if mount.name == 'airflow-dags']

        self.assertIsNotNone(dag_volume[0].empty_dir)
        self.assertEqual(self.kube_config.git_dags_folder_mount_point, dag_volume_mount[0].mount_path)
        self.assertTrue(dag_volume_mount[0].read_only)

        init_container = worker_config._get_init_containers()[0]
        init_container_volume_mount = [mount for mount in init_container.volume_mounts
                                       if mount.name == 'airflow-dags']

        self.assertEqual('git-sync-clone', init_container.name)
        self.assertEqual('gcr.io/google-containers/git-sync-amd64:v2.0.5', init_container.image)
        self.assertEqual(1, len(init_container_volume_mount))
        self.assertFalse(init_container_volume_mount[0].read_only)
        self.assertEqual(65533, init_container.security_context.run_as_user)
示例#6
0
    def test_make_pod_git_sync_ssh_with_known_hosts(self):
        # Tests the pod created with git-sync SSH authentication option is correct with known hosts
        self.kube_config.airflow_configmap = 'airflow-configmap'
        self.kube_config.git_ssh_secret_name = 'airflow-secrets'
        self.kube_config.dags_volume_claim = None
        self.kube_config.dags_volume_host = None
        self.kube_config.dags_in_image = None

        worker_config = WorkerConfiguration(self.kube_config)

        init_containers = worker_config._get_init_containers()
        git_ssh_known_hosts_file = next((x.value for x in init_containers[0].env
                                         if x.name == 'GIT_SSH_KNOWN_HOSTS_FILE'), None)

        volume_mount_ssh_known_hosts_file = next(
            (x.mount_path for x in init_containers[0].volume_mounts
             if x.name == worker_config.git_sync_ssh_known_hosts_volume_name),
            None)
        self.assertTrue(git_ssh_known_hosts_file)
        self.assertTrue(volume_mount_ssh_known_hosts_file)
        self.assertEqual(git_ssh_known_hosts_file,
                         volume_mount_ssh_known_hosts_file,
                         'The location where the git known hosts file is mounted'
                         ' needs to be the same as the GIT_SSH_KNOWN_HOSTS_FILE path')
    def test_init_environment_using_git_sync_user_with_known_hosts(self):
        # Tests the init environment created with git-sync User authentication option is correct
        # with known hosts file
        self.kube_config.airflow_configmap = 'airflow-configmap'
        self.kube_config.git_user = '******'
        self.kube_config.git_password = '******'
        self.kube_config.git_ssh_known_hosts_configmap_name = 'airflow-configmap'
        self.kube_config.git_ssh_key_secret_name = None
        self.kube_config.dags_volume_claim = None
        self.kube_config.dags_volume_host = None
        self.kube_config.dags_in_image = None

        worker_config = WorkerConfiguration(self.kube_config)
        init_containers = worker_config._get_init_containers()

        self.assertTrue(init_containers)  # check not empty
        env = init_containers[0]['env']

        self.assertFalse({
            'name': 'GIT_SSH_KEY_FILE',
            'value': '/etc/git-secret/ssh'
        } in env)
        self.assertTrue({
            'name': 'GIT_SYNC_USERNAME',
            'value': 'git_user'
        } in env)
        self.assertTrue({
            'name': 'GIT_SYNC_PASSWORD',
            'value': 'git_password'
        } in env)
        self.assertTrue({'name': 'GIT_KNOWN_HOSTS', 'value': 'true'} in env)
        self.assertTrue({
            'name': 'GIT_SSH_KNOWN_HOSTS_FILE',
            'value': '/etc/git-secret/known_hosts'
        } in env)
        self.assertFalse({'name': 'GIT_SYNC_SSH', 'value': 'true'} in env)
    def test_make_pod_with_empty_executor_config(self):
        self.kube_config.kube_affinity = self.affinity_config
        self.kube_config.kube_tolerations = self.tolerations_config

        worker_config = WorkerConfiguration(self.kube_config)
        kube_executor_config = KubernetesExecutorConfig(annotations=[],
                                                        volumes=[],
                                                        volume_mounts=[]
                                                        )

        pod = worker_config.make_pod("default", str(uuid.uuid4()), "test_pod_id", "test_dag_id",
                                     "test_task_id", str(datetime.utcnow()), 1, "bash -c 'ls /'",
                                     kube_executor_config)

        self.assertTrue(pod.affinity['podAntiAffinity'] is not None)
        self.assertEqual('app',
                         pod.affinity['podAntiAffinity']
                         ['requiredDuringSchedulingIgnoredDuringExecution'][0]
                         ['labelSelector']
                         ['matchExpressions'][0]
                         ['key'])

        self.assertEqual(2, len(pod.tolerations))
        self.assertEqual('prod', pod.tolerations[1]['key'])
    def test_set_airflow_configmap_different_for_local_setting(self):
        """
        Test that airflow_local_settings.py can be set via configmap by
        checking volume & volume-mounts are set correctly when using a different
        configmap than airflow_configmap (airflow.cfg)
        """
        self.kube_config.airflow_home = '/usr/local/airflow'
        self.kube_config.airflow_configmap = 'airflow-configmap'
        self.kube_config.airflow_local_settings_configmap = 'airflow-ls-configmap'
        self.kube_config.dags_folder = '/workers/path/to/dags'

        worker_config = WorkerConfiguration(self.kube_config)
        pod = worker_config.as_pod()

        pod_spec_dict = pod.spec.to_dict()

        airflow_local_settings_volume = [
            volume for volume in pod_spec_dict['volumes'] if volume["name"] == 'airflow-local-settings'
        ]
        # Test that volume_name is found
        self.assertEqual(1, len(airflow_local_settings_volume))

        # Test that config map exists
        self.assertEqual(
            {'default_mode': None, 'items': None, 'name': 'airflow-ls-configmap', 'optional': None},
            airflow_local_settings_volume[0]['config_map']
        )

        # Test that 2 Volume Mounts exists and has 2 different mount-paths
        # One for airflow.cfg
        # Second for airflow_local_settings.py
        airflow_cfg_volume_mount = [
            volume_mount for volume_mount in pod_spec_dict['containers'][0]['volume_mounts']
            if volume_mount['name'] == 'airflow-config'
        ]

        local_setting_volume_mount = [
            volume_mount for volume_mount in pod_spec_dict['containers'][0]['volume_mounts']
            if volume_mount['name'] == 'airflow-local-settings'
        ]
        self.assertEqual(1, len(airflow_cfg_volume_mount))
        self.assertEqual(1, len(local_setting_volume_mount))

        self.assertEqual(
            [
                {
                    'mount_path': '/usr/local/airflow/config/airflow_local_settings.py',
                    'mount_propagation': None,
                    'name': 'airflow-local-settings',
                    'read_only': True,
                    'sub_path': 'airflow_local_settings.py',
                    'sub_path_expr': None
                }
            ],
            local_setting_volume_mount
        )

        self.assertEqual(
            [
                {
                    'mount_path': '/usr/local/airflow/airflow.cfg',
                    'mount_propagation': None,
                    'name': 'airflow-config',
                    'read_only': True,
                    'sub_path': 'airflow.cfg',
                    'sub_path_expr': None
                }
            ],
            airflow_cfg_volume_mount
        )
 def test_worker_adds_config(self):
     worker_config = WorkerConfiguration(self.kube_config)
     volumes = worker_config._get_volumes()
     print(volumes)