From 1582681f7ab7a8fc58eb9e6fc508f7c69a5120df Mon Sep 17 00:00:00 2001 From: zsdc Date: Tue, 8 Oct 2019 19:49:36 +0300 Subject: [BGP] T1490: Added migration for obsoleted 'bgp scan-time' parameter --- src/migration-scripts/quagga/3-to-4 | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/migration-scripts/quagga/3-to-4 diff --git a/src/migration-scripts/quagga/3-to-4 b/src/migration-scripts/quagga/3-to-4 new file mode 100644 index 000000000..f8c87ce8c --- /dev/null +++ b/src/migration-scripts/quagga/3-to-4 @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# + +import sys + +from vyos.configtree import ConfigTree + + +if (len(sys.argv) < 1): + print("Must specify file name!") + sys.exit(1) + +file_name = sys.argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) + +if not config.exists(['protocols', 'bgp']): + # Nothing to do + sys.exit(0) +else: + # Check if BGP is actually configured and obtain the ASN + asn_list = config.list_nodes(['protocols', 'bgp']) + if asn_list: + # There's always just one BGP node, if any + asn = asn_list[0] + else: + # There's actually no BGP, just its empty shell + sys.exit(0) + + # Check if BGP scan-time parameter exist + scan_time_param = ['protocols', 'bgp', asn, 'parameters', 'scan-time'] + if config.exists(scan_time_param): + # Delete BGP scan-time parameter + config.delete(scan_time_param) + else: + # Do nothing + sys.exit(0) + + # Save a new configuration file + try: + with open(file_name, 'w') as f: + f.write(config.to_string()) + except OSError as e: + print("Failed to save the modified config: {}".format(e)) + sys.exit(1) -- cgit v1.2.3 From 64163806044bed98fcb68b46340e767deb0c8acc Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 13 Oct 2019 18:07:23 +0200 Subject: ssh.py: check if file exists before deleting it --- src/conf_mode/ssh.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py index 2a5cba99a..e3b11b537 100755 --- a/src/conf_mode/ssh.py +++ b/src/conf_mode/ssh.py @@ -267,7 +267,8 @@ def apply(ssh): else: # SSH access is removed in the commit os.system("sudo systemctl stop ssh.service") - os.unlink(config_file) + if os.path.isfile(config_file): + os.unlink(config_file) return None -- cgit v1.2.3 From 00adf5c48f4c29884d56d85c9ad24a2ca5b82444 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 13 Oct 2019 19:15:40 +0200 Subject: openvpn: T1548: clean out import statements --- src/conf_mode/interfaces-openvpn.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index 5345bf7a2..cdd133904 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -16,11 +16,11 @@ import os import re -import sys -import stat -import jinja2 +from jinja2 import Template from copy import deepcopy +from sys import exit +from stat import S_IRUSR,S_IRWXU,S_IRGRP,S_IXGRP,S_IROTH,S_IXOTH from grp import getgrnam from ipaddress import ip_address,ip_network,IPv4Interface from netifaces import interfaces @@ -331,12 +331,12 @@ def openvpn_mkdir(directory): os.mkdir(directory) # fix permissions - corresponds to mode 755 - os.chmod(directory, stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH) + os.chmod(directory, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) uid = getpwnam(user).pw_uid gid = getgrnam(group).gr_gid os.chown(directory, uid, gid) -def fixup_permission(filename, permission=stat.S_IRUSR): +def fixup_permission(filename, permission=S_IRUSR): """ Check if the given file exists and change ownershit to root/vyattacfg and appripriate file access permissions - default is user and group readable @@ -737,7 +737,7 @@ def verify(openvpn): if openvpn['shared_secret_file']: if openvpn['encryption'] in ['aes128gcm', 'aes192gcm', 'aes256gcm']: raise ConfigError('GCM encryption with shared-secret-key-file is not supported') - + if not checkCertHeader('-----BEGIN OpenVPN Static key V1-----', openvpn['shared_secret_file']): raise ConfigError('Specified shared-secret-key-file "{}" is not valid'.format(openvpn['shared_secret_file'])) @@ -851,13 +851,13 @@ def generate(openvpn): # Generate client specific configuration for client in openvpn['client']: client_file = directory + '/ccd/' + interface + '/' + client['name'] - tmpl = jinja2.Template(client_tmpl) + tmpl = Template(client_tmpl) client_text = tmpl.render(client) with open(client_file, 'w') as f: f.write(client_text) os.chown(client_file, uid, gid) - tmpl = jinja2.Template(config_tmpl) + tmpl = Template(config_tmpl) config_text = tmpl.render(openvpn) # we need to support quoting of raw parameters from OpenVPN CLI @@ -957,4 +957,4 @@ if __name__ == '__main__': apply(c) except ConfigError as e: print(e) - sys.exit(1) + exit(1) -- cgit v1.2.3 From 069f7e5a8431f95d7316a0da682e962f6eb1320a Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 13 Oct 2019 19:55:25 +0200 Subject: Revert "snmpd: T1705 - High CPU usage by bgpd when snmp is active" Systems not runing BGP won't boot anymore. Syslog shows: snmpd[5404]: getaddrinfo: inetCidrRouteTable Name or service not known snmpd[5404]: getaddrinfo("inetCidrRouteTable", NULL, ...): Name or service not known snmpd[5404]: Error opening specified endpoint "inetCidrRouteTable" snmpd[5404]: Server Exiting with code 1 snmpd[5401]: Starting SNMP services:: systemd[1]: snmpd.service: control process exited, code=exited status=1 systemd[1]: Failed to start LSB: SNMP agents. systemd[1]: Unit snmpd.service entered failed state. This reverts commit e45648cdd5a52569be7f3ac30473b0c7474a7894. --- src/conf_mode/snmp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index 60e4c343d..0ddab2129 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -224,7 +224,7 @@ init_config_tmpl = """ SNMPDRUN=yes # snmpd options (use syslog, close stdin/out/err). -SNMPDOPTS='-LSed -u snmp -g snmp -I -ipCidrRouteTable, inetCidrRouteTable -p /run/snmpd.pid' +SNMPDOPTS='-LSed -u snmp -g snmp -p /run/snmpd.pid' """ default_config_data = { -- cgit v1.2.3 From 50acd442ade9a4e447269eaf94ce14d354af8d0c Mon Sep 17 00:00:00 2001 From: hagbard Date: Tue, 15 Oct 2019 08:53:45 -0700 Subject: snmpd: T1705 - High CPU usage by bgpd when snmp is active * typo fixed --- src/conf_mode/snmp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index 0ddab2129..cba1fe319 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -224,7 +224,7 @@ init_config_tmpl = """ SNMPDRUN=yes # snmpd options (use syslog, close stdin/out/err). -SNMPDOPTS='-LSed -u snmp -g snmp -p /run/snmpd.pid' +SNMPDOPTS='-LSed -u snmp -g snmp -I -ipCidrRouteTable,inetCidrRouteTable -p /run/snmpd.pid' """ default_config_data = { -- cgit v1.2.3 From 71a2b2502a2e44d45fa34b87b7fff85ee1975ba0 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 16 Oct 2019 07:46:47 +0200 Subject: Revert "Python/ifconfig: T1712: wait when changing interface state" This reverts commit 1257d7851866d42287018b38dd871f279b87286a. It will delay network interface configuration everywhere when e.g. no network cable is plugged in. We should find the root cause why DHCPd sometimes did not start. --- python/vyos/ifconfig.py | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index 3225971ef..0692f77f3 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -71,7 +71,6 @@ class Interface: >>> i = Interface('eth0') """ self._ifname = str(ifname) - self._statechange_wait = True if not os.path.exists('/sys/class/net/{}'.format(ifname)) and not type: raise Exception('interface "{}" not found'.format(self._ifname)) @@ -320,22 +319,7 @@ class Interface: # Assemble command executed on system. Unfortunately there is no way # to up/down an interface via sysfs cmd = 'ip link set dev {} {}'.format(self._ifname, state) - tmp = self._cmd(cmd) - - if self._statechange_wait: - # better safe then sorry - wait until the interface is really up - # but only for a given period of time to avoid potential deadlocks! - cnt = 0 - while self.get_state() != state: - cnt += 1 - if cnt == 50: - print('Interface {} could not be brought up in time ...'.format(self._ifname)) - break - - # sleep 250ms - sleep(0.250) - - return tmp + return self._cmd(cmd) def set_proxy_arp(self, enable): """ @@ -1408,7 +1392,6 @@ class WireGuardIf(Interface): def __init__(self, ifname): super().__init__(ifname, type='wireguard') - self._statechange_wait = False self.config = { 'port': 0, -- cgit v1.2.3 From 7f9dceaa7898d6418edcdf148b52b66ccd3bd36a Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 17 Oct 2019 20:21:54 +0200 Subject: snmp: T1737: add missing completion helpers --- interface-definitions/snmp.xml | 44 +++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/interface-definitions/snmp.xml b/interface-definitions/snmp.xml index 8b2fa8a93..1634bfb64 100644 --- a/interface-definitions/snmp.xml +++ b/interface-definitions/snmp.xml @@ -21,6 +21,9 @@ Authorization type (default: 'ro') + + ro rw + ro read only @@ -193,6 +196,9 @@ Define group access permission (default: 'ro') + + ro rw + ro read only @@ -210,6 +216,9 @@ Security levels + + noauth auth priv2 + noauth Messages not authenticated and not encrypted (noAuthNoPriv) @@ -280,6 +289,9 @@ Defines the protocol used for authentication (default: 'md5') + + md5 sha + md5 Message Digest 5 @@ -343,6 +355,9 @@ Defines the protocol for privacy (default: 'des') + + des aes + des Data Encryption Standard @@ -361,6 +376,9 @@ Defines protocol for notification between TCP and UDP + + tcp udp + tcp Use Transmission Control Protocol for notifications @@ -377,6 +395,9 @@ Specifies the type of notification between inform and trap (default: 'inform') + + inform trap + inform Use INFORM @@ -464,6 +485,9 @@ Defines the protocol used for authentication (default: 'md5') + + md5 sha + md5 Message Digest 5 @@ -499,6 +523,9 @@ Define users access permission (default: 'ro') + + ro rw + ro read only @@ -539,6 +566,9 @@ Defines the protocol for privacy (default: 'des') + + des aes + des Data Encryption Standard @@ -610,13 +640,13 @@ - - Script location and name - - - - - + + Script location and name + + + + + -- cgit v1.2.3 From e4424dce0d387c5f9e9a710369cd5136fcd63c77 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 17 Oct 2019 22:05:12 +0200 Subject: bgp: T1490: fix migrator file permissions --- src/migration-scripts/quagga/3-to-4 | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/migration-scripts/quagga/3-to-4 diff --git a/src/migration-scripts/quagga/3-to-4 b/src/migration-scripts/quagga/3-to-4 old mode 100644 new mode 100755 -- cgit v1.2.3 From ca4f0dc76f918323c69905399a2dba9b2a21a8ec Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 18 Oct 2019 18:05:46 +0200 Subject: Python/ifconfig: T1557: get_status() must use admin state not operstate --- python/vyos/ifconfig.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index 0692f77f3..1ffa10978 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -16,6 +16,7 @@ import os import re import jinja2 +import json from vyos.validate import * from ipaddress import IPv4Network, IPv6Address @@ -116,7 +117,7 @@ class Interface: self._debug_msg("returned:\n{}".format(tmp.decode())) # do we need some error checking code here? - return tmp + return tmp.decode() def _read_sysfs(self, filename): """ @@ -300,8 +301,10 @@ class Interface: >>> Interface('eth0').get_state() 'up' """ - return self._read_sysfs('/sys/class/net/{}/operstate' - .format(self._ifname)) + cmd = 'ip -json link show dev {}'.format(self._ifname) + tmp = self._cmd(cmd) + out = json.loads(tmp) + return out[0]['operstate'].lower() def set_state(self, state): """ -- cgit v1.2.3 From 04c02bcd100f253832e9a57736cf0d1a9f32fc5f Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 18 Oct 2019 18:07:21 +0200 Subject: Python/ifconfig: T1712: always start DHCP when configured DHCP was only started when the interface operstate was set to up but this is wrong. An interface can be configured as DHCP interface and DHCP client must be launched even when the physical interface becomes available n-minutes later. DHCP client then can ask for an IP assignemnt by DHCP. Tested by starting DHCP client on a not connected ethernet interface. Address was assigned later on after link became ready. --- python/vyos/ifconfig.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index 1ffa10978..3470b3aa6 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -521,14 +521,13 @@ class Interface: with open(self._dhcp_cfg_file, 'w') as f: f.write(dhcp_text) - if self.get_state() == 'up': - cmd = 'start-stop-daemon --start --quiet --pidfile ' + \ - self._dhcp_pid_file - cmd += ' --exec /sbin/dhclient --' - # now pass arguments to dhclient binary - cmd += ' -4 -nw -cf {} -pf {} -lf {} {}'.format( - self._dhcp_cfg_file, self._dhcp_pid_file, self._dhcp_lease_file, self._ifname) - return self._cmd(cmd) + cmd = 'start-stop-daemon --start --quiet --pidfile ' + \ + self._dhcp_pid_file + cmd += ' --exec /sbin/dhclient --' + # now pass arguments to dhclient binary + cmd += ' -4 -nw -cf {} -pf {} -lf {} {}'.format( + self._dhcp_cfg_file, self._dhcp_pid_file, self._dhcp_lease_file, self._ifname) + return self._cmd(cmd) def _del_dhcp(self): -- cgit v1.2.3 From df9544233fb661e830285c1a0d7755cff4b27408 Mon Sep 17 00:00:00 2001 From: hagbard Date: Fri, 18 Oct 2019 10:58:03 -0700 Subject: system-proxy: T1741 - Add system wide proxy setting CLI implementation --- interface-definitions/system-proxy.xml | 43 ++++++++++++++++ src/conf_mode/system-proxy.py | 91 ++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 interface-definitions/system-proxy.xml create mode 100755 src/conf_mode/system-proxy.py diff --git a/interface-definitions/system-proxy.xml b/interface-definitions/system-proxy.xml new file mode 100644 index 000000000..f43702fc8 --- /dev/null +++ b/interface-definitions/system-proxy.xml @@ -0,0 +1,43 @@ + + + + + + + Sets a proxy for system wide use + + + + + Proxy URL + + ^http://[a-z0-9\.]+$ + + + + + + Proxy port + + + + + + + + Proxy username + + ^[a-z0-9-_\.]{1,100}$ + + + + + + Proxy password + + + + + + + diff --git a/src/conf_mode/system-proxy.py b/src/conf_mode/system-proxy.py new file mode 100755 index 000000000..02e1a2eda --- /dev/null +++ b/src/conf_mode/system-proxy.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# + +import sys +import os +import re +import subprocess + +from vyos import ConfigError +from vyos.config import Config + +proxy_def=r'/etc/profile.d/vyos-system-proxy.sh' + +def get_config(): + c = Config() + if not c.exists('system proxy'): + return None + + c.set_level('system proxy') + + cnf = { + 'url' : None, + 'port' : None, + 'usr' : None, + 'passwd' : None + } + + if c.exists('url'): + cnf['url'] = c.return_value('url') + if c.exists('port'): + cnf['port'] = c.return_value('port') + if c.exists('username'): + cnf['usr'] = c.return_value('username') + if c.exists('password'): + cnf['passwd'] = c.return_value('password') + + return cnf + +def verify(c): + if not c: + return None + if not c['url'] or not c['port']: + raise ConfigError("proxy url and port requires a value") + elif c['usr'] and not c['passwd']: + raise ConfigError("proxy password requires a value") + elif not c['usr'] and c['passwd']: + raise ConfigError("proxy username requires a value") + +def generate(c): + if not c: + return None + if not c['usr']: + return str("export http_proxy={url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy"\ + .format(url=c['url'], port=c['port'])) + else: + return str("export http_proxy=http://{usr}:{passwd}@{url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy"\ + .format(url=re.sub('http://','',c['url']), port=c['port'], usr=c['usr'], passwd=c['passwd'])) + +def apply(ln): + if not ln and os.path.exists(proxy_def): + subprocess.call(['unset http_proxy https_proxy ftp_proxy'], shell=True) + os.remove(proxy_def) + else: + open(proxy_def,'w').write("# generated by system-proxy.py\n{}\n".format(ln)) + subprocess.call(['. /etc/profile.d/vyos-system-proxy.sh'], shell=True) + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + ln = generate(c) + apply(ln) + except ConfigError as e: + print(e) + sys.exit(1) + -- cgit v1.2.3 From d2aa68e5e6a16e5e02ca7301ad9c37cbccbff83e Mon Sep 17 00:00:00 2001 From: hagbard Date: Fri, 18 Oct 2019 11:43:10 -0700 Subject: wireguard - remove endpoint check to enable roaming connections --- src/conf_mode/interfaces-wireguard.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py index 7a684bafa..013a07f32 100755 --- a/src/conf_mode/interfaces-wireguard.py +++ b/src/conf_mode/interfaces-wireguard.py @@ -190,9 +190,6 @@ def verify(c): raise ConfigError("ERROR: allowed-ips required for peer " + p) if not c['peer'][p]['pubkey']: raise ConfigError("peer pubkey required for peer " + p) - if not c['peer'][p]['endpoint']: - raise ConfigError("peer endpoint required for peer " + p) - def apply(c): # no wg configs left, remove all interface from system -- cgit v1.2.3 From f87b5fa3b9a2c1c6826701924712654c8f0c5709 Mon Sep 17 00:00:00 2001 From: hagbard Date: Fri, 18 Oct 2019 12:37:19 -0700 Subject: system-proxy: T1741 - Add system wide proxy setting * removed subprocess as it is not required, script is executed via sudo * pep8 formatted --- src/conf_mode/system-proxy.py | 97 ++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/conf_mode/system-proxy.py b/src/conf_mode/system-proxy.py index 02e1a2eda..cf72a1f96 100755 --- a/src/conf_mode/system-proxy.py +++ b/src/conf_mode/system-proxy.py @@ -19,65 +19,67 @@ import sys import os import re -import subprocess from vyos import ConfigError from vyos.config import Config -proxy_def=r'/etc/profile.d/vyos-system-proxy.sh' +proxy_def = r'/etc/profile.d/vyos-system-proxy.sh' + def get_config(): - c = Config() - if not c.exists('system proxy'): - return None - - c.set_level('system proxy') - - cnf = { - 'url' : None, - 'port' : None, - 'usr' : None, - 'passwd' : None - } - - if c.exists('url'): - cnf['url'] = c.return_value('url') - if c.exists('port'): - cnf['port'] = c.return_value('port') - if c.exists('username'): - cnf['usr'] = c.return_value('username') - if c.exists('password'): - cnf['passwd'] = c.return_value('password') - - return cnf + c = Config() + if not c.exists('system proxy'): + return None + + c.set_level('system proxy') + + cnf = { + 'url': None, + 'port': None, + 'usr': None, + 'passwd': None + } + + if c.exists('url'): + cnf['url'] = c.return_value('url') + if c.exists('port'): + cnf['port'] = c.return_value('port') + if c.exists('username'): + cnf['usr'] = c.return_value('username') + if c.exists('password'): + cnf['passwd'] = c.return_value('password') + + return cnf + def verify(c): - if not c: - return None - if not c['url'] or not c['port']: - raise ConfigError("proxy url and port requires a value") - elif c['usr'] and not c['passwd']: - raise ConfigError("proxy password requires a value") - elif not c['usr'] and c['passwd']: - raise ConfigError("proxy username requires a value") + if not c: + return None + if not c['url'] or not c['port']: + raise ConfigError("proxy url and port requires a value") + elif c['usr'] and not c['passwd']: + raise ConfigError("proxy password requires a value") + elif not c['usr'] and c['passwd']: + raise ConfigError("proxy username requires a value") + def generate(c): - if not c: - return None - if not c['usr']: - return str("export http_proxy={url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy"\ - .format(url=c['url'], port=c['port'])) - else: - return str("export http_proxy=http://{usr}:{passwd}@{url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy"\ - .format(url=re.sub('http://','',c['url']), port=c['port'], usr=c['usr'], passwd=c['passwd'])) + if not c: + return None + if not c['usr']: + return str("export http_proxy={url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy" + .format(url=c['url'], port=c['port'])) + else: + return str("export http_proxy=http://{usr}:{passwd}@{url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy" + .format(url=re.sub('http://', '', c['url']), port=c['port'], usr=c['usr'], passwd=c['passwd'])) + def apply(ln): - if not ln and os.path.exists(proxy_def): - subprocess.call(['unset http_proxy https_proxy ftp_proxy'], shell=True) - os.remove(proxy_def) - else: - open(proxy_def,'w').write("# generated by system-proxy.py\n{}\n".format(ln)) - subprocess.call(['. /etc/profile.d/vyos-system-proxy.sh'], shell=True) + if not ln and os.path.exists(proxy_def): + os.remove(proxy_def) + else: + open(proxy_def, 'w').write( + "# generated by system-proxy.py\n{}\n".format(ln)) if __name__ == '__main__': try: @@ -88,4 +90,3 @@ if __name__ == '__main__': except ConfigError as e: print(e) sys.exit(1) - -- cgit v1.2.3 From 735d73e162634d598aa6b8ee13197aa231eefedb Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 19 Oct 2019 10:11:46 +0200 Subject: dhcp-server: T1745: bugfix corner case on static-assignments There was a bug when refactoring this with commits 5848a4d ("dhcp-server: T1707: remove DHCP static-mappings from address pool") and 1182b44 ("dhcp-server: T1707: bugfix on subsequent DHCP exclude addresses") that when a static address assignemnt was using the last IP address from the specified range. This triggered the following error: "DHCP range stop address x must be greater or equal to the range start address y!" --- src/conf_mode/dhcp_server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py index f19bcb250..af803a696 100755 --- a/src/conf_mode/dhcp_server.py +++ b/src/conf_mode/dhcp_server.py @@ -303,7 +303,8 @@ def dhcp_slice_range(exclude_list, range_list): 'start': str(ip_address(e) + 1), 'stop': str(range_stop) } - output.append(r) + if not (ip_address(r['start']) > ip_address(r['stop'])): + output.append(r) else: # if we have no exclude in the whole range - we just take the range # as it is -- cgit v1.2.3 From 6f73338f0a652ca9b68a5778456f63d098f04522 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sat, 19 Oct 2019 10:28:00 +0200 Subject: T1749: support multiple ranges in the numeric validator. --- src/validators/numeric | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/validators/numeric b/src/validators/numeric index ffe84a234..0a2d83d14 100755 --- a/src/validators/numeric +++ b/src/validators/numeric @@ -24,7 +24,7 @@ import re parser = argparse.ArgumentParser() parser.add_argument("-f", "--float", action="store_true", help="Accept floating point values") group = parser.add_mutually_exclusive_group() -group.add_argument("-r", "--range", type=str, help="Check if the number is within range (inclusive), example: 1024-65535") +group.add_argument("-r", "--range", type=str, help="Check if the number is within range (inclusive), example: 1024-65535", action='append') group.add_argument("-n", "--non-negative", action="store_true", help="Check if the number is non-negative (>= 0)") group.add_argument("-p", "--positive", action="store_true", help="Check if the number is positive (> 0)") parser.add_argument("number", type=str, help="Number to validate") @@ -47,15 +47,25 @@ else: sys.exit(1) if args.range: - try: - lower, upper = re.match(r'(\d+)\s*\-\s*(\d+)', args.range).groups() - lower, upper = int(lower), int(upper) - except: - print("{0} is not a valid number range",format(args.range), file=sys.stderr) - sys.exit(1) + valid = False + for r in args.range: + try: + lower, upper = re.match(r'(\d+)\s*\-\s*(\d+)', r).groups() + lower, upper = int(lower), int(upper) + except: + print("{0} is not a valid number range",format(args.range), file=sys.stderr) + sys.exit(1) + + if (number >= lower) and (number <= upper): + valid = True + # end for - if (number < lower) or (number > upper): - print("Number {0} is not in the {1} range".format(number, args.range), file=sys.stderr) + if not valid: + if len(args.range) > 1: + err_msg = "Number {0} is not in any of the ranges {1}".format(number, args.range) + else: + err_msg = "Number {0} is not in the range {1}".format(number, args.range[0]) + print(err_msg, file=sys.stderr) sys.exit(1) elif args.non_negative: if number < 0: -- cgit v1.2.3