diff --git a/docker/auth/auth.py b/docker/auth/auth.py index 5607520e..399dae2b 100644 --- a/docker/auth/auth.py +++ b/docker/auth/auth.py @@ -158,7 +158,6 @@ def load_config(config_path=None): explicit config_path parameter > DOCKER_CONFIG environment variable > ~/.docker/config.json > ~/.dockercfg """ - config_file = find_config_file(config_path) if not config_file: @@ -168,11 +167,17 @@ def load_config(config_path=None): try: with open(config_file) as f: data = json.load(f) + res = {} if data.get('auths'): log.debug("Found 'auths' section") - return parse_auth(data['auths']) + res.update(parse_auth(data['auths'])) + if data.get('HttpHeaders'): + log.debug("Found 'HttpHeaders' section") + res.update({'HttpHeaders': data['HttpHeaders']}) + if res: + return res else: - log.debug("Couldn't find 'auths' section") + log.debug("Couldn't find 'auths' or 'HttpHeaders' sections") f.seek(0) return parse_auth(json.load(f)) except (IOError, KeyError, ValueError) as e: diff --git a/docker/client.py b/docker/client.py index e73adb8f..fb186cc7 100644 --- a/docker/client.py +++ b/docker/client.py @@ -28,7 +28,7 @@ from . import errors from .auth import auth from .unixconn import unixconn from .ssladapter import ssladapter -from .utils import utils, check_resource +from .utils import utils, check_resource, update_headers from .tls import TLSConfig @@ -103,15 +103,19 @@ class Client( kwargs.setdefault('timeout', self.timeout) return kwargs + @update_headers def _post(self, url, **kwargs): return self.post(url, **self._set_request_timeout(kwargs)) + @update_headers def _get(self, url, **kwargs): return self.get(url, **self._set_request_timeout(kwargs)) + @update_headers def _put(self, url, **kwargs): return self.put(url, **self._set_request_timeout(kwargs)) + @update_headers def _delete(self, url, **kwargs): return self.delete(url, **self._set_request_timeout(kwargs)) diff --git a/docker/utils/__init__.py b/docker/utils/__init__.py index 2e6d152f..16b08d18 100644 --- a/docker/utils/__init__.py +++ b/docker/utils/__init__.py @@ -8,4 +8,4 @@ from .utils import ( ) # flake8: noqa from .types import Ulimit, LogConfig # flake8: noqa -from .decorators import check_resource, minimum_version # flake8: noqa +from .decorators import check_resource, minimum_version, update_headers #flake8: noqa diff --git a/docker/utils/decorators.py b/docker/utils/decorators.py index 7d3b01a7..7c41a5f8 100644 --- a/docker/utils/decorators.py +++ b/docker/utils/decorators.py @@ -35,3 +35,14 @@ def minimum_version(version): return f(self, *args, **kwargs) return wrapper return decorator + + +def update_headers(f): + def inner(self, *args, **kwargs): + if 'HttpHeaders' in self._auth_configs: + if 'headers' not in kwargs: + kwargs['headers'] = self._auth_configs['HttpHeaders'] + else: + kwargs['headers'].update(self._auth_configs['HttpHeaders']) + return f(self, *args, **kwargs) + return inner diff --git a/tests/unit/auth_test.py b/tests/unit/auth_test.py index a88984f6..3fba602c 100644 --- a/tests/unit/auth_test.py +++ b/tests/unit/auth_test.py @@ -409,3 +409,27 @@ class LoadConfigTest(base.Cleanup, base.BaseTestCase): self.assertEqual(cfg['password'], b'izayoi\xc3\xa6'.decode('utf8')) self.assertEqual(cfg['email'], 'sakuya@scarlet.net') self.assertEqual(cfg.get('auth'), None) + + def test_load_config_custom_config_env_with_headers(self): + folder = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, folder) + + dockercfg_path = os.path.join(folder, 'config.json') + config = { + 'HttpHeaders': { + 'Name': 'Spike', + 'Surname': 'Spiegel' + }, + } + + with open(dockercfg_path, 'w') as f: + json.dump(config, f) + + with mock.patch.dict(os.environ, {'DOCKER_CONFIG': folder}): + cfg = auth.load_config(None) + assert 'HttpHeaders' in cfg + self.assertNotEqual(cfg['HttpHeaders'], None) + cfg = cfg['HttpHeaders'] + + self.assertEqual(cfg['Name'], 'Spike') + self.assertEqual(cfg['Surname'], 'Spiegel')