summaryrefslogtreecommitdiff
path: root/python/vyos/configquery.py
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2024-06-07 22:06:56 -0500
committerJohn Estabrook <jestabro@vyos.io>2024-06-10 22:48:55 -0500
commit1a164852d2cb4cb8db80274d8b1fba90854e9b20 (patch)
tree59c32f2ce9c04d153316898ce08ca4766033541b /python/vyos/configquery.py
parent3f931cca3c5dac40a2ea097caf323a05b3e45ca0 (diff)
downloadvyos-1x-1a164852d2cb4cb8db80274d8b1fba90854e9b20.tar.gz
vyos-1x-1a164852d2cb4cb8db80274d8b1fba90854e9b20.zip
op-mode: T6471: add optimized get_config_dict
Diffstat (limited to 'python/vyos/configquery.py')
-rw-r--r--python/vyos/configquery.py60
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)