def request(self,
                method,
                url,
                token=None,
                args=None,
                headers=None,
                accepted_codes=[200, 201, 202, 204]):
        params = {}
        if args:
            # extract filter and fields
            if 'filters' in args:
                params = args.pop('filters')
            if 'fields' in args:
                params['fields'] = args.pop('fields')
            args = jsonutils.dumps(args)
        if not headers:
            headers = {
                'Content-type': 'application/json',
                'X-Auth-Token': token
            }
        headers['User-Agent'] = OCTAVIA_PROXY_CLIENT

        url = '{}/{}'.format(self.base_url, str(url))
        LOG.debug("url = %s", url)
        LOG.debug("args = %s", args)
        LOG.debug("params = %s", str(params))
        r = requests.request(method,
                             url,
                             data=args,
                             params=params,
                             headers=headers)
        LOG.debug("Octavia Response Code: {0}".format(r.status_code))
        LOG.debug("Octavia Response Body: {0}".format(r.content))
        LOG.debug("Octavia Response Headers: {0}".format(r.headers))

        if r.status_code in accepted_codes:
            if method != 'DELETE':
                return r.json()
        elif r.status_code == 413:
            e = lib_exc.OverQuota()
            e.msg = str(r.content)
            raise e
        elif r.status_code == 409:
            e = lib_exc.Conflict()
            e.msg = str(r.content)
            raise e
        elif r.status_code == 401:
            e = lib_exc.NotAuthorized()
            e.msg = str(r.content)
            raise e
        elif r.status_code == 404:
            e = lib_exc.NotFound()
            e.msg = str(r.content)
            raise e
        elif r.status_code == 400:
            e = lib_exc.BadRequest(resource="", msg="")
            e.msg = str(r.content)
            raise e
        else:
            raise loadbalancerv2.DriverError(msg=str(r.content))
Exemple #2
0
    def limit_check(self, context, tenant_id, resources, values):
        """Check simple quota limits.

        For limits--those quotas for which there is no usage
        synchronization function--this method checks that a set of
        proposed values are permitted by the limit restriction.

        If any of the proposed values is over the defined quota, an
        OverQuota exception will be raised with the sorted list of the
        resources which are too high.  Otherwise, the method returns
        nothing.

        :param context: The request context, for access checks.
        :param tenant_id: The tenant_id to check the quota.
        :param resources: A dictionary of the registered resources.
        :param values: A dictionary of the values to check against the
                       quota.
        """

        # Ensure no value is less than zero
        unders = [key for key, val in values.items() if val < 0]
        if unders:
            raise n_exc.InvalidQuotaValue(unders=sorted(unders))

        # Get the applicable quotas
        quotas = self._get_quotas(context, tenant_id, resources)

        # Check the quotas and construct a list of the resources that
        # would be put over limit by the desired values
        overs = [key for key, val in values.items() if 0 <= quotas[key] < val]
        if overs:
            raise exceptions.OverQuota(overs=sorted(overs))
Exemple #3
0
    def make_reservation(self, context, project_id, resources, deltas, plugin):
        resources_over_limit = []
        with db_api.CONTEXT_WRITER.using(context):
            # Filter out unlimited resources.
            limits = self.get_tenant_quotas(context, resources, project_id)
            unlimited_resources = set([
                resource for (resource, limit) in limits.items() if limit < 0
            ])
            requested_resources = (set(deltas.keys()) - unlimited_resources)

            # Delete expired reservations before counting valid ones. This
            # operation is fast and by calling it before making any
            # reservation, we ensure the freshness of the reservations.
            quota_api.remove_expired_reservations(context,
                                                  tenant_id=project_id)

            # Count the number of (1) used and (2) reserved resources for this
            # project_id. If any resource limit is exceeded, raise exception.
            for resource_name in requested_resources:
                tracked_resource = resources.get(resource_name)
                if not tracked_resource:
                    continue

                used_and_reserved = tracked_resource.count(
                    context, None, project_id, count_db_registers=True)
                resource_num = deltas[resource_name]
                if limits[resource_name] < (used_and_reserved + resource_num):
                    resources_over_limit.append(resource_name)

            if resources_over_limit:
                raise exceptions.OverQuota(overs=sorted(resources_over_limit))

            return quota_api.create_reservation(context, project_id, deltas)
Exemple #4
0
 def _resource_create(self, resource_type, obj):
     create_method = getattr(self._vnc_api, resource_type + '_create')
     try:
         try:
             obj_uuid = create_method(obj)
         except vnc_exc.RefsExistError:
             obj.uuid = str(uuid.uuid4())
             obj.name += '-' + obj.uuid
             obj.fq_name[-1] += '-' + obj.uuid
             obj_uuid = create_method(obj)
     except (vnc_exc.PermissionDenied, vnc_exc.BadRequest) as e:
         neutron_exc.BadRequest(resource_type=resource_type, msg=str(e))
     except vnc_exc.OverQuota as e:
         neutron_exc.OverQuota(overs=[resource_type], msg=str(e))
     return obj_uuid
Exemple #5
0
    def make_reservation(self, context, project_id, resources, deltas, plugin):
        resources_over_limit = []
        with db_api.CONTEXT_WRITER.using(context):
            # Filter out unlimited resources.
            limits = self.get_project_quotas(context, resources, project_id)
            unlimited_resources = set([
                resource for (resource, limit) in limits.items() if limit < 0
            ])
            requested_resources = (set(deltas.keys()) - unlimited_resources)

            # Count the number of (1) used and (2) reserved resources for this
            # project_id. If any resource limit is exceeded, raise exception.
            for resource_name in requested_resources:
                used_and_reserved = self.get_resource_usage(
                    context, project_id, resources, resource_name)
                resource_num = deltas[resource_name]
                if limits[resource_name] < (used_and_reserved + resource_num):
                    resources_over_limit.append(resource_name)

            if resources_over_limit:
                raise exceptions.OverQuota(overs=sorted(resources_over_limit))

            return quota_api.create_reservation(context, project_id, deltas)
Exemple #6
0
    def quota_limit_check(self, context, project_id, resources, deltas):
        # Ensure no value is less than zero
        unders = [key for key, val in deltas.items() if val < 0]
        if unders:
            raise exceptions.InvalidQuotaValue(unders=sorted(unders))

        current_limits = self.get_project_quotas(context, resources,
                                                 project_id)
        overs = set()
        for resource_name, delta in deltas.items():
            resource_limit = current_limits.get(resource_name)
            if resource_limit in (None, quota_api.UNLIMITED_QUOTA):
                continue

            resource_usage = self.get_resource_usage(context, project_id,
                                                     resources, resource_name)
            if resource_usage is None:
                continue

            if resource_usage + delta > resource_limit:
                overs.add(resource_name)

        if overs:
            raise exceptions.OverQuota(overs=sorted(overs))
Exemple #7
0
    def make_reservation(self, context, tenant_id, resources, deltas, plugin):
        # Lock current reservation table
        # NOTE(salv-orlando): This routine uses DB write locks.
        # These locks are acquired by the count() method invoked on resources.
        # Please put your shotguns aside.
        # A non locking algorithm for handling reservation is feasible, however
        # it will require two database writes even in cases when there are not
        # concurrent reservations.
        # For this reason it might be advisable to handle contention using
        # this kind of locks and paying the cost of a write set certification
        # failure when a MySQL Galera cluster is employed. Also, this class of
        # locks should be ok to use when support for sending "hotspot" writes
        # to a single node will be available.
        requested_resources = deltas.keys()
        with db_api.context_manager.writer.using(context):
            # get_tenant_quotes needs in input a dictionary mapping resource
            # name to BaseResosurce instances so that the default quota can be
            # retrieved
            current_limits = self.get_tenant_quotas(context, resources,
                                                    tenant_id)
            unlimited_resources = set([
                resource for (resource, limit) in current_limits.items()
                if limit < 0
            ])
            # Do not even bother counting resources and calculating headroom
            # for resources with unlimited quota
            LOG.debug(
                "Resources %s have unlimited quota limit. It is not "
                "required to calculate headroom ",
                ",".join(unlimited_resources))
            requested_resources = (set(requested_resources) -
                                   unlimited_resources)
            # Gather current usage information
            # TODO(salv-orlando): calling count() for every resource triggers
            # multiple queries on quota usage. This should be improved, however
            # this is not an urgent matter as the REST API currently only
            # allows allocation of a resource at a time
            # NOTE: pass plugin too for compatibility with CountableResource
            # instances
            current_usages = dict((resource, resources[resource].count(
                context, plugin, tenant_id, resync_usage=False))
                                  for resource in requested_resources)
            # Adjust for expired reservations. Apparently it is cheaper than
            # querying every time for active reservations and counting overall
            # quantity of resources reserved
            expired_deltas = quota_api.get_reservations_for_resources(
                context, tenant_id, requested_resources, expired=True)
            # Verify that the request can be accepted with current limits
            resources_over_limit = []
            for resource in requested_resources:
                expired_reservations = expired_deltas.get(resource, 0)
                total_usage = current_usages[resource] - expired_reservations
                res_headroom = current_limits[resource] - total_usage
                LOG.debug(
                    ("Attempting to reserve %(delta)d items for "
                     "resource %(resource)s. Total usage: %(total)d; "
                     "quota limit: %(limit)d; headroom:%(headroom)d"), {
                         'resource': resource,
                         'delta': deltas[resource],
                         'total': total_usage,
                         'limit': current_limits[resource],
                         'headroom': res_headroom
                     })
                if res_headroom < deltas[resource]:
                    resources_over_limit.append(resource)
                if expired_reservations:
                    self._handle_expired_reservations(context, tenant_id)

            if resources_over_limit:
                raise exceptions.OverQuota(overs=sorted(resources_over_limit))
            # Success, store the reservation
            # TODO(salv-orlando): Make expiration time configurable
            return quota_api.create_reservation(context, tenant_id, deltas)