Example #1
0
    def __call_galaxy(self, url, args=None, headers=None, method=None):
        if args and not headers:
            headers = self.__auth_header()
        try:
            http_log.info('%s %s', method, url)
            request_log.debug('%s %s args=%s', method, url, args)
            request_log.debug('%s %s headers=%s', method, url, headers)

            resp = open_url(url,
                            data=args,
                            validate_certs=self._validate_certs,
                            headers=headers,
                            method=method,
                            timeout=20)

            http_log.info('%s %s http_status=%s', method, url, resp.getcode())

            final_url = resp.geturl()
            if final_url != url:
                http_log.debug('%s %s Redirected to: %s', method, url,
                               resp.geturl())

            resp_info = resp.info()
            response_log.debug('%s %s info:\n%s', method, url, resp_info)

            # FIXME: making the request and loading the response should be sep try/except blocks
            response_body = to_text(resp.read(), errors='surrogate_or_strict')

            # debug log the raw response body
            response_log.debug('%s %s response body:\n%s', method, url,
                               response_body)

            data = json.loads(response_body)

            # debug log a json version of the data that was created from the response
            response_log.debug('%s %s data:\n%s', method, url,
                               json.dumps(data, indent=2))
        except HTTPError as e:
            self.log.debug('Exception on %s %s', method, url)
            self.log.exception(e)

            # FIXME: probably need a try/except here if the response body isnt json which
            #        can happen if a proxy mangles the response
            res = json.loads(to_text(e.fp.read(),
                                     errors='surrogate_or_strict'))

            http_log.error('%s %s data from server error response:\n%s',
                           method, url, res)

            raise exceptions.GalaxyClientError(res['detail'])
        except (ssl.SSLError, socket.error) as e:
            self.log.debug(
                'Connection error to Galaxy API for request "%s %s": %s',
                method, url, e)
            self.log.exception(e)
            raise exceptions.GalaxyClientAPIConnectionError(
                'Connection error to Galaxy API for request "%s %s": %s' %
                (method, url, e))

        return data
Example #2
0
def test_galaxy_api_publish_file_request_error(galaxy_api_mocked, requests_mock, tmpdir, file_upload_form):

    # POST http://bogus.invalid:9443/api/v2/collections/
    # requests_mock.get('http://bogus.invalid:9443/api/',
    #                  exc=requests.
    exc = exceptions.GalaxyClientAPIConnectionError(requests.exceptions.SSLError('SSL stuff broke'))
    requests_mock.post('http://bogus.invalid:9443/api/v2/collections/',
                       exc=exc)

    publish_api_key = '1f107befb89e0863829264d5241111a'

    with pytest.raises(exceptions.GalaxyClientAPIConnectionError) as exc_info:
        galaxy_api_mocked.publish_file(form=file_upload_form, publish_api_key=publish_api_key)

    log.debug('exc_info:%s', exc_info)
Example #3
0
    def __call_galaxy(self, url, args=None, headers=None, http_method=None):
        http_method = http_method or 'GET'
        headers = headers or {}
        request_id = uuid.uuid4().hex
        headers['X-Request-ID'] = request_id

        # The slug we use to identify a request by method, url and request id
        # For ex, '"GET https://galaxy.ansible.com/api/v1/repositories" c48937f4e8e849828772c4a0ce0fd5ed'
        request_slug = '"%s %s" %s' % (http_method, url, request_id)

        try:
            # log the http request_slug with request_id to the main log and
            # to the http log, both at INFO level for now.
            http_log.info('%s', request_slug)
            self.log.info('%s', request_slug)

            request_log.debug('%s args=%s', request_slug, args)
            request_log.debug('%s headers=%s', request_slug, headers)

            resp = open_url(url,
                            data=args,
                            validate_certs=self._validate_certs,
                            headers=headers,
                            method=http_method,
                            http_agent=self.user_agent,
                            timeout=20)

            response_log.info('%s http_status=%s', request_slug,
                              resp.getcode())

            final_url = resp.geturl()
            if final_url != url:
                request_log.debug('%s Redirected to: %s', request_slug,
                                  resp.geturl())

            resp_info = resp.info()
            response_log.debug('%s info:\n%s', request_slug, resp_info)

            # FIXME: making the request and loading the response should be sep try/except blocks
            response_body = to_text(resp.read(), errors='surrogate_or_strict')

            # debug log the raw response body
            response_log.debug('%s response body:\n%s', request_slug,
                               response_body)

            data = json.loads(response_body)

            # debug log a json version of the data that was created from the response
            response_log.debug('%s data:\n%s', request_slug,
                               json.dumps(data, indent=2))
        except HTTPError as http_exc:
            self.log.debug('Exception on %s', request_slug)
            self.log.exception("%s: %s", request_slug, http_exc)

            # FIXME: probably need a try/except here if the response body isnt json which
            #        can happen if a proxy mangles the response
            res = json.loads(
                to_text(http_exc.fp.read(), errors='surrogate_or_strict'))

            http_log.error('%s data from server error response:\n%s',
                           request_slug, res)

            try:
                error_msg = 'HTTP error on request %s: %s' % (request_slug,
                                                              res['detail'])
                raise exceptions.GalaxyClientError(error_msg)
            except (KeyError, TypeError) as detail_parse_exc:
                self.log.exception("%s: %s", request_slug, detail_parse_exc)
                self.log.warning(
                    'Unable to parse error detail from response for request: %s response:  %s',
                    request_slug, detail_parse_exc)

            # TODO: great place to be able to use 'raise from'
            # FIXME: this needs to be tweaked so the
            raise exceptions.GalaxyClientError(http_exc)
        except (ssl.SSLError, socket.error) as e:
            self.log.debug('Connection error to Galaxy API for request %s: %s',
                           request_slug, e)
            self.log.exception("%s: %s", request_slug, e)
            raise exceptions.GalaxyClientAPIConnectionError(
                'Connection error to Galaxy API for request %s: %s' %
                (request_slug, e))

        return data
Example #4
0
    def mkrequest(self, url, args=None, headers=None, http_method=None):
        '''Make an REST-y http request to Galaxy APIs

        Requests that fail and raise exceptions are caught and
        either GalaxyClientAPIConnectionError or GalaxyRestAPIClientRequestError
        are raised. ie, mazer specific request error exceptions.

        Note: This only raises exceptions if the request fails (a connection failure,
              an SSL failure, DNS failure etc. If the server responds at all, this
              will not fail. Those cases are handled in GalaxyAPI.
        '''
        http_method = http_method or 'GET'

        request_headers = headers or {}
        request_id = uuid.uuid4().hex
        request_headers['X-Request-ID'] = request_id

        # The slug we use to identify a request by method, url and request id
        # For ex, '"GET https://galaxy.ansible.com/api/v1/repositories" c48937f4e8e849828772c4a0ce0fd5ed'
        pre_request_slug = '"%s %s" %s' % (http_method, url, request_id)

        # log the http request_slug with request_id to the main log and
        # to the http log.
        http_log.info('%s', pre_request_slug)
        self.log.debug('%s', pre_request_slug)

        # request_log.debug('%s headers=%s', pre_request_slug, request_headers)

        try:

            # Make the actual request
            resp = self.session.request(http_method,
                                        url,
                                        data=args,
                                        headers=request_headers,
                                        verify=self.validate_certs)

        except requests.exceptions.ConnectionError as connection_exc:
            self.log.debug('Connection exception on %s', pre_request_slug)
            self.log.exception("%s: %s %r", pre_request_slug, connection_exc,
                               connection_exc)

            # TODO: The request.ConnectionError error messages are very knarly and obscure real
            #       cause of message (like a 'connection refused'). Try to improve these cases.
            raise exceptions.GalaxyClientAPIConnectionError(
                connection_exc, response=connection_exc.response)

        except requests.exceptions.RequestException as request_exc:
            self.log.debug('Exception on %s', pre_request_slug)
            self.log.exception("%s: %s", pre_request_slug, request_exc)

            raise exceptions.GalaxyRestAPIClientRequestError(
                request_exc, response=request_exc.response)

        # Log info about the request/response for debug
        log.debug('resp.request: %s', resp.request)
        log.debug('resp: %s', resp)

        slug = response_slug(resp)

        response_log.info('%s http_status=%s reason=%s', slug,
                          resp.status_code, resp.reason)
        response_log.debug('%s headers=%s', slug, resp.headers)

        if resp.history:
            for redirect in resp.history:
                log.debug('%s %s redirected -->  %s', slug, redirect.url,
                          redirect.headers['Location'])

        return resp
Example #5
0
    def __call_galaxy(self, url, args=None, headers=None, http_method=None):
        http_method = http_method or 'GET'

        request_headers = headers or {}
        request_id = uuid.uuid4().hex
        request_headers['X-Request-ID'] = request_id

        # The slug we use to identify a request by method, url and request id
        # For ex, '"GET https://galaxy.ansible.com/api/v1/repositories" c48937f4e8e849828772c4a0ce0fd5ed'
        request_slug = '"%s %s" %s' % (http_method, url, request_id)

        log.debug('self.session: %s', self.session)

        try:
            # log the http request_slug with request_id to the main log and
            # to the http log, both at INFO level for now.
            http_log.info('%s', request_slug)
            self.log.info('%s', request_slug)

            request_log.debug('%s args=%s', request_slug, args)
            request_log.debug('%s headers=%s', request_slug, request_headers)

            resp = self.session.request(http_method,
                                        url,
                                        data=args,
                                        headers=request_headers,
                                        verify=self._validate_certs)
            log.debug('resp: %s', resp)
            log.debug('resp.request: %s', resp.request)
            log.debug('resp.request.headers: %s', resp.request.headers)

            response_log.info('%s http_status=%s', request_slug,
                              resp.status_code)
            response_log.debug('%s reason=%s', request_slug, resp.reason)
            response_log.debug('%s headers=%s', request_slug, resp.headers)
            response_log.debug('%s history=%s', request_slug, resp.history)

            if resp.history:
                for redirect in resp.history:
                    log.debug('%s Redirected. %s is redirected to %s',
                              request_slug, redirect.url,
                              redirect.headers['Location'])

            response_log.debug('%s resp repr:\n%r', request_slug, resp)

            # FIXME: making the request and loading the response should be sep try/except blocks
            response_body = resp.text

            # debug log the raw response body
            response_log.debug('%s response body:\n%s', request_slug,
                               response_body)

            # TODO/FIXME: Move the loading/parsing of json up a layer, since we don't always need it
            try:
                data = resp.json()
            except ValueError as e:
                log.exception(e)
                data = {}

            # debug log a json version of the data that was created from the response
            response_log.debug('%s data:\n%s', request_slug,
                               json.dumps(data, indent=2))

        except requests.exceptions.RequestException as http_exc:
            self.log.debug('Exception on %s', request_slug)
            self.log.exception("%s: %s", request_slug, http_exc)

            http_log.error('%s data from server error response:\n%s',
                           request_slug, http_exc.response)

            if http_exc.response:
                # FIXME: probably need a try/except here if the response body isnt json which
                #        can happen if a proxy mangles the response
                try:
                    error_msg = 'HTTP error on request %s: %s' % (
                        request_slug, http_exc.response.json()['detail'])
                    raise exceptions.GalaxyClientError(error_msg)
                except (ValueError, KeyError, TypeError) as detail_parse_exc:
                    self.log.exception("%s: %s", request_slug,
                                       detail_parse_exc)
                    self.log.warning(
                        'Unable to parse error detail from response for request: %s response:  %s',
                        request_slug, detail_parse_exc)

            # TODO: great place to be able to use 'raise from'
            raise exceptions.GalaxyClientError(http_exc)
        except (ssl.SSLError, socket.error) as e:
            self.log.debug('Connection error to Galaxy API for request %s: %s',
                           request_slug, e)
            self.log.exception("%s: %s", request_slug, e)

            raise exceptions.GalaxyClientAPIConnectionError(
                'Connection error to Galaxy API for request %s: %s' %
                (request_slug, e))

        return data