mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-04 19:21:51 +00:00
101 lines
3.1 KiB
Python
101 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Build a per-provider check inventory by scanning Prowler's check metadata files.
|
|
|
|
Outputs one JSON per provider at /tmp/checks_{provider}.json with the shape:
|
|
{
|
|
"check_id": {
|
|
"service": "...",
|
|
"subservice": "...",
|
|
"resource": "...",
|
|
"severity": "...",
|
|
"title": "...",
|
|
"description": "...",
|
|
"risk": "..."
|
|
},
|
|
...
|
|
}
|
|
|
|
This is the reference used by audit_framework_template.py for pre-validation
|
|
(every check id in the audit ledger must exist in the inventory) and by
|
|
query_checks.py for keyword/service lookup.
|
|
|
|
Usage:
|
|
python skills/prowler-compliance/assets/build_inventory.py
|
|
# Or for a specific provider:
|
|
python skills/prowler-compliance/assets/build_inventory.py aws
|
|
|
|
Output:
|
|
/tmp/checks_{provider}.json for every provider discovered under
|
|
prowler/providers/ with a services/ directory.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PROVIDERS_ROOT = Path("prowler/providers")
|
|
|
|
|
|
def discover_providers() -> list[str]:
|
|
"""Return every provider that currently has a services/ directory.
|
|
|
|
Derived from the filesystem so new providers are picked up automatically
|
|
and stale hard-coded lists cannot drift from the repo.
|
|
"""
|
|
if not PROVIDERS_ROOT.exists():
|
|
return []
|
|
return sorted(
|
|
p.name
|
|
for p in PROVIDERS_ROOT.iterdir()
|
|
if p.is_dir() and (p / "services").is_dir()
|
|
)
|
|
|
|
|
|
def build_for_provider(provider: str) -> dict:
|
|
inventory: dict[str, dict] = {}
|
|
base = Path(f"prowler/providers/{provider}/services")
|
|
if not base.exists():
|
|
print(f" skip {provider}: no services directory", file=sys.stderr)
|
|
return inventory
|
|
for meta_path in base.rglob("*.metadata.json"):
|
|
try:
|
|
with open(meta_path) as f:
|
|
data = json.load(f)
|
|
except Exception as exc:
|
|
print(f" warn: cannot parse {meta_path}: {exc}", file=sys.stderr)
|
|
continue
|
|
cid = data.get("CheckID") or meta_path.stem.replace(".metadata", "")
|
|
inventory[cid] = {
|
|
"service": data.get("ServiceName", ""),
|
|
"subservice": data.get("SubServiceName", ""),
|
|
"resource": data.get("ResourceType", ""),
|
|
"severity": data.get("Severity", ""),
|
|
"title": data.get("CheckTitle", ""),
|
|
"description": data.get("Description", ""),
|
|
"risk": data.get("Risk", ""),
|
|
}
|
|
return inventory
|
|
|
|
|
|
def main() -> int:
|
|
providers = sys.argv[1:] or discover_providers()
|
|
if not providers:
|
|
print(
|
|
f"error: no providers found under {PROVIDERS_ROOT}/",
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
for provider in providers:
|
|
inv = build_for_provider(provider)
|
|
out_path = Path(f"/tmp/checks_{provider}.json")
|
|
with open(out_path, "w") as f:
|
|
json.dump(inv, f, indent=2)
|
|
print(f" {provider}: {len(inv)} checks → {out_path}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|