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) # 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)
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)
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)
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
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)
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
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 _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
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
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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})
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)
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})
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)
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 })
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})
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
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
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)
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 _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)
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 _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)
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)
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
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)
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)
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)
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