Beispiel #1
0
    def request(
        self,
        path: str,
        method: str,
        params: Optional[dict] = None,
        tenant: Optional[Union[bool, auth.Tenant]] = True,
        raise_errors: Optional[bool] = True,
    ):
        if tenant is True:
            tenant = auth.get_current_tenant()
        elif tenant is False:
            tenant = None

        url = "{}/{}".format(current_app.config["VCS_SERVER_ENDPOINT"],
                             path.lstrip("/"))

        hub = Hub.current
        with hub.start_span(op="vcs-server", description=f"{method} {path}"):
            response = requests.request(
                method=method,
                url=url,
                params=({k: v
                         for k, v in params.items()
                         if v is not None} if params else None),
                headers={
                    "Authorization":
                    "Bearer zeus-t-{}".format(
                        auth.generate_token(tenant).decode("utf-8"))
                },
            )
        if raise_errors and not (200 <= response.status_code < 300):
            text = response.text
            data = {}
            try:
                data = json.loads(text)
            except ValueError:
                pass

            # XXX(dcramer): this feels a bit hacky, and ideally would be handled
            # in the vcs implementation
            if data.get("error") == "invalid_pubkey" and params:
                from zeus.tasks import deactivate_repo, DeactivationReason

                deactivate_repo.delay(params["repo_id"],
                                      DeactivationReason.invalid_pubkey)

            if data.get("error") == "invalid_ref":
                raise UnknownRevision(ref=data.get("ref"))

            raise ApiError(text=text, code=response.status_code)

        if raise_errors and not response.headers["Content-Type"].startswith(
                "application/json"):
            raise ApiError(
                text="Request returned invalid content type: {}".format(
                    response.headers["Content-Type"]),
                code=response.status_code,
            )

        return response.json()
Beispiel #2
0
    def dispatch(
        self,
        path: str,
        method: str,
        data: dict = None,
        files: Mapping[str, BinaryIO] = None,
        json: dict = None,
        params: dict = None,
        request=None,
        tenant=True,
    ) -> Response:
        if request:
            assert not json
            assert not data
            assert not files
            data = request.data
            files = request.files
            json = None
            params = request.args

        if tenant is True:
            tenant = auth.get_current_tenant()

        if json:
            assert not data
            data = dumps(json)
            content_type = 'application/json'
        elif files:
            if not data:
                data = {}
            for key, value in request.form.items():
                data[key] = value
            for key, value in files.items():
                data[key] = value
            content_type = 'multipart/form-data'
        else:
            content_type = None

        with current_app.test_client() as client:
            response = client.open(path='/api/{}'.format(path.lstrip('/')),
                                   query_string=params,
                                   method=method,
                                   content_type=content_type,
                                   data=data,
                                   environ_overrides={
                                       'zeus.tenant': tenant,
                                   })
        if not (200 <= response.status_code < 300):
            raise ApiError(
                text=response.get_data(as_text=True),
                code=response.status_code,
            )
        if response.headers['Content-Type'] != 'application/json':
            raise ApiError(
                text='Request returned invalid content type: {}'.format(
                    response.headers['Content-Type']),
                code=response.status_code,
            )
        return response
Beispiel #3
0
    def _dispatch(self,
                  method: str,
                  path: str,
                  headers: dict = None,
                  json: dict = None,
                  params: dict = None):
        if path.startswith(('http:', 'https:')):
            url = path
        else:
            url = '{}{}'.format(self.url, path)

        try:
            resp = requests.request(
                method=method,
                url=url,
                headers=headers,
                json=json,
                params=params,
                allow_redirects=True,
            )
            resp.raise_for_status()
        except HTTPError as e:
            raise ApiError.from_response(e.response)

        if resp.status_code == 204:
            return {}

        return BaseResponse.from_response(resp)
Beispiel #4
0
    def _dispatch(self,
                  method: str,
                  path: str,
                  headers: dict = None,
                  json: dict = None,
                  params: dict = None):
        try:
            resp = requests.request(
                method=method,
                url='{}{}'.format(self.url, path),
                headers=headers,
                json=json,
                params=params,
                allow_redirects=True,
            )
            resp.raise_for_status()
        except HTTPError as e:
            raise ApiError.from_response(e.response)

        if resp.status_code == 204:
            return {}

        return resp.json()
Beispiel #5
0
    def dispatch(
        self,
        path: str,
        method: str,
        data: dict = None,
        files: Mapping[str, BinaryIO] = None,
        json: dict = None,
        params: dict = None,
        request=None,
        tenant=True,
        raise_errors=True,
    ) -> Response:
        if request:
            assert not json
            assert not data
            assert not files
            data = request.data
            files = request.files
            json = None
            params = request.args

        if tenant is True:
            tenant = auth.get_current_tenant()

        if json:
            assert not data
            data = dumps(json, default=json_encoder)
            content_type = "application/json"
        elif files:
            if not data:
                data = {}
            for key, value in request.form.items():
                data[key] = value
            for key, value in files.items():
                data[key] = value
            content_type = "multipart/form-data"
        else:
            content_type = None

        path = "/api/{}".format(path.lstrip("/"))

        from sentry_sdk import Hub

        hub = Hub.current
        with hub.start_span(op="api", description=f"{method} {path}"
                            ), current_app.test_client() as client:
            response = client.open(
                path=path,
                query_string=params,
                method=method,
                content_type=content_type,
                data=data,
                environ_overrides={"zeus.tenant": tenant},
            )
        if raise_errors and not (200 <= response.status_code < 300):
            raise ApiError(text=response.get_data(as_text=True),
                           code=response.status_code)

        if raise_errors and response.headers[
                "Content-Type"] != "application/json":
            raise ApiError(
                text="Request returned invalid content type: {}".format(
                    response.headers["Content-Type"]),
                code=response.status_code,
            )

        return response