def get_common_server(self): data = { 'public_address': None, 'private_address': None, 'service_net_name_or_ip': self.get_config_option('service_net_name_or_ip'), 'tenant_net_name_or_ip': self.get_config_option('tenant_net_name_or_ip'), } data['instance'] = self.compute_api.server_get_by_name_or_id( self.admin_context, self.get_config_option('service_instance_name_or_id')) if netutils.is_valid_ipv4(data['service_net_name_or_ip']): data['private_address'] = [data['service_net_name_or_ip']] else: data['private_address'] = self._get_addresses_by_network_name( data['service_net_name_or_ip'], data['instance']) if netutils.is_valid_ipv4(data['tenant_net_name_or_ip']): data['public_address'] = [data['tenant_net_name_or_ip']] else: data['public_address'] = self._get_addresses_by_network_name( data['tenant_net_name_or_ip'], data['instance']) if not (data['public_address'] and data['private_address']): raise exception.ManilaException( "Can not find one of net addresses for service instance. " "Instance: %(instance)s, " "private_address: %(private_address)s, " "public_address: %(public_address)s." % data) share_server = { 'username': self.get_config_option('service_instance_user'), 'password': self.get_config_option('service_instance_password'), 'pk_path': self.path_to_private_key, 'instance_id': data['instance']['id'], } for key in ('private_address', 'public_address'): data[key + '_v4'] = None for address in data[key]: if netutils.is_valid_ipv4(address): data[key + '_v4'] = address break share_server['ip'] = data['private_address_v4'] share_server['public_address'] = data['public_address_v4'] return {'backend_details': share_server}
def get_common_server(self): data = { 'public_address': None, 'private_address': None, 'service_net_name_or_ip': self.get_config_option( 'service_net_name_or_ip'), 'tenant_net_name_or_ip': self.get_config_option( 'tenant_net_name_or_ip'), } data['instance'] = self.compute_api.server_get_by_name_or_id( self.admin_context, self.get_config_option('service_instance_name_or_id')) if netutils.is_valid_ipv4(data['service_net_name_or_ip']): data['private_address'] = [data['service_net_name_or_ip']] else: data['private_address'] = self._get_addresses_by_network_name( data['service_net_name_or_ip'], data['instance']) if netutils.is_valid_ipv4(data['tenant_net_name_or_ip']): data['public_address'] = [data['tenant_net_name_or_ip']] else: data['public_address'] = self._get_addresses_by_network_name( data['tenant_net_name_or_ip'], data['instance']) if not (data['public_address'] and data['private_address']): raise exception.ManilaException( "Can not find one of net addresses for service instance. " "Instance: %(instance)s, " "private_address: %(private_address)s, " "public_address: %(public_address)s." % data) share_server = { 'username': self.get_config_option('service_instance_user'), 'password': self.get_config_option('service_instance_password'), 'pk_path': self.path_to_private_key, 'instance_id': data['instance']['id'], } for key in ('private_address', 'public_address'): data[key + '_v4'] = None for address in data[key]: if netutils.is_valid_ipv4(address): data[key + '_v4'] = address break share_server['ip'] = data['private_address_v4'] share_server['public_address'] = data['public_address_v4'] return {'backend_details': share_server}
def get_ipv6_addr_by_EUI64(cidr, mac): """Generate a IPv6 addr by EUI-64 with CIDR and MAC :param str cidr: a IPv6 CIDR :param str mac: a MAC address :return: an IPv6 Address :rtype: netaddr.IPAddress """ # Check if the prefix is IPv4 address is_ipv4 = netutils.is_valid_ipv4(cidr) if is_ipv4: msg = "Unable to generate IP address by EUI64 for IPv4 prefix" raise TypeError(msg) try: eui64 = int(netaddr.EUI(mac).eui64()) prefix = netaddr.IPNetwork(cidr) return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57)) except (ValueError, netaddr.AddrFormatError): raise TypeError('Bad prefix or mac format for generating IPv6 ' 'address by EUI-64: %(prefix)s, %(mac)s:' % { 'prefix': cidr, 'mac': mac }) except TypeError: raise TypeError('Bad prefix type for generate IPv6 address by ' 'EUI-64: %s' % cidr)
def _get_fixed_ip_address(self, port_uuid, client): """Get a Neutron port's fixed ip address. :param port_uuid: Neutron port id. :param client: Neutron client instance. :returns: Neutron port ip address. :raises: FailedToGetIPAddressOnPort :raises: InvalidIPv4Address """ ip_address = None try: neutron_port = client.show_port(port_uuid).get('port') except neutron_client_exc.NeutronClientException: LOG.exception("Failed to Get IP address on Neutron port %s.", port_uuid) raise exception.FailedToGetIPAddressOnPort(port_id=port_uuid) fixed_ips = neutron_port.get('fixed_ips') # NOTE(faizan) At present only the first fixed_ip assigned to this # neutron port will be used, since nova allocates only one fixed_ip # for the instance. if fixed_ips: ip_address = fixed_ips[0].get('ip_address', None) if ip_address: if netutils.is_valid_ipv4(ip_address): return ip_address else: LOG.error("Neutron returned invalid IPv4 address %s.", ip_address) raise exception.InvalidIPv4Address(ip_address=ip_address) else: LOG.error("No IP address assigned to Neutron port %s.", port_uuid) raise exception.FailedToGetIPAddressOnPort(port_id=port_uuid)
def _get_server_port_id_and_ip4(self, server, ip_addr=None): if ip_addr: ports = self.os_admin.ports_client.list_ports( device_id=server['id'], fixed_ips='ip_address=%s' % ip_addr)['ports'] else: ports = self.os_admin.ports_client.list_ports( device_id=server['id'])['ports'] # A port can have more than one IP address in some cases. # If the network is dual-stack (IPv4 + IPv6), this port is associated # with 2 subnets def _is_active(port): # NOTE(vsaienko) With Ironic, instances live on separate hardware # servers. Neutron does not bind ports for Ironic instances, as a # result the port remains in the DOWN state. This has been fixed # with the introduction of the networking-baremetal plugin but # it's not mandatory (and is not used on all stable branches). return (port['status'] == 'ACTIVE' or port.get('binding:vnic_type') == 'baremetal') port_map = [ (p["id"], fxip["ip_address"]) for p in ports for fxip in p["fixed_ips"] if (netutils.is_valid_ipv4(fxip["ip_address"]) and _is_active(p)) ] inactive = [p for p in ports if p['status'] != 'ACTIVE'] if inactive: LOG.warning("Instance has ports that are not ACTIVE: %s", inactive) self.assertNotEmpty(port_map, "No IPv4 addresses found in: %s" % ports) self.assertEqual( len(port_map), 1, "Found multiple IPv4 addresses: %s. " "Unable to determine which port to target." % port_map) return port_map[0]
def _get_fixed_ip_address(self, port_uuid, client): """Get a port's fixed ip address. :param port_uuid: Neutron port id. :param client: Neutron client instance. :returns: Neutron port ip address. :raises: FailedToGetIPAddressOnPort :raises: InvalidIPv4Address """ ip_address = None try: neutron_port = client.show_port(port_uuid).get("port") except neutron_client_exc.NeutronClientException: LOG.exception(_LE("Failed to Get IP address on Neutron port %s."), port_uuid) raise exception.FailedToGetIPAddressOnPort(port_id=port_uuid) fixed_ips = neutron_port.get("fixed_ips") # NOTE(faizan) At present only the first fixed_ip assigned to this # neutron port will be used, since nova allocates only one fixed_ip # for the instance. if fixed_ips: ip_address = fixed_ips[0].get("ip_address", None) if ip_address: if netutils.is_valid_ipv4(ip_address): return ip_address else: LOG.error(_LE("Neutron returned invalid IPv4 address %s."), ip_address) raise exception.InvalidIPv4Address(ip_address=ip_address) else: LOG.error(_LE("No IP address assigned to Neutron port %s."), port_uuid) raise exception.FailedToGetIPAddressOnPort(port_id=port_uuid)
def _get_server_port_id_and_ip4(self, server, ip_addr=None): ports = self.os_admin.ports_client.list_ports( device_id=server['id'], fixed_ip=ip_addr)['ports'] # A port can have more than one IP address in some cases. # If the network is dual-stack (IPv4 + IPv6), this port is associated # with 2 subnets p_status = ['ACTIVE'] # NOTE(vsaienko) With Ironic, instances live on separate hardware # servers. Neutron does not bind ports for Ironic instances, as a # result the port remains in the DOWN state. # TODO(vsaienko) remove once bug: #1599836 is resolved. if getattr(CONF.service_available, 'ironic', False): p_status.append('DOWN') port_map = [(p["id"], fxip["ip_address"]) for p in ports for fxip in p["fixed_ips"] if (netutils.is_valid_ipv4(fxip["ip_address"]) and p['status'] in p_status)] inactive = [p for p in ports if p['status'] != 'ACTIVE'] if inactive: LOG.warning("Instance has ports that are not ACTIVE: %s", inactive) self.assertNotEqual(0, len(port_map), "No IPv4 addresses found in: %s" % ports) self.assertEqual(len(port_map), 1, "Found multiple IPv4 addresses: %s. " "Unable to determine which port to target." % port_map) return port_map[0]
def get_instance_ip(cls, instance=None): if not instance: instance = cls.client.get_resource( "instances", cls.instance_id)['instance'] # TODO(lxkong): IPv6 needs to be tested. v4_ip = None if 'addresses' in instance: for addr_info in instance['addresses']: if addr_info['type'] == 'private': v4_ip = addr_info['address'] if addr_info['type'] == 'public': v4_ip = addr_info['address'] break else: ips = instance.get('ip', []) for ip in ips: if netutils.is_valid_ipv4(ip): v4_ip = ip if not v4_ip: message = ('Failed to get instance IP address.') raise exceptions.TempestException(message) return v4_ip
def _get_server_port_id_and_ip4(self, server, ip_addr=None): ports = self.os_admin.ports_client.list_ports( device_id=server['id'], fixed_ip=ip_addr)['ports'] # A port can have more than one IP address in some cases. # If the network is dual-stack (IPv4 + IPv6), this port is associated # with 2 subnets p_status = ['ACTIVE'] # NOTE(vsaienko) With Ironic, instances live on separate hardware # servers. Neutron does not bind ports for Ironic instances, as a # result the port remains in the DOWN state. # TODO(vsaienko) remove once bug: #1599836 is resolved. if getattr(CONF.service_available, 'ironic', False): p_status.append('DOWN') port_map = [(p["id"], fxip["ip_address"]) for p in ports for fxip in p["fixed_ips"] if (netutils.is_valid_ipv4(fxip["ip_address"]) and p['status'] in p_status)] inactive = [p for p in ports if p['status'] != 'ACTIVE'] if inactive: LOG.warning("Instance has ports that are not ACTIVE: %s", inactive) self.assertNotEqual(0, len(port_map), "No IPv4 addresses found in: %s" % ports) self.assertEqual( len(port_map), 1, "Found multiple IPv4 addresses: %s. " "Unable to determine which port to target." % port_map) return port_map[0]
def is_valid_ip_address(ip_address, ip_version): if int(ip_version) == 4: return netutils.is_valid_ipv4(ip_address) elif int(ip_version) == 6: return netutils.is_valid_ipv6(ip_address) else: raise exception.ManilaException( _("Provided improper IP version '%s'.") % ip_version)
def _get_portal(ip, port=None): # ipv6 addresses use [ip]:port format, ipv4 use ip:port portal_port = ':%d' % port if port else '' if netutils.is_valid_ipv4(ip): portal_ip = ip else: portal_ip = '[' + ip + ']' return portal_ip + portal_port
def get_default_dns(self, ip_version=4): dns_list = self._settings.default_dns valid_dns = [] for ip in dns_list: if ip_version == 6 and netutils.is_valid_ipv6(ip): valid_dns.append(ip) elif ip_version == 4 and netutils.is_valid_ipv4(ip): valid_dns.append(ip) else: LOG.warning('{0} is not a vaild IPV{1} address, ' 'ingore...'.format(ip, ip_version)) return valid_dns
def remove_macs_from_lsp_addresses(addresses): """Remove the mac addreses from the Logical_Switch_Port addresses column. :param addresses: The list of addresses from the Logical_Switch_Port. Example: ["80:fa:5b:06:72:b7 158.36.44.22", "ff:ff:ff:ff:ff:ff 10.0.0.2"] :returns: A list of IP addesses (v4 and v6) """ ip_list = [] for addr in addresses: ip_list.extend([x for x in addr.split() if (netutils.is_valid_ipv4(x) or netutils.is_valid_ipv6(x))]) return ip_list
def server_to_ipaddress(self, server): ''' Return the server's IP address, fetching it from Nova. ''' try: server = self.client().servers.get(server) except exceptions.NotFound as ex: LOG.warn(_LW('Instance (%(server)s) not found: %(ex)s'), {'server': server, 'ex': ex}) else: for n in server.networks: if len(server.networks[n]) > 0: for addr in server.networks[n]: if netutils.is_valid_ipv4(addr): return addr
def is_valid_ip_address(ip_address, ip_version): ip_version = ([int(ip_version)] if not isinstance(ip_version, list) else ip_version) if not set(ip_version).issubset(set([4, 6])): raise exception.ImproperIPVersion(ip_version) if 4 in ip_version: if netutils.is_valid_ipv4(ip_address): return True if 6 in ip_version: if netutils.is_valid_ipv6(ip_address): return True return False
def is_valid_ip_address(ip_address, ip_version): ip_version = ([int(ip_version)] if not isinstance(ip_version, list) else ip_version) if not set(ip_version).issubset(set([4, 6])): raise exception.ManilaException( _("Provided improper IP version '%s'.") % ip_version) if 4 in ip_version: if netutils.is_valid_ipv4(ip_address): return True if 6 in ip_version: if netutils.is_valid_ipv6(ip_address): return True return False
def server_to_ipaddress(self, server): ''' Return the server's IP address, fetching it from Nova. ''' try: server = self.client().servers.get(server) except exceptions.NotFound as ex: LOG.warn(_LW('Instance (%(server)s) not found: %(ex)s'), { 'server': server, 'ex': ex }) else: for n in server.networks: if len(server.networks[n]) > 0: for addr in server.networks[n]: if netutils.is_valid_ipv4(addr): return addr
def get_system_dns_resolvers(resolver_file=DNS_RESOLVER_FILE): resolvers = [] if not os.path.exists(resolver_file): return resolvers with open(resolver_file, 'r') as rconf: for line in rconf.readlines(): if not line.startswith('nameserver'): continue line = line.split('nameserver')[1].strip() valid_ip = (netutils.is_valid_ipv4(line, strict=True) or netutils.is_valid_ipv6(line)) if valid_ip: resolvers.append(line) return resolvers
def parse_valid_host_port(host_port): """ Given a "host:port" string, attempts to parse it as intelligently as possible to determine if it is valid. This includes IPv6 [host]:port form, IPv4 ip:port form, and hostname:port or fqdn:port form. Invalid inputs will raise a ValueError, while valid inputs will return a (host, port) tuple where the port will always be of type int. """ try: try: host, port = netutils.parse_host_port(host_port) except Exception: raise ValueError(_('Host and port "%s" is not valid.') % host_port) if not netutils.is_valid_port(port): raise ValueError(_('Port "%s" is not valid.') % port) # First check for valid IPv6 and IPv4 addresses, then a generic # hostname. Failing those, if the host includes a period, then this # should pass a very generic FQDN check. The FQDN check for letters at # the tail end will weed out any hilariously absurd IPv4 addresses. if not ( netutils.is_valid_ipv6(host) or netutils.is_valid_ipv4(host) or is_valid_hostname(host) or is_valid_fqdn(host) ): raise ValueError(_('Host "%s" is not valid.') % host) except Exception as ex: raise ValueError( _( "%s " "Please specify a host:port pair, where host is an " "IPv4 address, IPv6 address, hostname, or FQDN. If " "using an IPv6 address, enclose it in brackets " "separately from the port (i.e., " '"[fe80::a:b:c]:9876").' ) % ex ) return (host, int(port))
def _get_server_portid_and_ip4(self, server, ip_addr=None): ports = self.os_admin.ports_client.list_ports( device_id=server['id'], fixed_ip=ip_addr)['ports'] p_status = ['ACTIVE'] if getattr(CONF.service_available, 'ironic', False): p_status.append('DOWN') port_map = [(p["id"], fxip["ip_address"]) for p in ports for fxip in p["fixed_ips"] if netutils.is_valid_ipv4(fxip["ip_address"]) and p['status'] in p_status] inactive = [p for p in ports if p['status'] != 'ACTIVE'] if inactive: LOG.warning("Instance has ports that are not ACTIVE: %s", inactive) self.assertNotEqual(0, len(port_map), "No IPv4 addresses found in: %s" % ports) return port_map
def check_params(self, values): if 'network_id' not in values: raise manager_ex.MissingParameter(param='network_id') if 'amount' not in values: raise manager_ex.MissingParameter(param='amount') if not strutils.is_int_like(values['amount']): raise manager_ex.MalformedParameter(param='amount') # required_floatingips param is an optional parameter fips = values.get('required_floatingips', []) if not isinstance(fips, list): manager_ex.MalformedParameter(param='required_floatingips') for ip in fips: if not (netutils.is_valid_ipv4(ip) or netutils.is_valid_ipv6(ip)): raise manager_ex.InvalidIPFormat(ip=ip)
def associate_floatingip(self, server_id, floatingip_id): iface_list = self.fetch_server(server_id).interface_list() if len(iface_list) == 0: raise client_exception.InterfaceNotFound(id=server_id) if len(iface_list) > 1: LOG.warning("Multiple interfaces found for server %s, " "using the first one.", server_id) port_id = iface_list[0].port_id fixed_ips = iface_list[0].fixed_ips fixed_address = next(ip['ip_address'] for ip in fixed_ips if netutils.is_valid_ipv4(ip['ip_address'])) request_body = { 'floatingip': { 'port_id': port_id, 'fixed_ip_address': fixed_address}} self.clients.client('neutron').update_floatingip(floatingip_id, request_body)
def delete(self, server_uuid, address): """Dissociate floating_ip from a server. :param server_uuid: UUID of a server. :param floatingip: The floating IP within the request body. """ if not netutils.is_valid_ipv4(address): msg = "Invalid IP address %s" % address raise wsme.exc.ClientSideError(msg, status_code=http_client.BAD_REQUEST) # get the floating ip object floating_ip = self.network_api.get_floating_ip_by_address( pecan.request.context, address) # get the associated server object (if any) try: server_id =\ self.network_api.get_server_id_by_floating_address( pecan.request.context, address) except (exception.FloatingIpNotFoundForAddress, exception.FloatingIpMultipleFoundForAddress) as e: six.reraise(type(e), e) # disassociate if associated if (floating_ip.get('port_id') and server_id == server_uuid): self.network_api.disassociate_floating_ip(pecan.request.context, address) server = self._resource or self._get_resource(server_uuid) for nic in server.nics: if nic.floating_ip == address: nic.floating_ip = None nic.save(pecan.request.context) else: msg = _("Floating IP %(address)s is not associated with server " "%(id)s.") % { 'address': address, 'id': server_uuid } raise wsme.exc.ClientSideError(msg, status_code=http_client.BAD_REQUEST)
def parse_nets(ns): err_msg = ("Invalid nets argument '%s'. nets arguments must be of " "the form --nets <network=network, v4-fixed-ip=ip-addr," "v6-fixed-ip=ip-addr, port=port-uuid>, " "with only one of network, or port specified.") nets = [] for net_str in ns: net_info = { "network": "", "v4-fixed-ip": "", "v6-fixed-ip": "", "port": "" } for kv_str in net_str.split(","): try: k, v = kv_str.split("=", 1) k = k.strip() v = v.strip() except ValueError: raise apiexec.CommandError(err_msg % net_str) if k in net_info: if net_info[k]: raise apiexec.CommandError(err_msg % net_str) net_info[k] = v else: raise apiexec.CommandError(err_msg % net_str) if net_info['v4-fixed-ip'] and not netutils.is_valid_ipv4( net_info['v4-fixed-ip']): raise apiexec.CommandError("Invalid ipv4 address.") if net_info['v6-fixed-ip'] and not netutils.is_valid_ipv6( net_info['v6-fixed-ip']): raise apiexec.CommandError("Invalid ipv6 address.") if bool(net_info['network']) == bool(net_info['port']): raise apiexec.CommandError(err_msg % net_str) nets.append(net_info) return nets
def parse_valid_host_port(host_port): """ Given a "host:port" string, attempts to parse it as intelligently as possible to determine if it is valid. This includes IPv6 [host]:port form, IPv4 ip:port form, and hostname:port or fqdn:port form. Invalid inputs will raise a ValueError, while valid inputs will return a (host, port) tuple where the port will always be of type int. """ try: try: host, port = netutils.parse_host_port(host_port) except Exception: raise ValueError(_('Host and port "%s" is not valid.') % host_port) if not netutils.is_valid_port(port): raise ValueError(_('Port "%s" is not valid.') % port) # First check for valid IPv6 and IPv4 addresses, then a generic # hostname. Failing those, if the host includes a period, then this # should pass a very generic FQDN check. The FQDN check for letters at # the tail end will weed out any hilariously absurd IPv4 addresses. if not (netutils.is_valid_ipv6(host) or netutils.is_valid_ipv4(host) or is_valid_hostname(host) or is_valid_fqdn(host)): raise ValueError(_('Host "%s" is not valid.') % host) except Exception as ex: raise ValueError( _('%s ' 'Please specify a host:port pair, where host is an ' 'IPv4 address, IPv6 address, hostname, or FQDN. If ' 'using an IPv6 address, enclose it in brackets ' 'separately from the port (i.e., ' '"[fe80::a:b:c]:9876").') % ex) return (host, int(port))
def _get_fixed_ip_address(self, port_uuid, client): """Get a Neutron port's fixed ip address. :param port_uuid: Neutron port id. :param client: Neutron client instance. :returns: Neutron port ip address. :raises: NetworkError :raises: InvalidIPv4Address :raises: FailedToGetIPAddressOnPort """ ip_address = None try: neutron_port = client.show_port(port_uuid).get('port') except neutron_client_exc.NeutronClientException: raise exception.NetworkError( _('Could not retrieve neutron port: %s') % port_uuid) fixed_ips = neutron_port.get('fixed_ips') # NOTE(faizan) At present only the first fixed_ip assigned to this # neutron port will be used, since nova allocates only one fixed_ip # for the instance. if fixed_ips: ip_address = fixed_ips[0].get('ip_address', None) if ip_address: if netutils.is_valid_ipv4(ip_address): return ip_address else: LOG.error("Neutron returned invalid IPv4 " "address %(ip_address)s on port %(port_uuid)s.", {'ip_address': ip_address, 'port_uuid': port_uuid}) raise exception.InvalidIPv4Address(ip_address=ip_address) else: LOG.error("No IP address assigned to Neutron port %s.", port_uuid) raise exception.FailedToGetIPAddressOnPort(port_id=port_uuid)
def parse_nets(ns): err_msg = ("Invalid nets argument '%s'. nets arguments must be of " "the form --nets <network=network, v4-fixed-ip=ip-addr," "v6-fixed-ip=ip-addr, port=port-uuid>, " "with only one of network, or port specified.") nets = [] for net_str in ns: keys = ["network", "port", "v4-fixed-ip", "v6-fixed-ip"] net_info = {} for kv_str in net_str.split(","): try: k, v = kv_str.split("=", 1) k = k.strip() v = v.strip() except ValueError: raise apiexec.CommandError(err_msg % net_str) if k in keys: if net_info.get(k): raise apiexec.CommandError(err_msg % net_str) net_info[k] = v else: raise apiexec.CommandError(err_msg % net_str) if net_info.get('v4-fixed-ip') and not netutils.is_valid_ipv4( net_info['v4-fixed-ip']): raise apiexec.CommandError("Invalid ipv4 address.") if net_info.get('v6-fixed-ip') and not netutils.is_valid_ipv6( net_info['v6-fixed-ip']): raise apiexec.CommandError("Invalid ipv6 address.") if bool(net_info.get('network')) == bool(net_info.get('port')): raise apiexec.CommandError(err_msg % net_str) nets.append(net_info) return nets
def __init__(self, **kwargs): """Initialize a new client for the plugin.""" self.format = 'json' # Extract configuration parameters from the configuration file. self.username = cfg.CONF.ml2_cisco_n1kv.username self.password = cfg.CONF.ml2_cisco_n1kv.password self.vsm_ips = config.get_vsm_hosts() self.action_prefix = 'http://%s/api/n1k' self.timeout = cfg.CONF.ml2_cisco_n1kv.http_timeout self.max_vsm_retries = cfg.CONF.ml2_cisco_n1kv.max_vsm_retries required_opts = ('vsm_ips', 'username', 'password') # Validate whether required options are configured for opt in required_opts: if not getattr(self, opt): raise cfg.RequiredOptError(opt, 'ml2_cisco_n1kv') # Validate the configured VSM IP addresses # Note: Currently only support IPv4 for vsm_ip in self.vsm_ips: if not (netutils.is_valid_ipv4(vsm_ip) or netutils.is_valid_ipv6(vsm_ip)): raise cfg.Error( _("Cisco Nexus1000V ML2 driver config: " "Invalid format for VSM IP address: %s") % vsm_ip)
def get_nuage_floating_ip(nuageclient, nuage_floating_ip_parsed_arg): """Convert to Nuage floating ip id""" nuage_fip = nuage_floating_ip_parsed_arg if netutils.is_valid_ipv4(nuage_floating_ip_parsed_arg): floatingips = nuageclient.list_nuage_floatingips( floating_ip_address=nuage_floating_ip_parsed_arg )['nuage_floatingips'] if len(floatingips) == 1: nuage_fip = floatingips[0]['id'] elif len(floatingips) > 1: msg = _("Multiple Nuage Floating IP exist with IP {}").format( nuage_floating_ip_parsed_arg) raise exceptions.CommandError(msg) else: msg = _("No Nuage Floating IP available with IP {}").format( nuage_floating_ip_parsed_arg) raise exceptions.CommandError(msg) else: if not re.match(UUID_PATTERN, nuage_floating_ip_parsed_arg): raise exceptions.CommandError( _('"--nuage-floatingip" should be UUID ' 'or valid IP, but is "{}".').format( nuage_floating_ip_parsed_arg)) return nuage_fip
def __init__(self, **kwargs): """Initialize a new client for the plugin.""" self.format = 'json' # Extract configuration parameters from the configuration file. self.username = cfg.CONF.ml2_cisco_n1kv.username self.password = cfg.CONF.ml2_cisco_n1kv.password self.vsm_ips = config.get_vsm_hosts() self.action_prefix = 'http://%s/api/n1k' self.timeout = cfg.CONF.ml2_cisco_n1kv.http_timeout self.max_vsm_retries = cfg.CONF.ml2_cisco_n1kv.max_vsm_retries required_opts = ('vsm_ips', 'username', 'password') # Validate whether required options are configured for opt in required_opts: if not getattr(self, opt): raise cfg.RequiredOptError(opt, 'ml2_cisco_n1kv') # Validate the configured VSM IP addresses # Note: Currently only support IPv4 for vsm_ip in self.vsm_ips: if not (netutils.is_valid_ipv4(vsm_ip) or netutils.is_valid_ipv6(vsm_ip)): raise cfg.Error(_("Cisco Nexus1000V ML2 driver config: " "Invalid format for VSM IP address: %s") % vsm_ip)
def get_ipv6_addr_by_EUI64(cidr, mac): """Generate a IPv6 addr by EUI-64 with CIDR and MAC :param str cidr: a IPv6 CIDR :param str mac: a MAC address :return: an IPv6 Address :rtype: netaddr.IPAddress """ # Check if the prefix is IPv4 address is_ipv4 = netutils.is_valid_ipv4(cidr) if is_ipv4: msg = "Unable to generate IP address by EUI64 for IPv4 prefix" raise TypeError(msg) try: eui64 = int(netaddr.EUI(mac).eui64()) prefix = netaddr.IPNetwork(cidr) return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57)) except (ValueError, netaddr.AddrFormatError): raise TypeError('Bad prefix or mac format for generating IPv6 ' 'address by EUI-64: %(prefix)s, %(mac)s:' % {'prefix': cidr, 'mac': mac}) except TypeError: raise TypeError('Bad prefix type for generate IPv6 address by ' 'EUI-64: %s' % cidr)
def _validate_access_ipv4(self, address): if not netutils.is_valid_ipv4(address): expl = _('accessIPv4 is not proper IPv4 format') raise exc.HTTPBadRequest(explanation=expl)
def validate_ip_address(ip_address=""): if not netutils.is_valid_ipv4(ip_address): raise ValidationError(_("Invalid IP Address Format."))
def is_valid_ipv4(self, address): if isinstance(address, six.string_types): if address.count('.') != 3: return False return netutils.is_valid_ipv4(address)
def create_iscsi_target(self, name, tid, lun, path, chap_auth=None, **kwargs): (out, err) = utils.execute('iscsictl', '-c', 'target=ALL', run_as_root=True) LOG.debug("Targets prior to update: %s", out) volumes_dir = self._get_volumes_dir() fileutils.ensure_tree(volumes_dir) vol_id = name.split(':')[1] if netutils.is_valid_ipv4(self.configuration.iscsi_ip_address): portal = "%s:%s" % (self.configuration.iscsi_ip_address, self.configuration.iscsi_port) else: # ipv6 addresses use [ip]:port format, ipv4 use ip:port portal = "[%s]:%s" % (self.configuration.iscsi_ip_address, self.configuration.iscsi_port) if chap_auth is None: volume_conf = self.TARGET_FMT % (name, path, portal) else: volume_conf = self.TARGET_FMT_WITH_CHAP % (name, path, portal, '"%s":"%s"' % chap_auth) LOG.debug('Creating iscsi_target for: %s', vol_id) volume_path = os.path.join(volumes_dir, vol_id) if os.path.exists(volume_path): LOG.warning(_LW('Persistence file already exists for volume, ' 'found file at: %s'), volume_path) f = open(volume_path, 'w+') f.write(volume_conf) f.close() LOG.debug('Created volume path %(vp)s,\n' 'content: %(vc)s', {'vp': volume_path, 'vc': volume_conf}) old_persist_file = None old_name = kwargs.get('old_name', None) if old_name: LOG.debug('Detected old persistence file for volume ' '%{vol}s at %{old_name}s', {'vol': vol_id, 'old_name': old_name}) old_persist_file = os.path.join(volumes_dir, old_name) try: # With the persistent tgts we create them # by creating the entry in the persist file # and then doing an update to get the target # created. (out, err) = utils.execute('iscsictl', '-S', 'target=%s' % name, '-f', volume_path, '-x', self.config, run_as_root=True) except putils.ProcessExecutionError as e: LOG.error(_LE("Failed to create iscsi target for volume " "id:%(vol_id)s: %(e)s"), {'vol_id': vol_id, 'e': e}) # Don't forget to remove the persistent file we created os.unlink(volume_path) raise exception.ISCSITargetCreateFailed(volume_id=vol_id) finally: LOG.debug("StdOut from iscsictl -S: %s", out) LOG.debug("StdErr from iscsictl -S: %s", err) # Grab targets list for debug (out, err) = utils.execute('iscsictl', '-c', 'target=ALL', run_as_root=True) LOG.debug("Targets after update: %s", out) iqn = '%s%s' % (self.iscsi_target_prefix, vol_id) tid = self._get_target(iqn) if tid is None: LOG.error(_LE("Failed to create iscsi target for volume " "id:%(vol_id)s. Please verify your configuration " "in %(volumes_dir)'"), { 'vol_id': vol_id, 'volumes_dir': volumes_dir, }) raise exception.NotFound() if old_persist_file is not None and os.path.exists(old_persist_file): os.unlink(old_persist_file) return tid
def test_is_valid_ipv4(self, mock_log): expected_log = 'Converting in non strict mode is deprecated. ' \ 'You should pass strict=False if you want to preserve ' \ 'legacy behavior' self.assertTrue(netutils.is_valid_ipv4('42.42.42.42')) self.assertFalse(netutils.is_valid_ipv4('-1.11.11.11')) self.assertFalse(netutils.is_valid_ipv4('')) self.assertTrue(netutils.is_valid_ipv4('10')) mock_log.warn.assert_called_with(expected_log) mock_log.reset_mock() self.assertTrue(netutils.is_valid_ipv4('10.10')) mock_log.warn.assert_called_with(expected_log) mock_log.reset_mock() self.assertTrue(netutils.is_valid_ipv4('10.10.10')) mock_log.warn.assert_called_with(expected_log) mock_log.reset_mock() self.assertTrue(netutils.is_valid_ipv4('10.10.10.10')) mock_log.warn.assert_not_called() mock_log.reset_mock() self.assertFalse(netutils.is_valid_ipv4('10', strict=True)) self.assertFalse(netutils.is_valid_ipv4('10.10', strict=True)) self.assertFalse(netutils.is_valid_ipv4('10.10.10', strict=True)) mock_log.warn.assert_not_called() mock_log.reset_mock() self.assertTrue(netutils.is_valid_ipv4('10', strict=False)) self.assertTrue(netutils.is_valid_ipv4('10.10', strict=False)) self.assertTrue(netutils.is_valid_ipv4('10.10.10', strict=False)) mock_log.warn.assert_not_called() mock_log.reset_mock()
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] context.can(fi_policies.BASE_POLICY_NAME) address = body['addFloatingIp']['address'] instance = common.get_instance(self.compute_api, context, id, expected_attrs=['flavor']) cached_nwinfo = instance.get_network_info() if not cached_nwinfo: LOG.warning( 'Info cache is %r during associate with no nw_info cache', instance.info_cache, instance=instance) msg = _('Instance network is not ready yet') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _('No fixed IPs associated to instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if 'fixed_address' in body['addFloatingIp']: fixed_address = body['addFloatingIp']['fixed_address'] for fixed in fixed_ips: if fixed['address'] == fixed_address: break else: msg = _('Specified fixed address not assigned to instance') raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: try: fixed_address = next(ip['address'] for ip in fixed_ips if netutils.is_valid_ipv4(ip['address'])) except StopIteration: msg = _('Unable to associate floating IP %(address)s ' 'to any fixed IPs for instance %(id)s. ' 'Instance has no fixed IPv4 addresses to ' 'associate.') % ({ 'address': address, 'id': id }) raise webob.exc.HTTPBadRequest(explanation=msg) if len(fixed_ips) > 1: LOG.warning( 'multiple fixed_ips exist, using the first ' 'IPv4 fixed_ip: %s', fixed_address) try: self.network_api.associate_floating_ip(context, instance, floating_address=address, fixed_address=fixed_address) except exception.FloatingIpAssociated: msg = _('floating IP is already associated') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.FloatingIpAssociateFailed as e: raise webob.exc.HTTPBadRequest(explanation=e.format_message()) except exception.NoFloatingIpInterface: msg = _('l3driver call to add floating IP failed') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.FloatingIpNotFoundForAddress: msg = _('floating IP not found') raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _('Unable to associate floating IP %(address)s to ' 'fixed IP %(fixed_address)s for instance %(id)s. ' 'Error: %(error)s') % ({ 'address': address, 'fixed_address': fixed_address, 'id': id, 'error': e }) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def post(self, server_uuid, floatingip): """Add(Associate) Floating Ip. :param server_uuid: UUID of a server. :param floatingip: The floating IP within the request body. """ validation.check_schema(floatingip, fip_schemas.add_floating_ip) server = self._resource or self._get_resource(server_uuid) address = floatingip['address'] server_nics = server.nics if not server_nics: msg = _('No ports associated to server') raise wsme.exc.ClientSideError(msg, status_code=http_client.BAD_REQUEST) fixed_address = None nic_to_associate = None if 'fixed_address' in floatingip: fixed_address = floatingip['fixed_address'] for nic in server_nics: for port_address in nic.fixed_ips: if port_address['ip_address'] == fixed_address: nic_to_associate = nic break else: continue break else: msg = _('Specified fixed address not assigned to server') raise wsme.exc.ClientSideError( msg, status_code=http_client.BAD_REQUEST) if nic_to_associate and nic_to_associate.floating_ip: msg = _('The specified fixed ip has already been associated with ' 'a floating ip.') raise wsme.exc.ClientSideError(msg, status_code=http_client.CONFLICT) if not fixed_address: for nic in server_nics: if nic.floating_ip: continue for port_address in nic.fixed_ips: if netutils.is_valid_ipv4(port_address['ip_address']): fixed_address = port_address['ip_address'] nic_to_associate = nic break else: continue break else: msg = _('Unable to associate floating IP %(address)s ' 'to any fixed IPs for server %(id)s. ' 'Server has no fixed IPv4 addresses to ' 'associate or all fixed ips have already been ' 'associated with floating ips.') % ({ 'address': address, 'id': server.uuid }) raise wsme.exc.ClientSideError( msg, status_code=http_client.BAD_REQUEST) if len(server_nics) > 1: LOG.warning( 'multiple ports exist, using the first ' 'IPv4 fixed_ip: %s', fixed_address) try: self.network_api.associate_floating_ip(pecan.request.context, floating_address=address, port_id=nic.port_id, fixed_address=fixed_address) except (exception.FloatingIpNotFoundForAddress, exception.Forbidden) as e: six.reraise(type(e), e) except Exception as e: msg = _('Unable to associate floating IP %(address)s to ' 'fixed IP %(fixed_address)s for server %(id)s. ' 'Error: %(error)s') % ({ 'address': address, 'fixed_address': fixed_address, 'id': server.uuid, 'error': e }) LOG.exception(msg) raise wsme.exc.ClientSideError(msg, status_code=http_client.BAD_REQUEST) nic_to_associate.floating_ip = address nic_to_associate.save(pecan.request.context)
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] context.can(fi_policies.BASE_POLICY_NAME) address = body['addFloatingIp']['address'] instance = common.get_instance(self.compute_api, context, id, expected_attrs=['flavor']) cached_nwinfo = instance.get_network_info() if not cached_nwinfo: LOG.warning( 'Info cache is %r during associate with no nw_info cache', instance.info_cache, instance=instance) msg = _('Instance network is not ready yet') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _('No fixed IPs associated to instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if 'fixed_address' in body['addFloatingIp']: fixed_address = body['addFloatingIp']['fixed_address'] for fixed in fixed_ips: if fixed['address'] == fixed_address: break else: msg = _('Specified fixed address not assigned to instance') raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: try: fixed_address = next(ip['address'] for ip in fixed_ips if netutils.is_valid_ipv4(ip['address'])) except StopIteration: msg = _('Unable to associate floating IP %(address)s ' 'to any fixed IPs for instance %(id)s. ' 'Instance has no fixed IPv4 addresses to ' 'associate.') % ( {'address': address, 'id': id}) raise webob.exc.HTTPBadRequest(explanation=msg) if len(fixed_ips) > 1: LOG.warning('multiple fixed_ips exist, using the first ' 'IPv4 fixed_ip: %s', fixed_address) try: self.network_api.associate_floating_ip(context, instance, floating_address=address, fixed_address=fixed_address) except exception.FloatingIpAssociated: msg = _('floating IP is already associated') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.FloatingIpAssociateFailed as e: raise webob.exc.HTTPBadRequest(explanation=e.format_message()) except exception.NoFloatingIpInterface: msg = _('l3driver call to add floating IP failed') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.InstanceUnknownCell as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) except exception.FloatingIpNotFoundForAddress: msg = _('floating IP not found') raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _('Unable to associate floating IP %(address)s to ' 'fixed IP %(fixed_address)s for instance %(id)s. ' 'Error: %(error)s') % ( {'address': address, 'fixed_address': fixed_address, 'id': id, 'error': e}) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def test_is_valid_ipv4(self): self.assertTrue(netutils.is_valid_ipv4('42.42.42.42')) self.assertFalse(netutils.is_valid_ipv4('-1.11.11.11')) self.assertFalse(netutils.is_valid_ipv4(''))
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ["nova.context"] context.can(fi_policies.BASE_POLICY_NAME) address = body["addFloatingIp"]["address"] instance = common.get_instance(self.compute_api, context, id, expected_attrs=["flavor"]) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: LOG.warning( _LW("Info cache is %r during associate with no nw_info cache"), instance.info_cache, instance=instance ) msg = _("No nw_info cache associated with instance") raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _("No fixed IPs associated to instance") raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if "fixed_address" in body["addFloatingIp"]: fixed_address = body["addFloatingIp"]["fixed_address"] for fixed in fixed_ips: if fixed["address"] == fixed_address: break else: msg = _("Specified fixed address not assigned to instance") raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: try: fixed_address = next(ip["address"] for ip in fixed_ips if netutils.is_valid_ipv4(ip["address"])) except StopIteration: msg = _( "Unable to associate floating IP %(address)s " "to any fixed IPs for instance %(id)s. " "Instance has no fixed IPv4 addresses to " "associate." ) % ({"address": address, "id": id}) raise webob.exc.HTTPBadRequest(explanation=msg) if len(fixed_ips) > 1: LOG.warning(_LW("multiple fixed_ips exist, using the first " "IPv4 fixed_ip: %s"), fixed_address) try: self.network_api.associate_floating_ip( context, instance, floating_address=address, fixed_address=fixed_address ) except exception.FloatingIpAssociated: msg = _("floating IP is already associated") raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _("l3driver call to add floating IP failed") raise webob.exc.HTTPBadRequest(explanation=msg) except exception.InstanceUnknownCell as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) except exception.FloatingIpNotFoundForAddress: msg = _("floating IP not found") raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _( "Unable to associate floating IP %(address)s to " "fixed IP %(fixed_address)s for instance %(id)s. " "Error: %(error)s" ) % ({"address": address, "fixed_address": fixed_address, "id": id, "error": e}) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def __init__(self, parsed_url): self.driver_endpoint_from_pipeline = parsed_url # database connection parameters self.dbaddress = cfg.CONF.influxdb.influxdb_addr self.dbport = cfg.CONF.influxdb.influxdb_port self.dbname = cfg.CONF.influxdb.influxdb_instance self.dbuser = cfg.CONF.influxdb.influxdb_user self.dbpass = cfg.CONF.influxdb.influxdb_pass self.retention_policy = cfg.CONF.influxdb.retention_policy self.verboselog = cfg.CONF.influxdb.verboselog self.mappings = cfg.CONF.influxdb.mappings self.mapping_data = {} # open mapping file with open(self.mappings, "r") as mapping_descriptor: self.mappingfile = json.loads(mapping_descriptor.read()) LOG.info( "[*] InfluxDB Publisher: Loaded Meters and Tag Mappings from config file [%s]." % self.mappings) # parse json... for entry in self.mappingfile: self.mapping_data[entry["name"]] = entry["values"] # this host self.hostname = gethostname() # compile additional tags self.additional_tags = { 'hypervisor_hostname': self.hostname, 'retention_policy': self.retention_policy } # set meter prefix if cfg.CONF.influxdb.append_hypervisor: self.meter_prefix = cfg.CONF.influxdb.metering_prefix + self.hostname else: self.meter_prefix = cfg.CONF.influxdb.metering_prefix # get keystone client instance self.identity = get_client() # get initial tenant list self.tenants = self.identity.projects.list() # at startup, register available tenants in in-memory database # subsequent queries either hit the in memory cache or need a new query to keystone for t in self.tenants: InfluxDBPublisherUtils.pushTenant(t.id, t.name) # create DB connection # sanity check on database parameters if not (network_utils.is_valid_ipv4(self.dbaddress) and network_utils.is_valid_port(self.dbport)): raise Exception("dbaddr:dbport validation error %s:%s" % (self.dbaddress, self.dbport)) try: self.dbconn = dbclient(self.dbaddress, self.dbport, self.dbuser, self.dbpass, self.dbname) except Exception as e: LOG.info(e) # OK init done LOG.info("[+] InfluxDB Publisher [%s] registered to [%s]" % (self.driver_endpoint_from_pipeline, self.dbaddress))