summaryrefslogtreecommitdiff
path: root/python/vyos
diff options
context:
space:
mode:
Diffstat (limited to 'python/vyos')
-rw-r--r--python/vyos/config.py15
-rw-r--r--python/vyos/configdict.py5
-rw-r--r--python/vyos/configtree.py62
-rw-r--r--python/vyos/ifconfig/control.py12
-rw-r--r--python/vyos/ifconfig/dhcp.py4
-rw-r--r--python/vyos/ifconfig/interface.py10
-rw-r--r--python/vyos/ifconfig/wireguard.py56
-rw-r--r--python/vyos/ifconfig/wireless.py2
-rw-r--r--python/vyos/ifconfig_vlan.py2
-rw-r--r--python/vyos/interfaces.py65
-rw-r--r--python/vyos/migrator.py11
-rw-r--r--python/vyos/util.py2
12 files changed, 104 insertions, 142 deletions
diff --git a/python/vyos/config.py b/python/vyos/config.py
index 2342f7021..75055a603 100644
--- a/python/vyos/config.py
+++ b/python/vyos/config.py
@@ -238,6 +238,19 @@ class Config(object):
str: working configuration
"""
+ # show_config should be independent of CLI edit level.
+ # Set the CLI edit environment to the top level, and
+ # restore original on exit.
+ save_env = self.__session_env
+
+ env_str = self._run(self._make_command('getEditResetEnv', ''))
+ env_list = re.findall(r'([A-Z_]+)=\'([^;\s]+)\'', env_str)
+ root_env = os.environ
+ for k, v in env_list:
+ root_env[k] = v
+
+ self.__session_env = root_env
+
# FIXUP: by default, showConfig will give you a diff
# if there are uncommitted changes.
# The config parser obviously cannot work with diffs,
@@ -253,8 +266,10 @@ class Config(object):
path = " ".join(path)
try:
out = self._run(self._make_command('showConfig', path))
+ self.__session_env = save_env
return out
except VyOSError:
+ self.__session_env = save_env
return(default)
def get_config_dict(self, path=[], effective=False):
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index 66da52ff3..24fe174d2 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -123,6 +123,7 @@ def vlan_to_dict(conf):
'ip_enable_arp_accept': 0,
'ip_enable_arp_announce': 0,
'ip_enable_arp_ignore': 0,
+ 'ip_proxy_arp': 0,
'ipv6_autoconf': 0,
'ipv6_forwarding': 1,
'ipv6_dup_addr_detect': 1,
@@ -190,6 +191,10 @@ def vlan_to_dict(conf):
if conf.exists('ip enable-arp-ignore'):
vlan['ip_enable_arp_ignore'] = 1
+ # Enable Proxy ARP
+ if conf.exists('ip enable-proxy-arp'):
+ vlan['ip_proxy_arp'] = 1
+
# Enable acquisition of IPv6 address using stateless autoconfig (SLAAC)
if conf.exists('ipv6 address autoconf'):
vlan['ipv6_autoconf'] = 1
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index 0274f3573..a0b0eb3c1 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -24,58 +24,10 @@ def escape_backslash(string: str) -> str:
result = p.sub(r'\\\\', string)
return result
-def strip_comments(s):
- """ Split a config string into the config section and the trailing comments """
- INITIAL = 0
- IN_COMMENT = 1
-
- i = len(s) - 1
-
- state = INITIAL
-
- config_end = 0
-
- # Find the first character of the comments section at the end,
- # if it exists
- while (i >= 0):
- c = s[i]
-
- if (state == INITIAL) and re.match(r'\s', c):
- # Ignore whitespace
- if (i != 0):
- i -= 1
- else:
- config_end = 0
- break
- elif (state == INITIAL) and not re.match(r'(\s|\/)', c):
- # Assume there are no (more) trailing comments,
- # this is an end of a node: either a brace of the last character
- # of a leaf node value
- config_end = i + 1
- break
- elif (state == INITIAL) and (c == '/'):
- # A comment begins, or it's a stray slash
- if (s[i-1] == '*'):
- state = IN_COMMENT
- i -= 2
- else:
- raise ValueError("Invalid syntax: stray slash at character {0}".format(i + 1))
- elif (state == IN_COMMENT) and (c == '*'):
- # A comment ends here
- try:
- if (s[i-1] == '/'):
- state = INITIAL
- i -= 2
- except:
- raise ValueError("Invalid syntax: malformed commend end at character {0}".format(i + 1))
- elif (state == IN_COMMENT) and (c != '*'):
- # Ignore everything inside comments, including braces
- i -= 1
- else:
- # Shouldn't happen
- raise ValueError("Invalid syntax at character {0}: invalid character {1}".format(i + 1, c))
-
- return (s[0:config_end], s[config_end+1:])
+def extract_version(s):
+ """ Extract the version string from the config string """
+ t = re.split('(^//)', s, maxsplit=1, flags=re.MULTILINE)
+ return (s, ''.join(t[1:]))
def check_path(path):
# Necessary type checking
@@ -174,7 +126,7 @@ class ConfigTree(object):
self.__destroy = self.__lib.destroy
self.__destroy.argtypes = [c_void_p]
- config_section, comments_section = strip_comments(config_string)
+ 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:
@@ -182,7 +134,7 @@ class ConfigTree(object):
raise ValueError("Failed to parse config: {0}".format(msg))
else:
self.__config = config
- self.__comments = comments_section
+ self.__version = version_section
def __del__(self):
if self.__config is not None:
@@ -193,7 +145,7 @@ class ConfigTree(object):
def to_string(self):
config_string = self.__to_string(self.__config).decode()
- config_string = "{0}\n{1}".format(config_string, self.__comments)
+ config_string = "{0}\n{1}".format(config_string, self.__version)
return config_string
def to_commands(self):
diff --git a/python/vyos/ifconfig/control.py b/python/vyos/ifconfig/control.py
index 1c9f7e284..c1a073aef 100644
--- a/python/vyos/ifconfig/control.py
+++ b/python/vyos/ifconfig/control.py
@@ -24,8 +24,18 @@ class Control(Register):
_command_get = {}
_command_set = {}
+ def __init__(self, **kargs):
+ # some commands (such as operation comands - show interfaces, etc.)
+ # need to query the interface statistics. If the interface
+ # code is used and the debugging is enabled, the screen output
+ # will include both the command but also the debugging for that command
+ # to prevent this, debugging can be explicitely disabled
+
+ # if debug is not explicitely disabled the the config, enable it
+ self.debug = kargs.get('debug', True)
+
def _debug_msg(self, msg):
- if os.path.isfile('/tmp/vyos.ifconfig.debug'):
+ if os.path.isfile('/tmp/vyos.ifconfig.debug') and self.debug:
print('DEBUG/{:<6} {}'.format(self.config['ifname'], msg))
def _popen(self, command):
diff --git a/python/vyos/ifconfig/dhcp.py b/python/vyos/ifconfig/dhcp.py
index 8d3653433..8ec8263b5 100644
--- a/python/vyos/ifconfig/dhcp.py
+++ b/python/vyos/ifconfig/dhcp.py
@@ -50,7 +50,9 @@ interface "{{ intf }}" {
class DHCP (Control):
client_base = r'/var/lib/dhcp/dhclient_'
- def __init__ (self, ifname):
+ def __init__ (self, ifname, **kargs):
+ super().__init__(**kargs)
+
# per interface DHCP config files
self._dhcp = {
4: {
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 8b41d6158..4a34f96d6 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -162,15 +162,17 @@ class Interface(DHCP):
>>> i = Interface('eth0')
"""
- DHCP.__init__(self, ifname)
-
self.config = deepcopy(self.default)
- self.config['ifname'] = ifname
-
for k in self.options:
if k in kargs:
self.config[k] = kargs[k]
+ # make sure the ifname is the first argument and not from the dict
+ self.config['ifname'] = ifname
+
+ # we must have updated config before initialising the Interface
+ super().__init__(ifname, **kargs)
+
if not os.path.exists('/sys/class/net/{}'.format(self.config['ifname'])):
if not self.config['type']:
raise Exception('interface "{}" not found'.format(self.config['ifname']))
diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py
index 7f123f9b4..def5ab7c5 100644
--- a/python/vyos/ifconfig/wireguard.py
+++ b/python/vyos/ifconfig/wireguard.py
@@ -15,14 +15,15 @@
import os
+import time
+import subprocess
+from datetime import timedelta
-import vyos
+from vyos.config import Config
from vyos.ifconfig.interface import Interface
-from vyos.interfaces import wireguard_dump
-from datetime import timedelta
-import time
from hurry.filesize import size,alternative
+
@Interface.register
class WireGuardIf(Interface):
default = {
@@ -108,10 +109,10 @@ class WireGuardIf(Interface):
return self._cmd(cmd)
def op_show_interface(self):
- wgdump = wireguard_dump().get(
+ wgdump = self._dump().get(
self.config['ifname'], None)
- c = vyos.config.Config()
+ c = Config()
c.set_level(["interfaces", "wireguard", self.config['ifname']])
description = c.return_effective_value(["description"])
ips = c.return_effective_values(["address"])
@@ -177,3 +178,46 @@ class WireGuardIf(Interface):
wgpeer['persistent_keepalive']))
print()
super().op_show_interface_stats()
+
+ def _dump(self):
+ """Dump wireguard data in a python friendly way."""
+ last_device = None
+ output = {}
+
+ # Dump wireguard connection data
+ _f = self._cmd('wg show all dump')
+ for line in _f.split('\n'):
+ if not line:
+ # Skip empty lines and last line
+ continue
+ items = line.split('\t')
+
+ if last_device != items[0]:
+ # We are currently entering a new node
+ device, private_key, public_key, listen_port, fw_mark = items
+ last_device = device
+
+ output[device] = {
+ 'private_key': None if private_key == '(none)' else private_key,
+ 'public_key': None if public_key == '(none)' else public_key,
+ 'listen_port': int(listen_port),
+ 'fw_mark': None if fw_mark == 'off' else int(fw_mark),
+ 'peers': {},
+ }
+ else:
+ # We are entering a peer
+ device, public_key, preshared_key, endpoint, allowed_ips, latest_handshake, transfer_rx, transfer_tx, persistent_keepalive = items
+ if allowed_ips == '(none)':
+ allowed_ips = []
+ else:
+ allowed_ips = allowed_ips.split('\t')
+ output[device]['peers'][public_key] = {
+ 'preshared_key': None if preshared_key == '(none)' else preshared_key,
+ 'endpoint': None if endpoint == '(none)' else endpoint,
+ 'allowed_ips': allowed_ips,
+ 'latest_handshake': None if latest_handshake == '0' else int(latest_handshake),
+ 'transfer_rx': int(transfer_rx),
+ 'transfer_tx': int(transfer_tx),
+ 'persistent_keepalive': None if persistent_keepalive == 'off' else int(persistent_keepalive),
+ }
+ return output
diff --git a/python/vyos/ifconfig/wireless.py b/python/vyos/ifconfig/wireless.py
index 932d07d01..946ae1642 100644
--- a/python/vyos/ifconfig/wireless.py
+++ b/python/vyos/ifconfig/wireless.py
@@ -47,7 +47,7 @@ class WiFiIf(Interface):
self._cmd(cmd)
# wireless interface is administratively down by default
- self.set_state('down')
+ self.set_admin_state('down')
def _delete(self):
cmd = 'iw dev {ifname} del' \
diff --git a/python/vyos/ifconfig_vlan.py b/python/vyos/ifconfig_vlan.py
index 00270cf58..ed22646c1 100644
--- a/python/vyos/ifconfig_vlan.py
+++ b/python/vyos/ifconfig_vlan.py
@@ -64,6 +64,8 @@ def apply_vlan_config(vlan, config):
vlan.set_arp_announce(config['ip_enable_arp_announce'])
# configure ARP ignore
vlan.set_arp_ignore(config['ip_enable_arp_ignore'])
+ # configure Proxy ARP
+ vlan.set_proxy_arp(config['ip_proxy_arp'])
# IPv6 address autoconfiguration
vlan.set_ipv6_autoconf(config['ipv6_autoconf'])
# IPv6 forwarding
diff --git a/python/vyos/interfaces.py b/python/vyos/interfaces.py
deleted file mode 100644
index 4697c0acc..000000000
--- a/python/vyos/interfaces.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2018 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/>.
-
-import re
-import json
-
-from vyos.ifconfig import Interface
-import subprocess
-import netifaces
-
-
-def wireguard_dump():
- """Dump wireguard data in a python friendly way."""
- last_device=None
- output = {}
-
- # Dump wireguard connection data
- _f = subprocess.check_output(["wg", "show", "all", "dump"]).decode()
- for line in _f.split('\n'):
- if not line:
- # Skip empty lines and last line
- continue
- items = line.split('\t')
-
- if last_device != items[0]:
- # We are currently entering a new node
- device, private_key, public_key, listen_port, fw_mark = items
- last_device = device
-
- output[device] = {
- 'private_key': None if private_key == '(none)' else private_key,
- 'public_key': None if public_key == '(none)' else public_key,
- 'listen_port': int(listen_port),
- 'fw_mark': None if fw_mark == 'off' else int(fw_mark),
- 'peers': {},
- }
- else:
- # We are entering a peer
- device, public_key, preshared_key, endpoint, allowed_ips, latest_handshake, transfer_rx, transfer_tx, persistent_keepalive = items
- if allowed_ips == '(none)':
- allowed_ips = []
- else:
- allowed_ips = allowed_ips.split('\t')
- output[device]['peers'][public_key] = {
- 'preshared_key': None if preshared_key == '(none)' else preshared_key,
- 'endpoint': None if endpoint == '(none)' else endpoint,
- 'allowed_ips': allowed_ips,
- 'latest_handshake': None if latest_handshake == '0' else int(latest_handshake),
- 'transfer_rx': int(transfer_rx),
- 'transfer_tx': int(transfer_tx),
- 'persistent_keepalive': None if persistent_keepalive == 'off' else int(persistent_keepalive),
- }
- return output
diff --git a/python/vyos/migrator.py b/python/vyos/migrator.py
index f05228041..9a5fdef2f 100644
--- a/python/vyos/migrator.py
+++ b/python/vyos/migrator.py
@@ -25,7 +25,7 @@ class MigratorError(Exception):
pass
class Migrator(object):
- def __init__(self, config_file, force=False, set_vintage=None):
+ def __init__(self, config_file, force=False, set_vintage='vyos'):
self._config_file = config_file
self._force = force
self._set_vintage = set_vintage
@@ -61,9 +61,6 @@ class Migrator(object):
if self._set_vintage:
self._config_file_vintage = self._set_vintage
- if not self._config_file_vintage:
- self._config_file_vintage = vyos.defaults.cfg_vintage
-
if self._config_file_vintage not in ['vyatta', 'vyos']:
raise MigratorError("Unknown vintage.")
@@ -204,16 +201,12 @@ class Migrator(object):
return self._changed
class VirtualMigrator(Migrator):
- def __init__(self, config_file, vintage='vyos'):
- super().__init__(config_file, set_vintage = vintage)
-
def run(self):
cfg_file = self._config_file
cfg_versions = self.read_config_file_versions()
if not cfg_versions:
- raise MigratorError("Config file has no version information;"
- " virtual migration not possible.")
+ return
if self.update_vintage():
self._changed = True
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 635b11ee5..67aa87a3a 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -84,6 +84,8 @@ def colon_separated_to_dict(data_string, uniquekeys=False):
def process_running(pid_file):
""" Checks if a process with PID in pid_file is running """
+ if not os.path.isfile(pid_file):
+ return False
with open(pid_file, 'r') as f:
pid = f.read().strip()
return psutil.pid_exists(int(pid))