summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2021-08-03 15:37:57 -0500
committerJohn Estabrook <jestabro@vyos.io>2021-08-03 15:37:57 -0500
commit5a11647335dc179834c55749b177bd1a47eff32a (patch)
treea21f59036c7d9cf001629205f6bec51fc21ed2b3 /python
parent1d8f1f2a8a286aedefbf40451c6fcfd78bd5f723 (diff)
downloadvyos-1x-5a11647335dc179834c55749b177bd1a47eff32a.tar.gz
vyos-1x-5a11647335dc179834c55749b177bd1a47eff32a.zip
configquery: T3402: add op-mode get_config_dict
Diffstat (limited to 'python')
-rw-r--r--python/vyos/configquery.py62
1 files changed, 60 insertions, 2 deletions
diff --git a/python/vyos/configquery.py b/python/vyos/configquery.py
index 0f0bc2f79..6871602d5 100644
--- a/python/vyos/configquery.py
+++ b/python/vyos/configquery.py
@@ -18,8 +18,12 @@ A small library that allows querying existence or value(s) of config
settings from op mode, and execution of arbitrary op mode commands.
'''
+import re
+import json
from subprocess import STDOUT
-from vyos.util import popen
+
+import vyos.util
+import vyos.xml
from vyos.configtree import ConfigTree
class ConfigQueryError(Exception):
@@ -51,7 +55,7 @@ class CliShellApiConfigQuery(GenericConfigQuery):
def exists(self, path: list):
cmd = ' '.join(path)
- (_, err) = popen(f'cli-shell-api existsActive {cmd}')
+ (_, err) = vyos.util.popen(f'cli-shell-api existsActive {cmd}')
if err:
return False
return True
@@ -78,6 +82,8 @@ class ConfigTreeActiveQuery(GenericConfigQuery):
config_file = f.read()
self.configtree = ConfigTree(config_file)
+ self._level = []
+
def exists(self, path: list):
return self.configtree.exists(path)
@@ -90,6 +96,58 @@ class ConfigTreeActiveQuery(GenericConfigQuery):
def list_nodes(self, path: list):
return self.configtree.list_nodes(path)
+ def _make_path(self, path):
+ # Backwards-compatibility stuff: original implementation used string paths
+ # libvyosconfig paths are lists, but since node names cannot contain whitespace,
+ # splitting at whitespace is reasonably safe.
+ # It may cause problems with exists() when it's used for checking values,
+ # since values may contain whitespace.
+ if isinstance(path, str):
+ path = re.split(r'\s+', path)
+ elif isinstance(path, list):
+ pass
+ else:
+ raise TypeError("Path must be a whitespace-separated string or a list")
+ return (self._level + path)
+
+ def get_config_dict(self, path=[], key_mangling=None,
+ get_first_key=False, no_multi_convert=False,
+ no_tag_node_value_mangle=False):
+ """
+ Args:
+ path (str list): Configuration tree path, can be empty
+ key_mangling=None: mangle dict keys according to regex and replacement
+ get_first_key=False: if k = path[:-1], return sub-dict d[k] instead of {k: d[k]}
+ no_multi_convert=False: if convert, return single value of multi node as list
+
+ Returns: a dict representation of the config under path
+ """
+ lpath = self._make_path(path)
+ root_dict = json.loads(self.configtree.to_json())
+ conf_dict = vyos.util.get_sub_dict(root_dict, lpath, get_first_key)
+
+ if not key_mangling and no_multi_convert:
+ return deepcopy(conf_dict)
+
+ xmlpath = lpath if get_first_key else lpath[:-1]
+
+ if not key_mangling:
+ conf_dict = vyos.xml.multi_to_list(xmlpath, conf_dict)
+ return conf_dict
+
+ if no_multi_convert is False:
+ conf_dict = multi_to_list(xmlpath, conf_dict)
+
+ 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")
+
+ conf_dict = vyos.util.mangle_dict_keys(conf_dict, key_mangling[0], key_mangling[1], abs_path=xmlpath, no_tag_node_value_mangle=no_tag_node_value_mangle)
+
+ return conf_dict
+
class VbashOpRun(GenericOpRun):
def __init__(self):
super().__init__()