Пример #1
0
    def validate_allocation_pools(self, ip_pools, subnet_cidr):
        """Validate IP allocation pools.

        Verify start and end address for each allocation pool are valid,
        ie: constituted by valid and appropriately ordered IP addresses.
        Also, verify pools do not overlap among themselves.
        Finally, verify that each range fall within the subnet's CIDR.
        """
        subnet = netaddr.IPNetwork(subnet_cidr)
        subnet_first_ip = netaddr.IPAddress(subnet.first + 1)
        # last address is broadcast in v4
        subnet_last_ip = netaddr.IPAddress(subnet.last - (subnet.version == 4))

        LOG.debug("Performing IP validity checks on allocation pools")
        ip_sets = []
        for ip_pool in ip_pools:
            start_ip = netaddr.IPAddress(ip_pool.first, ip_pool.version)
            end_ip = netaddr.IPAddress(ip_pool.last, ip_pool.version)
            if (start_ip.version != subnet.version
                    or end_ip.version != subnet.version):
                LOG.info(
                    _LI("Specified IP addresses do not match "
                        "the subnet IP version"))
                raise n_exc.InvalidAllocationPool(pool=ip_pool)
            if start_ip < subnet_first_ip or end_ip > subnet_last_ip:
                LOG.info(
                    _LI("Found pool larger than subnet "
                        "CIDR:%(start)s - %(end)s"), {
                            'start': start_ip,
                            'end': end_ip
                        })
                raise n_exc.OutOfBoundsAllocationPool(pool=ip_pool,
                                                      subnet_cidr=subnet_cidr)
            # Valid allocation pool
            # Create an IPSet for it for easily verifying overlaps
            ip_sets.append(netaddr.IPSet(ip_pool.cidrs()))

        LOG.debug("Checking for overlaps among allocation pools "
                  "and gateway ip")
        ip_ranges = ip_pools[:]

        # Use integer cursors as an efficient way for implementing
        # comparison and avoiding comparing the same pair twice
        for l_cursor in range(len(ip_sets)):
            for r_cursor in range(l_cursor + 1, len(ip_sets)):
                if ip_sets[l_cursor] & ip_sets[r_cursor]:
                    l_range = ip_ranges[l_cursor]
                    r_range = ip_ranges[r_cursor]
                    LOG.info(
                        _LI("Found overlapping ranges: %(l_range)s and "
                            "%(r_range)s"), {
                                'l_range': l_range,
                                'r_range': r_range
                            })
                    raise n_exc.OverlappingAllocationPools(
                        pool_1=l_range,
                        pool_2=r_range,
                        subnet_cidr=subnet_cidr)
Пример #2
0
    def _validate_allocation_pools(self):
        """Validate IP allocation pools.

        Verify start and end address for each allocation pool are valid,
        ie: constituted by valid and appropriately ordered IP addresses.
        Also, verify pools do not overlap among themselves.
        Finally, verify that each range fall within the subnet's CIDR.
        """
        ip_pools = self._alloc_pools
        subnet_cidr = self._subnet_cidr

        LOG.debug(_("Performing IP validity checks on allocation pools"))
        ip_sets = []
        for ip_pool in ip_pools:
            try:
                start_ip = netaddr.IPAddress(ip_pool['start'])
                end_ip = netaddr.IPAddress(ip_pool['end'])
            except netaddr.AddrFormatError:
                LOG.info(
                    _("Found invalid IP address in pool: "
                      "%(start)s - %(end)s:"), {
                          'start': ip_pool['start'],
                          'end': ip_pool['end']
                      })
                raise exceptions.InvalidAllocationPool(pool=ip_pool)
            if (start_ip.version != self._subnet_cidr.version
                    or end_ip.version != self._subnet_cidr.version):
                LOG.info(
                    _("Specified IP addresses do not match "
                      "the subnet IP version"))
                raise exceptions.InvalidAllocationPool(pool=ip_pool)
            if end_ip < start_ip:
                LOG.info(
                    _("Start IP (%(start)s) is greater than end IP "
                      "(%(end)s)"), {
                          'start': ip_pool['start'],
                          'end': ip_pool['end']
                      })
                raise exceptions.InvalidAllocationPool(pool=ip_pool)
            if (start_ip < self._subnet_first_ip
                    or end_ip > self._subnet_last_ip):
                LOG.info(
                    _("Found pool larger than subnet "
                      "CIDR:%(start)s - %(end)s"), {
                          'start': ip_pool['start'],
                          'end': ip_pool['end']
                      })
                raise exceptions.OutOfBoundsAllocationPool(
                    pool=ip_pool, subnet_cidr=subnet_cidr)
            # Valid allocation pool
            # Create an IPSet for it for easily verifying overlaps
            ip_sets.append(
                netaddr.IPSet(
                    netaddr.IPRange(ip_pool['start'], ip_pool['end']).cidrs()))

        LOG.debug(
            _("Checking for overlaps among allocation pools "
              "and gateway ip"))
        ip_ranges = ip_pools[:]

        # Use integer cursors as an efficient way for implementing
        # comparison and avoiding comparing the same pair twice
        for l_cursor in xrange(len(ip_sets)):
            for r_cursor in xrange(l_cursor + 1, len(ip_sets)):
                if ip_sets[l_cursor] & ip_sets[r_cursor]:
                    l_range = ip_ranges[l_cursor]
                    r_range = ip_ranges[r_cursor]
                    LOG.info(
                        _("Found overlapping ranges: %(l_range)s and "
                          "%(r_range)s"), {
                              'l_range': l_range,
                              'r_range': r_range
                          })
                    raise exceptions.OverlappingAllocationPools(
                        pool_1=l_range,
                        pool_2=r_range,
                        subnet_cidr=subnet_cidr)