def test_not_is_valid_ipv4(): # Only 0-255 should be accepted values assert not IPUtils.is_valid_ipv4('10.0.256.1') assert not IPUtils.is_valid_ipv4('10.0.foo.1') # Max 4 segments assert not IPUtils.is_valid_ipv4('10.0.255.1.1')
def parse_subnet_or_ip(self, ip_id): """Parse ip_id either as a subnet, or as an IP-number. Return: (subnet, ip) - subnet is None if unknown - ip is only set if the user requested a specific IP A request for a subnet is identified by a trailing /, or for IPv4 an IP with < 4 octets. IPv6-subnets must always be specified with a trailing /, followed by a mask number. Examples:: 129.240.200 -> adress on 129.240.200.0/23 129.240.200.0/ -> adress on 129.240.200.0/23 129.240.200.0 -> explicit IP 2001:700:100:2::/64 -> address on 2001:700:100:2::/64 2001:700:100:2::3 -> explicit IP """ tmp = ip_id.split("/") ip = tmp[0] subnet_slash = len(tmp) > 1 full_ip = False if IPUtils.is_valid_ipv4(ip): # ipv4 IPUtils.parse_ipv4(ip) if ip.count('.') == 3 and not subnet_slash: full_ip = True elif ip.count('.') == 3 and subnet_slash or \ ip.count('.') == 2 and not subnet_slash: pass else: raise CerebrumError(("'%s' does not look like a valid subnet " "or ip-address.") % ip_id) elif IPv6Utils.is_valid_ipv6(ip_id): # full ipv6 full_ip = True ip = ip_id elif IPv6Subnet.IPv6Subnet.is_valid_subnet(ip_id): ip = ip_id else: try: # Assume hostname self._arecord.clear() self._arecord.find_by_name(self.qualify_hostname(ip)) self._ip_number.clear() self._ip_number.find(self._arecord.ip_number_id) except Errors.NotFoundError: raise CerebrumError("Could not find host %s" % ip) ip = self._ip_number.a_ip try: ipc = Find(self._db, None) subnet_ip = ipc._find_subnet(ip) except: subnet_ip = None return subnet_ip, full_ip and ip or None
def get_relevant_ips(self, subnet_or_ip, force=False, no_of_addrs=None): """ Returns a list of available IPs. If a subnet is given as input, the list consists of avaiable IPs on the subnet. If a specific IP is given as input, the list will only contain that IP. :param subnet_or_ip: An IPv4/IPv6 subnet or IP-address :type subnet_or_ip: str :param force: Indicates if the method should attempt to force the operation, even if there is no record that the IP given as input belongs to any subnet records. :type force: boolean :param no_of_addrs: The max number of ips to be returned. :type no_of_addrs: int :returns: A list of available IPs found, or a list containing only the specified IP given to the method in subnet_or_ip, if it is evaluated to a full IP. :rtype: list """ subnet, ip = self._parser.parse_subnet_or_ip(subnet_or_ip) if subnet is None and not force: raise CerebrumError("Unknown subnet. Must force") elif subnet is None and ip is None: raise CerebrumError("Please specify a valid subnet or IP-address.") elif subnet is not None and ip is None: first = subnet_or_ip.split('/')[0] if IPUtils.is_valid_ipv4(first): first = IPCalc.ip_to_long(first) elif IPv6Utils.is_valid_ipv6(first): first = None free_ip_numbers = self._find.find_free_ip(subnet, first=first, no_of_addrs=no_of_addrs) else: free_ip_numbers = [ip] return free_ip_numbers
def test_is_valid_ipv4(): # Valid IPv4-entries that should pass assert IPUtils.is_valid_ipv4('10.0') assert IPUtils.is_valid_ipv4('10.0.255') assert IPUtils.is_valid_ipv4('10.0.255.1')