summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/config_mgmt.py34
-rw-r--r--python/vyos/configtree.py13
-rw-r--r--python/vyos/ifconfig/interface.py8
-rw-r--r--python/vyos/util.py11
-rw-r--r--python/vyos/validate.py4
-rw-r--r--python/vyos/xml_ref/__init__.py3
-rw-r--r--python/vyos/xml_ref/definition.py25
7 files changed, 71 insertions, 27 deletions
diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py
index fade3081c..57563a9c1 100644
--- a/python/vyos/config_mgmt.py
+++ b/python/vyos/config_mgmt.py
@@ -26,6 +26,7 @@ from tabulate import tabulate
from vyos.config import Config
from vyos.configtree import ConfigTree, ConfigTreeError, show_diff
from vyos.defaults import directories
+from vyos.version import get_full_version_data
from vyos.util import is_systemd_service_active, ask_yes_no, rc_cmd
SAVE_CONFIG = '/opt/vyatta/sbin/vyatta-save-config.pl'
@@ -56,6 +57,21 @@ formatter = logging.Formatter('%(funcName)s: %(levelname)s:%(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)
+def save_config(target):
+ cmd = f'{SAVE_CONFIG} {target}'
+ rc, out = rc_cmd(cmd)
+ if rc != 0:
+ logger.critical(f'save config failed: {out}')
+
+def unsaved_commits() -> bool:
+ if get_full_version_data()['boot_via'] == 'livecd':
+ return False
+ tmp_save = '/tmp/config.running'
+ save_config(tmp_save)
+ ret = not cmp(tmp_save, config_file, shallow=False)
+ os.unlink(tmp_save)
+ return ret
+
class ConfigMgmtError(Exception):
pass
@@ -98,20 +114,6 @@ class ConfigMgmt:
self.active_config = config._running_config
self.working_config = config._session_config
- @staticmethod
- def save_config(target):
- cmd = f'{SAVE_CONFIG} {target}'
- rc, out = rc_cmd(cmd)
- if rc != 0:
- logger.critical(f'save config failed: {out}')
-
- def _unsaved_commits(self) -> bool:
- tmp_save = '/tmp/config.boot.check-save'
- self.save_config(tmp_save)
- ret = not cmp(tmp_save, config_file, shallow=False)
- os.unlink(tmp_save)
- return ret
-
# Console script functions
#
def commit_confirm(self, minutes: int=DEFAULT_TIME_MINUTES,
@@ -123,7 +125,7 @@ class ConfigMgmt:
msg = 'Another confirm is pending'
return msg, 1
- if self._unsaved_commits():
+ if unsaved_commits():
W = '\nYou should save previous commits before commit-confirm !\n'
else:
W = ''
@@ -450,7 +452,7 @@ Proceed ?'''
ext = os.getpid()
tmp_save = f'/tmp/config.boot.{ext}'
- self.save_config(tmp_save)
+ save_config(tmp_save)
try:
if cmp(tmp_save, archive_config_file, shallow=False):
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index 19b9838d4..d0cd87464 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -201,7 +201,9 @@ class ConfigTree(object):
check_path(path)
path_str = " ".join(map(str, path)).encode()
- self.__delete(self.__config, path_str)
+ res = self.__delete(self.__config, path_str)
+ if (res != 0):
+ raise ConfigTreeError(f"Path doesn't exist: {path}")
if self.__migration:
print(f"- op: delete path: {path}")
@@ -210,7 +212,14 @@ class ConfigTree(object):
check_path(path)
path_str = " ".join(map(str, path)).encode()
- self.__delete_value(self.__config, path_str, value.encode())
+ res = self.__delete_value(self.__config, path_str, value.encode())
+ if (res != 0):
+ if res == 1:
+ raise ConfigTreeError(f"Path doesn't exist: {path}")
+ elif res == 2:
+ raise ConfigTreeError(f"Value doesn't exist: '{value}'")
+ else:
+ raise ConfigTreeError()
if self.__migration:
print(f"- op: delete_value path: {path} value: {value}")
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index f62b9f7d2..7754488c4 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -57,6 +57,8 @@ from vyos.ifconfig import Section
from netaddr import EUI
from netaddr import mac_unix_expanded
+link_local_prefix = 'fe80::/64'
+
class Interface(Control):
# This is the class which will be used to create
# self.operational, it allows subclasses, such as
@@ -1444,7 +1446,7 @@ class Interface(Control):
# we will delete all interface specific IP addresses if they are not
# explicitly configured on the CLI
if is_ipv6_link_local(addr):
- eui64 = mac2eui64(self.get_mac(), 'fe80::/64')
+ eui64 = mac2eui64(self.get_mac(), link_local_prefix)
if addr != f'{eui64}/64':
self.del_addr(addr)
else:
@@ -1571,9 +1573,9 @@ class Interface(Control):
# Manage IPv6 link-local addresses
if dict_search('ipv6.address.no_default_link_local', config) != None:
- self.del_ipv6_eui64_address('fe80::/64')
+ self.del_ipv6_eui64_address(link_local_prefix)
else:
- self.add_ipv6_eui64_address('fe80::/64')
+ self.add_ipv6_eui64_address(link_local_prefix)
# Add IPv6 EUI-based addresses
tmp = dict_search('ipv6.address.eui64', config)
diff --git a/python/vyos/util.py b/python/vyos/util.py
index d5330db13..61ce59324 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -463,14 +463,17 @@ def process_running(pid_file):
pid = f.read().strip()
return pid_exists(int(pid))
-def process_named_running(name):
+def process_named_running(name, cmdline: str=None):
""" Checks if process with given name is running and returns its PID.
If Process is not running, return None
"""
from psutil import process_iter
- for p in process_iter():
- if name in p.name():
- return p.pid
+ for p in process_iter(['name', 'pid', 'cmdline']):
+ if cmdline:
+ if p.info['name'] == name and cmdline in p.info['cmdline']:
+ return p.info['pid']
+ elif p.info['name'] == name:
+ return p.info['pid']
return None
def is_list_equal(first: list, second: list) -> bool:
diff --git a/python/vyos/validate.py b/python/vyos/validate.py
index a83193363..d18785aaf 100644
--- a/python/vyos/validate.py
+++ b/python/vyos/validate.py
@@ -62,7 +62,7 @@ def is_intf_addr_assigned(intf, address) -> bool:
# 10: [{'addr': 'fe80::a00:27ff:fed9:5b04%eth0', 'netmask': 'ffff:ffff:ffff:ffff::'}]
# }
try:
- ifaces = ifaddresses(intf)
+ addresses = ifaddresses(intf)
except ValueError as e:
print(e)
return False
@@ -74,7 +74,7 @@ def is_intf_addr_assigned(intf, address) -> bool:
netmask = None
if '/' in address:
address, netmask = address.split('/')
- for ip in ifaces.get(addr_type,[]):
+ for ip in addresses.get(addr_type, []):
# ip can have the interface name in the 'addr' field, we need to remove it
# {'addr': 'fe80::a00:27ff:fec5:f821%eth2', 'netmask': 'ffff:ffff:ffff:ffff::'}
ip_addr = ip['addr'].split('%')[0]
diff --git a/python/vyos/xml_ref/__init__.py b/python/vyos/xml_ref/__init__.py
index ae5184746..2e144ef10 100644
--- a/python/vyos/xml_ref/__init__.py
+++ b/python/vyos/xml_ref/__init__.py
@@ -45,6 +45,9 @@ def is_valueless(path: list) -> bool:
def is_leaf(path: list) -> bool:
return load_reference().is_leaf(path)
+def cli_defined(path: list, node: str, non_local=False) -> bool:
+ return load_reference().cli_defined(path, node, non_local=non_local)
+
def component_version() -> dict:
return load_reference().component_version()
diff --git a/python/vyos/xml_ref/definition.py b/python/vyos/xml_ref/definition.py
index 429331577..95ecc01a6 100644
--- a/python/vyos/xml_ref/definition.py
+++ b/python/vyos/xml_ref/definition.py
@@ -92,6 +92,31 @@ class Xml:
d = self._get_ref_path(path)
return self._is_leaf_node(d)
+ @staticmethod
+ def _dict_get(d: dict, path: list) -> dict:
+ for i in path:
+ d = d.get(i, {})
+ if not isinstance(d, dict):
+ return {}
+ if not d:
+ break
+ return d
+
+ def _dict_find(self, d: dict, key: str, non_local=False) -> bool:
+ for k in list(d):
+ if k in ('node_data', 'component_version'):
+ continue
+ if k == key:
+ return True
+ if non_local and isinstance(d[k], dict):
+ if self._dict_find(d[k], key):
+ return True
+ return False
+
+ def cli_defined(self, path: list, node: str, non_local=False) -> bool:
+ d = self._dict_get(self.ref, path)
+ return self._dict_find(d, node, non_local=non_local)
+
def component_version(self) -> dict:
d = {}
for k, v in self.ref['component_version']: