Kaydet (Commit) f1189bfb authored tarafından Joffrey F's avatar Joffrey F Kaydeden (comit) Joffrey F

Allow passing of env overrides to credstore through APIClient ctor

Signed-off-by: 's avatarJoffrey F <joffrey@docker.com>
üst 2d0c5dd4
...@@ -302,7 +302,8 @@ class BuildApiMixin(object): ...@@ -302,7 +302,8 @@ class BuildApiMixin(object):
# credentials/native_store.go#L68-L83 # credentials/native_store.go#L68-L83
for registry in self._auth_configs.get('auths', {}).keys(): for registry in self._auth_configs.get('auths', {}).keys():
auth_data[registry] = auth.resolve_authconfig( auth_data[registry] = auth.resolve_authconfig(
self._auth_configs, registry self._auth_configs, registry,
credstore_env=self.credstore_env,
) )
else: else:
auth_data = self._auth_configs.get('auths', {}).copy() auth_data = self._auth_configs.get('auths', {}).copy()
......
...@@ -83,6 +83,8 @@ class APIClient( ...@@ -83,6 +83,8 @@ class APIClient(
:py:class:`~docker.tls.TLSConfig` object to use custom :py:class:`~docker.tls.TLSConfig` object to use custom
configuration. configuration.
user_agent (str): Set a custom user agent for requests to the server. 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', __attrs__ = requests.Session.__attrs__ + ['_auth_configs',
...@@ -93,7 +95,8 @@ class APIClient( ...@@ -93,7 +95,8 @@ class APIClient(
def __init__(self, base_url=None, version=None, def __init__(self, base_url=None, version=None,
timeout=DEFAULT_TIMEOUT_SECONDS, tls=False, 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__() super(APIClient, self).__init__()
if tls and not base_url: if tls and not base_url:
...@@ -109,6 +112,7 @@ class APIClient( ...@@ -109,6 +112,7 @@ class APIClient(
self._auth_configs = auth.load_config( self._auth_configs = auth.load_config(
config_dict=self._general_configs config_dict=self._general_configs
) )
self.credstore_env = credstore_env
base_url = utils.parse_host( base_url = utils.parse_host(
base_url, IS_WINDOWS_PLATFORM, tls=bool(tls) base_url, IS_WINDOWS_PLATFORM, tls=bool(tls)
......
...@@ -128,7 +128,9 @@ class DaemonApiMixin(object): ...@@ -128,7 +128,9 @@ class DaemonApiMixin(object):
elif not self._auth_configs: elif not self._auth_configs:
self._auth_configs = auth.load_config() 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 # If we found an existing auth config for this registry and username
# combination, we can return it immediately unless reauth is requested. # combination, we can return it immediately unless reauth is requested.
if authcfg and authcfg.get('username', None) == username \ if authcfg and authcfg.get('username', None) == username \
......
...@@ -44,7 +44,9 @@ def get_config_header(client, registry): ...@@ -44,7 +44,9 @@ def get_config_header(client, registry):
"No auth config in memory - loading from filesystem" "No auth config in memory - loading from filesystem"
) )
client._auth_configs = load_config() 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 # Do not fail here if no authentication exists for this
# specific registry as we can have a readonly pull. Just # specific registry as we can have a readonly pull. Just
# put the header if we can. # put the header if we can.
...@@ -76,7 +78,7 @@ def get_credential_store(authconfig, registry): ...@@ -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 Returns the authentication data from the given auth configuration for a
specific registry. As with the Docker client, legacy entries in the config specific registry. As with the Docker client, legacy entries in the config
...@@ -91,7 +93,7 @@ def resolve_authconfig(authconfig, registry=None): ...@@ -91,7 +93,7 @@ def resolve_authconfig(authconfig, registry=None):
'Using credentials store "{0}"'.format(store_name) 'Using credentials store "{0}"'.format(store_name)
) )
cfg = _resolve_authconfig_credstore( cfg = _resolve_authconfig_credstore(
authconfig, registry, store_name authconfig, registry, store_name, env=credstore_env
) )
if cfg is not None: if cfg is not None:
return cfg return cfg
...@@ -115,13 +117,14 @@ def resolve_authconfig(authconfig, registry=None): ...@@ -115,13 +117,14 @@ def resolve_authconfig(authconfig, registry=None):
return 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: if not registry or registry == INDEX_NAME:
# The ecosystem is a little schizophrenic with index.docker.io VS # The ecosystem is a little schizophrenic with index.docker.io VS
# docker.io - in that case, it seems the full URL is necessary. # docker.io - in that case, it seems the full URL is necessary.
registry = INDEX_URL registry = INDEX_URL
log.debug("Looking for auth entry for {0}".format(repr(registry))) log.debug("Looking for auth entry for {0}".format(repr(registry)))
store = dockerpycreds.Store(credstore_name) store = dockerpycreds.Store(credstore_name, environment=env)
try: try:
data = store.get(registry) data = store.get(registry)
res = { res = {
......
...@@ -33,6 +33,8 @@ class DockerClient(object): ...@@ -33,6 +33,8 @@ class DockerClient(object):
:py:class:`~docker.tls.TLSConfig` object to use custom :py:class:`~docker.tls.TLSConfig` object to use custom
configuration. configuration.
user_agent (str): Set a custom user agent for requests to the server. 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): def __init__(self, *args, **kwargs):
self.api = APIClient(*args, **kwargs) self.api = APIClient(*args, **kwargs)
...@@ -66,6 +68,8 @@ class DockerClient(object): ...@@ -66,6 +68,8 @@ class DockerClient(object):
assert_hostname (bool): Verify the hostname of the server. assert_hostname (bool): Verify the hostname of the server.
environment (dict): The environment to read environment variables environment (dict): The environment to read environment variables
from. Default: the value of ``os.environ`` from. Default: the value of ``os.environ``
credstore_env (dict): Override environment variables when calling
the credential store process.
Example: Example:
...@@ -77,8 +81,9 @@ class DockerClient(object): ...@@ -77,8 +81,9 @@ class DockerClient(object):
""" """
timeout = kwargs.pop('timeout', DEFAULT_TIMEOUT_SECONDS) timeout = kwargs.pop('timeout', DEFAULT_TIMEOUT_SECONDS)
version = kwargs.pop('version', None) version = kwargs.pop('version', None)
return cls(timeout=timeout, version=version, return cls(
**kwargs_from_env(**kwargs)) timeout=timeout, version=version, **kwargs_from_env(**kwargs)
)
# Resources # Resources
@property @property
......
...@@ -3,7 +3,7 @@ asn1crypto==0.22.0 ...@@ -3,7 +3,7 @@ asn1crypto==0.22.0
backports.ssl-match-hostname==3.5.0.1 backports.ssl-match-hostname==3.5.0.1
cffi==1.10.0 cffi==1.10.0
cryptography==1.9 cryptography==1.9
docker-pycreds==0.2.3 docker-pycreds==0.3.0
enum34==1.1.6 enum34==1.1.6
idna==2.5 idna==2.5
ipaddress==1.0.18 ipaddress==1.0.18
......
...@@ -13,7 +13,7 @@ requirements = [ ...@@ -13,7 +13,7 @@ requirements = [
'requests >= 2.14.2, != 2.18.0', 'requests >= 2.14.2, != 2.18.0',
'six >= 1.4.0', 'six >= 1.4.0',
'websocket-client >= 0.32.0', 'websocket-client >= 0.32.0',
'docker-pycreds >= 0.2.3' 'docker-pycreds >= 0.3.0'
] ]
extras_require = { extras_require = {
......
...@@ -44,7 +44,7 @@ def response(status_code=200, content='', headers=None, reason=None, elapsed=0, ...@@ -44,7 +44,7 @@ def response(status_code=200, content='', headers=None, reason=None, elapsed=0,
return res return res
def fake_resolve_authconfig(authconfig, registry=None): def fake_resolve_authconfig(authconfig, registry=None, *args, **kwargs):
return None return None
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment