예제 #1
0
    def run(self) -> TaskResults:
        """
        Discover information about organization/user which wants to install packit on his repository
        Try to allowlist automatically if mapping from github username to FAS account can prove that
        user is a packager.
        :return: TaskResults
        """
        InstallationModel.create(event=self.installation_event)
        # try to add user to allowlist
        allowlist = Allowlist(
            fas_user=self.service_config.fas_user,
            fas_password=self.service_config.fas_password,
        )
        if not allowlist.add_account(self.account_login, self.sender_login):
            # Create an issue in our repository, so we are notified when someone install the app
            self.project.create_issue(
                title=
                f"{self.account_type} {self.account_login} needs to be approved.",
                body=
                (f"Hi @{self.sender_login}, we need to approve you in "
                 "order to start using Packit-as-a-Service. Someone from our team will "
                 "get back to you shortly.\n\n"
                 "For more info, please check out the documentation: "
                 "http://packit.dev/packit-as-a-service/"),
            )
            msg = f"{self.account_type} {self.account_login} needs to be approved manually!"
        else:
            msg = f"{self.account_type} {self.account_login} allowlisted!"

        logger.info(msg)
        return TaskResults(success=True, details={"msg": msg})
예제 #2
0
def remove(account_name):
    """
    Remove account from allowlist

    :param account_name: github namespace
    :return:
    """
    Allowlist().remove_account(account_name)
예제 #3
0
def approve(account_name):
    """
    Approve user who is waiting on allowlist.

    :param account_name: github namespace
    :return:
    """
    Allowlist().approve_account(account_name)
예제 #4
0
def approve(full_path: Optional[str]):
    if full_path is None:
        full_path = RepoUrl().convert(construct_path())

    is_approved_before = Allowlist.is_approved(full_path)

    Allowlist().approve_namespace(full_path)
    if Allowlist.is_approved(full_path) != is_approved_before:
        click.secho(f"Namespace ‹{full_path}› has been approved.", fg="green")
    else:
        click.secho(f"Status of namespace ‹{full_path}› has not changed.",
                    fg="yellow")
예제 #5
0
def waiting(ctx):
    click.echo("Accounts waiting for approval:")

    waiting_list = Allowlist().waiting_namespaces()
    for i, namespace in enumerate(waiting_list, 1):
        click.echo(f"{i}. {namespace}")

    if choice := click.prompt(
            "Do you wish to allowlist namespace or repository?",
            type=click.types.IntRange(min=min(1, len(waiting_list)),
                                      max=len(waiting_list)),
    ):
        click.echo()
        ctx.invoke(approve, full_path=prompt_variant(waiting_list[choice - 1]))
예제 #6
0
    def run(self) -> TaskResults:
        """
        Discover information about organization/user which wants to install packit on his repository
        Try to allowlist automatically if mapping from github username to FAS account can prove that
        user is a packager.
        :return: TaskResults
        """
        InstallationModel.create(event=self.installation_event)
        # try to add user to allowlist
        allowlist = Allowlist(
            fas_user=self.service_config.fas_user,
            fas_password=self.service_config.fas_password,
        )
        if not allowlist.add_namespace(f"github.com/{self.account_login}",
                                       self.sender_login):
            # Create an issue in our repository, so we are notified when someone install the app
            self.project.create_issue(
                title=
                f"{self.account_type} {self.account_login} needs to be approved.",
                body=
                (f"Hi @{self.sender_login}, we need to approve you in "
                 "order to start using Packit-as-a-Service. "
                 "We are now onboarding Fedora contributors who have a valid "
                 "[Fedora Account System](https://fedoraproject.org/wiki/Account_System) "
                 "account and have signed "
                 "[FPCA](https://fedoraproject.org/wiki/Legal"
                 ":Fedora_Project_Contributor_Agreement). "
                 "If you have such an account, please, provide it in a comment and "
                 "we'd be glad to approve you for using the service.\n\n"
                 "For more info, please check out the documentation: "
                 "https://packit.dev/docs/packit-service"),
            )
            msg = f"{self.account_type} {self.account_login} needs to be approved manually!"
        else:
            msg = f"{self.account_type} {self.account_login} allowlisted!"

        logger.info(msg)
        return TaskResults(success=True, details={"msg": msg})
예제 #7
0
def remove(full_path: str):
    if full_path is None:
        full_path = RepoUrl().convert(construct_path())

    Allowlist().remove_namespace(full_path)
예제 #8
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,
                AbstractCommentEvent) and get_packit_commands_from_comment(
                    event.comment):
            # we require packit config file when event is triggered by /packit command
            event.fail_when_config_file_missing = True

        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,
                )
            ]

        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 []

        allowlist = Allowlist()
        processing_results: List[TaskResults] = []

        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 allowlist approval for every job to be able to track down which jobs
            # failed because of missing allowlist approval
            if not allowlist.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 allowlisted!",
                            job_config=job_config,
                            event=event,
                        ))
                return processing_results

            signatures = []

            # we want to run handlers for all possible jobs, not just the first one
            for job_config in job_configs:
                handler = handler_kls(
                    package_config=event.package_config,
                    job_config=job_config,
                    event=event.get_dict(),
                )
                if not handler.pre_check():
                    continue

                if event.actor and not handler.check_if_actor_can_run_job_and_report(
                        actor=event.actor):
                    # For external contributors, we need to be more careful when running jobs.
                    # This is a handler-specific permission check
                    # for a user who trigger the action on a PR.
                    # e.g. We don't allow using internal TF for external contributors.
                    continue

                if isinstance(
                        handler,
                    (CoprBuildHandler, KojiBuildHandler, TestingFarmHandler)):
                    helper = (CoprBuildJobHelper if isinstance(
                        handler, (CoprBuildHandler,
                                  TestingFarmHandler)) else KojiBuildJobHelper)

                    job_helper = helper(
                        service_config=self.service_config,
                        package_config=event.package_config,
                        project=event.project,
                        metadata=EventData.from_event_dict(event.get_dict()),
                        db_trigger=event.db_trigger,
                        job_config=job_config,
                        targets_override=event.targets_override,
                    )

                    reporting_method = (job_helper.report_status_to_tests if
                                        isinstance(handler, TestingFarmHandler)
                                        else job_helper.report_status_to_build)

                    reporting_method(
                        description=TASK_ACCEPTED,
                        state=BaseCommitStatus.pending,
                        url="",
                    )
                    push_initial_metrics(event, handler,
                                         len(job_helper.build_targets))

                signatures.append(
                    handler_kls.get_signature(event=event, job=job_config))
                processing_results.append(
                    TaskResults.create_from(
                        success=True,
                        msg="Job created.",
                        job_config=job_config,
                        event=event,
                    ))
            # https://docs.celeryproject.org/en/stable/userguide/canvas.html#groups
            group(signatures).apply_async()

        return processing_results
예제 #9
0
def allowlist():
    w = Allowlist()
    return w
예제 #10
0
def allowlist():
    return Allowlist()