Skip to content

Commit

Permalink
Enable sync from google registry.
Browse files Browse the repository at this point in the history
  • Loading branch information
ipanova committed Apr 18, 2018
1 parent 9e6cae3 commit 3a6d9a9
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 9 deletions.
8 changes: 7 additions & 1 deletion plugins/pulp_docker/plugins/auth_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def update_basic_auth_header(headers, username, password):
return headers


def request_token(downloader, request, auth_header):
def request_token(downloader, request, auth_header, repo_name):
"""
Attempts to retrieve the correct token based on the 401 response header.
Expand All @@ -65,6 +65,8 @@ def request_token(downloader, request, auth_header):
:type request: nectar.request.DownloadRequest
:param auth_header: www-authenticate header returned in a 401 response
:type auth_header: basestring
:param repo_name: upstream repo name
:type repo_name: basestring
:return: Bearer token for requested resource
:rtype: str
"""
Expand All @@ -74,6 +76,10 @@ def request_token(downloader, request, auth_header):
except KeyError:
raise IOError("No realm specified for token auth challenge.")

# self defense strategy in cases when registry does not provide the scope
if 'scope' not in auth_info:
auth_info['scope'] = 'repository:%s:pull' % repo_name

parse_result = urlparse.urlparse(token_url)
query_dict = urlparse.parse_qs(parse_result.query)
query_dict.update(auth_info)
Expand Down
3 changes: 2 additions & 1 deletion plugins/pulp_docker/plugins/importers/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,8 @@ def download_failed(self, report):
_logger.debug(_('Download unauthorized, retrying with basic authentication'))
else:
token = auth_util.request_token(self.parent.index_repository.auth_downloader,
request, auth_header)
request, auth_header,
self.parent.index_repository.name)
self.downloader.session.headers = auth_util.update_token_auth_header(
self.downloader.session.headers, token)
_logger.debug("Download unauthorized, retrying with new bearer token.")
Expand Down
9 changes: 6 additions & 3 deletions plugins/pulp_docker/plugins/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,9 @@ def get_manifest(self, reference, headers=True, tag=True):
if headers:
# set the headers for first request
request_headers['Accept'] = ','.join((constants.MEDIATYPE_MANIFEST_S2,
constants.MEDIATYPE_MANIFEST_LIST))
constants.MEDIATYPE_MANIFEST_LIST,
constants.MEDIATYPE_MANIFEST_S1,
constants.MEDIATYPE_SIGNED_MANIFEST_S1))
response_headers, manifest = self._get_path(path, headers=request_headers)
# we need to disable here the digest check because of wrong digests registry returns
# https://github.com/docker/distribution/pull/2310
Expand All @@ -401,7 +403,8 @@ def get_manifest(self, reference, headers=True, tag=True):
# for older clients will be requested later during the manifest list process time
# if it is schema2 we need to ask schema1 for older clients.
if tag and response_headers.get(content_type_header) == constants.MEDIATYPE_MANIFEST_S2:
request_headers['Accept'] = constants.MEDIATYPE_MANIFEST_S1
request_headers['Accept'] = ','.join((constants.MEDIATYPE_MANIFEST_S1,
constants.MEDIATYPE_SIGNED_MANIFEST_S1))
try:
# for compatibility with older clients, try to fetch schema1 in case it is available
response_headers, manifest = self._get_path(path, headers=request_headers)
Expand Down Expand Up @@ -499,7 +502,7 @@ def _get_path(self, path, headers=None):
else:
_logger.debug(_('Download unauthorized, attempting to retrieve a token.'))
self.token = auth_util.request_token(self.auth_downloader, request,
auth_header)
auth_header, self.name)
request.headers = auth_util.update_token_auth_header(request.headers,
self.token)
report = self.downloader.download_one(request)
Expand Down
13 changes: 9 additions & 4 deletions plugins/test/unit/plugins/test_auth_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ def test_no_realm(self, mock_parse):
m_downloader = mock.MagicMock()
m_req = mock.MagicMock()
m_headers = mock.MagicMock()
m_name = mock.MagicMock()
resp_headers = {'missing': 'realm'}
mock_parse.return_value = resp_headers
self.assertRaises(IOError, auth_util.request_token, m_downloader, m_req, m_headers)
self.assertRaises(IOError, auth_util.request_token, m_downloader, m_req, m_headers, m_name)
mock_parse.assert_called_once_with(m_headers)

@mock.patch('pulp_docker.plugins.auth_util.StringIO')
Expand All @@ -72,12 +73,16 @@ def test_as_expected(self, mock_parse, mock_encode, m_dl_req, m_string_io):
m_downloader = mock.MagicMock()
m_req = mock.MagicMock()
m_headers = mock.MagicMock()
m_name = mock.MagicMock()
m_name.return_value = 'library/busybox'
m_string_io.return_value.getvalue.return_value = '{"token": "Hey, its a token!"}'
mock_parse.return_value = {'realm': 'url', 'other_info': 'stuff'}
mock_parse.return_value = {'realm': 'url', 'other_info': 'stuff',
'scope': 'repository:library/busybox:pull'}
mock_encode.return_value = 'other_info=stuff'
auth_util.request_token(m_downloader, m_req, m_headers)
auth_util.request_token(m_downloader, m_req, m_headers, m_name)

mock_encode.assert_called_once_with({'other_info': 'stuff'})
mock_encode.assert_called_once_with({'scope': "repository:library/busybox:pull",
'other_info': 'stuff'})
m_dl_req.assert_called_once_with('url?other_info=stuff', m_string_io.return_value)
mock_parse.assert_called_once_with(m_headers)
m_downloader.download_one.assert_called_once_with(m_dl_req.return_value)
Expand Down

0 comments on commit 3a6d9a9

Please sign in to comment.