summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleš Mrázek <ales.mrazek@nic.cz>2025-01-06 16:05:27 +0100
committerAleš Mrázek <ales.mrazek@nic.cz>2025-01-14 10:03:29 +0100
commitf7ca899b8858a9a00a76d2f475852037ea479fdc (patch)
treedaf956b68b4f7e915bfbd011c5d5999bee503f7d
parentpython: constants: added optional dependency import check (prometheus and wat... (diff)
downloadknot-resolver-f7ca899b8858a9a00a76d2f475852037ea479fdc.tar.xz
knot-resolver-f7ca899b8858a9a00a76d2f475852037ea479fdc.zip
datamodel: network: tls: added 'files-watchdog' option
-rw-r--r--doc/_static/config.schema.json17
-rw-r--r--python/knot_resolver/datamodel/network_schema.py47
-rw-r--r--tests/manager/datamodel/test_network_schema.py16
3 files changed, 68 insertions, 12 deletions
diff --git a/doc/_static/config.schema.json b/doc/_static/config.schema.json
index 1aa80cf9..9c214885 100644
--- a/doc/_static/config.schema.json
+++ b/doc/_static/config.schema.json
@@ -305,6 +305,21 @@
"description": "TLS configuration, also affects DNS over TLS and DNS over HTTPS.",
"type": "object",
"properties": {
+ "files-watchdog": {
+ "anyOf": [
+ {
+ "type": "string",
+ "enum": [
+ "auto"
+ ]
+ },
+ {
+ "type": "boolean"
+ }
+ ],
+ "description": "Enables files watchdog for TLS certificate files. Requires the optional 'watchdog' dependency.",
+ "default": "auto"
+ },
"cert-file": {
"type": [
"string",
@@ -359,6 +374,7 @@
}
},
"default": {
+ "files_watchdog": true,
"cert_file": null,
"key_file": null,
"sticket_secret": null,
@@ -517,6 +533,7 @@
},
"address_renumbering": null,
"tls": {
+ "files_watchdog": true,
"cert_file": null,
"key_file": null,
"sticket_secret": null,
diff --git a/python/knot_resolver/datamodel/network_schema.py b/python/knot_resolver/datamodel/network_schema.py
index a71c006b..e2753a85 100644
--- a/python/knot_resolver/datamodel/network_schema.py
+++ b/python/knot_resolver/datamodel/network_schema.py
@@ -1,5 +1,6 @@
-from typing import List, Literal, Optional, Union
+from typing import Any, List, Literal, Optional, Union
+from knot_resolver.constants import WATCHDOG_LIB
from knot_resolver.datamodel.types import (
EscapedStr32B,
Int0_512,
@@ -48,18 +49,31 @@ class AddressRenumberingSchema(ConfigSchema):
class TLSSchema(ConfigSchema):
- """
- TLS configuration, also affects DNS over TLS and DNS over HTTPS.
+ class Raw(ConfigSchema):
+ """
+ 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: Experimental automatic discovery of authoritative servers supporting DNS-over-TLS.
- padding: EDNS(0) padding of queries and answers sent over an encrypted channel.
- """
+ ---
+ files_watchdog: Enables files watchdog for TLS certificate files. Requires the optional 'watchdog' dependency.
+ 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: Experimental automatic discovery of authoritative servers supporting DNS-over-TLS.
+ padding: EDNS(0) padding of queries and answers sent over an encrypted channel.
+ """
+ files_watchdog: Union[Literal["auto"], bool] = "auto"
+ cert_file: Optional[ReadableFile] = None
+ key_file: Optional[ReadableFile] = None
+ sticket_secret: Optional[EscapedStr32B] = None
+ sticket_secret_file: Optional[ReadableFile] = None
+ auto_discovery: bool = False
+ padding: Union[bool, Int0_512] = True
+
+ _LAYER = Raw
+
+ files_watchdog: bool
cert_file: Optional[ReadableFile] = None
key_file: Optional[ReadableFile] = None
sticket_secret: Optional[EscapedStr32B] = None
@@ -67,9 +81,20 @@ class TLSSchema(ConfigSchema):
auto_discovery: bool = False
padding: Union[bool, Int0_512] = True
+ def _files_watchdog(self, obj: Raw) -> Any:
+ if obj.files_watchdog == "auto":
+ return WATCHDOG_LIB
+ return obj.files_watchdog
+
def _validate(self):
if self.sticket_secret and self.sticket_secret_file:
raise ValueError("'sticket_secret' and 'sticket_secret_file' are both defined, only one can be used")
+ if bool(self.cert_file) != bool(self.key_file):
+ raise ValueError("'cert-file' and 'key-file' must be configured together")
+ if self.cert_file and self.key_file and self.files_watchdog and not WATCHDOG_LIB:
+ raise ValueError(
+ "'files-watchdog' is enabled, but the required 'watchdog' dependency (optional) is not installed"
+ )
class ListenSchema(ConfigSchema):
diff --git a/tests/manager/datamodel/test_network_schema.py b/tests/manager/datamodel/test_network_schema.py
index aed09310..1451ac20 100644
--- a/tests/manager/datamodel/test_network_schema.py
+++ b/tests/manager/datamodel/test_network_schema.py
@@ -3,7 +3,8 @@ from typing import Any, Dict, Optional
import pytest
from pytest import raises
-from knot_resolver.datamodel.network_schema import ListenSchema, NetworkSchema
+from knot_resolver.constants import WATCHDOG_LIB
+from knot_resolver.datamodel.network_schema import ListenSchema, NetworkSchema, TLSSchema
from knot_resolver.datamodel.types import InterfaceOptionalPort, PortNumber
from knot_resolver.utils.modeling.exceptions import DataValidationError
@@ -77,3 +78,16 @@ def test_listen_valid(listen: Dict[str, Any]):
def test_listen_invalid(listen: Dict[str, Any]):
with raises(DataValidationError):
ListenSchema(listen)
+
+
+@pytest.mark.parametrize(
+ "tls",
+ [
+ {"files-watchdog": "auto"},
+ {"files-watchdog": True},
+ {"files-watchdog": False},
+ ],
+)
+def test_tls_files_watchdog(tls: Dict[str, Any]):
+ expected: bool = WATCHDOG_LIB if tls["files-watchdog"] == "auto" else tls["files-watchdog"]
+ assert TLSSchema(tls).files_watchdog == expected