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 migrate_nsgroups_to_dynamic_criteria(resource, event, trigger, **kwargs): if not utils.is_nsx_version_1_1_0(nsxlib.get_version()): LOG.error( _LE("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 fix_security_groups(resource, event, trigger, **kwargs): context_ = neutron_context.get_admin_context() plugin = v3_utils.NsxV3PluginWrapper() inconsistent_secgroups = _find_missing_sections() inconsistent_secgroups.update(_find_missing_security_groups()) 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_.session, 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 utils.is_nsx_version_1_1_0(plugin._nsx_version): members = [] for port_id in neutron_db.get_ports_in_security_group(sg_id): lport_id = neutron_db.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']) # Add nsgroup to a nested group plugin.nsgroup_manager.add_nsgroup(nsgroup['id'])
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. 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: # TODO(asarfaty): should add this as api to nsxlib instead of # abusing it resource = ('?attachment_type=DHCP_SERVICE&attachment_id=%s' % server['id']) response = nsxlib.logical_port.get(resource) 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 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 = _get_orphaned_dhcp_servers(dhcp_profile_uuid) LOG.info(formatters.output_formatter(constants.ORPHANED_DHCP_SERVERS, orphaned_servers, ['id', 'neutron_net_id']))
def fix_security_groups(resource, event, trigger, **kwargs): context_ = neutron_context.get_admin_context() plugin = v3_utils.NsxV3PluginWrapper() inconsistent_secgroups = _find_missing_sections() inconsistent_secgroups.update(_find_missing_security_groups()) for sg_id, sg in inconsistent_secgroups.items(): secgroup = plugin.get_security_group(context_, sg_id) nsxlib.delete_section(sg['section-id']) nsxlib.delete_nsgroup(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_.session, 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 utils.is_nsx_version_1_1_0(plugin._nsx_version): members = [] for port_id in neutron_db.get_ports_in_security_group(sg_id): lport_id = neutron_db.get_logical_port_id(port_id) members.append(lport_id) nsxlib.add_nsgroup_members(nsgroup['id'], firewall.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 = (firewall.DROP if secgroup.get(provider_sg.PROVIDER) else firewall.ALLOW) rules = nsxlib.create_firewall_rules( context_, fw_section['id'], nsgroup['id'], secgroup.get(sg_logging.LOGGING, False), action, secgroup['security_group_rules']) nsxlib.save_sg_rule_mappings(context_.session, rules['rules']) # Add nsgroup to a nested group plugin.nsgroup_manager.add_nsgroup(nsgroup['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_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_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_update_dhcp_bindings(resource, event, trigger, **kwargs): """Resync DHCP bindings for NSXv3 CrossHairs.""" 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 = None # TODO(asarfaty) Add availability zones support here if kwargs.get('property'): properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) dhcp_profile_uuid = properties.get('dhcp_profile_uuid') 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') port_bindings = {} # lswitch_id: [(port_id, mac, ip), ...] server_bindings = {} # lswitch_id: dhcp_server_id ports = neutron_client.get_ports() for port in ports: device_owner = port['device_owner'] if (device_owner != const.DEVICE_OWNER_DHCP and not nsx_utils.is_port_dhcp_configurable(port)): continue for fixed_ip in port['fixed_ips']: if netaddr.IPNetwork(fixed_ip['ip_address']).version == 6: continue network_id = port['network_id'] subnet = neutron_client.get_subnet(fixed_ip['subnet_id']) if device_owner == const.DEVICE_OWNER_DHCP: # For each DHCP-enabled network, create a logical DHCP server # and update the attachment type to DHCP on the corresponding # logical port of the Neutron DHCP port. network = neutron_client.get_network(port['network_id']) net_tags = nsxlib.build_v3_tags_payload( network, resource_type='os-neutron-net-id', project_name='admin') # TODO(asarfaty): add default_dns_nameservers & dns_domain # from availability zone server_data = nsxlib.native_dhcp.build_server_config( network, subnet, port, net_tags) server_data['dhcp_profile_id'] = dhcp_profile_uuid dhcp_server = nsxlib.dhcp_server.create(**server_data) LOG.info("Created logical DHCP server %(server)s for " "network %(network)s", {'server': dhcp_server['id'], 'network': port['network_id']}) # Add DHCP service binding in neutron DB. neutron_client.add_dhcp_service_binding( network['id'], port['id'], dhcp_server['id']) # Update logical port for DHCP purpose. lswitch_id, lport_id = ( neutron_client.get_lswitch_and_lport_id(port['id'])) nsxlib.logical_port.update( lport_id, dhcp_server['id'], attachment_type=nsx_constants.ATTACHMENT_DHCP) server_bindings[lswitch_id] = dhcp_server['id'] LOG.info("Updated DHCP logical port %(port)s for " "network %(network)s", {'port': lport_id, 'network': port['network_id']}) elif subnet['enable_dhcp']: # Store (mac, ip) binding of each compute port in a # DHCP-enabled subnet. lswitch_id = neutron_client.net_id_to_lswitch_id(network_id) bindings = port_bindings.get(lswitch_id, []) bindings.append((port['id'], port['mac_address'], fixed_ip['ip_address'], fixed_ip['subnet_id'])) port_bindings[lswitch_id] = bindings break # process only the first IPv4 address # Populate mac/IP bindings in each logical DHCP server. for lswitch_id, bindings in port_bindings.items(): dhcp_server_id = server_bindings.get(lswitch_id) if not dhcp_server_id: continue for (port_id, mac, ip, subnet_id) in bindings: hostname = 'host-%s' % ip.replace('.', '-') options = {'option121': {'static_routes': [ {'network': '%s' % cfg.CONF.nsx_v3.native_metadata_route, 'next_hop': ip}]}} subnet = neutron_client.get_subnet(subnet_id) binding = nsxlib.dhcp_server.create_binding( dhcp_server_id, mac, ip, hostname, cfg.CONF.nsx_v3.dhcp_lease_time, options, subnet.get('gateway_ip')) # Add DHCP static binding in neutron DB. neutron_client.add_dhcp_static_binding( port_id, subnet_id, ip, dhcp_server_id, binding['id']) LOG.info("Added DHCP binding (mac: %(mac)s, ip: %(ip)s) " "for neutron port %(port)s", {'mac': mac, 'ip': ip, 'port': port_id})