Unverified Kaydet (Commit) c344660f authored tarafından Joffrey F's avatar Joffrey F Kaydeden (comit) GitHub

Merge pull request #2188 from docker/c6374-credhelpers

Modernize auth management
...@@ -288,36 +288,18 @@ class BuildApiMixin(object): ...@@ -288,36 +288,18 @@ class BuildApiMixin(object):
# file one more time in case anything showed up in there. # file one more time in case anything showed up in there.
if not self._auth_configs: if not self._auth_configs:
log.debug("No auth config in memory - loading from filesystem") log.debug("No auth config in memory - loading from filesystem")
self._auth_configs = auth.load_config() self._auth_configs = auth.load_config(
credsore_env=self.credsore_env
)
# Send the full auth configuration (if any exists), since the build # Send the full auth configuration (if any exists), since the build
# could use any (or all) of the registries. # could use any (or all) of the registries.
if self._auth_configs: if self._auth_configs:
auth_cfgs = self._auth_configs auth_data = self._auth_configs.get_all_credentials()
auth_data = {}
if auth_cfgs.get('credsStore'): # See https://github.com/docker/docker-py/issues/1683
# Using a credentials store, we need to retrieve the if auth.INDEX_URL not in auth_data and auth.INDEX_URL in auth_data:
# credentials for each registry listed in the config.json file auth_data[auth.INDEX_URL] = auth_data.get(auth.INDEX_NAME, {})
# Matches CLI behavior: https://github.com/docker/docker/blob/
# 67b85f9d26f1b0b2b240f2d794748fac0f45243c/cliconfig/
# credentials/native_store.go#L68-L83
for registry in auth_cfgs.get('auths', {}).keys():
auth_data[registry] = auth.resolve_authconfig(
auth_cfgs, registry,
credstore_env=self.credstore_env,
)
else:
for registry in auth_cfgs.get('credHelpers', {}).keys():
auth_data[registry] = auth.resolve_authconfig(
auth_cfgs, registry,
credstore_env=self.credstore_env
)
for registry, creds in auth_cfgs.get('auths', {}).items():
if registry not in auth_data:
auth_data[registry] = creds
# See https://github.com/docker/docker-py/issues/1683
if auth.INDEX_NAME in auth_data:
auth_data[auth.INDEX_URL] = auth_data[auth.INDEX_NAME]
log.debug( log.debug(
'Sending auth config ({0})'.format( 'Sending auth config ({0})'.format(
...@@ -325,9 +307,10 @@ class BuildApiMixin(object): ...@@ -325,9 +307,10 @@ class BuildApiMixin(object):
) )
) )
headers['X-Registry-Config'] = auth.encode_header( if auth_data:
auth_data headers['X-Registry-Config'] = auth.encode_header(
) auth_data
)
else: else:
log.debug('No auth config found') log.debug('No auth config found')
......
...@@ -115,7 +115,7 @@ class APIClient( ...@@ -115,7 +115,7 @@ class APIClient(
self._general_configs = config.load_general_config() self._general_configs = config.load_general_config()
self._auth_configs = auth.load_config( self._auth_configs = auth.load_config(
config_dict=self._general_configs config_dict=self._general_configs, credstore_env=credstore_env,
) )
self.credstore_env = credstore_env self.credstore_env = credstore_env
...@@ -480,4 +480,6 @@ class APIClient( ...@@ -480,4 +480,6 @@ class APIClient(
Returns: Returns:
None None
""" """
self._auth_configs = auth.load_config(dockercfg_path) self._auth_configs = auth.load_config(
dockercfg_path, credstore_env=self.credstore_env
)
...@@ -124,13 +124,15 @@ class DaemonApiMixin(object): ...@@ -124,13 +124,15 @@ class DaemonApiMixin(object):
# If dockercfg_path is passed check to see if the config file exists, # If dockercfg_path is passed check to see if the config file exists,
# if so load that config. # if so load that config.
if dockercfg_path and os.path.exists(dockercfg_path): if dockercfg_path and os.path.exists(dockercfg_path):
self._auth_configs = auth.load_config(dockercfg_path) self._auth_configs = auth.load_config(
dockercfg_path, credstore_env=self.credstore_env
)
elif not self._auth_configs: elif not self._auth_configs:
self._auth_configs = auth.load_config() self._auth_configs = auth.load_config(
credstore_env=self.credstore_env
)
authcfg = auth.resolve_authconfig( authcfg = self._auth_configs.resolve_authconfig(registry)
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 \
...@@ -146,9 +148,7 @@ class DaemonApiMixin(object): ...@@ -146,9 +148,7 @@ class DaemonApiMixin(object):
response = self._post_json(self._url('/auth'), data=req_data) response = self._post_json(self._url('/auth'), data=req_data)
if response.status_code == 200: if response.status_code == 200:
if 'auths' not in self._auth_configs: self._auth_configs.add_auth(registry or auth.INDEX_NAME, req_data)
self._auth_configs['auths'] = {}
self._auth_configs['auths'][registry or auth.INDEX_NAME] = req_data
return self._result(response, json=True) return self._result(response, json=True)
def ping(self): def ping(self):
......
This diff is collapsed.
...@@ -4,7 +4,7 @@ backports.ssl-match-hostname==3.5.0.1 ...@@ -4,7 +4,7 @@ backports.ssl-match-hostname==3.5.0.1
cffi==1.10.0 cffi==1.10.0
cryptography==1.9; python_version == '3.3' cryptography==1.9; python_version == '3.3'
cryptography==2.3; python_version > '3.3' cryptography==2.3; python_version > '3.3'
docker-pycreds==0.3.0 docker-pycreds==0.4.0
enum34==1.1.6 enum34==1.1.6
idna==2.5 idna==2.5
ipaddress==1.0.18 ipaddress==1.0.18
......
...@@ -12,7 +12,7 @@ SOURCE_DIR = os.path.join(ROOT_DIR) ...@@ -12,7 +12,7 @@ SOURCE_DIR = os.path.join(ROOT_DIR)
requirements = [ requirements = [
'six >= 1.4.0', 'six >= 1.4.0',
'websocket-client >= 0.32.0', 'websocket-client >= 0.32.0',
'docker-pycreds >= 0.3.0', 'docker-pycreds >= 0.4.0',
'requests >= 2.14.2, != 2.18.0', 'requests >= 2.14.2, != 2.18.0',
] ]
......
...@@ -65,7 +65,7 @@ class BuildTest(BaseAPIClientTest): ...@@ -65,7 +65,7 @@ class BuildTest(BaseAPIClientTest):
) )
def test_build_remote_with_registry_auth(self): def test_build_remote_with_registry_auth(self):
self.client._auth_configs = { self.client._auth_configs = auth.AuthConfig({
'auths': { 'auths': {
'https://example.com': { 'https://example.com': {
'user': 'example', 'user': 'example',
...@@ -73,7 +73,7 @@ class BuildTest(BaseAPIClientTest): ...@@ -73,7 +73,7 @@ class BuildTest(BaseAPIClientTest):
'email': 'example@example.com' 'email': 'example@example.com'
} }
} }
} })
expected_params = {'t': None, 'q': False, 'dockerfile': None, expected_params = {'t': None, 'q': False, 'dockerfile': None,
'rm': False, 'nocache': False, 'pull': False, 'rm': False, 'nocache': False, 'pull': False,
...@@ -81,7 +81,7 @@ class BuildTest(BaseAPIClientTest): ...@@ -81,7 +81,7 @@ class BuildTest(BaseAPIClientTest):
'remote': 'https://github.com/docker-library/mongo'} 'remote': 'https://github.com/docker-library/mongo'}
expected_headers = { expected_headers = {
'X-Registry-Config': auth.encode_header( 'X-Registry-Config': auth.encode_header(
self.client._auth_configs['auths'] self.client._auth_configs.auths
) )
} }
...@@ -115,7 +115,7 @@ class BuildTest(BaseAPIClientTest): ...@@ -115,7 +115,7 @@ class BuildTest(BaseAPIClientTest):
}) })
def test_set_auth_headers_with_empty_dict_and_auth_configs(self): def test_set_auth_headers_with_empty_dict_and_auth_configs(self):
self.client._auth_configs = { self.client._auth_configs = auth.AuthConfig({
'auths': { 'auths': {
'https://example.com': { 'https://example.com': {
'user': 'example', 'user': 'example',
...@@ -123,12 +123,12 @@ class BuildTest(BaseAPIClientTest): ...@@ -123,12 +123,12 @@ class BuildTest(BaseAPIClientTest):
'email': 'example@example.com' 'email': 'example@example.com'
} }
} }
} })
headers = {} headers = {}
expected_headers = { expected_headers = {
'X-Registry-Config': auth.encode_header( 'X-Registry-Config': auth.encode_header(
self.client._auth_configs['auths'] self.client._auth_configs.auths
) )
} }
...@@ -136,7 +136,7 @@ class BuildTest(BaseAPIClientTest): ...@@ -136,7 +136,7 @@ class BuildTest(BaseAPIClientTest):
assert headers == expected_headers assert headers == expected_headers
def test_set_auth_headers_with_dict_and_auth_configs(self): def test_set_auth_headers_with_dict_and_auth_configs(self):
self.client._auth_configs = { self.client._auth_configs = auth.AuthConfig({
'auths': { 'auths': {
'https://example.com': { 'https://example.com': {
'user': 'example', 'user': 'example',
...@@ -144,12 +144,12 @@ class BuildTest(BaseAPIClientTest): ...@@ -144,12 +144,12 @@ class BuildTest(BaseAPIClientTest):
'email': 'example@example.com' 'email': 'example@example.com'
} }
} }
} })
headers = {'foo': 'bar'} headers = {'foo': 'bar'}
expected_headers = { expected_headers = {
'X-Registry-Config': auth.encode_header( 'X-Registry-Config': auth.encode_header(
self.client._auth_configs['auths'] self.client._auth_configs.auths
), ),
'foo': 'bar' 'foo': 'bar'
} }
......
...@@ -222,13 +222,11 @@ class DockerApiTest(BaseAPIClientTest): ...@@ -222,13 +222,11 @@ class DockerApiTest(BaseAPIClientTest):
'username': 'sakuya', 'password': 'izayoi' 'username': 'sakuya', 'password': 'izayoi'
} }
assert args[1]['headers'] == {'Content-Type': 'application/json'} assert args[1]['headers'] == {'Content-Type': 'application/json'}
assert self.client._auth_configs['auths'] == { assert self.client._auth_configs.auths['docker.io'] == {
'docker.io': { 'email': None,
'email': None, 'password': 'izayoi',
'password': 'izayoi', 'username': 'sakuya',
'username': 'sakuya', 'serveraddress': None,
'serveraddress': None,
}
} }
def test_events(self): def test_events(self):
......
This diff is collapsed.
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