summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/config_mgmt.py75
-rw-r--r--python/vyos/configtree.py15
-rw-r--r--python/vyos/derivedtree.py15
-rw-r--r--python/vyos/utils/config.py12
4 files changed, 41 insertions, 76 deletions
diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py
index b3efdeac9..06cfb3d78 100644
--- a/python/vyos/config_mgmt.py
+++ b/python/vyos/config_mgmt.py
@@ -38,7 +38,6 @@ from vyos.configtree import ConfigTreeError
from vyos.configsession import ConfigSession
from vyos.configsession import ConfigSessionError
from vyos.configtree import diff_compare
-from vyos.configtree import DiffTree
from vyos.load_config import load
from vyos.load_config import LoadConfigError
from vyos.defaults import directories
@@ -452,80 +451,6 @@ Proceed ?"""
return self.compare(commands=cmnds, rev1=r1, rev2=r2)
- def _format_remote_diff(self, diff_tree: DiffTree, path: list, commands: bool):
- add_tree = diff_tree.add
- del_tree = diff_tree.delete
- command_prefix = ' '.join(path)
-
- result_lines = []
- if commands:
- # Process the deleted elements into command format and filter based on prefix (path)
- for line in del_tree.to_commands(op='delete').splitlines():
- if line.startswith(f'delete {command_prefix}'):
- result_lines.append(line)
-
- # Process the added elements into command format and filter based on prefix (path)
- for line in add_tree.to_commands(op='set').splitlines():
- if line.startswith(f'set {command_prefix}'):
- result_lines.append(line)
- else:
- with_node = len(path) > 1
- # Retrieve subtrees for the specified path from both added and deleted trees
- del_tree = del_tree.get_subtree(path, with_node=with_node)
- add_tree = add_tree.get_subtree(path, with_node=with_node)
-
- # Convert the subtrees to string lines for further processing
- del_tree_lines = str(del_tree).splitlines()
- add_tree_lines = str(add_tree).splitlines()
-
- # Format the lines with a prefix ('-', '+') and filter out empty lines
- del_lines = [f'- {l}' for l in del_tree_lines if l.strip()]
- add_lines = [f'+ {l}' for l in add_tree_lines if l.strip()]
-
- if del_lines or add_lines:
- # Adjust command prefix if a node is present in the path
- command_prefix = ' '.join(path[:-1]) if with_node else command_prefix
- if command_prefix:
- result_lines.append(f'[{command_prefix}]')
-
- # Combine both deleted and added lines and process them
- result_lines.extend(del_lines + add_lines)
-
- # Join the result lines into a single string, excluding empty lines
- return '\n'.join((line for line in result_lines if line.strip()))
-
- def remote_compare(
- self,
- source: str,
- remote_tree: ConfigTree,
- path: Optional[list] = None,
- commands: bool = False,
- ) -> str:
- """
- Compares a local configuration tree with a remote
- configuration tree based on the specified source ('running', 'candidate', 'saved').
- """
- path = path or []
-
- # Determine the correct local configuration tree based on the 'source' parameter
- if source == 'running':
- local_tree = self.active_config
- elif source == 'candidate':
- local_tree = self.working_config
- elif source == 'saved':
- local_tree = self._get_saved_config_tree()
- else:
- raise ConfigMgmtError(
- 'Invalid source, must be one of: running, candidate, saved'
- )
-
- try:
- diff_tree = DiffTree(remote_tree, local_tree)
- except ConfigTreeError as e:
- raise ConfigMgmtError(e) from e
-
- return self._format_remote_diff(diff_tree, path, commands)
-
# Initialization and post-commit hooks for conf-mode
#
def initialize_revision(self):
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index 9c5d69ad1..24b3252fd 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -19,6 +19,8 @@ import logging
from ctypes import cdll, c_char_p, c_void_p, c_int, c_bool
from typing import TYPE_CHECKING
+from pathlib import Path
+
# https://peps.python.org/pep-0484/#forward-references
# for type 'ConfigDict'
@@ -265,6 +267,19 @@ class ConfigTree:
if self.__migration:
self.migration_log = logging.getLogger('vyos.migrate')
+ @classmethod
+ def load_file(cls, location):
+ # pylint: disable=raise-missing-from
+ config_file = Path(location)
+ if not config_file.exists():
+ raise ConfigTreeError(f'Missing config file at {location}')
+ try:
+ config_tree = cls(config_file.read_text())
+ except (OSError, ValueError, TypeError) as e:
+ raise ConfigTreeError(f'Corrupted config file at {location}: {e}')
+
+ return config_tree
+
def __del__(self):
if self.__config is not None:
self.__destroy(self.__config)
diff --git a/python/vyos/derivedtree.py b/python/vyos/derivedtree.py
index dc46b8eb3..61e1a4d94 100644
--- a/python/vyos/derivedtree.py
+++ b/python/vyos/derivedtree.py
@@ -18,6 +18,7 @@ from vyos.referencetree import ReferenceTree
from vyos.configtree import ConfigTree
from vyos.configtree import ConfigTreeError
from vyos.configtree import subtree_from_partial
+from vyos.configtree import mask_exclusive
class DerivedTreeError(Exception):
@@ -29,7 +30,7 @@ def subtree_from_list_of_partial_paths(
paths: list[list[str]],
accumulator: ConfigTree = None,
reference_tree: ReferenceTree = None,
-):
+) -> ConfigTree:
"""Return the union of subtrees of the ConfigTree argument matching each
of the 'partial' paths. A partial path is one that may or may not
contain intervening tag node values, in which case it will match for all
@@ -61,3 +62,15 @@ def subtree_from_list_of_partial_paths(
raise DerivedTreeError(f'Nonsensical paths: {errors}')
return accumulator
+
+
+def apply_exclusion_list(
+ config_tree: ConfigTree, exclusion_list: list[list[str]]
+) -> ConfigTree:
+ mask_ex = subtree_from_list_of_partial_paths(config_tree, exclusion_list)
+ try:
+ masked = mask_exclusive(config_tree, mask_ex)
+ except ConfigTreeError as e:
+ raise DerivedTreeError(str(e)) from e
+
+ return masked
diff --git a/python/vyos/utils/config.py b/python/vyos/utils/config.py
index 1032e22dc..004d64bbd 100644
--- a/python/vyos/utils/config.py
+++ b/python/vyos/utils/config.py
@@ -75,6 +75,18 @@ def write_saved_value(path: list, value=None, config_path: str=config_file):
write_file(config_path, ct.to_string())
+
+def get_saved_config_tree() -> 'ConfigTree':
+ # pylint: disable=import-outside-toplevel
+ """Return config tree of saved config.
+
+ Raises ConfigTreeError.
+ """
+ from vyos.configtree import ConfigTree
+
+ return ConfigTree.load_file(config_file)
+
+
def flag(l: list) -> list:
res = [l[0:i] for i,_ in enumerate(l, start=1)]
return res