Beispiel #1
0
    def validate_static_ip(self, ip):
        """Validates that the requested IP address is acceptable for allocation
        in this `Subnet` (assuming it has not already been allocated).

        Raises `StaticIPAddressUnavailable` if the address is not acceptable.

        Does not consider whether or not the IP address is already allocated,
        only whether or not it is in the proper network and range.

        :raises StaticIPAddressUnavailable: If the IP address specified is not
            available for allocation.
        """
        if ip not in self.get_ipnetwork():
            raise StaticIPAddressOutOfRange(
                "%s is not within subnet CIDR: %s" % (ip, self.cidr))
        for iprange in self.get_reserved_maasipset():
            if ip in iprange:
                raise StaticIPAddressUnavailable(
                    "%s is within the reserved range from %s to %s" %
                    (ip, IPAddress(iprange.first), IPAddress(iprange.last)))
        for iprange in self.get_dynamic_maasipset():
            if ip in iprange:
                raise StaticIPAddressUnavailable(
                    "%s is within the dynamic range from %s to %s" %
                    (ip, IPAddress(iprange.first), IPAddress(iprange.last)))
Beispiel #2
0
    def allocate_new(
        self,
        subnet=None,
        alloc_type=IPADDRESS_TYPE.AUTO,
        user=None,
        requested_address=None,
        exclude_addresses=None,
    ):
        """Return a new StaticIPAddress.

        :param subnet: The subnet from which to allocate the address.
        :param alloc_type: What sort of IP address to allocate in the
            range of choice in IPADDRESS_TYPE.
        :param user: If providing a user, the alloc_type must be
            IPADDRESS_TYPE.USER_RESERVED. Conversely, if the alloc_type is
            IPADDRESS_TYPE.USER_RESERVED the user must also be provided.
            AssertionError is raised if these conditions are not met.
        :param requested_address: Optional IP address that the caller wishes
            to use instead of being allocated one at random.
        :param exclude_addresses: A list of addresses which MUST NOT be used.

        All IP parameters can be strings or netaddr.IPAddress.
        """
        # This check for `alloc_type` is important for later on. We rely on
        # detecting IntegrityError as a sign than an IP address is already
        # taken, and so we must first eliminate all other possible causes.
        self._verify_alloc_type(alloc_type, user)

        if subnet is None:
            if requested_address:
                subnet = Subnet.objects.get_best_subnet_for_ip(
                    requested_address)
            else:
                raise StaticIPAddressOutOfRange(
                    "Could not find an appropriate subnet.")

        if requested_address is None:
            requested_address = subnet.get_next_ip_for_allocation(
                exclude_addresses=exclude_addresses)
            return self._attempt_allocation_of_free_address(requested_address,
                                                            alloc_type,
                                                            user=user,
                                                            subnet=subnet)
        else:
            requested_address = IPAddress(requested_address)
            # Circular imports.
            from maasserver.models import StaticIPAddress

            if (StaticIPAddress.objects.filter(
                    ip=str(requested_address)).exclude(
                        alloc_type=IPADDRESS_TYPE.DISCOVERED).count() > 0):
                raise StaticIPAddressUnavailable(
                    "The IP address %s is already in use." % requested_address)

            subnet.validate_static_ip(requested_address)
            return self._attempt_allocation(requested_address,
                                            alloc_type,
                                            user=user,
                                            subnet=subnet)