nadzoring.dns_lookup.validation module¶
DNS record validation functions.
This module is split into small, single-responsibility validators:
calculate_record_score()— score one record type for a health checkvalidate_mx_records()— validate MX priority uniquenessvalidate_txt_records()— validate SPF / DKIM TXT recordsdetermine_status()— map a numeric score to a status label
Each validator returns a plain dict or primitive; none raise exceptions.
Typical usage via nadzoring.dns_lookup.health:
from nadzoring.dns_lookup.validation import (
validate_mx_records,
validate_txt_records,
determine_status,
)
mx_result = validate_mx_records(["10 mail.example.com", "20 backup.example.com"])
print(mx_result["valid"]) # True
print(mx_result["issues"]) # []
status = determine_status(85) # "healthy"
- nadzoring.dns_lookup.validation._apply_type_specific_checks(rtype: str, record_result: dict[str, Any], score: int, accumulator: dict[str, list[str]]) int[source]¶
Apply record-type-specific scoring rules.
- Parameters:
rtype – DNS record type.
record_result – Dict with record data.
score – Current score before type-specific adjustments.
accumulator – Issues/warnings accumulator updated in-place.
- Returns:
Adjusted score.
- nadzoring.dns_lookup.validation._parse_mx_priority(mx: str) int | None[source]¶
Parse the numeric priority from an MX record string.
- Parameters:
mx – MX record string in
"priority mailserver"format.- Returns:
Integer priority, or
Nonewhen the format is invalid.
- nadzoring.dns_lookup.validation._score_mx(records: list[str], score: int, accumulator: dict[str, list[str]]) int[source]¶
Deduct points for duplicate MX priorities or malformed records.
- nadzoring.dns_lookup.validation._score_txt(records: list[str], score: int, accumulator: dict[str, list[str]]) int[source]¶
Deduct points for SPF / DKIM issues in TXT records.
- nadzoring.dns_lookup.validation._validate_dkim(txt: str) tuple[list[str], list[str]][source]¶
Check a single DKIM record; return (issues, warnings).
- nadzoring.dns_lookup.validation._validate_spf(txt: str) tuple[list[str], list[str]][source]¶
Check a single SPF record; return (issues, warnings).
- nadzoring.dns_lookup.validation.calculate_record_score(rtype: str, record_result: dict[str, Any], accumulator: dict[str, list[str]]) int[source]¶
Calculate a health score for a single DNS record type.
Starts at 100 and deducts points for errors, missing records, or type-specific issues. Side-effects: appends messages to
accumulator["issues"]andaccumulator["warnings"].- Parameters:
rtype – DNS record type (e.g.
"A","MX","TXT").record_result – Dict with optional
"error"and"records"keys (aDNSResult).accumulator – Dict with
"issues"and"warnings"lists that are updated in-place.
- Returns:
Score between 0 and 100.
- nadzoring.dns_lookup.validation.determine_status(score: int) str[source]¶
Map a numeric health score to a status label.
Thresholds:
score >= 80→"healthy"score >= 50→"degraded"score < 50→"unhealthy"
- Parameters:
score – Numeric score in the range 0-100.
- Returns:
Status label string.
Examples
>>> determine_status(85) 'healthy' >>> determine_status(65) 'degraded' >>> determine_status(30) 'unhealthy'
- nadzoring.dns_lookup.validation.validate_mx_records(mx_records: list[str]) dict[str, bool | list[str]][source]¶
Validate MX records for duplicate priority values.
- Parameters:
mx_records – MX record strings in
"priority mailserver"format.- Returns:
Dict with
"valid"(bool),"issues"(list[str]), and"warnings"(list[str]) keys.
Examples
Valid records:
result = validate_mx_records( ["10 mail.example.com", "20 backup.example.com"] ) assert result["valid"] is True assert result["issues"] == []
Duplicate priorities:
result = validate_mx_records( ["10 mail1.example.com", "10 mail2.example.com"] ) assert result["valid"] is False assert "Duplicate priority: 10" in result["issues"]
- nadzoring.dns_lookup.validation.validate_txt_records(txt_records: list[str]) dict[str, bool | list[str]][source]¶
Validate TXT records for SPF and DKIM compliance.
Checks:
SPF — warns when
~allor-allmechanism is absentDKIM — marks invalid when the
p=public-key tag is missing
- Parameters:
txt_records – List of TXT record strings.
- Returns:
Dict with
"valid"(bool),"issues"(list[str]), and"warnings"(list[str]) keys.
Examples
SPF without terminator:
result = validate_txt_records(["v=spf1 include:spf.example.com"]) assert result["valid"] is True # SPF warning only assert result["warnings"] != []
Missing DKIM key:
result = validate_txt_records(["v=DKIM1; k=rsa;"]) assert result["valid"] is False assert result["issues"] != []
All good:
result = validate_txt_records( [ "v=spf1 include:spf.example.com ~all", "v=DKIM1; k=rsa; p=MIIBIjANBg...", ] ) assert result["valid"] is True assert result["issues"] == []