Esempio n. 1
0
 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)
Esempio n. 2
0
 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
Esempio n. 3
0
    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)