From: Aleš Date: Thu, 3 Feb 2022 14:48:26 +0000 (+0100) Subject: datamodel: docstrings annotatinons (network, static-hint, view, policy) X-Git-Tag: v6.0.0a1~44^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57baf7a717207a2a52b8d9a1b2a674d95c7f71f0;p=thirdparty%2Fknot-resolver.git datamodel: docstrings annotatinons (network, static-hint, view, policy) - changed name of some schema fields - related to #706 --- diff --git a/manager/knot_resolver_manager/datamodel/network_schema.py b/manager/knot_resolver_manager/datamodel/network_schema.py index 1cadc9cb7..6292cd1c7 100644 --- a/manager/knot_resolver_manager/datamodel/network_schema.py +++ b/manager/knot_resolver_manager/datamodel/network_schema.py @@ -18,16 +18,44 @@ KindEnum = Literal["dns", "xdp", "dot", "doh-legacy", "doh2"] class EdnsBufferSizeSchema(SchemaNode): + """ + EDNS payload size advertised in DNS packets. + + --- + upstream: Maximum EDNS upstream (towards other DNS servers) payload size. + downstream: Maximum EDNS downstream (towards clients) payload size for communication. + """ + upstream: SizeUnit = SizeUnit("1232B") downstream: SizeUnit = SizeUnit("1232B") class AddressRenumberingSchema(SchemaNode): + """ + Renumbers addresses in answers to different address space. + + --- + source: Source subnet. + destination: Destination address prefix. + """ + source: IPNetwork destination: IPAddress class TLSSchema(SchemaNode): + """ + TLS configuration, also affects DNS over TLS and DNS over HTTPS. + + --- + cert_file: Path to certificate file. + key_file: Path to certificate key file. + sticket_secret: Secret for TLS session resumption via tickets. (RFC 5077). + sticket_secret_file: Path to file with secret for TLS session resumption via tickets. (RFC 5077). + auto_discovery: Automatic discovery of authoritative servers supporting DNS-over-TLS. + padding: EDNS(0) padding of answers to queries that arrive over TLS transport. + """ + cert_file: Optional[CheckedPath] = None key_file: Optional[CheckedPath] = None sticket_secret: Optional[str] = None @@ -44,6 +72,17 @@ class TLSSchema(SchemaNode): class ListenSchema(SchemaNode): class Raw(SchemaNode): + """ + Configuration of listening interface. + + --- + unix_socket: Path to unix domain socket to listen to. + interface: IP address or interface name with optional port number to listen to. + port: Port number to listen to. + kind: Specifies DNS query transport protocol. + freebind: Used for binding to non-local address. + """ + interface: Union[None, InterfaceOptionalPort, List[InterfaceOptionalPort]] = None unix_socket: Union[None, CheckedPath, List[CheckedPath]] = None port: Optional[PortNumber] = None @@ -96,12 +135,28 @@ class ListenSchema(SchemaNode): class NetworkSchema(SchemaNode): + """ + Network connections and protocols configuration. + + --- + do_ipv4: Enable/disable using IPv4 for contacting upstream nameservers. + do_ipv6: Enable/disable using IPv6 for contacting upstream nameservers. + out_interface_v4: IPv4 address used to perform queries. Not set by default, which lets the OS choose any address. + out_interface_v6: IPv6 address used to perform queries. Not set by default, which lets the OS choose any address. + tcp_pipeline: TCP pipeline limit. The number of outstanding queries that a single client connection can make in parallel. + edns_tcp_keepalive: Allows clients to discover the connection timeout. (RFC 7828) + edns_buffer_size: Maximum EDNS payload size advertised in DNS packets. Different values can be configured for communication downstream (towards clients) and upstream (towards other DNS servers). + address_renumbering: Renumbers addresses in answers to different address space. + tls: TLS configuration, also affects DNS over TLS and DNS over HTTPS. + listen: List of interfaces to listen to and its configuration. + """ + do_ipv4: bool = True do_ipv6: bool = True out_interface_v4: Optional[IPv4Address] = None out_interface_v6: Optional[IPv6Address] = None tcp_pipeline: int = 100 - edns_keep_alive: bool = True + edns_tcp_keepalive: bool = True edns_buffer_size: EdnsBufferSizeSchema = EdnsBufferSizeSchema() address_renumbering: Optional[List[AddressRenumberingSchema]] = None tls: TLSSchema = TLSSchema() diff --git a/manager/knot_resolver_manager/datamodel/policy_schema.py b/manager/knot_resolver_manager/datamodel/policy_schema.py index ce415c92b..491629020 100644 --- a/manager/knot_resolver_manager/datamodel/policy_schema.py +++ b/manager/knot_resolver_manager/datamodel/policy_schema.py @@ -12,21 +12,55 @@ from knot_resolver_manager.utils import SchemaNode class FilterSchema(SchemaNode): + """ + Query filtering configuration. + + --- + suffix: Filter based on the suffix of the query name. + pattern: Filter based on the pattern that match query name. + qtype: Filter based on the DNS query type. + """ + suffix: Optional[str] = None pattern: Optional[str] = None qtype: Optional[DNSRecordTypeEnum] = None class AnswerSchema(SchemaNode): - qtype: DNSRecordTypeEnum + """ + Configuration of custom resource record for DNS answer. + + --- + rtype: Type of DNS resource record. + rdata: Data of DNS resource record. + ttl: Time-to-live value for defined answer. + nodata: Answer with NODATA If requested type is not configured in the answer. Otherwise policy rule is ignored. + """ + + rtype: DNSRecordTypeEnum rdata: str ttl: TimeUnit = TimeUnit("1s") nodata: bool = False class PolicySchema(SchemaNode): + """ + Configuration of policy rule. + + --- + action: Policy rule action. + priority: Policy rule priority. + filter: Query filtering configuration. + views: Use policy rule only for clients defined by views. + options: Configuration flags for policy rule. + message: Deny message for 'deny' action. + reroute: Configuration for 'reroute' action. + answer: Answer definition for 'answer' action. + mirror: Mirroring parameters for 'mirror' action. + """ + action: PolicyActionEnum - order: Optional[int] = None + priority: Optional[int] = None filter: Optional[FilterSchema] = None views: Optional[List[str]] = None options: Optional[List[PolicyFlagEnum]] = None diff --git a/manager/knot_resolver_manager/datamodel/static_hints_schema.py b/manager/knot_resolver_manager/datamodel/static_hints_schema.py index 0d9c010a9..9529fde0a 100644 --- a/manager/knot_resolver_manager/datamodel/static_hints_schema.py +++ b/manager/knot_resolver_manager/datamodel/static_hints_schema.py @@ -5,10 +5,23 @@ from knot_resolver_manager.utils import SchemaNode class StaticHintsSchema(SchemaNode): + """ + Static hints for forward records (A/AAAA) and reverse records (PTR) + + --- + ttl: TTL value used for records added from static hints. + nodata: Use NODATA synthesis. NODATA will be synthesised for matching hint name, but mismatching type. + etc_hosts: Add hints from '/etc/hosts' file. + root_hints: Direct addition of root hints pairs (hostname, list of addresses). + root_hints_file: Path to root hints in zonefile. Replaces all current root hints. + hints: Direct addition of hints pairs (hostname, list of addresses). + hints_files: Path to hints in hosts-like file. + """ + ttl: Optional[TimeUnit] = None - no_data: bool = True + nodata: bool = True etc_hosts: bool = False - root_hints_file: Optional[CheckedPath] = None - hints_files: Optional[List[CheckedPath]] = None root_hints: Optional[Dict[DomainName, List[IPAddress]]] = None + root_hints_file: Optional[CheckedPath] = None hints: Optional[Dict[DomainName, List[IPAddress]]] = None + hints_files: Optional[List[CheckedPath]] = None diff --git a/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 index 1b2d22be1..bf8090ae5 100644 --- a/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 +++ b/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 @@ -136,10 +136,10 @@ policy.REROUTE( {%- endmacro %} {% macro policy_answer(answer) -%} -policy.ANSWER({[kres.type.{{ answer.qtype }}]={rdata= -{%- if answer.qtype in ['A','AAAA'] -%} +policy.ANSWER({[kres.type.{{ answer.rtype }}]={rdata= +{%- if answer.rtype in ['A','AAAA'] -%} {{ str2ip_table(answer.rdata) }}, -{%- elif answer.qtype == '' -%} +{%- elif answer.rtype == '' -%} {# TODO: Do the same for other record types that require a special rdata type in Lua. By default, the raw string from config is used. #} {%- else -%} diff --git a/manager/knot_resolver_manager/datamodel/templates/network.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/network.lua.j2 index 6d7795a19..1ab6b2814 100644 --- a/manager/knot_resolver_manager/datamodel/templates/network.lua.j2 +++ b/manager/knot_resolver_manager/datamodel/templates/network.lua.j2 @@ -18,7 +18,7 @@ net.outgoing_v6('{{ cfg.network.out_interface_v6 }}') net.tcp_pipeline({{ cfg.network.tcp_pipeline }}) -- network.edns-keep-alive -{% if cfg.network.edns_keep_alive %} +{% if cfg.network.edns_tcp_keepalive %} modules.load('edns_keepalive') {% else %} modules.unload('edns_keepalive') @@ -53,7 +53,15 @@ modules.load('experimental_dot_auth') {% endif %} -- network.tls.padding -net.tls_padding({{ cfg.network.tls.padding }}) +net.tls_padding( +{%- if cfg.network.tls.padding == true -%} +true +{%- elif cfg.network.tls.padding == false -%} +false +{%- else -%} +{{ cfg.network.tls.padding }} +{%- endif -%} +) {% if cfg.network.address_renumbering %} -- network.address-renumbering diff --git a/manager/knot_resolver_manager/datamodel/templates/static_hints.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/static_hints.lua.j2 index eebdac993..d3d1c61eb 100644 --- a/manager/knot_resolver_manager/datamodel/templates/static_hints.lua.j2 +++ b/manager/knot_resolver_manager/datamodel/templates/static_hints.lua.j2 @@ -7,7 +7,7 @@ hints.ttl({{ cfg.static_hints.ttl.seconds()|string }}) {% endif %} -- static-hints.no-data -hints.use_nodata({{ 'true' if cfg.static_hints.no_data else 'false' }}) +hints.use_nodata({{ 'true' if cfg.static_hints.nodata else 'false' }}) {% if cfg.static_hints.etc_hosts %} -- static-hints.etc-hosts diff --git a/manager/knot_resolver_manager/datamodel/view_schema.py b/manager/knot_resolver_manager/datamodel/view_schema.py index 65e757f09..c6027535d 100644 --- a/manager/knot_resolver_manager/datamodel/view_schema.py +++ b/manager/knot_resolver_manager/datamodel/view_schema.py @@ -6,12 +6,12 @@ from knot_resolver_manager.utils import SchemaNode class ViewSchema(SchemaNode): """ - Configuration parameters that allows you to create personalized policy rules and other. + Configuration parameters that allow you to create personalized policy rules and other. --- - subnets: Identifies clients based on subnets. - tsig: Identifies clients based on a TSIG key name. This is only for testing purposes, TSIG signature is not verified! - options: List of flags for clients specified in view. + subnets: Identifies the client based on his subnet. + tsig: Identifies the client based on a TSIG key name (for testing purposes, TSIG signature is not verified!). + options: Configuration flags for clients identified by the view. """ subnets: Optional[List[IPNetwork]] = None diff --git a/manager/tests/unit/datamodel/templates/test_policy_macros.py b/manager/tests/unit/datamodel/templates/test_policy_macros.py index 129055a8b..28f8d5aa6 100644 --- a/manager/tests/unit/datamodel/templates/test_policy_macros.py +++ b/manager/tests/unit/datamodel/templates/test_policy_macros.py @@ -113,12 +113,12 @@ def test_policy_reroute(): def test_policy_answer(): - ans = AnswerSchema({"qtype": "AAAA", "rdata": "192.0.2.7"}) + ans = AnswerSchema({"rtype": "AAAA", "rdata": "192.0.2.7"}) tmpl_str = """{% from 'macros/policy_macros.lua.j2' import policy_answer %} {{ policy_answer(ans) }}""" tmpl = template_from_str(tmpl_str) assert ( tmpl.render(ans=ans) - == f"policy.ANSWER({{[kres.type.{ans.qtype}]={{rdata=kres.str2ip('{ans.rdata}'),ttl={ans.ttl.seconds()}}}}},{str(ans.nodata).lower()})" + == f"policy.ANSWER({{[kres.type.{ans.rtype}]={{rdata=kres.str2ip('{ans.rdata}'),ttl={ans.ttl.seconds()}}}}},{str(ans.nodata).lower()})" ) diff --git a/manager/tests/unit/datamodel/test_policy_schema.py b/manager/tests/unit/datamodel/test_policy_schema.py index 4fce14dd0..192c561e9 100644 --- a/manager/tests/unit/datamodel/test_policy_schema.py +++ b/manager/tests/unit/datamodel/test_policy_schema.py @@ -36,12 +36,12 @@ def test_reroute(): def test_answer(): - assert PolicySchema({"action": "answer", "answer": {"qtype": "AAAA", "rdata": "::1"}}) + assert PolicySchema({"action": "answer", "answer": {"rtype": "AAAA", "rdata": "::1"}}) with raises(KresManagerException): PolicySchema({"action": "answer"}) with raises(KresManagerException): - PolicySchema({"action": "pass", "answer": {"qtype": "AAAA", "rdata": "::1"}}) + PolicySchema({"action": "pass", "answer": {"rtype": "AAAA", "rdata": "::1"}}) def test_mirror():