55 行
2.3 KiB
Python
55 行
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from tempfile import TemporaryDirectory
|
|
from typing import Any, Dict, List
|
|
|
|
from lab.compose import compose_payload
|
|
from lab.config import ENV_CATALOG_DIR, REPRO_MAP_PATH, REPRO_PROFILES_DIR
|
|
from lab.utils import command_available, read_yaml, run, write_yaml
|
|
|
|
|
|
def validate_assets() -> List[str]:
|
|
errors: List[str] = []
|
|
if not REPRO_MAP_PATH.exists():
|
|
errors.append(f"missing repro map: {REPRO_MAP_PATH}")
|
|
if not ENV_CATALOG_DIR.exists():
|
|
errors.append(f"missing environment catalog dir: {ENV_CATALOG_DIR}")
|
|
for path in sorted(REPRO_PROFILES_DIR.rglob("*.yaml")):
|
|
content = read_yaml(path, default=None)
|
|
if not isinstance(content, dict):
|
|
errors.append(f"invalid repro profile yaml: {path}")
|
|
continue
|
|
for field in [
|
|
"profile_id",
|
|
"match_rules",
|
|
"vuln_family",
|
|
"provisioning_mode",
|
|
"attack_actions",
|
|
"baseline_actions",
|
|
"success_criteria",
|
|
"cleanup_policy",
|
|
"destructive_risk",
|
|
"allowed_target_types",
|
|
]:
|
|
if field not in content:
|
|
errors.append(f"repro profile missing {field}: {path}")
|
|
docker_available = command_available("docker")
|
|
profile_roots = sorted((ENV_CATALOG_DIR.parent.parent / "profiles").rglob("*.yaml"))
|
|
for path in profile_roots:
|
|
content = read_yaml(path, default=None)
|
|
if not isinstance(content, dict):
|
|
errors.append(f"invalid environment profile yaml: {path}")
|
|
continue
|
|
for field in ["profile_id", "system_id", "services", "cleanup_policy"]:
|
|
if field not in content:
|
|
errors.append(f"environment profile missing {field}: {path}")
|
|
if docker_available:
|
|
with TemporaryDirectory() as temp_dir:
|
|
compose_path = Path(temp_dir) / "compose.yaml"
|
|
write_yaml(compose_path, compose_payload(content))
|
|
result = run(["docker", "compose", "-f", str(compose_path), "config"], cwd=compose_path.parent)
|
|
if result.returncode != 0:
|
|
errors.append(f"docker compose config failed for {path}: {result.stderr.strip() or result.stdout.strip()}")
|
|
return errors
|