MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / ComplianceReporter

Class ComplianceReporter

compliance_report.py:32–339  ·  view source on GitHub ↗

Builds CIS and PCI compliance views from data Ragnar already collects.

Source from the content-addressed store, hash-verified

30
31
32class ComplianceReporter:
33 """Builds CIS and PCI compliance views from data Ragnar already collects."""
34
35 def __init__(self, shared_data=None, db=None):
36 self.shared_data = shared_data
37 self.db = db or getattr(shared_data, "db", None)
38 self.mappings = self._load_mappings()
39
40 def _load_mappings(self) -> Dict[str, Any]:
41 try:
42 with open(_MAPPINGS_FILE, "r", encoding="utf-8") as handle:
43 return json.load(handle)
44 except Exception as exc:
45 logger.error(f"Could not load compliance mappings: {exc}")
46 return {"cis": {"lynis_to_cis": {}, "prefix_to_cis": {}}, "pci": {"requirements": []}}
47
48 # ------------------------------------------------------------------
49 # Data collection
50 # ------------------------------------------------------------------
51
52 def _vuln_dir(self) -> Optional[str]:
53 return getattr(self.shared_data, "vulnerabilities_dir", None)
54
55 def _collect_lynis(self, host: Optional[str] = None) -> List[Dict[str, Any]]:
56 records = []
57 base = self._vuln_dir()
58 if not base or not os.path.isdir(base):
59 return records
60
61 for root, _dirs, files in os.walk(base):
62 for filename in files:
63 match = _LYNIS_DAT_RE.match(filename)
64 if not match:
65 continue
66 rec_host = match.group("host")
67 if host and rec_host != host:
68 continue
69 path = os.path.join(root, filename)
70 try:
71 with open(path, "r", encoding="utf-8", errors="ignore") as handle:
72 parsed = parse_lynis_dat(handle.read()) or {}
73 except Exception as exc:
74 logger.warning(f"Failed to parse Lynis dat {filename}: {exc}")
75 continue
76
77 metadata = parsed.get("metadata", {}) if isinstance(parsed, dict) else {}
78 scan_date = datetime.fromtimestamp(os.path.getmtime(path)).strftime("%Y-%m-%d %H:%M:%S")
79 records.append({
80 "host": rec_host,
81 "scan_date": scan_date,
82 "hardening_index": metadata.get("hardening_index"),
83 "warnings": parsed.get("warnings", []),
84 "suggestions": parsed.get("suggestions", []),
85 "vulnerable_packages": parsed.get("vulnerable_packages", []),
86 })
87
88 records.sort(key=lambda r: r["scan_date"], reverse=True)
89 seen = set()

Callers 2

compliance_report_exportFunction · 0.90
compliance_report_jsonFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected