diff --git a/2026_Nessus_Remediation_Tracker.xlsx b/2026_Nessus_Remediation_Tracker.xlsx new file mode 100644 index 0000000..651ed78 Binary files /dev/null and b/2026_Nessus_Remediation_Tracker.xlsx differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 527b0c4..219d76d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog ## 2026-02-26 +- Added `scripts/build_2026_tracker_workbook.py` to build `2026_Nessus_Remediation_Tracker.xlsx` with: + - `Intro` sheet copied from `OLD_Tracker.xlsx` + - current generated `Remediations` and `Template` sheets + - month sheets (`January`..`December`) cloned from `Template` + - exclusion of `CVETracker`, `testing`, and historical month CVE data +- Updated 2026 workbook generation to preserve `Intro` in-place from `OLD_Tracker.xlsx` (including original sheet outline/formatting fidelity). +- Set freeze panes to `A2` on `Template` and all month sheets in `2026_Nessus_Remediation_Tracker.xlsx`. - Added `WIKI.md` quick usage guide with setup, workbook workflow, key formats, validation, and push/mirror steps. - Simplified `Remediations` status options to `exception`, `exception - permanent`, in-progress variants, and `resolved`. - Added `Excepted until (date)` to `Remediations` and `Template`, with overdue-date highlighting (red) when the date has passed. diff --git a/README.md b/README.md index 7f7bb0d..d1f3292 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,14 @@ python3 scripts/build_tracker_workbook.py Output file: `nessus_remediation_tracker.xlsx` +## Generate 2026 tracker workbook + +```bash +python3 scripts/build_2026_tracker_workbook.py +``` + +Output file: `2026_Nessus_Remediation_Tracker.xlsx` + ## Validate workbook output ```bash diff --git a/scripts/build_2026_tracker_workbook.py b/scripts/build_2026_tracker_workbook.py new file mode 100644 index 0000000..efa23ce --- /dev/null +++ b/scripts/build_2026_tracker_workbook.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +"""Build the 2026 Nessus remediation tracker workbook.""" + +from __future__ import annotations + +from pathlib import Path + +from openpyxl import load_workbook + +from build_tracker_workbook import MAX_TEMPLATE_ROWS +from build_tracker_workbook import build_remediations_sheet +from build_tracker_workbook import build_template_sheet + +OLD_TRACKER_FILE = Path("OLD_Tracker.xlsx") +OUTPUT_FILE = Path("2026_Nessus_Remediation_Tracker.xlsx") +MONTH_SHEETS = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", +] + + +def main() -> None: + if not OLD_TRACKER_FILE.exists(): + raise FileNotFoundError(f"Missing required input file: {OLD_TRACKER_FILE}") + + wb = load_workbook(OLD_TRACKER_FILE) + if "Intro" not in wb.sheetnames: + raise ValueError(f"Sheet 'Intro' not found in {OLD_TRACKER_FILE}") + + for sheet_name in list(wb.sheetnames): + if sheet_name != "Intro": + wb.remove(wb[sheet_name]) + + scratch = wb.create_sheet("Scratch") + wb.active = wb.index(scratch) + build_remediations_sheet(wb) + build_template_sheet(wb, MAX_TEMPLATE_ROWS) + + template_ws = wb["Template"] + template_ws.freeze_panes = "A2" + for month in MONTH_SHEETS: + month_ws = wb.copy_worksheet(template_ws) + month_ws.title = month + month_ws.freeze_panes = "A2" + + ordered_sheets = ["Intro", "Remediations", "Template", *MONTH_SHEETS] + wb._sheets = [wb[name] for name in ordered_sheets] + + temp_output = OUTPUT_FILE.with_suffix(".tmp.xlsx") + wb.save(temp_output) + temp_output.replace(OUTPUT_FILE) + print(f"Wrote {OUTPUT_FILE}") + + +if __name__ == "__main__": + main()