def list_missing_networks(resource, event, trigger, **kwargs): """List neutron networks that are missing the NSX backend network """ plugin = db_base_plugin_v2.NeutronDbPluginV2() admin_cxt = neutron_context.get_admin_context() neutron_networks = plugin.get_networks(admin_cxt) networks = [] for net in neutron_networks: neutron_id = net['id'] # get the network nsx id from the mapping table nsx_id = get_network_nsx_id(admin_cxt, neutron_id) if not nsx_id: # skip external networks pass else: try: utils.get_connected_nsxlib().logical_switch.get(nsx_id) except nsx_exc.ResourceNotFound: networks.append({ 'name': net['name'], 'neutron_id': neutron_id, 'nsx_id': nsx_id }) if len(networks) > 0: title = _LI("Found %d internal networks missing from the NSX " "manager:") % len(networks) LOG.info( formatters.output_formatter(title, networks, ['name', 'neutron_id', 'nsx_id'])) else: LOG.info(_LI("All internal networks exist on the NSX manager"))
def update_security_groups_logging(resource, event, trigger, **kwargs): """Update allowed traffic logging for all neutron security group rules""" errmsg = ("Need to specify log-allowed-traffic property. Add --property " "log-allowed-traffic=true/false") if not kwargs.get('property'): LOG.error("%s", errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) log_allowed_str = properties.get('log-allowed-traffic') if not log_allowed_str or log_allowed_str.lower() not in ['true', 'false']: LOG.error("%s", errmsg) return log_allowed = log_allowed_str.lower() == 'true' context = neutron_context.get_admin_context() nsxlib = v3_utils.get_connected_nsxlib() with v3_utils.NsxV3PluginWrapper() as plugin: secgroups = plugin.get_security_groups(context, fields=['id', sg_logging.LOGGING]) LOG.info("Going to update logging of %s sections", len(secgroups)) for sg in [sg for sg in secgroups if sg.get(sg_logging.LOGGING) is False]: nsgroup_id, section_id = nsx_db.get_sg_mappings( context.session, sg['id']) if section_id: try: nsxlib.firewall_section.set_rule_logging( section_id, logging=log_allowed) except nsx_lib_exc.ManagerError: LOG.error("Failed to update firewall rule logging " "for rule in section %s", section_id)
def list_orphaned_routers(resource, event, trigger, **kwargs): nsxlib = utils.get_connected_nsxlib() admin_cxt = neutron_context.get_admin_context() missing_routers = v3_utils.get_orphaned_routers(admin_cxt, nsxlib) LOG.info( formatters.output_formatter(constants.ORPHANED_ROUTERS, missing_routers, ['id', 'display_name']))
def update_enable_standby_relocation(resource, event, trigger, **kwargs): """Enable standby relocation on all routers """ # This feature is supported only since nsx version 2.4 nsxlib = utils.get_connected_nsxlib() version = nsxlib.get_version() if not nsx_utils.is_nsx_version_2_4_0(version): LOG.info("Standby relocation update is only supported from 2.4 " "onwards") LOG.info("Version is %s", version) return # Go over all neutron routers plugin = RoutersPlugin() admin_cxt = neutron_context.get_admin_context() filters = utils.get_plugin_filters(admin_cxt) neutron_routers = plugin.get_routers(admin_cxt, filters=filters) for router in neutron_routers: neutron_id = router['id'] # get the router nsx id from the mapping table nsx_id = nsx_db.get_nsx_router_id(admin_cxt.session, neutron_id) try: nsxlib.logical_router.update(lrouter_id=nsx_id, enable_standby_relocation=True) except Exception as e: # This may fail if the service router is not created LOG.warning("Router %s cannot enable standby relocation: %s", neutron_id, e) else: LOG.info("Router %s was enabled with standby relocation", neutron_id) LOG.info("Done")
def list_orphaned_networks(resource, event, trigger, **kwargs): nsxlib = utils.get_connected_nsxlib() admin_cxt = neutron_context.get_admin_context() missing_networks = v3_utils.get_orphaned_networks(admin_cxt, nsxlib) LOG.info(formatters.output_formatter(constants.ORPHANED_NETWORKS, missing_networks, ['id', 'display_name']))
def list_missing_networks(resource, event, trigger, **kwargs): """List neutron networks that are missing the NSX backend network """ nsxlib = utils.get_connected_nsxlib() plugin = db_base_plugin_v2.NeutronDbPluginV2() admin_cxt = neutron_context.get_admin_context() filters = utils.get_plugin_filters(admin_cxt) neutron_networks = plugin.get_networks(admin_cxt, filters=filters) networks = [] for net in neutron_networks: neutron_id = net['id'] # get the network nsx id from the mapping table nsx_id = get_network_nsx_id(admin_cxt, neutron_id) if not nsx_id: # skip external networks pass else: try: nsxlib.logical_switch.get(nsx_id) except nsx_exc.ResourceNotFound: networks.append({'name': net['name'], 'neutron_id': neutron_id, 'nsx_id': nsx_id}) if len(networks) > 0: title = ("Found %d internal networks missing from the NSX " "manager:") % len(networks) LOG.info(formatters.output_formatter( title, networks, ['name', 'neutron_id', 'nsx_id'])) else: LOG.info("All internal networks exist on the NSX manager")
def list_missing_routers(resource, event, trigger, **kwargs): """List neutron routers that are missing the NSX backend router """ nsxlib = utils.get_connected_nsxlib() plugin = RoutersPlugin() admin_cxt = neutron_context.get_admin_context() neutron_routers = plugin.get_routers(admin_cxt) routers = [] for router in neutron_routers: neutron_id = router['id'] # get the router nsx id from the mapping table nsx_id = nsx_db.get_nsx_router_id(admin_cxt.session, neutron_id) if not nsx_id: routers.append({ 'name': router['name'], 'neutron_id': neutron_id, 'nsx_id': None }) else: try: nsxlib.logical_router.get(nsx_id) except nsx_exc.ResourceNotFound: routers.append({ 'name': router['name'], 'neutron_id': neutron_id, 'nsx_id': nsx_id }) if len(routers) > 0: title = ("Found %d routers missing from the NSX " "manager:") % len(routers) LOG.info( formatters.output_formatter(title, routers, ['name', 'neutron_id', 'nsx_id'])) else: LOG.info("All routers exist on the NSX manager")
def tag_default_ports(resource, event, trigger, **kwargs): nsxlib = v3_utils.get_connected_nsxlib() admin_cxt = neutron_context.get_admin_context() filters = v3_utils.get_plugin_filters(admin_cxt) # the plugin creation below will create the NS group and update the default # OS section to have the correct applied to group with v3_utils.NsxV3PluginWrapper() as _plugin: neutron_ports = _plugin.get_ports(admin_cxt, filters=filters) for port in neutron_ports: neutron_id = port['id'] # get the network nsx id from the mapping table nsx_id = plugin_utils.get_port_nsx_id(admin_cxt.session, neutron_id) if not nsx_id: continue device_owner = port['device_owner'] if (device_owner == l3_db.DEVICE_OWNER_ROUTER_INTF or device_owner == const.DEVICE_OWNER_DHCP): continue ps = _plugin._get_port_security_binding(admin_cxt, neutron_id) if not ps: continue try: nsx_port = nsxlib.logical_port.get(nsx_id) except nsx_exc.ResourceNotFound: continue tags_update = nsx_port['tags'] tags_update += [{'scope': security.PORT_SG_SCOPE, 'tag': plugin.NSX_V3_DEFAULT_SECTION}] nsxlib.logical_port.update(nsx_id, None, tags_update=tags_update)
def list_metadata_networks(resource, event, trigger, **kwargs): """List Metadata networks in Neutron.""" if not cfg.CONF.nsx_v3.native_metadata_route: meta_networks = [network for network in neutron_client.get_networks() if _is_metadata_network(network)] LOG.info(formatters.output_formatter(constants.METADATA_PROXY, meta_networks, ['id', 'name', 'subnets'])) else: nsxlib = utils.get_connected_nsxlib() tags = [{'scope': 'os-neutron-net-id'}] ports = nsxlib.search_by_tags(resource_type='LogicalPort', tags=tags) for port in ports['results']: if port['attachment']['attachment_type'] == 'METADATA_PROXY': net_id = None for tag in port['tags']: if tag['scope'] == 'os-neutron-net-id': net_id = tag['tag'] break uri = '/md-proxies/%s/%s/status' % (port['attachment']['id'], port['logical_switch_id']) status = nsxlib.client.get(uri) LOG.info("Status for MD proxy on neutron network %s (logical " "switch %s) is %s", net_id, port['logical_switch_id'], status.get('proxy_status', 'Unknown'))
def update_nat_rules(resource, event, trigger, **kwargs): """Update all routers NAT rules to not bypass the firewall""" # This feature is supported only since nsx version 2 nsxlib = utils.get_connected_nsxlib() version = nsxlib.get_version() if not nsx_utils.is_nsx_version_2_0_0(version): LOG.info("NAT rules update only supported from 2.0 onwards") LOG.info("Version is %s", version) return # Go over all neutron routers plugin = RoutersPlugin() admin_cxt = neutron_context.get_admin_context() neutron_routers = plugin.get_routers(admin_cxt) num_of_updates = 0 for router in neutron_routers: neutron_id = router['id'] # get the router nsx id from the mapping table nsx_id = nsx_db.get_nsx_router_id(admin_cxt.session, neutron_id) if nsx_id: # get all NAT rules: rules = nsxlib.logical_router.list_nat_rules(nsx_id)['results'] for rule in rules: if 'nat_pass' not in rule or rule['nat_pass']: nsxlib.logical_router.update_nat_rule(nsx_id, rule['id'], nat_pass=False) num_of_updates = num_of_updates + 1 if num_of_updates: LOG.info("Done updating %s NAT rules", num_of_updates) else: LOG.info("Did not find any NAT rule to update")
def tag_default_ports(resource, event, trigger, **kwargs): nsxlib = v3_utils.get_connected_nsxlib() admin_cxt = neutron_context.get_admin_context() filters = v3_utils.get_plugin_filters(admin_cxt) # the plugin creation below will create the NS group and update the default # OS section to have the correct applied to group with v3_utils.NsxV3PluginWrapper() as _plugin: neutron_ports = _plugin.get_ports(admin_cxt, filters=filters) for port in neutron_ports: neutron_id = port['id'] # get the network nsx id from the mapping table nsx_id = get_port_nsx_id(admin_cxt.session, neutron_id) if not nsx_id: continue device_owner = port['device_owner'] if (device_owner == l3_db.DEVICE_OWNER_ROUTER_INTF or device_owner == const.DEVICE_OWNER_DHCP): continue ps = _plugin._get_port_security_binding(admin_cxt, neutron_id) if not ps: continue try: nsx_port = nsxlib.logical_port.get(nsx_id) except nsx_exc.ResourceNotFound: continue tags_update = nsx_port['tags'] tags_update += [{ 'scope': security.PORT_SG_SCOPE, 'tag': plugin.NSX_V3_DEFAULT_SECTION }] nsxlib.logical_port.update(nsx_id, None, tags_update=tags_update)
def update_security_groups_logging(resource, event, trigger, **kwargs): """Update allowed traffic logging for all neutron security group rules""" errmsg = ("Need to specify log-allowed-traffic property. Add --property " "log-allowed-traffic=true/false") if not kwargs.get('property'): LOG.error("%s", errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) log_allowed_str = properties.get('log-allowed-traffic') if not log_allowed_str or log_allowed_str.lower() not in ['true', 'false']: LOG.error("%s", errmsg) return log_allowed = log_allowed_str.lower() == 'true' context = neutron_context.get_admin_context() nsxlib = v3_utils.get_connected_nsxlib() with v3_utils.NsxV3PluginWrapper() as plugin: secgroups = plugin.get_security_groups( context, fields=['id', sg_logging.LOGGING]) LOG.info("Going to update logging of %s sections", len(secgroups)) for sg in [ sg for sg in secgroups if sg.get(sg_logging.LOGGING) is False ]: nsgroup_id, section_id = nsx_db.get_sg_mappings( context.session, sg['id']) if section_id: try: nsxlib.firewall_section.set_rule_logging( section_id, logging=log_allowed) except nsx_lib_exc.ManagerError: LOG.error( "Failed to update firewall rule logging " "for rule in section %s", section_id)
def list_orphaned_sections(resource, event, trigger, **kwargs): """List orphaned firewall sections""" nsxlib = v3_utils.get_connected_nsxlib() orphaned_sections = plugin_utils.get_orphaned_firewall_sections( neutron_sg.context, nsxlib) _log_info(constants.ORPHANED_FIREWALL_SECTIONS, orphaned_sections, attrs=['id', 'display_name'])
def nsx_update_metadata_proxy(resource, event, trigger, **kwargs): """Update Metadata proxy for NSXv3 CrossHairs.""" nsx_version = utils.get_connected_nsxlib().get_version() if not nsx_utils.is_nsx_version_1_1_0(nsx_version): LOG.info(_LI("This utility is not available for NSX version %s"), nsx_version) return metadata_proxy_uuid = None if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) metadata_proxy_uuid = properties.get('metadata_proxy_uuid') if not metadata_proxy_uuid: LOG.error(_LE("metadata_proxy_uuid is not defined")) return cfg.CONF.set_override('dhcp_agent_notification', False) cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3') cfg.CONF.set_override('metadata_proxy_uuid', metadata_proxy_uuid, 'nsx_v3') plugin = utils.NsxV3PluginWrapper() nsx_client = utils.get_nsxv3_client() port_resource = resources.LogicalPort(nsx_client) # For each Neutron network, check if it is an internal metadata network. # If yes, delete the network and associated router interface. # Otherwise, create a logical switch port with MD-Proxy attachment. for network in neutron_client.get_networks(): if _is_metadata_network(network): # It is a metadata network, find the attached router, # remove the router interface and the network. filters = {'device_owner': const.ROUTER_INTERFACE_OWNERS, 'fixed_ips': { 'subnet_id': [network['subnets'][0]], 'ip_address': [nsx_rpc.METADATA_GATEWAY_IP]}} ports = neutron_client.get_ports(filters=filters) if not ports: continue router_id = ports[0]['device_id'] interface = {'subnet_id': network['subnets'][0]} plugin.remove_router_interface(router_id, interface) LOG.info(_LI("Removed metadata interface on router %s"), router_id) plugin.delete_network(network['id']) LOG.info(_LI("Removed metadata network %s"), network['id']) else: lswitch_id = neutron_client.net_id_to_lswitch_id(network['id']) if not lswitch_id: continue tags = nsx_utils.build_v3_tags_payload( network, resource_type='os-neutron-net-id', project_name='admin') name = nsx_utils.get_name_and_uuid('%s-%s' % ( 'mdproxy', network['name'] or 'network'), network['id']) port_resource.create( lswitch_id, metadata_proxy_uuid, tags=tags, name=name, attachment_type=nsx_constants.ATTACHMENT_MDPROXY) LOG.info(_LI("Enabled native metadata proxy for network %s"), network['id'])
def find_cluster_managers_ips(resource, event, trigger, **kwargs): """Show the current NSX rate limit.""" nsxlib = utils.get_connected_nsxlib() manager_ips = nsxlib.cluster_nodes.get_managers_ips() LOG.info("NSX Cluster has %s manager nodes:", len(manager_ips)) for ip in manager_ips: LOG.info("%s", str(ip))
def migrate_nsgroups_to_dynamic_criteria(resource, event, trigger, **kwargs): nsxlib = v3_utils.get_connected_nsxlib() if not nsxlib.feature_supported(consts.FEATURE_DYNAMIC_CRITERIA): LOG.error("Dynamic criteria grouping feature isn't supported by " "this NSX version.") return # First, we add the criteria tags for all ports. _update_ports_dynamic_criteria_tags() # Update security-groups with dynamic criteria and remove direct members. _update_security_group_dynamic_criteria()
def _update_ports_dynamic_criteria_tags(): nsxlib = v3_utils.get_connected_nsxlib() for port in neutron_db.get_ports(): secgroups = neutron_sg.get_port_security_groups(port['id']) # Nothing to do with ports that are not associated with any sec-group. if not secgroups: continue _, lport_id = neutron_db.get_lswitch_and_lport_id(port['id']) criteria_tags = nsxlib.ns_group.get_lport_tags(secgroups) nsxlib.logical_port.update(lport_id, False, tags_update=criteria_tags)
def nsx_rate_limit_show(resource, event, trigger, **kwargs): """Show the current NSX rate limit.""" nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(nsx_constants.FEATURE_RATE_LIMIT): LOG.error("This utility is not available for NSX version %s", nsxlib.get_version()) return rate_limit = nsxlib.http_services.get_rate_limit() LOG.info("Current NSX rate limit is %s", rate_limit)
def _get_dhcp_profile_uuid(**kwargs): if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) dhcp_profile_uuid = properties.get('dhcp_profile_uuid') if dhcp_profile_uuid: return dhcp_profile_uuid nsxlib = utils.get_connected_nsxlib() if cfg.CONF.nsx_v3.dhcp_profile: return nsxlib.native_dhcp_profile.get_id_by_name_or_id( cfg.CONF.nsx_v3.dhcp_profile)
def migrate_nsgroups_to_dynamic_criteria(resource, event, trigger, **kwargs): """Update NSX security groups dynamic criteria for NSXv3 CrossHairs""" nsxlib = v3_utils.get_connected_nsxlib() if not nsxlib.feature_supported(consts.FEATURE_DYNAMIC_CRITERIA): LOG.error("Dynamic criteria grouping feature isn't supported by " "this NSX version.") return # First, we add the criteria tags for all ports. _update_ports_dynamic_criteria_tags() # Update security-groups with dynamic criteria and remove direct members. _update_security_group_dynamic_criteria()
def nsx_update_metadata_proxy_server_ip(resource, event, trigger, **kwargs): """Update Metadata proxy server ip on the nsx.""" nsxlib = utils.get_connected_nsxlib() nsx_version = nsxlib.get_version() if not nsx_utils.is_nsx_version_1_1_0(nsx_version): LOG.error("This utility is not available for NSX version %s", nsx_version) return server_ip = None az_name = nsx_az.DEFAULT_NAME if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) server_ip = properties.get('server-ip') az_name = properties.get('availability-zone', az_name) if not server_ip or not netaddr.valid_ipv4(server_ip): LOG.error("Need to specify a valid server-ip parameter") return config.register_nsxv3_azs(cfg.CONF, cfg.CONF.nsx_v3.availability_zones) if (az_name != nsx_az.DEFAULT_NAME and az_name not in cfg.CONF.nsx_v3.availability_zones): LOG.error("Availability zone %s was not found in the configuration", az_name) return az = nsx_az.NsxV3AvailabilityZones().get_availability_zone(az_name) az.translate_configured_names_to_uuids(nsxlib) if (not az.metadata_proxy or not cfg.CONF.nsx_v3.native_dhcp_metadata): LOG.error( "Native DHCP metadata is not enabled in the configuration " "of availability zone %s", az_name) return metadata_proxy_uuid = az._native_md_proxy_uuid try: mdproxy = nsxlib.native_md_proxy.get(metadata_proxy_uuid) except nsx_exc.ResourceNotFound: LOG.error("metadata proxy %s not found", metadata_proxy_uuid) return # update the IP in the URL url = mdproxy.get('metadata_server_url') url = re.sub(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', server_ip, url) LOG.info( "Updating the URL of the metadata proxy server %(uuid)s to " "%(url)s", { 'uuid': metadata_proxy_uuid, 'url': url }) nsxlib.native_md_proxy.update(metadata_proxy_uuid, server_url=url) LOG.info("Done.")
def _update_ports_dynamic_criteria_tags(): nsxlib = v3_utils.get_connected_nsxlib() for port in neutron_db.get_ports(): secgroups = neutron_sg.get_port_security_groups(port['id']) # Nothing to do with ports that are not associated with any sec-group. if not secgroups: continue _, lport_id = neutron_db.get_lswitch_and_lport_id(port['id']) criteria_tags = nsxlib.ns_group.get_lport_tags(secgroups) nsxlib.logical_port.update( lport_id, False, tags_update=criteria_tags)
def _find_missing_sections(): nsxlib = v3_utils.get_connected_nsxlib() fw_sections = nsxlib.firewall_section.list() sg_mappings = plugin_utils.get_security_groups_mappings(neutron_sg.context) missing_sections = {} for sg_db in sg_mappings: for fw_section in fw_sections: if fw_section['id'] == sg_db['section-id']: break else: missing_sections[sg_db['id']] = sg_db return missing_sections
def _find_missing_security_groups(): nsxlib = v3_utils.get_connected_nsxlib() nsx_secgroups = nsxlib.ns_group.list() sg_mappings = plugin_utils.get_security_groups_mappings(neutron_sg.context) missing_secgroups = {} for sg_db in sg_mappings: for nsx_sg in nsx_secgroups: if nsx_sg['id'] == sg_db['nsx-securitygroup-id']: break else: missing_secgroups[sg_db['id']] = sg_db return missing_secgroups
def nsx_list_lb_monitors(resource, event, trigger, **kwargs): nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(consts.FEATURE_LOAD_BALANCER): LOG.error("This utility is not available for NSX version %s", nsxlib.get_version()) return lb_monitors = nsxlib.load_balancer.monitor.list() LOG.info(formatters.output_formatter( constants.LB_MONITORS, [lb_monitors['results']], ['display_name', 'id', 'resource_type'])) return bool(lb_monitors)
def clean_orphaned_sections(resource, event, trigger, **kwargs): """Delete orphaned firewall sections from the NSX backend""" nsxlib = v3_utils.get_connected_nsxlib() orphaned_sections = plugin_utils.get_orphaned_firewall_sections( neutron_sg.context, nsxlib) for sec in orphaned_sections: try: nsxlib.firewall_section.delete(sec['id']) except Exception as e: LOG.error("Failed to delete backend firewall section %(id)s : " "%(e)s.", {'id': sec['id'], 'e': e}) else: LOG.info("Backend firewall section %s was deleted.", sec['id'])
def nsx_list_lb_pools(resource, event, trigger, **kwargs): nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(consts.FEATURE_LOAD_BALANCER): LOG.error("This utility is not available for NSX version %s", nsxlib.get_version()) return lb_pools = nsxlib.load_balancer.pool.list() LOG.info(formatters.output_formatter( constants.LB_POOLS, lb_pools['results'], ['display_name', 'id', 'active_monitor_ids', 'members'])) return bool(lb_pools)
def fix_security_groups(resource, event, trigger, **kwargs): """Fix mismatch security groups by recreating missing sections & NS groups on the NSX backend """ context_ = neutron_context.get_admin_context() inconsistent_secgroups = _find_missing_sections() inconsistent_secgroups.update(_find_missing_security_groups()) nsxlib = v3_utils.get_connected_nsxlib() with v3_utils.NsxV3PluginWrapper() as plugin: for sg_id, sg in inconsistent_secgroups.items(): secgroup = plugin.get_security_group(context_, sg_id) try: # FIXME(roeyc): try..except clause should be removed once the # api will return 404 response code instead 400 for trying to # delete a non-existing firewall section. nsxlib.firewall_section.delete(sg['section-id']) except Exception: pass nsxlib.ns_group.delete(sg['nsx-securitygroup-id']) neutron_sg.delete_security_group_section_mapping(sg_id) neutron_sg.delete_security_group_backend_mapping(sg_id) nsgroup, fw_section = ( plugin._create_security_group_backend_resources(secgroup)) nsx_db.save_sg_mappings( context_, sg_id, nsgroup['id'], fw_section['id']) # If version > 1.1 then we use dynamic criteria tags, and the port # should already have them. if not nsxlib.feature_supported(consts.FEATURE_DYNAMIC_CRITERIA): members = [] for port_id in neutron_sg.get_ports_in_security_group(sg_id): lport_id = neutron_sg.get_logical_port_id(port_id) members.append(lport_id) nsxlib.ns_group.add_members( nsgroup['id'], consts.TARGET_TYPE_LOGICAL_PORT, members) for rule in secgroup['security_group_rules']: rule_mapping = (context_.session.query( nsx_models.NeutronNsxRuleMapping).filter_by( neutron_id=rule['id']).one()) with context_.session.begin(subtransactions=True): context_.session.delete(rule_mapping) action = (consts.FW_ACTION_DROP if secgroup.get(provider_sg.PROVIDER) else consts.FW_ACTION_ALLOW) rules = plugin._create_firewall_rules( context_, fw_section['id'], nsgroup['id'], secgroup.get(sg_logging.LOGGING, False), action, secgroup['security_group_rules']) plugin.save_security_group_rule_mappings(context_, rules['rules'])
def fix_security_groups(resource, event, trigger, **kwargs): """Fix mismatch security groups by recreating missing sections & NS groups on the NSX backend """ context_ = neutron_context.get_admin_context() inconsistent_secgroups = _find_missing_sections() inconsistent_secgroups.update(_find_missing_security_groups()) nsxlib = v3_utils.get_connected_nsxlib() with v3_utils.NsxV3PluginWrapper() as plugin: for sg_id, sg in inconsistent_secgroups.items(): secgroup = plugin.get_security_group(context_, sg_id) try: # FIXME(roeyc): try..except clause should be removed once the # api will return 404 response code instead 400 for trying to # delete a non-existing firewall section. nsxlib.firewall_section.delete(sg['section-id']) except Exception: pass nsxlib.ns_group.delete(sg['nsx-securitygroup-id']) neutron_sg.delete_security_group_section_mapping(sg_id) neutron_sg.delete_security_group_backend_mapping(sg_id) nsgroup, fw_section = ( plugin._create_security_group_backend_resources(secgroup)) nsx_db.save_sg_mappings(context_, sg_id, nsgroup['id'], fw_section['id']) # If version > 1.1 then we use dynamic criteria tags, and the port # should already have them. if not nsxlib.feature_supported(consts.FEATURE_DYNAMIC_CRITERIA): members = [] for port_id in neutron_sg.get_ports_in_security_group(sg_id): lport_id = neutron_sg.get_logical_port_id(port_id) members.append(lport_id) nsxlib.ns_group.add_members(nsgroup['id'], consts.TARGET_TYPE_LOGICAL_PORT, members) for rule in secgroup['security_group_rules']: rule_mapping = (context_.session.query( nsx_models.NeutronNsxRuleMapping).filter_by( neutron_id=rule['id']).one()) with context_.session.begin(subtransactions=True): context_.session.delete(rule_mapping) action = (consts.FW_ACTION_DROP if secgroup.get( provider_sg.PROVIDER) else consts.FW_ACTION_ALLOW) rules = plugin._create_firewall_rules( context_, fw_section['id'], nsgroup['id'], secgroup.get(sg_logging.LOGGING, False), action, secgroup['security_group_rules']) plugin.save_security_group_rule_mappings(context_, rules['rules'])
def nsx_list_lb_services(resource, event, trigger, **kwargs): """List LB services on NSX backend""" nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(consts.FEATURE_LOAD_BALANCER): LOG.error("This utility is not available for NSX version %s", nsxlib.get_version()) return lb_services = nsxlib.load_balancer.service.list() LOG.info(formatters.output_formatter( constants.LB_SERVICES, lb_services['results'], ['display_name', 'id', 'virtual_server_ids', 'attachment'])) return bool(lb_services)
def nsx_list_lb_virtual_servers(resource, event, trigger, **kwargs): """List LB virtual servers on NSX backend""" nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(consts.FEATURE_LOAD_BALANCER): LOG.error("This utility is not available for NSX version %s", nsxlib.get_version()) return lb_virtual_servers = nsxlib.load_balancer.virtual_server.list() LOG.info(formatters.output_formatter( constants.LB_VIRTUAL_SERVERS, [lb_virtual_servers['results']], ['display_name', 'id', 'ip_address', 'pool_id'])) return bool(lb_virtual_servers)
def update_dhcp_relay(resource, event, trigger, **kwargs): """Update all routers dhcp relay service by the current configuration""" nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(nsx_constants.FEATURE_DHCP_RELAY): version = nsxlib.get_version() LOG.error("DHCP relay is not supported by NSX version %s", version) return admin_cxt = neutron_context.get_admin_context() filters = utils.get_plugin_filters(admin_cxt) with utils.NsxV3PluginWrapper() as plugin: # Make sure FWaaS was initialized plugin.init_fwaas_for_admin_utils() # get all neutron routers and interfaces ports routers = plugin.get_routers(admin_cxt, filters=filters) for router in routers: LOG.info("Updating router %s", router['id']) port_filters = { 'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF], 'device_id': [router['id']] } ports = plugin.get_ports(admin_cxt, filters=port_filters) for port in ports: # get the backend router port by the tag nsx_port_id = nsxlib.get_id_by_resource_and_tag( 'LogicalRouterDownLinkPort', 'os-neutron-rport-id', port['id']) if not nsx_port_id: LOG.warning( "Couldn't find nsx router port for interface " "%s", port['id']) continue # get the network of this port network_id = port['network_id'] # check the relay service on the az of the network az = plugin.get_network_az_by_net_id(admin_cxt, network_id) nsxlib.logical_router_port.update( nsx_port_id, relay_service_uuid=az.dhcp_relay_service) # if FWaaS is enables, also update the firewall rules try: plugin.update_router_firewall(admin_cxt, router['id']) except Exception as e: LOG.warning( "Updating router firewall was skipped because of " "an error %s", e) LOG.info("Done.")
def migrate_exclude_ports(resource, event, trigger, **kwargs): _nsx_client = v3_utils.get_nsxv3_client() nsxlib = v3_utils.get_connected_nsxlib() version = nsxlib.get_version() if not nsx_utils.is_nsx_version_2_0_0(version): LOG.info("Migration only supported from 2.0 onwards") LOG.info("Version is %s", version) return admin_cxt = neutron_context.get_admin_context() plugin = PortsPlugin() _port_client = resources.LogicalPort(_nsx_client) exclude_list = nsxlib.firewall_section.get_excludelist() for member in exclude_list['members']: if member['target_type'] == 'LogicalPort': port_id = member['target_id'] # Get port try: nsx_port = _port_client.get(port_id) except nsx_exc.ResourceNotFound: LOG.info("Port %s not found", port_id) continue # Validate its a neutron port is_neutron_port = False for tag in nsx_port['tags']: if tag['scope'] == 'os-neutron-port-id': is_neutron_port = True neutron_port_id = tag['tag'] break if not is_neutron_port: LOG.info("Port %s is not a neutron port", port_id) continue # Check if this port exists in the DB try: plugin.get_port(admin_cxt, neutron_port_id) except Exception: LOG.info("Port %s is not defined in DB", neutron_port_id) continue # Update tag for the port tags_update = [{ 'scope': security.PORT_SG_SCOPE, 'tag': nsxlib_consts.EXCLUDE_PORT }] _port_client.update(port_id, None, tags_update=tags_update) # Remove port from the exclude list nsxlib.firewall_section.remove_member_from_fw_exclude_list( port_id, nsxlib_consts.TARGET_TYPE_LOGICAL_PORT) LOG.info("Port %s successfully updated", port_id)
def nsx_update_router_lb_advertisement(resource, event, trigger, **kwargs): """The implementation of the VIP advertisement changed. This utility will update existing LB/routers """ nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(consts.FEATURE_LOAD_BALANCER): LOG.error("This utility is not available for NSX version %s", nsxlib.get_version()) return # Get the list of neutron routers used by LB lb_services = nsxlib.load_balancer.service.list()['results'] lb_routers = [] for lb_srv in lb_services: for tag in lb_srv.get('tags', []): if tag['scope'] == 'os-neutron-router-id': lb_routers.append(tag['tag']) lb_routers = set(lb_routers) LOG.info( "Going to update LB advertisement on %(num)s router(s): " "%(routers)s", { 'num': len(lb_routers), 'routers': lb_routers }) context = neutron_context.get_admin_context() with utils.NsxV3PluginWrapper() as plugin: for rtr_id in lb_routers: nsx_router_id = nsx_db.get_nsx_router_id(context.session, rtr_id) if not nsx_router_id: LOG.error("Router %s NSX Id was not found.", rtr_id) continue try: # disable the global vip advertisement flag plugin.nsxlib.logical_router.update_advertisement( nsx_router_id, advertise_lb_vip=False) # Add an advertisement rule for the external network router = plugin.get_router(context, rtr_id) lb_utils.update_router_lb_vip_advertisement( context, plugin, router, nsx_router_id) except Exception as e: LOG.error("Failed updating router %(id)s: %(e)s", { 'id': rtr_id, 'e': e }) LOG.info("Done.")
def list_orphaned_routers(resource, event, trigger, **kwargs): nsxlib = utils.get_connected_nsxlib() nsx_routers = nsxlib.logical_router.list()['results'] missing_routers = [] for nsx_router in nsx_routers: # check if it exists in the neutron DB if not neutron_client.lrouter_id_to_router_id(nsx_router['id']): # Skip non-neutron routers, by tags for tag in nsx_router.get('tags', []): if tag.get('scope') == 'os-neutron-router-id': missing_routers.append(nsx_router) break LOG.info( formatters.output_formatter(constants.ORPHANED_ROUTERS, missing_routers, ['id', 'display_name']))
def nsx_clean_orphaned_dhcp_servers(resource, event, trigger, **kwargs): """Remove logical DHCP servers without associated DHCP-enabled subnet.""" # For each orphaned DHCP server, # (1) delete the attached logical DHCP port, # (2) delete the logical DHCP server, # (3) clean corresponding neutron DB entry. nsxlib = utils.get_connected_nsxlib() nsx_version = nsxlib.get_version() if not nsx_utils.is_nsx_version_1_1_0(nsx_version): LOG.error("This utility is not available for NSX version %s", nsx_version) return dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs) if not dhcp_profile_uuid: LOG.error("dhcp_profile_uuid is not defined") return cfg.CONF.set_override('dhcp_agent_notification', False) cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3') cfg.CONF.set_override('dhcp_profile', dhcp_profile_uuid, 'nsx_v3') orphaned_servers = _get_orphaned_dhcp_servers(dhcp_profile_uuid) for server in orphaned_servers: try: response = nsxlib.logical_port.get_by_attachment( 'DHCP_SERVICE', server['id']) if response and response['result_count'] > 0: nsxlib.logical_port.delete(response['results'][0]['id']) nsxlib.dhcp_server.delete(server['id']) net_id = server.get('neutron_net_id') if net_id: # Delete neutron_net_id -> dhcp_service_id mapping from the DB. nsx_db.delete_neutron_nsx_service_binding( context.get_admin_context().session, net_id, nsx_constants.SERVICE_DHCP) LOG.info("Removed orphaned DHCP server %s", server['id']) except Exception as e: LOG.error( "Failed to clean orphaned DHCP server %(id)s. " "Exception: %(e)s", { 'id': server['id'], 'e': e })
def migrate_exclude_ports(resource, event, trigger, **kwargs): _nsx_client = v3_utils.get_nsxv3_client() nsxlib = v3_utils.get_connected_nsxlib() version = nsxlib.get_version() if not nsx_utils.is_nsx_version_2_0_0(version): LOG.info("Migration only supported from 2.0 onwards") LOG.info("Version is %s", version) return admin_cxt = neutron_context.get_admin_context() plugin = PortsPlugin() _port_client = resources.LogicalPort(_nsx_client) exclude_list = nsxlib.firewall_section.get_excludelist() for member in exclude_list['members']: if member['target_type'] == 'LogicalPort': port_id = member['target_id'] # Get port try: nsx_port = _port_client.get(port_id) except nsx_exc.ResourceNotFound: LOG.info("Port %s not found", port_id) continue # Validate its a neutron port is_neutron_port = False for tag in nsx_port.get('tags', []): if tag['scope'] == 'os-neutron-port-id': is_neutron_port = True neutron_port_id = tag['tag'] break if not is_neutron_port: LOG.info("Port %s is not a neutron port", port_id) continue # Check if this port exists in the DB try: plugin.get_port(admin_cxt, neutron_port_id) except Exception: LOG.info("Port %s is not defined in DB", neutron_port_id) continue # Update tag for the port tags_update = [{'scope': security.PORT_SG_SCOPE, 'tag': nsxlib_consts.EXCLUDE_PORT}] _port_client.update(port_id, None, tags_update=tags_update) # Remove port from the exclude list nsxlib.firewall_section.remove_member_from_fw_exclude_list( port_id, nsxlib_consts.TARGET_TYPE_LOGICAL_PORT) LOG.info("Port %s successfully updated", port_id)
def clean_orphaned_sections(resource, event, trigger, **kwargs): """Delete orphaned firewall sections from the NSX backend""" nsxlib = v3_utils.get_connected_nsxlib() orphaned_sections = plugin_utils.get_orphaned_firewall_sections( neutron_sg.context, nsxlib) for sec in orphaned_sections: try: nsxlib.firewall_section.delete(sec['id']) except Exception as e: LOG.error( "Failed to delete backend firewall section %(id)s : " "%(e)s.", { 'id': sec['id'], 'e': e }) else: LOG.info("Backend firewall section %s was deleted.", sec['id'])
def delete_backend_router(resource, event, trigger, **kwargs): nsxlib = utils.get_connected_nsxlib() errmsg = ("Need to specify nsx-id property. Add --property nsx-id=<id>") if not kwargs.get('property'): LOG.error("%s", errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) nsx_id = properties.get('nsx-id') if not nsx_id: LOG.error("%s", errmsg) return # check if the router exists try: nsxlib.logical_router.get(nsx_id, silent=True) except nsx_exc.ResourceNotFound: # prevent logger from logging this exception sys.exc_clear() LOG.warning("Backend router %s was not found.", nsx_id) return # try to delete it try: # first delete its ports ports = nsxlib.logical_router_port.get_by_router_id(nsx_id) for port in ports: nsxlib.logical_router_port.delete(port['id']) nsxlib.logical_router.delete(nsx_id) except Exception as e: LOG.error("Failed to delete backend router %(id)s : %(e)s.", { 'id': nsx_id, 'e': e }) return # Verify that the router was deleted since the backend does not always # throws errors try: nsxlib.logical_router.get(nsx_id, silent=True) except nsx_exc.ResourceNotFound: # prevent logger from logging this exception sys.exc_clear() LOG.info("Backend router %s was deleted.", nsx_id) else: LOG.error("Failed to delete backend router %s.", nsx_id)
def _update_security_group_dynamic_criteria(): nsxlib = v3_utils.get_connected_nsxlib() secgroups = neutron_sg.get_security_groups() for sg in secgroups: nsgroup_id = neutron_sg.get_nsgroup_id(sg['id']) membership_criteria = nsxlib.ns_group.get_port_tag_expression( security.PORT_SG_SCOPE, sg['id']) try: # We want to add the dynamic criteria and remove all direct members # they will be added by the manager using the new criteria. nsxlib.ns_group.update(nsgroup_id, membership_criteria=membership_criteria, members=[]) except Exception as e: LOG.warning("Failed to update membership criteria for nsgroup " "%(nsgroup_id)s, request to backend returned " "with error: %(error)s", {'nsgroup_id': nsgroup_id, 'error': str(e)})
def list_missing_ports(resource, event, trigger, **kwargs): """List neutron ports that are missing the NSX backend port And ports with wrong switch profiles or bindings """ admin_cxt = neutron_context.get_admin_context() filters = v3_utils.get_plugin_filters(admin_cxt) nsxlib = v3_utils.get_connected_nsxlib() with v3_utils.NsxV3PluginWrapper() as plugin: problems = plugin_utils.get_mismatch_logical_ports( admin_cxt, nsxlib, plugin, filters) if len(problems) > 0: title = ("Found internal ports misconfiguration on the " "NSX manager:") LOG.info(formatters.output_formatter( title, problems, ['neutron_id', 'nsx_id', 'error'])) else: LOG.info("All internal ports verified on the NSX manager")
def delete_backend_network(resource, event, trigger, **kwargs): errmsg = ("Need to specify nsx-id property. Add --property nsx-id=<id>") if not kwargs.get('property'): LOG.error("%s", errmsg) return properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) nsx_id = properties.get('nsx-id') if not nsx_id: LOG.error("%s", errmsg) return nsxlib = utils.get_connected_nsxlib() # check if the network exists try: nsxlib.logical_switch.get(nsx_id, silent=True) except nsx_exc.ResourceNotFound: # prevent logger from logging this exception sys.exc_clear() LOG.warning("Backend network %s was not found.", nsx_id) return # try to delete it try: nsxlib.logical_switch.delete(nsx_id) except Exception as e: LOG.error("Failed to delete backend network %(id)s : %(e)s.", { 'id': nsx_id, 'e': e}) return # Verify that the network was deleted since the backend does not always # through errors try: nsxlib.logical_switch.get(nsx_id, silent=True) except nsx_exc.ResourceNotFound: # prevent logger from logging this exception sys.exc_clear() LOG.info("Backend network %s was deleted.", nsx_id) else: LOG.error("Failed to delete backend network %s.", nsx_id)
def nsx_list_orphaned_dhcp_servers(resource, event, trigger, **kwargs): """List logical DHCP servers without associated DHCP-enabled subnet.""" nsxlib = utils.get_connected_nsxlib() nsx_version = nsxlib.get_version() if not nsx_utils.is_nsx_version_1_1_0(nsx_version): LOG.error("This utility is not available for NSX version %s", nsx_version) return dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs) if not dhcp_profile_uuid: LOG.error("dhcp_profile_uuid is not defined") return orphaned_servers = v3_utils.get_orphaned_dhcp_servers( context.get_admin_context(), neutron_client, nsxlib, dhcp_profile_uuid) LOG.info(formatters.output_formatter( constants.ORPHANED_DHCP_SERVERS, orphaned_servers, ['id', 'neutron_net_id', 'display_name']))
def nsx_rate_limit_update(resource, event, trigger, **kwargs): """Set the NSX rate limit The default value is 40. 0 means no limit """ nsxlib = utils.get_connected_nsxlib() if not nsxlib.feature_supported(nsx_constants.FEATURE_RATE_LIMIT): LOG.error("This utility is not available for NSX version %s", nsxlib.get_version()) return rate_limit = None if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) rate_limit = properties.get('value', None) if rate_limit is None or not rate_limit.isdigit(): usage = ("nsxadmin -r rate-limit -o nsx-update " "--property value=<new limit>") LOG.error("Missing parameters. Usage: %s", usage) return nsxlib.http_services.update_rate_limit(rate_limit) LOG.info("NSX rate limit was updated to %s", rate_limit)
def nsx_clean_orphaned_dhcp_servers(resource, event, trigger, **kwargs): """Remove logical DHCP servers without associated DHCP-enabled subnet.""" # For each orphaned DHCP server, # (1) delete the attached logical DHCP port, # (2) delete the logical DHCP server, # (3) clean corresponding neutron DB entry. nsxlib = utils.get_connected_nsxlib() nsx_version = nsxlib.get_version() if not nsx_utils.is_nsx_version_1_1_0(nsx_version): LOG.error("This utility is not available for NSX version %s", nsx_version) return dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs) if not dhcp_profile_uuid: LOG.error("dhcp_profile_uuid is not defined") return cfg.CONF.set_override('dhcp_agent_notification', False) cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3') cfg.CONF.set_override('dhcp_profile', dhcp_profile_uuid, 'nsx_v3') orphaned_servers = v3_utils.get_orphaned_dhcp_servers( context.get_admin_context(), neutron_client, nsxlib, dhcp_profile_uuid) for server in orphaned_servers: success, error = v3_utils.delete_orphaned_dhcp_server( context.get_admin_context(), nsxlib, server) if success: LOG.info("Removed orphaned DHCP server %s", server['id']) else: LOG.error("Failed to clean orphaned DHCP server %(id)s. " "Exception: %(e)s", {'id': server['id'], 'e': error})
def nsx_list_security_groups(resource, event, trigger, **kwargs): """List NSX backend security groups""" nsxlib = v3_utils.get_connected_nsxlib() nsx_secgroups = nsxlib.ns_group.list() _log_info(constants.FIREWALL_NSX_GROUPS, nsx_secgroups) return bool(nsx_secgroups)
def nsx_list_dfw_sections(resource, event, trigger, **kwargs): """List NSX backend firewall sections""" nsxlib = v3_utils.get_connected_nsxlib() fw_sections = nsxlib.firewall_section.list() _log_info(constants.FIREWALL_SECTIONS, fw_sections) return bool(fw_sections)