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 get_metadata_status(resource, event, trigger, **kwargs): if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) net_id = properties.get('network_id') else: net_id = None edgeapi = utils.NeutronDbClient() edge_list = nsxv_db.get_nsxv_internal_edges_by_purpose( edgeapi.context.session, vcns_constants.InternalEdgePurposes.INTER_EDGE_PURPOSE) md_rtr_ids = [edge['router_id'] for edge in edge_list] router_bindings = nsxv_db.get_nsxv_router_bindings( edgeapi.context.session, filters={'router_id': md_rtr_ids}) edge_ids = [b['edge_id'] for b in router_bindings] _md_member_status('Metadata edge appliance: %s members', edge_ids) if net_id: as_provider_data = nsxv_db.get_edge_vnic_bindings_by_int_lswitch( edgeapi.context.session, net_id) providers = [asp['edge_id'] for asp in as_provider_data] if providers: LOG.info('Metadata providers for network %s', net_id) _md_member_status('Edge %s', providers) else: LOG.info('No providers found for network %s', net_id)
def update_shared_secret(resource, event, trigger, **kwargs): edgeapi = utils.NeutronDbClient() edge_list = nsxv_db.get_nsxv_internal_edges_by_purpose( edgeapi.context.session, vcns_constants.InternalEdgePurposes.INTER_EDGE_PURPOSE) md_rtr_ids = [edge['router_id'] for edge in edge_list] router_bindings = nsxv_db.get_nsxv_router_bindings( edgeapi.context.session, filters={'edge_type': [nsxv_constants.SERVICE_EDGE]}) edge_ids = list(set([binding['edge_id'] for binding in router_bindings if (binding['router_id'] not in set(md_rtr_ids) and not binding['router_id'].startswith( vcns_constants.BACKUP_ROUTER_PREFIX) and not binding['router_id'].startswith( vcns_constants.PLR_EDGE_PREFIX))])) for edge_id in edge_ids: with locking.LockManager.get_lock(edge_id): lb = nsxv_lb.NsxvLoadbalancer.get_loadbalancer(nsxv, edge_id) virt = lb.virtual_servers.get(md_proxy.METADATA_VSE_NAME) if not virt: LOG.error("Virtual server not found for edge: %s", edge_id) continue virt.del_app_rule('insert-auth') if cfg.CONF.nsxv.metadata_shared_secret: signature = hmac.new( bytearray(cfg.CONF.nsxv.metadata_shared_secret, 'ascii'), bytearray(edge_id, 'ascii'), hashlib.sha256).hexdigest() sign = 'reqadd X-Metadata-Provider-Signature:' + signature sign_app_rule = nsxv_lb.NsxvLBAppRule('insert-auth', sign) virt.add_app_rule(sign_app_rule) lb.submit_to_backend(nsxv, edge_id)
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 neutron_clean_backup_edge(resource, event, trigger, **kwargs): """Delete a backup edge from the neutron, and backend by it's name The name of the backup edge is the router-id column in the BD table nsxv_router_bindings, and it is also printed by list-mismatches """ errmsg = ("Need to specify router-id property. Add --property " "router-id=<router-id>") if not kwargs.get('property'): LOG.error("%s", errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) router_id = properties.get('router-id') if not router_id: LOG.error("%s", errmsg) return # look for the router-binding entry edgeapi = utils.NeutronDbClient() rtr_binding = nsxv_db.get_nsxv_router_binding( edgeapi.context.session, router_id) if not rtr_binding: LOG.error('Backup %s was not found in DB', router_id) return edge_id = rtr_binding['edge_id'] if edge_id: # delete from backend too _delete_edge_from_nsx_and_neutron(edge_id, router_id) else: # delete only from DB _delete_backup_from_neutron_db(None, router_id)
def _create_router(self): tenant_id = uuidutils.generate_uuid() data = {'router': {'tenant_id': tenant_id}} data['router']['name'] = 'dummy' data['router']['admin_state_up'] = True edgeapi = nsxv_utils.NeutronDbClient() return self._plugin.create_router(edgeapi.context, data)
def get_edge_id(self): edgeapi = nsxv_utils.NeutronDbClient() bindings = nsxv_db.get_nsxv_router_bindings(edgeapi.context.session) for binding in bindings: if binding.edge_id: return binding.edge_id # use a dummy edge return "edge-1"
def extend_edge_info(edge): """Add information from the nsxv-db, if available""" edgeapi = utils.NeutronDbClient() rtr_binding = nsxv_db.get_nsxv_router_binding_by_edge( edgeapi.context.session, edge['id']) if rtr_binding: edge['availability_zone'] = rtr_binding['availability_zone'] edge['db_status'] = rtr_binding['status']
def _get_edge_az_and_size(edge_id): edgeapi = utils.NeutronDbClient() binding = nsxv_db.get_nsxv_router_binding_by_edge(edgeapi.context.session, edge_id) if binding: return binding['availability_zone'], binding['appliance_size'] # default fallback return nsx_az.DEFAULT_NAME, nsxv_constants.LARGE
def create_router(self): # Create an exclusive router (with an edge) tenant_id = uuidutils.generate_uuid() data = {'router': {'tenant_id': tenant_id}} data['router']['name'] = 'dummy' data['router']['admin_state_up'] = True data['router']['router_type'] = 'exclusive' edgeapi = nsxv_utils.NeutronDbClient() return self._plugin.create_router(edgeapi.context, data)
def get_nsxv_backup_edges(): edges = utils.get_nsxv_backend_edges() backup_edges = [] edgeapi = utils.NeutronDbClient() for edge in edges: if edge['name'].startswith("backup-"): edge_vnic_binds = nsxv_db.get_edge_vnic_bindings_by_edge( edgeapi.context.session, edge['id']) if not edge_vnic_binds: backup_edges.append(edge) return backup_edges
def nsx_redo_metadata_cfg(resource, event, trigger, **kwargs): edgeapi = utils.NeutronDbClient() config.register_nsxv_azs(cfg.CONF, cfg.CONF.nsxv.availability_zones) conf_az = nsx_az.NsxVAvailabilityZones() az_list = conf_az.list_availability_zones_objects() for az in az_list: if az.supports_metadata(): nsx_redo_metadata_cfg_for_az(az, edgeapi) else: LOG.info("Skipping availability zone: %s - no metadata " "configuration", az.name)
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_list_name_mismatches(resource, event, trigger, **kwargs): edges = utils.get_nsxv_backend_edges() plugin_nsx_mismatch = [] backend_edge_ids = [] edgeapi = utils.NeutronDbClient() # Look for edges with the wrong names: for edge in edges: backend_edge_ids.append(edge['id']) rtr_binding = nsxv_db.get_nsxv_router_binding_by_edge( edgeapi.context.session, edge['id']) if (rtr_binding and edge['name'].startswith('backup-') and rtr_binding['router_id'] != edge['name']): plugin_nsx_mismatch.append({ 'edge_id': edge['id'], 'edge_name': edge['name'], 'router_id': rtr_binding['router_id'] }) LOG.info( formatters.output_formatter( constants.BACKUP_EDGES + ' with name mismatch:', plugin_nsx_mismatch, ['edge_id', 'edge_name', 'router_id'])) # Also look for missing edges like_filters = {'router_id': vcns_const.BACKUP_ROUTER_PREFIX + "%"} rtr_bindings = nsxv_db.get_nsxv_router_bindings(edgeapi.context.session, like_filters=like_filters) plugin_nsx_missing = [] for rtr_binding in rtr_bindings: if rtr_binding['edge_id'] not in backend_edge_ids: plugin_nsx_missing.append({ 'edge_id': rtr_binding['edge_id'], 'router_id': rtr_binding['router_id'], 'db_status': rtr_binding['status'] }) LOG.info( formatters.output_formatter( constants.BACKUP_EDGES + ' missing from backend:', plugin_nsx_missing, ['edge_id', 'router_id', 'db_status']))
def nsx_list_mismatch_addresses(resource, event, trigger, **kwargs): """List missing spoofguard policies approved addresses on NSXv. Address pairs defined on neutron compute ports that are missing from the NSX-V spoofguard policy of a specific/all networks. """ network_id = None if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) network_id = properties.get('network') spgapi = utils.NeutronDbClient() if network_id: policy_id = nsxv_db.get_spoofguard_policy_id(spgapi.context.session, network_id) if not policy_id: LOG.error( "Could not find spoofguard policy for neutron network " "%s", network_id) return with utils.NsxVPluginWrapper() as plugin: missing_data = nsx_list_mismatch_addresses_for_net( spgapi.context, plugin, network_id, policy_id) else: with utils.NsxVPluginWrapper() as plugin: missing_data = [] # Go over all the networks with spoofguard policies mappings = get_spoofguard_policy_network_mappings() for entry in mappings: missing_data.extend( nsx_list_mismatch_addresses_for_net( spgapi.context, plugin, entry['network_id'], entry['policy_id'])) if missing_data: LOG.info( formatters.output_formatter(constants.SPOOFGUARD_POLICY, missing_data, ['network', 'policy', 'port', 'data'])) else: LOG.info("No mismatches found.")
def nsx_redo_metadata_cfg(resource, event, trigger, **kwargs): properties = admin_utils.parse_multi_keyval_opt(kwargs.get('property')) edgeapi = utils.NeutronDbClient() plugin = utils.NsxVPluginWrapper() edge_id = properties.get('edge-id') if properties: if edge_id: nsx_redo_metadata_cfg_for_edge(edgeapi.context, plugin, edge_id) return else: # if the net-id property exist - recreate the edge for this network az_name = properties.get('az-name') if az_name: nsx_redo_metadata_cfg_for_az(edgeapi.context, plugin, az_name) return LOG.error('Cannot parse properties %s', properties) return nsx_redo_metadata_cfg_all(edgeapi.context, plugin)
def nsx_list_name_mismatches(resource, event, trigger, **kwargs): edges = nsxv.get_edges()[1] edges = edges['edgePage'].get('data', []) plugin_nsx_mismatch = [] edgeapi = utils.NeutronDbClient() for edge in edges: rtr_binding = nsxv_db.get_nsxv_router_binding_by_edge( edgeapi.context.session, edge['id']) if (rtr_binding and edge['name'].startswith('backup-') and rtr_binding['router_id'] != edge['name']): plugin_nsx_mismatch.append({ 'edge_id': edge['id'], 'edge_name': edge['name'], 'router_id': rtr_binding['router_id'] }) LOG.info( formatters.output_formatter(constants.BACKUP_EDGES, plugin_nsx_mismatch, ['edge_id', 'edge_name', 'router_id']))
def sync_lbaas_dfw_rules(resource, event, trigger, **kwargs): vcns = utils.get_nsxv_client() with locking.LockManager.get_lock('lbaas-fw-section'): fw_section_id = vcns.get_section_id(LBAAS_FW_SECTION_NAME) if not fw_section_id: section = et.Element('section') section.attrib['name'] = LBAAS_FW_SECTION_NAME sect = vcns.create_section('ip', et.tostring(section))[1] fw_section_id = et.fromstring(sect).attrib['id'] if not fw_section_id: LOG.error('No LBaaS FW Section id found') return neutron_db = utils.NeutronDbClient() pools = neutron_db.context.session.query(nlbaas_v2.PoolV2).all() pool_ids = [pool['id'] for pool in pools] section_uri = '%s/%s/%s' % (nsxv_api.FIREWALL_PREFIX, 'layer3sections', fw_section_id) xml_section_data = vcns.get_section(section_uri) if xml_section_data: xml_section = xml_section_data[1] else: LOG.info('LBaaS XML section was not found!') return section = et.fromstring(xml_section) for rule in section.findall('.//rule'): if rule.find('name').text in pool_ids: LOG.info('Rule %s found and valid', rule.find('name').text) else: section.remove(rule) LOG.info('Rule %s is stale and removed', rule.find('name').text) vcns.update_section(section_uri, et.tostring(section, encoding="us-ascii"), None)
def get_nsxv_backup_edges(scope="all"): edges = utils.get_nsxv_backend_edges() backup_edges = [] edgeapi = utils.NeutronDbClient() for edge in edges: if edge['name'].startswith("backup-"): # Make sure it is really a backup edge edge_vnic_binds = nsxv_db.get_edge_vnic_bindings_by_edge( edgeapi.context.session, edge['id']) if scope != "all": # Make sure the backup edge exists in neutron # Return backup edges existing in both neutron and backend # when scope != all edge_in_neutron = nsxv_db.get_nsxv_router_binding_by_edge( edgeapi.context.session, edge['id']) if not edge_vnic_binds and edge_in_neutron: extend_edge_info(edge) backup_edges.append(edge) else: if not edge_vnic_binds: extend_edge_info(edge) backup_edges.append(edge) return backup_edges
def nsx_fix_mismatch_addresses(resource, event, trigger, **kwargs): """Fix missing spoofguard policies approved addresses for a port.""" port_id = None if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) port_id = properties.get('port') if not port_id: usage_msg = ("Need to specify the id of the neutron port. " "Add --property port=<port_id>") LOG.error(usage_msg) return spgapi = utils.NeutronDbClient() with utils.NsxVPluginWrapper() as plugin: try: port = plugin.get_port(spgapi.context, port_id) except exceptions.PortNotFound: LOG.error("Could not find neutron port %s", port_id) return vnic_id = get_port_vnic_id(plugin, port) plugin._update_vnic_assigned_addresses(spgapi.context.session, port, vnic_id) LOG.info("Done.")
def get_spoofguard_policy_network_mappings(): spgapi = utils.NeutronDbClient() return nsxv_db.get_nsxv_spoofguard_policy_network_mappings( spgapi.context)
def nsx_fix_name_mismatch(resource, event, trigger, **kwargs): errmsg = ("Need to specify edge-id property. Add --property " "edge-id=<edge-id>") if not kwargs.get('property'): LOG.error("%s", errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) edgeapi = utils.NeutronDbClient() edge_id = properties.get('edge-id') if not edge_id: LOG.error("%s", errmsg) return try: # edge[0] is response status code # edge[1] is response body edge = nsxv.get_edge(edge_id)[1] except exceptions.NeutronException as e: LOG.error("%s", str(e)) else: if edge['name'].startswith('backup-'): rtr_binding = nsxv_db.get_nsxv_router_binding_by_edge( edgeapi.context.session, edge['id']) if rtr_binding['router_id'] == edge['name']: LOG.error('Edge %s no mismatch with NSX', edge_id) return try: with locking.LockManager.get_lock(edge_id): # Update edge at NSXv backend if rtr_binding['router_id'].startswith('dhcp-'): # Edge is a DHCP edge - just use router_id as name edge['name'] = rtr_binding['router_id'] else: # This is a router - if shared, prefix with 'shared-' nsx_attr = (edgeapi.context.session.query( nsxv_models.NsxvRouterExtAttributes).filter_by( router_id=rtr_binding['router_id']).first()) if nsx_attr and nsx_attr['router_type'] == 'shared': edge['name'] = ('shared-' + _uuid())[ :vcns_const.EDGE_NAME_LEN] elif (nsx_attr and nsx_attr['router_type'] == 'exclusive'): rtr_db = (edgeapi.context.session.query( l3_db.Router).filter_by( id=rtr_binding['router_id']).first()) if rtr_db: edge['name'] = ( rtr_db['name'][ :nsxv_constants.ROUTER_NAME_LENGTH - len(rtr_db['id'])] + '-' + rtr_db['id']) else: LOG.error( 'No database entry for router id %s', rtr_binding['router_id']) else: LOG.error( 'Could not determine the name for ' 'Edge %s', edge_id) return if not kwargs.get('force'): confirm = admin_utils.query_yes_no( "Do you want to rename edge %s to %s" % (edge_id, edge['name']), default="no") if not confirm: LOG.info("Edge rename aborted by user") return LOG.info("Edge rename started") # remove some keys that will fail the NSX transaction edge_utils.remove_irrelevant_keys_from_edge_request(edge) try: LOG.error("Update edge...") nsxv.update_edge(edge_id, edge) except Exception as e: LOG.error("Update failed - %s", (e)) except Exception as e: LOG.error("%s", str(e)) else: LOG.error( 'Edge %s has no backup prefix on NSX', edge_id) return
def tearDown(self): if self.router and self.router.get('id'): edgeapi = nsxv_utils.NeutronDbClient() self._plugin.delete_router(edgeapi.context, self.router['id']) super(TestNsxvAdminUtils, self).tearDown()
def get_router_edge_bindings(): edgeapi = utils.NeutronDbClient() return nsxv_db.get_nsxv_router_bindings(edgeapi.context)
def get_router_edge_vnic_bindings(edge_id): edgeapi = utils.NeutronDbClient() return nsxv_db.get_edge_vnic_bindings_by_edge(edgeapi.context.session, edge_id)
import vmware_nsx.shell.admin.plugins.nsxv.resources.utils as utils import vmware_nsx.shell.nsxadmin as shell from neutron.callbacks import registry from neutron.db import db_base_plugin_v2 from vmware_nsx._i18n import _LE, _LI from vmware_nsx.db import nsxv_db from vmware_nsx.plugins.nsx_v.vshield.common import exceptions from vmware_nsx.plugins.nsx_v.vshield import edge_utils from vmware_nsx.plugins.nsx_v.vshield import vcns_driver LOG = logging.getLogger(__name__) nsxv = utils.get_nsxv_client() neutron_db = utils.NeutronDbClient() def nsx_get_static_bindings_by_edge(edge_id): nsx_dhcp_static_bindings = set() nsx_dhcp_bindings = nsxv.query_dhcp_configuration(edge_id) # nsx_dhcp_bindings[0] contains response headers; # nsx_dhcp_bindings[1] contains response payload sbindings = nsx_dhcp_bindings[1].get('staticBindings').get( 'staticBindings') for binding in sbindings: nsx_dhcp_static_bindings.add( (edge_id, binding.get('macAddress').lower(), binding.get('bindingId').lower()))
def nsx_redo_metadata_cfg(resource, event, trigger, **kwargs): edgeapi = utils.NeutronDbClient() net_list = nsxv_db.get_nsxv_internal_network( edgeapi.context.session, vcns_constants.InternalEdgePurposes.INTER_EDGE_PURPOSE) internal_net = None internal_subnet = None if net_list: internal_net = net_list[0]['network_id'] internal_subnet = edgeapi.context.session.query( models_v2.Subnet).filter_by( network_id=internal_net).first().get('id') edge_list = nsxv_db.get_nsxv_internal_edges_by_purpose( edgeapi.context.session, vcns_constants.InternalEdgePurposes.INTER_EDGE_PURPOSE) md_rtr_ids = [edge['router_id'] for edge in edge_list] edge_internal_ips = [] for edge in edge_list: edge_internal_port = edgeapi.context.session.query( models_v2.Port).filter_by(network_id=internal_net, device_id=edge['router_id']).first() if edge_internal_port: edge_internal_ip = edgeapi.context.session.query( models_v2.IPAllocation).filter_by( port_id=edge_internal_port['id']).first() edge_internal_ips.append(edge_internal_ip['ip_address']) if not internal_net or not internal_subnet or not edge_internal_ips: LOG.error(_LE("Metadata infrastructure is missing or broken. " "It is recommended to restart neutron service before " "proceeding with configuration restoration")) return router_bindings = nsxv_db.get_nsxv_router_bindings( edgeapi.context.session, filters={'edge_type': [nsxv_constants.SERVICE_EDGE]}) edge_ids = list(set([binding['edge_id'] for binding in router_bindings if (binding['router_id'] not in set(md_rtr_ids) and not binding['router_id'].startswith( vcns_constants.BACKUP_ROUTER_PREFIX) and not binding['router_id'].startswith( vcns_constants.PLR_EDGE_PREFIX))])) for edge_id in edge_ids: with locking.LockManager.get_lock(edge_id): lb = nsxv_lb.NsxvLoadbalancer.get_loadbalancer(nsxv, edge_id) virt = lb.virtual_servers.get(md_proxy.METADATA_VSE_NAME) if virt: pool = virt.default_pool pool.members = {} i = 0 s_port = cfg.CONF.nsxv.nova_metadata_port for member_ip in edge_internal_ips: i += 1 member = nsxv_lb.NsxvLBPoolMember( name='Member-%d' % i, ip_address=member_ip, port=s_port, monitor_port=s_port) pool.add_member(member) lb.submit_to_backend(nsxv, edge_id)