def test_basic_uncfg(self): Genie.testbed = testbed = Testbed() dev1 = Device(testbed=testbed, name='PE1', os='nxos') dev2 = Device(testbed=testbed, name='PE2', os='nxos') rpl1 = RoutePolicy(policy_definition='rpl1', route_disposition='permit') dev1.add_feature(rpl1) rpl1.device_attr[dev1].statement_attr['10'] rpl1.device_attr[dev1].statement_attr['10'].match_med_eq = 5 # Unconfig testing # Set a mock dev1.configure = Mock() dev1.add_feature(rpl1) # Mock config uncfg1 = rpl1.build_unconfig(apply=False) self.assertCountEqual(uncfg1.keys(), ['PE1']) self.assertMultiLineEqual(str(uncfg1['PE1']), '\n'.join(['no route-map rpl1 permit 10'])) partial_uncfg1 = rpl1.build_unconfig( apply=False, attributes={'device_attr':{'*':{'statement_attr':\ {'*':"match_med_eq"}}}}) self.assertCountEqual(partial_uncfg1.keys(), ['PE1']) self.assertMultiLineEqual( str(partial_uncfg1['PE1']), '\n'.join( ['route-map rpl1 permit 10', ' no match metric 5', ' exit']))
def test_basic_uncfg_with_name(self): ''' Testing in case of having 'name' as the route-policy name. ''' Genie.testbed = testbed = Testbed() dev1 = Device(testbed=testbed, name='PE1', os='iosxr') rpl1 = RoutePolicy(name='rpl1') dev1.add_feature(rpl1) rpl1.device_attr[dev1].statement_attr['10'] rpl1.device_attr[dev1].statement_attr['10'].match_med_eq = 5 rpl1.device_attr[dev1].statement_attr['10'].match_nexthop_in = 'hop' rpl1.device_attr[dev1].statement_attr['10'].actions = 'pass' # Unconfig testing # Set a mock dev1.configure = Mock() dev1.add_feature(rpl1) # Mock config uncfg1 = rpl1.build_unconfig(apply=False) self.assertCountEqual(uncfg1.keys(), ['PE1']) self.assertMultiLineEqual(str(uncfg1['PE1']), '\n'.join( ['no route-policy rpl1' ]))
def test_basic_cfg(self): Genie.testbed = testbed = Testbed() dev1 = Device(testbed=testbed, name='PE1', os='nxos') intf1 = Interface(device=dev1, name='Ethernet0/0/1', ipv4='10.1.0.1/24') intf2 = Interface(device=dev1, name='Ethernet0/0/2', ipv4='10.2.0.1/24') dev2 = Device(testbed=testbed, name='PE2', os='nxos') intf3 = Interface(device=dev2, name='Ethernet0/0/3', ipv4='10.1.0.2/24', ipv6='2001:111:222::/64') intf4 = Interface(device=dev2, name='Ethernet0/0/4', ipv4='10.2.0.2/24') rpl1 = RoutePolicy(policy_definition='rpl1', route_disposition='permit') dev1.add_feature(rpl1) rpl1.device_attr[dev1].statement_attr['10'] rpl1.device_attr[dev1].statement_attr['10'].match_med_eq = 5 cfgs = rpl1.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineEqual( str(cfgs[dev1.name]), '\n'.join(['route-map rpl1 permit 10', ' match metric 5', ' exit'])) # import pdb; pdb.set_trace() rpl2 = RoutePolicy(policy_definition='rpl2', route_disposition='deny') dev2.add_feature(rpl2) rpl2.device_attr[dev2].statement_attr['20'] rpl2.device_attr[dev2].statement_attr['20'].set_metric_type = \ 'internal' rpl2.device_attr[dev2].statement_attr['20'].set_ext_community_rt = \ ['100:100','200:200'] rpl2.device_attr[dev2].statement_attr['20'].\ set_ext_community_rt_additive = True cfgs = rpl2.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev2.name]) self.assertMultiLineEqual( str(cfgs[dev2.name]), '\n'.join([ "route-map rpl2 deny 20", " set extcommunity rt ['100:100', '200:200'] additive", " set metric-type internal", " exit" ]))
def test_basic_cfg(self): Genie.testbed = testbed = Testbed() dev1 = Device(testbed=testbed, name='PE1', os='iosxe') dev2 = Device(testbed=testbed, name='PE2', os='iosxe') rpl1 = RoutePolicy(policy_definition='rpl1', route_disposition='permit') dev1.add_feature(rpl1) rpl1.device_attr[dev1].statement_attr['10'] rpl1.device_attr[dev1].statement_attr['10'].match_med_eq = 5 rpl1.device_attr[dev1].statement_attr['10'].description = 'test' rpl1.device_attr[dev1].statement_attr['10'].match_nexthop_in = '10' rpl1.device_attr[dev1].statement_attr['10'].match_nexthop_in_v6 = '30' rpl1.device_attr[dev1].statement_attr['10'].match_local_pref_eq = 40 rpl1.device_attr[dev1].statement_attr['10'].match_route_type = 'internal' rpl1.device_attr[dev1].statement_attr['10'].match_community_list = \ 'community-list1' rpl1.device_attr[dev1].statement_attr['10'].match_ext_community_list = \ 'community-list2' rpl1.device_attr[dev1].statement_attr['10'].match_as_path_list = \ '100' rpl1.device_attr[dev1].statement_attr['10'].match_level_eq = \ 'level-1-2' rpl1.device_attr[dev1].statement_attr['10'].match_interface = \ 'GigabitEthernet3/0/1' rpl1.device_attr[dev1].statement_attr['10'].match_prefix_list = \ 'prefixlist1' rpl1.device_attr[dev1].statement_attr['10'].match_prefix_list_v6 = \ 'prefixlist1v6' rpl1.device_attr[dev1].statement_attr['10'].match_tag_list = \ 'match_tag_list' rpl1.device_attr[dev1].statement_attr['10'].set_route_origin = \ 'igp' rpl1.device_attr[dev1].statement_attr['10'].set_local_pref = \ 100 rpl1.device_attr[dev1].statement_attr['10'].set_next_hop = \ '1.1.1.1' rpl1.device_attr[dev1].statement_attr['10'].set_next_hop_v6 = \ '2001:db8:1::1' rpl1.device_attr[dev1].statement_attr['10'].set_next_hop_self = \ True rpl1.device_attr[dev1].statement_attr['10'].set_med = \ '100' rpl1.device_attr[dev1].statement_attr['10'].set_as_path_prepend = \ '100' rpl1.device_attr[dev1].statement_attr['10'].set_as_path_prepend_n = \ 3 rpl1.device_attr[dev1].statement_attr['10'].set_community = \ ['100:100', '200:200'] rpl1.device_attr[dev1].statement_attr['10'].set_community_no_export = \ True rpl1.device_attr[dev1].statement_attr['10'].set_community_no_advertise = \ True rpl1.device_attr[dev1].statement_attr['10'].set_community_additive = \ True rpl1.device_attr[dev1].statement_attr['10'].set_community_delete = \ 'communit_list' rpl1.device_attr[dev1].statement_attr['10'].set_ext_community_rt = \ ['100:10'] rpl1.device_attr[dev1].statement_attr['10'].set_ext_community_rt_additive = \ True rpl1.device_attr[dev1].statement_attr['10'].set_ext_community_soo = \ '100:10' rpl1.device_attr[dev1].statement_attr['10'].set_ext_community_vpn = \ '100:10' rpl1.device_attr[dev1].statement_attr['10'].set_ext_community_delete = \ 'community_list' rpl1.device_attr[dev1].statement_attr['10'].set_level = \ 'level-1' rpl1.device_attr[dev1].statement_attr['10'].set_metric_type = \ 'internal' rpl1.device_attr[dev1].statement_attr['10'].set_metric = \ 30 rpl1.device_attr[dev1].statement_attr['10'].set_ospf_metric_type = \ 'type-1' rpl1.device_attr[dev1].statement_attr['10'].set_ospf_metric = \ 200 rpl1.device_attr[dev1].statement_attr['10'].set_tag = \ 111 rpl1.device_attr[dev1].statement_attr['10'].set_weight = \ 100 self.maxDiff = None cfgs = rpl1.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineEqual(str(cfgs[dev1.name]), '\n'.join( ['route-map rpl1 permit 10', ' description test', ' match metric 5', ' match ip next-hop prefix-list 10', ' match ipv6 next-hop prefix-list 30', ' match local-preference 40', ' match route-type internal', ' match community community-list1', ' match extcommunity community-list2', ' match as-path 100', ' match route-type level-1', ' match route-type level-2', ' match interface GigabitEthernet3/0/1', ' match ip address prefix-list prefixlist1', ' match ipv6 address prefix-list prefixlist1v6', ' match tag list match_tag_list', ' set origin igp', ' set local-preference 100', ' set ip next-hop 1.1.1.1', ' set ipv6 next-hop 2001:db8:1::1', ' set ip next-hop self', ' set metric 100', " set community 100:100 200:200 no-export no-advertise additive", ' set comm-list communit_list delete', " set extcommunity rt 100:10 additive", ' set extcommunity soo 100:10', ' set extcommunity vpn-distinguisher 100:10', ' set extcomm-list community_list delete', ' set level level-1', ' set metric-type internal', ' set metric 30', ' set metric-type type-1', ' set metric 200', ' set tag 111', ' set weight 100', ' exit' ])) # import pdb; pdb.set_trace() rpl2 = RoutePolicy(policy_definition='rpl2', route_disposition='deny') dev2.add_feature(rpl2) rpl2.device_attr[dev2].statement_attr['20'] rpl2.device_attr[dev2].statement_attr['20'].set_metric_type = \ 'internal' cfgs = rpl2.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev2.name]) self.assertMultiLineEqual(str(cfgs[dev2.name]), '\n'.join( ['route-map rpl2 deny 20', ' set metric-type internal', ' exit' ])) uncfg1 = rpl1.build_unconfig(apply=False) self.assertCountEqual(uncfg1.keys(), [dev1.name]) self.assertMultiLineEqual( str(uncfg1[dev1.name]), '\n'.join([ 'no route-map rpl1 permit 10' ])) partial_uncfg1 = rpl1.build_unconfig( apply=False, attributes={'device_attr':{'*':{'statement_attr':\ {'*':"match_med_eq"}}}}) self.assertCountEqual(partial_uncfg1.keys(), [dev1.name]) self.assertMultiLineEqual( str(partial_uncfg1[dev1.name]), '\n'.join([ 'route-map rpl1 permit 10', ' no match metric 5', ' exit' ]))
def test_init(self): Genie.testbed = testbed = Testbed() dev1 = Device(testbed=testbed, name='PE1', os='iosxr') intf1 = Interface(device=dev1, name='GigabitEthernet0/0/0/1', ipv4='10.1.0.1/24') intf2 = Interface(device=dev1, name='GigabitEthernet0/0/0/2', ipv4='10.2.0.1/24') dev2 = Device(testbed=testbed, name='PE2', os='iosxr') intf3 = Interface(device=dev2, name='GigabitEthernet0/0/0/3', ipv4='10.1.0.2/24') intf4 = Interface(device=dev2, name='GigabitEthernet0/0/0/4', ipv4='10.2.0.2/24') vrf1 = Vrf(name='vrf1') vrf2 = Vrf(name='a') # must be < 'default' with self.assertNoWarnings(): Genie.testbed = None with self.assertRaises(TypeError): bgp = Bgp() with self.assertRaises(TypeError): bgp = Bgp(testbed=testbed) Genie.testbed = testbed with self.assertRaises(TypeError): bgp = Bgp() bgp = Bgp(asn=100) self.assertIs(bgp.testbed, testbed) Genie.testbed = testbed bgp = Bgp(asn=100) self.assertIs(bgp.testbed, Genie.testbed) self.assertIs(bgp.testbed, testbed) dev1.add_feature(bgp) cfgs = bgp.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineEqual(str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' exit', ])) dev2.add_feature(bgp) cfgs = bgp.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name, dev2.name]) self.assertMultiLineEqual(str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' exit', ])) self.assertMultiLineEqual(str(cfgs[dev2.name]), '\n'.join([ 'router bgp 100', ' exit', ])) ospf1 = Ospf(pid=1) isis1 = Isis(pid=1) rtepol1 = RoutePolicy(name='rtepol1') bgp.redistributes = ( 'connected', Redistribution(ospf1, metric=20), Redistribution(isis1, route_policy=rtepol1), ) bgp.device_attr[dev1].address_family_attr['ipv4 unicast'] bgp.device_attr[dev2].address_family_attr['ipv4 unicast'] cfgs = bgp.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name, dev2.name]) self.assertMultiLineEqual( str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' address-family ipv4 unicast', ' redistribute connected', ' redistribute ospf 1 metric 20', ' redistribute isis 1 route-policy rtepol1', ' exit', ' exit', ])) self.assertMultiLineEqual( str(cfgs[dev2.name]), '\n'.join([ 'router bgp 100', ' address-family ipv4 unicast', ' redistribute connected', ' redistribute ospf 1 metric 20', ' redistribute isis 1 route-policy rtepol1', ' exit', ' exit', ])) del bgp.redistributes bgp.device_attr[dev1].add_neighbor(intf3.ipv4) bgp.device_attr[dev1].neighbor_attr[intf3.ipv4].\ address_family_attr['ipv4 unicast'] bgp.device_attr[dev1].add_vrf(vrf1) bgp.device_attr[dev1].vrf_attr[vrf1].address_family_attr[ 'ipv4 unicast'] bgp.device_attr[dev1].vrf_attr[vrf1].add_neighbor(intf4.ipv4) bgp.device_attr[dev1].vrf_attr[vrf1].neighbor_attr[intf4.ipv4].\ address_family_attr['ipv4 unicast'] bgp.device_attr[dev1].add_vrf(vrf2) bgp.device_attr[dev1].vrf_attr[vrf2].address_family_attr[ 'ipv4 unicast'] cfgs = bgp.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name, dev2.name]) self.assertMultiLineEqual( str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' address-family ipv4 unicast', ' exit', ' neighbor 10.1.0.2', ' remote-as 100', ' address-family ipv4 unicast', ' exit', ' exit', ' vrf a', ' address-family ipv4 unicast', ' exit', ' exit', ' vrf vrf1', ' address-family ipv4 unicast', ' exit', ' neighbor 10.2.0.2', ' remote-as 100', ' address-family ipv4 unicast', ' exit', ' exit', ' exit', ' exit', ])) self.assertMultiLineEqual( str(cfgs[dev2.name]), '\n'.join([ 'router bgp 100', ' address-family ipv4 unicast', ' exit', ' exit', ])) cfgs = bgp.build_config( apply=False, attributes='device_attr__PE1__vrf_attr__default') self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineEqual( str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' address-family ipv4 unicast', ' exit', ' neighbor 10.1.0.2', ' remote-as 100', ' address-family ipv4 unicast', ' exit', ' exit', ' exit', ])) cfgs = bgp.build_config(apply=False, attributes={ 'device_attr': { '*': (), }, }) self.assertCountEqual(cfgs.keys(), [dev1.name, dev2.name]) self.assertMultiLineEqual(str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' exit', ])) self.assertMultiLineEqual(str(cfgs[dev2.name]), '\n'.join([ 'router bgp 100', ' exit', ])) cfgs = bgp.build_config(apply=False, attributes={ 'device_attr': { 'PE1': 'vrf_attr__default', }, }) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineEqual( str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' address-family ipv4 unicast', ' exit', ' neighbor 10.1.0.2', ' remote-as 100', ' address-family ipv4 unicast', ' exit', ' exit', ' exit', ])) cfgs = bgp.build_config( apply=False, attributes={ 'device_attr': { 'PE1': 'vrf_attr__default__neighbor_attr__10.1.0.2', }, }) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineEqual( str(cfgs[dev1.name]), '\n'.join([ 'router bgp 100', ' neighbor 10.1.0.2', ' remote-as 100', ' address-family ipv4 unicast', ' exit', ' exit', ' exit', ]))
def test_basic_cfg(self): Genie.testbed = testbed = Testbed() dev1 = Device(testbed=testbed, name='PE1', os='iosxr') dev2 = Device(testbed=testbed, name='PE2', os='iosxr') rpl1 = RoutePolicy(policy_definition='rpl1') dev1.add_feature(rpl1) rpl1.device_attr[dev1].statement_attr[10] rpl1.device_attr[dev1].statement_attr[10].match_med_eq = 5 rpl1.device_attr[dev1].statement_attr[10].match_nexthop_in = 'hop' rpl1.device_attr[dev1].statement_attr[10].actions = 'pass' rpl1.device_attr[dev1].statement_attr[20] rpl1.device_attr[dev1].statement_attr[20].match_med_eq = 10 rpl1.device_attr[dev1].statement_attr[20].match_nexthop_in = 'hop2' rpl1.device_attr[dev1].statement_attr[20].match_local_pref_eq = 16 rpl1.device_attr[dev1].statement_attr[20].actions = 'drop' rpl1.device_attr[dev1].statement_attr[30] rpl1.device_attr[dev1].statement_attr[30].match_med_eq = 20 rpl1.device_attr[dev1].statement_attr[30].match_nexthop_in = 'hop3' rpl1.device_attr[dev1].statement_attr[30].actions = 'done' rpl1.device_attr[dev1].statement_attr[30].set_med = 32 cfgs = rpl1.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineEqual(str(cfgs[dev1.name]), '\n'.join( ['route-policy rpl1', ' if med eq 5 and next-hop in hop then', ' # 10', ' pass', ' elseif local-preference eq 16 and med eq 10 and next-hop in hop2 then', ' # 20', ' drop', ' elseif med eq 20 and next-hop in hop3 then', ' # 30', ' set med 32', ' done', ' endif', ' end-policy', ' exit' ])) # Testing the configuration without if/else statements # ---------------------------------------------------- rpl2 = RoutePolicy(policy_definition='rpl2') dev2.add_feature(rpl2) rpl2.device_attr[dev2].statement_attr['10'] rpl2.device_attr[dev2].statement_attr['10'].actions = 'pass' rpl2.device_attr[dev2].statement_attr['10'].set_med = 32 cfgs2 = rpl2.build_config(apply=False) self.assertCountEqual(cfgs2.keys(), [dev2.name]) self.assertMultiLineEqual(str(cfgs2[dev2.name]), '\n'.join( ['route-policy rpl2', ' # 10', ' set med 32', ' pass', ' end-policy', ' exit' ]))
def test_init(self): Genie.testbed = testbed = Testbed() dev1 = Device(testbed=testbed, name='PE1', os='iosxr') intf1 = Interface(device=dev1, name='GigabitEthernet0/0/0/1', ipv4='10.1.0.1/24') intf2 = Interface(device=dev1, name='GigabitEthernet0/0/0/2', ipv4='10.2.0.1/24') intf3 = Interface(device=dev1, name='GigabitEthernet0/0/0/3', ipv4='10.3.0.1/24') dev2 = Device(testbed=testbed, name='PE2', os='iosxr') intf4 = Interface(device=dev2, name='GigabitEthernet0/0/0/3', ipv4='10.1.0.2/24') intf5 = Interface(device=dev2, name='GigabitEthernet0/0/0/4', ipv4='10.2.0.2/24') with self.assertNoWarnings(): rpl1 = RoutePolicy(name='rpl1') dev1.add_feature(rpl1) rpl1.pass_on = True cfgs = rpl1.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineDictEqual(cfgs, { dev1.name: '\n'.join([ 'route-policy rpl1', ' pass', ' end-policy', ]), }) rpl1 = RoutePolicy(name='rpl1') dev1.add_feature(rpl1) rpl1.conditions = [] cond = RoutePolicy.Condition( RoutePolicy.Condition.op_contains, (intf1.ipv4.ip, intf2.ipv4.network), 'destination') cond.if_attr.set_nexthop = intf3.ipv4.ip cond.else_attr.drop_on = True rpl1.conditions.append(cond) cfgs = rpl1.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineDictEqual(cfgs, { dev1.name: '\n'.join([ 'route-policy rpl1', ' if destination in (10.1.0.1, 10.2.0.0/24) then', ' set next-hop 10.3.0.1', ' else', ' drop', ' endif', ' end-policy', ]), }) class A(object): def __repr__(self): return '<a>' def __init__(self): self.rpl_set = Mock(side_effect=setattr) self.rpl_get = Mock(side_effect=getattr) a = A() a.destination = intf5.ipv4.ip pass_on = rpl1.rpl_apply_attributes(a, setattr=a.rpl_set, getattr=a.rpl_get) self.assertEqual(a.rpl_get.call_args_list, [ unittest.mock.call(a, 'destination'), ]) self.assertEqual(a.rpl_set.call_args_list, [ unittest.mock.call(a, 'nexthop', intf3.ipv4.ip), ]) self.assertIs(pass_on, True) a = A() a.destination = intf4.ipv4.ip pass_on = rpl1.rpl_apply_attributes(a, setattr=a.rpl_set, getattr=a.rpl_get) self.assertEqual(a.rpl_get.call_args_list, [ unittest.mock.call(a, 'destination'), ]) self.assertEqual(a.rpl_set.call_args_list, [ unittest.mock.call(a, 'drop', True), ]) self.assertIs(pass_on, False) del cond.else_attr.drop_on cfgs = rpl1.build_config(apply=False) self.assertCountEqual(cfgs.keys(), [dev1.name]) self.assertMultiLineDictEqual(cfgs, { dev1.name: '\n'.join([ 'route-policy rpl1', ' if destination in (10.1.0.1, 10.2.0.0/24) then', ' set next-hop 10.3.0.1', ' endif', ' end-policy', ]), }) a = A() a.destination = intf4.ipv4.ip pass_on = rpl1.rpl_apply_attributes(a, setattr=a.rpl_set, getattr=a.rpl_get) self.assertEqual(a.rpl_get.call_args_list, [ unittest.mock.call(a, 'destination'), ]) self.assertEqual(a.rpl_set.call_args_list, [ ]) self.assertIs(pass_on, False)