diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/dhcpv6_server.py | 5 | ||||
-rwxr-xr-x | src/conf_mode/dns_forwarding.py | 4 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-openvpn.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 8 | ||||
-rwxr-xr-x | src/conf_mode/protocols_bfd.py | 8 | ||||
-rwxr-xr-x | src/conf_mode/protocols_isis.py | 152 | ||||
-rwxr-xr-x | src/conf_mode/service_ipoe-server.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/snmp.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/tftp_server.py | 2 | ||||
-rwxr-xr-x | src/conf_mode/vpn_l2tp.py | 4 | ||||
-rwxr-xr-x | src/op_mode/powerctrl.py | 6 | ||||
-rw-r--r-- | src/tests/test_jinja_filters.py | 72 | ||||
-rw-r--r-- | src/tests/test_template.py | 46 | ||||
-rw-r--r-- | src/tests/test_validate.py | 23 |
14 files changed, 263 insertions, 79 deletions
diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py index 1777d4db7..c2868e078 100755 --- a/src/conf_mode/dhcpv6_server.py +++ b/src/conf_mode/dhcpv6_server.py @@ -22,10 +22,11 @@ from copy import deepcopy from vyos.config import Config from vyos.template import render +from vyos.template import is_ipv6 from vyos.util import call -from vyos.validate import is_subnet_connected, is_ipv6 -from vyos import ConfigError +from vyos.validate import is_subnet_connected +from vyos import ConfigError from vyos import airbag airbag.enable() diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index d0c2dd252..ef52cbfd3 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -21,12 +21,12 @@ from sys import exit from vyos.config import Config from vyos.configdict import dict_merge from vyos.hostsd_client import Client as hostsd_client +from vyos.template import render +from vyos.template import is_ipv6 from vyos.util import call from vyos.util import chown from vyos.util import dict_search -from vyos.template import render from vyos.xml import defaults -from vyos.validate import is_ipv6 from vyos import ConfigError from vyos import airbag diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index b507afcc0..c23e79948 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -33,13 +33,13 @@ from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_diffie_hellman_length from vyos.ifconfig import VTunIf from vyos.template import render +from vyos.template import is_ipv4 +from vyos.template import is_ipv6 from vyos.util import call from vyos.util import chown from vyos.util import chmod_600 from vyos.util import dict_search from vyos.validate import is_addr_assigned -from vyos.validate import is_ipv4 -from vyos.validate import is_ipv6 from vyos import ConfigError from vyos import airbag @@ -320,7 +320,7 @@ def verify(openvpn): if 'local_port' in openvpn: raise ConfigError('Cannot specify "local-port" with "tcp-active"') - if 'remote_host' in openvpn: + if 'remote_host' not in openvpn: raise ConfigError('Must specify "remote-host" with "tcp-active"') # shared secret and TLS diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 5561514bd..f1217b62d 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -23,12 +23,14 @@ from netifaces import interfaces from vyos.config import Config from vyos.configdict import is_member +from vyos.configdict import list_diff +from vyos.dicts import FixedDict from vyos.ifconfig import Interface, GREIf, GRETapIf, IPIPIf, IP6GREIf, IPIP6If, IP6IP6If, SitIf, Sit6RDIf from vyos.ifconfig.afi import IP4, IP6 -from vyos.configdict import list_diff -from vyos.validate import is_ipv4, is_ipv6 +from vyos.template import is_ipv4 +from vyos.template import is_ipv6 from vyos import ConfigError -from vyos.dicts import FixedDict + from vyos import airbag airbag.enable() diff --git a/src/conf_mode/protocols_bfd.py b/src/conf_mode/protocols_bfd.py index c8e791c78..d1e551cad 100755 --- a/src/conf_mode/protocols_bfd.py +++ b/src/conf_mode/protocols_bfd.py @@ -20,11 +20,11 @@ from sys import exit from copy import deepcopy from vyos.config import Config -from vyos.validate import is_ipv6_link_local, is_ipv6 -from vyos import ConfigError -from vyos.util import call +from vyos.template import is_ipv6 from vyos.template import render - +from vyos.util import call +from vyos.validate import is_ipv6_link_local +from vyos import ConfigError from vyos import airbag airbag.enable() diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py new file mode 100755 index 000000000..d5e5b64fb --- /dev/null +++ b/src/conf_mode/protocols_isis.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2017-2020 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 <http://www.gnu.org/licenses/>. + +import os + +from sys import exit + +from vyos.config import Config +from vyos.configdict import node_changed +from vyos import ConfigError +from vyos.util import call +from vyos.template import render +from vyos.template import render_to_string +from vyos import frr +from vyos import airbag +airbag.enable() + +config_file = r'/tmp/isis.frr' + +def get_config(config=None): + if config: + conf = config + else: + conf = Config() + base = ['protocols', 'isis'] + + isis = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + + # determine which members have been removed + for instance in isis: + conf.set_level(base + [instance]) + tmp = node_changed(conf, ['interface']) + if tmp: + isis[instance].update({'interface_remove': tmp}) + + return isis + +def verify(isis): + # bail out early - looks like removal from running config + if not isis: + return None + + for process, isis_config in isis.items(): + # If more then one isis process is defined (Frr only supports one) + # http://docs.frrouting.org/en/latest/isisd.html#isis-router + if len(isis) > 1: + raise ConfigError('Only one isis process can be definded') + + # If network entity title (net) not defined + if 'net' not in isis_config: + raise ConfigError('ISIS net format iso is mandatory!') + + # If interface not set + if 'interface' not in isis_config: + raise ConfigError('ISIS interface is mandatory!') + + # If md5 and plaintext-password set at the same time + if 'area_password' in isis_config: + if {'md5', 'plaintext_password'} <= set(isis_config['encryption']): + raise ConfigError('Can not use both md5 and plaintext-password for ISIS area-password!') + + # If one param from deley set, but not set others + if 'spf_delay_ietf' in isis_config: + required_timers = ['holddown', 'init_delay', 'long_delay', 'short_delay', 'time_to_learn'] + exist_timers = [] + for elm_timer in required_timers: + if elm_timer in isis_config['spf_delay_ietf']: + exist_timers.append(elm_timer) + + exist_timers = set(required_timers).difference(set(exist_timers)) + if len(exist_timers) > 0: + raise ConfigError('All types of delay must be specified: ' + ', '.join(exist_timers).replace('_', '-')) + + # If Redistribute set, but level don't set + if 'redistribute' in isis_config: + proc_level = isis_config.get('level','').replace('-','_') + for proto, proto_config in isis_config.get('redistribute', {}).get('ipv4', {}).items(): + if 'level_1' not in proto_config and 'level_2' not in proto_config: + raise ConfigError('Redistribute level-1 or level-2 should be specified in \"protocols isis {} redistribute ipv4 {}\"'.format(process, proto)) + for redistribute_level in proto_config.keys(): + if proc_level and proc_level != 'level_1_2' and proc_level != redistribute_level: + raise ConfigError('\"protocols isis {0} redistribute ipv4 {2} {3}\" cannot be used with \"protocols isis {0} level {1}\"'.format(process, proc_level, proto, redistribute_level)) + + return None + +def generate(isis): + if not isis: + isis['new_frr_config'] = '' + return None + + # only one ISIS process is supported, so we can directly send the first key + # of the config dict + process = list(isis.keys())[0] + isis[process]['process'] = process + + import pprint + pprint.pprint(isis[process]) + + # render(config) not needed, its only for debug + render(config_file, 'frr/isis.frr.tmpl', isis[process], trim_blocks=True) + + isis['new_frr_config'] = render_to_string('frr/isis.frr.tmpl', + isis[process], trim_blocks=True) + + return None + +def apply(isis): + + # Save original configration prior to starting any commit actions + frr_cfg = {} + frr_cfg['original_config'] = frr.get_configuration(daemon='isisd') + frr_cfg['modified_config'] = frr.replace_section(frr_cfg['original_config'], isis['new_frr_config'], from_re='router isis .*') + + # Debugging + print('') + print('--------- DEBUGGING ----------') + print(f'Existing config:\n{frr_cfg["original_config"]}\n\n') + print(f'Replacement config:\n{isis["new_frr_config"]}\n\n') + print(f'Modified config:\n{frr_cfg["modified_config"]}\n\n') + + # FRR mark configuration will test for syntax errors and throws an + # exception if any syntax errors is detected + frr.mark_configuration(frr_cfg['modified_config']) + + # Commit resulting configuration to FRR, this will throw CommitError + # on failure + frr.reload_configuration(frr_cfg['modified_config'], daemon='isisd') + + return None + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + exit(1) diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py index 87c7754f3..68c554360 100755 --- a/src/conf_mode/service_ipoe-server.py +++ b/src/conf_mode/service_ipoe-server.py @@ -23,8 +23,9 @@ from sys import exit from vyos.config import Config from vyos.template import render +from vyos.template import is_ipv4 +from vyos.template import is_ipv6 from vyos.util import call, get_half_cpus -from vyos.validate import is_ipv4 from vyos import ConfigError from vyos import airbag diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index 117bf0274..3990e5735 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -22,8 +22,9 @@ from vyos.config import Config from vyos.configverify import verify_vrf from vyos.snmpv3_hashgen import plaintext_to_md5, plaintext_to_sha1, random from vyos.template import render +from vyos.template import is_ipv4 from vyos.util import call, chmod_755 -from vyos.validate import is_ipv4, is_addr_assigned +from vyos.validate import is_addr_assigned from vyos.version import get_version_data from vyos import ConfigError, airbag airbag.enable() diff --git a/src/conf_mode/tftp_server.py b/src/conf_mode/tftp_server.py index cac95afe2..56e195b6a 100755 --- a/src/conf_mode/tftp_server.py +++ b/src/conf_mode/tftp_server.py @@ -25,9 +25,9 @@ from sys import exit from vyos.config import Config from vyos.configdict import dict_merge from vyos.template import render +from vyos.template import is_ipv4 from vyos.util import call from vyos.util import chmod_755 -from vyos.validate import is_ipv4 from vyos.validate import is_addr_assigned from vyos.xml import defaults from vyos import ConfigError diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index 465986d5b..80eb8daf2 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -25,10 +25,10 @@ from time import sleep from ipaddress import ip_network from vyos.config import Config +from vyos.template import is_ipv4 +from vyos.template import render from vyos.util import call, get_half_cpus -from vyos.validate import is_ipv4 from vyos import ConfigError -from vyos.template import render from vyos import airbag airbag.enable() diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py index 69af427ec..c000d7d06 100755 --- a/src/op_mode/powerctrl.py +++ b/src/op_mode/powerctrl.py @@ -34,7 +34,11 @@ def utc2local(datetime): def parse_time(s): try: if re.match(r'^\d{1,2}$', s): - return datetime.strptime(s, "%M").time() + if (int(s) > 59): + s = str(int(s)//60) + ":" + str(int(s)%60) + return datetime.strptime(s, "%H:%M").time() + else: + return datetime.strptime(s, "%M").time() else: return datetime.strptime(s, "%H:%M").time() except ValueError: diff --git a/src/tests/test_jinja_filters.py b/src/tests/test_jinja_filters.py index acd7a5952..8a7241fe3 100644 --- a/src/tests/test_jinja_filters.py +++ b/src/tests/test_jinja_filters.py @@ -17,13 +17,13 @@ from unittest import TestCase from ipaddress import ip_network -from vyos.template import vyos_address_from_cidr -from vyos.template import vyos_netmask_from_cidr -from vyos.template import vyos_ipv4 -from vyos.template import vyos_ipv6 -from vyos.template import vyos_first_host_address -from vyos.template import vyos_last_host_address -from vyos.template import vyos_inc_ip +from vyos.template import address_from_cidr +from vyos.template import netmask_from_cidr +from vyos.template import is_ipv4 +from vyos.template import is_ipv6 +from vyos.template import first_host_address +from vyos.template import last_host_address +from vyos.template import inc_ip class TestTeamplteHelpers(TestCase): def setUp(self): @@ -31,39 +31,39 @@ class TestTeamplteHelpers(TestCase): def test_helpers_from_cidr(self): network_v4 = '192.0.2.0/26' - self.assertEqual(vyos_address_from_cidr(network_v4), str(ip_network(network_v4).network_address)) - self.assertEqual(vyos_netmask_from_cidr(network_v4), str(ip_network(network_v4).netmask)) + self.assertEqual(address_from_cidr(network_v4), str(ip_network(network_v4).network_address)) + self.assertEqual(netmask_from_cidr(network_v4), str(ip_network(network_v4).netmask)) def test_helpers_ipv4(self): - self.assertTrue(vyos_ipv4('192.0.2.1')) - self.assertTrue(vyos_ipv4('192.0.2.0/24')) - self.assertTrue(vyos_ipv4('192.0.2.1/32')) - self.assertTrue(vyos_ipv4('10.255.1.2')) - self.assertTrue(vyos_ipv4('10.255.1.0/24')) - self.assertTrue(vyos_ipv4('10.255.1.2/32')) - self.assertFalse(vyos_ipv4('2001:db8::')) - self.assertFalse(vyos_ipv4('2001:db8::1')) - self.assertFalse(vyos_ipv4('2001:db8::/64')) + self.assertTrue(is_ipv4('192.0.2.1')) + self.assertTrue(is_ipv4('192.0.2.0/24')) + self.assertTrue(is_ipv4('192.0.2.1/32')) + self.assertTrue(is_ipv4('10.255.1.2')) + self.assertTrue(is_ipv4('10.255.1.0/24')) + self.assertTrue(is_ipv4('10.255.1.2/32')) + self.assertFalse(is_ipv4('2001:db8::')) + self.assertFalse(is_ipv4('2001:db8::1')) + self.assertFalse(is_ipv4('2001:db8::/64')) def test_helpers_ipv6(self): - self.assertFalse(vyos_ipv6('192.0.2.1')) - self.assertFalse(vyos_ipv6('192.0.2.0/24')) - self.assertFalse(vyos_ipv6('192.0.2.1/32')) - self.assertFalse(vyos_ipv6('10.255.1.2')) - self.assertFalse(vyos_ipv6('10.255.1.0/24')) - self.assertFalse(vyos_ipv6('10.255.1.2/32')) - self.assertTrue(vyos_ipv6('2001:db8::')) - self.assertTrue(vyos_ipv6('2001:db8::1')) - self.assertTrue(vyos_ipv6('2001:db8::1/64')) - self.assertTrue(vyos_ipv6('2001:db8::/32')) - self.assertTrue(vyos_ipv6('2001:db8::/64')) + self.assertFalse(is_ipv6('192.0.2.1')) + self.assertFalse(is_ipv6('192.0.2.0/24')) + self.assertFalse(is_ipv6('192.0.2.1/32')) + self.assertFalse(is_ipv6('10.255.1.2')) + self.assertFalse(is_ipv6('10.255.1.0/24')) + self.assertFalse(is_ipv6('10.255.1.2/32')) + self.assertTrue(is_ipv6('2001:db8::')) + self.assertTrue(is_ipv6('2001:db8::1')) + self.assertTrue(is_ipv6('2001:db8::1/64')) + self.assertTrue(is_ipv6('2001:db8::/32')) + self.assertTrue(is_ipv6('2001:db8::/64')) def test_helpers_first_host_address(self): - self.assertEqual(vyos_first_host_address('10.0.0.0/24'), '10.0.0.1') - self.assertEqual(vyos_first_host_address('10.0.0.128/25'), '10.0.0.129') - self.assertEqual(vyos_first_host_address('10.0.0.200/29'), '10.0.0.201') + self.assertEqual(first_host_address('10.0.0.0/24'), '10.0.0.1') + self.assertEqual(first_host_address('10.0.0.128/25'), '10.0.0.129') + self.assertEqual(first_host_address('10.0.0.200/29'), '10.0.0.201') - self.assertEqual(vyos_first_host_address('2001:db8::/64'), '2001:db8::') - self.assertEqual(vyos_first_host_address('2001:db8::/112'), '2001:db8::') - self.assertEqual(vyos_first_host_address('2001:db8::10/112'), '2001:db8::10') - self.assertEqual(vyos_first_host_address('2001:db8::100/112'), '2001:db8::100') + self.assertEqual(first_host_address('2001:db8::/64'), '2001:db8::') + self.assertEqual(first_host_address('2001:db8::/112'), '2001:db8::') + self.assertEqual(first_host_address('2001:db8::10/112'), '2001:db8::10') + self.assertEqual(first_host_address('2001:db8::100/112'), '2001:db8::100') diff --git a/src/tests/test_template.py b/src/tests/test_template.py new file mode 100644 index 000000000..6dc2f075e --- /dev/null +++ b/src/tests/test_template.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2020 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 <http://www.gnu.org/licenses/>. + +import vyos.template +from unittest import TestCase + +class TestVyOSTemplate(TestCase): + def setUp(self): + pass + + def test_is_ip(self): + self.assertTrue(vyos.template.is_ip('192.0.2.1')) + self.assertTrue(vyos.template.is_ip('2001:db8::1')) + self.assertFalse(vyos.template.is_ip('VyOS')) + + def test_is_ipv4(self): + self.assertTrue(vyos.template.is_ipv4('192.0.2.1')) + self.assertTrue(vyos.template.is_ipv4('192.0.2.0/24')) + self.assertTrue(vyos.template.is_ipv4('192.0.2.1/32')) + + self.assertFalse(vyos.template.is_ipv4('2001:db8::1')) + self.assertFalse(vyos.template.is_ipv4('2001:db8::/64')) + self.assertFalse(vyos.template.is_ipv4('VyOS')) + + def test_is_ipv6(self): + self.assertTrue(vyos.template.is_ipv6('2001:db8::1')) + self.assertTrue(vyos.template.is_ipv6('2001:db8::/64')) + self.assertTrue(vyos.template.is_ipv6('2001:db8::1/64')) + + self.assertFalse(vyos.template.is_ipv6('192.0.2.1')) + self.assertFalse(vyos.template.is_ipv6('192.0.2.0/24')) + self.assertFalse(vyos.template.is_ipv6('192.0.2.1/32')) + self.assertFalse(vyos.template.is_ipv6('VyOS')) diff --git a/src/tests/test_validate.py b/src/tests/test_validate.py index e9fe185ed..226e856a3 100644 --- a/src/tests/test_validate.py +++ b/src/tests/test_validate.py @@ -21,29 +21,6 @@ class TestVyOSValidate(TestCase): def setUp(self): pass - def test_is_ip(self): - self.assertTrue(vyos.validate.is_ip('192.0.2.1')) - self.assertTrue(vyos.validate.is_ip('2001:db8::1')) - self.assertFalse(vyos.validate.is_ip('VyOS')) - - def test_is_ipv4(self): - self.assertTrue(vyos.validate.is_ipv4('192.0.2.1')) - self.assertTrue(vyos.validate.is_ipv4('192.0.2.0/24')) - self.assertTrue(vyos.validate.is_ipv4('192.0.2.1/32')) - - self.assertFalse(vyos.validate.is_ipv4('2001:db8::1')) - self.assertFalse(vyos.validate.is_ipv4('2001:db8::/64')) - self.assertFalse(vyos.validate.is_ipv4('VyOS')) - - def test_is_ipv6(self): - self.assertFalse(vyos.validate.is_ipv6('192.0.2.1')) - self.assertFalse(vyos.validate.is_ipv6('192.0.2.0/24')) - self.assertFalse(vyos.validate.is_ipv6('192.0.2.1/32')) - self.assertTrue(vyos.validate.is_ipv6('2001:db8::1')) - self.assertTrue(vyos.validate.is_ipv6('2001:db8::/64')) - self.assertTrue(vyos.validate.is_ipv6('2001:db8::1/64')) - self.assertFalse(vyos.validate.is_ipv6('VyOS')) - def test_is_ipv6_link_local(self): self.assertFalse(vyos.validate.is_ipv6_link_local('169.254.0.1')) self.assertTrue(vyos.validate.is_ipv6_link_local('fe80::')) |