diff options
Diffstat (limited to 'smoketest/scripts/cli')
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_tunnel.py | 31 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_nat66.py | 156 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_bgp.py | 152 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_ospf.py | 277 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_ospfv3.py | 123 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_ssh.py | 8 |
6 files changed, 708 insertions, 39 deletions
diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py index f67b813af..8405fc7d0 100755 --- a/smoketest/scripts/cli/test_interfaces_tunnel.py +++ b/smoketest/scripts/cli/test_interfaces_tunnel.py @@ -84,7 +84,6 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): self.session.delete(['interfaces', 'dummy', source_if]) super().tearDown() - def test_ipv4_encapsulations(self): # When running tests ensure that for certain encapsulation types the # local and remote IP address is actually an IPv4 address @@ -106,7 +105,6 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): with self.assertRaises(ConfigSessionError): self.session.commit() self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) - self.session.set(self._base_path + [interface, 'source-interface', source_if]) # Source interface can not be used with sit and gre-bridge @@ -130,6 +128,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local']) self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) + self.assertTrue(conf['linkinfo']['info_data']['pmtudisc']) # cleanup this instance self.session.delete(self._base_path + [interface]) @@ -177,7 +176,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): self.assertEqual(encapsulation, conf['link_type']) self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local']) - self.assertEqual(remote_ip6, conf['linkinfo']['info_data']['remote']) + self.assertEqual(remote_ip6, conf['linkinfo']['info_data']['remote']) # cleanup this instance self.session.delete(self._base_path + [interface]) @@ -203,5 +202,31 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): # Check if commit is ok self.session.commit() + def test_tunnel_parameters_gre(self): + interface = f'tun1030' + gre_key = '10' + encapsulation = 'gre' + tos = '20' + + self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) + self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) + self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) + + self.session.set(self._base_path + [interface, 'parameters', 'ip', 'no-pmtu-discovery']) + self.session.set(self._base_path + [interface, 'parameters', 'ip', 'key', gre_key]) + self.session.set(self._base_path + [interface, 'parameters', 'ip', 'tos', tos]) + + # Check if commit is ok + self.session.commit() + + conf = tunnel_conf(interface) + self.assertEqual(mtu, conf['mtu']) + self.assertEqual(interface, conf['ifname']) + self.assertEqual(encapsulation, conf['link_type']) + self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local']) + self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) + self.assertEqual(0, conf['linkinfo']['info_data']['ttl']) + self.assertFalse( conf['linkinfo']['info_data']['pmtudisc']) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_nat66.py b/smoketest/scripts/cli/test_nat66.py new file mode 100755 index 000000000..ccc4196e0 --- /dev/null +++ b/smoketest/scripts/cli/test_nat66.py @@ -0,0 +1,156 @@ +#!/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 os +import jmespath +import json +import unittest + +from vyos.configsession import ConfigSession +from vyos.configsession import ConfigSessionError +from vyos.util import cmd +from vyos.util import dict_search + +base_path = ['nat66'] +src_path = base_path + ['source'] +dst_path = base_path + ['destination'] + +class TestNAT66(unittest.TestCase): + def setUp(self): + # ensure we can also run this test on a live system - so lets clean + # out the current configuration :) + self.session = ConfigSession(os.getpid()) + self.session.delete(base_path) + + def tearDown(self): + self.session.delete(base_path) + self.session.commit() + + def test_source_nat66(self): + source_prefix = 'fc00::/64' + translation_prefix = 'fc01::/64' + self.session.set(src_path + ['rule', '1', 'outbound-interface', 'eth1']) + self.session.set(src_path + ['rule', '1', 'source', 'prefix', source_prefix]) + self.session.set(src_path + ['rule', '1', 'translation', 'prefix', translation_prefix]) + + # check validate() - outbound-interface must be defined + self.session.commit() + + tmp = cmd('sudo nft -j list table ip6 nat') + data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp)) + + for idx in range(0, len(data_json)): + data = data_json[idx] + + self.assertEqual(data['chain'], 'POSTROUTING') + self.assertEqual(data['family'], 'ip6') + self.assertEqual(data['table'], 'nat') + + iface = dict_search('match.right', data['expr'][0]) + address = dict_search('match.right.prefix.addr', data['expr'][2]) + mask = dict_search('match.right.prefix.len', data['expr'][2]) + translation_address = dict_search('snat.addr.prefix.addr', data['expr'][3]) + translation_mask = dict_search('snat.addr.prefix.len', data['expr'][3]) + + self.assertEqual(iface, 'eth1') + # check for translation address + self.assertEqual(f'{translation_address}/{translation_mask}', translation_prefix) + self.assertEqual(f'{address}/{mask}', source_prefix) + + def test_destination_nat66(self): + destination_address = 'fc00::1' + translation_address = 'fc01::1' + self.session.set(dst_path + ['rule', '1', 'inbound-interface', 'eth1']) + self.session.set(dst_path + ['rule', '1', 'destination', 'address', destination_address]) + self.session.set(dst_path + ['rule', '1', 'translation', 'address', translation_address]) + + # check validate() - outbound-interface must be defined + self.session.commit() + + tmp = cmd('sudo nft -j list table ip6 nat') + data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp)) + + for idx in range(0, len(data_json)): + data = data_json[idx] + + self.assertEqual(data['chain'], 'PREROUTING') + self.assertEqual(data['family'], 'ip6') + self.assertEqual(data['table'], 'nat') + + iface = dict_search('match.right', data['expr'][0]) + dnat_addr = dict_search('dnat.addr', data['expr'][3]) + + self.assertEqual(dnat_addr, translation_address) + self.assertEqual(iface, 'eth1') + + def test_destination_nat66_prefix(self): + destination_prefix = 'fc00::/64' + translation_prefix = 'fc01::/64' + self.session.set(dst_path + ['rule', '1', 'inbound-interface', 'eth1']) + self.session.set(dst_path + ['rule', '1', 'destination', 'address', destination_prefix]) + self.session.set(dst_path + ['rule', '1', 'translation', 'address', translation_prefix]) + + # check validate() - outbound-interface must be defined + self.session.commit() + + tmp = cmd('sudo nft -j list table ip6 nat') + data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp)) + + for idx in range(0, len(data_json)): + data = data_json[idx] + + self.assertEqual(data['chain'], 'PREROUTING') + self.assertEqual(data['family'], 'ip6') + self.assertEqual(data['table'], 'nat') + + iface = dict_search('match.right', data['expr'][0]) + translation_address = dict_search('dnat.addr.prefix.addr', data['expr'][3]) + translation_mask = dict_search('dnat.addr.prefix.len', data['expr'][3]) + + self.assertEqual(f'{translation_address}/{translation_mask}', translation_prefix) + self.assertEqual(iface, 'eth1') + + def test_source_nat66_required_translation_prefix(self): + # T2813: Ensure translation address is specified + rule = '5' + source_prefix = 'fc00::/64' + translation_prefix = 'fc00:2::/64' + self.session.set(src_path + ['rule', rule, 'source', 'prefix', source_prefix]) + + # check validate() - outbound-interface must be defined + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.set(src_path + ['rule', rule, 'outbound-interface', 'eth0']) + + # check validate() - translation address not specified + with self.assertRaises(ConfigSessionError): + self.session.commit() + + self.session.set(src_path + ['rule', rule, 'translation', 'prefix', translation_prefix]) + self.session.commit() + + def test_nat66_no_rules(self): + # T3206: deleting all rules but keep the direction 'destination' or + # 'source' resulteds in KeyError: 'rule'. + # + # Test that both 'nat destination' and 'nat source' nodes can exist + # without any rule + self.session.set(src_path) + self.session.set(dst_path) + self.session.commit() + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index ccb9268fe..66ca3cdd7 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -26,59 +26,72 @@ PROCESS_NAME = 'bgpd' ASN = '64512' base_path = ['protocols', 'bgp', ASN] +route_map_in = 'foo-map-in' +route_map_out = 'foo-map-out' +prefix_list_in = 'pfx-foo-in' +prefix_list_out = 'pfx-foo-out' + neighbor_config = { '192.0.2.1' : { - 'cap_dynamic' : '', - 'cap_ext_next': '', - 'remote_as' : '100', - 'adv_interv' : '400', - 'passive' : '', - 'password' : 'VyOS-Secure123', - 'shutdown' : '', - 'cap_over' : '', - 'ttl_security': '5', - 'local_as' : '300', + 'cap_dynamic' : '', + 'cap_ext_next' : '', + 'remote_as' : '100', + 'adv_interv' : '400', + 'passive' : '', + 'password' : 'VyOS-Secure123', + 'shutdown' : '', + 'cap_over' : '', + 'ttl_security' : '5', + 'local_as' : '300', + 'route_map_in' : route_map_in, + 'route_map_out': route_map_out, }, '192.0.2.2' : { - 'remote_as' : '200', - 'shutdown' : '', - 'no_cap_nego' : '', - 'port' : '667', - 'cap_strict' : '', + 'remote_as' : '200', + 'shutdown' : '', + 'no_cap_nego' : '', + 'port' : '667', + 'cap_strict' : '', + 'pfx_list_in' : prefix_list_in, + 'pfx_list_out' : prefix_list_out, }, '192.0.2.3' : { - 'description' : 'foo bar baz', - 'remote_as' : '200', - 'passive' : '', - 'multi_hop' : '5', - 'update_src' : 'lo', + 'description' : 'foo bar baz', + 'remote_as' : '200', + 'passive' : '', + 'multi_hop' : '5', + 'update_src' : 'lo', }, } peer_group_config = { 'foo' : { - 'remote_as' : '100', - 'passive' : '', - 'password' : 'VyOS-Secure123', - 'shutdown' : '', - 'cap_over' : '', + 'remote_as' : '100', + 'passive' : '', + 'password' : 'VyOS-Secure123', + 'shutdown' : '', + 'cap_over' : '', # XXX: not available in current Perl backend # 'ttl_security': '5', }, 'bar' : { - 'description' : 'foo peer bar group', - 'remote_as' : '200', - 'shutdown' : '', - 'no_cap_nego' : '', - 'local_as' : '300', + 'description' : 'foo peer bar group', + 'remote_as' : '200', + 'shutdown' : '', + 'no_cap_nego' : '', + 'local_as' : '300', + 'pfx_list_in' : prefix_list_in, + 'pfx_list_out' : prefix_list_out, }, 'baz' : { - 'cap_dynamic' : '', - 'cap_ext_next': '', - 'remote_as' : '200', - 'passive' : '', - 'multi_hop' : '5', - 'update_src' : 'lo', + 'cap_dynamic' : '', + 'cap_ext_next' : '', + 'remote_as' : '200', + 'passive' : '', + 'multi_hop' : '5', + 'update_src' : 'lo', + 'route_map_in' : route_map_in, + 'route_map_out': route_map_out, }, } @@ -89,7 +102,19 @@ class TestProtocolsBGP(unittest.TestCase): def setUp(self): self.session = ConfigSession(os.getpid()) + self.session.set(['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'prefix', '192.0.2.0/25']) + self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25']) + def tearDown(self): + self.session.delete(['policy', 'route-map', route_map_in]) + self.session.delete(['policy', 'route-map', route_map_out]) + self.session.delete(['policy', 'prefix-list', prefix_list_in]) + self.session.delete(['policy', 'prefix-list', prefix_list_out]) + self.session.delete(base_path) self.session.commit() del self.session @@ -122,6 +147,15 @@ class TestProtocolsBGP(unittest.TestCase): self.assertIn(f' neighbor {peer} ttl-security hops {peer_config["ttl_security"]}', frrconfig) if 'update_src' in peer_config: self.assertIn(f' neighbor {peer} update-source {peer_config["update_src"]}', frrconfig) + if 'route_map_in' in peer_config: + self.assertIn(f' neighbor {peer} route-map {peer_config["route_map_in"]} in', frrconfig) + if 'route_map_out' in peer_config: + self.assertIn(f' neighbor {peer} route-map {peer_config["route_map_out"]} out', frrconfig) + if 'pfx_list_in' in peer_config: + self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_in"]} in', frrconfig) + if 'pfx_list_out' in peer_config: + self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_out"]} out', frrconfig) + def test_bgp_01_simple(self): router_id = '127.0.0.1' @@ -184,6 +218,14 @@ class TestProtocolsBGP(unittest.TestCase): self.session.set(base_path + ['neighbor', neighbor, 'ttl-security', 'hops', config["ttl_security"]]) if 'update_src' in config: self.session.set(base_path + ['neighbor', neighbor, 'update-source', config["update_src"]]) + if 'route_map_in' in config: + self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-map', 'import', config["route_map_in"]]) + if 'route_map_out' in config: + self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-map', 'export', config["route_map_out"]]) + if 'pfx_list_in' in config: + self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'prefix-list', 'import', config["pfx_list_in"]]) + if 'pfx_list_out' in config: + self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'prefix-list', 'export', config["pfx_list_out"]]) # commit changes self.session.commit() @@ -231,6 +273,14 @@ class TestProtocolsBGP(unittest.TestCase): self.session.set(base_path + ['peer-group', peer_group, 'ttl-security', 'hops', config["ttl_security"]]) if 'update_src' in config: self.session.set(base_path + ['peer-group', peer_group, 'update-source', config["update_src"]]) + if 'route_map_in' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'route-map', 'import', config["route_map_in"]]) + if 'route_map_out' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'route-map', 'export', config["route_map_out"]]) + if 'pfx_list_in' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'import', config["pfx_list_in"]]) + if 'pfx_list_out' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'export', config["pfx_list_out"]]) # commit changes self.session.commit() @@ -336,5 +386,35 @@ class TestProtocolsBGP(unittest.TestCase): self.assertIn(f' aggregate-address {network} summary-only', frrconfig) + def test_bgp_06_listen_range(self): + # Implemented via T1875 + limit = '64' + listen_ranges = ['192.0.2.0/25', '192.0.2.128/25'] + peer_group = 'listenfoobar' + self.session.set(base_path + ['listen', 'limit', limit]) + for prefix in listen_ranges: + self.session.set(base_path + ['listen', 'range', prefix]) + # check validate() - peer-group must be defined for range/prefix + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.set(base_path + ['listen', 'range', prefix, 'peer-group', peer_group]) + + # check validate() - peer-group does yet not exist! + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.set(base_path + ['peer-group', peer_group, 'remote-as', ASN]) + + # commit changes + self.session.commit() + + # Verify FRR bgpd configuration + frrconfig = getFRRBGPconfig() + self.assertIn(f'router bgp {ASN}', frrconfig) + self.assertIn(f' neighbor {peer_group} peer-group', frrconfig) + self.assertIn(f' neighbor {peer_group} remote-as {ASN}', frrconfig) + self.assertIn(f' bgp listen limit {limit}', frrconfig) + for prefix in listen_ranges: + self.assertIn(f' bgp listen range {prefix} peer-group {peer_group}', frrconfig) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py new file mode 100755 index 000000000..d47838d8c --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_ospf.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 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 +import unittest + +from vyos.configsession import ConfigSession +from vyos.ifconfig import Section +from vyos.util import cmd +from vyos.util import process_named_running + +PROCESS_NAME = 'ospfd' +base_path = ['protocols', 'ospf'] + +route_map = 'foo-bar-baz10' + +def getFRROSPFconfig(): + return cmd('vtysh -c "show run" | sed -n "/router ospf/,/^!/p"') + +class TestProtocolsOSPF(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + self.session.set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit']) + + def tearDown(self): + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + + self.session.delete(['policy', 'route-map', route_map]) + self.session.delete(base_path) + self.session.commit() + del self.session + + def test_ospf_01_defaults(self): + # commit changes + self.session.set(base_path) + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig) + self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults + + + def test_ospf_02_simple(self): + router_id = '127.0.0.1' + abr_type = 'ibm' + bandwidth = '1000' + metric = '123' + + self.session.set(base_path + ['auto-cost', 'reference-bandwidth', bandwidth]) + self.session.set(base_path + ['parameters', 'router-id', router_id]) + self.session.set(base_path + ['parameters', 'abr-type', abr_type]) + self.session.set(base_path + ['log-adjacency-changes', 'detail']) + self.session.set(base_path + ['default-metric', metric]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + self.assertIn(f' auto-cost reference-bandwidth {bandwidth}', frrconfig) + self.assertIn(f' ospf router-id {router_id}', frrconfig) + self.assertIn(f' ospf abr-type {abr_type}', frrconfig) + self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults + self.assertIn(f' default-metric {metric}', frrconfig) + + + def test_ospf_03_access_list(self): + acl = '100' + seq = '10' + protocols = ['bgp', 'connected', 'kernel', 'rip', 'static'] + + self.session.set(['policy', 'access-list', acl, 'rule', seq, 'action', 'permit']) + self.session.set(['policy', 'access-list', acl, 'rule', seq, 'source', 'any']) + self.session.set(['policy', 'access-list', acl, 'rule', seq, 'destination', 'any']) + for ptotocol in protocols: + self.session.set(base_path + ['access-list', acl, 'export', ptotocol]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults + for ptotocol in protocols: + self.assertIn(f' distribute-list {acl} out {ptotocol}', frrconfig) # defaults + self.session.delete(['policy', 'access-list', acl]) + + + def test_ospf_04_default_originate(self): + seq = '100' + metric = '50' + metric_type = '1' + + self.session.set(base_path + ['default-information', 'originate', 'metric', metric]) + self.session.set(base_path + ['default-information', 'originate', 'metric-type', metric_type]) + self.session.set(base_path + ['default-information', 'originate', 'route-map', route_map]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults + self.assertIn(f' default-information originate metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig) + + # Now set 'always' + self.session.set(base_path + ['default-information', 'originate', 'always']) + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f' default-information originate always metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig) + + + def test_ospf_05_options(self): + global_distance = '128' + intra_area = '100' + inter_area = '110' + external = '120' + on_startup = '30' + on_shutdown = '60' + refresh = '50' + + self.session.set(base_path + ['distance', 'global', global_distance]) + self.session.set(base_path + ['distance', 'ospf', 'external', external]) + self.session.set(base_path + ['distance', 'ospf', 'intra-area', intra_area]) + + self.session.set(base_path + ['max-metric', 'router-lsa', 'on-startup', on_startup]) + self.session.set(base_path + ['max-metric', 'router-lsa', 'on-shutdown', on_shutdown]) + + self.session.set(base_path + ['mpls-te', 'enable']) + self.session.set(base_path + ['refresh', 'timers', refresh]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + self.assertIn(f' mpls-te on', frrconfig) + self.assertIn(f' mpls-te router-address 0.0.0.0', frrconfig) # default + self.assertIn(f' distance {global_distance}', frrconfig) + self.assertIn(f' distance ospf intra-area {intra_area} external {external}', frrconfig) + self.assertIn(f' max-metric router-lsa on-startup {on_startup}', frrconfig) + self.assertIn(f' max-metric router-lsa on-shutdown {on_shutdown}', frrconfig) + self.assertIn(f' refresh timer {refresh}', frrconfig) + + + # enable inter-area + self.session.set(base_path + ['distance', 'ospf', 'inter-area', inter_area]) + self.session.commit() + + frrconfig = getFRROSPFconfig() + self.assertIn(f' distance ospf intra-area {intra_area} inter-area {inter_area} external {external}', frrconfig) + + + def test_ospf_06_neighbor(self): + priority = '10' + poll_interval = '20' + neighbors = ['1.1.1.1', '2.2.2.2', '3.3.3.3'] + for neighbor in neighbors: + self.session.set(base_path + ['neighbor', neighbor, 'priority', priority]) + self.session.set(base_path + ['neighbor', neighbor, 'poll-interval', poll_interval]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + for neighbor in neighbors: + self.assertIn(f' neighbor {neighbor} priority {priority} poll-interval {poll_interval}', frrconfig) # default + + + def test_ospf_07_passive_interface(self): + self.session.set(base_path + ['passive-interface', 'default']) + interfaces = Section.interfaces('ethernet') + for interface in interfaces: + self.session.set(base_path + ['passive-interface-exclude', interface]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + self.assertIn(f' passive-interface default', frrconfig) # default + for interface in interfaces: + self.assertIn(f' no passive-interface {interface}', frrconfig) # default + + + def test_ospf_08_redistribute(self): + metric = '15' + metric_type = '1' + redistribute = ['bgp', 'connected', 'kernel', 'rip', 'static'] + + for protocol in redistribute: + self.session.set(base_path + ['redistribute', protocol, 'metric', metric]) + self.session.set(base_path + ['redistribute', protocol, 'route-map', route_map]) + if protocol not in ['kernel', 'static']: + self.session.set(base_path + ['redistribute', protocol, 'metric-type', metric_type]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + for protocol in redistribute: + if protocol in ['kernel', 'static']: + self.assertIn(f' redistribute {protocol} metric {metric} route-map {route_map}', frrconfig) + else: + self.assertIn(f' redistribute {protocol} metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig) + + + def test_ospf_09_area(self): + area = '0' + networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'] + for network in networks: + self.session.set(base_path + ['area', area, 'network', network]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + for network in networks: + self.assertIn(f' network {network} area {area}', frrconfig) + + + def test_ospf_10_virtual_link(self): + area = '10' + shortcut = 'enable' + virtual_link = '192.0.2.1' + hello = '6' + retransmit = '5' + transmit = '5' + dead = '40' + + self.session.set(base_path + ['area', area, 'shortcut', shortcut]) + self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'hello-interval', hello]) + self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'retransmit-interval', retransmit]) + self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'transmit-delay', transmit]) + self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'dead-interval', dead]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf', frrconfig) + self.assertIn(f' area {area} shortcut {shortcut}', frrconfig) + self.assertIn(f' area {area} virtual-link {virtual_link} hello-interval {hello} retransmit-interval {retransmit} transmit-delay {transmit} dead-interval {dead}', frrconfig) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py new file mode 100755 index 000000000..297d5d996 --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_ospfv3.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 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 +import unittest + +from vyos.configsession import ConfigSession +from vyos.ifconfig import Section +from vyos.util import cmd +from vyos.util import process_named_running + +PROCESS_NAME = 'ospf6d' +base_path = ['protocols', 'ospfv3'] + + +def getFRROSPFconfig(): + return cmd('vtysh -c "show run" | sed -n "/router ospf6/,/^!/p"') + +class TestProtocolsOSPFv3(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + def tearDown(self): + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + + self.session.delete(base_path) + self.session.commit() + del self.session + + + def test_ospfv3_01_basic(self): + area = '0' + seq = '10' + prefix = '2001:db8::/32' + acl_name = 'foo-acl-100' + router_id = '192.0.2.1' + + self.session.set(['policy', 'access-list6', acl_name, 'rule', seq, 'action', 'permit']) + self.session.set(['policy', 'access-list6', acl_name, 'rule', seq, 'source', 'any']) + + self.session.set(base_path + ['parameters', 'router-id', router_id]) + self.session.set(base_path + ['area', area, 'range', prefix, 'advertise']) + self.session.set(base_path + ['area', area, 'export-list', acl_name]) + self.session.set(base_path + ['area', area, 'import-list', acl_name]) + + interfaces = Section.interfaces('ethernet') + for interface in interfaces: + self.session.set(base_path + ['area', area, 'interface', interface]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf6', frrconfig) + self.assertIn(f' area {area} range {prefix}', frrconfig) + self.assertIn(f' ospf6 router-id {router_id}', frrconfig) + self.assertIn(f' area {area} import-list {acl_name}', frrconfig) + self.assertIn(f' area {area} export-list {acl_name}', frrconfig) + + for interface in interfaces: + self.assertIn(f' interface {interface} area {area}', frrconfig) + + self.session.delete(['policy', 'access-list6', acl_name]) + + + def test_ospfv3_02_distance(self): + dist_global = '200' + dist_external = '110' + dist_inter_area = '120' + dist_intra_area = '130' + + self.session.set(base_path + ['distance', 'global', dist_global]) + self.session.set(base_path + ['distance', 'ospfv3', 'external', dist_external]) + self.session.set(base_path + ['distance', 'ospfv3', 'inter-area', dist_inter_area]) + self.session.set(base_path + ['distance', 'ospfv3', 'intra-area', dist_intra_area]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf6', frrconfig) + self.assertIn(f' distance {dist_global}', frrconfig) + self.assertIn(f' distance ospf6 intra-area {dist_intra_area} inter-area {dist_inter_area} external {dist_external}', frrconfig) + + + def test_ospfv3_03_redistribute(self): + route_map = 'foo-bar' + route_map_seq = '10' + redistribute = ['bgp', 'connected', 'kernel', 'ripng', 'static'] + + self.session.set(['policy', 'route-map', route_map, 'rule', route_map_seq, 'action', 'permit']) + + for protocol in redistribute: + self.session.set(base_path + ['redistribute', protocol, 'route-map', route_map]) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf6', frrconfig) + for protocol in redistribute: + self.assertIn(f' redistribute {protocol} route-map {route_map}', frrconfig) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_service_ssh.py b/smoketest/scripts/cli/test_service_ssh.py index 1e099b0a5..68081e56f 100755 --- a/smoketest/scripts/cli/test_service_ssh.py +++ b/smoketest/scripts/cli/test_service_ssh.py @@ -29,6 +29,10 @@ SSHD_CONF = '/run/sshd/sshd_config' base_path = ['service', 'ssh'] vrf = 'mgmt' +key_rsa = '/etc/ssh/ssh_host_rsa_key' +key_dsa = '/etc/ssh/ssh_host_dsa_key' +key_ed25519 = '/etc/ssh/ssh_host_ed25519_key' + def get_config_value(key): tmp = read_file(SSHD_CONF) tmp = re.findall(f'\n?{key}\s+(.*)', tmp) @@ -47,6 +51,10 @@ class TestServiceSSH(unittest.TestCase): self.session.commit() del self.session + self.assertTrue(os.path.isfile(key_rsa)) + self.assertTrue(os.path.isfile(key_dsa)) + self.assertTrue(os.path.isfile(key_ed25519)) + def test_ssh_default(self): # Check if SSH service runs with default settings - used for checking # behavior of <defaultValue> in XML definition |