summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/configquery.py90
-rw-r--r--python/vyos/configverify.py2
-rw-r--r--python/vyos/ifconfig/bridge.py6
-rw-r--r--python/vyos/ifconfig/interface.py18
-rw-r--r--python/vyos/util.py15
5 files changed, 129 insertions, 2 deletions
diff --git a/python/vyos/configquery.py b/python/vyos/configquery.py
new file mode 100644
index 000000000..ed7346f1f
--- /dev/null
+++ b/python/vyos/configquery.py
@@ -0,0 +1,90 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# 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/>.
+
+'''
+A small library that allows querying existence or value(s) of config
+settings from op mode, and execution of arbitrary op mode commands.
+'''
+
+from subprocess import STDOUT
+from vyos.util import popen
+
+
+class ConfigQueryError(Exception):
+ pass
+
+class GenericConfigQuery:
+ def __init__(self):
+ pass
+
+ def exists(self, path: list):
+ raise NotImplementedError
+
+ def value(self, path: list):
+ raise NotImplementedError
+
+ def values(self, path: list):
+ raise NotImplementedError
+
+class GenericOpRun:
+ def __init__(self):
+ pass
+
+ def run(self, path: list, **kwargs):
+ raise NotImplementedError
+
+class CliShellApiConfigQuery(GenericConfigQuery):
+ def __init__(self):
+ super().__init__()
+
+ def exists(self, path: list):
+ cmd = ' '.join(path)
+ (_, err) = popen(f'cli-shell-api existsActive {cmd}')
+ if err:
+ return False
+ return True
+
+ def value(self, path: list):
+ cmd = ' '.join(path)
+ (out, err) = popen(f'cli-shell-api returnActiveValue {cmd}')
+ if err:
+ raise ConfigQueryError('No value for given path')
+ return out
+
+ def values(self, path: list):
+ cmd = ' '.join(path)
+ (out, err) = popen(f'cli-shell-api returnActiveValues {cmd}')
+ if err:
+ raise ConfigQueryError('No values for given path')
+ return out
+
+class VbashOpRun(GenericOpRun):
+ def __init__(self):
+ super().__init__()
+
+ def run(self, path: list, **kwargs):
+ cmd = ' '.join(path)
+ (out, err) = popen(f'. /opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run; _vyatta_op_run {cmd}', stderr=STDOUT, **kwargs)
+ if err:
+ raise ConfigQueryError(out)
+ return out
+
+def query_context(config_query_class=CliShellApiConfigQuery,
+ op_run_class=VbashOpRun):
+ query = config_query_class()
+ run = op_run_class()
+ return query, run
+
+
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index 7cf2cb8f9..718b7445d 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -80,7 +80,7 @@ def verify_vrf(config):
recurring validation of VRF configuration.
"""
from netifaces import interfaces
- if 'vrf' in config:
+ if 'vrf' in config and config['vrf'] != 'default':
if config['vrf'] not in interfaces():
raise ConfigError('VRF "{vrf}" does not exist'.format(**config))
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index 600bd3db8..14f64a8de 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -312,9 +312,15 @@ class BridgeIf(Interface):
# not have any addresses configured by CLI so just flush any
# remaining ones
lower.flush_addrs()
+
# 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)
+
# set bridge port path cost
if 'cost' in interface_config:
value = interface_config.get('cost')
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index fe6a3c95e..5a1605a18 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -113,6 +113,10 @@ class Interface(Control):
'convert': lambda name: name if name else '',
'shellcmd': 'ip link set dev {ifname} alias "{value}"',
},
+ 'bridge_port_isolation': {
+ 'validate': lambda v: assert_list(v, ['on', 'off']),
+ 'shellcmd': 'bridge link set dev {ifname} isolated {value}',
+ },
'mac': {
'validate': assert_mac,
'shellcmd': 'ip link set dev {ifname} address {value}',
@@ -689,6 +693,20 @@ class Interface(Control):
"""
self.set_interface('path_priority', priority)
+ def set_port_isolation(self, on_or_off):
+ """
+ Controls whether a given port will be isolated, which means it will be
+ able to communicate with non-isolated ports only. By default this flag
+ is off.
+
+ Use enable=1 to enable or enable=0 to disable
+
+ Example:
+ >>> from vyos.ifconfig import Interface
+ >>> Interface('eth1').set_port_isolation('on')
+ """
+ self.set_interface('bridge_port_isolation', on_or_off)
+
def set_proxy_arp(self, enable):
"""
Set per interface proxy ARP configuration
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 17a7dda91..e4de56cdb 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -646,7 +646,7 @@ def dict_search(path, dict):
c = c.get(p, {})
return c.get(parts[-1], None)
-def get_json_iface_options(interface):
+def get_interface_config(interface):
""" Returns the used encapsulation protocol for given interface.
If interface does not exist, None is returned.
"""
@@ -655,3 +655,16 @@ def get_json_iface_options(interface):
from json import loads
tmp = loads(cmd(f'ip -d -j link show {interface}'))[0]
return tmp
+
+def get_all_vrfs():
+ """ Return a dictionary of all system wide known VRF instances """
+ from json import loads
+ tmp = loads(cmd('ip -j vrf list'))
+ # Result is of type [{"name":"red","table":1000},{"name":"blue","table":2000}]
+ # so we will re-arrange it to a more nicer representation:
+ # {'red': {'table': 1000}, 'blue': {'table': 2000}}
+ data = {}
+ for entry in tmp:
+ name = entry.pop('name')
+ data[name] = entry
+ return data