예제 #1
0
파일: base.py 프로젝트: robopsi/zeus
    def dispatch_request(self,
                         hook_id,
                         signature=None,
                         *args,
                         **kwargs) -> Response:
        current_app.logger.info("received webhook id=%s", hook_id)

        with nplusone.ignore("eager_load"):
            hook = Hook.query.unrestricted_unsafe().options(
                joinedload("repository")).get(hook_id)
        if not self.public and not hook.is_valid_signature(signature):
            current_app.logger.warn("invalid webhook signature id=%s", hook_id)
            return "", 403

        try:
            method = getattr(self, request.method.lower())
        except AttributeError:
            current_app.logger.warn("invalid webhook method id=%s, method=%s",
                                    hook_id, request.method)
            return self.respond({"message": "resource not found"}, 405)

        auth.set_current_tenant(
            auth.RepositoryTenant(repository_id=hook.repository_id,
                                  permission=Permission.admin))

        try:
            resp = method(hook, *args, **kwargs)
        except ApiError as exc:
            return self.respond(exc.json, exc.code)

        if isinstance(resp, Response):
            return resp

        return self.respond(resp)
예제 #2
0
 def get_latest_build(self, results, many, **kwargs):
     if results:
         with nplusone.ignore("eager_load"):
             builds = dict(fetch_builds_for_revisions(results))
         for item in results:
             item.latest_build = builds.get((item.repository_id, item.sha))
     return results
예제 #3
0
    def dispatch_request(self,
                         hook_id,
                         signature=None,
                         *args,
                         **kwargs) -> Response:
        current_app.logger.info('received webhook id=%s', hook_id)

        with nplusone.ignore('eager_load'):
            hook = Hook.query.unrestricted_unsafe().options(
                joinedload('repository'), ).get(hook_id)
        if not self.public and not hook.is_valid_signature(signature):
            current_app.logger.warn('invalid webhook signature id=%s', hook_id)
            return '', 403

        try:
            method = getattr(self, request.method.lower())
        except AttributeError:
            current_app.logger.warn('invalid webhook method id=%s, method=%s',
                                    hook_id, request.method)
            return self.respond({'message': 'resource not found'}, 405)

        auth.set_current_tenant(
            auth.Tenant(repository_ids=[hook.repository_id]))

        try:
            resp = method(hook, *args, **kwargs)
        except ApiError as exc:
            return self.respond(exc.json, exc.code)
        if isinstance(resp, Response):
            return resp
        return self.respond(resp)
예제 #4
0
 def get(self, build: Build):
     """
     Return a build.
     """
     with nplusone.ignore("eager_load"):
         build.source = Source.query.options(joinedload("revision"),
                                             joinedload("patch")).get(
                                                 build.source_id)
     build.stats = list(ItemStat.query.filter(ItemStat.item_id == build.id))
     return self.respond_with_schema(build_schema, build)
예제 #5
0
    def get(self, revision: Revision, repo=None):
        """
        Return the joined build status of a revision.
        """
        with nplusone.ignore("eager_load"):
            build = fetch_build_for_revision(revision)
        if not build:
            return self.respond(status=404)

        return self.respond_with_schema(build_schema, build)
예제 #6
0
 def get(self, build: Build):
     """
     Return a build.
     """
     with nplusone.ignore("eager_load"):
         build.revision = Revision.query.filter(
             Revision.sha == build.revision_sha,
             Revision.repository_id == build.repository_id,
         ).first()
     build.stats = list(ItemStat.query.filter(ItemStat.item_id == build.id))
     return self.respond_with_schema(build_schema, build)
예제 #7
0
def process_travis_webhook(hook_id: str, payload: dict, timestamp_ms: int):
    # TODO(dcramer): we want to utilize timestamp_ms to act as a version and
    # ensure we dont process older updates after newer updates are already present
    with nplusone.ignore("eager_load"):
        hook = (Hook.query.unrestricted_unsafe().options(
            joinedload("repository")).get(hook_id))

    auth.set_current_tenant(
        auth.Tenant(access={hook.repository_id: Permission.admin}))

    data = {"ref": payload["commit"], "url": payload["build_url"]}

    domain = urlparse(data["url"]).netloc

    try:
        if payload["pull_request"]:
            data["label"] = "PR #{} - {}".format(
                payload["pull_request_number"], payload["pull_request_title"])

            upsert_change_request(
                repository=hook.repository,
                provider="github",
                external_id=str(payload["pull_request_number"]),
                data={
                    "parent_revision_sha": payload["base_commit"],
                    "head_revision_sha": payload["head_commit"],
                    "message": payload["pull_request_title"],
                },
            )

        response = upsert_build(hook=hook,
                                external_id=str(payload["id"]),
                                data=data)
        build = Build.query.get(response.json()["id"])
        for job_payload in payload["matrix"]:
            upsert_job(
                build=build,
                hook=hook,
                external_id=str(job_payload["id"]),
                data={
                    "status": ("finished" if job_payload["status"] is not None
                               else "in_progress"),
                    "result":
                    get_result(job_payload["state"]),
                    "allow_failure":
                    bool(job_payload["allow_failure"]),
                    "label":
                    get_job_label(job_payload),
                    "url":
                    "https://{domain}/{owner}/{name}/jobs/{job_id}".format(
                        domain=domain,
                        owner=payload["repository"]["owner_name"],
                        name=payload["repository"]["name"],
                        job_id=job_payload["id"],
                    ),
                    "started_at":
                    (dateutil.parser.parse(job_payload["started_at"])
                     if job_payload["started_at"] else None),
                    "finished_at":
                    (dateutil.parser.parse(job_payload["finished_at"])
                     if job_payload["finished_at"] else None),
                },
            )
    except ApiError:
        current_app.logger.error("travis.webhook-unexpected-error",
                                 exc_info=True)
        raise