Beispiel #1
0
    def test_as_expected(self, mock_parse, mock_encode, m_dl_req, m_string_io):
        """
        Test that a request is created with correct query parameters to retrieve a bearer token.
        """
        m_downloader = mock.MagicMock()
        m_req = mock.MagicMock()
        m_headers = mock.MagicMock()
        m_string_io.return_value.getvalue.return_value = '{"token": "Hey, its a token!"}'
        mock_parse.return_value = {"realm": "url", "other_info": "stuff"}
        mock_encode.return_value = "other_info=stuff"
        token_util.request_token(m_downloader, m_req, m_headers)

        mock_encode.assert_called_once_with({"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)
Beispiel #2
0
    def _get_path(self, path):
        """
        Retrieve a single path within the upstream registry, and return a 2-tuple of the headers and
        the response body.

        :param path: a full http path to retrieve that will be urljoin'd to the upstream registry
                     url.
        :type  path: basestring

        :return:     (headers, response body)
        :rtype:      tuple
        """
        url = urlparse.urljoin(self.registry_url, path)
        _logger.debug(_('Retrieving {0}'.format(url)))
        request = DownloadRequest(url, StringIO())

        if self.token:
            token_util.add_auth_header(request, self.token)

        report = self.downloader.download_one(request)

        # If the download was unauthorized, attempt to get a token and try again
        if report.state == report.DOWNLOAD_FAILED:
            if report.error_report.get('response_code') == httplib.UNAUTHORIZED:
                _logger.debug(_('Download unauthorized, attempting to retrieve a token.'))
                self.token = token_util.request_token(self.downloader, request, report.headers)
                token_util.add_auth_header(request, self.token)
                report = self.downloader.download_one(request)

        if report.state == report.DOWNLOAD_FAILED:
            raise IOError(report.error_msg)

        return report.headers, report.destination.getvalue()
    def test_as_expected(self, mock_parse, mock_encode, m_dl_req, m_string_io):
        """
        Test that a request is created with correct query parameters to retrieve a bearer token.
        """
        m_downloader = mock.MagicMock()
        m_req = mock.MagicMock()
        m_headers = mock.MagicMock()
        m_string_io.return_value.getvalue.return_value = '{"token": "Hey, its a token!"}'
        mock_parse.return_value = {'realm': 'url', 'other_info': 'stuff'}
        mock_encode.return_value = 'other_info=stuff'
        token_util.request_token(m_downloader, m_req, m_headers)

        mock_encode.assert_called_once_with({'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)
Beispiel #4
0
    def _get_path(self, path, headers=None):
        """
        Retrieve a single path within the upstream registry, and return a 2-tuple of the headers and
        the response body.

        :param path: a full http path to retrieve that will be urljoin'd to the upstream registry
                     url.
        :type  path: basestring
        :param headers: headers sent in the request
        :type headers:  dict

        :return:     (headers, response body)
        :rtype:      tuple
        """
        url = urlparse.urljoin(self.registry_url, path)
        _logger.debug(_('Retrieving {0}'.format(url)))
        request = DownloadRequest(url, StringIO())
        request.headers = headers

        if self.token:
            request.headers = token_util.update_auth_header(
                request.headers, self.token)

        report = self.downloader.download_one(request)

        # If the download was unauthorized, attempt to get a token and try again
        if report.state == report.DOWNLOAD_FAILED:
            if report.error_report.get(
                    'response_code') == httplib.UNAUTHORIZED:
                _logger.debug(
                    _('Download unauthorized, attempting to retrieve a token.')
                )
                self.token = token_util.request_token(self.token_downloader,
                                                      request, report.headers)
                request.headers = token_util.update_auth_header(
                    request.headers, self.token)
                report = self.downloader.download_one(request)

        if report.state == report.DOWNLOAD_FAILED:
            # this condition was added in case the registry would not allow to access v2 endpoint
            # but still token would be valid for other endpoints.
            # see https://pulp.plan.io/issues/2643
            if path == '/v2/' and report.error_report.get(
                    'response_code') == httplib.UNAUTHORIZED:
                pass
            else:
                self._raise_path_error(report)

        return report.headers, report.destination.getvalue()
Beispiel #5
0
    def download_failed(self, report):
        """
        If the download fails due to a 401, attempt to retreive a token and try again.

        :param report: download report
        :type  report: nectar.report.DownloadReport
        """
        if report.error_report.get('response_code') == httplib.UNAUTHORIZED:
            _logger.debug(_('Download unauthorized, attempting to retrieve a token.'))
            request = self._requests_map[report.url]
            token = token_util.request_token(self.downloader, request, report.headers)
            token_util.add_auth_header(request, token)
            _logger.debug("Trying download again with new bearer token.")
            report = self.downloader.download_one(request, events=True)
        if report.state == report.DOWNLOAD_FAILED:
            super(TokenAuthDownloadStep, self).download_failed(report)
Beispiel #6
0
    def _get_path(self, path):
        """
        Retrieve a single path within the upstream registry, and return a 2-tuple of the headers and
        the response body.

        :param path: a full http path to retrieve that will be urljoin'd to the upstream registry
                     url.
        :type  path: basestring

        :return:     (headers, response body)
        :rtype:      tuple
        """
        url = urlparse.urljoin(self.registry_url, path)
        _logger.debug(_('Retrieving {0}'.format(url)))
        request = DownloadRequest(url, StringIO())

        if self.token:
            token_util.add_auth_header(request, self.token)

        report = self.downloader.download_one(request)

        # If the download was unauthorized, attempt to get a token and try again
        if report.state == report.DOWNLOAD_FAILED:
            if report.error_report.get(
                    'response_code') == httplib.UNAUTHORIZED:
                _logger.debug(
                    _('Download unauthorized, attempting to retrieve a token.')
                )
                self.token = token_util.request_token(self.downloader, request,
                                                      report.headers)
                token_util.add_auth_header(request, self.token)
                report = self.downloader.download_one(request)

        if report.state == report.DOWNLOAD_FAILED:
            raise IOError(report.error_msg)

        return report.headers, report.destination.getvalue()
Beispiel #7
0
    def download_failed(self, report):
        """
        If the download is unauthorized, attempt to retreive a token and try again.

        :param report: download report
        :type  report: nectar.report.DownloadReport
        """
        if report.error_report.get('response_code') == httplib.UNAUTHORIZED:
            _logger.debug(_('Download unauthorized, attempting to retrieve a token.'))
            request = self._requests_map[report.url]
            token = token_util.request_token(self.parent.index_repository.token_downloader,
                                             request, report.headers)
            self.downloader.session.headers = token_util.update_auth_header(
                self.downloader.session.headers, token)
            _logger.debug("Trying download again with new bearer token.")
            # Events must be false or download_failed will recurse
            report = self.downloader.download_one(request, events=False)
        if report.state is report.DOWNLOAD_SUCCEEDED:
            self.download_succeeded(report)
        elif report.state is report.DOWNLOAD_FAILED:
            super(TokenAuthDownloadStep, self).download_failed(report)
            # Docker blobs have ancestry relationships and need all blobs to function. Sync should
            # stop immediately to prevent publishing of an incomplete repository.
            os.kill(os.getpid(), signal.SIGKILL)
Beispiel #8
0
    def download_failed(self, report):
        """
        If the download is unauthorized, attempt to retreive a token and try again.

        :param report: download report
        :type  report: nectar.report.DownloadReport
        """
        if report.error_report.get('response_code') == httplib.UNAUTHORIZED:
            _logger.debug(_('Download unauthorized, attempting to retrieve a token.'))
            request = self._requests_map[report.url]
            token = token_util.request_token(self.parent.index_repository.token_downloader,
                                             request, report.headers)
            self.downloader.session.headers = token_util.update_auth_header(
                self.downloader.session.headers, token)
            _logger.debug("Trying download again with new bearer token.")
            # Events must be false or download_failed will recurse
            report = self.downloader.download_one(request, events=False)
        if report.state is report.DOWNLOAD_SUCCEEDED:
            self.download_succeeded(report)
        elif report.state is report.DOWNLOAD_FAILED:
            super(TokenAuthDownloadStep, self).download_failed(report)
            # Docker blobs have ancestry relationships and need all blobs to function. Sync should
            # stop immediately to prevent publishing of an incomplete repository.
            os.kill(os.getpid(), signal.SIGKILL)