diff options
author | Aleš Mrázek <ales.mrazek@nic.cz> | 2025-01-14 10:02:02 +0100 |
---|---|---|
committer | Aleš Mrázek <ales.mrazek@nic.cz> | 2025-01-14 10:02:02 +0100 |
commit | 3c2bc79515ead4e28cc2eca9eeac4625d18caf62 (patch) | |
tree | 06c464b480cd7c9158bb14b7975ef7205a2f227f | |
parent | Merge !1641: Request prioritization (defer) (diff) | |
parent | NEWS: update (diff) | |
download | knot-resolver-3c2bc79515ead4e28cc2eca9eeac4625d18caf62.tar.xz knot-resolver-3c2bc79515ead4e28cc2eca9eeac4625d18caf62.zip |
Merge branch 'manager-files-reload' into 'master'
manager: TLS cert files reload (force)
See merge request knot/knot-resolver!1644
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | python/knot_resolver/manager/config_store.py | 19 | ||||
-rw-r--r-- | python/knot_resolver/manager/files/__init__.py | 3 | ||||
-rw-r--r-- | python/knot_resolver/manager/files/reload.py | 17 | ||||
-rw-r--r-- | python/knot_resolver/manager/manager.py | 11 | ||||
-rwxr-xr-x | tests/packaging/interactive/files_reload.sh | 93 |
6 files changed, 143 insertions, 2 deletions
@@ -6,9 +6,11 @@ Improvements - avoid multiple log lines when IPv6 isn't available (!1633) - manager: fix startup on Linux without libsystemd (!1608) - auto-reload TLS certificate files (!1626) +- reload TLS certificate files even if the configuration has not changed (!1644) - kresctl: bash command-line TAB completion (!1622) - add request prioritization (defer) to mitigate DoS attacks (!1641) + Knot Resolver 6.0.9 (2024-11-11) ================================ diff --git a/python/knot_resolver/manager/config_store.py b/python/knot_resolver/manager/config_store.py index 214062b2..70a9d942 100644 --- a/python/knot_resolver/manager/config_store.py +++ b/python/knot_resolver/manager/config_store.py @@ -59,6 +59,25 @@ class ConfigStore: return self._config +def only_on_no_changes_update(selector: Callable[[KresConfig], Any]) -> Callable[[UpdateCallback], UpdateCallback]: + def decorator(orig_func: UpdateCallback) -> UpdateCallback: + original_value_set: Any = False + original_value: Any = None + + async def new_func_update(config: KresConfig) -> None: + nonlocal original_value_set + nonlocal original_value + if not original_value_set: + original_value_set = True + elif original_value == selector(config): + await orig_func(config) + original_value = selector(config) + + return new_func_update + + return decorator + + def only_on_real_changes_update(selector: Callable[[KresConfig], Any]) -> Callable[[UpdateCallback], UpdateCallback]: def decorator(orig_func: UpdateCallback) -> UpdateCallback: original_value_set: Any = False diff --git a/python/knot_resolver/manager/files/__init__.py b/python/knot_resolver/manager/files/__init__.py index 49700656..29fbc741 100644 --- a/python/knot_resolver/manager/files/__init__.py +++ b/python/knot_resolver/manager/files/__init__.py @@ -1,3 +1,4 @@ +from .reload import files_reload from .watchdog import init_files_watchdog -__all__ = ["init_files_watchdog"] +__all__ = ["files_reload", "init_files_watchdog"] diff --git a/python/knot_resolver/manager/files/reload.py b/python/knot_resolver/manager/files/reload.py new file mode 100644 index 00000000..6dfd5874 --- /dev/null +++ b/python/knot_resolver/manager/files/reload.py @@ -0,0 +1,17 @@ +import logging + +from knot_resolver.controller.registered_workers import command_registered_workers +from knot_resolver.datamodel import KresConfig + +logger = logging.getLogger(__name__) + + +async def files_reload(config: KresConfig) -> None: + cert_file = config.network.tls.cert_file + key_file = config.network.tls.key_file + + if cert_file and key_file: + logger.info("TLS cert files reload triggered") + + cmd = f"net.tls('{cert_file}', '{key_file}')" + await command_registered_workers(cmd) diff --git a/python/knot_resolver/manager/manager.py b/python/knot_resolver/manager/manager.py index 68edb915..e2fa33b3 100644 --- a/python/knot_resolver/manager/manager.py +++ b/python/knot_resolver/manager/manager.py @@ -11,7 +11,13 @@ from knot_resolver.controller.exceptions import SubprocessControllerError from knot_resolver.controller.interface import Subprocess, SubprocessController, SubprocessStatus, SubprocessType from knot_resolver.controller.registered_workers import command_registered_workers, get_registered_workers_kresids from knot_resolver.datamodel import KresConfig -from knot_resolver.manager.config_store import ConfigStore, only_on_real_changes_update, only_on_real_changes_verifier +from knot_resolver.manager.config_store import ( + ConfigStore, + only_on_no_changes_update, + only_on_real_changes_update, + only_on_real_changes_verifier, +) +from knot_resolver.manager.files import files_reload from knot_resolver.utils.compat.asyncio import create_task from knot_resolver.utils.functional import Result from knot_resolver.utils.modeling.types import NoneType @@ -152,6 +158,9 @@ class KresManager: # pylint: disable=too-many-instance-attributes only_on_real_changes_update(config_nodes)(self.set_new_tls_sticket_secret) ) + # register callback that reloads files (TLS cert files) if selected configuration has not been changed + await config_store.register_on_change_callback(only_on_no_changes_update(config_nodes)(files_reload)) + # register controller config change listeners await config_store.register_verifier(_deny_max_worker_changes) diff --git a/tests/packaging/interactive/files_reload.sh b/tests/packaging/interactive/files_reload.sh new file mode 100755 index 00000000..b787100d --- /dev/null +++ b/tests/packaging/interactive/files_reload.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +set -e + +gitroot=$(git rev-parse --show-toplevel) +cert_file=$gitroot/modules/http/test_tls/test.crt +key_file=$gitroot/modules/http/test_tls/test.key + +tls_certificate_conf=$(cat <<EOF +{ + "cert-file": "$cert_file", + "key-file": "$key_file" +} +EOF +) + +function count_errors(){ + echo "$(journalctl -u knot-resolver.service | grep -c error)" +} + +function count_reloads(){ + echo "$(journalctl -u knot-resolver.service | grep -c "TLS cert files reload triggered")" +} + + + +# test reload without files configure +# {{ + +err_count=$(count_errors) +rel_count=$(count_reloads) + +kresctl reload +if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -ne $rel_count ]; then + echo "TLS cert files reload triggered when should not be." + exit 1 +fi + +# }} + +# configure TLS certificate files +kresctl config set -p /network/tls "$tls_certificate_conf" +if [ "$?" -ne "0" ]; then + echo "Could not set TLS certificate files." + exit 1 +fi + +# test reload on no config changes +# {{ + +rel_count=$(count_reloads) + +kresctl config set -p /workers 2 +if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -eq $rel_count ]; then + echo "TLS cert files reload not triggered whe should be." + exit 1 +fi + +# }} + +# test reload on config changes +# {{ + +rel_count=$(count_reloads) + +kresctl config set -p /workers 5 +if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -ne $rel_count ]; then + echo "TLS cert files reload triggered when should not be." + exit 1 +fi + +# }} + +# test reload again on no config changes +# {{ + +rel_count=$(count_reloads) + +kresctl config set -p /workers 5 +if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -eq $rel_count ]; then + echo "TLS cert files reload not triggered whe should be." + exit 1 +fi + +# }} + +# reload to defaults +kresctl reload +if [ "$?" -ne "0" ]; then + echo "The resolver reload failed." + exit 1 +fi + |