Beispiel #1
0
 def _check_num_keypairs_quota(self, context, count):
     keypair_resource = self.quota.resources['keypairs']
     quotas = self.quota.get_quota_limit_and_usage(
         context, {'keyparis': keypair_resource}, context.tenant)
     limit = quotas['keypairs']['limit']
     in_use = quotas['keypairs']['in_use']
     reserved = quotas['keypairs']['reserved']
     available_quota = limit - in_use - reserved
     if count <= available_quota:
         return count
     else:
         raise exception.OverQuota(overs='keypairs')
Beispiel #2
0
 def _check_num_servers_quota(self, context, min_count, max_count):
     ins_resource = self.quota.resources['servers']
     quotas = self.quota.get_quota_limit_and_usage(
         context, {'servers': ins_resource}, context.tenant)
     limit = quotas['servers']['limit']
     in_use = quotas['servers']['in_use']
     reserved = quotas['servers']['reserved']
     available_quota = limit - in_use - reserved
     if max_count <= available_quota:
         return max_count
     elif min_count <= available_quota and max_count > available_quota:
         return available_quota
     else:
         raise exception.OverQuota(overs='servers')
Beispiel #3
0
    def quota_reserve(self,
                      context,
                      resources,
                      quotas,
                      deltas,
                      expire,
                      until_refresh,
                      max_age,
                      project_id,
                      is_allocated_reserve=False):
        # NOTE(wanghao): Now we still doesn't support contenxt.elevated() yet.
        # We can support it later.
        elevated = context
        with _session_for_write() as session:
            if project_id is None:
                project_id = context.project_id
            # Get the current usages
            usages = self._get_quota_usages(context, project_id)
            allocated = self.quota_allocated_get_all_by_project(
                context, project_id)
            allocated.pop('project_id')

            # Handle usage refresh
            work = set(deltas.keys())
            while work:
                resource = work.pop()

                # Do we need to refresh the usage?
                refresh = False
                if resource not in usages:
                    usages[resource] = self._quota_usage_create(
                        elevated,
                        project_id,
                        resource,
                        0,
                        0,
                        until_refresh or None,
                        session=session)
                    refresh = True
                elif usages[resource].in_use < 0:
                    refresh = True
                elif usages[resource].until_refresh is not None:
                    usages[resource].until_refresh -= 1
                    if usages[resource].until_refresh <= 0:
                        refresh = True
                elif max_age and usages[resource].updated_at is not None and (
                    (usages[resource].updated_at - timeutils.utcnow()).seconds
                        >= max_age):
                    refresh = True

                # OK, refresh the usage
                if refresh:
                    # Grab the sync routine
                    sync = self.QUOTA_SYNC_FUNCTIONS[resources[resource].sync]
                    updates = sync(elevated, project_id)
                    for res, in_use in updates.items():
                        # Make sure we have a destination for the usage!
                        if res not in usages:
                            usages[res] = self._quota_usage_create(
                                elevated,
                                project_id,
                                res,
                                0,
                                0,
                                until_refresh or None,
                                session=session)

                        # Update the usage
                        usages[res].in_use = in_use
                        usages[res].until_refresh = until_refresh or None

                        # Because more than one resource may be refreshed
                        # by the call to the sync routine, and we don't
                        # want to double-sync, we make sure all refreshed
                        # resources are dropped from the work set.
                        work.discard(res)

            # Check for deltas that would go negative
            if is_allocated_reserve:
                unders = [
                    r for r, delta in deltas.items()
                    if delta < 0 and delta + allocated.get(r, 0) < 0
                ]
            else:
                unders = [
                    r for r, delta in deltas.items()
                    if delta < 0 and delta + usages[r].in_use < 0
                ]

            # Now, let's check the quotas
            overs = [
                r for r, delta in deltas.items()
                if quotas[r] >= 0 and delta >= 0 and quotas[r] < delta +
                usages[r].total + allocated.get(r, 0)
            ]

            # Create the reservations
            if not overs:
                reservations = []
                for resource, delta in deltas.items():
                    usage = usages[resource]
                    allocated_id = None
                    if is_allocated_reserve:
                        try:
                            quota = self.quota_get(context, project_id,
                                                   resource)
                        except exception.ProjectQuotaNotFound:
                            # If we were using the default quota, create DB
                            # entry
                            quota = self.quota_create(context, project_id,
                                                      resource,
                                                      quotas[resource], 0)
                        # Since there's no reserved/total for allocated, update
                        # allocated immediately and subtract on rollback
                        # if needed
                        self.quota_allocated_update(context, project_id,
                                                    resource,
                                                    quota.allocated + delta)
                        allocated_id = quota.id
                        usage = None
                    reservation = self._reservation_create(
                        elevated,
                        uuidutils.generate_uuid(),
                        usage,
                        project_id,
                        resource,
                        delta,
                        expire,
                        session=session,
                        allocated_id=allocated_id)

                    reservations.append(reservation)

                    # Also update the reserved quantity
                    if delta > 0 and not is_allocated_reserve:
                        usages[resource].reserved += delta

        if unders:
            LOG.warning(
                "Change will make usage less than 0 for the "
                "following resources: %s", unders)
        if overs:
            usages = {
                k: dict(in_use=v.in_use,
                        reserved=v.reserved,
                        allocated=allocated.get(k, 0))
                for k, v in usages.items()
            }
            raise exception.OverQuota(overs=sorted(overs),
                                      quotas=quotas,
                                      usages=usages)
        return reservations