Esempio n. 1
0
    def process_comment_jobs(
        self, event: Union[PullRequestCommentEvent, IssueCommentEvent]
    ) -> HandlerResults:
        # packit_command can be `/packit propose-update`
        msg = f"PR comment '{event.comment[:35]}'"
        try:
            (packit_mark, *packit_command) = event.comment.split(maxsplit=3)
        except ValueError:
            return HandlerResults(success=False,
                                  details={"msg": f"{msg} is empty."})

        if REQUESTED_PULL_REQUEST_COMMENT != packit_mark:
            return HandlerResults(
                success=False,
                details={"msg": f"{msg} is not handled by packit-service."},
            )

        if not packit_command:
            return HandlerResults(
                success=False,
                details={
                    "msg": f"{msg} does not contain a packit-service command."
                },
            )

        # packit has command `copr-build`. But PullRequestCommentAction has enum `copr_build`.
        try:
            packit_action = CommentAction[packit_command[0].replace("-", "_")]
        except KeyError:
            return HandlerResults(
                success=False,
                details={
                    "msg":
                    f"{msg} does not contain a valid packit-service command."
                },
            )
        handler_kls: Type[
            CommentActionHandler] = COMMENT_ACTION_HANDLER_MAPPING.get(
                packit_action, None)
        if not handler_kls:
            return HandlerResults(
                success=False,
                details={"msg": f"{msg} is not a packit-service command."},
            )

        handler = handler_kls(self.config, event)

        try:
            # check whitelist approval for every job to be able to track down which jobs
            # failed because of missing whitelist approval
            whitelist = Whitelist()
            if not whitelist.check_and_report(event, event.get_project()):
                handlers_results = HandlerResults(
                    success=False,
                    details={"msg": "Account is not whitelisted!"})
                return handlers_results
            handlers_results = handler.run()
        finally:
            handler.clean()
        return handlers_results
Esempio n. 2
0
    def process_comment_jobs(
        self, event: Union[PullRequestCommentEvent, IssueCommentEvent]
    ) -> HandlerResults:
        # packit_command can be `/packit propose-update`
        msg = f"comment '{event.comment[:35]}'"
        try:
            (packit_mark, *packit_command) = event.comment.split(maxsplit=3)
        except ValueError:
            return HandlerResults(success=True,
                                  details={"msg": f"{msg} is empty."})

        if packit_mark != REQUESTED_PULL_REQUEST_COMMENT:
            return HandlerResults(
                success=True,
                details={"msg": f"{msg} is not handled by packit-service."},
            )

        if not packit_command:
            return HandlerResults(
                success=True,
                details={
                    "msg": f"{msg} does not contain a packit-service command."
                },
            )

        # packit has command `copr-build`. But PullRequestCommentAction has enum `copr_build`.
        try:
            packit_action = CommentAction[packit_command[0].replace("-", "_")]
        except KeyError:
            return HandlerResults(
                success=True,
                details={
                    "msg":
                    f"{msg} does not contain a valid packit-service command."
                },
            )
        handler_kls: Type[
            CommentActionHandler] = COMMENT_ACTION_HANDLER_MAPPING.get(
                packit_action, None)
        if not handler_kls:
            return HandlerResults(
                success=True,
                details={"msg": f"{msg} is not a packit-service command."})

        # check whitelist approval for every job to be able to track down which jobs
        # failed because of missing whitelist approval
        whitelist = Whitelist()
        github_login = getattr(event, "github_login", None)
        if github_login and github_login in self.config.admins:
            logger.info(f"{github_login} is admin, you shall pass")
        elif not whitelist.check_and_report(
                event, event.get_project(), config=self.config):
            return HandlerResults(
                success=True, details={"msg": "Account is not whitelisted!"})

        return handler_kls(self.config, event).run_n_clean()
Esempio n. 3
0
    def process_jobs(self, event: Event) -> Dict[str, HandlerResults]:
        """
        Run a job handler (if trigger matches) for every job defined in config.
        """

        handlers_results = {}

        if not event.package_config:
            # this happens when service receives events for repos which
            # don't have packit config, this is not an error
            # success=True - it's not an error that people don't have packit.yaml in their repo
            handlers_results[event.trigger.value] = HandlerResults(
                success=True, details={"msg": "No packit config in repo"}
            )
            return handlers_results

        handler_classes = get_handlers_for_event(event, event.package_config)

        if not handler_classes:
            logger.warning(f"There is no handler for {event.trigger} event.")
            return handlers_results

        for handler_kls in handler_classes:
            job_configs = get_config_for_handler_kls(
                handler_kls=handler_kls,
                event=event,
                package_config=event.package_config,
            )
            # check whitelist approval for every job to be able to track down which jobs
            # failed because of missing whitelist approval
            whitelist = Whitelist()
            user_login = getattr(event, "user_login", None)
            if user_login and user_login in self.config.admins:
                logger.info(f"{user_login} is admin, you shall pass.")
            elif not whitelist.check_and_report(
                event, event.project, config=self.config
            ):
                for job_config in job_configs:
                    handlers_results[job_config.type.value] = HandlerResults(
                        success=False, details={"msg": "Account is not whitelisted!"}
                    )
                return handlers_results

            # we want to run handlers for all possible jobs, not just the first one
            for job_config in job_configs:
                logger.debug(f"Running handler: {str(handler_kls)} for {job_config}")
                handler = handler_kls(
                    config=self.config, job_config=job_config, event=event
                )
                if handler.pre_check():
                    current_time = datetime.datetime.now().strftime(DATETIME_FORMAT)
                    result_key = f"{job_config.type.value}-{current_time}"
                    handlers_results[result_key] = handler.run_n_clean()

        return handlers_results
Esempio n. 4
0
    def process_jobs(self, event: Event) -> Dict[str, TaskResults]:
        """
        Create a Celery task for a job handler (if trigger matches) for every job defined in config.
        """

        processing_results = {}

        if not event.package_config:
            # this happens when service receives events for repos which don't have packit config
            # success=True - it's not an error that people don't have packit.yaml in their repo
            processing_results[event.trigger.value] = TaskResults(
                success=True, details={"msg": "No packit config in repo"})
            return processing_results

        handler_classes = get_handlers_for_event(event, event.package_config)

        if not handler_classes:
            logger.warning(f"There is no handler for {event.trigger} event.")
            return processing_results

        job_configs = []
        for handler_kls in handler_classes:
            job_configs = get_config_for_handler_kls(
                handler_kls=handler_kls,
                event=event,
                package_config=event.package_config,
            )
            # check whitelist approval for every job to be able to track down which jobs
            # failed because of missing whitelist approval
            whitelist = Whitelist()
            user_login = getattr(event, "user_login", None)
            if user_login and user_login in self.service_config.admins:
                logger.info(f"{user_login} is admin, you shall pass.")
            elif not whitelist.check_and_report(
                    event,
                    event.project,
                    service_config=self.service_config,
                    job_configs=job_configs,
            ):
                for job_config in job_configs:
                    processing_results[job_config.type.value] = TaskResults(
                        success=False,
                        details={"msg": "Account is not whitelisted!"})
                return processing_results

            # we want to run handlers for all possible jobs, not just the first one
            signatures = [
                handler_kls.get_signature(event=event, job=job_config)
                for job_config in job_configs
            ]
            # https://docs.celeryproject.org/en/stable/userguide/canvas.html#groups
            group(signatures).apply_async()
        return get_processing_results(event=event, jobs=job_configs)
Esempio n. 5
0
def test_check_and_report(whitelist: Whitelist,
                          events: List[Tuple[AbstractGithubEvent, bool]]):
    """
    :param whitelist: fixture
    :param events: fixture: [(Event, should-be-approved)]
    """
    flexmock(
        GithubProject,
        pr_comment=lambda *args, **kwargs: None,
        set_commit_status=lambda *args, **kwargs: None,
        issue_comment=lambda *args, **kwargs: None,
    )
    flexmock(PullRequestEvent).should_receive("get_package_config").and_return(
        flexmock(jobs=[
            JobConfig(
                job=JobType.tests,
                trigger=JobTriggerType.pull_request,
                metadata={"targets": ["fedora-rawhide"]},
            )
        ], ))

    git_project = GithubProject("", GithubService(), "")
    for event, is_valid in events:
        if isinstance(event, PullRequestEvent) and not is_valid:
            # Report the status
            flexmock(CoprHelper).should_receive("get_copr_client").and_return(
                Client(
                    config={
                        "copr_url": "https://copr.fedorainfracloud.org",
                        "username": "******",
                    }))
            flexmock(LocalProject).should_receive(
                "refresh_the_arguments").and_return(None)
            flexmock(LocalProject).should_receive("checkout_pr").and_return(
                None)
            flexmock(Model).should_receive("save").and_return(None)
            flexmock(StatusReporter).should_receive("report").with_args(
                description="Account is not whitelisted!",
                state="error",
                url=FAQ_URL,
                check_names=[EXPECTED_TESTING_FARM_CHECK_NAME],
            ).once()
        assert (whitelist.check_and_report(
            event,
            git_project,
            config=flexmock(deployment=Deployment.stg,
                            command_handler_work_dir=""),
        ) is is_valid)
Esempio n. 6
0
    def process_jobs(self, event: Event) -> Dict[str, HandlerResults]:
        """
        Run a job handler (if trigger matches) for every job defined in config.
        """

        handlers_results = {}
        package_config = event.get_package_config()

        if not package_config:
            # this happens when service receives events for repos which
            # don't have packit config, this is not an error
            # success=True - it's not an error that people don't have packit.yaml in their repo
            handlers_results[event.trigger.value] = HandlerResults(
                success=True, details={"msg": "No packit config in repo"}
            )
            return handlers_results

        handler_classes = get_handlers_for_event(event, package_config)

        if not handler_classes:
            logger.warning(f"There is no handler for {event.trigger} event.")
            return handlers_results

        for handler_kls in handler_classes:
            job = get_config_for_handler_kls(
                handler_kls=handler_kls, event=event, package_config=package_config
            )
            # check whitelist approval for every job to be able to track down which jobs
            # failed because of missing whitelist approval
            whitelist = Whitelist()
            github_login = getattr(event, "github_login", None)
            if github_login and github_login in self.config.admins:
                logger.info(f"{github_login} is admin, you shall pass")
            elif not whitelist.check_and_report(
                event, event.get_project(), config=self.config
            ):
                handlers_results[job.type.value] = HandlerResults(
                    success=False, details={"msg": "Account is not whitelisted!"}
                )
                return handlers_results

            logger.debug(f"Running handler: {str(handler_kls)}")
            handler = handler_kls(config=self.config, job_config=job, event=event)
            if handler.pre_check():
                handlers_results[job.type.value] = handler.run_n_clean()
            # don't break here, other handlers may react to the same event

        return handlers_results
Esempio n. 7
0
    def process_comment_jobs(
        self, event: Union[PullRequestCommentEvent, IssueCommentEvent]
    ) -> HandlerResults:

        msg = f"comment '{event.comment}'"
        packit_command, pr_comment_error_msg = self.find_packit_command(
            str(event.comment))

        if pr_comment_error_msg:
            return HandlerResults(
                success=True,
                details={"msg": pr_comment_error_msg},
            )

        # packit has command `copr-build`. But PullRequestCommentAction has enum `copr_build`.
        try:
            packit_action = CommentAction[packit_command[0].replace("-", "_")]
        except KeyError:
            return HandlerResults(
                success=True,
                details={
                    "msg":
                    f"{msg} does not contain a valid packit-service command."
                },
            )
        handler_kls: Type[
            CommentActionHandler] = MAP_COMMENT_ACTION_TO_HANDLER.get(
                packit_action, None)
        if not handler_kls:
            return HandlerResults(
                success=True,
                details={"msg": f"{msg} is not a packit-service command."})

        # check whitelist approval for every job to be able to track down which jobs
        # failed because of missing whitelist approval
        whitelist = Whitelist()
        github_login = getattr(event, "github_login", None)
        if github_login and github_login in self.config.admins:
            logger.info(f"{github_login} is admin, you shall pass")
        elif not whitelist.check_and_report(
                event, event.get_project(), config=self.config):
            return HandlerResults(
                success=True, details={"msg": "Account is not whitelisted!"})

        handler_instance: Handler = handler_kls(config=self.config,
                                                event=event)
        return handler_instance.run_n_clean()
Esempio n. 8
0
    def process_jobs(self, event: Event) -> Dict[str, HandlerResults]:
        """
        Run a job handler (if trigger matches) for every job defined in config.
        """
        handlers_results = {}
        package_config = event.get_package_config()

        if not package_config:
            # this happens when service receives events for repos which
            # don't have packit config, this is not an error
            msg = "Failed to obtain package config!"
            logger.info(msg)
            handlers_results[event.trigger.value] = HandlerResults(
                success=False, details={"msg": msg})
            return handlers_results

        for job in package_config.jobs:
            if event.trigger == job.trigger:
                handler_kls: Type[JobHandler] = JOB_NAME_HANDLER_MAPPING.get(
                    job.job, None)
                if not handler_kls:
                    logger.warning(f"There is no handler for job {job}")
                    continue

                handler = handler_kls(self.config, job, event)
                try:
                    # check whitelist approval for every job to be able to track down which jobs
                    # failed because of missing whitelist approval
                    whitelist = Whitelist()
                    if not whitelist.check_and_report(event,
                                                      event.get_project()):
                        handlers_results[job.job.value] = HandlerResults(
                            success=False,
                            details={"msg": "Account is not whitelisted!"},
                        )
                        return handlers_results

                    logger.debug(f"Running handler: {str(handler_kls)}")
                    handlers_results[job.job.value] = handler.run()
                    # don't break here, other handlers may react to the same event
                finally:
                    handler.clean()
        return handlers_results
Esempio n. 9
0
def test_check_and_report(event, should_pass):
    w = Whitelist()
    w.db = {
        "anakin": {
            "status": "approved_manually"
        },
        "yoda": {
            "status": "approved_manually"
        },
        "naboo": {
            "status": "approved_manually"
        },
    }

    flexmock(
        GithubProject,
        pr_comment=lambda *args, **kwargs: None,
        set_commit_status=lambda *args, **kwargs: None,
        issue_comment=lambda *args, **kwargs: None,
    )
    git_project = GithubProject("", GithubService(), "")
    assert w.check_and_report(event, git_project) == should_pass
Esempio n. 10
0
def test_check_and_report(whitelist: Whitelist,
                          events: List[Tuple[AbstractGithubEvent, bool]]):
    """
    :param whitelist: fixture
    :param events: fixture: [(Event, should-be-approved)]
    """
    flexmock(
        GithubProject,
        pr_comment=lambda *args, **kwargs: None,
        set_commit_status=lambda *args, **kwargs: None,
        issue_comment=lambda *args, **kwargs: None,
    )
    flexmock(PullRequestEvent).should_receive("get_package_config").and_return(
        flexmock(jobs=[
            JobConfig(job=JobType.tests,
                      trigger=JobTriggerType.pull_request,
                      metadata={})
        ]))
    git_project = GithubProject("", GithubService(), "")
    for event in events:
        assert (whitelist.check_and_report(
            event[0], git_project, config=flexmock(deployment=Deployment.stg))
                is event[1])
Esempio n. 11
0
    def process_comment_jobs(
        self,
        event: Union[
            PullRequestCommentGithubEvent,
            PullRequestCommentPagureEvent,
            IssueCommentEvent,
        ],
    ) -> Dict[str, HandlerResults]:

        msg = f"comment '{event.comment}'"
        packit_command, pr_comment_error_msg = self.find_packit_command(
            str(event.comment)
        )

        if pr_comment_error_msg:
            return {
                event.trigger.value: HandlerResults(
                    success=True, details={"msg": pr_comment_error_msg},
                )
            }

        # packit has command `copr-build`. But PullRequestCommentAction has enum `copr_build`.
        try:
            packit_action = CommentAction[packit_command[0].replace("-", "_")]
        except KeyError:
            return {
                event.trigger.value: HandlerResults(
                    success=True,
                    details={
                        "msg": f"{msg} does not contain a valid packit-service command."
                    },
                )
            }

        if packit_action == CommentAction.test and isinstance(
            event.db_trigger, PullRequestModel
        ):
            if not event.db_trigger.get_copr_builds():
                packit_action = CommentAction.build

        handler_kls: Type[CommentActionHandler] = MAP_COMMENT_ACTION_TO_HANDLER.get(
            packit_action, None
        )
        if not handler_kls:
            return {
                event.trigger.value: HandlerResults(
                    success=True,
                    details={"msg": f"{msg} is not a packit-service command."},
                )
            }

        # check whitelist approval for every job to be able to track down which jobs
        # failed because of missing whitelist approval
        whitelist = Whitelist()
        user_login = getattr(event, "user_login", None)
        if user_login and user_login in self.config.admins:
            logger.info(f"{user_login} is admin, you shall pass.")
        elif not whitelist.check_and_report(event, event.project, config=self.config):
            return {
                event.trigger.value: HandlerResults(
                    success=True, details={"msg": f"Account is not whitelisted!"}
                )
            }

        # VERY UGLY
        # TODO: REFACTOR !!!
        if handler_kls == GitHubPullRequestCommentCoprBuildHandler and isinstance(
            event, PullRequestCommentPagureEvent
        ):
            handler_kls = PagurePullRequestCommentCoprBuildHandler

        handlers_results: Dict[str, HandlerResults] = {}
        jobs = get_config_for_handler_kls(
            handler_kls=handler_kls, event=event, package_config=event.package_config,
        )
        for job in jobs:
            handler_instance: Handler = handler_kls(
                config=self.config, event=event, job=job
            )
            result_key = (
                f"{job.type.value}-{datetime.datetime.now().strftime(DATETIME_FORMAT)}"
            )
            handlers_results[result_key] = handler_instance.run_n_clean()
        return handlers_results
Esempio n. 12
0
    def process_comment_jobs(
        self,
        event: Union[PullRequestCommentGithubEvent,
                     PullRequestCommentPagureEvent, IssueCommentEvent,
                     MergeRequestCommentGitlabEvent,
                     IssueCommentGitlabEvent, ],
    ) -> Dict[str, TaskResults]:

        msg = f"comment '{event.comment}'"
        packit_command, pr_comment_error_msg = self.find_packit_command(
            str(event.comment))

        if pr_comment_error_msg:
            return {
                event.trigger.value:
                TaskResults(
                    success=True,
                    details={"msg": pr_comment_error_msg},
                )
            }

        # packit has command `copr-build`. But PullRequestCommentAction has enum `copr_build`.
        try:
            packit_action = CommentAction[packit_command[0].replace("-", "_")]
        except KeyError:
            return {
                event.trigger.value:
                TaskResults(
                    success=True,
                    details={
                        "msg":
                        f"{msg} does not contain a valid packit-service command."
                    },
                )
            }

        if (packit_action == CommentAction.test
                and isinstance(event.db_trigger, PullRequestModel)
                and not event.db_trigger.get_copr_builds()):
            packit_action = CommentAction.build

        handler_kls: Type[
            CommentActionHandler] = MAP_COMMENT_ACTION_TO_HANDLER.get(
                packit_action, None)
        if not handler_kls:
            return {
                event.trigger.value:
                TaskResults(
                    success=True,
                    details={"msg": f"{msg} is not a packit-service command."},
                )
            }

        # check whitelist approval for every job to be able to track down which jobs
        # failed because of missing whitelist approval
        whitelist = Whitelist()
        user_login = getattr(event, "user_login", None)
        jobs = get_config_for_handler_kls(
            handler_kls=handler_kls,
            event=event,
            package_config=event.package_config,
        )
        if user_login and user_login in self.service_config.admins:
            logger.info(f"{user_login} is admin, you shall pass.")
        elif not whitelist.check_and_report(event,
                                            event.project,
                                            service_config=self.service_config,
                                            job_configs=jobs):
            return {
                event.trigger.value:
                TaskResults(success=True,
                            details={"msg": "Account is not whitelisted!"})
            }

        # VERY UGLY
        # TODO: REFACTOR !!!
        if handler_kls == GitHubPullRequestCommentCoprBuildHandler and isinstance(
                event, PullRequestCommentPagureEvent):
            handler_kls = PagurePullRequestCommentCoprBuildHandler

        signatures = [
            handler_kls.get_signature(event=event, job=job) for job in jobs
        ]
        # https://docs.celeryproject.org/en/stable/userguide/canvas.html#groups
        group(signatures).apply_async()
        return get_processing_results(event=event, jobs=jobs)
Esempio n. 13
0
def test_check_and_report(whitelist: Whitelist,
                          events: List[Tuple[AbstractGithubEvent, bool]]):
    """
    :param whitelist: fixture
    :param events: fixture: [(Event, should-be-approved)]
    """
    flexmock(
        GithubProject,
        pr_comment=lambda *args, **kwargs: None,
        set_commit_status=lambda *args, **kwargs: None,
        issue_comment=lambda *args, **kwargs: None,
    )
    flexmock(PullRequestGithubEvent).should_receive(
        "get_package_config").and_return(
            flexmock(jobs=[
                JobConfig(
                    type=JobType.tests,
                    trigger=JobConfigTriggerType.pull_request,
                    metadata=JobMetadataConfig(targets=["fedora-rawhide"]),
                )
            ], ))

    git_project = GithubProject("", GithubService(), "")
    for event, is_valid in events:
        if isinstance(event, PullRequestGithubEvent) and not is_valid:
            # Report the status
            flexmock(CoprHelper).should_receive("get_copr_client").and_return(
                Client(
                    config={
                        "copr_url": "https://copr.fedorainfracloud.org",
                        "username": "******",
                    }))
            flexmock(LocalProject).should_receive(
                "refresh_the_arguments").and_return(None)
            flexmock(LocalProject).should_receive("checkout_pr").and_return(
                None)
            flexmock(StatusReporter).should_receive("report").with_args(
                description="Account is not whitelisted!",
                state=CommitStatus.error,
                url=FAQ_URL,
                check_names=[EXPECTED_TESTING_FARM_CHECK_NAME],
            ).once()

        # get_account returns the whitelist object if it exists
        # returns nothing if it isn't whitelisted
        # then inside the whitelist.py file, a function checks if the status is
        # one of the approved statuses

        # this exact code is used twice above but mypy has an issue with this one only
        whitelist_mock = flexmock(DBWhitelist).should_receive("get_account")
        if not TYPE_CHECKING:
            if is_valid:
                whitelist_mock.and_return(
                    DBWhitelist(status="approved_manually"))
            else:
                whitelist_mock.and_return(None)

        assert (whitelist.check_and_report(
            event,
            git_project,
            config=flexmock(deployment=Deployment.stg,
                            command_handler_work_dir=""),
        ) is is_valid)
Esempio n. 14
0
    def process_jobs(self, event: Event) -> List[TaskResults]:
        """
        Create a Celery task for a job handler (if trigger matches) for every job defined in config.
        """

        if isinstance(
                event,
            (PushGitHubEvent, PushGitlabEvent,
             PushPagureEvent)) and event.commit_sha.startswith("0000000"):
            return [
                TaskResults.create_from(
                    success=True,
                    msg="Triggered by deleting a branch",
                    job_config=None,
                    event=event,
                )
            ]

        if not event.package_config:
            # this happens when service receives events for repos which don't have packit config
            # success=True - it's not an error that people don't have packit.yaml in their repo
            return [
                TaskResults.create_from(
                    success=True,
                    msg="No packit config found in the repository.",
                    job_config=None,
                    event=event,
                )
            ]

        if isinstance(
                event,
            (
                PullRequestCommentGithubEvent,
                PullRequestCommentPagureEvent,
                IssueCommentEvent,
                MergeRequestCommentGitlabEvent,
                IssueCommentGitlabEvent,
            ),
        ):
            if not event.project.can_merge_pr(event.user_login):
                logger.debug(
                    f"User {event.user_login} not allowed to trigger packit via comments."
                )
                return [
                    TaskResults.create_from(
                        success=True,
                        msg=
                        f"User {event.user_login} not allowed to trigger packit via comments.",
                        job_config=None,
                        event=event,
                    )
                ]

        handler_classes = get_handlers_for_event(event, event.package_config)

        if not handler_classes:
            logger.debug(
                f"There is no handler for {event} event suitable for the configuration."
            )
            return []

        job_configs = []
        for handler_kls in handler_classes:
            # TODO: merge to to get_handlers_for_event so
            # so we don't need to go through the similar process twice.
            job_configs = get_config_for_handler_kls(
                handler_kls=handler_kls,
                event=event,
                package_config=event.package_config,
            )
            # check whitelist approval for every job to be able to track down which jobs
            # failed because of missing whitelist approval
            whitelist = Whitelist()
            user_login = getattr(event, "user_login", None)
            if user_login and user_login in self.service_config.admins:
                logger.info(f"{user_login} is admin, you shall pass.")
            elif not whitelist.check_and_report(
                    event,
                    event.project,
                    service_config=self.service_config,
                    job_configs=job_configs,
            ):
                processing_results = []
                for job_config in job_configs:
                    processing_results.append(
                        TaskResults.create_from(
                            success=False,
                            msg="Account is not whitelisted!",
                            job_config=job_config,
                            event=event,
                        ))
                return processing_results

            # we want to run handlers for all possible jobs, not just the first one
            signatures = [
                handler_kls.get_signature(event=event, job=job_config)
                for job_config in job_configs
            ]
            # https://docs.celeryproject.org/en/stable/userguide/canvas.html#groups
            group(signatures).apply_async()

        processing_results = []
        for job_config in job_configs:
            processing_results.append(
                TaskResults.create_from(
                    success=True,
                    msg="Job created.",
                    job_config=job_config,
                    event=event,
                ))
        return processing_results