Ejemplo n.º 1
0
def run(
    service_type: str,
    namespace: str,
    project: str,
    service_url: Optional[str],
    enabled_managers: List[str] = list(REGISTERED_MANAGERS.keys()),
    parsed_payload: Optional[Dict[Any, Any]] = None,
    metadata: Optional[Dict[str, Any]] = None,
    analysis_id: Optional[str] = None,
    runtime_environment: Optional[str] = None,
) -> None:
    """Run Kebechet using provided YAML configuration file."""
    token = os.getenv(f"{service_type.upper()}_KEBECHET_TOKEN")

    ogr_service = create_ogr_service(
        service_type=service_type,
        service_url=service_url,
        token=token,
        github_app_id=os.getenv("GITHUB_APP_ID"),
        github_private_key_path=os.getenv("GITHUB_PRIVATE_KEY_PATH"),
    )

    with download_kebechet_config(ogr_service, namespace, project) as f:
        config = _Config.from_file(f)

    slug = f"{namespace}/{project}"

    managers = config.managers

    for manager in managers:
        # We do pops on dict, which changes it. Let's create a soft duplicate so if a user uses
        # YAML references, we do not break.
        manager = dict(manager)
        try:
            manager_name = manager.pop("name")
        except Exception:
            _LOGGER.exception(
                "No manager name provided in configuration entry for %r, ignoring entry",
                slug,
            )
            continue

        if manager_name not in enabled_managers:
            _LOGGER.debug(
                "Skipping manager %r because it is not in the list of enabled managers.",
                manager_name,
            )
            continue

        kebechet_manager = REGISTERED_MANAGERS.get(manager_name)
        if not kebechet_manager:
            _LOGGER.error("Unable to find requested manager %r, skipping", manager_name)
            continue

        _LOGGER.info("Running manager %r for %r", manager_name, slug)
        manager_configuration = manager.get("configuration") or {}

        if analysis_id:
            manager_configuration["analysis_id"] = analysis_id

        try:
            instance = kebechet_manager(
                slug=slug,
                service=ogr_service,
                service_type=service_type,
                parsed_payload=parsed_payload,
                token=token,
                metadata=metadata,
                runtime_environment=runtime_environment,
            )
            instance.run(**manager_configuration)
        except Exception as exc:  # noqa F841
            _LOGGER.exception(
                "An error occurred during run of manager %r %r for %r, skipping",
                manager,
                kebechet_manager,
                slug,
            )
    _LOGGER.info("Finished management for %r", slug)
def run(
    service_type: str,
    namespace: str,
    project: str,
    service_url: Optional[str],
    enabled_managers: List[str] = list(REGISTERED_MANAGERS.keys()),
    parsed_payload: Optional[Dict[Any, Any]] = None,
    metadata: Optional[Dict[str, Any]] = None,
    analysis_id: Optional[str] = None,
    runtime_environment: Optional[str] = None,
) -> None:
    """Run Kebechet using provided YAML configuration file."""
    token = os.getenv(f"{service_type.upper()}_KEBECHET_TOKEN")

    ogr_service = create_ogr_service(
        service_type=service_type,
        service_url=service_url,
        token=token,
        github_app_id=os.getenv("GITHUB_APP_ID"),
        github_private_key_path=os.getenv("GITHUB_PRIVATE_KEY_PATH"),
    )

    slug = f"{namespace}/{project}"

    try:
        with download_kebechet_config(ogr_service, namespace, project) as f:
            config = _Config.from_file(f)
    except FileNotFoundError:
        _LOGGER.info(
            "No Kebechet found in repo. Opening PR with simple configuration.")
        ConfigInitializer(
            slug=slug,
            service=ogr_service,
            service_type=service_type,
        ).run()
        return

    managers = config.managers

    for manager in managers:
        # We do pops on dict, which changes it. Let's create a soft duplicate so if a user uses
        # YAML references, we do not break.
        manager = dict(manager)
        try:
            manager_name = manager.pop("name")
        except Exception:
            _LOGGER.exception(
                "No manager name provided in configuration entry for %r, ignoring entry",
                slug,
            )
            continue

        if manager_name not in enabled_managers:
            _LOGGER.debug(
                "Skipping manager %r because it is not in the list of enabled managers.",
                manager_name,
            )
            continue

        kebechet_manager = REGISTERED_MANAGERS.get(manager_name)
        if not kebechet_manager:
            _LOGGER.error("Unable to find requested manager %r, skipping",
                          manager_name)
            continue

        _LOGGER.info("Running manager %r for %r", manager_name, slug)
        manager_configuration = manager.get("configuration") or {}

        if analysis_id:
            manager_configuration["analysis_id"] = analysis_id

        try:
            if manager_configuration.pop("enabled", True):
                instance = kebechet_manager(
                    slug=slug,
                    service=ogr_service,
                    service_type=service_type,
                    parsed_payload=parsed_payload,
                    metadata=metadata,
                    runtime_environment=runtime_environment,
                )
                instance.run(**manager_configuration)
        except Exception as exc:  # noqa F841
            _LOGGER.exception(
                "An error occurred during run of manager %r %r for %r, skipping",
                manager,
                kebechet_manager,
                slug,
            )
            if (isinstance(exc, GithubException) and exc.status == 410
                    and isinstance(exc.data, dict)
                    and (message := exc.data.get("message")) is not None
                    and "issue" in message.lower()  # type: ignore
                    and "disable" in message.lower()  # type: ignore
                ):
                _LOGGER.info(
                    "Cannot open issue because it is disabled on this repo.")
                continue
            elif isinstance(exc, GithubException) and exc.status >= 500:
                raise exc  # reraise server error as the response could be flaky (behaviour dependent on retry policy).
            elif isinstance(exc, ConnectionError):
                continue