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 test_ipv4_prefix_not_allowed(): # TODO: Should this really raise a bofhd-error? from Cerebrum.modules.bofhd.errors import CerebrumError # Technically valid IPv4-addresses that contain leading # zeroes should raise an error for ipaddr in ('010.0.0.10', '010.0.0.10', '10.00.0.1', '10.0.00.1', '10.0.00.01'): with pytest.raises(CerebrumError): IPUtils.parse_ipv4(ipaddr)