Compare commits

...

2 Commits

3 changed files with 66 additions and 31 deletions

View File

@ -1 +1 @@
v20260112-02-synology-abb-subject-partial-warning
v20260112-03-ntfs-audit-recognize-bouter-hosts

View File

@ -6,6 +6,20 @@ from typing import Dict, Tuple, List
from ..models import MailMessage
_HOSTNAME_RE = re.compile(r"""(?ix)
\b
(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+
(?:[a-z]{2,}|local)
\b
""")
_COUNTS_RE = re.compile(r"""(?x)
[\u2193\u2191] # ↓ or ↑
\s*
(\d+)
""")
def _normalize_subject(subject: str) -> str:
# Some senders use underscores as spaces in the subject.
s = (subject or "").strip()
@ -14,49 +28,62 @@ def _normalize_subject(subject: str) -> str:
return s.strip()
def _extract_host(subject: str) -> str | None:
subj = _normalize_subject(subject)
lower = subj.lower()
idx = lower.find("file audits")
if idx == -1:
return None
prefix = subj[:idx].strip()
# Some senders add a company prefix in front of the hostname, e.g. "Bouter btr-dc001.bouter.nl ...".
# Extract the last hostname-looking token before "file audits".
hosts = _HOSTNAME_RE.findall(prefix)
if not hosts:
return None
return hosts[-1].lower()
def _extract_counts(subject: str) -> Tuple[int, int]:
# Subject format: "<host> file audits ↓ 0 ↑ 29"
# Not all senders include both arrows, so we parse what we can.
subj = _normalize_subject(subject)
nums = [int(x) for x in _COUNTS_RE.findall(subj)]
down = nums[0] if len(nums) >= 1 else 0
up = nums[1] if len(nums) >= 2 else 0
return down, up
def try_parse_ntfs_auditing(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
"""Parse NTFS Auditing "Audit" report e-mails.
subject = getattr(msg, "subject", None) or ""
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:
# Fast checks: this parser is subject-based.
if "file audits" not in _normalize_subject(subject).lower():
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 hostname/FQDN at the start of the subject (before "file audits").
m = re.search(r"^(?P<host>[^\s]+)\s+file\s+audits\b", subject, flags=re.IGNORECASE)
if not m:
return False, {}, []
host = m.group("host").strip()
host = _extract_host(subject)
if not host:
return False, {}, []
down, up = _extract_counts(subject)
# If changes were detected, mark as Warning (auditing reports only changes).
overall_status = "Warning" if (down > 0 or up > 0) else "Success"
overall_message = None
if overall_status == "Warning":
overall_message = f"NTFS auditing detected file changes (deleted: {down}, changed: {up})."
job_name = f"{host} file audits"
result = {
"backup_software": "NTFS Auditing",
"backup_type": "Audit",
"job_name": job_name,
"overall_status": "Success",
"overall_message": None,
"overall_status": overall_status,
"overall_message": overall_message,
}
# There are no objects in this mail.
# This mail contains an attachment report; objects are not tracked.
return True, result, []

View File

@ -125,6 +125,14 @@
- Added subject-based detection for “partially completed / gedeeltelijk voltooid” and map this to Overall status: Warning.
- Fixed the ABB completion regex (it previously failed to match valid subjects).
- Improved per-device object parsing by detecting “backup succeeded/failed” device-list variants and mapping them to Success/Error accordingly.
---
## v20260112-03-ntfs-audit-recognize-bouter-hosts
- Improved NTFS Auditing (Audit) subject parsing to extract the hostname reliably, including subjects with a leading company prefix (e.g. "Bouter ...") and underscores-as-spaces variants.
- Set overall status to Warning when the subject indicates any detected changes (↑/↓ counts > 0); otherwise Success.
- Ensured job name is consistently generated as "<hostname> file audits" for all supported senders.
================================================================================================================================================
## 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.