diff options
Diffstat (limited to 'python/vyos/configquery.py')
-rw-r--r-- | python/vyos/configquery.py | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/python/vyos/configquery.py b/python/vyos/configquery.py index 71ad5b4f0..5d6ca9be9 100644 --- a/python/vyos/configquery.py +++ b/python/vyos/configquery.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -19,6 +19,8 @@ settings from op mode, and execution of arbitrary op mode commands. ''' import os +import json +import subprocess from vyos.utils.process import STDOUT from vyos.utils.process import popen @@ -27,6 +29,14 @@ from vyos.utils.boot import boot_configuration_complete from vyos.config import Config from vyos.configsource import ConfigSourceSession, ConfigSourceString from vyos.defaults import directories +from vyos.configtree import ConfigTree +from vyos.utils.dict import embed_dict +from vyos.utils.dict import get_sub_dict +from vyos.utils.dict import mangle_dict_keys +from vyos.utils.error import cli_shell_api_err +from vyos.xml_ref import multi_to_list +from vyos.xml_ref import is_tag +from vyos.base import Warning config_file = os.path.join(directories['config'], 'config.boot') @@ -133,4 +143,50 @@ def query_context(config_query_class=CliShellApiConfigQuery, run = op_run_class() return query, run - +def verify_mangling(key_mangling): + if not (isinstance(key_mangling, tuple) and + len(key_mangling) == 2 and + isinstance(key_mangling[0], str) and + isinstance(key_mangling[1], str)): + raise ValueError("key_mangling must be a tuple of two strings") + +def op_mode_run(cmd): + """ low-level to avoid overhead """ + p = subprocess.Popen(cmd, stdout=subprocess.PIPE) + out = p.stdout.read() + p.wait() + return p.returncode, out.decode() + +def op_mode_config_dict(path=None, key_mangling=None, + no_tag_node_value_mangle=False, + no_multi_convert=False, get_first_key=False): + + if path is None: + path = [] + command = ['/bin/cli-shell-api', '--show-active-only', 'showConfig'] + + rc, out = op_mode_run(command + path) + if rc == cli_shell_api_err.VYOS_EMPTY_CONFIG: + out = '' + if rc == cli_shell_api_err.VYOS_INVALID_PATH: + Warning(out) + return {} + + ct = ConfigTree(out) + d = json.loads(ct.to_json()) + # cli-shell-api output includes last path component if tag node + if is_tag(path): + config_dict = embed_dict(path[:-1], d) + else: + config_dict = embed_dict(path, d) + + if not no_multi_convert: + config_dict = multi_to_list([], config_dict) + + if key_mangling is not None: + verify_mangling(key_mangling) + config_dict = mangle_dict_keys(config_dict, + key_mangling[0], key_mangling[1], + no_tag_node_value_mangle=no_tag_node_value_mangle) + + return get_sub_dict(config_dict, path, get_first_key=get_first_key) |