-id: dev
cache:
storage: ../cache
logging:
listen:
- interface: 127.0.0.1@5353
server:
+ id: dev
workers: 1
rundir: etc/knot-resolver/runtime
management:
@property
def ID(self) -> str:
- return self._config_store.get().id
+ return str(self._config_store.get().server.id)
_user_constants: Optional[_UserConstants] = None
async def _deny_id_changes(config_old: KresConfig, config_new: KresConfig) -> Result[None, str]:
- if config_old.id != config_new.id:
+ if config_old.server.id != config_new.server.id:
return Result.err(
- "/id: Based on the groupid, the manager recognizes subprocesses,"
+ "/id: Based on the ID, the manager recognizes subprocesses,"
" so it is not possible to change it while services are running."
)
return Result.ok(None)
import os
-import re
import sys
from typing import Dict, Optional, Union
from knot_resolver_manager.datamodel.static_hints_schema import StaticHintsSchema
from knot_resolver_manager.datamodel.stub_zone_schema import StubZoneSchema
from knot_resolver_manager.datamodel.types import DomainName
-from knot_resolver_manager.datamodel.types.base_types import PatternBase
from knot_resolver_manager.datamodel.view_schema import ViewSchema
from knot_resolver_manager.utils import SchemaNode
_MAIN_TEMPLATE = _import_lua_template()
-class IDPattern(PatternBase):
- _re = re.compile(r"[a-zA-Z0-9]*")
-
-
class KresConfig(SchemaNode):
class Raw(SchemaNode):
"""
Knot Resolver declarative configuration.
---
- id: System-wide unique identifier of this manager instance. Used for grouping logs and tagging kresd processes.
server: DNS server control and management configuration.
options: Fine-tuning global parameters of DNS resolver operation.
network: Network connections and protocols configuration.
lua: Custom Lua configuration.
"""
- id: IDPattern
- server: ServerSchema = ServerSchema()
+ server: ServerSchema
options: OptionsSchema = OptionsSchema()
network: NetworkSchema = NetworkSchema()
static_hints: StaticHintsSchema = StaticHintsSchema()
_PREVIOUS_SCHEMA = Raw
- id: str
server: ServerSchema
options: OptionsSchema
network: NetworkSchema
Funtion used just for testing purposes. Creates an instance of KresConfig without requiring
any arguments.
"""
- return KresConfig({"id": "test"})
+ return KresConfig({"server": {"id": "test"}})
IPAddressPort,
UncheckedPath,
)
+from knot_resolver_manager.datamodel.types.types import IDPattern
from knot_resolver_manager.exceptions import DataException
from knot_resolver_manager.utils import SchemaNode
DNS server control and management configuration.
---
+ id: System-wide unique identifier of this manager instance. Used for grouping logs and tagging kresd processes.
hostname: Internal DNS resolver hostname. Default is machine hostname.
nsid: Name Server Identifier (RFC 5001) which allows DNS clients to request resolver to send back its NSID along with the reply to a DNS request.
workers: The number of running kresd (Knot Resolver daemon) workers. If set to 'auto', it is equal to number of CPUs available.
webmgmt: Configuration of legacy web management endpoint.
"""
+ id: IDPattern
hostname: Optional[str] = None
nsid: Optional[str] = None
workers: Union[Literal["auto"], IntPositive] = IntPositive(1)
_PREVIOUS_SCHEMA = Raw
+ id: IDPattern
hostname: str
nsid: Optional[str]
workers: IntPositive
_re = re.compile(r"^[a-zA-Z0-9]+(?:[-_][a-zA-Z0-9]+)*$")
+class IDPattern(PatternBase):
+ """
+ Alphanumerical ID for identifying systemd slice.
+ """
+
+ _re = re.compile(r"[a-zA-Z0-9]+")
+
+
class InterfacePort(StrBase):
addr: Union[ipaddress.IPv4Address, ipaddress.IPv6Address]
if_name: InterfaceName
async def initialize_controller(self, config: KresConfig) -> None:
self._controller_config = config
try:
- await to_thread(start_slice, self._controller_config, self._systemd_type)
+ await to_thread(start_slice, self._systemd_type)
except SubprocessControllerException as e:
logger.warning(
f"Failed to create systemd slice for our subprocesses: '{e}'. There is/was a manager running with the same ID."
)
async def shutdown_controller(self) -> None:
- await to_thread(stop_slice, self._controller_config, self._systemd_type)
+ await to_thread(stop_slice, self._systemd_type)
async def create_subprocess(self, subprocess_config: KresConfig, subprocess_type: SubprocessType) -> Subprocess:
assert self._controller_config is not None
from typing_extensions import Literal
from knot_resolver_manager.compat.dataclasses import dataclass
-from knot_resolver_manager.constants import kres_gc_executable, kresd_cache_dir, kresd_config_file, kresd_executable
+from knot_resolver_manager.constants import (
+ kres_gc_executable,
+ kresd_cache_dir,
+ kresd_config_file,
+ kresd_executable,
+ user_constants,
+)
from knot_resolver_manager.datamodel.config_schema import KresConfig
from knot_resolver_manager.exceptions import SubprocessControllerException, SubprocessControllerTimeoutException
from knot_resolver_manager.kresd_controller.interface import KresID, SubprocessType
_wait_for_job_completion(systemd, job)
-def _slice_name(config: KresConfig) -> str:
- return f"kres-{config.id}.slice"
+def _slice_name() -> str:
+ return f"kres-{user_constants().ID}.slice"
def _kresd_unit_properties(config: KresConfig, kres_id: KresID) -> List[Tuple[str, str]]:
("Restart", GLib.Variant("s", "always")),
("LimitNOFILE", GLib.Variant("t", 524288)),
("Environment", GLib.Variant("as", [f"SYSTEMD_INSTANCE={kres_id}"])),
- ("Slice", GLib.Variant("s", _slice_name(config))),
+ ("Slice", GLib.Variant("s", _slice_name())),
]
if config.server.watchdog:
("RestartUSec", GLib.Variant("t", 30000000)),
("StartLimitIntervalUSec", GLib.Variant("t", 400000000)),
("StartLimitBurst", GLib.Variant("u", 10)),
- ("Slice", GLib.Variant("s", _slice_name(config))),
+ ("Slice", GLib.Variant("s", _slice_name())),
]
return val
_start_transient_unit(type_, name, properties)
-def start_slice(config: KresConfig, systemd_type: SystemdType) -> None:
- _start_transient_unit(systemd_type, _slice_name(config), _kres_slice_properties())
+def start_slice(systemd_type: SystemdType) -> None:
+ _start_transient_unit(systemd_type, _slice_name(), _kres_slice_properties())
-def stop_slice(config: KresConfig, systemd_type: SystemdType) -> None:
- stop_unit(systemd_type, _slice_name(config))
+def stop_slice(systemd_type: SystemdType) -> None:
+ stop_unit(systemd_type, _slice_name())
-def list_our_slice_processes(config: KresConfig, systemd_type: SystemdType) -> Set[str]:
- return _list_slice_services(systemd_type, _slice_name(config))
+def list_our_slice_processes(systemd_type: SystemdType) -> Set[str]:
+ return _list_slice_services(systemd_type, _slice_name())
@_wrap_dbus_errors
except SchemaException as e:
errs.append(e)
- if len(errs) > 0:
+ if len(errs) == 1:
+ raise errs[0]
+ elif len(errs) > 1:
raise AggregateSchemaException(object_path, errs)
return used_keys
if source and not isinstance(source, SchemaNode):
unused = source.keys() - used_keys
if len(unused) > 0:
+ keys = ", ".join((f"'{u}'" for u in unused))
raise SchemaException(
- f"Keys {unused} in your configuration object are not part of the configuration schema."
- " Are you using '-' instead of '_'?",
+ f"unexpected extra key(s) {keys}",
object_path,
)
-id: integration
network:
listen:
- interface: 127.0.0.1@5353
server:
+ id: integration-test
workers: 1
rundir: tests/integration/run
management:
def test_dns64_true():
- config = KresConfig({"id": "test", "dns64": True})
+ config = KresConfig({"server": {"id": "test"}, "dns64": True})
assert config.dns64
assert config.dns64.prefix == IPv6Network96("64:ff9b::/96")
def test_dnssec_false():
- config = KresConfig({"id": "test", "dnssec": False})
+ config = KresConfig({"server": {"id": "test"}, "dnssec": False})
assert config.dnssec == False
def test_watchdog():
- assert ServerSchema({"watchdog": {"qname": "nic.cz.", "qtype": "A"}})
+ assert ServerSchema({"watchdog": {"qname": "nic.cz.", "qtype": "A"}, "id": "test"})
with raises(KresManagerException):
ServerSchema({"backend": "supervisord", "watchdog": {"qname": "nic.cz.", "qtype": "A"}})