summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <joffrey@docker.com>2016-09-02 19:59:47 -0700
committerJoffrey F <joffrey@docker.com>2016-09-06 15:17:36 -0700
commitfbe1686e629804fb47dabea1eda5c6d664f0a6b7 (patch)
treed1cea57f6e5ff2987e5fc5d931ccb01d839dfe23
parent545c5ac3cca04fbb95622f2440e15af186ff19fd (diff)
downloaddocker-py-fbe1686e629804fb47dabea1eda5c6d664f0a6b7.tar.gz
Add credentials store support
Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r--docker/auth/auth.py37
-rw-r--r--requirements.txt3
-rw-r--r--setup.py1
3 files changed, 40 insertions, 1 deletions
diff --git a/docker/auth/auth.py b/docker/auth/auth.py
index 50f86f6..fdaa7b5 100644
--- a/docker/auth/auth.py
+++ b/docker/auth/auth.py
@@ -3,6 +3,7 @@ import json
import logging
import os
+import dockerpycreds
import six
from .. import errors
@@ -11,6 +12,7 @@ INDEX_NAME = 'docker.io'
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__)
@@ -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)))
@@ -91,6 +100,34 @@ 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)))
+ if registry not in authconfig:
+ log.debug("No entry found")
+ 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.StoreError as e:
+ log.error('Credentials store error: {0}'.format(repr(e)))
+
+ return None
+
+
def convert_to_hostname(url):
return url.replace('http://', '').replace('https://', '').split('/', 1)[0]
diff --git a/requirements.txt b/requirements.txt
index a79b7bf..078163a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -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' \ No newline at end of file
+ipaddress==1.0.16 ; python_version < '3.3'
+docker-pycreds==0.1.0 \ No newline at end of file
diff --git a/setup.py b/setup.py
index c809321..3877e96 100644
--- a/setup.py
+++ b/setup.py
@@ -12,6 +12,7 @@ requirements = [
'requests >= 2.5.2, < 2.11',
'six >= 1.4.0',
'websocket-client >= 0.32.0',
+ 'docker-pycreds >= 0.1.0'
]
if sys.platform == 'win32':