def _validate_value_formats(): """Validate format of some values Certain values have a specific format that must be maintained in order to work properly. For example, local_ip must be in CIDR form, and the hostname must be a FQDN. """ try: local_ip = netaddr.IPNetwork(CONF.local_ip) if local_ip.prefixlen == 32: LOG.error(_('Invalid netmask')) raise netaddr.AddrFormatError(_('Invalid netmask')) # If IPv6 the ctlplane network uses the EUI-64 address format, # which requires the prefix to be /64 if local_ip.version == 6 and local_ip.prefixlen != 64: LOG.error(_('Prefix must be 64 for IPv6')) raise netaddr.AddrFormatError(_('Prefix must be 64 for IPv6')) except netaddr.core.AddrFormatError as e: message = (_('local_ip "{0}" not valid: "{1}" ' 'Value must be in CIDR format.').format( CONF.local_ip, str(e))) LOG.error(message) raise FailedValidation(message) hostname = CONF['undercloud_hostname'] if hostname is not None and '.' not in hostname: message = (_('Hostname "%s" is not fully qualified.') % hostname) LOG.error(message) raise FailedValidation(message)
def to_mac_range(val): """ Doc Tests. >>> testval1 = "AA:AA:AA/8" >>> testval2 = "12-23-45/9" >>> testval3 = "::/0" >>> testval4 = "00-00-00-00/10" >>> to_mac_range(testval1) ('AA:AA:AA:00:00:00/8', 187649973288960, 188749484916736) >>> to_mac_range(testval2) ('12:23:45:00:00:00/9', 19942690783232, 20492446597120) This should fail: >>> to_mac_range(testval3) Traceback (most recent call last): ... ValueError: 6>len(::/0) || len(::/0)>10 [len == 0] this should not fail: >>> to_mac_range(testval4) ('00:00:00:00:00:00/10', 0, 274877906944) bad cidr: >>> badcidr = "ZZZZZZ" >>> to_mac_range(badcidr) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... AddrFormatError: ZZZZZZ000000 raised netaddr.AddrFormatError: failed to detect EUI version: 'ZZZZZZ000000'... ignoring. """ import netaddr cidr_parts = val.split("/") prefix = cidr_parts[0] prefix = prefix.replace(':', '') prefix = prefix.replace('-', '') prefix_length = len(prefix) if prefix_length < 6 or prefix_length > 12: r = "6>len({0}) || len({0})>12 len == {1}]".format(val, prefix_length) raise ValueError(r) diff = 12 - len(prefix) if len(cidr_parts) > 1: mask = int(cidr_parts[1]) else: mask = 48 - diff * 4 mask_size = 1 << (48 - mask) prefix = "%s%s" % (prefix, "0" * diff) try: cidr = "%s/%s" % (str(netaddr.EUI(prefix)).replace("-", ":"), mask) except netaddr.AddrFormatError as e: r = "{0} raised netaddr.AddrFormatError: ".format(prefix) r += "{0}... ignoring.".format(e.message) raise netaddr.AddrFormatError(r) prefix_int = int(prefix, base=16) del netaddr return cidr, prefix_int, prefix_int + mask_size
def test_addr_format_error_exception(self): req = wsgi_resource.Request({}) language = req.best_match_language() e = netaddr.AddrFormatError() result = common.convert_exception_to_http_exc(e, {}, language) except_res = {'message': '', 'type': 'AddrFormatError', 'detail': ''} self.assertEqual(except_res, json.loads(result.body)["TackerError"]) self.assertEqual(500, result.code)
def normalize_ip_port(ipport): try: return normalize_ip(ipport) except netaddr.AddrFormatError: # maybe we have a port if ipport[0] == '[': # Should be an IPv6 w/ port try: ip, port = ipport[1:].split(']:') except ValueError: raise netaddr.AddrFormatError("Invalid Port") ip = "[%s]" % normalize_ip(ip) else: try: ip, port = ipport.split(':') except ValueError: raise netaddr.AddrFormatError("Invalid Port") ip = normalize_ip(ip) if int(port) <= 0 or int(port) > 65535: raise netaddr.AddrFormatError("Invalid port") return "%s:%s" % (ip, port)
def ipv4_str_to_int(ipaddrstr): """ Wrapper for converting an IPv4 address from a human-readable string to an int. param ipaddrstr: IP address in str format. return: IP address in int format. """ if (len(ipaddrstr.split('.')) != 4): raise netaddr.AddrFormatError("Invalid IPv4 address format: " + ipaddrstr) try: return int(netaddr.IPAddress(ipaddrstr)) except netaddr.AddrFormatError, e: raise
def ipv4_int_to_str(ipaddrint): """ Wrapper for converting an IPv4 address in int for to a human-readable string. param ipaddrint: IP address in int format. return: IP address in str format. """ if (ipaddrint > 4294967295 or ipaddrint < 0): raise netaddr.AddrFormatError("IP address out of range: " + str(ipaddrint)) addrlist = [str(ipaddrint >> 24 & 0xFF), str(ipaddrint >> 16 & 0xFF), str(ipaddrint >> 8 & 0xFF), str(ipaddrint & 0xFF)] addrstr = '.'.join(addrlist) return addrstr
def _validate_value_formats(params, error_callback): """Validate format of some values Certain values have a specific format that must be maintained in order to work properly. For example, local_ip must be in CIDR form, and the hostname must be a FQDN. """ try: local_ip = netaddr.IPNetwork(params['local_ip']) if local_ip.prefixlen == 32: raise netaddr.AddrFormatError('Invalid netmask') # If IPv6 the ctlplane network uses the EUI-64 address format, # which requires the prefix to be /64 if local_ip.version == 6 and local_ip.prefixlen != 64: raise netaddr.AddrFormatError('Prefix must be 64 for IPv6') except netaddr.core.AddrFormatError as e: message = ('local_ip "%s" not valid: "%s" ' 'Value must be in CIDR format.' % (params['local_ip'], str(e))) error_callback(message) hostname = params['undercloud_hostname'] if hostname is not None and '.' not in hostname: message = 'Hostname "%s" is not fully qualified.' % hostname error_callback(message)
def _validate_value_formats(params, error_callback): """Validate format of some values Certain values have a specific format that must be maintained in order to work properly. For example, local_ip must be in CIDR form, and the hostname must be a FQDN. """ try: local_ip = netaddr.IPNetwork(params['local_ip']) if local_ip.prefixlen == 32: raise netaddr.AddrFormatError('Invalid netmask') except netaddr.core.AddrFormatError as e: message = ('local_ip "%s" not valid: "%s" ' 'Value must be in CIDR format.' % (params['local_ip'], str(e))) error_callback(message) if '.' not in params['undercloud_hostname']: message = ('Hostname "%s" is not fully qualified.' % params['undercloud_hostname']) error_callback(message)
def parse_ip_address_and_port(addr, default_port=22): """ Return a pair (IP address, port) extracted from string `addr`. Different formats are accepted for the address/port string: * IPv6 literals in square brackets, with or without an optional port specification, as used in URLs:: >>> parse_ip_address_and_port('[fe80::dead:beef]:1234') (IPAddress('fe80::dead:beef'), 1234) >>> parse_ip_address_and_port('[fe80::dead:beef]') (IPAddress('fe80::dead:beef'), 22) * IPv6 literals with a "local interface" specification:: >>> parse_ip_address_and_port('[fe80::dead:beef%eth0]') (IPAddress('fe80::dead:beef'), 22) >>> parse_ip_address_and_port('fe80::dead:beef%eth0') (IPAddress('fe80::dead:beef'), 22) * bare IPv6 addresses:: >>> parse_ip_address_and_port('fe80::dead:beef') (IPAddress('fe80::dead:beef'), 22) >>> parse_ip_address_and_port('2001:db8:5ca1:1f0:f816:3eff:fe05:f40f') (IPAddress('2001:db8:5ca1:1f0:f816:3eff:fe05:f40f'), 22) * IPv4 addresses, with or without an additional port specification:: >>> parse_ip_address_and_port('192.0.2.123') (IPAddress('192.0.2.123'), 22) >>> parse_ip_address_and_port('192.0.2.123:999') (IPAddress('192.0.2.123'), 999) Note that the default port can be changed by passing an additional parameter:: >>> parse_ip_address_and_port('192.0.2.123', 987) (IPAddress('192.0.2.123'), 987) >>> parse_ip_address_and_port('fe80::dead:beef', 987) (IPAddress('fe80::dead:beef'), 987) :raise netaddr.AddrFormatError: Upon parse failure, e.g., syntactically incorrect IP address. """ # we assume one and only one of the regexps will match for regexp in _IP_ADDRESS_RE: match = regexp.search(addr) if not match: continue # can raise netaddr.AddrFormatError ip_addr = netaddr.IPAddress(match.group('ip_addr')) try: port = match.group('port') except IndexError: port = None if port is not None: port = int(port[1:]) # skip leading `:` else: port = default_port return ip_addr, port # parse failed raise netaddr.AddrFormatError( "Could not extract IP address and port from `{1}`" .format(addr))