def __init__(self, rt_key, obj=None): self.name = rt_key try: self.obj = obj or self.read_vnc_obj(fq_name=[rt_key]) except NoIdError: self.obj = RouteTarget(rt_key) self._vnc_lib.route_target_create(self.obj)
def update_route_target_list(self, rt_add=None, rt_add_import=None, rt_add_export=None, rt_del=None): update = False for rt in rt_del or []: if rt in self.stale_route_targets: self.stale_route_targets.remove(rt) rtgt_obj = RouteTarget(rt) self.obj.del_route_target(rtgt_obj) update = True for rt in rt_add or []: if rt not in self.stale_route_targets: rtgt_obj = ResourceBaseST.get_obj_type_map().get( 'route_target').locate(rt).obj inst_tgt_data = InstanceTargetType(import_export=None) self.obj.add_route_target(rtgt_obj, inst_tgt_data) update = True else: self.stale_route_targets.remove(rt) for rt in rt_add_import or []: if rt not in self.stale_route_targets: rtgt_obj = ResourceBaseST.get_obj_type_map().get( 'route_target').locate(rt).obj inst_tgt_data = InstanceTargetType(import_export='import') self.obj.add_route_target(rtgt_obj, inst_tgt_data) update = True else: self.stale_route_targets.remove(rt) for rt in rt_add_export or []: if rt not in self.stale_route_targets: rtgt_obj = ResourceBaseST.get_obj_type_map().get( 'route_target').locate(rt).obj inst_tgt_data = InstanceTargetType(import_export='export') self.obj.add_route_target(rtgt_obj, inst_tgt_data) update = True else: self.stale_route_targets.remove(rt) if update: try: self._vnc_lib.routing_instance_update(self.obj) # update local cache of ri-->rt refs self.update_route_targets() except NoIdError: return
def update_autonomous_system(cls, new_asn): if int(new_asn) == cls._autonomous_system: return False # From the global route target list, pick ones with the # changed ASN, and update the routing instances' referred # by the route target for route_tgt in list(ResourceBaseST.get_obj_type_map().get( 'route_target').values()): _, asn, target = route_tgt.obj.get_fq_name()[0].split(':') if int(asn) != cls.get_autonomous_system(): continue if int(target) < common.get_bgp_rtgt_min_id(asn): continue asn = cls._autonomous_system new_target = target if ((new_asn > 0xFFFF) and (asn <= 0xFFFF) or (new_asn <= 0xFFFF and asn > 0xFFFF)): ri_fq_name_in_str = cls._object_db.get_ri_from_route_target( int(target), asn) if ri_fq_name_in_str is None or ri_fq_name_in_str == '': continue # free_route_target has to be called before alloc_route_target. # as get_route_target(ri_fq_name) inside free_route_target # will return wrong values if this order is changed. cls._object_db.free_route_target(ri_fq_name_in_str, asn) new_target = cls._object_db.alloc_route_target( ri_fq_name_in_str, new_asn) new_rtgt_name = "target:%s:%s" % (new_asn, new_target) new_rtgt_obj = ResourceBaseST.get_obj_type_map().get( 'route_target').locate(new_rtgt_name) old_rtgt_name = "target:%d:%s" % (cls._autonomous_system, target) old_rtgt_obj = RouteTarget(old_rtgt_name) route_tgt.obj = ResourceBaseST.get_obj_type_map().get( 'route_target').read_vnc_obj(fq_name=[old_rtgt_name], fields=[ 'logical_router_back_refs', 'routing_instance_back_refs' ]) for ri_ref in route_tgt.obj.get_routing_instance_back_refs() or []: rt_inst = ResourceBaseST.get_obj_type_map().get( 'routing_instance').get(':'.join(ri_ref['to'])) if rt_inst: ri = rt_inst.obj else: continue inst_tgt_data = InstanceTargetType() ri.del_route_target(old_rtgt_obj) ri.add_route_target(new_rtgt_obj.obj, inst_tgt_data) cls._vnc_lib.routing_instance_update(ri) # Also, update the static_routes, if any, in the routing # instance with the new route target static_route_entries = ri.get_static_route_entries() if static_route_entries is None: continue for static_route in static_route_entries.get_route() or []: if old_rtgt_name in static_route.route_target: static_route.route_target.remove(old_rtgt_name) static_route.route_target.append(new_rtgt_name) ri.set_static_route_entries(static_route_entries) cls._vnc_lib.routing_instance_update(ri) # Updating the logical router referred by the route target with # new route target. for router_ref in route_tgt.obj.get_logical_router_back_refs() \ or []: lr = ResourceBaseST.get_obj_type_map().get( 'logical_router').get(':'.join(router_ref['to'])) if lr: logical_router = lr.obj else: continue logical_router.del_route_target(old_rtgt_obj) logical_router.add_route_target(new_rtgt_obj.obj) cls._vnc_lib.logical_router_update(logical_router) # We need to execute this code only in case of SNAT routing. # If vxlan_routing is enabled, LR RTs will not have a back_ref # to the Routing Instance of all the connected VNs proj_obj = ResourceBaseST.get_obj_type_map().get( 'logical_router').read_vnc_obj(logical_router.parent_uuid, obj_type='project', fields=['vxlan_routing']) vxlan_routing = proj_obj.get_vxlan_routing() if not vxlan_routing: for vn in lr.virtual_networks: vn_obj = ResourceBaseST.get_obj_type_map().get( 'virtual_network').get(vn) if vn_obj is not None: ri_obj = vn_obj.get_primary_routing_instance() ri_obj.update_route_target_list( rt_del=[old_rtgt_name], rt_add=[new_rtgt_name]) lr.route_target = new_rtgt_name ResourceBaseST.get_obj_type_map().get( 'route_target').delete_vnc_obj(old_rtgt_obj.get_fq_name()[0]) cls._autonomous_system = int(new_asn) return True
def locate_route_target(self): old_rtgt = self._object_db.get_route_target(self.name) asn = ResourceBaseST.get_obj_type_map().get( 'global_system_config').get_autonomous_system() rtgt_num = self._object_db.alloc_route_target(self.name, asn) rt_key = "target:%s:%d" % (asn, rtgt_num) rtgt_obj = ResourceBaseST.get_obj_type_map().get( 'route_target').locate(rt_key).obj if self.is_default: inst_tgt_data = InstanceTargetType() elif ResourceBaseST.get_obj_type_map().get( 'virtual_network')._ri_needs_external_rt( self.virtual_network, self.name): inst_tgt_data = InstanceTargetType(import_export="export") else: inst_tgt_data = None vn = ResourceBaseST.get_obj_type_map().get('virtual_network').get( self.virtual_network) if vn is None: self._logger.error("Parent VN not found for RI: " + self.name) return try: if self.obj.parent_uuid != vn.obj.uuid: # Stale object. Delete it. self._vnc_lib.routing_instance_delete(id=self.obj.uuid) self.obj = None else: update_ri = False self.stale_route_targets = \ [':'.join(rt_ref['to']) for rt_ref in self.obj.get_route_target_refs() or []] if rt_key not in self.stale_route_targets: self.obj.add_route_target(rtgt_obj, InstanceTargetType()) update_ri = True else: self.stale_route_targets.remove(rt_key) if inst_tgt_data: for rt in vn.rt_list | vn.bgpvpn_rt_list: if rt not in self.stale_route_targets: rtgt_obj = ResourceBaseST.get_obj_type_map().get( 'route_target').locate(rt) self.obj.add_route_target(rtgt_obj.obj, inst_tgt_data) update_ri = True else: self.stale_route_targets.remove(rt) if self.is_default: for rt in (vn.export_rt_list | vn.bgpvpn_export_rt_list): if rt not in self.stale_route_targets: rtgt_obj = \ ResourceBaseST.get_obj_type_map().get( 'route_target').locate(rt) self.obj.add_route_target( rtgt_obj.obj, InstanceTargetType('export')) update_ri = True else: self.stale_route_targets.remove(rt) for rt in (vn.import_rt_list | vn.bgpvpn_import_rt_list): if rt not in self.stale_route_targets: rtgt_obj = \ ResourceBaseST.get_obj_type_map().get( 'route_target').locate(rt) self.obj.add_route_target( rtgt_obj.obj, InstanceTargetType('import')) update_ri = True else: self.stale_route_targets.remove(rt) elif vn.allow_transit: if vn.get_route_target() not in \ self.stale_route_targets: rtgt_obj = RouteTarget(vn.get_route_target()) self.obj.add_route_target(rtgt_obj, inst_tgt_data) update_ri = True else: self.stale_route_targets.remove( vn.get_route_target()) update_ri |= \ self.import_default_ri_route_target_to_service_ri() if update_ri: try: self._vnc_lib.routing_instance_update(self.obj) except Exception as e: # error due to inconsistency in db self._logger.error( "Error while updating routing instance: " + str(e)) return except NoIdError as e: self._logger.error("Error while updating routing instance: " + str(e)) raise self.route_target = rt_key if self.is_default: vn.set_route_target(rt_key) asn = ResourceBaseST.get_obj_type_map().get( 'global_system_config').get_autonomous_system() if 0 < old_rtgt < common.get_bgp_rtgt_min_id(asn): rt_key = "target:%s:%d" % (asn, old_rtgt) ResourceBaseST.get_obj_type_map().get( 'route_target').delete_vnc_obj(rt_key)