Skip to content

Commit

Permalink
op-mode: T6471: add optimized get_config_dict
Browse files Browse the repository at this point in the history
  • Loading branch information
jestabro committed Jun 11, 2024
1 parent 3f931cc commit 1a16485
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
60 changes: 58 additions & 2 deletions python/vyos/configquery.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2021-2023 VyOS maintainers and contributors <[email protected]>
# Copyright 2021-2024 VyOS maintainers and contributors <[email protected]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
Expand All @@ -19,6 +19,8 @@
'''

import os
import json
import subprocess

from vyos.utils.process import STDOUT
from vyos.utils.process import popen
Expand All @@ -27,6 +29,14 @@
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')

Expand Down Expand Up @@ -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)
7 changes: 7 additions & 0 deletions python/vyos/utils/dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ def func(d, path):
for r in func(d, []):
yield r

def embed_dict(p: list[str], d: dict) -> dict:
path = p.copy()
ret = d
while path:
ret = {path.pop(): ret}
return ret

def check_mutually_exclusive_options(d, keys, required=False):
""" Checks if a dict has at most one or only one of
mutually exclusive keys.
Expand Down
24 changes: 24 additions & 0 deletions python/vyos/utils/error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2024 VyOS maintainers and contributors <[email protected]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.

from enum import IntEnum

class cli_shell_api_err(IntEnum):
""" vyatta-cfg/src/vyos-errors.h """
VYOS_SUCCESS = 0
VYOS_GENERAL_FAILURE = 1
VYOS_INVALID_PATH = 2
VYOS_EMPTY_CONFIG = 3
VYOS_CONFIG_PARSE_ERROR = 4

0 comments on commit 1a16485

Please sign in to comment.