1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
from typing import Dict, List, Literal, Optional
from knot_resolver.datamodel.types import (
DomainName,
EscapedStr,
IDPattern,
IPAddress,
ListOrItem,
ReadableFile,
TimeUnit,
)
from knot_resolver.utils.modeling import ConfigSchema
class RuleSchema(ConfigSchema):
"""
Local data advanced rule configuration.
---
name: Hostname(s).
subtree: Type of subtree.
address: Address(es) to pair with hostname(s).
file: Path to file(s) with hostname and IP address(es) pairs in '/etc/hosts' like format.
records: Direct addition of records in DNS zone file format.
tags: Tags to link with other policy rules.
ttl: Optional, TTL value used for these answers.
nodata: Optional, use NODATA synthesis. NODATA will be synthesised for matching name, but mismatching type(e.g. AAAA query when only A exists).
"""
name: Optional[ListOrItem[DomainName]] = None
subtree: Optional[Literal["empty", "nxdomain", "redirect"]] = None
address: Optional[ListOrItem[IPAddress]] = None
file: Optional[ListOrItem[ReadableFile]] = None
records: Optional[EscapedStr] = None
tags: Optional[List[IDPattern]] = None
ttl: Optional[TimeUnit] = None
nodata: Optional[bool] = None
def _validate(self) -> None:
options_sum = sum([bool(self.address), bool(self.subtree), bool(self.file), bool(self.records)])
if options_sum == 2 and bool(self.address) and self.subtree in {"empty", "redirect"}:
pass # these combinations still make sense
elif options_sum > 1:
raise ValueError("only one of 'address', 'subtree' or 'file' can be configured")
elif options_sum < 1:
raise ValueError("one of 'address', 'subtree', 'file' or 'records' must be configured")
options_sum2 = sum([bool(self.name), bool(self.file), bool(self.records)])
if options_sum2 != 1:
raise ValueError("one of 'name', 'file or 'records' must be configured")
if bool(self.nodata) and bool(self.subtree) and not bool(self.address):
raise ValueError("'nodata' defined but unused with 'subtree'")
class RPZSchema(ConfigSchema):
"""
Configuration or Response Policy Zone (RPZ).
---
file: Path to the RPZ zone file.
tags: Tags to link with other policy rules.
"""
file: ReadableFile
tags: Optional[List[IDPattern]] = None
class LocalDataSchema(ConfigSchema):
"""
Local data for forward records (A/AAAA) and reverse records (PTR).
---
ttl: Default TTL value used for added local data/records.
nodata: Use NODATA synthesis. NODATA will be synthesised for matching name, but mismatching type(e.g. AAAA query when only A exists).
root_fallback_addresses: Direct replace of root hints.
root_fallback_addresses_files: Direct replace of root hints from a zonefile.
addresses: Direct addition of hostname and IP addresses pairs.
addresses_files: Direct addition of hostname and IP addresses pairs from files in '/etc/hosts' like format.
records: Direct addition of records in DNS zone file format.
rules: Local data rules.
rpz: List of Response Policy Zones and its configuration.
"""
ttl: Optional[TimeUnit] = None
nodata: bool = True
root_fallback_addresses: Optional[Dict[DomainName, ListOrItem[IPAddress]]] = None
root_fallback_addresses_files: Optional[List[ReadableFile]] = None
addresses: Optional[Dict[DomainName, ListOrItem[IPAddress]]] = None
addresses_files: Optional[List[ReadableFile]] = None
records: Optional[EscapedStr] = None
rules: Optional[List[RuleSchema]] = None
rpz: Optional[List[RPZSchema]] = None
|