Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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))