diff --git a/botocore/session.py b/botocore/session.py index fc1eb83c8c..cf28f2926b 100644 --- a/botocore/session.py +++ b/botocore/session.py @@ -170,7 +170,6 @@ def _register_credential_provider(self): 'credential_provider', lambda: botocore.credentials.create_credential_resolver(self)) - def _reset_components(self): self._register_credential_provider() @@ -359,10 +358,23 @@ def full_config(self): """ if self._config is None: try: - self._config = botocore.config.load_config( - self.get_config_variable('config_file')) + config_file = self.get_config_variable('config_file') + self._config = botocore.config.load_config(config_file) except ConfigNotFound: self._config = {'profiles': {}} + try: + # Now we need to inject the profiles from the + # credentials file. We don't actually need the values + # in the creds file, only the profile names so that we + # can validate the user is not referring to a nonexistent + # profile. + cred_file = self.get_config_variable('credentials_file') + cred_profiles = botocore.config.raw_config_parse(cred_file) + for profile in cred_profiles: + if profile not in self._config['profiles']: + self._config['profiles'][profile] = {} + except ConfigNotFound: + pass return self._config def set_credentials(self, access_key, secret_key, token=None): @@ -643,6 +655,9 @@ def get_component(self, name): def register_component(self, name, component): self._components.register_component(name, component) + def lazy_register_component(self, name, component): + self._components.lazy_register_component(name, component) + class ComponentLocator(object): """Service locator for session components.""" diff --git a/tests/__init__.py b/tests/__init__.py index 2b4c5953fc..ac74ee0320 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -14,6 +14,11 @@ import os import sys import mock +import time +import random +import shutil +import contextlib +import tempfile # The unittest module got a significant overhaul @@ -36,7 +41,32 @@ def create_session(**kwargs): # so that we reused the same models across tests. base_args = {'loader': _LOADER} base_args.update(kwargs) - return botocore.session.Session(**base_args) + session = botocore.session.Session(**base_args) + session.set_config_variable('credentials_file', 'noexist/foo/botocore') + return session + + +@contextlib.contextmanager +def temporary_file(mode): + """This is a cross platform temporary file creation. + + tempfile.NamedTemporary file on windows creates a secure temp file + that can't be read by other processes and can't be opened a second time. + + For tests, we generally *want* them to be read multiple times. + The test fixture writes the temp file contents, the test reads the + temp file. + + """ + temporary_directory = tempfile.mkdtemp() + basename = 'tmpfile-%s-%s' % (int(time.time()), random.randint(1, 1000)) + full_filename = os.path.join(temporary_directory, basename) + open(full_filename, 'w').close() + try: + with open(full_filename, mode) as f: + yield f + finally: + shutil.rmtree(temporary_directory) class BaseEnvVar(unittest.TestCase): diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index 680d16cd18..fde5d1d853 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -13,7 +13,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -from tests import unittest, create_session +from tests import unittest, create_session, temporary_file import os import logging import tempfile @@ -287,5 +287,17 @@ def test_can_append_to_user_agent(self): self.assertTrue(self.session.user_agent().endswith('custom-thing/other')) +class TestConfigLoaderObject(BaseSessionTest): + def test_config_loader_delegation(self): + with temporary_file('w') as f: + f.write('[credfile-profile]\naws_access_key_id=a\n') + f.write('aws_secret_access_key=b\n') + f.flush() + self.session.set_config_variable('credentials_file', f.name) + self.session.profile = 'credfile-profile' + # Now trying to retrieve the scoped config should not fail. + self.assertEqual(self.session.get_scoped_config(), {}) + + if __name__ == "__main__": unittest.main()