From aaab87c3f067a2824e2a11dd7d5794620bf456a5 Mon Sep 17 00:00:00 2001 From: Sachin Bansal Date: Thu, 11 Jun 2015 11:17:40 -0700 Subject: [PATCH] Fix multiple issues with ibgp auto mesh 1. vendor name was not being initialized 2. router asn change and global asn change need to be handled differently 3. create peering among all routers with asn same as global Change-Id: I1589e10ece9575f935b9e78ca1d6f41192dc1463 Closes-Bug: 1463771 (cherry picked from commit f5e5450dba0bc27961c95f44fa174134602e5310) --- .../schema-transformer/test/test_service.py | 57 ++++++++++++++++++ src/config/schema-transformer/to_bgp.py | 58 +++++++++++-------- 2 files changed, 91 insertions(+), 24 deletions(-) diff --git a/src/config/schema-transformer/test/test_service.py b/src/config/schema-transformer/test/test_service.py index c7e00489125..43a5b0a45ed 100644 --- a/src/config/schema-transformer/test/test_service.py +++ b/src/config/schema-transformer/test/test_service.py @@ -635,4 +635,61 @@ def test_st_restart_service_chain(self): self.check_ri_is_deleted(fq_name=self.get_ri_name(vn2_obj, sc_ri_name)) #end + @retries(5, hook=retry_exc_handler) + def check_bgp_peering(self, router1, router2, length): + r1 = self._vnc_lib.bgp_router_read(fq_name=router1.get_fq_name()) + ref_names = [ref['to'] for ref in r1.get_bgp_router_refs() or []] + self.assertEqual(len(ref_names), length) + self.assertThat(ref_names, Contains(router2.get_fq_name())) + + def create_bgp_router(self, name, vendor, asn=None): + ip_fabric_ri = self._vnc_lib.routing_instance_read( + fq_name=['default-domain', 'default-project', 'ip-fabric', '__default__']) + router = BgpRouter(name, parent_obj=ip_fabric_ri) + params = BgpRouterParams() + params.vendor = 'contrail' + params.autonomous_system = asn + router.set_bgp_router_parameters(params) + self._vnc_lib.bgp_router_create(router) + return router + + def test_ibgp_auto_mesh(self): + + # create router1 + r1_name = self.id() + 'router1' + router1 = self.create_bgp_router(r1_name, 'contrail') + + # create router2 + r2_name = self.id() + 'router2' + router2 = self.create_bgp_router(r2_name, 'contrail') + + self.check_bgp_peering(router1, router2, 1) + + r3_name = self.id() + 'router3' + router3 = self.create_bgp_router(r3_name, 'juniper', 1) + + self.check_bgp_peering(router1, router2, 1) + + params = router3.get_bgp_router_parameters() + params.autonomous_system = 64512 + router3.set_bgp_router_parameters(params) + self._vnc_lib.bgp_router_update(router3) + + self.check_bgp_peering(router1, router3, 2) + + r4_name = self.id() + 'router4' + router4 = self.create_bgp_router(r4_name, 'juniper', 1) + + gsc = self._vnc_lib.global_system_config_read( + fq_name=['default-global-system-config']) + + gsc.set_autonomous_system(1) + self.check_bgp_peering(router1, router4, 3) + + self._vnc_lib.bgp_router_delete(id=router1.uuid) + self._vnc_lib.bgp_router_delete(id=router2.uuid) + self._vnc_lib.bgp_router_delete(id=router3.uuid) + self._vnc_lib.bgp_router_delete(id=router4.uuid) + gevent.sleep(1) + # end class TestRouteTable diff --git a/src/config/schema-transformer/to_bgp.py b/src/config/schema-transformer/to_bgp.py index 0ecf6ffcf0d..edc01c530a7 100644 --- a/src/config/schema-transformer/to_bgp.py +++ b/src/config/schema-transformer/to_bgp.py @@ -382,13 +382,13 @@ def update_autonomous_system(cls, new_asn): pass # end for vn + cls._autonomous_system = int(new_asn) for router in BgpRouterST.values(): - router.update_autonomous_system(new_asn) + router.update_global_asn(new_asn) # end for router for router in LogicalRouterST.values(): router.update_autonomous_system(new_asn) # end for router - cls._autonomous_system = int(new_asn) # end update_autonomous_system def add_policy(self, policy_name, attrib=None): @@ -2001,11 +2001,11 @@ def update_acl_entries(self, acl_entries): class BgpRouterST(DictST): _dict = {} _ibgp_auto_mesh = None - def __init__(self, name): + def __init__(self, name, params): self.name = name - self.vendor = None + self.vendor = (params.vendor or 'contrail').lower() self.asn = None - self.identifier = None + self.identifier = params.identifier if self._ibgp_auto_mesh is None: gsc = _vnc_lib.global_system_config_read( @@ -2013,7 +2013,6 @@ def __init__(self, name): self._ibgp_auto_mesh = gsc.get_ibgp_auto_mesh() if self._ibgp_auto_mesh is None: self._ibgp_auto_mesh = True - # end __init__ @classmethod @@ -2022,20 +2021,27 @@ def delete(cls, name): del cls._dict[name] # end delete - def update_autonomous_system(self, asn): - if self.vendor not in ["contrail", None]: - self.asn = asn - return - my_asn = int(VirtualNetworkST.get_autonomous_system()) - if asn == my_asn: - self.asn = asn - self.update_peering() + def set_params(self, params): + if self.vendor == 'contrail': + self.update_global_asn(VirtualNetworkST.get_autonomous_system()) + else: + self.update_autonomous_system(params.autonomous_system) + # end set_params + + def update_global_asn(self, asn): + if self.vendor != 'contrail' or self.asn == int(asn): return - bgp_router_obj = _vnc_lib.bgp_router_read(fq_name_str=self.name) - params = bgp_router_obj.get_bgp_router_parameters() + router_obj = _vnc_lib.bgp_router_read(fq_name_str=self.name) + params = router_obj.get_bgp_router_parameters() params.autonomous_system = int(asn) - bgp_router_obj.set_bgp_router_parameters(params) - _vnc_lib.bgp_router_update(bgp_router_obj) + router_obj.set_bgp_router_parameters(params) + _vnc_lib.bgp_router_update(router_obj) + self.update_autonomous_system(asn) + # end update_global_asn + + def update_autonomous_system(self, asn): + if self.asn == int(asn): + return self.asn = int(asn) self.update_peering() # end update_autonomous_system @@ -2054,8 +2060,8 @@ def update_ibgp_auto_mesh(cls, value): def update_peering(self): if not self._ibgp_auto_mesh: return - my_asn = int(VirtualNetworkST.get_autonomous_system()) - if self.asn != my_asn: + global_asn = int(VirtualNetworkST.get_autonomous_system()) + if self.asn != global_asn: return try: obj = _vnc_lib.bgp_router_read(fq_name_str=self.name) @@ -2064,14 +2070,14 @@ def update_peering(self): "%s: %s", self.name, str(e)) return + peerings = [ref['to'] for ref in (obj.get_bgp_router_refs() or [])] for router in self._dict.values(): if router.name == self.name: continue - if router.asn != my_asn: + if router.asn != global_asn: continue router_fq_name = router.name.split(':') - if (router_fq_name in - [ref['to'] for ref in (obj.get_bgp_router_refs() or [])]): + if router_fq_name in peerings: continue router_obj = BgpRouter() router_obj.fq_name = router_fq_name @@ -3076,7 +3082,11 @@ def delete_route_target_list(self, idents, meta): def add_bgp_router_parameters(self, idents, meta): router_name = idents['bgp-router'] - router = BgpRouterST.locate(router_name) + params = BgpRouterParams() + params.build(meta) + router = BgpRouterST.locate(router_name, params) + if router: + router.set_params(params) # end add_bgp_router_parameters def delete_bgp_router_parameters(self, idents, meta):