diff options
Diffstat (limited to 'smoketest/scripts/cli/test_policy.py')
-rwxr-xr-x | smoketest/scripts/cli/test_policy.py | 652 |
1 files changed, 532 insertions, 120 deletions
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py index 8efbab7e5..59425b789 100755 --- a/smoketest/scripts/cli/test_policy.py +++ b/smoketest/scripts/cli/test_policy.py @@ -14,26 +14,20 @@ # 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.util import cmd +from base_vyostest_shim import VyOSUnitTestSHIM + from vyos.configsession import ConfigSession from vyos.configsession import ConfigSessionError +from vyos.util import cmd base_path = ['policy'] -def getFRRconfig(section): - return cmd(f'vtysh -c "show run" | sed -n "/^{section}/,/^!/p"') - -class TestPolicy(unittest.TestCase): - def setUp(self): - self.session = ConfigSession(os.getpid()) - +class TestPolicy(VyOSUnitTestSHIM.TestCase): def tearDown(self): - self.session.delete(base_path) - self.session.commit() - del self.session + self.cli_delete(base_path) + self.cli_commit() def test_access_list(self): acls = { @@ -51,7 +45,7 @@ class TestPolicy(unittest.TestCase): }, '150' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'source' : { 'any' : '' }, 'destination' : { 'host' : '2.2.2.2' }, @@ -65,32 +59,32 @@ class TestPolicy(unittest.TestCase): }, '2000' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'destination' : { 'any' : '' }, 'source' : { 'network' : '10.0.0.0', 'inverse-mask' : '0.255.255.255' }, }, - '20' : { + '10' : { 'action' : 'permit', 'destination' : { 'any' : '' }, 'source' : { 'network' : '172.16.0.0', 'inverse-mask' : '0.15.255.255' }, }, - '30' : { + '15' : { 'action' : 'permit', 'destination' : { 'any' : '' }, 'source' : { 'network' : '192.168.0.0', 'inverse-mask' : '0.0.255.255' }, }, - '50' : { + '20' : { 'action' : 'permit', 'destination' : { 'network' : '172.16.0.0', 'inverse-mask' : '0.15.255.255' }, 'source' : { 'network' : '10.0.0.0', 'inverse-mask' : '0.255.255.255' }, }, - '60' : { + '25' : { 'action' : 'deny', 'destination' : { 'network' : '192.168.0.0', 'inverse-mask' : '0.0.255.255' }, 'source' : { 'network' : '172.16.0.0', 'inverse-mask' : '0.15.255.255' }, }, - '70' : { + '30' : { 'action' : 'deny', 'destination' : { 'any' : '' }, 'source' : { 'any' : '' }, @@ -101,29 +95,28 @@ class TestPolicy(unittest.TestCase): for acl, acl_config in acls.items(): path = base_path + ['access-list', acl] - self.session.set(path + ['description', f'VyOS-ACL-{acl}']) + self.cli_set(path + ['description', f'VyOS-ACL-{acl}']) if 'rule' not in acl_config: continue for rule, rule_config in acl_config['rule'].items(): - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) for direction in ['source', 'destination']: if direction in rule_config: if 'any' in rule_config[direction]: - self.session.set(path + ['rule', rule, direction, 'any']) + self.cli_set(path + ['rule', rule, direction, 'any']) if 'host' in rule_config[direction]: - self.session.set(path + ['rule', rule, direction, 'host', rule_config[direction]['host']]) + self.cli_set(path + ['rule', rule, direction, 'host', rule_config[direction]['host']]) if 'network' in rule_config[direction]: - self.session.set(path + ['rule', rule, direction, 'network', rule_config[direction]['network']]) - self.session.set(path + ['rule', rule, direction, 'inverse-mask', rule_config[direction]['inverse-mask']]) + self.cli_set(path + ['rule', rule, direction, 'network', rule_config[direction]['network']]) + self.cli_set(path + ['rule', rule, direction, 'inverse-mask', rule_config[direction]['inverse-mask']]) - self.session.commit() + self.cli_commit() - config = getFRRconfig('access-list') + config = self.getFRRconfig('access-list', end='') for acl, acl_config in acls.items(): - seq = '5' for rule, rule_config in acl_config['rule'].items(): - tmp = f'access-list {acl} seq {seq}' + tmp = f'access-list {acl} seq {rule}' if rule_config['action'] == 'permit': tmp += ' permit' else: @@ -137,12 +130,16 @@ class TestPolicy(unittest.TestCase): if 'any' in rule_config[direction]: tmp += ' any' if 'host' in rule_config[direction]: + # XXX: Some weird side rule from the old vyatta days + # possible to clean this up after the vyos-1x migration + if int(acl) in range(100, 200) or int(acl) in range(2000, 2700): + tmp += ' host' + tmp += ' ' + rule_config[direction]['host'] if 'network' in rule_config[direction]: tmp += ' ' + rule_config[direction]['network'] + ' ' + rule_config[direction]['inverse-mask'] self.assertIn(tmp, config) - seq = int(seq) + 5 def test_access_list6(self): acls = { @@ -156,7 +153,7 @@ class TestPolicy(unittest.TestCase): 'action' : 'deny', 'source' : { 'network' : '2001:db8:10::/48', 'exact-match' : '' }, }, - '10' : { + '15' : { 'action' : 'deny', 'source' : { 'network' : '2001:db8:20::/48' }, }, @@ -180,7 +177,7 @@ class TestPolicy(unittest.TestCase): 'action' : 'deny', 'source' : { 'network' : '2001:db8:40::/64', 'exact-match' : '' }, }, - '100' : { + '25' : { 'action' : 'deny', 'source' : { 'any' : '' }, }, @@ -190,28 +187,27 @@ class TestPolicy(unittest.TestCase): for acl, acl_config in acls.items(): path = base_path + ['access-list6', acl] - self.session.set(path + ['description', f'VyOS-ACL-{acl}']) + self.cli_set(path + ['description', f'VyOS-ACL-{acl}']) if 'rule' not in acl_config: continue for rule, rule_config in acl_config['rule'].items(): - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) for direction in ['source', 'destination']: if direction in rule_config: if 'any' in rule_config[direction]: - self.session.set(path + ['rule', rule, direction, 'any']) + self.cli_set(path + ['rule', rule, direction, 'any']) if 'network' in rule_config[direction]: - self.session.set(path + ['rule', rule, direction, 'network', rule_config[direction]['network']]) + self.cli_set(path + ['rule', rule, direction, 'network', rule_config[direction]['network']]) if 'exact-match' in rule_config[direction]: - self.session.set(path + ['rule', rule, direction, 'exact-match']) + self.cli_set(path + ['rule', rule, direction, 'exact-match']) - self.session.commit() + self.cli_commit() - config = getFRRconfig('ipv6 access-list') + config = self.getFRRconfig('ipv6 access-list', end='') for acl, acl_config in acls.items(): - seq = '5' for rule, rule_config in acl_config['rule'].items(): - tmp = f'ipv6 access-list {acl} seq {seq}' + tmp = f'ipv6 access-list {acl} seq {rule}' if rule_config['action'] == 'permit': tmp += ' permit' else: @@ -230,22 +226,21 @@ class TestPolicy(unittest.TestCase): tmp += ' exact-match' self.assertIn(tmp, config) - seq = int(seq) + 5 def test_as_path_list(self): test_data = { 'VyOS' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'regex' : '^44501 64502$', }, - '20' : { + '10' : { 'action' : 'permit', 'regex' : '44501|44502|44503', }, - '30' : { + '15' : { 'action' : 'permit', 'regex' : '^44501_([0-9]+_)+', }, @@ -253,19 +248,19 @@ class TestPolicy(unittest.TestCase): }, 'Customers' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'regex' : '_10_', }, - '20' : { + '10' : { 'action' : 'permit', 'regex' : '_20_', }, - '30' : { + '15' : { 'action' : 'permit', 'regex' : '_30_', }, - '30' : { + '20' : { 'action' : 'deny', 'regex' : '_40_', }, @@ -273,19 +268,19 @@ class TestPolicy(unittest.TestCase): }, 'bogons' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'regex' : '_0_', }, - '20' : { + '10' : { 'action' : 'permit', 'regex' : '_23456_', }, - '30' : { + '15' : { 'action' : 'permit', 'regex' : '_6449[6-9]_|_65[0-4][0-9][0-9]_|_655[0-4][0-9]_|_6555[0-1]_', }, - '30' : { + '20' : { 'action' : 'permit', 'regex' : '_6555[2-9]_|_655[6-9][0-9]_|_65[6-9][0-9][0-9]_|_6[6-9][0-9][0-9][0-]_|_[7-9][0-9][0-9][0-9][0-9]_|_1[0-2][0-9][0-9][0-9][0-9]_|_130[0-9][0-9][0-9]_|_1310[0-6][0-9]_|_13107[01]_', }, @@ -295,19 +290,19 @@ class TestPolicy(unittest.TestCase): for as_path, as_path_config in test_data.items(): path = base_path + ['as-path-list', as_path] - self.session.set(path + ['description', f'VyOS-ASPATH-{as_path}']) + self.cli_set(path + ['description', f'VyOS-ASPATH-{as_path}']) if 'rule' not in as_path_config: continue for rule, rule_config in as_path_config['rule'].items(): if 'action' in rule_config: - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) if 'regex' in rule_config: - self.session.set(path + ['rule', rule, 'regex', rule_config['regex']]) + self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']]) - self.session.commit() + self.cli_commit() - config = getFRRconfig('bgp as-path access-list') + config = self.getFRRconfig('bgp as-path access-list', end='') for as_path, as_path_config in test_data.items(): if 'rule' not in as_path_config: continue @@ -327,7 +322,7 @@ class TestPolicy(unittest.TestCase): test_data = { '100' : { 'rule' : { - '4' : { + '5' : { 'action' : 'permit', 'regex' : '.*', }, @@ -335,15 +330,15 @@ class TestPolicy(unittest.TestCase): }, '200' : { 'rule' : { - '1' : { + '5' : { 'action' : 'deny', 'regex' : '^1:201$', }, - '2' : { + '10' : { 'action' : 'deny', 'regex' : '1:101$', }, - '3' : { + '15' : { 'action' : 'deny', 'regex' : '^1:100$', }, @@ -353,26 +348,25 @@ class TestPolicy(unittest.TestCase): for comm_list, comm_list_config in test_data.items(): path = base_path + ['community-list', comm_list] - self.session.set(path + ['description', f'VyOS-COMM-{comm_list}']) + self.cli_set(path + ['description', f'VyOS-COMM-{comm_list}']) if 'rule' not in comm_list_config: continue for rule, rule_config in comm_list_config['rule'].items(): if 'action' in rule_config: - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) if 'regex' in rule_config: - self.session.set(path + ['rule', rule, 'regex', rule_config['regex']]) + self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']]) - self.session.commit() + self.cli_commit() - config = getFRRconfig('bgp community-list') + config = self.getFRRconfig('bgp community-list', end='') for comm_list, comm_list_config in test_data.items(): if 'rule' not in comm_list_config: continue - seq = '5' for rule, rule_config in comm_list_config['rule'].items(): - tmp = f'bgp community-list {comm_list} seq {seq}' + tmp = f'bgp community-list {comm_list} seq {rule}' if rule_config['action'] == 'permit': tmp += ' permit' else: @@ -381,13 +375,12 @@ class TestPolicy(unittest.TestCase): tmp += ' ' + rule_config['regex'] self.assertIn(tmp, config) - seq = int(seq) + 5 def test_extended_community_list(self): test_data = { 'foo' : { 'rule' : { - '4' : { + '5' : { 'action' : 'permit', 'regex' : '.*', }, @@ -395,15 +388,15 @@ class TestPolicy(unittest.TestCase): }, '200' : { 'rule' : { - '1' : { + '5' : { 'action' : 'deny', 'regex' : '^1:201$', }, - '2' : { + '10' : { 'action' : 'deny', 'regex' : '1:101$', }, - '3' : { + '15' : { 'action' : 'deny', 'regex' : '^1:100$', }, @@ -413,31 +406,30 @@ class TestPolicy(unittest.TestCase): for comm_list, comm_list_config in test_data.items(): path = base_path + ['extcommunity-list', comm_list] - self.session.set(path + ['description', f'VyOS-EXTCOMM-{comm_list}']) + self.cli_set(path + ['description', f'VyOS-EXTCOMM-{comm_list}']) if 'rule' not in comm_list_config: continue for rule, rule_config in comm_list_config['rule'].items(): if 'action' in rule_config: - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) if 'regex' in rule_config: - self.session.set(path + ['rule', rule, 'regex', rule_config['regex']]) + self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']]) - self.session.commit() + self.cli_commit() - config = getFRRconfig('bgp extcommunity-list') + config = self.getFRRconfig('bgp extcommunity-list', end='') for comm_list, comm_list_config in test_data.items(): if 'rule' not in comm_list_config: continue - seq = '5' for rule, rule_config in comm_list_config['rule'].items(): # if the community is not a number but a name, the expanded # keyword is used expanded = '' if not comm_list.isnumeric(): expanded = ' expanded' - tmp = f'bgp extcommunity-list{expanded} {comm_list} seq {seq}' + tmp = f'bgp extcommunity-list{expanded} {comm_list} seq {rule}' if rule_config['action'] == 'permit': tmp += ' permit' @@ -447,14 +439,13 @@ class TestPolicy(unittest.TestCase): tmp += ' ' + rule_config['regex'] self.assertIn(tmp, config) - seq = int(seq) + 5 def test_large_community_list(self): test_data = { 'foo' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'regex' : '667:123:100', }, @@ -462,15 +453,15 @@ class TestPolicy(unittest.TestCase): }, 'bar' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'regex' : '65000:120:10', }, - '20' : { + '10' : { 'action' : 'permit', 'regex' : '65000:120:20', }, - '30' : { + '15' : { 'action' : 'permit', 'regex' : '65000:120:30', }, @@ -480,26 +471,25 @@ class TestPolicy(unittest.TestCase): for comm_list, comm_list_config in test_data.items(): path = base_path + ['large-community-list', comm_list] - self.session.set(path + ['description', f'VyOS-LARGECOMM-{comm_list}']) + self.cli_set(path + ['description', f'VyOS-LARGECOMM-{comm_list}']) if 'rule' not in comm_list_config: continue for rule, rule_config in comm_list_config['rule'].items(): if 'action' in rule_config: - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) if 'regex' in rule_config: - self.session.set(path + ['rule', rule, 'regex', rule_config['regex']]) + self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']]) - self.session.commit() + self.cli_commit() - config = getFRRconfig('bgp large-community-list') + config = self.getFRRconfig('bgp large-community-list', end='') for comm_list, comm_list_config in test_data.items(): if 'rule' not in comm_list_config: continue - seq = '5' for rule, rule_config in comm_list_config['rule'].items(): - tmp = f'bgp large-community-list expanded {comm_list} seq {seq}' + tmp = f'bgp large-community-list expanded {comm_list} seq {rule}' if rule_config['action'] == 'permit': tmp += ' permit' @@ -509,25 +499,24 @@ class TestPolicy(unittest.TestCase): tmp += ' ' + rule_config['regex'] self.assertIn(tmp, config) - seq = int(seq) + 5 def test_prefix_list(self): test_data = { 'foo' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'prefix' : '10.0.0.0/8', 'ge' : '16', 'le' : '24', }, - '20' : { + '10' : { 'action' : 'deny', 'prefix' : '172.16.0.0/12', 'ge' : '16', }, - '30' : { + '15' : { 'action' : 'permit', 'prefix' : '192.168.0.0/16', }, @@ -535,18 +524,18 @@ class TestPolicy(unittest.TestCase): }, 'bar' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'prefix' : '10.0.10.0/24', 'ge' : '25', 'le' : '26', }, - '20' : { + '10' : { 'action' : 'deny', 'prefix' : '10.0.20.0/24', 'le' : '25', }, - '25' : { + '15' : { 'action' : 'permit', 'prefix' : '10.0.25.0/24', }, @@ -556,23 +545,23 @@ class TestPolicy(unittest.TestCase): for prefix_list, prefix_list_config in test_data.items(): path = base_path + ['prefix-list', prefix_list] - self.session.set(path + ['description', f'VyOS-PFX-LIST-{prefix_list}']) + self.cli_set(path + ['description', f'VyOS-PFX-LIST-{prefix_list}']) if 'rule' not in prefix_list_config: continue for rule, rule_config in prefix_list_config['rule'].items(): if 'action' in rule_config: - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) if 'prefix' in rule_config: - self.session.set(path + ['rule', rule, 'prefix', rule_config['prefix']]) + self.cli_set(path + ['rule', rule, 'prefix', rule_config['prefix']]) if 'ge' in rule_config: - self.session.set(path + ['rule', rule, 'ge', rule_config['ge']]) + self.cli_set(path + ['rule', rule, 'ge', rule_config['ge']]) if 'le' in rule_config: - self.session.set(path + ['rule', rule, 'le', rule_config['le']]) + self.cli_set(path + ['rule', rule, 'le', rule_config['le']]) - self.session.commit() + self.cli_commit() - config = getFRRconfig('ip prefix-list') + config = self.getFRRconfig('ip prefix-list', end='') for prefix_list, prefix_list_config in test_data.items(): if 'rule' not in prefix_list_config: continue @@ -599,18 +588,18 @@ class TestPolicy(unittest.TestCase): test_data = { 'foo' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'prefix' : '2001:db8::/32', 'ge' : '40', 'le' : '48', }, - '20' : { + '10' : { 'action' : 'deny', 'prefix' : '2001:db8::/32', 'ge' : '48', }, - '30' : { + '15' : { 'action' : 'permit', 'prefix' : '2001:db8:1000::/64', }, @@ -618,17 +607,17 @@ class TestPolicy(unittest.TestCase): }, 'bar' : { 'rule' : { - '10' : { + '5' : { 'action' : 'permit', 'prefix' : '2001:db8:100::/40', 'ge' : '48', }, - '20' : { + '10' : { 'action' : 'permit', 'prefix' : '2001:db8:200::/40', 'ge' : '48', }, - '25' : { + '15' : { 'action' : 'deny', 'prefix' : '2001:db8:300::/40', 'le' : '64', @@ -639,23 +628,23 @@ class TestPolicy(unittest.TestCase): for prefix_list, prefix_list_config in test_data.items(): path = base_path + ['prefix-list6', prefix_list] - self.session.set(path + ['description', f'VyOS-PFX-LIST-{prefix_list}']) + self.cli_set(path + ['description', f'VyOS-PFX-LIST-{prefix_list}']) if 'rule' not in prefix_list_config: continue for rule, rule_config in prefix_list_config['rule'].items(): if 'action' in rule_config: - self.session.set(path + ['rule', rule, 'action', rule_config['action']]) + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) if 'prefix' in rule_config: - self.session.set(path + ['rule', rule, 'prefix', rule_config['prefix']]) + self.cli_set(path + ['rule', rule, 'prefix', rule_config['prefix']]) if 'ge' in rule_config: - self.session.set(path + ['rule', rule, 'ge', rule_config['ge']]) + self.cli_set(path + ['rule', rule, 'ge', rule_config['ge']]) if 'le' in rule_config: - self.session.set(path + ['rule', rule, 'le', rule_config['le']]) + self.cli_set(path + ['rule', rule, 'le', rule_config['le']]) - self.session.commit() + self.cli_commit() - config = getFRRconfig('ipv6 prefix-list') + config = self.getFRRconfig('ipv6 prefix-list', end='') for prefix_list, prefix_list_config in test_data.items(): if 'rule' not in prefix_list_config: continue @@ -677,5 +666,428 @@ class TestPolicy(unittest.TestCase): self.assertIn(tmp, config) + def test_route_map(self): + access_list = '50' + as_path_list = '100' + test_interface = 'eth0' + community_list = 'BGP-comm-0815' + + # ext community name only allows alphanumeric characters and no hyphen :/ + # maybe change this if possible in vyos-1x rewrite + extcommunity_list = 'BGPextcomm123' + + large_community_list = 'bgp-large-community-123456' + prefix_list = 'foo-pfx-list' + ipv6_nexthop = 'fe80::1' + local_pref = '300' + metric = '50' + peer = '2.3.4.5' + tag = '6542' + goto = '25' + + test_data = { + 'foo-map-bar' : { + 'rule' : { + '5' : { + 'action' : 'permit', + 'continue' : '20', + }, + '10' : { + 'action' : 'permit', + 'call' : 'complicated-configuration', + }, + }, + }, + 'a-matching-rule-0815': { + 'rule' : { + '5' : { + 'action' : 'deny', + 'match' : { + 'as-path' : as_path_list, + 'rpki-invalid': '', + 'tag': tag, + }, + }, + '10' : { + 'action' : 'permit', + 'match' : { + 'community' : community_list, + 'interface' : test_interface, + 'rpki-not-found': '', + }, + }, + '15' : { + 'action' : 'permit', + 'match' : { + 'extcommunity' : extcommunity_list, + 'rpki-valid': '', + }, + 'on-match' : { + 'next' : '', + }, + }, + '20' : { + 'action' : 'permit', + 'match' : { + 'ip-address-acl': access_list, + 'ip-nexthop-acl': access_list, + 'ip-route-source-acl': access_list, + 'ipv6-address-acl': access_list, + 'origin-incomplete' : '', + }, + 'on-match' : { + 'goto' : goto, + }, + }, + '25' : { + 'action' : 'permit', + 'match' : { + 'ip-address-pfx': prefix_list, + 'ip-nexthop-pfx': prefix_list, + 'ip-route-source-pfx': prefix_list, + 'ipv6-address-pfx': prefix_list, + 'origin-igp': '', + }, + }, + '30' : { + 'action' : 'permit', + 'match' : { + 'ipv6-nexthop' : ipv6_nexthop, + 'large-community' : large_community_list, + 'local-pref' : local_pref, + 'metric': metric, + 'origin-egp': '', + 'peer' : peer, + }, + }, + }, + }, + 'complicated-configuration' : { + 'rule' : { + '10' : { + 'action' : 'deny', + 'set' : { + 'aggregator-as' : '1234567890', + 'aggregator-ip' : '10.255.255.0', + 'as-path-exclude' : '1234', + 'as-path-prepend' : '1234567890 987654321', + 'atomic-aggregate' : '', + 'distance' : '110', + 'ipv6-next-hop-global': '2001::1', + 'ipv6-next-hop-local' : 'fe80::1', + 'ip-next-hop' : '192.168.1.1', + 'large-community' : '100:200:300', + 'local-preference' : '500', + 'metric' : '150', + 'metric-type' : 'type-1', + 'origin' : 'incomplete', + 'originator-id' : '172.16.10.1', + 'src' : '100.0.0.1', + 'tag' : '65530', + 'weight' : '2', + }, + }, + }, + }, + } + + self.cli_set(['policy', 'access-list', access_list, 'rule', '10', 'action', 'permit']) + self.cli_set(['policy', 'access-list', access_list, 'rule', '10', 'source', 'host', '1.1.1.1']) + self.cli_set(['policy', 'access-list6', access_list, 'rule', '10', 'action', 'permit']) + self.cli_set(['policy', 'access-list6', access_list, 'rule', '10', 'source', 'network', '2001:db8::/32']) + + self.cli_set(['policy', 'as-path-list', as_path_list, 'rule', '10', 'action', 'permit']) + self.cli_set(['policy', 'as-path-list', as_path_list, 'rule', '10', 'regex', '64501 64502']) + self.cli_set(['policy', 'community-list', community_list, 'rule', '10', 'action', 'deny']) + self.cli_set(['policy', 'community-list', community_list, 'rule', '10', 'regex', '65432']) + self.cli_set(['policy', 'extcommunity-list', extcommunity_list, 'rule', '10', 'action', 'deny']) + self.cli_set(['policy', 'extcommunity-list', extcommunity_list, 'rule', '10', 'regex', '65000']) + self.cli_set(['policy', 'large-community-list', large_community_list, 'rule', '10', 'action', 'permit']) + self.cli_set(['policy', 'large-community-list', large_community_list, 'rule', '10', 'regex', '100:200:300']) + + self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', '10', 'action', 'permit']) + self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', '10', 'prefix', '192.0.2.0/24']) + self.cli_set(['policy', 'prefix-list6', prefix_list, 'rule', '10', 'action', 'permit']) + self.cli_set(['policy', 'prefix-list6', prefix_list, 'rule', '10', 'prefix', '2001:db8::/32']) + + for route_map, route_map_config in test_data.items(): + path = base_path + ['route-map', route_map] + self.cli_set(path + ['description', f'VyOS ROUTE-MAP {route_map}']) + if 'rule' not in route_map_config: + continue + + for rule, rule_config in route_map_config['rule'].items(): + if 'action' in rule_config: + self.cli_set(path + ['rule', rule, 'action', rule_config['action']]) + + if 'call' in rule_config: + self.cli_set(path + ['rule', rule, 'call', rule_config['call']]) + + if 'continue' in rule_config: + self.cli_set(path + ['rule', rule, 'continue', rule_config['continue']]) + + if 'match' in rule_config: + if 'as-path' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'as-path', rule_config['match']['as-path']]) + if 'community' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'community', 'community-list', rule_config['match']['community']]) + self.cli_set(path + ['rule', rule, 'match', 'community', 'exact-match']) + if 'extcommunity' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'extcommunity', rule_config['match']['extcommunity']]) + if 'interface' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'interface', rule_config['match']['interface']]) + if 'ip-address-acl' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ip', 'address', 'access-list', rule_config['match']['ip-address-acl']]) + if 'ip-address-pfx' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ip', 'address', 'prefix-list', rule_config['match']['ip-address-pfx']]) + if 'ip-nexthop-acl' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ip', 'nexthop', 'access-list', rule_config['match']['ip-nexthop-acl']]) + if 'ip-nexthop-pfx' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ip', 'nexthop', 'prefix-list', rule_config['match']['ip-nexthop-pfx']]) + if 'ip-route-source-acl' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ip', 'route-source', 'access-list', rule_config['match']['ip-route-source-acl']]) + if 'ip-route-source-pfx' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ip', 'route-source', 'prefix-list', rule_config['match']['ip-route-source-pfx']]) + if 'ipv6-address-acl' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'address', 'access-list', rule_config['match']['ipv6-address-acl']]) + if 'ipv6-address-pfx' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'address', 'prefix-list', rule_config['match']['ipv6-address-pfx']]) + if 'ipv6-nexthop' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', rule_config['match']['ipv6-nexthop']]) + if 'large-community' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'large-community', 'large-community-list', rule_config['match']['large-community']]) + if 'local-pref' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'local-preference', rule_config['match']['local-pref']]) + if 'metric' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'metric', rule_config['match']['metric']]) + if 'origin-igp' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'origin', 'igp']) + if 'origin-egp' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'origin', 'egp']) + if 'origin-incomplete' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'origin', 'incomplete']) + if 'peer' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'peer', rule_config['match']['peer']]) + if 'rpki-invalid' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'rpki', 'invalid']) + if 'rpki-not-found' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'rpki', 'notfound']) + if 'rpki-valid' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'rpki', 'valid']) + if 'tag' in rule_config['match']: + self.cli_set(path + ['rule', rule, 'match', 'tag', rule_config['match']['tag']]) + + if 'on-match' in rule_config: + if 'goto' in rule_config['on-match']: + self.cli_set(path + ['rule', rule, 'on-match', 'goto', rule_config['on-match']['goto']]) + if 'next' in rule_config['on-match']: + self.cli_set(path + ['rule', rule, 'on-match', 'next']) + + if 'set' in rule_config: + if 'aggregator-as' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'aggregator', 'as', rule_config['set']['aggregator-as']]) + if 'aggregator-ip' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'aggregator', 'ip', rule_config['set']['aggregator-ip']]) + if 'as-path-exclude' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'as-path-exclude', rule_config['set']['as-path-exclude']]) + if 'as-path-prepend' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'as-path-prepend', rule_config['set']['as-path-prepend']]) + if 'atomic-aggregate' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'atomic-aggregate']) + if 'distance' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'distance', rule_config['set']['distance']]) + if 'ipv6-next-hop-global' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'ipv6-next-hop', 'global', rule_config['set']['ipv6-next-hop-global']]) + if 'ipv6-next-hop-local' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'ipv6-next-hop', 'local', rule_config['set']['ipv6-next-hop-local']]) + if 'ip-next-hop' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'ip-next-hop', rule_config['set']['ip-next-hop']]) + if 'large-community' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'large-community', rule_config['set']['large-community']]) + if 'local-preference' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'local-preference', rule_config['set']['local-preference']]) + if 'metric' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'metric', rule_config['set']['metric']]) + if 'metric-type' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'metric-type', rule_config['set']['metric-type']]) + if 'origin' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'origin', rule_config['set']['origin']]) + if 'originator-id' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'originator-id', rule_config['set']['originator-id']]) + if 'src' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'src', rule_config['set']['src']]) + if 'tag' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'tag', rule_config['set']['tag']]) + if 'weight' in rule_config['set']: + self.cli_set(path + ['rule', rule, 'set', 'weight', rule_config['set']['weight']]) + + self.cli_commit() + + for route_map, route_map_config in test_data.items(): + if 'rule' not in route_map_config: + continue + for rule, rule_config in route_map_config['rule'].items(): + name = f'route-map {route_map} {rule_config["action"]} {rule}' + config = self.getFRRconfig(name) + self.assertIn(name, config) + + if 'call' in rule_config: + tmp = 'call ' + rule_config['call'] + self.assertIn(tmp, config) + + if 'continue' in rule_config: + tmp = 'on-match goto ' + rule_config['continue'] + self.assertIn(tmp, config) + + if 'match' in rule_config: + if 'as-path' in rule_config['match']: + tmp = 'match as-path ' + rule_config['match']['as-path'] + self.assertIn(tmp, config) + if 'community' in rule_config['match']: + tmp = f'match community {rule_config["match"]["community"]} exact-match' + self.assertIn(tmp, config) + if 'extcommunity' in rule_config['match']: + tmp = f'match extcommunity {rule_config["match"]["extcommunity"]}' + self.assertIn(tmp, config) + if 'interface' in rule_config['match']: + tmp = f'match interface {rule_config["match"]["interface"]}' + self.assertIn(tmp, config) + if 'ip-address-acl' in rule_config['match']: + tmp = f'match ip address {rule_config["match"]["ip-address-acl"]}' + self.assertIn(tmp, config) + if 'ip-address-pfx' in rule_config['match']: + tmp = f'match ip address prefix-list {rule_config["match"]["ip-address-pfx"]}' + self.assertIn(tmp, config) + if 'ip-nexthop-acl' in rule_config['match']: + tmp = f'match ip next-hop {rule_config["match"]["ip-nexthop-acl"]}' + self.assertIn(tmp, config) + if 'ip-nexthop-pfx' in rule_config['match']: + tmp = f'match ip next-hop prefix-list {rule_config["match"]["ip-nexthop-pfx"]}' + self.assertIn(tmp, config) + if 'ip-route-source-acl' in rule_config['match']: + tmp = f'match ip route-source {rule_config["match"]["ip-route-source-acl"]}' + self.assertIn(tmp, config) + if 'ip-route-source-pfx' in rule_config['match']: + tmp = f'match ip route-source prefix-list {rule_config["match"]["ip-route-source-pfx"]}' + self.assertIn(tmp, config) + if 'ipv6-address-acl' in rule_config['match']: + tmp = f'match ipv6 address {rule_config["match"]["ipv6-address-acl"]}' + self.assertIn(tmp, config) + if 'ipv6-address-pfx' in rule_config['match']: + tmp = f'match ipv6 address prefix-list {rule_config["match"]["ipv6-address-pfx"]}' + self.assertIn(tmp, config) + if 'ipv6-nexthop' in rule_config['match']: + tmp = f'match ipv6 next-hop {rule_config["match"]["ipv6-nexthop"]}' + self.assertIn(tmp, config) + if 'large-community' in rule_config['match']: + tmp = f'match large-community {rule_config["match"]["large-community"]}' + self.assertIn(tmp, config) + if 'local-pref' in rule_config['match']: + tmp = f'match local-preference {rule_config["match"]["local-pref"]}' + self.assertIn(tmp, config) + if 'metric' in rule_config['match']: + tmp = f'match metric {rule_config["match"]["metric"]}' + self.assertIn(tmp, config) + if 'origin-igp' in rule_config['match']: + tmp = f'match origin igp' + self.assertIn(tmp, config) + if 'origin-egp' in rule_config['match']: + tmp = f'match origin egp' + self.assertIn(tmp, config) + if 'origin-incomplete' in rule_config['match']: + tmp = f'match origin incomplete' + self.assertIn(tmp, config) + if 'peer' in rule_config['match']: + tmp = f'match peer {rule_config["match"]["peer"]}' + self.assertIn(tmp, config) + if 'rpki-invalid' in rule_config['match']: + tmp = f'match rpki invalid' + self.assertIn(tmp, config) + if 'rpki-not-found' in rule_config['match']: + tmp = f'match rpki notfound' + self.assertIn(tmp, config) + if 'rpki-valid' in rule_config['match']: + tmp = f'match rpki valid' + self.assertIn(tmp, config) + if 'tag' in rule_config['match']: + tmp = f'match tag {rule_config["match"]["tag"]}' + self.assertIn(tmp, config) + + if 'on-match' in rule_config: + if 'goto' in rule_config['on-match']: + tmp = f'on-match goto {rule_config["on-match"]["goto"]}' + self.assertIn(tmp, config) + if 'next' in rule_config['on-match']: + tmp = f'on-match next' + self.assertIn(tmp, config) + + if 'set' in rule_config: + tmp = ' set ' + if 'aggregator-as' in rule_config['set']: + tmp += 'aggregator as ' + rule_config['set']['aggregator-as'] + elif 'aggregator-ip' in rule_config['set']: + tmp += ' ' + rule_config['set']['aggregator-ip'] + elif 'as-path-exclude' in rule_config['set']: + tmp += 'as-path exclude ' + rule_config['set']['as-path-exclude'] + elif 'as-path-prepend' in rule_config['set']: + tmp += 'as-path prepend ' + rule_config['set']['as-path-prepend'] + elif 'atomic-aggregate' in rule_config['set']: + tmp += 'atomic-aggregate' + elif 'distance' in rule_config['set']: + tmp += 'distance ' + rule_config['set']['distance'] + elif 'ip-next-hop' in rule_config['set']: + tmp += 'ip next-hop ' + rule_config['set']['ip-next-hop'] + elif 'ipv6-next-hop-global' in rule_config['set']: + tmp += 'ipv6 next-hop global ' + rule_config['set']['ipv6-next-hop-global'] + elif 'ipv6-next-hop-local' in rule_config['set']: + tmp += 'ipv6 next-hop local ' + rule_config['set']['ipv6-next-hop-local'] + elif 'large-community' in rule_config['set']: + tmp += 'large-community ' + rule_config['set']['large-community'] + elif 'local-preference' in rule_config['set']: + tmp += 'local-preference ' + rule_config['set']['local-preference'] + elif 'metric' in rule_config['set']: + tmp += 'metric ' + rule_config['set']['metric'] + elif 'metric-type' in rule_config['set']: + tmp += 'metric-type ' + rule_config['set']['metric-type'] + elif 'origin' in rule_config['set']: + tmp += 'origin ' + rule_config['set']['origin'] + elif 'originator-id' in rule_config['set']: + tmp += 'originator-id ' + rule_config['set']['originator-id'] + elif 'src' in rule_config['set']: + tmp += 'src ' + rule_config['set']['src'] + elif 'tag' in rule_config['set']: + tmp += 'tag ' + rule_config['set']['tag'] + elif 'weight' in rule_config['set']: + tmp += 'weight ' + rule_config['set']['weight'] + + self.assertIn(tmp, config) + + + # Test set table for some sources + def test_table_id(self): + path = base_path + ['local-route'] + + sources = ['203.0.113.1', '203.0.113.2'] + rule = '50' + table = '23' + for src in sources: + self.cli_set(path + ['rule', rule, 'set', 'table', table]) + self.cli_set(path + ['rule', rule, 'source', src]) + + self.cli_commit() + + # Check generated configuration + + # Expected values + original = """ + 50: from 203.0.113.1 lookup 23 + 50: from 203.0.113.2 lookup 23 + """ + tmp = cmd('ip rule show prio 50') + original = original.split() + tmp = tmp.split() + + self.assertEqual(tmp, original) + if __name__ == '__main__': unittest.main(verbosity=2) |