From 1cacb1a959b9e7d45401cb9bf2540bdb360d2dfa Mon Sep 17 00:00:00 2001 From: Ignatious Johnson Christopher Date: Thu, 23 Jun 2016 16:10:13 +0000 Subject: [PATCH] Route targets of the connected logical routers are not added to routing instances during reinit, when schema transformer restarts. They are added later during the Logical Router objects are evaluated. Fix is to add them during reinit of routing instances. Closed-Bug: 1588204 Change-Id: Id321a12e6c4a3aacb05f63b6ea0f6a2d5e9793fa --- src/config/schema-transformer/to_bgp.py | 58 ++++++++++++++++++------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/config/schema-transformer/to_bgp.py b/src/config/schema-transformer/to_bgp.py index f6fc4d7c788..359eb59bf4a 100644 --- a/src/config/schema-transformer/to_bgp.py +++ b/src/config/schema-transformer/to_bgp.py @@ -509,6 +509,7 @@ def locate_routing_instance(self, rinst_name, service_chain=None, try: try: + stale_rt_list = [] if ri_dict: rinst_obj = ri_dict[rinst_fq_name_str] else: @@ -519,24 +520,33 @@ def locate_routing_instance(self, rinst_name, service_chain=None, _vnc_lib.routing_instance_delete(id=rinst_obj.uuid) rinst_obj = None else: - need_update = False + update_ri = False + stale_rt_list = [':'.join(rt_ref['to']) for rt_ref in + rinst_obj.get_route_target_refs()] + if rt_key in stale_rt_list: + stale_rt_list.remove(rt_key) if (rinst_obj.get_routing_instance_is_default() != is_default): rinst_obj.set_routing_instance_is_default(is_default) - need_update = True - old_rt_refs = copy.deepcopy(rinst_obj.get_route_target_refs()) - rinst_obj.set_route_target(rtgt_obj, InstanceTargetType()) + update_ri = True if inst_tgt_data: for rt in self.rt_list: - rtgt_obj = RouteTarget(rt) - rinst_obj.add_route_target(rtgt_obj, inst_tgt_data) + if rt not in stale_rt_list: + rtgt_obj = RouteTarget(rt) + rinst_obj.add_route_target(rtgt_obj, + inst_tgt_data) + update_ri = True + else: + stale_rt_list.remove(rt) if not is_default and self.allow_transit: - rtgt_obj = RouteTarget(self.get_route_target()) - rinst_obj.add_route_target(rtgt_obj, inst_tgt_data) - if (not compare_refs(rinst_obj.get_route_target_refs(), - old_rt_refs)): - need_update = True - if need_update: + rt = self.get_route_target() + if rt not in stale_rt_list: + rtgt_obj = RouteTarget(rt) + rinst_obj.add_route_target(rtgt_obj, inst_tgt_data) + update_ri = True + else: + stale_rt_list.remove(rt) + if update_ri: _vnc_lib.routing_instance_update(rinst_obj) except (NoIdError, KeyError): rinst_obj = None @@ -562,6 +572,7 @@ def locate_routing_instance(self, rinst_name, service_chain=None, rinst = RoutingInstanceST(rinst_obj, service_chain, rt_key) self.rinst[rinst_name] = rinst + rinst.stale_route_targets = stale_rt_list if 0 < old_rtgt < common.BGP_RTGT_MIN_ID: rt_key = "target:%s:%d" % (self.get_autonomous_system(), old_rtgt) @@ -1362,6 +1373,7 @@ def __init__(self, ri_obj, service_chain=None, route_target=None): self.connections = set() for ri_ref in self.obj.get_routing_instance_refs() or []: self.connections.add(':'.join(ri_ref['to'])) + self.stale_route_targets = [] # end __init__ def get_fq_name(self): @@ -1426,14 +1438,23 @@ def add_service_info(self, remote_vn, service_instance=None, def update_route_target_list(self, rt_add, rt_del=None, import_export=None): + update = False for rt in rt_add: - rtgt_obj = RouteTarget(rt) - inst_tgt_data = InstanceTargetType(import_export=import_export) - self.obj.add_route_target(rtgt_obj, inst_tgt_data) + if rt not in self.stale_route_targets: + rtgt_obj = RouteTarget(rt) + inst_tgt_data = InstanceTargetType(import_export=import_export) + self.obj.add_route_target(rtgt_obj, inst_tgt_data) + update = True + else: + self.stale_route_targets.remove(rt) for rt in rt_del or set(): + if rt in self.stale_route_targets: + self.stale_route_targets.remove(rt) rtgt_obj = RouteTarget(rt) self.obj.del_route_target(rtgt_obj) - if len(rt_add) or len(rt_del or set()): + update = True + + if update: _vnc_lib.routing_instance_update(self.obj) # end update_route_target_list @@ -3224,6 +3245,11 @@ def process_stale_objects(self): sc.destroy() if sc.present_stale: sc.delete() + for vn in VirtualNetworkST.values(): + for rinst in vn.rinst.values(): + if rinst.stale_route_targets: + rinst.update_route_target_list(rt_add=set(), + rt_del=rinst.stale_route_targets) # end process_stale_objects def process_poll_result(self, poll_result_str):