import json import logging import subprocess import traceback from dataclasses import dataclass from enum import StrEnum from typing import Optional from alerting import alerts from alerting.enum import AlertType, Severity class Severity(StrEnum): LOW = "Low" MEDIUM = "Medium" HIGH = "High" CRITICAL = "Critical" @dataclass class Vulnerability: id: str link: str vuln_type: str packages: list[str] severity: Severity fixed: Optional[str] def _parse_arch_audit_output(output: str) -> list[Vulnerability]: arch_audit_json = json.loads(output) vulnerabilities = [] for v in arch_audit_json: vulnerability = Vulnerability( id=v["name"], link=f"https://security.archlinux.org/{v['name']}", vuln_type=v["type"], packages=v["packages"], severity=v["severity"], fixed=v["fixed"], ) vulnerabilities.append(vulnerability) return vulnerabilities async def get_vulns() -> list[Vulnerability]: try: arch_audit_output = subprocess.check_output(["arch-audit", "--json"]) except FileNotFoundError: await alerts.send_alert( alerts.Alert( alert_type=AlertType.ERROR, message="arch-audit not installed!", severity=Severity.CRITICAL, ) ) return [] except Exception as exc: await alerts.send_alert( alerts.Alert( alert_type=AlertType.ERROR, message=f"arch-audit failed to run: {repr(exc)}, see logs", severity=Severity.CRITICAL, ) ) logging.error(traceback.format_exc()) return [] return _parse_arch_audit_output(arch_audit_output)