From: Aleš Date: Thu, 24 Feb 2022 14:48:16 +0000 (+0100) Subject: manager: server: deny server.groupid runtime changes X-Git-Tag: v6.0.0a1~41^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=414d2ab9bb8bea0c0db4f49671f221e63b554ea7;p=thirdparty%2Fknot-resolver.git manager: server: deny server.groupid runtime changes - conf files names based on groupid --- diff --git a/manager/knot_resolver_manager/client/__init__.py b/manager/knot_resolver_manager/client/__init__.py index 35a7c8112..ae7f31276 100644 --- a/manager/knot_resolver_manager/client/__init__.py +++ b/manager/knot_resolver_manager/client/__init__.py @@ -29,6 +29,10 @@ class KnotManagerClient: response = requests.post(self._create_url("/config/server/workers"), data=str(n)) print(response.text) + def set_groupid(self, gid: str) -> None: + response = requests.post(self._create_url("/config/server/groupid"), data=f'"{gid}"') + print(response.text) + def set_static_hints(self, hints: Dict[str, List[Union[ipaddress.IPv4Address, ipaddress.IPv6Address]]]) -> None: payload = {name: [str(a) for a in addrs] for name, addrs in hints.items()} response = requests.post(self._create_url("/config/static-hints/hints"), json=payload) diff --git a/manager/knot_resolver_manager/client/__main__.py b/manager/knot_resolver_manager/client/__main__.py index c39e708fc..0e14488f3 100644 --- a/manager/knot_resolver_manager/client/__main__.py +++ b/manager/knot_resolver_manager/client/__main__.py @@ -58,6 +58,14 @@ def workers(ctx: click.Context, instances: int) -> None: client.set_num_workers(instances) +@main.command(help="Set the manager groupid") +@click.argument("gid", type=str, nargs=1) +@click.pass_context +def groupid(ctx: click.Context, gid: str) -> None: + client = KnotManagerClient(ctx.obj[BASE_URL]) + client.set_groupid(gid) + + @main.command("one-static-hint", help="Set one inline static-hint hints (replaces old static hints)") @click.argument("name", type=str, nargs=1) @click.argument("ip", type=str, nargs=1) diff --git a/manager/knot_resolver_manager/constants.py b/manager/knot_resolver_manager/constants.py index 8f4dfb200..3f1f0a8c7 100644 --- a/manager/knot_resolver_manager/constants.py +++ b/manager/knot_resolver_manager/constants.py @@ -21,8 +21,8 @@ def kresd_cache_dir(config: KresConfig) -> Path: return config.cache.storage.to_path() -def kresd_config_file(_config: KresConfig, kres_id: KresID) -> Path: - return Path(f"kresd_{kres_id}.conf") +def kresd_config_file(config: KresConfig, kres_id: KresID) -> Path: + return Path(f"{config.server.groupid}kresd_{kres_id}.conf") def supervisord_config_file(_config: KresConfig) -> Path: diff --git a/manager/knot_resolver_manager/kresd_controller/systemd/dbus_api.py b/manager/knot_resolver_manager/kresd_controller/systemd/dbus_api.py index 31acd2a68..b0270c9e4 100644 --- a/manager/knot_resolver_manager/kresd_controller/systemd/dbus_api.py +++ b/manager/knot_resolver_manager/kresd_controller/systemd/dbus_api.py @@ -26,11 +26,13 @@ GC_SERVICE_BASE_NAME = "kres_cache_gc.service" KRESD_SERVICE_BASE_PATTERN = re.compile(r"^kresd_([0-9]+).service$") +def service_name_remove_prefix(service_name: str, prefix: str) -> str: + return service_name[len(prefix) :] if service_name.startswith(prefix) else service_name # noqa: E203 + + def kres_id_from_service_name(service_name: str, config: KresConfig) -> KresID: - base_service_name = service_name - if service_name.startswith(config.server.groupid): - base_service_name = service_name[len(config.server.groupid) :] # noqa: E203 - kid = KRESD_SERVICE_BASE_PATTERN.search(base_service_name) + service_name_noprefix = service_name_remove_prefix(service_name, config.server.groupid) + kid = KRESD_SERVICE_BASE_PATTERN.search(service_name_noprefix) if kid: return KresID.from_string(kid.groups()[0]) return KresID.from_string(service_name) @@ -44,10 +46,9 @@ def create_service_name(kid: KresID, config: KresConfig) -> str: def is_service_name_ours(service_name: str, config: KresConfig) -> bool: - if service_name.startswith(config.server.groupid): - service_name = service_name[len(config.server.groupid) :] # noqa: E203 - is_ours = service_name == GC_SERVICE_BASE_NAME - is_ours |= bool(KRESD_SERVICE_BASE_PATTERN.match(service_name)) + service_name_noprefix = service_name_remove_prefix(service_name, config.server.groupid) + is_ours = service_name_noprefix == GC_SERVICE_BASE_NAME + is_ours |= bool(KRESD_SERVICE_BASE_PATTERN.match(service_name_noprefix)) return is_ours diff --git a/manager/knot_resolver_manager/server.py b/manager/knot_resolver_manager/server.py index e1b533119..e7e68ee4b 100644 --- a/manager/knot_resolver_manager/server.py +++ b/manager/knot_resolver_manager/server.py @@ -78,15 +78,22 @@ class Server: async def _reconfigure(self, config: KresConfig) -> None: await self._reconfigure_listen_address(config) - async def _deny_listen_address_changes(self, config_old: KresConfig, config_new: KresConfig) -> Result[None, str]: + async def _deny_management_changes(self, config_old: KresConfig, config_new: KresConfig) -> Result[None, str]: if config_old.server.management != config_new.server.management: return Result.err( - "Changing API listen address dynamically is not allowed as it's really dangerous. If you" - " really need this feature, please contact the developers and explain why. Technically," + "/server/management: Changing management API address/unix-socket dynamically is not allowed as it's really dangerous." + " If you really need this feature, please contact the developers and explain why. Technically," " there are no problems in supporting it. We are only blocking the dynamic changes because" " we think the consequences of leaving this footgun unprotected are worse than its usefulness." ) + return Result.ok(None) + async def _deny_groupid_changes(self, config_old: KresConfig, config_new: KresConfig) -> Result[None, str]: + if config_old.server.groupid != config_new.server.groupid: + return Result.err( + "/server/groupid: Based on the groupid, the manager recognizes his subprocesses," + " so it is not possible to change it while services are running." + ) return Result.ok(None) async def sigint_handler(self) -> None: @@ -121,7 +128,8 @@ class Server: asyncio_compat.add_async_signal_handler(signal.SIGINT, self.sigint_handler) asyncio_compat.add_async_signal_handler(signal.SIGHUP, self.sighup_handler) await self.runner.setup() - await self.config_store.register_verifier(self._deny_listen_address_changes) + await self.config_store.register_verifier(self._deny_management_changes) + await self.config_store.register_verifier(self._deny_groupid_changes) await self.config_store.register_on_change_callback(self._reconfigure) async def wait_for_shutdown(self) -> None: