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):