Merge pull request 'Auto-commit local changes before build (2026-01-12 09:09:48)' (#85) from v20260109-11-ntfs-auditing-audit-parser into main

Reviewed-on: #85
This commit is contained in:
Ivo Oskamp 2026-01-13 11:36:31 +01:00
commit be670c2ae5
5 changed files with 99 additions and 1 deletions

View File

@ -1 +1 @@
v20260109-10-veeam-cloud-connect-report-parser
v20260109-11-ntfs-auditing-audit-parser

View File

@ -13,6 +13,7 @@ from .nakivo import try_parse_nakivo
from .veeam import try_parse_veeam
from .rdrive import try_parse_rdrive
from .syncovery import try_parse_syncovery
from .ntfs_auditing import try_parse_ntfs_auditing
def _sanitize_text(value: object) -> object:
@ -117,6 +118,8 @@ def parse_mail_message(msg: MailMessage) -> None:
handled, result, objects = try_parse_veeam(msg)
if not handled:
handled, result, objects = try_parse_syncovery(msg)
if not handled:
handled, result, objects = try_parse_ntfs_auditing(msg)
except Exception as exc:
msg.parse_result = "error"
msg.parse_error = str(exc)[:500]

View File

@ -0,0 +1,62 @@
from __future__ import annotations
import re
from typing import Dict, Tuple, List
from ..models import MailMessage
def _normalize_subject(subject: str) -> str:
# Some senders use underscores as spaces in the subject.
s = (subject or "").strip()
s = s.replace("_", " ")
s = re.sub(r"\s+", " ", s)
return s.strip()
def try_parse_ntfs_auditing(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
"""Parse NTFS Auditing "Audit" report e-mails.
Example subjects (decoded):
- "Bouter btr-dc002.bouter.nl file audits → 0 ↑ 0"
- "Bouter btr-dc001.bouter.nl file audits → 6 ↑ 12"
Notes:
- These mails do not include per-object rows that should be tracked.
- The job does not provide a meaningful overall status; we store it as Success.
- Missing runs are handled by the existing scheduler/missing logic (no mail received).
"""
subject_raw = (msg.subject or "").strip()
if not subject_raw:
return False, {}, []
# Basic sender sanity check (but keep it tolerant)
from_addr = (msg.from_address or "").lower()
if from_addr and "auditing@" not in from_addr and "file auditing" not in from_addr:
# Not our sender
return False, {}, []
subject = _normalize_subject(subject_raw)
# Find the host part between "Bouter" and "file audits".
m = re.search(r"\bBouter\b\s+(?P<host>[^\s]+)\s+file\s+audits\b", subject, flags=re.IGNORECASE)
if not m:
return False, {}, []
host = m.group("host").strip()
if not host:
return False, {}, []
job_name = f"{host} file audits"
result = {
"backup_software": "NTFS Auditing",
"backup_type": "Audit",
"job_name": job_name,
"overall_status": "Success",
"overall_message": None,
}
# There are no objects in this mail.
return True, result, []

View File

@ -38,6 +38,29 @@ PARSER_DEFINITIONS = [
},
},
},
{
"name": "ntfs_auditing_audit",
"backup_software": "NTFS Auditing",
"backup_types": ["Audit"],
"order": 220,
"enabled": True,
"match": {
"from_contains": "auditing@",
"subject_contains": "file audits",
},
"description": "Parses NTFS Auditing file audit report mails (attachment-based HTML reports).",
"example": {
"subject": "Bouter btr-dc001.bouter.nl file audits → 6 ↑ 12",
"from_address": "auditing@bouter.nl",
"body_snippet": "(empty body, HTML report in attachment)",
"parsed_result": {
"backup_software": "NTFS Auditing",
"backup_type": "Audit",
"job_name": "btr-dc001.bouter.nl file audits",
"objects": [],
},
},
},
{
"name": "veeam_replication_job",
"backup_software": "Veeam",

View File

@ -80,6 +80,16 @@
- Adjusted status detection so red rows are interpreted as Errors and yellow/orange rows as Warnings.
- Ensured the overall status is set to Error when one or more objects are detected as errors.
- Improved parsing logic to correctly classify mixed-status reports within a single mail.
---
## v20260109-11-ntfs-auditing-audit-parser
- Added parser support for “NTFS Auditing” with type “Audit”.
- Implemented job name extraction from the mail subject (e.g. “<hostname> file audits”).
- Handled reports without an overall status by defaulting the result to Success.
- Ensured existing missing-run logic is applied when no audit report mail is received.
- Defined that these audit mails contain no objects; object list remains empty.
================================================================================================================================================
## v0.1.19
This release delivers a broad set of improvements focused on reliability, transparency, and operational control across mail processing, administrative auditing, and Run Checks workflows. The changes aim to make message handling more robust, provide better insight for administrators, and give operators clearer and more flexible control when reviewing backup runs.