Skip to content

Commit be8c144

Browse files
authored
Merge pull request #1662 from docker/1633-credhelpers-support
Support credHelpers section in config.json
2 parents 28e76a6 + 320c810 commit be8c144

File tree

2 files changed

+74
-7
lines changed

2 files changed

+74
-7
lines changed

docker/auth.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,33 @@ def split_repo_name(repo_name):
7070
return tuple(parts)
7171

7272

73+
def get_credential_store(authconfig, registry):
74+
if not registry or registry == INDEX_NAME:
75+
registry = 'https://index.docker.io/v1/'
76+
77+
return authconfig.get('credHelpers', {}).get(registry) or authconfig.get(
78+
'credsStore'
79+
)
80+
81+
7382
def resolve_authconfig(authconfig, registry=None):
7483
"""
7584
Returns the authentication data from the given auth configuration for a
7685
specific registry. As with the Docker client, legacy entries in the config
7786
with full URLs are stripped down to hostnames before checking for a match.
7887
Returns None if no match was found.
7988
"""
80-
if 'credsStore' in authconfig:
81-
log.debug(
82-
'Using credentials store "{0}"'.format(authconfig['credsStore'])
83-
)
84-
return _resolve_authconfig_credstore(
85-
authconfig, registry, authconfig['credsStore']
86-
)
89+
90+
if 'credHelpers' in authconfig or 'credsStore' in authconfig:
91+
store_name = get_credential_store(authconfig, registry)
92+
if store_name is not None:
93+
log.debug(
94+
'Using credentials store "{0}"'.format(store_name)
95+
)
96+
return _resolve_authconfig_credstore(
97+
authconfig, registry, store_name
98+
)
99+
87100
# Default to the public index server
88101
registry = resolve_index_name(registry) if registry else INDEX_NAME
89102
log.debug("Looking for auth entry for {0}".format(repr(registry)))
@@ -274,6 +287,9 @@ def load_config(config_path=None):
274287
if data.get('credsStore'):
275288
log.debug("Found 'credsStore' section")
276289
res.update({'credsStore': data['credsStore']})
290+
if data.get('credHelpers'):
291+
log.debug("Found 'credHelpers' section")
292+
res.update({'credHelpers': data['credHelpers']})
277293
if res:
278294
return res
279295
else:

tests/unit/auth_test.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,57 @@ def test_resolve_registry_and_auth_unauthenticated_registry(self):
272272
)
273273

274274

275+
class CredStoreTest(unittest.TestCase):
276+
def test_get_credential_store(self):
277+
auth_config = {
278+
'credHelpers': {
279+
'registry1.io': 'truesecret',
280+
'registry2.io': 'powerlock'
281+
},
282+
'credsStore': 'blackbox',
283+
}
284+
285+
assert auth.get_credential_store(
286+
auth_config, 'registry1.io'
287+
) == 'truesecret'
288+
assert auth.get_credential_store(
289+
auth_config, 'registry2.io'
290+
) == 'powerlock'
291+
assert auth.get_credential_store(
292+
auth_config, 'registry3.io'
293+
) == 'blackbox'
294+
295+
def test_get_credential_store_no_default(self):
296+
auth_config = {
297+
'credHelpers': {
298+
'registry1.io': 'truesecret',
299+
'registry2.io': 'powerlock'
300+
},
301+
}
302+
assert auth.get_credential_store(
303+
auth_config, 'registry2.io'
304+
) == 'powerlock'
305+
assert auth.get_credential_store(
306+
auth_config, 'registry3.io'
307+
) is None
308+
309+
def test_get_credential_store_default_index(self):
310+
auth_config = {
311+
'credHelpers': {
312+
'https://index.docker.io/v1/': 'powerlock'
313+
},
314+
'credsStore': 'truesecret'
315+
}
316+
317+
assert auth.get_credential_store(auth_config, None) == 'powerlock'
318+
assert auth.get_credential_store(
319+
auth_config, 'docker.io'
320+
) == 'powerlock'
321+
assert auth.get_credential_store(
322+
auth_config, 'images.io'
323+
) == 'truesecret'
324+
325+
275326
class FindConfigFileTest(unittest.TestCase):
276327
def tmpdir(self, name):
277328
tmpdir = ensuretemp(name)

0 commit comments

Comments
 (0)