Ejemplo n.º 1
0
    def run(cls, configuration_file: str) -> None:
        """Run Kebechet using provided YAML configuration file."""
        global config
        from kebechet.managers import REGISTERED_MANAGERS

        config.from_file(configuration_file)

        for managers, slug, service_type, service_url, token, tls_verify in config.iter_entries():
            cls._tls_verification(service_url, slug, verify=tls_verify)

            if service_url and not service_url.startswith(('https://', 'http://')):
                # We need to have this explicitly set for IGitt and also for security reasons.
                _LOGGER.error(
                    "You have to specify protocol ('https://' or 'http://') in service URL "
                    "configuration entry - invalid configuration {service_url!}"
                )
                continue

            if service_url and service_url.endswith('/'):
                service_url = service_url[:-1]

            if token:
                # Allow token expansion based on env variables.
                token = token.format(**os.environ)
                _LOGGER.debug(f"Using token '{token[:3]}{'*'*len(token[3:])}'")

            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(f"No manager name provided in configuration entry for {slug}, ignoring entry")
                    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(f"Running manager %r for %r", manager_name, slug)
                manager_configuration = manager.pop('configuration', {})
                if manager:
                    _LOGGER.warning(f"Ignoring option {manager} in manager entry for {slug}")

                try:
                    instance = kebechet_manager(slug, ServiceType.by_name(service_type), service_url, token)
                    instance.run(**manager_configuration)
                except Exception as exc:
                    _LOGGER.exception(
                        f"An error occurred during run of manager {manager!r} {kebechet_manager} for {slug}, skipping"
                    )

            _LOGGER.info(f"Finished management for {slug!r}")
Ejemplo n.º 2
0
    def run_url(cls, url: str, service: str, parsed_payload: dict,
                tls_verify: bool):
        temp_file = cls.download_conf_from_url(url, service)
        _LOGGER.debug("Filename = %s", temp_file.name)

        global config
        from kebechet.managers import REGISTERED_MANAGERS

        tempfile = config.download_conf_from_url(url, service)
        managers = cls._managers_from_file(tempfile.name)

        # If called from run_webhook tls verify is always true.
        if tls_verify is None:
            tls_verify = cls._tls_verify_from_file(tempfile.name)

        scheme, _, host, _, slug, _, _ = urllib3.util.parse_url(url)
        slug = slug[1:]
        service_url = f"{scheme}://{host}"

        cls._tls_verification(service_url, slug, verify=tls_verify)

        if service_url and not service_url.startswith(("https://", "http://")):
            # We need to have this explicitly set for IGitt and also for security reasons.
            _LOGGER.error(
                "You have to specify protocol ('https://' or 'http://') in service URL "
                "configuration entry - invalid configuration %r",
                service_url,
            )

        if service_url and service_url.endswith("/"):
            service_url = service_url[:-1]

        service = Service(service, url)
        token = service.token
        _LOGGER.debug("Using token %r%r", token[:3], "*" * len(token[3:]))

        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
            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(f"Running manager %r for %r", manager_name, slug)
            manager_configuration = manager.pop("configuration", {})
            if manager:
                _LOGGER.warning(
                    "Ignoring option %r in manager entry for %r",
                    manager,
                    slug,
                )
            try:
                instance = kebechet_manager(slug, service.service, service_url,
                                            parsed_payload, token)
                instance.run(**manager_configuration)
            except Exception as exc:
                _LOGGER.exception(
                    "An error occurred during run of manager %r %r for %r, skipping",
                    manager,
                    kebechet_manager,
                    slug,
                )

        temp_file.close()
Ejemplo n.º 3
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
Ejemplo n.º 5
0
    def run(cls, configuration_file: str) -> None:
        """Run Kebechet using provided YAML configuration file."""
        global config
        from kebechet.managers import REGISTERED_MANAGERS

        config.from_file(configuration_file)

        for (
            managers,
            slug,
            service_type,
            service_url,
            token,
            tls_verify,
        ) in config.iter_entries():
            cls._tls_verification(service_url, slug, verify=tls_verify)

            if service_url and not service_url.startswith(("https://", "http://")):
                # We need to have this explicitly set for IGitt and also for security reasons.
                _LOGGER.error(
                    "You have to specify protocol ('https://' or 'http://') in service URL "
                    "configuration entry - invalid configuration {service_url!}"
                )
                continue

            if service_url and service_url.endswith("/"):
                service_url = service_url[:-1]

            if token:
                # Allow token expansion based on env variables.
                token = token.format(**os.environ)
                _LOGGER.debug("Using token '%r%r'", token[:3], "*" * len(token[3:]))

            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

                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 manager:
                    _LOGGER.warning(
                        "Ignoring option %r in manager entry for %r", manager, slug
                    )

                try:
                    instance = kebechet_manager(
                        # The service type is set by default to github.
                        slug,
                        ServiceType.by_name(service_type),
                        service_url,
                        None,
                        token,
                    )
                    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)