Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    def validate_subnet(subnet):
        """Validates that a subnet specification is correctly
        formatted and with legal values.

        Raises SubnetError if invalid.
        """
        try:
            ip, mask = subnet.split('/')
            mask = int(mask)
        except ValueError:
            raise SubnetError("Not a valid subnet '%s'" % subnet)
        if not IPv6Utils.is_valid_ipv6(ip):
            raise SubnetError("Invalid adress: %s" % ip)
        # TODO 25-08-2015:
        # Since Subnet-masks for IPv6 are not properly implemented yet, this
        # will validate an unspecified subnet mask (''), enabling bofh-users
        # to specify a subnet like this: '2007:700:111:1/'. This should be
        # fixed when/if proper subnet-handling is implemented.
        if mask < 0 or mask > 128:
            raise SubnetError("Invalid subnet mask '%s'; "
                              "outside range 0-128" % mask)
        return True
Beispiel #6
0
    def validate_subnet(subnet):
        """Validates that a subnet specification is correctly
        formatted and with legal values.

        Raises SubnetError if invalid.
        """
        try:
            ip, mask = subnet.split('/')
            mask = int(mask)
        except ValueError:
            raise SubnetError("Not a valid subnet '%s'" % subnet)
        if not IPv6Utils.is_valid_ipv6(ip):
            raise SubnetError("Invalid adress: %s" % ip)
        # TODO 25-08-2015:
        # Since Subnet-masks for IPv6 are not properly implemented yet, this
        # will validate an unspecified subnet mask (''), enabling bofh-users
        # to specify a subnet like this: '2007:700:111:1/'. This should be
        # fixed when/if proper subnet-handling is implemented.
        if mask < 0 or mask > 128:
            raise SubnetError("Invalid subnet mask '%s'; "
                              "outside range 0-128" % mask)
        return True
Beispiel #7
0
def test_not_is_valid_ipv6(addr):
    assert not IPv6Utils.is_valid_ipv6(addr)