diff options
author | shin- <joffrey@dotcloud.com> | 2013-10-15 19:19:20 +0200 |
---|---|---|
committer | shin- <joffrey@dotcloud.com> | 2013-10-15 19:19:20 +0200 |
commit | 0808905636003164b3ecc976d32c191016f29196 (patch) | |
tree | f521f5c9386ae50773e99089a2a9cb16030c7a2a /docker/auth | |
parent | 07d791d50c7105caf76b4e8090a26870c5b683ea (diff) | |
parent | 128cdb9112389f18d864dd2cb11bc584a0af55da (diff) | |
download | docker-py-0808905636003164b3ecc976d32c191016f29196.tar.gz |
Refactoring, Python 3 compatibility, Tests working with python 3, cleaned up imports.
Diffstat (limited to 'docker/auth')
-rw-r--r-- | docker/auth/__init__.py | 1 | ||||
-rw-r--r-- | docker/auth/auth.py | 130 |
2 files changed, 131 insertions, 0 deletions
diff --git a/docker/auth/__init__.py b/docker/auth/__init__.py new file mode 100644 index 0000000..d7c8ad3 --- /dev/null +++ b/docker/auth/__init__.py @@ -0,0 +1 @@ +from .auth import *
\ No newline at end of file diff --git a/docker/auth/auth.py b/docker/auth/auth.py new file mode 100644 index 0000000..22a9f96 --- /dev/null +++ b/docker/auth/auth.py @@ -0,0 +1,130 @@ +# Copyright 2013 dotCloud inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import base64 +import json +import os + +import six + +import docker.utils as utils + +INDEX_URL = 'https://index.docker.io/v1/' + + +def swap_protocol(url): + if url.startswith('http://'): + return url.replace('http://', 'https://', 1) + if url.startswith('https://'): + return url.replace('https://', 'http://', 1) + return url + + +def expand_registry_url(hostname): + if hostname.startswith('http:') or hostname.startswith('https:'): + if '/' not in hostname[9:]: + hostname = hostname + '/v1/' + return hostname + if utils.ping('https://' + hostname + '_ping'): + return 'https://' + hostname + '/v1/' + return 'http://' + hostname + '/v1/' + + +def resolve_repository_name(repo_name): + if '://' in repo_name: + raise ValueError('Repository name can not contain a' + 'scheme ({0})'.format(repo_name)) + parts = repo_name.split('/', 1) + if not '.' in parts[0] and not ':' in parts[0] and parts[0] != 'localhost': + # This is a docker index repo (ex: foo/bar or ubuntu) + return INDEX_URL, repo_name + if len(parts) < 2: + raise ValueError('Invalid repository name ({0})'.format(repo_name)) + + if 'index.docker.io' in parts[0]: + raise ValueError('Invalid repository name,' + 'try "{0}" instead'.format(parts[1])) + + return expand_registry_url(parts[0]), parts[1] + + +def resolve_authconfig(authconfig, registry): + default = {} + if registry == INDEX_URL or registry == '': + # default to the index server + return authconfig['Configs'].get(INDEX_URL, default) + # if its not the index server there are three cases: + # + # 1. this is a full config url -> it should be used as is + # 2. it could be a full url, but with the wrong protocol + # 3. it can be the hostname optionally with a port + # + # as there is only one auth entry which is fully qualified we need to start + # parsing and matching + if '/' not in registry: + registry = registry + '/v1/' + if not registry.startswith('http:') and not registry.startswith('https:'): + registry = 'https://' + registry + + if registry in authconfig['Configs']: + return authconfig['Configs'][registry] + elif swap_protocol(registry) in authconfig['Configs']: + return authconfig['Configs'][swap_protocol(registry)] + return default + + +def decode_auth(auth): + if isinstance(auth, six.string_types): + auth = auth.encode('ascii') + s = base64.b64decode(auth) + login, pwd = s.split(b':') + return login, pwd + + +def encode_header(auth): + auth_json = json.dumps(auth) + return base64.b64encode(auth_json) + + +def load_config(root=None): + if root is None: + root = os.environ['HOME'] + config_file = { + 'Configs': {}, + 'rootPath': root + } + f = open(os.path.join(root, '.dockercfg')) + try: + config_file['Configs'] = json.load(f) + for k, conf in six.iteritems(config_file['Configs']): + conf['Username'], conf['Password'] = decode_auth(conf['auth']) + del conf['auth'] + config_file['Configs'][k] = conf + except Exception: + f.seek(0) + buf = [] + for line in f: + k, v = line.split(' = ') + buf.append(v) + if len(buf) < 2: + raise Exception("The Auth config file is empty") + user, pwd = decode_auth(buf[0]) + config_file['Configs'][INDEX_URL] = { + 'Username': user, + 'Password': pwd, + 'Email': buf[1] + } + finally: + f.close() + return config_file |