Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docker/auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import os

import dockerpycreds
import six

from .. import errors
Expand All @@ -11,6 +12,7 @@
INDEX_URL = 'https://{0}/v1/'.format(INDEX_NAME)
DOCKER_CONFIG_FILENAME = os.path.join('.docker', 'config.json')
LEGACY_DOCKER_CONFIG_FILENAME = '.dockercfg'
TOKEN_USERNAME = '<token>'

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -74,6 +76,13 @@ def resolve_authconfig(authconfig, registry=None):
with full URLs are stripped down to hostnames before checking for a match.
Returns None if no match was found.
"""
if 'credsStore' in authconfig:
log.debug(
'Using credentials store "{0}"'.format(authconfig['credsStore'])
)
return _resolve_authconfig_credstore(
authconfig, registry, authconfig['credsStore']
)
# Default to the public index server
registry = resolve_index_name(registry) if registry else INDEX_NAME
log.debug("Looking for auth entry for {0}".format(repr(registry)))
Expand All @@ -91,6 +100,35 @@ def resolve_authconfig(authconfig, registry=None):
return None


def _resolve_authconfig_credstore(authconfig, registry, credstore_name):
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 = 'https://index.docker.io/v1/'
log.debug("Looking for auth entry for {0}".format(repr(registry)))
store = dockerpycreds.Store(credstore_name)
try:
data = store.get(registry)
res = {
'ServerAddress': registry,
}
if data['Username'] == TOKEN_USERNAME:
res['IdentityToken'] = data['Secret']
else:
res.update({
'Username': data['Username'],
'Password': data['Secret'],
})
return res
except dockerpycreds.CredentialsNotFound as e:
log.debug('No entry found')
return None
except dockerpycreds.StoreError as e:
raise errors.DockerException(
'Credentials store error: {0}'.format(repr(e))
)


def convert_to_hostname(url):
return url.replace('http://', '').replace('https://', '').split('/', 1)[0]

Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ requests==2.5.3
six>=1.4.0
websocket-client==0.32.0
backports.ssl_match_hostname>=3.5 ; python_version < '3.5'
ipaddress==1.0.16 ; python_version < '3.3'
ipaddress==1.0.16 ; python_version < '3.3'
docker-pycreds==0.2.0
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
'requests >= 2.5.2, < 2.11',
'six >= 1.4.0',
'websocket-client >= 0.32.0',
'docker-pycreds >= 0.2.0'
]

if sys.platform == 'win32':
Expand Down