transport: tls
hostname: odvr.nic.cz
- address: [ 192.0.2.1, 192.0.2.2 ]
- pin-sha256: ['YQ==', 'Wg==']
+ pin-sha256:
+ - YmE3ODE2YmY4ZjAx+2ZlYTQxNDE0MGRlNWRhZTIyMjNiMDAzNjFhMzk/MTc3YTljYjQxMGZmNjFmMjAwMTVhZA==
+ - OTJmODU3ZDMyOWMwOWNlNTU4Y2M0YWNjMjI5NWE2NWJlMzY4MzRmMzY3NGU3NDAwNTI1YjMxZTMxYTgzMzQwMQ==
- subtree: 1.168.192.in-addr.arpa
options:
dnssec: false
from typing_extensions import Literal
-from knot_resolver_manager.datamodel.types import DomainName, File, IPAddressOptionalPort, ListOrItem
+from knot_resolver_manager.datamodel.types import DomainName, File, IPAddressOptionalPort, ListOrItem, PinSha256
from knot_resolver_manager.utils.modeling import ConfigSchema
address: ListOrItem[IPAddressOptionalPort]
transport: Optional[Literal["tls"]] = None
- pin_sha256: Optional[ListOrItem[str]] = None
+ pin_sha256: Optional[ListOrItem[PinSha256]] = None
hostname: Optional[DomainName] = None
ca_file: Optional[File] = None
IPv6Network,
IPv6Network96,
Percent,
+ PinSha256,
PortNumber,
SizeUnit,
TimeUnit,
"IPv6Network96",
"ListOrItem",
"Percent",
+ "PinSha256",
"PortNumber",
"SizeUnit",
"TimeUnit",
_re = re.compile(r"^(?!-)[a-z0-9-]*[a-z0-9]+$")
+class PinSha256(PatternBase):
+ """
+ A string that stores base64 encoded sha256.
+ """
+
+ _re = re.compile(r"^[A-Za-z\d+/]{86}==$")
+
+
class InterfacePort(StrBase):
addr: Union[None, ipaddress.IPv4Address, ipaddress.IPv6Address] = None
if_name: Optional[InterfaceName] = None
# the ca-file is a dummy, because it's existence is checked
{"address": ["2001:DB8::d0c"], "hostname": "res.example.com", "ca-file": "/etc/passwd"}
)
- t = [d, ForwardServerSchema({"address": ["192.0.2.1"], "pin-sha256": "YQ=="})]
+ t = [
+ d,
+ ForwardServerSchema(
+ {
+ "address": "192.0.2.1",
+ "pin-sha256": "OTJmODU3ZDMyOWMwOWNlNTU4Y2M0YWNjMjI5NWE2NWJlMzY4MzRmMzY3NGU3NDAwNTI1YjMxZTMxYTgzMzQwMQ==",
+ }
+ ),
+ ]
tmpl_str = """{% from 'macros/common_macros.lua.j2' import tls_servers_table %}
{{ tls_servers_table(x) }}"""
IPv4Address,
IPv6Address,
IPv6Network96,
+ PinSha256,
PortNumber,
SizeUnit,
TimeUnit,
assert str(TestSchema({"p": "/tmp"}).p) == "/tmp"
+@pytest.mark.parametrize(
+ "val",
+ [
+ "YmE3ODE2YmY4ZjAx+2ZlYTQxNDE0MGRlNWRhZTIyMjNiMDAzNjFhMzk/MTc3YTljYjQxMGZmNjFmMjAwMTVhZA==",
+ "OTJmODU3ZDMyOWMwOWNlNTU4Y2M0YWNjMjI5NWE2NWJlMzY4MzRmMzY3NGU3NDAwNTI1YjMxZTMxYTgzMzQwMQ==",
+ ],
+)
+def test_pin_sha256_valid(val: str):
+ o = PinSha256(val)
+ assert str(o) == val
+
+
+@pytest.mark.parametrize(
+ "val",
+ [
+ "!YmE3ODE2YmY4ZjAxY2ZlYTQxNDE0MGRlNWRhZTIyMjNiMDAzNjFhMzk2MTc3YTljjQxMGZmNjFmMjAwMTVhZA==",
+ "OTJmODU3ZDMyOWMwOWNlNTU4Y2M0YWNjMjI5NWE2NWJlMzY4MzRmMzY3NGU3NDAwNTI1YjMxZTMxYTgzMzQwMQ",
+ "YmFzZTY0IQ",
+ ],
+)
+def test_pin_sha256_invalid(val: str):
+ with raises(ValueError):
+ PinSha256(val)
+
+
@pytest.mark.parametrize(
"val",
[