summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2023-02-15 19:05:24 +0100
committerGitHub <noreply@github.com>2023-02-15 19:05:24 +0100
commita48940a943d237b0b2e8fcf8f9066c416d175e8d (patch)
tree8e76bfb1bd77b35d4f4a4a39898b2c5941871f2a
parent63dfe01db5fb60031cf5b4b017a2f172166fe4b7 (diff)
parent694096f108c3421d4ff11ad75eec3bfb1cde562b (diff)
downloadvyos-1x-a48940a943d237b0b2e8fcf8f9066c416d175e8d.tar.gz
vyos-1x-a48940a943d237b0b2e8fcf8f9066c416d175e8d.zip
Merge pull request #1811 from jestabro/udiff
config_mgmt: T4991: use configtree.show_diff instead of Python difflib
-rw-r--r--python/vyos/config_mgmt.py43
-rw-r--r--python/vyos/configtree.py32
2 files changed, 44 insertions, 31 deletions
diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py
index 22a49ff50..fade3081c 100644
--- a/python/vyos/config_mgmt.py
+++ b/python/vyos/config_mgmt.py
@@ -24,7 +24,7 @@ from datetime import datetime
from tabulate import tabulate
from vyos.config import Config
-from vyos.configtree import ConfigTree
+from vyos.configtree import ConfigTree, ConfigTreeError, show_diff
from vyos.defaults import directories
from vyos.util import is_systemd_service_active, ask_yes_no, rc_cmd
@@ -93,15 +93,7 @@ class ConfigMgmt:
# a call to compare without args is edit_level aware
edit_level = os.getenv('VYATTA_EDIT_LEVEL', '')
- edit_path = [l for l in edit_level.split('/') if l]
- if edit_path:
- eff_conf = config.show_config(edit_path, effective=True)
- self.edit_level_active_config = ConfigTree(eff_conf)
- conf = config.show_config(edit_path)
- self.edit_level_working_config = ConfigTree(conf)
- else:
- self.edit_level_active_config = None
- self.edit_level_working_config = None
+ self.edit_path = [l for l in edit_level.split('/') if l]
self.active_config = config._running_config
self.working_config = config._session_config
@@ -241,14 +233,8 @@ Proceed ?'''
revision n vs. revision m; working version vs. active version;
or working version vs. saved version.
"""
- from difflib import unified_diff
-
- ct1 = self.edit_level_active_config
- if ct1 is None:
- ct1 = self.active_config
- ct2 = self.edit_level_working_config
- if ct2 is None:
- ct2 = self.working_config
+ ct1 = self.active_config
+ ct2 = self.working_config
msg = 'No changes between working and active configurations.\n'
if saved:
ct1 = self._get_saved_config_tree()
@@ -268,19 +254,16 @@ Proceed ?'''
ct1 = self._get_config_tree_revision(rev2)
msg = f'No changes between revisions {rev2} and {rev1} configurations.\n'
- if commands:
- lines1 = ct1.to_commands().splitlines(keepends=True)
- lines2 = ct2.to_commands().splitlines(keepends=True)
- else:
- lines1 = ct1.to_string().splitlines(keepends=True)
- lines2 = ct2.to_string().splitlines(keepends=True)
-
out = ''
- comp = unified_diff(lines1, lines2)
- for line in comp:
- if re.match(r'(\-\-)|(\+\+)|(@@)', line):
- continue
- out += line
+ path = [] if commands else self.edit_path
+ try:
+ if commands:
+ out = show_diff(ct1, ct2, path=path, commands=True)
+ else:
+ out = show_diff(ct1, ct2, path=path)
+ except ConfigTreeError as e:
+ return e, 1
+
if out:
msg = out
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index f2358ee4f..c0b3ebd78 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -16,7 +16,7 @@ import os
import re
import json
-from ctypes import cdll, c_char_p, c_void_p, c_int
+from ctypes import cdll, c_char_p, c_void_p, c_int, c_bool
LIBPATH = '/usr/lib/libvyosconfig.so.0'
@@ -322,6 +322,36 @@ class ConfigTree(object):
subt = ConfigTree(address=res)
return subt
+def show_diff(left, right, path=[], commands=False, libpath=LIBPATH):
+ if left is None:
+ left = ConfigTree(config_string='\n')
+ if right is None:
+ right = ConfigTree(config_string='\n')
+ if not (isinstance(left, ConfigTree) and isinstance(right, ConfigTree)):
+ raise TypeError("Arguments must be instances of ConfigTree")
+ if path:
+ if (not left.exists(path)) and (not right.exists(path)):
+ raise ConfigTreeError(f"Path {path} doesn't exist")
+
+ check_path(path)
+ path_str = " ".join(map(str, path)).encode()
+
+ __lib = cdll.LoadLibrary(libpath)
+ __show_diff = __lib.show_diff
+ __show_diff.argtypes = [c_bool, c_char_p, c_void_p, c_void_p]
+ __show_diff.restype = c_char_p
+ __get_error = __lib.get_error
+ __get_error.argtypes = []
+ __get_error.restype = c_char_p
+
+ res = __show_diff(commands, path_str, left._get_config(), right._get_config())
+ res = res.decode()
+ if res == "#1@":
+ msg = __get_error().decode()
+ raise ConfigTreeError(msg)
+
+ return res
+
class DiffTree:
def __init__(self, left, right, path=[], libpath=LIBPATH):
if left is None: