# Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutron_lib.api import converters from neutron_lib.api import extensions as api_extensions from neutron_lib.api import faults from neutron_lib.db import constants as const from neutron_lib import exceptions as n_exc from neutron_lib.plugins import directory from oslo_config import cfg from oslo_utils import importutils import webob from neutron._i18n import _ from neutron.api import extensions from neutron.api.v2 import base from neutron.api.v2 import resource from neutron.common import exceptions from neutron import quota from neutron.quota import resource_registry from neutron import wsgi DEFAULT_QUOTAS_ACTION = 'default' RESOURCE_NAME = 'quota' RESOURCE_COLLECTION = RESOURCE_NAME + "s" QUOTAS = quota.QUOTAS DB_QUOTA_DRIVER = 'neutron.db.quota.driver.DbQuotaDriver' EXTENDED_ATTRIBUTES_2_0 = { RESOURCE_COLLECTION: {} } class QuotaSetsController(wsgi.Controller): def __init__(self, plugin): self._resource_name = RESOURCE_NAME self._plugin = plugin self._driver = importutils.import_class( cfg.CONF.QUOTAS.quota_driver ) self._update_extended_attributes = True def _update_attributes(self): for quota_resource in resource_registry.get_all_resources().keys(): attr_dict = EXTENDED_ATTRIBUTES_2_0[RESOURCE_COLLECTION] attr_dict[quota_resource] = { 'allow_post': False, 'allow_put': True, 'convert_to': converters.convert_to_int, 'validate': {'type:range': [-1, const.DB_INTEGER_MAX_VALUE]}, 'is_visible': True} self._update_extended_attributes = False def _get_quotas(self, request, tenant_id): return self._driver.get_tenant_quotas( request.context, resource_registry.get_all_resources(), tenant_id) def default(self, request, id): if id != request.context.tenant_id: self._check_admin(request.context, reason=_("Only admin is authorized " "to access quotas for another tenant")) return {self._resource_name: self._driver.get_default_quotas( context=request.context, resources=resource_registry.get_all_resources(), tenant_id=id)} def create(self, request, body=None): msg = _('POST requests are not supported on this resource.') raise webob.exc.HTTPNotImplemented(msg) def index(self, request): context = request.context self._check_admin(context) return {self._resource_name + "s": self._driver.get_all_quotas( context, resource_registry.get_all_resources())} def tenant(self, request): """Retrieve the tenant info in context.""" context = request.context if not context.tenant_id: raise exceptions.QuotaMissingTenant() return {'tenant': {'tenant_id': context.tenant_id}} def show(self, request, id): if id != request.context.tenant_id: self._check_admin(request.context, reason=_("Only admin is authorized " "to access quotas for another tenant")) return {self._resource_name: self._get_quotas(request, id)} def _check_admin(self, context, reason=_("Only admin can view or configure quota")): if not context.is_admin: raise n_exc.AdminRequired(reason=reason) def delete(self, request, id): self._check_admin(request.context) self._driver.delete_tenant_quota(request.context, id) def update(self, request, id, body=None): self._check_admin(request.context) if self._update_extended_attributes: self._update_attributes() body = base.Controller.prepare_request_body( request.context, body, False, self._resource_name, EXTENDED_ATTRIBUTES_2_0[RESOURCE_COLLECTION]) for key, value in body[self._resource_name].items(): self._driver.update_quota_limit(request.context, id, key, value) return {self._resource_name: self._get_quotas(request, id)} class Quotasv2(api_extensions.ExtensionDescriptor): """Quotas management support.""" extensions.register_custom_supported_check( RESOURCE_COLLECTION, lambda: True, plugin_agnostic=True) @classmethod def get_name(cls): return "Quota management support" @classmethod def get_alias(cls): return RESOURCE_COLLECTION @classmethod def get_description(cls): description = 'Expose functions for quotas management' if cfg.CONF.QUOTAS.quota_driver == DB_QUOTA_DRIVER: description += ' per tenant' return description @classmethod def get_updated(cls): return "2012-07-29T10:00:00-00:00" @classmethod def get_resources(cls): """Returns Ext Resources.""" controller = resource.Resource( QuotaSetsController(directory.get_plugin()), faults=faults.FAULT_MAP) return [extensions.ResourceExtension( Quotasv2.get_alias(), controller, member_actions={DEFAULT_QUOTAS_ACTION: 'GET'}, collection_actions={'tenant': 'GET'})] def get_extended_resources(self, version): if version == "2.0": return EXTENDED_ATTRIBUTES_2_0 else: return {}