def delete_router(self, context, router_id): # make sure that the router binding is cleaned up try: nsxv_db.delete_nsxv_router_binding(context.session, router_id) except Exception as e: LOG.debug('Unable to delete router binding for %s. Error: ' '%s', router_id, e)
def delete_edge(self, context, router_id, edge_id, dist=False): LOG.debug("Deleting edge %s", edge_id) if context is None: context = q_context.get_admin_context() try: LOG.debug("Deleting router binding %s", router_id) nsxv_db.delete_nsxv_router_binding(context.session, router_id) if not dist: LOG.debug("Deleting vnic bindings for edge %s", edge_id) nsxv_db.clean_edge_vnic_binding(context.session, edge_id) except sa_exc.NoResultFound: LOG.warning("Router Binding for %s not found", router_id) if edge_id: try: self.vcns.delete_edge(edge_id) return True except exceptions.ResourceNotFound: return True except exceptions.VcnsApiException as e: LOG.exception("VCNS: Failed to delete %(edge_id)s:\n" "%(response)s", {'edge_id': edge_id, 'response': e.response}) return False except Exception: LOG.exception("VCNS: Failed to delete %s", edge_id) return False
def clean_orphaned_router_bindings(resource, event, trigger, **kwargs): """Delete nsx router bindings entries without real objects behind them""" orphaned_list = get_orphaned_router_bindings() if not len(orphaned_list): LOG.info("No orphaned Router bindings found.") return LOG.info("Before delete; Orphaned Bindings:") LOG.info( formatters.output_formatter( constants.ORPHANED_BINDINGS, orphaned_list, ['edge_id', 'router_id', 'availability_zone', 'status'])) if not kwargs.get('force'): if len(orphaned_list): user_confirm = admin_utils.query_yes_no( "Do you want to delete " "orphaned bindings", default="no") if not user_confirm: LOG.info("NSXv Router bindings deletion aborted by user") return edgeapi = utils.NeutronDbClient() for binding in orphaned_list: nsxv_db.delete_nsxv_router_binding(edgeapi.context.session, binding.router_id) LOG.info( "Deleted %s orphaned router bindings. You may need to check for " "orphaned edges now.", len(orphaned_list))
def delete_old_dhcp_edge(context, old_edge_id, bindings): LOG.info(_LI("Deleting the old DHCP edge: %s"), old_edge_id) # using one of the router-ids in the bindings for the deleting dhcp_names = [binding['router_id'] for binding in bindings] dhcp_name = dhcp_names[0] with locking.LockManager.get_lock(old_edge_id): # Delete from NSXv backend # (using the first dhcp name as the "router name") # Note - If we will not delete the router, but free it - it will be # immediately used as the new one, So it is better to delete it. try: nsxv.delete_edge(old_edge_id) except Exception as e: LOG.warning(_LW("Failed to delete the old edge %(id)s: %(e)s"), { 'id': old_edge_id, 'e': e }) # Continue the process anyway # The edge may have been already deleted at the backend try: # Remove bindings from Neutron DB nsxv_db.delete_nsxv_router_binding(context.session, dhcp_name) nsxv_db.clean_edge_vnic_binding(context.session, old_edge_id) except Exception as e: LOG.warning( _LW("Failed to delete the old edge %(id)s from the " "DB : %(e)s"), { 'id': old_edge_id, 'e': e })
def _delete_backup_from_neutron_db(edge_id, router_id): # Remove bindings from Neutron DB edgeapi = utils.NeutronDbClient() nsxv_db.delete_nsxv_router_binding( edgeapi.context.session, router_id) if edge_id: nsxv_db.clean_edge_vnic_binding(edgeapi.context.session, edge_id)
def delete_edge(self, context, router_id, edge_id, dist=False): try: nsxv_db.delete_nsxv_router_binding(context.session, router_id) if not dist: nsxv_db.clean_edge_vnic_binding(context.session, edge_id) except sa_exc.NoResultFound: LOG.warning(_LW("Router Binding for %s not found"), router_id) if edge_id: try: self.vcns.delete_edge(edge_id) return True except exceptions.ResourceNotFound: return True except exceptions.VcnsApiException as e: LOG.exception( _LE("VCNS: Failed to delete %(edge_id)s:\n" "%(response)s"), { 'edge_id': edge_id, 'response': e.response }) return False except Exception: LOG.exception(_LE("VCNS: Failed to delete %s"), edge_id) return False
def delete_edge(self, context, router_id, edge_id, dist=False): LOG.debug("Deleting edge %s", edge_id) if context is None: context = q_context.get_admin_context() try: LOG.debug("Deleting router binding %s", router_id) nsxv_db.delete_nsxv_router_binding(context.session, router_id) if not dist: LOG.debug("Deleting vnic bindings for edge %s", edge_id) nsxv_db.clean_edge_vnic_binding(context.session, edge_id) except sa_exc.NoResultFound: LOG.warning("Router Binding for %s not found", router_id) if edge_id: try: self.vcns.delete_edge(edge_id) return True except exceptions.ResourceNotFound: return True except exceptions.VcnsApiException as e: LOG.exception( "VCNS: Failed to delete %(edge_id)s:\n" "%(response)s", { 'edge_id': edge_id, 'response': e.response }) return False except Exception: LOG.exception("VCNS: Failed to delete %s", edge_id) return False
def clean_orphaned_router_bindings(resource, event, trigger, **kwargs): """Delete nsx router bindings entries without real objects behind them""" orphaned_list = get_orphaned_router_bindings() if not len(orphaned_list): LOG.info("No orphaned Router bindings found.") return LOG.info("Before delete; Orphaned Bindings:") LOG.info(formatters.output_formatter( constants.ORPHANED_BINDINGS, orphaned_list, ['edge_id', 'router_id', 'availability_zone', 'status'])) if not kwargs.get('force'): if len(orphaned_list): user_confirm = admin_utils.query_yes_no("Do you want to delete " "orphaned bindings", default="no") if not user_confirm: LOG.info("NSXv Router bindings deletion aborted by user") return edgeapi = utils.NeutronDbClient() for binding in orphaned_list: nsxv_db.delete_nsxv_router_binding( edgeapi.context.session, binding.router_id) LOG.info("Deleted %s orphaned router bindings. You may need to check for " "orphaned edges now.", len(orphaned_list))
def nsx_recreate_dhcp_edge_by_net_id(net_id): """Recreate a dhcp edge for a specific network without an edge""" LOG.info("ReCreating NSXv Edge for network: %s", net_id) context = n_context.get_admin_context() # init the plugin and edge manager cfg.CONF.set_override( 'core_plugin', 'vmware_nsx.shell.admin.plugins.nsxv.resources' '.utils.NsxVPluginWrapper') with utils.NsxVPluginWrapper() as plugin: nsxv_manager = vcns_driver.VcnsDriver(edge_utils.NsxVCallbacks(plugin)) edge_manager = edge_utils.EdgeManager(nsxv_manager, plugin) # verify that there is no DHCP edge for this network at the moment resource_id = (nsxv_constants.DHCP_EDGE_PREFIX + net_id)[:36] router_binding = nsxv_db.get_nsxv_router_binding( context.session, resource_id) if router_binding: # make sure there is no real edge if router_binding['edge_id']: edge_id = router_binding['edge_id'] try: nsxv_manager.vcns.get_edge(edge_id) except exceptions.ResourceNotFound: # No edge on backend # prevent logger from logging this exception sys.exc_clear() LOG.info("Edge %s does not exist on the NSX", edge_id) else: LOG.warning( "Network %(net_id)s already has a dhcp edge: " "%(edge_id)s", { 'edge_id': edge_id, 'net_id': net_id }) return # delete this old entry nsxv_db.delete_nsxv_router_binding(context.session, resource_id) # Verify that the network exists on neutron try: plugin.get_network(context, net_id) except nl_exc.NetworkNotFound: LOG.error("Network %s does not exist", net_id) return recreate_network_dhcp(context, plugin, edge_manager, None, net_id)
def recreate_network_dhcp(context, plugin, edge_manager, old_edge_id, net_id): """Handle the DHCP edge recreation of a network """ LOG.info("Moving network %s to a new edge", net_id) # delete the old binding resource_id = (nsxv_constants.DHCP_EDGE_PREFIX + net_id)[:36] nsxv_db.delete_nsxv_router_binding(context.session, resource_id) # Delete the old static binding of the networks` compute ports port_filters = {'network_id': [net_id], 'device_owner': ['compute:None']} compute_ports = plugin.get_ports(context, filters=port_filters) if old_edge_id: for port in compute_ports: # Delete old binding from the DB nsxv_db.delete_edge_dhcp_static_binding(context.session, old_edge_id, port['mac_address']) # Go over all the subnets with DHCP net_filters = {'network_id': [net_id], 'enable_dhcp': [True]} subnets = plugin.get_subnets(context, filters=net_filters) for subnet in subnets: LOG.info("Moving subnet %s to a new edge", subnet['id']) # allocate / reuse the new dhcp edge new_resource_id = edge_manager.create_dhcp_edge_service( context, net_id, subnet) if new_resource_id: # also add fw rules and metadata, once for the new edge plugin._update_dhcp_service_new_edge(context, resource_id) # Update the ip of the dhcp port LOG.info("Creating network %s DHCP address group", net_id) address_groups = plugin._create_network_dhcp_address_group(context, net_id) plugin.edge_manager.update_dhcp_edge_service(context, net_id, address_groups=address_groups) # find out the id of the new edge: new_binding = nsxv_db.get_nsxv_router_binding(context.session, resource_id) if new_binding: LOG.info("Network %(net_id)s was moved to edge %(edge_id)s", { 'net_id': net_id, 'edge_id': new_binding['edge_id'] }) else: LOG.error("Network %(net_id)s was not moved to a new edge", {'net_id': net_id})
def recreate_network_dhcp(context, plugin, edge_manager, old_edge_id, net_id): """Handle the DHCP edge recreation of a network """ LOG.info("Moving network %s to a new edge", net_id) # delete the old binding resource_id = (nsxv_constants.DHCP_EDGE_PREFIX + net_id)[:36] nsxv_db.delete_nsxv_router_binding(context.session, resource_id) # Delete the old static binding of the networks` compute ports port_filters = {'network_id': [net_id], 'device_owner': ['compute:None']} compute_ports = plugin.get_ports(context, filters=port_filters) if old_edge_id: for port in compute_ports: # Delete old binding from the DB nsxv_db.delete_edge_dhcp_static_binding(context.session, old_edge_id, port['mac_address']) # Go over all the subnets with DHCP net_filters = {'network_id': [net_id], 'enable_dhcp': [True]} subnets = plugin.get_subnets(context, filters=net_filters) for subnet in subnets: LOG.info("Moving subnet %s to a new edge", subnet['id']) # allocate / reuse the new dhcp edge new_resource_id = edge_manager.create_dhcp_edge_service( context, net_id, subnet) if new_resource_id: # also add fw rules and metadata, once for the new edge plugin._update_dhcp_service_new_edge(context, resource_id) # Update the ip of the dhcp port LOG.info("Creating network %s DHCP address group", net_id) address_groups = plugin._create_network_dhcp_address_group( context, net_id) plugin.edge_manager.update_dhcp_edge_service( context, net_id, address_groups=address_groups) # find out the id of the new edge: new_binding = nsxv_db.get_nsxv_router_binding( context.session, resource_id) if new_binding: LOG.info("Network %(net_id)s was moved to edge %(edge_id)s", {'net_id': net_id, 'edge_id': new_binding['edge_id']}) else: LOG.error("Network %(net_id)s was not moved to a new edge", {'net_id': net_id})
def nsx_recreate_dhcp_edge_by_net_id(net_id): """Recreate a dhcp edge for a specific network without an edge""" LOG.info("ReCreating NSXv Edge for network: %s", net_id) context = n_context.get_admin_context() # init the plugin and edge manager cfg.CONF.set_override('core_plugin', 'vmware_nsx.shell.admin.plugins.nsxv.resources' '.utils.NsxVPluginWrapper') with utils.NsxVPluginWrapper() as plugin: nsxv_manager = vcns_driver.VcnsDriver(edge_utils.NsxVCallbacks(plugin)) edge_manager = edge_utils.EdgeManager(nsxv_manager, plugin) # verify that there is no DHCP edge for this network at the moment resource_id = (nsxv_constants.DHCP_EDGE_PREFIX + net_id)[:36] router_binding = nsxv_db.get_nsxv_router_binding( context.session, resource_id) if router_binding: # make sure there is no real edge if router_binding['edge_id']: edge_id = router_binding['edge_id'] try: nsxv_manager.vcns.get_edge(edge_id) except exceptions.ResourceNotFound: # No edge on backend # prevent logger from logging this exception sys.exc_clear() LOG.info("Edge %s does not exist on the NSX", edge_id) else: LOG.warning("Network %(net_id)s already has a dhcp edge: " "%(edge_id)s", {'edge_id': edge_id, 'net_id': net_id}) return # delete this old entry nsxv_db.delete_nsxv_router_binding(context.session, resource_id) # Verify that the network exists on neutron try: plugin.get_network(context, net_id) except nl_exc.NetworkNotFound: LOG.error("Network %s does not exist", net_id) return recreate_network_dhcp(context, plugin, edge_manager, None, net_id)
def nsx_clean_backup_edge(resource, event, trigger, **kwargs): """Delete backup edge""" errmsg = ("Need to specify edge-id property. Add --property " "edge-id=<edge-id>") if not kwargs.get('property'): LOG.error(_LE("%s"), errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) edge_id = properties.get('edge-id') if not edge_id: LOG.error(_LE("%s"), errmsg) return try: edge = nsxv.get_edge(edge_id) except exceptions.NeutronException as x: LOG.error(_LE("%s"), str(x)) else: # edge[0] is response status code # edge[1] is response body backup_edges = [e['id'] for e in get_nsxv_backup_edges()] if (not edge[1]['name'].startswith('backup-') or edge[1]['id'] not in backup_edges): LOG.error(_LE('Edge: %s is not a backup edge; aborting delete'), edge_id) return confirm = admin_utils.query_yes_no("Do you want to delete edge: %s" % edge_id, default="no") if not confirm: LOG.info(_LI("Backup edge deletion aborted by user")) return try: with locking.LockManager.get_lock(edge_id): # Delete from NSXv backend nsxv.delete_edge(edge_id) # Remove bindings from Neutron DB edgeapi = utils.NeutronDbClient() nsxv_db.delete_nsxv_router_binding(edgeapi.context.session, edge[1]['name']) nsxv_db.clean_edge_vnic_binding(edgeapi.context.session, edge_id) except Exception as expt: LOG.error(_LE("%s"), str(expt))
def nsx_clean_backup_edge(resource, event, trigger, **kwargs): """Delete backup edge""" errmsg = ("Need to specify edge-id property. Add --property " "edge-id=<edge-id>") if not kwargs.get('property'): LOG.error(_LE("%s"), errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) edge_id = properties.get('edge-id') if not edge_id: LOG.error(_LE("%s"), errmsg) return try: edge = nsxv.get_edge(edge_id) except exceptions.NeutronException as e: LOG.error(_LE("%s"), str(e)) else: # edge[0] is response status code # edge[1] is response body backup_edges = [e['id'] for e in get_nsxv_backup_edges()] if (not edge[1]['name'].startswith('backup-') or edge[1]['id'] not in backup_edges): LOG.error( _LE('Edge: %s is not a backup edge; aborting delete'), edge_id) return confirm = admin_utils.query_yes_no( "Do you want to delete edge: %s" % edge_id, default="no") if not confirm: LOG.info(_LI("Backup edge deletion aborted by user")) return try: with locking.LockManager.get_lock(edge_id): # Delete from NSXv backend nsxv.delete_edge(edge_id) # Remove bindings from Neutron DB edgeapi = utils.NeutronDbClient() nsxv_db.delete_nsxv_router_binding( edgeapi.context.session, edge[1]['name']) nsxv_db.clean_edge_vnic_binding(edgeapi.context.session, edge_id) except Exception as e: LOG.error(_LE("%s"), str(e))
def nsx_recreate_dhcp_edge_by_net_id(net_id): """Recreate a dhcp edge for a specific network without an edge""" LOG.info("ReCreating NSXv Edge for network: %s", net_id) context = n_context.get_admin_context() # verify that there is no DHCP edge for this network at the moment resource_id = (nsxv_constants.DHCP_EDGE_PREFIX + net_id)[:36] router_binding = nsxv_db.get_nsxv_router_binding(context.session, resource_id) if router_binding: # make sure there is no edge if router_binding['edge_id']: LOG.warning( "Network %(net_id)s already has a dhcp edge: " "%(egde_id)s", { 'edge_id': router_binding['edge_id'], 'net_id': net_id }) return # delete this old entry nsxv_db.delete_nsxv_router_binding(context.session, resource_id) # init the plugin and edge manager cfg.CONF.set_override( 'core_plugin', 'vmware_nsx.shell.admin.plugins.nsxv.resources' '.utils.NsxVPluginWrapper') with utils.NsxVPluginWrapper() as plugin: nsxv_manager = vcns_driver.VcnsDriver(edge_utils.NsxVCallbacks(plugin)) edge_manager = edge_utils.EdgeManager(nsxv_manager, plugin) # check if this network is attached to a distributed router vdr_router_id = _get_net_vdr_router_id(plugin, context, net_id) if vdr_router_id: # recreate the edge as a VDR DHCP edge recreate_vdr_dhcp_edge(context, plugin, edge_manager, vdr_router_id) else: # This is a regular DHCP edge: recreate_network_dhcp(context, plugin, edge_manager, None, net_id)
def _validate_dhcp_edge(self, context, edge_dict, pfx_dict, networks, edge_id, readonly): # Also metadata network should be a valid network for the edge az_name = self.plugin.get_availability_zone_name_by_edge( context, edge_id) with locking.LockManager.get_lock(edge_id): vnic_binds = nsxv_db.get_edge_vnic_bindings_by_edge( context.session, edge_id) edge_networks = [bind['network_id'] for bind in vnic_binds] # Step (A) # Find router bindings which are mapped to dead networks, or # do not have interfaces registered in nsxv tables for binding in edge_dict[edge_id]: router_id = binding['router_id'] net_pfx = router_id[len(vcns_const.DHCP_EDGE_PREFIX):] net_id = pfx_dict.get(net_pfx) if net_id is None: # Delete router binding as we do not have such network # in Neutron self.error_count += 1 self.error_info = base_job.housekeeper_warning( self.error_info, 'router binding %s for edge %s has no matching ' 'neutron network', router_id, edge_id) if not readonly: nsxv_db.delete_nsxv_router_binding( context.session, binding['router_id']) self.fixed_count += 1 else: if net_id not in edge_networks: # Create vNic bind here self.error_count += 1 self.error_info = base_job.housekeeper_warning( self.error_info, 'edge %s vnic binding missing for network %s', edge_id, net_id) if not readonly: nsxv_db.allocate_edge_vnic_with_tunnel_index( context.session, edge_id, net_id, az_name) self.fixed_count += 1 # Step (B) # Find vNic bindings which reference invalid networks or aren't # bound to any router binding # Reread vNic binds as we might created more or deleted some in # step (A) vnic_binds = nsxv_db.get_edge_vnic_bindings_by_edge( context.session, edge_id) for bind in vnic_binds: if bind['network_id'] not in networks: self.error_count += 1 self.error_info = base_job.housekeeper_warning( self.error_info, 'edge vnic binding for edge %s is for invalid ' 'network id %s', edge_id, bind['network_id']) if not readonly: nsxv_db.free_edge_vnic_by_network( context.session, edge_id, bind['network_id']) self.fixed_count += 1 # Step (C) # Verify that backend is in sync with Neutron # Reread vNic binds as we might deleted some in step (B) vnic_binds = nsxv_db.get_edge_vnic_bindings_by_edge( context.session, edge_id) # Transform to network-keyed dict vnic_dict = { vnic['network_id']: { 'vnic_index': vnic['vnic_index'], 'tunnel_index': vnic['tunnel_index'] } for vnic in vnic_binds } backend_vnics = self.plugin.nsx_v.vcns.get_interfaces( edge_id)[1].get('vnics', []) if_changed = {} self._validate_edge_subinterfaces(context, edge_id, backend_vnics, vnic_dict, if_changed) self._add_missing_subinterfaces(context, edge_id, vnic_binds, backend_vnics, if_changed, readonly) if not readonly: for vnic in backend_vnics: if if_changed[vnic['index']]: self.plugin.nsx_v.vcns.update_interface(edge_id, vnic) self._update_router_bindings(context, edge_id) self.fixed_count += self.fixed_sub_if_count