diff --git a/config/__init__.py b/config/__init__.py index 3476ff71..83bd581c 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -15,4 +15,4 @@ from .config_exception import ConfigException from .incluster_config import load_incluster_config from .kube_config import (list_kube_config_contexts, load_kube_config, - new_client_from_config) + new_client_from_config, load_kube_config_from_dict) diff --git a/config/kube_config.py b/config/kube_config.py index 43676728..423178b6 100644 --- a/config/kube_config.py +++ b/config/kube_config.py @@ -688,31 +688,43 @@ def save_config(self, path): yaml.safe_dump(self.config_files[path], f, default_flow_style=False) - def _get_kube_config_loader_for_yaml_file( filename, persist_config=False, **kwargs): - - kcfg = KubeConfigMerger(filename) - if persist_config and 'config_persister' not in kwargs: - kwargs['config_persister'] = kcfg.save_changes - - if kcfg.config is None: - raise ConfigException( - 'Invalid kube-config file. ' - 'No configuration found.') - - return KubeConfigLoader( - config_dict=kcfg.config, - config_base_path=None, + return _get_kube_config_loader( + filename=filename, + persist_config=persist_config, **kwargs) +def _get_kube_config_loader( + filename=None, + config_dict=None, + persist_config=False, + **kwargs): + if config_dict is None: + kcfg = KubeConfigMerger(filename) + if persist_config and 'config_persister' not in kwargs: + kwargs['config_persister'] = kcfg.save_changes + + if kcfg.config is None: + raise ConfigException( + 'Invalid kube-config file. ' + 'No configuration found.') + return KubeConfigLoader( + config_dict=kcfg.config, + config_base_path=None, + **kwargs) + else: + return KubeConfigLoader( + config_dict=config_dict, + config_base_path=None, + **kwargs) def list_kube_config_contexts(config_file=None): if config_file is None: config_file = KUBE_CONFIG_DEFAULT_LOCATION - loader = _get_kube_config_loader_for_yaml_file(config_file) + loader = _get_kube_config_loader(filename=config_file) return loader.list_contexts(), loader.current_context @@ -734,8 +746,8 @@ def load_kube_config(config_file=None, context=None, if config_file is None: config_file = KUBE_CONFIG_DEFAULT_LOCATION - loader = _get_kube_config_loader_for_yaml_file( - config_file, active_context=context, + loader = _get_kube_config_loader( + filename=config_file, active_context=context, persist_config=persist_config) if client_configuration is None: @@ -745,6 +757,36 @@ def load_kube_config(config_file=None, context=None, else: loader.load_and_set(client_configuration) +def load_kube_config_from_dict(config_dict, context=None, + client_configuration=None, + persist_config=True): + """Loads authentication and cluster information from config_dict file + and stores them in kubernetes.client.configuration. + + :param config_dict: Takes the config file as a dict. + :param context: set the active context. If is set to None, current_context + from config file will be used. + :param client_configuration: The kubernetes.client.Configuration to + set configs to. + :param persist_config: If True, config file will be updated when changed + (e.g GCP token refresh). + """ + + if config_dict is None: + raise ConfigException( + 'Invalid kube-config dict. ' + 'No configuration found.') + + loader = _get_kube_config_loader( + config_dict=config_dict, active_context=context, + persist_config=persist_config) + + if client_configuration is None: + config = type.__call__(Configuration) + loader.load_and_set(config) + Configuration.set_default(config) + else: + loader.load_and_set(client_configuration) def new_client_from_config( config_file=None, diff --git a/config/kube_config_test.py b/config/kube_config_test.py index c8a4c93b..25508d8b 100644 --- a/config/kube_config_test.py +++ b/config/kube_config_test.py @@ -33,9 +33,10 @@ ConfigNode, FileOrData, KubeConfigLoader, KubeConfigMerger, _cleanup_temp_files, _create_temp_file_with_content, + _get_kube_config_loader, _get_kube_config_loader_for_yaml_file, list_kube_config_contexts, load_kube_config, - new_client_from_config) + load_kube_config_from_dict, new_client_from_config) BEARER_TOKEN_FORMAT = "Bearer %s" @@ -1229,6 +1230,16 @@ def test_load_kube_config(self): client_configuration=actual) self.assertEqual(expected, actual) + def test_load_kube_config_from_dict(self): + expected = FakeConfig(host=TEST_HOST, + token=BEARER_TOKEN_FORMAT % TEST_DATA_BASE64) + + actual = FakeConfig() + load_kube_config_from_dict(config_dict=self.TEST_KUBE_CONFIG, + context="simple_token", + client_configuration=actual) + self.assertEqual(expected, actual) + def test_list_kube_config_contexts(self): config_file = self._create_temp_file( yaml.safe_dump(self.TEST_KUBE_CONFIG)) @@ -1344,6 +1355,30 @@ def test__get_kube_config_loader_for_yaml_file_persist(self): self.assertTrue(callable(actual._config_persister)) self.assertEquals(actual._config_persister.__name__, "save_changes") + def test__get_kube_config_loader_file_no_persist(self): + expected = FakeConfig(host=TEST_HOST, + token=BEARER_TOKEN_FORMAT % TEST_DATA_BASE64) + config_file = self._create_temp_file( + yaml.safe_dump(self.TEST_KUBE_CONFIG)) + actual = _get_kube_config_loader(filename=config_file) + self.assertIsNone(actual._config_persister) + + def test__get_kube_config_loader_file_persist(self): + expected = FakeConfig(host=TEST_HOST, + token=BEARER_TOKEN_FORMAT % TEST_DATA_BASE64) + config_file = self._create_temp_file( + yaml.safe_dump(self.TEST_KUBE_CONFIG)) + actual = _get_kube_config_loader(filename=config_file, + persist_config=True) + self.assertTrue(callable(actual._config_persister)) + self.assertEquals(actual._config_persister.__name__, "save_changes") + + def test__get_kube_config_loader_dict_no_persist(self): + expected = FakeConfig(host=TEST_HOST, + token=BEARER_TOKEN_FORMAT % TEST_DATA_BASE64) + actual = _get_kube_config_loader( + config_dict=self.TEST_KUBE_CONFIG) + self.assertIsNone(actual._config_persister) class TestKubernetesClientConfiguration(BaseTestCase): # Verifies properties of kubernetes.client.Configuration.