def update_router(self, context, router_id, router): r = router['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), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): 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._remove_router_services_on_edge(context, router_id) 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), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): self._add_router_services_on_available_edge(context, router_id) else: 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 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), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): 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 update_router(self, 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 lockutils.lock(str(edge_id), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): gw_info = self.plugin._extract_external_gw( context, router, is_extract=True) super(nsx_v.NsxVPluginV2, self.plugin).update_router( context, router_id, router) # 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) else: with lockutils.lock(str(edge_id), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): router_db = self.plugin._get_router(context, router_id) nexthop = self.plugin._get_external_attachment_info( context, router_db)[2] self.update_routes(context, router_id, nexthop) return self.plugin.get_router(context, router_id)
def _bind_router_on_available_edge(self, context, router_id): 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) conflict_router_ids_by_ext_net = ( self._get_conflict_router_ids_by_ext_net(context, conflict_network_ids)) conflict_router_ids.extend(conflict_router_ids_by_ext_net) optional_router_ids, conflict_router_ids_by_gw = ( self._get_optional_and_conflict_router_ids_by_gw( context, router_id)) conflict_router_ids.extend(conflict_router_ids_by_gw) 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 lockutils.lock(str(edge_id), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): # add all internal interfaces of the router on edge intf_net_ids = self._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)
def _update_edge_router(self, context, router_id): edge_id = edge_utils.get_router_edge_id(context, router_id) with lockutils.lock(str(edge_id), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): 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 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( str(edge_id), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): router_ids = self.edge_manager.get_routers_on_same_edge( context, router_id) info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface( context, router_id, interface_info) 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 conflct 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 is_conflict: 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 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, 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_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), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): self._add_router_services_on_available_edge(context, router_id) else: info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface( context, router_id, interface_info) # bind and configure routing servie on an availab 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), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): self._add_router_services_on_available_edge(context, router_id) return info
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), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): 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), lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True): self._add_router_services_on_available_edge(context, router_id)