Beispiel #1
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 #2
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 #3
0
    def find(self, identifier):
        """Find and instantiate the subnet entity with data from the db.

        @type identifier: mixed
        @param identifier:
            The identifier of the Subnet. Note that the DNS module behaves a bit
            differently than other Cerebrum modules, in that this find method
            accepts other input than entity_id. Possibilities are:

                - A string containing the entity_id, prefixed with 'entity_id:'
                  or 'id:'.

                - A string with a subnet address, e.g. '10.0.1.0/16'.

                - A string with an IP address, e.g. '10.0.1.57'.

        """
        binds = {}

        if identifier is None:
            raise SubnetError("Unable to find IPv4 subnet identified by '%s'" % identifier)

        if isinstance(identifier, (str, unicode)) and identifier.count(':') >= 2:
            # This is probably an IPv6 subnet
            raise SubnetError("Unable to find IPv4 subnet identified by '%s'" % identifier)

        if isinstance(identifier, (int, long)):
            # The proper way of running find()
            where_param = "entity_id = :e_id"
            binds['e_id'] = identifier
        elif identifier.startswith('id:') or identifier.startswith('entity_id:'):
            # E.g. 'id:X' or 'entity_id:X';
            where_param = "entity_id = :e_id"
            try:
                binds['e_id'] = int(identifier.split(':')[1])
            except ValueError:
                raise SubnetError("Entity ID must be an integer")
        elif identifier.find('/') > 0:
            # A '/' indicates a subnet spec: just need the ip
            where_param = "subnet_ip = :subnet_ip"
            subnet_ip = identifier.split('/')[0]
            if len(subnet_ip.split(".")) == 3:
                subnet_ip += ".0"
            binds['subnet_ip'] = subnet_ip
        else:
            # Last valid type is simply an IP; need to find correct range
            if len(identifier.split(".")) == 3:
                identifier += ".0"
            where_param = "ip_min <= :ip AND ip_max >= :ip"
            binds['ip'] = IPCalc.ip_to_long(identifier)

        try:
            (eid, self.subnet_ip, self.ip_min, self.ip_max,
             self.description, self.dns_delegated, self.name_prefix,
             self.vlan_number, self.no_of_reserved_adr) = self.query_1(
                 """SELECT entity_id, subnet_ip, ip_min, ip_max, description,
                           dns_delegated, name_prefix, vlan_number,
                           no_of_reserved_adr
                    FROM [:table schema=cerebrum name=dns_subnet]
                    WHERE %s""" % where_param, binds)

            self.__super.find(eid)

            self.subnet_mask = Subnet.calculate_subnet_mask(self.ip_min, self.ip_max)
            self.calculate_reserved_addresses()

        except NotFoundError:
            raise SubnetError("Unable to find IPv4 subnet identified by '%s'" % identifier)

        self.__in_db = True
        self.__updated = []