70 lines
2.2 KiB
Python
70 lines
2.2 KiB
Python
"""Orchestrate running all checks for a given profile."""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from typing import List, Optional
|
|
|
|
from .checks import ALL_CHECKS, PROFILE_CHECKS
|
|
from .executor import LocalExecutor, SSHExecutor
|
|
from .models import AuditReport, CheckResult, ERROR
|
|
|
|
|
|
def run_audit(
|
|
executor: LocalExecutor | SSHExecutor,
|
|
profile: str,
|
|
check_ids: Optional[List[str]] = None,
|
|
verbose: bool = False,
|
|
) -> AuditReport:
|
|
"""
|
|
Run all checks for *profile* (or a specific subset via *check_ids*)
|
|
against *executor*. Returns a populated AuditReport.
|
|
"""
|
|
if profile not in PROFILE_CHECKS:
|
|
raise ValueError(
|
|
f"Unknown profile '{profile}'. "
|
|
f"Valid: {list(PROFILE_CHECKS.keys())}"
|
|
)
|
|
|
|
ids_to_run = check_ids if check_ids else PROFILE_CHECKS[profile]
|
|
report = AuditReport(target=executor.name, profile=profile)
|
|
|
|
total = len(ids_to_run)
|
|
for i, cid in enumerate(ids_to_run, 1):
|
|
if verbose:
|
|
print(f" [{i}/{total}] Running check {cid} ...", end="\r", flush=True)
|
|
|
|
func = ALL_CHECKS.get(cid)
|
|
if func is None:
|
|
result = CheckResult(
|
|
check_id=cid,
|
|
title=f"Check {cid}",
|
|
profiles=[profile],
|
|
status=ERROR,
|
|
actual_value="No implementation found for this check ID",
|
|
expected_value="N/A",
|
|
commands_run=[],
|
|
remediation="",
|
|
notes="This check ID is not implemented in the current version.",
|
|
)
|
|
else:
|
|
try:
|
|
result = func(executor)
|
|
except Exception as exc:
|
|
result = CheckResult(
|
|
check_id=cid,
|
|
title=f"Check {cid}",
|
|
profiles=[profile],
|
|
status=ERROR,
|
|
actual_value=f"Unexpected error: {exc}",
|
|
expected_value="N/A",
|
|
commands_run=[],
|
|
remediation="",
|
|
notes=str(exc),
|
|
)
|
|
|
|
report.results.append(result)
|
|
|
|
if verbose:
|
|
print(" " * 60, end="\r") # clear progress line
|
|
|
|
return report
|