From: Aleš Mrázek Date: Wed, 28 Jun 2023 13:35:38 +0000 (+0200) Subject: manager: datamodel: missing options for dns64 X-Git-Tag: v6.0.2~39^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0dff69c54a48a4a38a016b135fa2359ce43582cc;p=thirdparty%2Fknot-resolver.git manager: datamodel: missing options for dns64 --- diff --git a/manager/knot_resolver_manager/datamodel/dns64_schema.py b/manager/knot_resolver_manager/datamodel/dns64_schema.py index 55d3200a2..60b92f2b9 100644 --- a/manager/knot_resolver_manager/datamodel/dns64_schema.py +++ b/manager/knot_resolver_manager/datamodel/dns64_schema.py @@ -1,4 +1,6 @@ -from knot_resolver_manager.datamodel.types import IPv6Network96 +from typing import List, Optional + +from knot_resolver_manager.datamodel.types import IPv6Network, IPv6Network96, TimeUnit from knot_resolver_manager.utils.modeling import ConfigSchema @@ -8,6 +10,10 @@ class Dns64Schema(ConfigSchema): --- prefix: IPv6 prefix to be used for synthesizing AAAA records. + rev_ttl: TTL in CNAME generated in the reverse 'ip6.arpa.' subtree. + exclude_subnets: IPv6 subnets that are disallowed in answer. """ prefix: IPv6Network96 = IPv6Network96("64:ff9b::/96") + rev_ttl: Optional[TimeUnit] = None + exclude_subnets: Optional[List[IPv6Network]] = None diff --git a/manager/knot_resolver_manager/datamodel/templates/dns64.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/dns64.lua.j2 index d4fdf28fc..c5239f00e 100644 --- a/manager/knot_resolver_manager/datamodel/templates/dns64.lua.j2 +++ b/manager/knot_resolver_manager/datamodel/templates/dns64.lua.j2 @@ -1,7 +1,17 @@ +{% from 'macros/common_macros.lua.j2' import string_table %} + {% if cfg.dns64 %} -- load dns64 module modules.load('dns64') -- dns64.prefix -dns64.config('{{ cfg.dns64.prefix.to_std().network_address|string }}') +dns64.config({ + prefix = '{{ cfg.dns64.prefix.to_std().network_address|string }}', +{% if cfg.dns64.rev_ttl %} + rev_ttl = {{ cfg.dns64.rev_ttl.seconds() }}, +{% endif %} +{% if cfg.dns64.exclude_subnets %} + exclude_subnets = {{ string_table(cfg.dns64.exclude_subnets) }}, +{% endif %} +}) {% endif %} \ No newline at end of file diff --git a/manager/knot_resolver_manager/datamodel/types/__init__.py b/manager/knot_resolver_manager/datamodel/types/__init__.py index 33d8c90d4..7f06951a0 100644 --- a/manager/knot_resolver_manager/datamodel/types/__init__.py +++ b/manager/knot_resolver_manager/datamodel/types/__init__.py @@ -17,6 +17,7 @@ from .types import ( IPNetwork, IPv4Address, IPv6Address, + IPv6Network, IPv6Network96, Percent, PortNumber, @@ -43,6 +44,7 @@ __all__ = [ "IPNetwork", "IPv4Address", "IPv6Address", + "IPv6Network", "IPv6Network96", "ListOrItem", "Percent", diff --git a/manager/knot_resolver_manager/datamodel/types/types.py b/manager/knot_resolver_manager/datamodel/types/types.py index f38759c82..dacac8da8 100644 --- a/manager/knot_resolver_manager/datamodel/types/types.py +++ b/manager/knot_resolver_manager/datamodel/types/types.py @@ -362,35 +362,25 @@ class IPNetwork(BaseValueType): } -class IPv6Network96(BaseValueType): +class IPv6Network(BaseValueType): _value: ipaddress.IPv6Network def __init__(self, source_value: Any, object_path: str = "/") -> None: - super().__init__(source_value, object_path=object_path) + super().__init__(source_value) if isinstance(source_value, str): try: self._value: ipaddress.IPv6Network = ipaddress.IPv6Network(source_value) except ValueError as e: - raise ValueError("failed to parse IPv6 /96 network.") from e - - if self._value.prefixlen == 128: - raise ValueError( - "Expected IPv6 network address with /96 prefix length." - " Submitted address has been interpreted as /128." - " Maybe, you forgot to add /96 after the base address?" - ) - - if self._value.prefixlen != 96: - raise ValueError( - "expected IPv6 network address with /96 prefix length." - f" Got prefix lenght of {self._value.prefixlen}" - ) + raise ValueError("failed to parse IPv6 network.") from e else: raise ValueError( - "Unexpected value for a network subnet." + "Unexpected value for a IPv6 network subnet." f" Expected string, got '{source_value}' with type '{type(source_value)}'" ) + def to_std(self) -> ipaddress.IPv6Network: + return self._value + def __str__(self) -> str: return self._value.with_prefixlen @@ -398,14 +388,29 @@ class IPv6Network96(BaseValueType): raise ValueError("Can't convert network prefix to an integer") def __eq__(self, o: object) -> bool: - return isinstance(o, IPv6Network96) and o._value == self._value + return isinstance(o, IPv6Network) and o._value == self._value def serialize(self) -> Any: return self._value.with_prefixlen - def to_std(self) -> ipaddress.IPv6Network: - return self._value - @classmethod - def json_schema(cls: Type["IPv6Network96"]) -> Dict[Any, Any]: - return {"type": "string"} + def json_schema(cls: Type["IPv6Network"]) -> Dict[Any, Any]: + return { + "type": "string", + } + + +class IPv6Network96(IPv6Network): + def __init__(self, source_value: Any, object_path: str = "/") -> None: + super().__init__(source_value, object_path=object_path) + if self._value.prefixlen == 128: + raise ValueError( + "Expected IPv6 network address with /96 prefix length." + " Submitted address has been interpreted as /128." + " Maybe, you forgot to add /96 after the base address?" + ) + + if self._value.prefixlen != 96: + raise ValueError( + "expected IPv6 network address with /96 prefix length." f" Got prefix lenght of {self._value.prefixlen}" + )