def test_conf_as_dict(self):
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        self.assertEqual(cfg_dict["core"]["unit_test_mode"], "True")

        # test env vars
        self.assertEqual(cfg_dict["testsection"]["testkey"], "< hidden >")

        # test defaults
        conf.remove_option("core", "load_examples")
        cfg_dict = conf.as_dict()
        self.assertEqual(cfg_dict["core"]["load_examples"], "True")

        # test display_source
        cfg_dict = conf.as_dict(display_source=True)
        self.assertEqual(cfg_dict["core"]["unit_test_mode"][1], "airflow.cfg")
        self.assertEqual(cfg_dict["core"]["load_examples"][1], "default")
        self.assertEqual(cfg_dict["testsection"]["testkey"], ("< hidden >", "env var"))

        # test display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True)
        self.assertEqual(cfg_dict["testsection"]["testkey"], "testvalue")

        # test display_source and display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True, display_source=True)
        self.assertEqual(cfg_dict["testsection"]["testkey"], ("testvalue", "env var"))
示例#2
0
    def test_conf_as_dict_sensitive(self):
        # test display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True)
        self.assertEqual(cfg_dict['testsection']['testkey'], 'testvalue')
        self.assertEqual(cfg_dict['testsection']['testpercent'], 'with%percent')

        # test display_source and display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True, display_source=True)
        self.assertEqual(
            cfg_dict['testsection']['testkey'], ('testvalue', 'env var'))
    def test_conf_as_dict_sensitive(self):
        # test display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True)
        self.assertEqual(cfg_dict['testsection']['testkey'], 'testvalue')
        self.assertEqual(cfg_dict['testsection']['testpercent'], 'with%percent')

        # test display_source and display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True, display_source=True)
        self.assertEqual(
            cfg_dict['testsection']['testkey'], ('testvalue', 'env var'))
示例#4
0
def get_config_with_source(include_default: bool = False) -> str:
    """Return configuration along with source for each option."""
    config_dict = conf.as_dict(display_source=True)

    with io.StringIO() as buf, redirect_stdout(buf):
        for section, options in config_dict.items():
            if not include_default:
                options = {
                    key: (value, source)
                    for key, (value, source) in options.items()
                    if source != "default"
                }

            # Print the section only when there are options after filtering
            if options:
                print(f"[{section}]")
                for key, (value, source) in options.items():
                    print(f"{key} = {value} [{source}]")
                print()
        code = buf.getvalue()

        if is_terminal_support_colors():
            code = pygments.highlight(code=code,
                                      formatter=get_terminal_formatter(),
                                      lexer=IniLexer())

        return code
    def test_conf_as_dict_exclude_env(self):
        # test display_sensitive
        cfg_dict = conf.as_dict(include_env=False, display_sensitive=True)

        # Since testsection is only created from env vars, it shouldn't be
        # present at all if we don't ask for env vars to be included.
        self.assertNotIn('testsection', cfg_dict)
示例#6
0
def tmp_configuration_copy(chmod=0o600, include_env=True, include_cmds=True):
    """
    Returns a path for a temporary file including a full copy of the configuration
    settings.

    :param include_env: Should the value of configuration from ``AIRFLOW__``
        environment variables be included or not
    :type include_env: bool
    :param include_cmds: Should the result of calling any *_cmd config be
        set (True, default), or should the _cmd options be left as the
        command to run (False)
    :type include_cmds: bool
    :return: a path to a temporary file
    """
    cfg_dict = conf.as_dict(display_sensitive=True,
                            raw=True,
                            include_cmds=include_cmds,
                            include_env=include_env)
    temp_fd, cfg_path = mkstemp()

    with os.fdopen(temp_fd, 'w') as temp_file:
        # Set the permissions before we write anything to it.
        if chmod is not None:
            os.fchmod(temp_fd, chmod)
        json.dump(cfg_dict, temp_file)

    return cfg_path
 def test_conf_as_dict_source(self):
     # test display_source
     cfg_dict = conf.as_dict(display_source=True)
     self.assertEqual(
         cfg_dict['core']['load_examples'][1], 'airflow.cfg')
     self.assertEqual(
         cfg_dict['testsection']['testkey'], ('< hidden >', 'env var'))
 def test_conf_as_dict_source(self):
     # test display_source
     cfg_dict = conf.as_dict(display_source=True)
     self.assertEqual(
         cfg_dict['core']['load_examples'][1], 'airflow.cfg')
     self.assertEqual(
         cfg_dict['testsection']['testkey'], ('< hidden >', 'env var'))
    def test_conf_as_dict_raw(self):
        # test display_sensitive
        cfg_dict = conf.as_dict(raw=True, display_sensitive=True)
        self.assertEqual(cfg_dict['testsection']['testkey'], 'testvalue')

        # Values with '%' in them should be escaped
        self.assertEqual(cfg_dict['testsection']['testpercent'], 'with%%percent')
        self.assertEqual(cfg_dict['core']['percent'], 'with%%inside')
    def test_conf_as_dict_raw(self):
        # test display_sensitive
        cfg_dict = conf.as_dict(raw=True, display_sensitive=True)
        self.assertEqual(cfg_dict['testsection']['testkey'], 'testvalue')

        # Values with '%' in them should be escaped
        self.assertEqual(cfg_dict['testsection']['testpercent'], 'with%%percent')
        self.assertEqual(cfg_dict['core']['percent'], 'with%%inside')
示例#11
0
 def test_config_as_dict(self):
     """Test that getting config as dict works even if
     environment has non-legal env vars"""
     with unittest.mock.patch.dict('os.environ'):
         os.environ['AIRFLOW__VAR__broken'] = "not_ok"
         asdict = conf.as_dict(raw=True, display_sensitive=True)
     assert asdict.get('VAR') is None
     assert asdict['testsection']['testkey'] == 'testvalue'
示例#12
0
def show_config(args):
    """Show current application configuration"""
    config = conf.as_dict(display_sensitive=True, raw=True)

    for section_key, parameters in sorted(config.items()):
        print(f"[{section_key}]")
        for parameter_key, value in sorted(parameters.items()):
            print(f"{parameter_key}={value}")
        print()
示例#13
0
    def test_conf_as_dict(self):
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        self.assertEqual(cfg_dict['core']['unit_test_mode'], 'True')

        self.assertEqual(cfg_dict['core']['percent'], 'with%inside')

        # test env vars
        self.assertEqual(cfg_dict['testsection']['testkey'], '< hidden >')
    def test_conf_as_dict(self):
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        self.assertEqual(cfg_dict['core']['unit_test_mode'], 'True')

        self.assertEqual(cfg_dict['core']['percent'], 'with%inside')

        # test env vars
        self.assertEqual(cfg_dict['testsection']['testkey'], '< hidden >')
示例#15
0
    def test_conf_as_dict(self):
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        assert cfg_dict['core']['unit_test_mode'] == 'True'

        assert cfg_dict['core']['percent'] == 'with%inside'

        # test env vars
        assert cfg_dict['testsection']['testkey'] == '< hidden >'
        assert cfg_dict['kubernetes_environment_variables']['AIRFLOW__TESTSECTION__TESTKEY'] == '< hidden >'
示例#16
0
    def __init__(self):  # pylint: disable=too-many-statements
        configuration_dict = conf.as_dict(display_sensitive=True)
        self.core_configuration = configuration_dict['core']
        self.airflow_home = settings.AIRFLOW_HOME
        self.dags_folder = conf.get(self.core_section, 'dags_folder')
        self.parallelism = conf.getint(self.core_section, 'parallelism')
        self.pod_template_file = conf.get(self.kubernetes_section,
                                          'pod_template_file',
                                          fallback=None)

        self.delete_worker_pods = conf.getboolean(self.kubernetes_section,
                                                  'delete_worker_pods')
        self.delete_worker_pods_on_failure = conf.getboolean(
            self.kubernetes_section, 'delete_worker_pods_on_failure')
        self.worker_pods_creation_batch_size = conf.getint(
            self.kubernetes_section, 'worker_pods_creation_batch_size')

        self.worker_container_repository = conf.get(
            self.kubernetes_section, 'worker_container_repository')
        self.worker_container_tag = conf.get(self.kubernetes_section,
                                             'worker_container_tag')
        self.kube_image = f'{self.worker_container_repository}:{self.worker_container_tag}'

        # The Kubernetes Namespace in which the Scheduler and Webserver reside. Note
        # that if your
        # cluster has RBAC enabled, your scheduler may need service account permissions to
        # create, watch, get, and delete pods in this namespace.
        self.kube_namespace = conf.get(self.kubernetes_section, 'namespace')
        self.multi_namespace_mode = conf.getboolean(self.kubernetes_section,
                                                    'multi_namespace_mode')
        # The Kubernetes Namespace in which pods will be created by the executor. Note
        # that if your
        # cluster has RBAC enabled, your workers may need service account permissions to
        # interact with cluster components.
        self.executor_namespace = conf.get(self.kubernetes_section,
                                           'namespace')

        kube_client_request_args = conf.get(self.kubernetes_section,
                                            'kube_client_request_args')
        if kube_client_request_args:
            self.kube_client_request_args = json.loads(
                kube_client_request_args)
            if self.kube_client_request_args['_request_timeout'] and \
                    isinstance(self.kube_client_request_args['_request_timeout'], list):
                self.kube_client_request_args['_request_timeout'] = \
                    tuple(self.kube_client_request_args['_request_timeout'])
        else:
            self.kube_client_request_args = {}
        delete_option_kwargs = conf.get(self.kubernetes_section,
                                        'delete_option_kwargs')
        if delete_option_kwargs:
            self.delete_option_kwargs = json.loads(delete_option_kwargs)
        else:
            self.delete_option_kwargs = {}
示例#17
0
    def test_conf_as_dict(self):
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        self.assertEqual(cfg_dict['core']['unit_test_mode'], 'True')

        self.assertEqual(cfg_dict['core']['percent'], 'with%inside')

        # test env vars
        self.assertEqual(cfg_dict['testsection']['testkey'], '< hidden >')
        self.assertEqual(
            cfg_dict['kubernetes_environment_variables']
            ['airflow__testsection__testkey'], '< hidden >')
示例#18
0
def _get_scratch_base_path() -> str:
    dct = airflow_conf.as_dict(display_sensitive=True)['connections']
    if 'WORKFLOW_SCRATCH' in dct:
        scratch_path = dct['WORKFLOW_SCRATCH']
    elif 'workflow_scratch' in dct:
        # support for lower case is necessary setting the scratch path via the
        # environment variable AIRFLOW__CONNECTIONS__WORKFLOW_SCRATCH
        scratch_path = dct['workflow_scratch']
    else:
        raise KeyError('WORKFLOW_SCRATCH')  # preserve original code behavior
    scratch_path = scratch_path.strip("'").strip(
        '"')  # remove quotes that may be on the string
    return scratch_path
示例#19
0
def map_queue_name(raw_queue_name: str) -> str:
    """
    If the configuration contains QUEUE_NAME_TEMPLATE, use it to customize the
    provided queue name.  This allows job separation under Celery.
    """
    conf_dict = airflow_conf.as_dict()
    if 'QUEUE_NAME_TEMPLATE' in conf_dict.get('connections', {}):
        template = conf_dict['connections']['QUEUE_NAME_TEMPLATE']
        template = template.strip("'").strip(
            '"')  # remove quotes that may be on the config string
        rslt = template.format(raw_queue_name)
        return rslt
    else:
        return raw_queue_name
示例#20
0
    def test_conf_as_dict(self):
        os.environ['AIRFLOW__KUBERNETES_ENVIRONMENT_VARIABLES__AIRFLOW__TESTSECTION__TESTKEY'] = 'nested'
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        self.assertEqual(cfg_dict['core']['unit_test_mode'], 'True')

        self.assertEqual(cfg_dict['core']['percent'], 'with%inside')

        # test env vars
        self.assertEqual(cfg_dict['testsection']['testkey'], '< hidden >')
        self.assertEqual(
            cfg_dict['kubernetes_environment_variables']['AIRFLOW__TESTSECTION__TESTKEY'],
            '< hidden >')
        del os.environ['AIRFLOW__KUBERNETES_ENVIRONMENT_VARIABLES__AIRFLOW__TESTSECTION__TESTKEY']
    def test_conf_as_dict(self):
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        self.assertEqual(cfg_dict['core']['unit_test_mode'], 'True')

        # test env vars
        self.assertEqual(cfg_dict['testsection']['testkey'], '< hidden >')

        # test display_source
        cfg_dict = conf.as_dict(display_source=True)
        self.assertEqual(
            cfg_dict['core']['load_examples'][1], 'airflow config')
        self.assertEqual(
            cfg_dict['testsection']['testkey'], ('< hidden >', 'env var'))

        # test display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True)
        self.assertEqual(cfg_dict['testsection']['testkey'], 'testvalue')

        # test display_source and display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True, display_source=True)
        self.assertEqual(
            cfg_dict['testsection']['testkey'], ('testvalue', 'env var'))
def get_config() -> Response:
    """Get current configuration."""
    serializer = {
        'text/plain': _config_to_text,
        'application/json': _config_to_json,
    }
    response_types = serializer.keys()
    return_type = request.accept_mimetypes.best_match(response_types)
    conf_dict = conf.as_dict(display_source=False, display_sensitive=True)
    config = _conf_dict_to_config(conf_dict)
    if return_type not in serializer:
        return Response(status=406)
    else:
        config_text = serializer[return_type](config)
        return Response(config_text, headers={'Content-Type': return_type})
示例#23
0
    def test_conf_as_dict(self):
        cfg_dict = conf.as_dict()

        # test that configs are picked up
        self.assertEqual(cfg_dict['core']['unit_test_mode'], 'True')

        # test env vars
        self.assertEqual(cfg_dict['testsection']['testkey'], '< hidden >')

        # test display_source
        cfg_dict = conf.as_dict(display_source=True)
        self.assertEqual(
            cfg_dict['core']['load_examples'][1], 'airflow config')
        self.assertEqual(
            cfg_dict['testsection']['testkey'], ('< hidden >', 'env var'))

        # test display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True)
        self.assertEqual(cfg_dict['testsection']['testkey'], 'testvalue')

        # test display_source and display_sensitive
        cfg_dict = conf.as_dict(display_sensitive=True, display_source=True)
        self.assertEqual(
            cfg_dict['testsection']['testkey'], ('testvalue', 'env var'))
示例#24
0
def tmp_configuration_copy(chmod=0o600):
    """
    Returns a path for a temporary file including a full copy of the configuration
    settings.
    :return: a path to a temporary file
    """
    cfg_dict = conf.as_dict(display_sensitive=True, raw=True)
    temp_fd, cfg_path = mkstemp()

    with os.fdopen(temp_fd, 'w') as temp_file:
        # Set the permissions before we write anything to it.
        if chmod is not None:
            os.fchmod(temp_fd, chmod)
        json.dump(cfg_dict, temp_file)

    return cfg_path
示例#25
0
def get_config() -> Response:
    """Get current configuration."""
    serializer = {
        'text/plain': _config_to_text,
        'application/json': _config_to_json,
    }
    return_type = request.accept_mimetypes.best_match(serializer.keys())
    if return_type not in serializer:
        return Response(status=406)
    elif conf.getboolean("webserver", "expose_config"):
        conf_dict = conf.as_dict(display_source=False, display_sensitive=True)
        config = _conf_dict_to_config(conf_dict)
        config_text = serializer[return_type](config)
        return Response(config_text, headers={'Content-Type': return_type})
    else:
        raise PermissionDenied(detail=(
            'Your Airflow administrator chose not to expose the configuration, most likely for security'
            ' reasons.'))
示例#26
0
def config(section, key):
    dct = airflow_conf.as_dict(display_sensitive=True)
    if section in dct:
        if key in dct[section]:
            rslt = dct[section][key]
        elif key.lower() in dct[section]:
            rslt = dct[section][key.lower()]
        elif key.upper() in dct[section]:
            rslt = dct[section][key.upper()]
        else:
            raise AirflowConfigException('No config entry for [{}] {}'.format(
                section, key))
        # airflow config reader leaves quotes, which we want to strip
        for qc in ['"', "'"]:
            if rslt.startswith(qc) and rslt.endswith(qc):
                rslt = rslt.strip(qc)
        return rslt
    else:
        raise AirflowConfigException('No config section [{}]'.format(section))
示例#27
0
def check_config():
    # Check for needed configuration elements, since it's better to fail early
    dct = airflow_conf.as_dict(display_sensitive=True)
    failed = 0
    for elt in NEEDED_ENV_VARS:
        if elt not in os.environ:
            LOGGER.error('The environment variable {} is not set'.format(elt))
            failed += 1
    for key in NEEDED_CONFIG_SECTIONS + [a for a, b in NEEDED_CONFIGS]:
        if not (key in dct or key.upper() in dct):
            LOGGER.error(
                'The configuration section {} does not exist'.format(key))
            failed += 1
    for key1, key2 in NEEDED_CONFIGS:
        sub_dct = dct[key1] if key1 in dct else dct[key1.upper()]
        if not (key2 in sub_dct or key2.upper() in sub_dct):
            LOGGER.error(
                'The configuration parameter [{}] {} does not exist'.format(
                    key1, key2))
            failed += 1
    assert failed == 0, 'ingest-pipeline plugin found {} configuration errors'.format(
        failed)
示例#28
0
    def __init__(self):
        configuration_dict = conf.as_dict(display_sensitive=True)
        self.core_configuration = configuration_dict[self.core_section]
        self.airflow_home = AIRFLOW_HOME
        self.dags_folder = conf.get(self.core_section, 'dags_folder')
        self.parallelism = conf.getint(self.core_section, 'parallelism')
        self.pod_template_file = conf.get(self.kubernetes_section,
                                          'pod_template_file',
                                          fallback=None)

        self.delete_worker_pods = conf.getboolean(self.kubernetes_section,
                                                  'delete_worker_pods')
        self.delete_worker_pods_on_failure = conf.getboolean(
            self.kubernetes_section, 'delete_worker_pods_on_failure')
        self.worker_pods_creation_batch_size = conf.getint(
            self.kubernetes_section, 'worker_pods_creation_batch_size')

        self.worker_container_repository = conf.get(
            self.kubernetes_section, 'worker_container_repository')
        self.worker_container_tag = conf.get(self.kubernetes_section,
                                             'worker_container_tag')
        if self.worker_container_repository and self.worker_container_tag:
            self.kube_image = f'{self.worker_container_repository}:{self.worker_container_tag}'
        else:
            self.kube_image = None

        # The Kubernetes Namespace in which the Scheduler and Webserver reside. Note
        # that if your
        # cluster has RBAC enabled, your scheduler may need service account permissions to
        # create, watch, get, and delete pods in this namespace.
        self.kube_namespace = conf.get(self.kubernetes_section, 'namespace')
        self.multi_namespace_mode = conf.getboolean(self.kubernetes_section,
                                                    'multi_namespace_mode')
        # The Kubernetes Namespace in which pods will be created by the executor. Note
        # that if your
        # cluster has RBAC enabled, your workers may need service account permissions to
        # interact with cluster components.
        self.executor_namespace = conf.get(self.kubernetes_section,
                                           'namespace')

        self.worker_pods_pending_timeout = conf.getint(
            self.kubernetes_section, 'worker_pods_pending_timeout')
        self.worker_pods_pending_timeout_check_interval = conf.getint(
            self.kubernetes_section,
            'worker_pods_pending_timeout_check_interval')
        self.worker_pods_pending_timeout_batch_size = conf.getint(
            self.kubernetes_section, 'worker_pods_pending_timeout_batch_size')
        self.worker_pods_queued_check_interval = conf.getint(
            self.kubernetes_section, 'worker_pods_queued_check_interval')

        self.kube_client_request_args = conf.getjson(
            self.kubernetes_section, 'kube_client_request_args', fallback={})
        if not isinstance(self.kube_client_request_args, dict):
            raise AirflowConfigException(
                f"[{self.kubernetes_section}] 'kube_client_request_args' expected a JSON dict, got "
                + type(self.kube_client_request_args).__name__)
        if self.kube_client_request_args:
            if '_request_timeout' in self.kube_client_request_args and isinstance(
                    self.kube_client_request_args['_request_timeout'], list):
                self.kube_client_request_args['_request_timeout'] = tuple(
                    self.kube_client_request_args['_request_timeout'])
        self.delete_option_kwargs = conf.getjson(self.kubernetes_section,
                                                 'delete_option_kwargs',
                                                 fallback={})
        if not isinstance(self.delete_option_kwargs, dict):
            raise AirflowConfigException(
                f"[{self.kubernetes_section}] 'delete_option_kwargs' expected a JSON dict, got "
                + type(self.delete_option_kwargs).__name__)
示例#29
0
 def api_admin_view3(self):
     LOGGER.info('In APIAdminView1.api_admin_view3')
     return show_template('show_config.html',
                          title='Airflow Config',
                          dict_of_dicts=airflow_conf.as_dict())
示例#30
0
         user_defined_macros={'tmp_dir_path': utils.get_tmp_dir_path}) as dag:

    prev = dag

    for idx, uuid in enumerate(UUIDS_TO_RESET):

        this_t = PythonOperator(
            task_id=f'set_dataset_new_{idx}',
            python_callable=utils.pythonop_set_dataset_state,
            provide_context=True,
            op_kwargs={
                'dataset_uuid_callable':
                uuid_fun,
                'http_conn_id':
                'ingest_api_connection',
                'endpoint':
                '/datasets/status',
                'ds_state':
                'New',
                'message':
                'Resetting state to NEW',
                'crypt_auth_tok':
                utils.encrypt_tok(airflow_conf.as_dict()['connections']
                                  ['APP_CLIENT_SECRET']).decode(),
                'uuid':
                uuid
            })

        prev >> this_t
        prev = this_t
示例#31
0
def get_process_strings():
    dct = airflow_conf.as_dict()
    psl = [s.upper() for s in dct['ingest_map']] if 'ingest_map' in dct else []
    return HubmapApiResponse.success({'process_strings': psl})
示例#32
0
def encrypt_tok(cleartext_tok: str) -> bytes:
    key = airflow_conf.as_dict(display_sensitive=True)['core']['fernet_key']
    fernet = Fernet(key.encode())
    return fernet.encrypt(cleartext_tok.encode())
示例#33
0
def decrypt_tok(crypt_tok: bytes) -> str:
    key = airflow_conf.as_dict(display_sensitive=True)['core']['fernet_key']
    fernet = Fernet(key.encode())
    return fernet.decrypt(crypt_tok).decode()
示例#34
0
    def __init__(self):  # pylint: disable=too-many-statements
        configuration_dict = conf.as_dict(display_sensitive=True)
        self.core_configuration = configuration_dict['core']
        self.kube_secrets = configuration_dict.get('kubernetes_secrets', {})
        self.kube_env_vars = configuration_dict.get(
            'kubernetes_environment_variables', {})
        self.env_from_configmap_ref = conf.get(self.kubernetes_section,
                                               'env_from_configmap_ref')
        self.env_from_secret_ref = conf.get(self.kubernetes_section,
                                            'env_from_secret_ref')
        self.airflow_home = settings.AIRFLOW_HOME
        self.dags_folder = conf.get(self.core_section, 'dags_folder')
        self.parallelism = conf.getint(self.core_section, 'parallelism')
        self.worker_container_repository = conf.get(
            self.kubernetes_section, 'worker_container_repository')
        self.worker_container_tag = conf.get(self.kubernetes_section,
                                             'worker_container_tag')
        self.kube_image = '{}:{}'.format(self.worker_container_repository,
                                         self.worker_container_tag)
        self.kube_image_pull_policy = conf.get(
            self.kubernetes_section, "worker_container_image_pull_policy")
        self.kube_node_selectors = configuration_dict.get(
            'kubernetes_node_selectors', {})
        self.pod_template_file = conf.get(self.kubernetes_section,
                                          'pod_template_file',
                                          fallback=None)

        kube_worker_annotations = conf.get(self.kubernetes_section,
                                           'worker_annotations')
        if kube_worker_annotations:
            self.kube_annotations = json.loads(kube_worker_annotations)
        else:
            self.kube_annotations = None

        self.kube_labels = configuration_dict.get('kubernetes_labels', {})
        self.delete_worker_pods = conf.getboolean(self.kubernetes_section,
                                                  'delete_worker_pods')
        self.delete_worker_pods_on_failure = conf.getboolean(
            self.kubernetes_section, 'delete_worker_pods_on_failure')
        self.worker_pods_creation_batch_size = conf.getint(
            self.kubernetes_section, 'worker_pods_creation_batch_size')
        self.worker_service_account_name = conf.get(
            self.kubernetes_section, 'worker_service_account_name')
        self.image_pull_secrets = conf.get(self.kubernetes_section,
                                           'image_pull_secrets')

        # NOTE: user can build the dags into the docker image directly,
        # this will set to True if so
        self.dags_in_image = conf.getboolean(self.kubernetes_section,
                                             'dags_in_image')

        # Run as user for pod security context
        self.worker_run_as_user = self._get_security_context_val('run_as_user')
        self.worker_fs_group = self._get_security_context_val('fs_group')

        kube_worker_resources = conf.get(self.kubernetes_section,
                                         'worker_resources')
        if kube_worker_resources:
            self.worker_resources = json.loads(kube_worker_resources)
        else:
            self.worker_resources = None

        # NOTE: `git_repo` and `git_branch` must be specified together as a pair
        # The http URL of the git repository to clone from
        self.git_repo = conf.get(self.kubernetes_section, 'git_repo')
        # The branch of the repository to be checked out
        self.git_branch = conf.get(self.kubernetes_section, 'git_branch')
        # Optionally, the directory in the git repository containing the dags
        self.git_subpath = conf.get(self.kubernetes_section, 'git_subpath')
        # Optionally, the root directory for git operations
        self.git_sync_root = conf.get(self.kubernetes_section, 'git_sync_root')
        # Optionally, the name at which to publish the checked-out files under --root
        self.git_sync_dest = conf.get(self.kubernetes_section, 'git_sync_dest')
        # Optionally, the tag or hash to checkout
        self.git_sync_rev = conf.get(self.kubernetes_section, 'git_sync_rev')
        # Optionally, if git_dags_folder_mount_point is set the worker will use
        # {git_dags_folder_mount_point}/{git_sync_dest}/{git_subpath} as dags_folder
        self.git_dags_folder_mount_point = conf.get(
            self.kubernetes_section, 'git_dags_folder_mount_point')

        # Optionally a user may supply a (`git_user` AND `git_password`) OR
        # (`git_ssh_key_secret_name` AND `git_ssh_key_secret_key`) for private repositories
        self.git_user = conf.get(self.kubernetes_section, 'git_user')
        self.git_password = conf.get(self.kubernetes_section, 'git_password')
        self.git_ssh_key_secret_name = conf.get(self.kubernetes_section,
                                                'git_ssh_key_secret_name')
        self.git_ssh_known_hosts_configmap_name = conf.get(
            self.kubernetes_section, 'git_ssh_known_hosts_configmap_name')
        self.git_sync_credentials_secret = conf.get(
            self.kubernetes_section, 'git_sync_credentials_secret')

        # NOTE: The user may optionally use a volume claim to mount a PV containing
        # DAGs directly
        self.dags_volume_claim = conf.get(self.kubernetes_section,
                                          'dags_volume_claim')

        self.dags_volume_mount_point = conf.get(self.kubernetes_section,
                                                'dags_volume_mount_point')

        # This prop may optionally be set for PV Claims and is used to write logs
        self.logs_volume_claim = conf.get(self.kubernetes_section,
                                          'logs_volume_claim')

        # This prop may optionally be set for PV Claims and is used to locate DAGs
        # on a SubPath
        self.dags_volume_subpath = conf.get(self.kubernetes_section,
                                            'dags_volume_subpath')

        # This prop may optionally be set for PV Claims and is used to locate logs
        # on a SubPath
        self.logs_volume_subpath = conf.get(self.kubernetes_section,
                                            'logs_volume_subpath')

        # Optionally, hostPath volume containing DAGs
        self.dags_volume_host = conf.get(self.kubernetes_section,
                                         'dags_volume_host')

        # Optionally, write logs to a hostPath Volume
        self.logs_volume_host = conf.get(self.kubernetes_section,
                                         'logs_volume_host')

        # This prop may optionally be set for PV Claims and is used to write logs
        self.base_log_folder = conf.get(self.logging_section,
                                        'base_log_folder')

        # The Kubernetes Namespace in which the Scheduler and Webserver reside. Note
        # that if your
        # cluster has RBAC enabled, your scheduler may need service account permissions to
        # create, watch, get, and delete pods in this namespace.
        self.kube_namespace = conf.get(self.kubernetes_section, 'namespace')
        # The Kubernetes Namespace in which pods will be created by the executor. Note
        # that if your
        # cluster has RBAC enabled, your workers may need service account permissions to
        # interact with cluster components.
        self.executor_namespace = conf.get(self.kubernetes_section,
                                           'namespace')

        # If the user is using the git-sync container to clone their repository via git,
        # allow them to specify repository, tag, and pod name for the init container.
        self.git_sync_container_repository = conf.get(
            self.kubernetes_section, 'git_sync_container_repository')

        self.git_sync_container_tag = conf.get(self.kubernetes_section,
                                               'git_sync_container_tag')
        self.git_sync_container = '{}:{}'.format(
            self.git_sync_container_repository, self.git_sync_container_tag)

        self.git_sync_init_container_name = conf.get(
            self.kubernetes_section, 'git_sync_init_container_name')

        self.git_sync_run_as_user = self._get_security_context_val(
            'git_sync_run_as_user')

        # The worker pod may optionally have a  valid Airflow config loaded via a
        # configmap
        self.airflow_configmap = conf.get(self.kubernetes_section,
                                          'airflow_configmap')

        # The worker pod may optionally have a valid Airflow local settings loaded via a
        # configmap
        self.airflow_local_settings_configmap = conf.get(
            self.kubernetes_section, 'airflow_local_settings_configmap')

        affinity_json = conf.get(self.kubernetes_section, 'affinity')
        if affinity_json:
            self.kube_affinity = json.loads(affinity_json)
        else:
            self.kube_affinity = None

        tolerations_json = conf.get(self.kubernetes_section, 'tolerations')
        if tolerations_json:
            self.kube_tolerations = json.loads(tolerations_json)
        else:
            self.kube_tolerations = None

        kube_client_request_args = conf.get(self.kubernetes_section,
                                            'kube_client_request_args')
        if kube_client_request_args:
            self.kube_client_request_args = json.loads(
                kube_client_request_args)
            if self.kube_client_request_args['_request_timeout'] and \
                    isinstance(self.kube_client_request_args['_request_timeout'], list):
                self.kube_client_request_args['_request_timeout'] = \
                    tuple(self.kube_client_request_args['_request_timeout'])
        else:
            self.kube_client_request_args = {}
        self._validate()

        delete_option_kwargs = conf.get(self.kubernetes_section,
                                        'delete_option_kwargs')
        if delete_option_kwargs:
            self.delete_option_kwargs = json.loads(delete_option_kwargs)
        else:
            self.delete_option_kwargs = {}
示例#35
0
 def test_conf_as_dict_source(self):
     # test display_source
     cfg_dict = conf.as_dict(display_source=True)
     assert cfg_dict['core']['load_examples'][1] == 'airflow.cfg'
     assert cfg_dict['core']['load_default_connections'][1] == 'airflow.cfg'
     assert cfg_dict['testsection']['testkey'] == ('< hidden >', 'env var')