Merge "Support basic auth for image registry" into stable/ussuri
This commit is contained in:
commit
244c32fbcd
|
@ -688,31 +688,48 @@ class BaseImageUploader(object):
|
||||||
raise ImageUploaderException(
|
raise ImageUploaderException(
|
||||||
'Unknown authentication method for headers: %s' % r.headers)
|
'Unknown authentication method for headers: %s' % r.headers)
|
||||||
|
|
||||||
|
auth = None
|
||||||
www_auth = r.headers['www-authenticate']
|
www_auth = r.headers['www-authenticate']
|
||||||
if not www_auth.startswith('Bearer '):
|
|
||||||
raise ImageUploaderException(
|
|
||||||
'Unknown www-authenticate value: %s' % www_auth)
|
|
||||||
token_param = {}
|
token_param = {}
|
||||||
|
|
||||||
realm = re.search('realm="(.*?)"', www_auth).group(1)
|
if www_auth.startswith('Bearer '):
|
||||||
if 'service=' in www_auth:
|
LOG.debug('Using bearer token auth')
|
||||||
token_param['service'] = re.search(
|
realm = re.search('realm="(.*?)"', www_auth).group(1)
|
||||||
'service="(.*?)"', www_auth).group(1)
|
if 'service=' in www_auth:
|
||||||
token_param['scope'] = 'repository:%s:pull' % image[1:]
|
token_param['service'] = re.search(
|
||||||
|
'service="(.*?)"', www_auth).group(1)
|
||||||
|
token_param['scope'] = 'repository:%s:pull' % image[1:]
|
||||||
|
|
||||||
auth = None
|
if username:
|
||||||
if username:
|
auth = requests_auth.HTTPBasicAuth(username, password)
|
||||||
|
LOG.debug('Token parameters: params {}'.format(token_param))
|
||||||
|
rauth = session.get(realm, params=token_param, auth=auth,
|
||||||
|
timeout=30)
|
||||||
|
rauth.raise_for_status()
|
||||||
|
auth_header = 'Bearer %s' % rauth.json()['token']
|
||||||
|
elif www_auth.startswith('Basic '):
|
||||||
|
LOG.debug('Using basic auth')
|
||||||
|
if not username or not password:
|
||||||
|
raise Exception('Authentication credentials required for '
|
||||||
|
'basic auth: %s' % url)
|
||||||
auth = requests_auth.HTTPBasicAuth(username, password)
|
auth = requests_auth.HTTPBasicAuth(username, password)
|
||||||
LOG.debug('Token parameters: params {}'.format(token_param))
|
rauth = session.get(url, params=token_param, auth=auth, timeout=30)
|
||||||
rauth = session.get(realm, params=token_param, auth=auth, timeout=30)
|
rauth.raise_for_status()
|
||||||
rauth.raise_for_status()
|
auth_header = (
|
||||||
session.headers['Authorization'] = 'Bearer %s' % rauth.json()['token']
|
'Basic %s' % base64.b64encode(
|
||||||
|
bytes(username + ':' + password, 'utf-8')).decode('ascii')
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ImageUploaderException(
|
||||||
|
'Unknown www-authenticate value: %s' % www_auth)
|
||||||
hash_request_id = hashlib.sha1(str(rauth.url).encode())
|
hash_request_id = hashlib.sha1(str(rauth.url).encode())
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
'Session authenticated: id {}'.format(
|
'Session authenticated: id {}'.format(
|
||||||
hash_request_id.hexdigest()
|
hash_request_id.hexdigest()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
session.headers['Authorization'] = auth_header
|
||||||
|
|
||||||
setattr(session, 'reauthenticate', self.authenticate)
|
setattr(session, 'reauthenticate', self.authenticate)
|
||||||
setattr(
|
setattr(
|
||||||
session,
|
session,
|
||||||
|
|
|
@ -800,6 +800,31 @@ class TestBaseImageUploader(base.TestCase):
|
||||||
auth(url1).headers['Authorization']
|
auth(url1).headers['Authorization']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_authenticate_basic_auth(self):
|
||||||
|
req = self.requests
|
||||||
|
auth = self.uploader.authenticate
|
||||||
|
url1 = urlparse('docker://myrepo.com/t/nova-api:latest')
|
||||||
|
|
||||||
|
# successful auth requests
|
||||||
|
headers = {
|
||||||
|
'www-authenticate': 'Basic realm="Some Realm"'
|
||||||
|
}
|
||||||
|
|
||||||
|
def req_match(request):
|
||||||
|
resp = requests.Response()
|
||||||
|
resp.headers = headers
|
||||||
|
resp.status_code = 401
|
||||||
|
# if we got sent an user/password, return 200
|
||||||
|
if 'Authorization' in request.headers:
|
||||||
|
resp.status_code = 200
|
||||||
|
return resp
|
||||||
|
|
||||||
|
req.add_matcher(req_match)
|
||||||
|
self.assertEqual(
|
||||||
|
'Basic Zm9vOmJhcg==',
|
||||||
|
auth(url1, username='foo', password='bar').headers['Authorization']
|
||||||
|
)
|
||||||
|
|
||||||
def test_authenticate_with_no_service(self):
|
def test_authenticate_with_no_service(self):
|
||||||
req = self.requests
|
req = self.requests
|
||||||
auth = self.uploader.authenticate
|
auth = self.uploader.authenticate
|
||||||
|
|
Loading…
Reference in New Issue