summaryrefslogtreecommitdiff
path: root/python/vyos
diff options
context:
space:
mode:
Diffstat (limited to 'python/vyos')
-rw-r--r--python/vyos/configtree.py65
-rw-r--r--python/vyos/configverify.py2
-rw-r--r--python/vyos/ethtool.py2
-rw-r--r--python/vyos/ifconfig/bridge.py12
-rw-r--r--python/vyos/ifconfig/wireless.py6
-rw-r--r--python/vyos/migrator.py2
-rw-r--r--python/vyos/systemversions.py7
-rw-r--r--python/vyos/util.py9
-rw-r--r--python/vyos/xml/__init__.py4
-rw-r--r--python/vyos/xml/definition.py9
10 files changed, 88 insertions, 30 deletions
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index d8ffaca99..866f24e47 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -15,8 +15,9 @@
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, POINTER
+LIBPATH = '/usr/lib/libvyosconfig.so.0'
def escape_backslash(string: str) -> str:
"""Escape single backslashes in string that are not in escape sequence"""
@@ -42,7 +43,9 @@ class ConfigTreeError(Exception):
class ConfigTree(object):
- def __init__(self, config_string, libpath='/usr/lib/libvyosconfig.so.0'):
+ def __init__(self, config_string=None, address=None, libpath=LIBPATH):
+ if config_string is None and address is None:
+ raise TypeError("ConfigTree() requires one of 'config_string' or 'address'")
self.__config = None
self.__lib = cdll.LoadLibrary(libpath)
@@ -60,7 +63,7 @@ class ConfigTree(object):
self.__to_string.restype = c_char_p
self.__to_commands = self.__lib.to_commands
- self.__to_commands.argtypes = [c_void_p]
+ self.__to_commands.argtypes = [c_void_p, c_char_p]
self.__to_commands.restype = c_char_p
self.__to_json = self.__lib.to_json
@@ -126,15 +129,19 @@ class ConfigTree(object):
self.__destroy = self.__lib.destroy
self.__destroy.argtypes = [c_void_p]
- config_section, version_section = extract_version(config_string)
- config_section = escape_backslash(config_section)
- config = self.__from_string(config_section.encode())
- if config is None:
- msg = self.__get_error().decode()
- raise ValueError("Failed to parse config: {0}".format(msg))
+ if address is None:
+ config_section, version_section = extract_version(config_string)
+ config_section = escape_backslash(config_section)
+ config = self.__from_string(config_section.encode())
+ if config is None:
+ msg = self.__get_error().decode()
+ raise ValueError("Failed to parse config: {0}".format(msg))
+ else:
+ self.__config = config
+ self.__version = version_section
else:
- self.__config = config
- self.__version = version_section
+ self.__config = address
+ self.__version = ''
def __del__(self):
if self.__config is not None:
@@ -143,13 +150,16 @@ class ConfigTree(object):
def __str__(self):
return self.to_string()
+ def _get_config(self):
+ return self.__config
+
def to_string(self):
config_string = self.__to_string(self.__config).decode()
config_string = "{0}\n{1}".format(config_string, self.__version)
return config_string
- def to_commands(self):
- return self.__to_commands(self.__config).decode()
+ def to_commands(self, op="set"):
+ return self.__to_commands(self.__config, op.encode()).decode()
def to_json(self):
return self.__to_json(self.__config).decode()
@@ -281,3 +291,32 @@ class ConfigTree(object):
else:
raise ConfigTreeError("Path [{}] doesn't exist".format(path_str))
+class Diff:
+ def __init__(self, left, right, path=[], libpath=LIBPATH):
+ if not (isinstance(left, ConfigTree) and isinstance(right, ConfigTree)):
+ raise TypeError("Arguments must be instances of ConfigTree")
+ if path:
+ if not left.exists(path):
+ raise ConfigTreeError(f"Path {path} doesn't exist in lhs tree")
+ if not right.exists(path):
+ raise ConfigTreeError(f"Path {path} doesn't exist in rhs tree")
+ self.left = left
+ self.right = right
+
+ check_path(path)
+ path_str = " ".join(map(str, path)).encode()
+ df = cdll.LoadLibrary(libpath).diffs
+ df.restype = POINTER(c_void_p * 3)
+ res = list(df(path_str, left._get_config(), right._get_config()).contents)
+ self._diff = {'add': ConfigTree(address=res[0]),
+ 'del': ConfigTree(address=res[1]),
+ 'int': ConfigTree(address=res[2]) }
+
+ self.add = self._diff['add']
+ self.delete = self._diff['del']
+ self.inter = self._diff['int']
+
+ def to_commands(self):
+ add = self.add.to_commands()
+ delete = self.delete.to_commands(op="delete")
+ return delete + "\n" + add
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index 365a28feb..18fb7f9f7 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -173,7 +173,7 @@ def verify_eapol(config):
if ca_cert_name not in config['pki']['ca']:
raise ConfigError('Invalid CA certificate specified for EAPoL')
- ca_cert = config['pki']['ca'][cert_name]
+ ca_cert = config['pki']['ca'][ca_cert_name]
if 'certificate' not in ca_cert:
raise ConfigError('Invalid CA certificate specified for EAPoL')
diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index e45b0f041..80d44eee6 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -41,7 +41,7 @@ class Ethtool:
# '100' : {'full': '', 'half': ''},
# '1000': {'full': ''}
# }
- _speed_duplex = { }
+ _speed_duplex = {'auto': {'auto': ''}}
_ring_buffers = { }
_ring_buffers_max = { }
_driver_name = None
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index 27073b266..ffd9c590f 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -298,7 +298,6 @@ class BridgeIf(Interface):
tmp = dict_search('member.interface', config)
if tmp:
-
for interface, interface_config in tmp.items():
# if interface does yet not exist bail out early and
# add it later
@@ -316,10 +315,13 @@ class BridgeIf(Interface):
# enslave interface port to bridge
self.add_port(interface)
- # always set private-vlan/port isolation
- tmp = dict_search('isolated', interface_config)
- value = 'on' if (tmp != None) else 'off'
- lower.set_port_isolation(value)
+ if not interface.startswith('wlan'):
+ # always set private-vlan/port isolation - this can not be
+ # done when lower link is a wifi link, as it will trigger:
+ # RTNETLINK answers: Operation not supported
+ tmp = dict_search('isolated', interface_config)
+ value = 'on' if (tmp != None) else 'off'
+ lower.set_port_isolation(value)
# set bridge port path cost
if 'cost' in interface_config:
diff --git a/python/vyos/ifconfig/wireless.py b/python/vyos/ifconfig/wireless.py
index 748b6e02d..88eaa772b 100644
--- a/python/vyos/ifconfig/wireless.py
+++ b/python/vyos/ifconfig/wireless.py
@@ -49,10 +49,10 @@ class WiFiIf(Interface):
on any interface. """
# We can not call add_to_bridge() until wpa_supplicant is running, thus
- # we will remove the key from the config dict and react to this specal
- # case in thie derived class.
+ # we will remove the key from the config dict and react to this special
+ # case in this derived class.
# re-add ourselves to any bridge we might have fallen out of
- bridge_member = ''
+ bridge_member = None
if 'is_bridge_member' in config:
bridge_member = config['is_bridge_member']
del config['is_bridge_member']
diff --git a/python/vyos/migrator.py b/python/vyos/migrator.py
index 4574bb6d1..a2e0daabd 100644
--- a/python/vyos/migrator.py
+++ b/python/vyos/migrator.py
@@ -195,7 +195,7 @@ class Migrator(object):
# This will force calling all migration scripts:
cfg_versions = {}
- sys_versions = systemversions.get_system_versions()
+ sys_versions = systemversions.get_system_component_version()
# save system component versions in json file for easy reference
self.save_json_record(sys_versions)
diff --git a/python/vyos/systemversions.py b/python/vyos/systemversions.py
index 9b3f4f413..f2da76d4f 100644
--- a/python/vyos/systemversions.py
+++ b/python/vyos/systemversions.py
@@ -17,7 +17,10 @@ import os
import re
import sys
import vyos.defaults
+from vyos.xml import component_version
+# legacy version, reading from the file names in
+# /opt/vyatta/etc/config-migrate/current
def get_system_versions():
"""
Get component versions from running system; critical failure if
@@ -37,3 +40,7 @@ def get_system_versions():
system_versions[pair[0]] = int(pair[1])
return system_versions
+
+# read from xml cache
+def get_system_component_version():
+ return component_version()
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 571d43754..1767ff9d3 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -997,3 +997,12 @@ def boot_configuration_complete() -> bool:
if os.path.isfile(config_status):
return True
return False
+
+def sysctl(name, value):
+ """ Change value via sysctl() - return True if changed, False otherwise """
+ tmp = cmd(f'sysctl {name}')
+ # last list index contains the actual value - only write if value differs
+ if tmp.split()[-1] != str(value):
+ call(f'sysctl -wq {name}={value}')
+ return True
+ return False
diff --git a/python/vyos/xml/__init__.py b/python/vyos/xml/__init__.py
index e0eacb2d1..6db446a40 100644
--- a/python/vyos/xml/__init__.py
+++ b/python/vyos/xml/__init__.py
@@ -46,8 +46,8 @@ def is_tag(lpath):
def is_leaf(lpath, flat=True):
return load_configuration().is_leaf(lpath, flat)
-def component_versions():
- return load_configuration().component_versions()
+def component_version():
+ return load_configuration().component_version()
def defaults(lpath, flat=False):
return load_configuration().defaults(lpath, flat)
diff --git a/python/vyos/xml/definition.py b/python/vyos/xml/definition.py
index 5e0d5282c..bc3892b42 100644
--- a/python/vyos/xml/definition.py
+++ b/python/vyos/xml/definition.py
@@ -249,10 +249,11 @@ class XML(dict):
# @lru_cache(maxsize=100)
# XXX: need to use cachetool instead - for later
- def component_versions(self) -> dict:
- sort_component = sorted(self[kw.component_version].items(),
- key = lambda kv: kv[0])
- return dict(sort_component)
+ def component_version(self) -> dict:
+ d = {}
+ for k in sorted(self[kw.component_version]):
+ d[k] = int(self[kw.component_version][k])
+ return d
def defaults(self, lpath, flat):
d = self[kw.default]