From: Aleš Mrázek Date: Thu, 11 Sep 2025 09:02:25 +0000 (+0200) Subject: client: validate: allow combination of config files X-Git-Tag: v6.0.16~10^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9efbcdaf6df16276dbf385522ef7d53077a61ce0;p=thirdparty%2Fknot-resolver.git client: validate: allow combination of config files --- diff --git a/doc/user/manager-client.rst b/doc/user/manager-client.rst index c0c757c01..6ab8d2bf5 100644 --- a/doc/user/manager-client.rst +++ b/doc/user/manager-client.rst @@ -251,13 +251,15 @@ single ``kresctl`` command. This is because the validation runs under a different user/group than the resolver itself and attempts to access the configured paths directly. - .. option:: + .. option:: [ ...] - File with the declarative configuration in YAML or JSON format. + :default: /etc/knot-resolver/config.yaml + + Optional, file or combination of files with the declarative configuration in YAML or JSON format. .. code-block:: bash - $ kresctl validate input-config.json + $ kresctl validate config.yaml config.additional.json .. option:: convert diff --git a/python/knot_resolver/client/commands/validate.py b/python/knot_resolver/client/commands/validate.py index 2a336db3e..0b71983a7 100644 --- a/python/knot_resolver/client/commands/validate.py +++ b/python/knot_resolver/client/commands/validate.py @@ -1,13 +1,15 @@ import argparse import sys from pathlib import Path -from typing import List, Tuple, Type +from typing import Any, Dict, List, Tuple, Type from knot_resolver.client.command import Command, CommandArgs, CompWords, comp_get_words, register_command +from knot_resolver.constants import CONFIG_FILE from knot_resolver.datamodel import KresConfig from knot_resolver.datamodel.globals import Context, reset_global_validation_context, set_global_validation_context from knot_resolver.utils.modeling import try_to_parse from knot_resolver.utils.modeling.exceptions import DataParsingError, DataValidationError +from knot_resolver.utils.modeling.parsing import data_combine @register_command @@ -32,9 +34,9 @@ class ValidateCommand(Command): validate.add_argument( "input_file", type=str, - nargs="?", - help="File with configuration in YAML or JSON format.", - default=None, + nargs="*", + help="File or combination of files with the declarative configuration in YAML or JSON format.", + default=[CONFIG_FILE], ) return validate, ValidateCommand @@ -44,15 +46,16 @@ class ValidateCommand(Command): return comp_get_words(args, parser) def run(self, args: CommandArgs) -> None: - if self.input_file: - with open(self.input_file, "r") as f: - data = f.read() - else: - data = input("Type configuration to validate: ") - + data: Dict[str, Any] = {} try: - set_global_validation_context(Context(Path(self.input_file).parent, self.strict)) - KresConfig(try_to_parse(data)) + for file in self.input_file: + with open(file, "r") as f: + raw = f.read() + parsed = try_to_parse(raw) + data = data_combine(data, parsed) + + set_global_validation_context(Context(Path(self.input_file[0]).parent, self.strict)) + KresConfig(data) reset_global_validation_context() except (DataParsingError, DataValidationError) as e: print(e, file=sys.stderr)