blancco: CMMC evidence pack, ServiceNow tick list, cloud-upload status

Automates the Blancco parts of the onsite-support CMMC playbook:

- ENT-056/158 evidence pack: /reports/evidence?month=YYYY-MM returns
  ENT-056_<Site>_<YYYY-MM>.zip (summary.csv, README, each report's XML
  and PDF). pxe-blancco-evidence.timer saves last month's pack to the
  reports share's evidence/ folder on the 1st (Persistent).
- ENT-045/159 ServiceNow tick list: /reports/servicenow lists recent
  reports as "Wiped" or "Blancco Wipe failed" with a pre-written
  destruction note, copy buttons and Done (CSRF-protected).
- Cloud upload: blancco-progress.py posts each report's upload result
  ("Sending report document id" -> "Report sent to MC") to
  /reports/cloud-status (CSRF-exempt like /imaging/status); the Reports
  page and the CSVs show it, so a wipe missing from BMP is visible.
- CSV gains failure_reason (exception messages, failed steps, error
  counts), business_location and cloud_upload.
- Preferences: business_location "West Jefferson" (config.BLANCCO_SITE)
  and pdf+xml reports; the report copier now copies the PDF too, named
  after its XML. .part and hidden files are not listed as reports.

State (cloud confirmations, ServiceNow ticks) is a JSON file at
/var/lib/pxe-webapp/blancco-state.json, off the report share.
This commit is contained in:
cproudlock
2026-10-05 13:43:16 -04:00
parent eff956ae6c
commit 44a7eeae95
12 changed files with 590 additions and 26 deletions

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env python3
"""Save the monthly Blancco CMMC evidence pack to the report share.
Run by pxe-blancco-evidence.timer on the 1st of each month: writes
<BLANCCO_REPORTS>/evidence/ENT-056_<Site>_<YYYY-MM>.zip for the previous
month (or --month YYYY-MM), so the tech only has to copy it into the
site's Box evidence folder. Same pack as the webapp's /reports/evidence.
"""
import argparse
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import config # noqa: E402
from services import blancco_evidence # noqa: E402
def main():
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
ap.add_argument("--month", default=blancco_evidence.previous_month(),
help="YYYY-MM, default: previous month")
args = ap.parse_args()
blancco_evidence.month_bounds(args.month) # validates the format
out_dir = os.path.join(config.BLANCCO_REPORTS, "evidence")
os.makedirs(out_dir, exist_ok=True)
final = os.path.join(out_dir, blancco_evidence.evidence_name(args.month) + ".zip")
tmp = final + ".part"
with open(tmp, "wb") as f:
count = blancco_evidence.build_evidence_zip(args.month, f)
os.replace(tmp, final)
print(f"{final}: {count} report(s)")
if __name__ == "__main__":
main()