def update_router(self, context, router_id, router):
        r = router['router']
        self._validate_no_routes(r)

        # If only the name and or description are updated. We do not need to
        # update the backend.
        if set(['name', 'description']) >= set(r.keys()):
            return super(nsx_v.NsxVPluginV2,
                         self.plugin).update_router(context, router_id, router)

        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            return super(nsx_v.NsxVPluginV2,
                         self.plugin).update_router(context, router_id, router)
        else:
            with locking.LockManager.get_lock(str(edge_id)):
                gw_info = self.plugin._extract_external_gw(context,
                                                           router,
                                                           is_extract=True)
                super(nsx_v.NsxVPluginV2,
                      self.plugin).update_router(context, router_id, router)

            if gw_info != constants.ATTR_NOT_SPECIFIED:
                self.plugin._update_router_gw_info(context, router_id, gw_info)
            if 'admin_state_up' in r:
                # If router was deployed on a different edge then
                # admin-state-up is already updated on the new edge.
                current_edge_id = (edge_utils.get_router_edge_id(
                    context, router_id))
                if current_edge_id == edge_id:
                    self.plugin._update_router_admin_state(
                        context, router_id, self.get_type(),
                        r['admin_state_up'])
            return self.plugin.get_router(context, router_id)
Пример #2
0
    def update_router(self, context, router_id, router):
        r = router['router']
        self._validate_no_routes(r)

        # If only the name and or description are updated. We do not need to
        # update the backend.
        if set(['name', 'description']) >= set(r.keys()):
            return super(nsx_v.NsxVPluginV2, self.plugin).update_router(
                context, router_id, router)

        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            return super(nsx_v.NsxVPluginV2, self.plugin).update_router(
                context, router_id, router)
        else:
            with locking.LockManager.get_lock(str(edge_id)):
                gw_info = self.plugin._extract_external_gw(
                    context, router, is_extract=True)
                super(nsx_v.NsxVPluginV2, self.plugin).update_router(
                    context, router_id, router)

            if gw_info != constants.ATTR_NOT_SPECIFIED:
                self.plugin._update_router_gw_info(context, router_id, gw_info)
            if 'admin_state_up' in r:
                # If router was deployed on a different edge then
                # admin-state-up is already updated on the new edge.
                current_edge_id = (
                    edge_utils.get_router_edge_id(context, router_id))
                if current_edge_id == edge_id:
                    self.plugin._update_router_admin_state(context, router_id,
                                                           self.get_type(),
                                                           r['admin_state_up'])
            return self.plugin.get_router(context, router_id)
 def update_router(self, context, router_id, router):
     r = router['router']
     self._validate_no_routes(r)
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     if not edge_id:
         return super(nsx_v.NsxVPluginV2, self.plugin).update_router(
             context, router_id, router)
     else:
         with locking.LockManager.get_lock(str(edge_id)):
             gw_info = self.plugin._extract_external_gw(
                 context, router, is_extract=True)
             super(nsx_v.NsxVPluginV2, self.plugin).update_router(
                 context, router_id, router)
             self.update_routes(context, router_id, None)
         # here is used to handle routes which tenant updates.
         if gw_info != attr.ATTR_NOT_SPECIFIED:
             self._update_router_gw_info(context, router_id, gw_info)
         if 'admin_state_up' in r:
             # If router was deployed on a different edge then
             # admin-state-up is already updated on the new edge.
             current_edge_id = (
                 edge_utils.get_router_edge_id(context, router_id))
             if current_edge_id == edge_id:
                 self.plugin._update_router_admin_state(context, router_id,
                                                        self.get_type(),
                                                        r['admin_state_up'])
         return self.plugin.get_router(context, router_id)
Пример #4
0
 def update_routes(self, context, router_id, nexthop):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     if edge_id:
         router_db = self.plugin._get_router(context, router_id)
         available_router_ids, conflict_router_ids = (
             self._get_available_and_conflicting_ids(context, router_id))
         is_conflict = self.edge_manager.is_router_conflict_on_edge(
             context, router_id, conflict_router_ids, [], 0)
         if is_conflict:
             self._notify_before_router_edge_association(context, router_db)
             with locking.LockManager.get_lock(str(edge_id)):
                 self._remove_router_services_on_edge(context, router_id)
                 with locking.LockManager.get_lock(
                     'nsx-shared-router-pool'):
                     self._unbind_router_on_edge(context, router_id)
             self._bind_router_on_available_edge(
                 context, router_id, router_db.admin_state_up)
             new_edge_id = edge_utils.get_router_edge_id(context,
                                                         router_id)
             with locking.LockManager.get_lock(str(new_edge_id)):
                 self._add_router_services_on_available_edge(context,
                                                             router_id)
             self._notify_after_router_edge_association(context, router_db)
         else:
             with locking.LockManager.get_lock(str(edge_id)):
                 router_ids = self.edge_manager.get_routers_on_same_edge(
                     context, router_id)
                 if router_ids:
                     self._update_routes_on_routers(
                         context, router_id, router_ids)
Пример #5
0
 def update_routes(self, context, router_id, nexthop):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     if edge_id:
         router_db = self.plugin._get_router(context, router_id)
         available_router_ids, conflict_router_ids = (
             self._get_available_and_conflicting_ids(context, router_id))
         is_conflict = self.edge_manager.is_router_conflict_on_edge(
             context, router_id, conflict_router_ids, [], 0)
         if is_conflict:
             self._notify_before_router_edge_association(context, router_db)
             with locking.LockManager.get_lock(str(edge_id)):
                 self._remove_router_services_on_edge(context, router_id)
                 with locking.LockManager.get_lock(
                     'nsx-shared-router-pool'):
                     self._unbind_router_on_edge(context, router_id)
             self._bind_router_on_available_edge(
                 context, router_id, router_db.admin_state_up)
             new_edge_id = edge_utils.get_router_edge_id(context,
                                                         router_id)
             with locking.LockManager.get_lock(str(new_edge_id)):
                 self._add_router_services_on_available_edge(context,
                                                             router_id)
             self._notify_after_router_edge_association(context, router_db)
         else:
             with locking.LockManager.get_lock(str(edge_id)):
                 router_ids = self.edge_manager.get_routers_on_same_edge(
                     context, router_id)
                 if router_ids:
                     self._update_routes_on_routers(
                         context, router_id, router_ids)
Пример #6
0
def is_router_conflicting_on_edge(context, driver, router_id):
    edge_id = edge_utils.get_router_edge_id(context, router_id)
    if not edge_id:
        return False
    (available_routers,
     conflict_routers) = driver._get_available_and_conflicting_ids(
        context, router_id)
    for conf_router in conflict_routers:
        conf_edge_id = edge_utils.get_router_edge_id(context, conf_router)
        if conf_edge_id == edge_id:
            LOG.info("Router %(rtr)s on edge %(edge)s is conflicting with "
                     "another router and will be moved",
                     {'rtr': router_id, 'edge': edge_id})
            return True
    return False
Пример #7
0
    def update_router_interface_ip(self, context, router_id, port_id,
                                   int_net_id, old_ip, new_ip, subnet_mask):
        """Update the fixed ip of a router interface.
        This implementation will not work for distributed routers,
        and there is a different implementation in that driver class
        """
        # get the edge-id of this router
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            # This may be a shared router that was not attached to an edge yet
            return

        # find out if the port is uplink or internal
        router = self.plugin._get_router(context, router_id)
        is_uplink = (port_id == router.gw_port_id)

        # update the edge interface configuration
        self.edge_manager.update_interface_addr(context,
                                                edge_id,
                                                old_ip,
                                                new_ip,
                                                subnet_mask,
                                                is_uplink=is_uplink)

        # Also update the nat rules
        if is_uplink:
            self.update_nat_rules(context, router, router_id)
 def remove_router_interface(self, context, router_id, interface_info):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock(str(edge_id)):
         info = super(
             nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
                 context, router_id, interface_info)
         subnet = self.plugin.get_subnet(context, info['subnet_id'])
         network_id = subnet['network_id']
         router_ids = self.edge_manager.get_routers_on_same_edge(
             context, router_id)
         self._update_nat_rules_on_routers(context, router_id, router_ids)
         self._update_subnets_and_dnat_firewall_on_routers(
             context, router_id, router_ids, allow_external=True)
         ports = self.plugin._get_router_interface_ports_by_network(
             context, router_id, network_id)
         if not ports:
             edge_utils.delete_interface(self.nsx_v, context,
                                         router_id, network_id)
             # unbind all services if no interfaces attached to the router
             if not self.plugin._get_internal_network_ids_by_router(
                     context, router_id):
                 self._remove_router_services_on_edge(context, router_id)
                 self._unbind_router_on_edge(context, router_id)
         else:
             address_groups = self.plugin._get_address_groups(
                 context, router_id, network_id)
             edge_utils.update_internal_interface(
                 self.nsx_v, context, router_id, network_id, address_groups)
     return info
    def attach_router(self, context, router_id, router, appliance_size=None):
        router_db = self.plugin._get_router(context, router_id)

        # Add DB attributes to the router data structure
        # before creating it as an exclusive router
        self._build_router_data_from_db(router_db, router)

        self.create_router(context,
                           router['router'],
                           allow_metadata=False,
                           appliance_size=appliance_size)

        edge_id = edge_utils.get_router_edge_id(context, router_id)
        LOG.debug("Exclusive router %s attached to edge %s",
                  router_id, edge_id)

        # add all internal interfaces of the router on edge
        intf_net_ids = (
            self.plugin._get_internal_network_ids_by_router(context,
                                                            router_id))
        for network_id in intf_net_ids:
            address_groups = self.plugin._get_address_groups(
                context, router_id, network_id)
            edge_utils.update_internal_interface(
                self.nsx_v, context, router_id, network_id,
                address_groups, router_db.admin_state_up)

        # Update external interface (which also update nat rules, routes, etc)
        external_net_id = self._get_external_network_id_by_router(context,
                                                                  router_id)
        gw_info = None
        if (external_net_id):
            gw_info = {'network_id': external_net_id}
        self._update_router_gw_info(
            context, router_id, gw_info, force_update=True)
Пример #10
0
    def _get_routers_edges(self, context, apply_list):
        # Get edges for all the routers in the apply list.
        # note that shared routers are currently not supported
        edge_manager = self.edge_manager
        edges_map = {}
        for router_info in apply_list:

            # No FWaaS rules needed if there is no external gateway
            if not self.should_apply_firewall_to_router(router_info.router):
                continue

            lookup_id = None
            router_id = router_info.router_id
            if router_info.router.get('distributed'):
                # Distributed router
                # we need the plr edge id
                lookup_id = edge_manager.get_plr_by_tlr_id(context, router_id)
            else:
                # Exclusive router
                lookup_id = router_id
            if lookup_id:
                # look for the edge id in the DB
                edge_id = edge_utils.get_router_edge_id(context, lookup_id)
                if edge_id:
                    edges_map[router_id] = {
                        'edge_id': edge_id,
                        'lookup_id': lookup_id
                    }
        return edges_map
Пример #11
0
 def remove_router_interface(self, context, router_id, interface_info):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock(str(edge_id)):
         info = super(nsx_v.NsxVPluginV2,
                      self.plugin).remove_router_interface(
                          context, router_id, interface_info)
         subnet = self.plugin.get_subnet(context, info['subnet_id'])
         network_id = subnet['network_id']
         router_ids = self.edge_manager.get_routers_on_same_edge(
             context, router_id)
         self._update_nat_rules_on_routers(context, router_id, router_ids)
         self._update_subnets_and_dnat_firewall_on_routers(
             context, router_id, router_ids, allow_external=True)
         ports = self.plugin._get_router_interface_ports_by_network(
             context, router_id, network_id)
         if not ports:
             edge_utils.delete_interface(self.nsx_v, context, router_id,
                                         network_id)
             # unbind all services if no interfaces attached to the router
             if not self.plugin._get_internal_network_ids_by_router(
                     context, router_id):
                 self._remove_router_services_on_edge(context, router_id)
                 self._unbind_router_on_edge(context, router_id)
         else:
             address_groups = self.plugin._get_address_groups(
                 context, router_id, network_id)
             edge_utils.update_internal_interface(self.nsx_v, context,
                                                  router_id, network_id,
                                                  address_groups)
     return info
Пример #12
0
 def _get_edge_id_or_raise(self, context, router_id):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     if not edge_id:
         error = (_("Failed to get router %(rid)s edge Id") %
                  {'rid': router_id})
         raise nsxv_exc.NsxPluginException(err_msg=error)
     return edge_id
Пример #13
0
    def _bind_router_on_available_edge(self, context, router_id, admin_state):
        with locking.LockManager.get_lock('nsx-shared-router-pool'):
            conflict_network_ids, conflict_router_ids, intf_num = (
                self._get_conflict_network_and_router_ids_by_intf(
                    context, router_id))
            conflict_network_ids_by_ext_net = (
                self._get_conflict_network_ids_by_ext_net(context, router_id))
            conflict_network_ids.extend(conflict_network_ids_by_ext_net)
            optional_router_ids, new_conflict_router_ids = (
                self._get_available_and_conflicting_ids(context, router_id))
            conflict_router_ids.extend(new_conflict_router_ids)
            conflict_router_ids = list(set(conflict_router_ids))

            az = self.get_router_az_by_id(context, router_id)
            new = self.edge_manager.bind_router_on_available_edge(
                context, router_id, optional_router_ids, conflict_router_ids,
                conflict_network_ids, intf_num, az)
            # configure metadata service on the router.
            metadata_proxy_handler = self.plugin.metadata_proxy_handler
            if metadata_proxy_handler and new:
                metadata_proxy_handler.configure_router_edge(router_id)
            edge_id = edge_utils.get_router_edge_id(context, router_id)
            with locking.LockManager.get_lock(str(edge_id)):
                # add all internal interfaces of the router on edge
                intf_net_ids = (
                    self.plugin._get_internal_network_ids_by_router(
                        context, router_id))
                for network_id in intf_net_ids:
                    address_groups = self.plugin._get_address_groups(
                        context, router_id, network_id)
                    edge_utils.update_internal_interface(
                        self.nsx_v, context, router_id, network_id,
                        address_groups, admin_state)
 def _get_edge_id_or_raise(self, context, router_id):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     if not edge_id:
         error = (_("Failed to get router %(rid)s edge Id") %
                  {'rid': router_id})
         raise nsxv_exc.NsxPluginException(err_msg=error)
     return edge_id
Пример #15
0
    def _bind_router_on_available_edge(self, context, router_id, admin_state):
        with locking.LockManager.get_lock('nsx-shared-router-pool'):
            conflict_network_ids, conflict_router_ids, intf_num = (
                self._get_conflict_network_and_router_ids_by_intf(context,
                                                                  router_id))
            conflict_network_ids_by_ext_net = (
                self._get_conflict_network_ids_by_ext_net(context, router_id))
            conflict_network_ids.extend(conflict_network_ids_by_ext_net)
            optional_router_ids, new_conflict_router_ids = (
                self._get_available_and_conflicting_ids(context, router_id))
            conflict_router_ids.extend(new_conflict_router_ids)
            conflict_router_ids = list(set(conflict_router_ids))

            new = self.edge_manager.bind_router_on_available_edge(
                context, router_id, optional_router_ids,
                conflict_router_ids, conflict_network_ids, intf_num)
            # configure metadata service on the router.
            metadata_proxy_handler = self.plugin.metadata_proxy_handler
            if metadata_proxy_handler and new:
                metadata_proxy_handler.configure_router_edge(router_id)
            edge_id = edge_utils.get_router_edge_id(context, router_id)
            with locking.LockManager.get_lock(str(edge_id)):
                # add all internal interfaces of the router on edge
                intf_net_ids = (
                    self.plugin._get_internal_network_ids_by_router(context,
                                                                    router_id))
                for network_id in intf_net_ids:
                    address_groups = self.plugin._get_address_groups(
                        context, router_id, network_id)
                    edge_utils.update_internal_interface(
                        self.nsx_v, context, router_id, network_id,
                        address_groups, admin_state)
Пример #16
0
def is_router_conflicting_on_edge(context, driver, router_id):
    edge_id = edge_utils.get_router_edge_id(context, router_id)
    if not edge_id:
        return False
    (available_routers,
     conflict_routers) = driver._get_available_and_conflicting_ids(
         context, router_id)
    for conf_router in conflict_routers:
        conf_edge_id = edge_utils.get_router_edge_id(context, conf_router)
        if conf_edge_id == edge_id:
            LOG.info(
                "Router %(rtr)s on edge %(edge)s is conflicting with "
                "another router and will be moved", {
                    'rtr': router_id,
                    'edge': edge_id
                })
            return True
    return False
Пример #17
0
 def attach_router(self, context, router_id, router, appliance_size=None):
     # find the right place to add, and create a new one if necessary
     router_db = self.plugin._get_router(context, router_id)
     self._bind_router_on_available_edge(context, router_id,
                                         router_db.admin_state_up)
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     LOG.debug("Shared router %s attached to edge %s", router_id, edge_id)
     with locking.LockManager.get_lock(str(edge_id)):
         self._add_router_services_on_available_edge(context, router_id)
Пример #18
0
 def attach_router(self, context, router_id, router, appliance_size=None):
     # find the right place to add, and create a new one if necessary
     router_db = self.plugin._get_router(context, router_id)
     self._bind_router_on_available_edge(
         context, router_id, router_db.admin_state_up)
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     LOG.debug("Shared router %s attached to edge %s", router_id, edge_id)
     with locking.LockManager.get_lock(str(edge_id)):
         self._add_router_services_on_available_edge(context, router_id)
Пример #19
0
    def _update_backend_routers(self, apply_list, fwg_id):
        """Update all the affected routers on the backend"""
        LOG.info("Updating routers firewall for firewall group %s", fwg_id)
        context = n_context.get_admin_context()
        routers = set()
        routers_mapping = {}
        # the apply_list is a list of tuples: routerInfo, port-id
        for router_info, port_id in apply_list:
            # Skip dummy entries that were added only to avoid errors
            if isinstance(router_info, str):
                continue
            # Skip unsupported routers
            if not self.should_apply_firewall_to_router(router_info.router):
                continue

            lookup_id = None
            router_id = router_info.router_id
            if router_info.router.get('distributed'):
                # Distributed router (need to update the plr edge)
                lookup_id = self.core_plugin.edge_manager.get_plr_by_tlr_id(
                    context, router_id)
            else:
                # Exclusive router
                lookup_id = router_id
            if lookup_id:
                # look for the edge id in the DB
                edge_id = edge_utils.get_router_edge_id(context, lookup_id)
                if edge_id:
                    routers_mapping[router_id] = {
                        'edge_id': edge_id,
                        'lookup_id': lookup_id
                    }
                    routers.add(router_id)

        # update each router once using the core plugin
        for router_id in routers:
            router_db = self.core_plugin._get_router(context, router_id)
            edge_id = routers_mapping[router_id]['edge_id']
            LOG.info("Updating FWaaS rules for router %s on edge %s",
                     router_id, edge_id)
            router_lookup_id = routers_mapping[router_id]['lookup_id']
            try:
                with locking.LockManager.get_lock(str(edge_id)):
                    self.core_plugin.update_router_firewall(
                        context, router_lookup_id, router_db)
            except Exception as e:
                # catch known library exceptions and raise Fwaas generic
                # exception
                LOG.error(
                    "Failed to update firewall rules on edge "
                    "%(edge_id)s for router %(rtr)s: %(e)s", {
                        'e': e,
                        'rtr': router_id,
                        'edge_id': edge_id
                    })
                raise exceptions.FirewallInternalDriverError(
                    driver=self.driver_name)
Пример #20
0
    def detach_router(self, context, router_id, router):
        LOG.debug("Detach shared router id %s", router_id)
        # if it is the last shared router on this adge - add it to the pool
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            return

        self._remove_router_services_on_edge(context, router_id)
        self._unbind_router_on_edge(context, router_id)
Пример #21
0
    def detach_router(self, context, router_id, router):
        LOG.debug("Detach shared router id %s", router_id)
        # if it is the last shared router on this adge - add it to the pool
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            return

        with locking.LockManager.get_lock(str(edge_id)):
            self._remove_router_services_on_edge(context, router_id)
            self._unbind_router_on_edge(context, router_id)
Пример #22
0
 def _update_edge_router(self, context, router_id):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock(str(edge_id)):
         router_ids = self.edge_manager.get_routers_on_same_edge(
             context, router_id)
         if router_ids:
             self._update_external_interface_on_routers(
                 context, router_id, router_ids)
             self._update_nat_rules_on_routers(context, router_id,
                                               router_ids)
             self._update_subnets_and_dnat_firewall_on_routers(
                 context, router_id, router_ids, allow_external=True)
Пример #23
0
 def _update_edge_router(self, context, router_id):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock(str(edge_id)):
         router_ids = self.edge_manager.get_routers_on_same_edge(
             context, router_id)
         if router_ids:
             self._update_external_interface_on_routers(
                 context, router_id, router_ids)
             self._update_nat_rules_on_routers(
                 context, router_id, router_ids)
             self._update_subnets_and_dnat_firewall_on_routers(
                 context, router_id, router_ids, allow_external=True)
Пример #24
0
    def detach_router(self, context, router_id, router):
        LOG.debug("Detach shared router id %s", router_id)
        # if it is the last shared router on this edge - add it to the pool
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            return

        router_db = self.plugin._get_router(context, router_id)
        self._notify_before_router_edge_association(context, router_db)
        with locking.LockManager.get_lock(str(edge_id)):
            self._remove_router_services_on_edge(context, router_id)
            with locking.LockManager.get_lock('nsx-shared-router-pool'):
                self._unbind_router_on_edge(context, router_id)
Пример #25
0
 def _unbind_router_on_edge(self, context, router_id):
     az = self.get_router_az_by_id(context, router_id)
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     self.edge_manager.reconfigure_shared_edge_metadata_port(
         context, router_id)
     self.edge_manager.unbind_router_on_edge(context, router_id)
     if self.plugin.metadata_proxy_handler:
         metadata_proxy_handler = self.plugin.get_metadata_proxy_handler(
             az.name)
         if metadata_proxy_handler:
             metadata_proxy_handler.cleanup_router_edge(context, router_id)
     LOG.info("Unbinding shared router %(rtr)s: edge %(edge)s",
              {'rtr': router_id, 'edge': edge_id})
Пример #26
0
    def detach_router(self, context, router_id, router):
        LOG.debug("Detach shared router id %s", router_id)
        # if it is the last shared router on this edge - add it to the pool
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            return

        router_db = self.plugin._get_router(context, router_id)
        self._notify_before_router_edge_association(context, router_db)
        with locking.LockManager.get_lock(str(edge_id)):
            self._remove_router_services_on_edge(context, router_id)
            with locking.LockManager.get_lock('nsx-shared-router-pool'):
                self._unbind_router_on_edge(context, router_id)
Пример #27
0
 def _unbind_router_on_edge(self, context, router_id):
     az = self.get_router_az_by_id(context, router_id)
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     self.edge_manager.reconfigure_shared_edge_metadata_port(
         context, router_id)
     self.edge_manager.unbind_router_on_edge(context, router_id)
     if self.plugin.metadata_proxy_handler:
         metadata_proxy_handler = self.plugin.get_metadata_proxy_handler(
             az.name)
         if metadata_proxy_handler:
             metadata_proxy_handler.cleanup_router_edge(context, router_id)
     LOG.info("Unbinding shared router %(rtr)s: edge %(edge)s",
              {'rtr': router_id, 'edge': edge_id})
Пример #28
0
    def _update_backend_routers(self, apply_list, fwg_id):
        """Update all the affected routers on the backend"""
        LOG.info("Updating routers firewall for firewall group %s", fwg_id)
        context = n_context.get_admin_context()
        routers = set()
        routers_mapping = {}
        # the apply_list is a list of tuples: routerInfo, port-id
        for router_info, port_id in apply_list:
            # Skip dummy entries that were added only to avoid errors
            if isinstance(router_info, str):
                continue
            # Skip unsupported routers
            if not self.should_apply_firewall_to_router(router_info.router):
                continue

            lookup_id = None
            router_id = router_info.router_id
            if router_info.router.get('distributed'):
                # Distributed router (need to update the plr edge)
                lookup_id = self.core_plugin.edge_manager.get_plr_by_tlr_id(
                    context, router_id)
            else:
                # Exclusive router
                lookup_id = router_id
            if lookup_id:
                # look for the edge id in the DB
                edge_id = edge_utils.get_router_edge_id(context, lookup_id)
                if edge_id:
                    routers_mapping[router_id] = {'edge_id': edge_id,
                                                  'lookup_id': lookup_id}
                    routers.add(router_id)

        # update each router once using the core plugin
        for router_id in routers:
            router_db = self.core_plugin._get_router(context, router_id)
            edge_id = routers_mapping[router_id]['edge_id']
            LOG.info("Updating FWaaS rules for router %s on edge %s",
                router_id, edge_id)
            router_lookup_id = routers_mapping[router_id]['lookup_id']
            try:
                with locking.LockManager.get_lock(str(edge_id)):
                    self.core_plugin.update_router_firewall(
                        context, router_lookup_id, router_db)
            except Exception as e:
                # catch known library exceptions and raise Fwaas generic
                # exception
                LOG.error("Failed to update firewall rules on edge "
                          "%(edge_id)s for router %(rtr)s: %(e)s",
                          {'e': e, 'rtr': router_id, 'edge_id': edge_id})
                raise exceptions.FirewallInternalDriverError(
                    driver=self.driver_name)
Пример #29
0
    def _bind_router_on_available_edge(self, context, router_id, admin_state):
        with locking.LockManager.get_lock('nsx-shared-router-pool'):
            conflict_network_ids, conflict_router_ids, intf_num = (
                self._get_conflict_network_and_router_ids_by_intf(
                    context, router_id))
            conflict_network_ids_by_ext_net = (
                self._get_conflict_network_ids_by_ext_net(context, router_id))
            conflict_network_ids.extend(conflict_network_ids_by_ext_net)
            optional_router_ids, new_conflict_router_ids = (
                self._get_available_and_conflicting_ids(context, router_id))
            conflict_router_ids.extend(new_conflict_router_ids)
            conflict_router_ids = list(set(conflict_router_ids))

            az, flavor_id = self.get_router_az_and_flavor_by_id(
                context, router_id)
            new = self.edge_manager.bind_router_on_available_edge(
                context, router_id, optional_router_ids, conflict_router_ids,
                conflict_network_ids, intf_num, az)
            # configure metadata service on the router.
            if self.plugin.metadata_proxy_handler and new:
                md_proxy_handler = self.plugin.get_metadata_proxy_handler(
                    az.name)
                if md_proxy_handler:
                    md_proxy_handler.configure_router_edge(context, router_id)
            edge_id = edge_utils.get_router_edge_id(context, router_id)
            with locking.LockManager.get_lock(str(edge_id)):
                # add all internal interfaces of the router on edge
                intf_net_ids = (
                    self.plugin._get_internal_network_ids_by_router(
                        context, router_id))
                for network_id in intf_net_ids:
                    address_groups = self.plugin._get_address_groups(
                        context, router_id, network_id)
                    edge_utils.update_internal_interface(
                        self.nsx_v, context, router_id, network_id,
                        address_groups, admin_state)

            if flavor_id:
                # if several routers share same edge, they might have
                # different flavors with conflicting syslog settings.
                # in this case, each new router association will override
                # previous syslog settings on the edge
                self.edge_manager.update_syslog_by_flavor(
                    context, router_id, flavor_id, edge_id)
            LOG.info("Binding shared router %(rtr)s: edge %(edge)s", {
                'rtr': router_id,
                'edge': edge_id
            })
Пример #30
0
    def _bind_router_on_available_edge(self, context, router_id, admin_state):
        with locking.LockManager.get_lock('nsx-shared-router-pool'):
            conflict_network_ids, conflict_router_ids, intf_num = (
                self._get_conflict_network_and_router_ids_by_intf(context,
                                                                  router_id))
            conflict_network_ids_by_ext_net = (
                self._get_conflict_network_ids_by_ext_net(context, router_id))
            conflict_network_ids.extend(conflict_network_ids_by_ext_net)
            optional_router_ids, new_conflict_router_ids = (
                self._get_available_and_conflicting_ids(context, router_id))
            conflict_router_ids.extend(new_conflict_router_ids)
            conflict_router_ids = list(set(conflict_router_ids))

            az, flavor_id = self.get_router_az_and_flavor_by_id(context,
                                                                router_id)
            new = self.edge_manager.bind_router_on_available_edge(
                context, router_id, optional_router_ids,
                conflict_router_ids, conflict_network_ids,
                intf_num, az)
            # configure metadata service on the router.
            if self.plugin.metadata_proxy_handler and new:
                md_proxy_handler = self.plugin.get_metadata_proxy_handler(
                    az.name)
                if md_proxy_handler:
                    md_proxy_handler.configure_router_edge(context, router_id)
            edge_id = edge_utils.get_router_edge_id(context, router_id)
            with locking.LockManager.get_lock(str(edge_id)):
                # add all internal interfaces of the router on edge
                intf_net_ids = (
                    self.plugin._get_internal_network_ids_by_router(context,
                                                                    router_id))
                for network_id in intf_net_ids:
                    address_groups = self.plugin._get_address_groups(
                        context, router_id, network_id)
                    edge_utils.update_internal_interface(
                        self.nsx_v, context, router_id, network_id,
                        address_groups, admin_state)

            if flavor_id:
                # if several routers share same edge, they might have
                # different flavors with conflicting syslog settings.
                # in this case, each new router association will override
                # previous syslog settings on the edge
                self.edge_manager.update_syslog_by_flavor(context, router_id,
                        flavor_id, edge_id)
            LOG.info("Binding shared router %(rtr)s: edge %(edge)s",
                     {'rtr': router_id, 'edge': edge_id})
Пример #31
0
 def _safe_remove_router_interface(self, context, router_id,
                                   interface_info):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock('nsx-shared-router-pool'):
         info = super(
             nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
                 context, router_id, interface_info)
         subnet = self.plugin.get_subnet(context, info['subnet_id'])
         network_id = subnet['network_id']
         ports = self.plugin._get_router_interface_ports_by_network(
             context, router_id, network_id)
         connected_networks = (
             self.plugin._get_internal_network_ids_by_router(context,
                                                             router_id))
         if not ports and not connected_networks:
             router = self.plugin._get_router(context, router_id)
             self._notify_before_router_edge_association(context, router)
         with locking.LockManager.get_lock(str(edge_id)):
             router_ids = self.edge_manager.get_routers_on_same_edge(
                 context, router_id)
             self._update_nat_rules_on_routers(context, router_id,
                                               router_ids)
             self._update_subnets_and_dnat_firewall_on_routers(
                 context, router_id, router_ids, allow_external=True)
             if not ports:
                 edge_utils.delete_interface(self.nsx_v, context,
                                             router_id, network_id)
                 # unbind all services if no interfaces attached to the
                 # router
                 if not connected_networks:
                     self._remove_router_services_on_edge(context,
                                                          router_id)
                     self._unbind_router_on_edge(context, router_id)
             else:
                 address_groups = self.plugin._get_address_groups(
                     context, router_id, network_id)
                 edge_utils.update_internal_interface(self.nsx_v, context,
                                                      router_id,
                                                      network_id,
                                                      address_groups)
     return info
Пример #32
0
 def _safe_remove_router_interface(self, context, router_id,
                                   interface_info):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock('nsx-shared-router-pool'):
         info = super(
             nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
                 context, router_id, interface_info)
         subnet = self.plugin.get_subnet(context, info['subnet_id'])
         network_id = subnet['network_id']
         ports = self.plugin._get_router_interface_ports_by_network(
             context, router_id, network_id)
         connected_networks = (
             self.plugin._get_internal_network_ids_by_router(context,
                                                             router_id))
         if not ports and not connected_networks:
             router = self.plugin._get_router(context, router_id)
             self._notify_before_router_edge_association(context, router)
         with locking.LockManager.get_lock(str(edge_id)):
             router_ids = self.edge_manager.get_routers_on_same_edge(
                 context, router_id)
             self._update_nat_rules_on_routers(context, router_id,
                                               router_ids)
             self._update_subnets_and_dnat_firewall_on_routers(
                 context, router_id, router_ids, allow_external=True)
             if not ports:
                 edge_utils.delete_interface(self.nsx_v, context,
                                             router_id, network_id)
                 # unbind all services if no interfaces attached to the
                 # router
                 if not connected_networks:
                     self._remove_router_services_on_edge(context,
                                                          router_id)
                     self._unbind_router_on_edge(context, router_id)
             else:
                 address_groups = self.plugin._get_address_groups(
                     context, router_id, network_id)
                 edge_utils.update_internal_interface(self.nsx_v, context,
                                                      router_id,
                                                      network_id,
                                                      address_groups)
     return info
Пример #33
0
    def attach_router(self, context, router_id, router, appliance_size=None):
        router_db = self.plugin._get_router(context, router_id)

        # Add DB attributes to the router data structure
        # before creating it as an exclusive router
        router_attr = self._build_router_data_from_db(router_db, router)
        allow_metadata = True if self.plugin.metadata_proxy_handler else False
        self.create_router(context,
                           router_attr,
                           allow_metadata=allow_metadata,
                           appliance_size=appliance_size)

        edge_id = edge_utils.get_router_edge_id(context, router_id)
        LOG.debug("Exclusive router %s attached to edge %s", router_id,
                  edge_id)

        # add all internal interfaces of the router on edge
        intf_net_ids = (self.plugin._get_internal_network_ids_by_router(
            context, router_id))
        with locking.LockManager.get_lock(edge_id):
            for network_id in intf_net_ids:
                address_groups = self.plugin._get_address_groups(
                    context, router_id, network_id)
                edge_utils.update_internal_interface(self.nsx_v, context,
                                                     router_id, network_id,
                                                     address_groups,
                                                     router_db.admin_state_up)

        # Update external interface (which also update nat rules, routes, etc)
        external_net_id = self._get_external_network_id_by_router(
            context, router_id)
        gw_info = None
        if (external_net_id):
            gw_info = {
                'network_id': external_net_id,
                'enable_snat': router_db.enable_snat
            }
        self.plugin._update_router_gw_info(context,
                                           router_id,
                                           gw_info,
                                           force_update=True)
Пример #34
0
    def _get_all_routers_vnic_indices(self, context, router_ids):

        all_vnic_indices = {}
        if len(router_ids) < 1:
            # there are no routers
            return all_vnic_indices

        intf_ports = self.plugin.get_ports(
            context.elevated(),
            filters={'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]})

        edge_id = edge_utils.get_router_edge_id(context, router_ids[0])
        edge_vnic_bindings = nsxv_db.get_edge_vnic_bindings_by_edge(
            context.session, edge_id)

        for this_router_id in router_ids:
            # get networks IDs for this router
            router_net_ids = list(
                set([
                    port['network_id'] for port in intf_ports
                    if port['device_id'] == this_router_id
                ]))

            # get vnic index for each network
            vnic_indices = []
            for net_id in router_net_ids:
                vnic_indices.extend([
                    edge_vnic_binding.vnic_index
                    for edge_vnic_binding in edge_vnic_bindings
                    if edge_vnic_binding.network_id == net_id
                ])

            # make sure the list is unique:
            vnic_indices = list(set(vnic_indices))
            # add to the result dict
            all_vnic_indices[this_router_id] = list(vnic_indices)

        return all_vnic_indices
Пример #35
0
    def _get_all_routers_vnic_indices(self, context, router_ids):

        all_vnic_indices = {}
        if len(router_ids) < 1:
            # there are no routers
            return all_vnic_indices

        intf_ports = self.plugin.get_ports(
            context.elevated(),
            filters={'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]})

        edge_id = edge_utils.get_router_edge_id(context, router_ids[0])
        edge_vnic_bindings = nsxv_db.get_edge_vnic_bindings_by_edge(
            context.session, edge_id)

        for this_router_id in router_ids:
            # get networks IDs for this router
            router_net_ids = list(
                set([port['network_id']
                     for port in intf_ports
                     if port['device_id'] == this_router_id]))

            # get vnic index for each network
            vnic_indices = []
            for net_id in router_net_ids:
                vnic_indices.extend([edge_vnic_binding.vnic_index
                                     for edge_vnic_binding
                                     in edge_vnic_bindings
                                     if edge_vnic_binding.network_id == net_id
                                     ])

            # make sure the list is unique:
            vnic_indices = list(set(vnic_indices))
            # add to the result dict
            all_vnic_indices[this_router_id] = list(vnic_indices)

        return all_vnic_indices
    def update_router(self, context, router_id, router):
        r = router['router']
        is_routes_update = True if 'routes' in r else False

        gw_info = self.plugin._extract_external_gw(context,
                                                   router,
                                                   is_extract=True)
        super(nsx_v.NsxVPluginV2,
              self.plugin).update_router(context, router_id, router)
        if gw_info != n_consts.ATTR_NOT_SPECIFIED:
            self.plugin._update_router_gw_info(context, router_id, gw_info,
                                               is_routes_update)
        elif is_routes_update:
            # here is used to handle routes which tenant updates.
            router_db = self.plugin._get_router(context, router_id)
            nexthop = self.plugin._get_external_attachment_info(
                context, router_db)[2]
            self.plugin._update_subnets_and_dnat_firewall(context, router_db)
            self.update_routes(context, router_id, nexthop)
        if 'admin_state_up' in r:
            self.plugin._update_router_admin_state(context, router_id,
                                                   self.get_type(),
                                                   r['admin_state_up'])
        if 'name' in r:
            self.edge_manager.rename_lrouter(context, router_id, r['name'])
        if r.get('router_size'):
            edge_id = edge_utils.get_router_edge_id(context, router_id)
            with locking.LockManager.get_lock(edge_id):
                edge_cfg = self.vcns.get_edge(edge_id)[1]
                if edge_cfg.get('appliances'):
                    edge_cfg['appliances']['applianceSize'] = r['router_size']
                    self.vcns.update_edge(edge_id, edge_cfg)
                    nsxv_db.update_nsxv_router_binding(
                        context.session,
                        router_id,
                        appliance_size=r['router_size'])
        return self.plugin.get_router(context, router_id)
Пример #37
0
    def update_router_interface_ip(self, context, router_id, port_id,
                                   int_net_id, old_ip, new_ip, subnet_mask):
        """Update the fixed ip of a router interface.
        This implementation will not work for distributed routers,
        and there is a different implementation in that driver class
        """
        # get the edge-id of this router
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            # This may be a shared router that was not attached to an edge yet
            return

        # find out if the port is uplink or internal
        router = self.plugin._get_router(context, router_id)
        is_uplink = (port_id == router.gw_port_id)

        # update the edge interface configuration
        self.edge_manager.update_interface_addr(
            context, edge_id, old_ip, new_ip,
            subnet_mask, is_uplink=is_uplink)

        # Also update the nat rules
        if is_uplink:
            self.update_nat_rules(context, router, router_id)
Пример #38
0
    def _update_router_gw_info(self, context, router_id, info,
                               is_routes_update=False,
                               force_update=False):
        router = self.plugin._get_router(context, router_id)
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
                context, router_id, info, router=router)
        # UPDATE gw info only if the router has been attached to an edge
        else:
            is_migrated = False
            router_ids = self.edge_manager.get_routers_on_same_edge(
                context, router_id)
            org_ext_net_id = (router.gw_port_id and
                              router.gw_port.network_id)
            org_enable_snat = router.enable_snat
            orgaddr, orgmask, orgnexthop = (
                self.plugin._get_external_attachment_info(
                    context, router))
            super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
                context, router_id, info, router=router)
            new_ext_net_id = (router.gw_port_id and
                              router.gw_port.network_id)
            new_enable_snat = router.enable_snat
            newaddr, newmask, newnexthop = (
                self.plugin._get_external_attachment_info(context, router))
            with locking.LockManager.get_lock(str(edge_id)):
                if new_ext_net_id and new_ext_net_id != org_ext_net_id:
                    # Check whether the gw address has overlapping
                    # with networks attached to the same edge
                    conflict_network_ids = (
                        self._get_conflict_network_ids_by_ext_net(
                            context, router_id))
                    is_migrated = self.edge_manager.is_router_conflict_on_edge(
                        context, router_id, [], conflict_network_ids)
                    if is_migrated:
                        self._remove_router_services_on_edge(context,
                                                             router_id)
                        with locking.LockManager.get_lock(
                            'nsx-shared-router-pool'):
                            self._unbind_router_on_edge(context, router_id)

                if not is_migrated:
                    ext_net_ids = self._get_ext_net_ids(context, router_ids)
                    if len(ext_net_ids) > 1:
                        # move all routing service of the router from existing
                        # edge to a new available edge if new_ext_net_id is
                        # changed.
                        self._remove_router_services_on_edge(context,
                                                             router_id)
                        with locking.LockManager.get_lock(
                            'nsx-shared-router-pool'):
                            self._unbind_router_on_edge(context, router_id)
                        is_migrated = True
                    else:
                        updated_routes = False
                        # Update external vnic if addr or mask is changed
                        if orgaddr != newaddr or orgmask != newmask:
                            # If external gateway is removed, the default
                            # gateway should be cleared before updating the
                            # interface, or else the backend will fail.
                            if (new_ext_net_id != org_ext_net_id and
                                new_ext_net_id is None):
                                self._update_routes_on_routers(
                                    context, router_id, router_ids)
                                updated_routes = True

                            self._update_external_interface_on_routers(
                                context, router_id, router_ids)

                        # Update SNAT rules if ext net changed
                        # or ext net not changed but snat is changed.
                        if ((new_ext_net_id != org_ext_net_id) or
                            (new_ext_net_id == org_ext_net_id and
                             new_enable_snat != org_enable_snat)):
                            self._update_nat_rules_on_routers(context,
                                                              router_id,
                                                              router_ids)

                        if (new_ext_net_id != org_ext_net_id or
                            new_enable_snat != org_enable_snat):
                            self._update_subnets_and_dnat_firewall_on_routers(
                                context, router_id, router_ids,
                                allow_external=True)

                        # Update static routes in all (if not updated yet).
                        if not updated_routes:
                            self._update_routes_on_routers(
                                context, router_id, router_ids)
            if is_migrated:
                self._notify_before_router_edge_association(context,
                                                            router, edge_id)
                self._bind_router_on_available_edge(
                    context, router_id, router.admin_state_up)
                edge_id = edge_utils.get_router_edge_id(context, router_id)
                with locking.LockManager.get_lock(str(edge_id)):
                    self._add_router_services_on_available_edge(context,
                                                                router_id)
            self._notify_after_router_edge_association(context, router)
Пример #39
0
    def _update_router_gw_info(self, context, router_id, info):
        router = self.plugin._get_router(context, router_id)
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
                context, router_id, info, router=router)
        # UPDATE gw info only if the router has been attached to an edge
        else:
            is_migrated = False
            with locking.LockManager.get_lock(str(edge_id)):
                router_ids = self.edge_manager.get_routers_on_same_edge(
                    context, router_id)
                org_ext_net_id = (router.gw_port_id and
                                  router.gw_port.network_id)
                org_enable_snat = router.enable_snat
                orgaddr, orgmask, orgnexthop = (
                    self.plugin._get_external_attachment_info(
                        context, router))
                super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
                    context, router_id, info, router=router)
                new_ext_net_id = (router.gw_port_id and
                                  router.gw_port.network_id)
                new_enable_snat = router.enable_snat
                newaddr, newmask, newnexthop = (
                    self.plugin._get_external_attachment_info(
                        context, router))
                if new_ext_net_id and new_ext_net_id != org_ext_net_id:
                    # Check whether the gw address has overlapping
                    # with networks attached to the same edge
                    conflict_network_ids = (
                        self._get_conflict_network_ids_by_ext_net(
                            context, router_id))
                    is_migrated = self.edge_manager.is_router_conflict_on_edge(
                        context, router_id, [], conflict_network_ids)
                    if is_migrated:
                        self._remove_router_services_on_edge(context,
                                                             router_id)
                        self._unbind_router_on_edge(context, router_id)

                if not is_migrated:
                    ext_net_ids = self._get_ext_net_ids(context, router_ids)
                    if len(ext_net_ids) > 1:
                        # move all routing service of the router from existing
                        # edge to a new available edge if new_ext_net_id is
                        # changed.
                        self._remove_router_services_on_edge(context,
                                                             router_id)
                        self._unbind_router_on_edge(context, router_id)
                        is_migrated = True
                    else:
                        # Clear gateway info if all routers has no gw conf
                        if (orgnexthop and
                            (org_ext_net_id != new_ext_net_id or
                             len(ext_net_ids) == 0)):
                            LOG.debug("Delete default gateway %s", orgnexthop)
                            edge_utils.clear_gateway(self.nsx_v, context,
                                                     router_id)

                        # Update external vnic if addr or mask is changed
                        if orgaddr != newaddr or orgmask != newmask:
                            self._update_external_interface_on_routers(
                                context, router_id, router_ids)

                        # Update SNAT rules if ext net changed
                        # or ext net not changed but snat is changed.
                        if ((new_ext_net_id != org_ext_net_id) or
                            (new_ext_net_id == org_ext_net_id and
                             new_enable_snat != org_enable_snat)):
                            self._update_nat_rules_on_routers(context,
                                                              router_id,
                                                              router_ids)

                        if (new_ext_net_id != org_ext_net_id or
                            new_enable_snat != org_enable_snat):
                            self._update_subnets_and_dnat_firewall_on_routers(
                                context, router_id, router_ids,
                                allow_external=True)

                        # Update static routes in all.
                        self._update_routes_on_routers(
                            context, router_id, router_ids)
            if is_migrated:
                self._bind_router_on_available_edge(
                    context, router_id, router.admin_state_up)
                edge_id = edge_utils.get_router_edge_id(context, router_id)
                with locking.LockManager.get_lock(str(edge_id)):
                    self._add_router_services_on_available_edge(context,
                                                                router_id)
Пример #40
0
    def _safe_add_router_interface(self, context, router_id, interface_info):
        self.plugin._check_intf_number_of_router(context, router_id)
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        router_db = self.plugin._get_router(context, router_id)
        if edge_id:
            is_migrated = False
            with locking.LockManager.get_lock('nsx-shared-router-pool'):
                info = super(nsx_v.NsxVPluginV2,
                             self.plugin).add_router_interface(
                                 context, router_id, interface_info)
                with locking.LockManager.get_lock(str(edge_id)):
                    router_ids = self.edge_manager.get_routers_on_same_edge(
                        context, router_id)
                    subnet = self.plugin.get_subnet(context, info['subnet_id'])
                    network_id = subnet['network_id']
                    # Collect all conflict networks whose cidr are overlapped
                    # with networks attached to the router and conflict routers
                    # which has same network with the router's.
                    conflict_network_ids, conflict_router_ids, _ = (
                        self._get_conflict_network_and_router_ids_by_intf(
                            context, router_id))

                    _, new_conflict_router_ids = (
                        self._get_available_and_conflicting_ids(
                            context, router_id))
                    conflict_router_ids.extend(new_conflict_router_ids)
                    conflict_router_ids = list(set(conflict_router_ids))

                    interface_ports = (
                        self.plugin._get_router_interface_ports_by_network(
                            context, router_id, network_id))
                    # Consider whether another subnet of the same network
                    # has been attached to the router.
                    if len(interface_ports) > 1:
                        is_conflict = (
                            self.edge_manager.is_router_conflict_on_edge(
                                context, router_id, conflict_router_ids,
                                conflict_network_ids, 0))
                    else:
                        is_conflict = (
                            self.edge_manager.is_router_conflict_on_edge(
                                context, router_id, conflict_router_ids,
                                conflict_network_ids, 1))
                    if not is_conflict:

                        address_groups = self.plugin._get_address_groups(
                            context, router_id, network_id)
                        edge_utils.update_internal_interface(
                            self.nsx_v, context, router_id, network_id,
                            address_groups, router_db.admin_state_up)
                        if router_db.gw_port and router_db.enable_snat:
                            self._update_nat_rules_on_routers(
                                context, router_id, router_ids)
                        self._update_subnets_and_dnat_firewall_on_routers(
                            context,
                            router_id,
                            router_ids,
                            allow_external=True)
                if is_conflict:
                    self._notify_before_router_edge_association(
                        context, router_db, edge_id)
                    with locking.LockManager.get_lock(str(edge_id)):
                        if len(interface_ports) > 1:
                            self._remove_router_services_on_edge(
                                context, router_id)
                        else:
                            self._remove_router_services_on_edge(
                                context, router_id, network_id)
                        self._unbind_router_on_edge(context, router_id)
                    is_migrated = True
            if is_migrated:
                self._bind_router_on_available_edge(context, router_id,
                                                    router_db.admin_state_up)
                edge_id = edge_utils.get_router_edge_id(context, router_id)
                with locking.LockManager.get_lock(str(edge_id)):
                    self._add_router_services_on_available_edge(
                        context, router_id)
                self._notify_after_router_edge_association(context, router_db)
        else:
            info = self._base_add_router_interface(context, router_id,
                                                   interface_info)
            # bind and configure routing service on an available edge
            self._bind_router_on_available_edge(context, router_id,
                                                router_db.admin_state_up)
            edge_id = edge_utils.get_router_edge_id(context, router_id)
            with locking.LockManager.get_lock(str(edge_id)):
                self._add_router_services_on_available_edge(context, router_id)
            self._notify_after_router_edge_association(context, router_db)
        return info
Пример #41
0
    def _update_router_gw_info(self,
                               context,
                               router_id,
                               info,
                               is_routes_update=False,
                               force_update=False):
        router = self.plugin._get_router(context, router_id)
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            super(nsx_v.NsxVPluginV2,
                  self.plugin)._update_router_gw_info(context,
                                                      router_id,
                                                      info,
                                                      router=router)
        # UPDATE gw info only if the router has been attached to an edge
        else:
            is_migrated = False
            router_ids = self.edge_manager.get_routers_on_same_edge(
                context, router_id)
            org_ext_net_id = (router.gw_port_id and router.gw_port.network_id)
            org_enable_snat = router.enable_snat
            orgaddr, orgmask, orgnexthop = (
                self.plugin._get_external_attachment_info(context, router))
            super(nsx_v.NsxVPluginV2,
                  self.plugin)._update_router_gw_info(context,
                                                      router_id,
                                                      info,
                                                      router=router)
            new_ext_net_id = (router.gw_port_id and router.gw_port.network_id)
            new_enable_snat = router.enable_snat
            newaddr, newmask, newnexthop = (
                self.plugin._get_external_attachment_info(context, router))
            with locking.LockManager.get_lock(str(edge_id)):
                if new_ext_net_id and new_ext_net_id != org_ext_net_id:
                    # Check whether the gw address has overlapping
                    # with networks attached to the same edge
                    conflict_network_ids = (
                        self._get_conflict_network_ids_by_ext_net(
                            context, router_id))
                    is_migrated = self.edge_manager.is_router_conflict_on_edge(
                        context, router_id, [], conflict_network_ids)
                    if is_migrated:
                        self._remove_router_services_on_edge(
                            context, router_id)
                        with locking.LockManager.get_lock(
                                'nsx-shared-router-pool'):
                            self._unbind_router_on_edge(context, router_id)

                if not is_migrated:
                    ext_net_ids = self._get_ext_net_ids(context, router_ids)
                    if len(ext_net_ids) > 1:
                        # move all routing service of the router from existing
                        # edge to a new available edge if new_ext_net_id is
                        # changed.
                        self._remove_router_services_on_edge(
                            context, router_id)
                        with locking.LockManager.get_lock(
                                'nsx-shared-router-pool'):
                            self._unbind_router_on_edge(context, router_id)
                        is_migrated = True
                    else:
                        updated_routes = False
                        # Update external vnic if addr or mask is changed
                        if orgaddr != newaddr or orgmask != newmask:
                            # If external gateway is removed, the default
                            # gateway should be cleared before updating the
                            # interface, or else the backend will fail.
                            if (new_ext_net_id != org_ext_net_id
                                    and new_ext_net_id is None):
                                self._update_routes_on_routers(
                                    context, router_id, router_ids)
                                updated_routes = True

                            self._update_external_interface_on_routers(
                                context, router_id, router_ids)

                        # Update SNAT rules if ext net changed
                        # or ext net not changed but snat is changed.
                        if ((new_ext_net_id != org_ext_net_id)
                                or (new_ext_net_id == org_ext_net_id
                                    and new_enable_snat != org_enable_snat)):
                            self._update_nat_rules_on_routers(
                                context, router_id, router_ids)

                        if (new_ext_net_id != org_ext_net_id
                                or new_enable_snat != org_enable_snat):
                            self._update_subnets_and_dnat_firewall_on_routers(
                                context,
                                router_id,
                                router_ids,
                                allow_external=True)

                        # Update static routes in all (if not updated yet).
                        if not updated_routes:
                            self._update_routes_on_routers(
                                context, router_id, router_ids)
            if is_migrated:
                self._notify_before_router_edge_association(
                    context, router, edge_id)
                self._bind_router_on_available_edge(context, router_id,
                                                    router.admin_state_up)
                edge_id = edge_utils.get_router_edge_id(context, router_id)
                with locking.LockManager.get_lock(str(edge_id)):
                    self._add_router_services_on_available_edge(
                        context, router_id)
            self._notify_after_router_edge_association(context, router)
Пример #42
0
 def update_nat_rules(self, context, router, router_id):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock(str(edge_id)):
         router_ids = self.edge_manager.get_routers_on_same_edge(
             context, router_id)
         self._update_nat_rules_on_routers(context, router_id, router_ids)
Пример #43
0
 def update_nat_rules(self, context, router, router_id):
     edge_id = edge_utils.get_router_edge_id(context, router_id)
     with locking.LockManager.get_lock(str(edge_id)):
         router_ids = self.edge_manager.get_routers_on_same_edge(
             context, router_id)
         self._update_nat_rules_on_routers(context, router_id, router_ids)
Пример #44
0
    def _safe_add_router_interface(self, context, router_id, interface_info):
        self.plugin._check_intf_number_of_router(context, router_id)
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        router_db = self.plugin._get_router(context, router_id)
        if edge_id:
            is_migrated = False
            with locking.LockManager.get_lock('nsx-shared-router-pool'):
                info = super(nsx_v.NsxVPluginV2,
                             self.plugin).add_router_interface(
                                 context, router_id, interface_info)
                with locking.LockManager.get_lock(str(edge_id)):
                    router_ids = self.edge_manager.get_routers_on_same_edge(
                        context, router_id)
                    subnet = self.plugin.get_subnet(context, info['subnet_id'])
                    network_id = subnet['network_id']
                    # Collect all conflict networks whose cidr are overlapped
                    # with networks attached to the router and conflict routers
                    # which has same network with the router's.
                    conflict_network_ids, conflict_router_ids, _ = (
                        self._get_conflict_network_and_router_ids_by_intf(
                            context, router_id))

                    _, new_conflict_router_ids = (
                        self._get_available_and_conflicting_ids(context,
                                                                router_id))
                    conflict_router_ids.extend(new_conflict_router_ids)
                    conflict_router_ids = list(set(conflict_router_ids))

                    interface_ports = (
                        self.plugin._get_router_interface_ports_by_network(
                            context, router_id, network_id))
                    # Consider whether another subnet of the same network
                    # has been attached to the router.
                    if len(interface_ports) > 1:
                        is_conflict = (
                            self.edge_manager.is_router_conflict_on_edge(
                                context, router_id, conflict_router_ids,
                                conflict_network_ids, 0))
                    else:
                        is_conflict = (
                            self.edge_manager.is_router_conflict_on_edge(
                                context, router_id, conflict_router_ids,
                                conflict_network_ids, 1))
                    if not is_conflict:

                        address_groups = self.plugin._get_address_groups(
                            context, router_id, network_id)
                        edge_utils.update_internal_interface(
                            self.nsx_v, context, router_id,
                            network_id, address_groups,
                            router_db.admin_state_up)
                        if router_db.gw_port and router_db.enable_snat:
                            self._update_nat_rules_on_routers(
                                context, router_id, router_ids)
                        self._update_subnets_and_dnat_firewall_on_routers(
                            context, router_id, router_ids,
                            allow_external=True)
                if is_conflict:
                    self._notify_before_router_edge_association(
                        context, router_db, edge_id)
                    with locking.LockManager.get_lock(str(edge_id)):
                        if len(interface_ports) > 1:
                            self._remove_router_services_on_edge(
                                context, router_id)
                        else:
                            self._remove_router_services_on_edge(
                                context, router_id, network_id)
                        self._unbind_router_on_edge(context, router_id)
                    is_migrated = True
            if is_migrated:
                self._bind_router_on_available_edge(
                    context, router_id, router_db.admin_state_up)
                edge_id = edge_utils.get_router_edge_id(context, router_id)
                with locking.LockManager.get_lock(str(edge_id)):
                    self._add_router_services_on_available_edge(context,
                                                                router_id)
                self._notify_after_router_edge_association(context, router_db)
        else:
            info = self._base_add_router_interface(context, router_id,
                                                   interface_info)
            # bind and configure routing service on an available edge
            self._bind_router_on_available_edge(
                context, router_id, router_db.admin_state_up)
            edge_id = edge_utils.get_router_edge_id(context, router_id)
            with locking.LockManager.get_lock(str(edge_id)):
                self._add_router_services_on_available_edge(context,
                                                            router_id)
            self._notify_after_router_edge_association(context, router_db)
        return info