From 9d8ea53149b21ff64d1fa5911eecb54ff3dc2244 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Fri, 8 Jun 2018 15:14:06 -0700 Subject: Allow passing of env overrides to credstore through APIClient ctor Signed-off-by: Joffrey F --- docker/api/build.py | 3 ++- docker/api/client.py | 6 +++++- docker/api/daemon.py | 4 +++- docker/auth.py | 13 ++++++++----- docker/client.py | 9 +++++++-- requirements.txt | 2 +- setup.py | 2 +- tests/unit/api_test.py | 2 +- 8 files changed, 28 insertions(+), 13 deletions(-) diff --git a/docker/api/build.py b/docker/api/build.py index 3c3f130..419255f 100644 --- a/docker/api/build.py +++ b/docker/api/build.py @@ -302,7 +302,8 @@ class BuildApiMixin(object): # credentials/native_store.go#L68-L83 for registry in self._auth_configs.get('auths', {}).keys(): auth_data[registry] = auth.resolve_authconfig( - self._auth_configs, registry + self._auth_configs, registry, + credstore_env=self.credstore_env, ) else: auth_data = self._auth_configs.get('auths', {}).copy() diff --git a/docker/api/client.py b/docker/api/client.py index 13c292a..91da1c8 100644 --- a/docker/api/client.py +++ b/docker/api/client.py @@ -83,6 +83,8 @@ class APIClient( :py:class:`~docker.tls.TLSConfig` object to use custom configuration. user_agent (str): Set a custom user agent for requests to the server. + credstore_env (dict): Override environment variables when calling the + credential store process. """ __attrs__ = requests.Session.__attrs__ + ['_auth_configs', @@ -93,7 +95,8 @@ class APIClient( def __init__(self, base_url=None, version=None, timeout=DEFAULT_TIMEOUT_SECONDS, tls=False, - user_agent=DEFAULT_USER_AGENT, num_pools=DEFAULT_NUM_POOLS): + user_agent=DEFAULT_USER_AGENT, num_pools=DEFAULT_NUM_POOLS, + credstore_env=None): super(APIClient, self).__init__() if tls and not base_url: @@ -109,6 +112,7 @@ class APIClient( self._auth_configs = auth.load_config( config_dict=self._general_configs ) + self.credstore_env = credstore_env base_url = utils.parse_host( base_url, IS_WINDOWS_PLATFORM, tls=bool(tls) diff --git a/docker/api/daemon.py b/docker/api/daemon.py index fc3692c..76a94cf 100644 --- a/docker/api/daemon.py +++ b/docker/api/daemon.py @@ -128,7 +128,9 @@ class DaemonApiMixin(object): elif not self._auth_configs: self._auth_configs = auth.load_config() - authcfg = auth.resolve_authconfig(self._auth_configs, registry) + authcfg = auth.resolve_authconfig( + self._auth_configs, registry, credstore_env=self.credstore_env, + ) # If we found an existing auth config for this registry and username # combination, we can return it immediately unless reauth is requested. if authcfg and authcfg.get('username', None) == username \ diff --git a/docker/auth.py b/docker/auth.py index 48fcd8b..0c0cb20 100644 --- a/docker/auth.py +++ b/docker/auth.py @@ -44,7 +44,9 @@ def get_config_header(client, registry): "No auth config in memory - loading from filesystem" ) client._auth_configs = load_config() - authcfg = resolve_authconfig(client._auth_configs, registry) + authcfg = resolve_authconfig( + client._auth_configs, registry, credstore_env=client.credstore_env + ) # Do not fail here if no authentication exists for this # specific registry as we can have a readonly pull. Just # put the header if we can. @@ -76,7 +78,7 @@ def get_credential_store(authconfig, registry): ) -def resolve_authconfig(authconfig, registry=None): +def resolve_authconfig(authconfig, registry=None, credstore_env=None): """ Returns the authentication data from the given auth configuration for a specific registry. As with the Docker client, legacy entries in the config @@ -91,7 +93,7 @@ def resolve_authconfig(authconfig, registry=None): 'Using credentials store "{0}"'.format(store_name) ) cfg = _resolve_authconfig_credstore( - authconfig, registry, store_name + authconfig, registry, store_name, env=credstore_env ) if cfg is not None: return cfg @@ -115,13 +117,14 @@ def resolve_authconfig(authconfig, registry=None): return None -def _resolve_authconfig_credstore(authconfig, registry, credstore_name): +def _resolve_authconfig_credstore(authconfig, registry, credstore_name, + env=None): if not registry or registry == INDEX_NAME: # The ecosystem is a little schizophrenic with index.docker.io VS # docker.io - in that case, it seems the full URL is necessary. registry = INDEX_URL log.debug("Looking for auth entry for {0}".format(repr(registry))) - store = dockerpycreds.Store(credstore_name) + store = dockerpycreds.Store(credstore_name, environment=env) try: data = store.get(registry) res = { diff --git a/docker/client.py b/docker/client.py index b4364c3..8d4a52b 100644 --- a/docker/client.py +++ b/docker/client.py @@ -33,6 +33,8 @@ class DockerClient(object): :py:class:`~docker.tls.TLSConfig` object to use custom configuration. user_agent (str): Set a custom user agent for requests to the server. + credstore_env (dict): Override environment variables when calling the + credential store process. """ def __init__(self, *args, **kwargs): self.api = APIClient(*args, **kwargs) @@ -66,6 +68,8 @@ class DockerClient(object): assert_hostname (bool): Verify the hostname of the server. environment (dict): The environment to read environment variables from. Default: the value of ``os.environ`` + credstore_env (dict): Override environment variables when calling + the credential store process. Example: @@ -77,8 +81,9 @@ class DockerClient(object): """ timeout = kwargs.pop('timeout', DEFAULT_TIMEOUT_SECONDS) version = kwargs.pop('version', None) - return cls(timeout=timeout, version=version, - **kwargs_from_env(**kwargs)) + return cls( + timeout=timeout, version=version, **kwargs_from_env(**kwargs) + ) # Resources @property diff --git a/requirements.txt b/requirements.txt index 9079315..6c5e7d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ asn1crypto==0.22.0 backports.ssl-match-hostname==3.5.0.1 cffi==1.10.0 cryptography==1.9 -docker-pycreds==0.2.3 +docker-pycreds==0.3.0 enum34==1.1.6 idna==2.5 ipaddress==1.0.18 diff --git a/setup.py b/setup.py index c1eabcf..57b2b5a 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ requirements = [ 'requests >= 2.14.2, != 2.18.0', 'six >= 1.4.0', 'websocket-client >= 0.32.0', - 'docker-pycreds >= 0.2.3' + 'docker-pycreds >= 0.3.0' ] extras_require = { diff --git a/tests/unit/api_test.py b/tests/unit/api_test.py index ba80840..af2bb1c 100644 --- a/tests/unit/api_test.py +++ b/tests/unit/api_test.py @@ -44,7 +44,7 @@ def response(status_code=200, content='', headers=None, reason=None, elapsed=0, return res -def fake_resolve_authconfig(authconfig, registry=None): +def fake_resolve_authconfig(authconfig, registry=None, *args, **kwargs): return None -- cgit v1.2.1