OpenStack Networking (Neutron)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

179 lines
6.1 KiB

  1. # Copyright 2011 OpenStack Foundation.
  2. # All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. from neutron_lib.api import converters
  16. from neutron_lib.api import extensions as api_extensions
  17. from neutron_lib.api import faults
  18. from neutron_lib.db import constants as const
  19. from neutron_lib import exceptions
  20. from neutron_lib.plugins import directory
  21. from oslo_config import cfg
  22. from oslo_log import log as logging
  23. from oslo_utils import importutils
  24. import webob
  25. from neutron._i18n import _
  26. from neutron.api import extensions
  27. from neutron.api.v2 import base
  28. from neutron.api.v2 import resource
  29. from neutron import policy
  30. from neutron import quota
  31. from neutron.quota import resource_registry
  32. from neutron import wsgi
  33. DEFAULT_QUOTAS_ACTION = 'default'
  34. RESOURCE_NAME = 'quota'
  35. RESOURCE_COLLECTION = RESOURCE_NAME + "s"
  36. QUOTAS = quota.QUOTAS
  37. DB_QUOTA_DRIVER = 'neutron.db.quota.driver.DbQuotaDriver'
  38. EXTENDED_ATTRIBUTES_2_0 = {
  39. RESOURCE_COLLECTION: {}
  40. }
  41. LOG = logging.getLogger(__name__)
  42. def validate_policy(context, policy_name):
  43. policy.init()
  44. policy.enforce(context,
  45. policy_name,
  46. target={'project_id': context.project_id},
  47. plugin=None)
  48. class QuotaSetsController(wsgi.Controller):
  49. def __init__(self, plugin):
  50. self._resource_name = RESOURCE_NAME
  51. self._plugin = plugin
  52. self._driver = importutils.import_class(
  53. cfg.CONF.QUOTAS.quota_driver
  54. )
  55. self._update_extended_attributes = True
  56. def _update_attributes(self):
  57. for quota_resource in resource_registry.get_all_resources().keys():
  58. attr_dict = EXTENDED_ATTRIBUTES_2_0[RESOURCE_COLLECTION]
  59. attr_dict[quota_resource] = {
  60. 'allow_post': False,
  61. 'allow_put': True,
  62. 'convert_to': converters.convert_to_int,
  63. 'validate': {'type:range': [-1, const.DB_INTEGER_MAX_VALUE]},
  64. 'is_visible': True}
  65. self._update_extended_attributes = False
  66. def _get_quotas(self, request, tenant_id):
  67. return self._driver.get_tenant_quotas(
  68. request.context,
  69. resource_registry.get_all_resources(),
  70. tenant_id)
  71. def default(self, request, id):
  72. context = request.context
  73. if id != context.tenant_id:
  74. validate_policy(context, "get_quota")
  75. return {self._resource_name: self._driver.get_default_quotas(
  76. context=context,
  77. resources=resource_registry.get_all_resources(),
  78. tenant_id=id)}
  79. def create(self, request, body=None):
  80. msg = _('POST requests are not supported on this resource.')
  81. raise webob.exc.HTTPNotImplemented(msg)
  82. def index(self, request):
  83. context = request.context
  84. validate_policy(context, "get_quota")
  85. return {self._resource_name + "s":
  86. self._driver.get_all_quotas(
  87. context, resource_registry.get_all_resources())}
  88. def tenant(self, request):
  89. """Retrieve the tenant info in context."""
  90. context = request.context
  91. if not context.tenant_id:
  92. raise exceptions.QuotaMissingTenant()
  93. return {'tenant': {'tenant_id': context.tenant_id}}
  94. def show(self, request, id):
  95. if id != request.context.tenant_id:
  96. validate_policy(request.context, "get_quota")
  97. return {self._resource_name: self._get_quotas(request, id)}
  98. def delete(self, request, id):
  99. validate_policy(request.context, "delete_quota")
  100. self._driver.delete_tenant_quota(request.context, id)
  101. def update(self, request, id, body=None):
  102. validate_policy(request.context, "update_quota")
  103. if self._update_extended_attributes:
  104. self._update_attributes()
  105. try:
  106. body = base.Controller.prepare_request_body(
  107. request.context, body, False, self._resource_name,
  108. EXTENDED_ATTRIBUTES_2_0[RESOURCE_COLLECTION])
  109. except Exception as e:
  110. LOG.warning(
  111. "An exception happened while processing the request "
  112. "body. The exception message is [%s].", e)
  113. raise e
  114. for key, value in body[self._resource_name].items():
  115. self._driver.update_quota_limit(request.context, id, key, value)
  116. return {self._resource_name: self._get_quotas(request, id)}
  117. class Quotasv2(api_extensions.ExtensionDescriptor):
  118. """Quotas management support."""
  119. extensions.register_custom_supported_check(
  120. RESOURCE_COLLECTION, lambda: True, plugin_agnostic=True)
  121. @classmethod
  122. def get_name(cls):
  123. return "Quota management support"
  124. @classmethod
  125. def get_alias(cls):
  126. return RESOURCE_COLLECTION
  127. @classmethod
  128. def get_description(cls):
  129. description = 'Expose functions for quotas management'
  130. if cfg.CONF.QUOTAS.quota_driver == DB_QUOTA_DRIVER:
  131. description += ' per tenant'
  132. return description
  133. @classmethod
  134. def get_updated(cls):
  135. return "2012-07-29T10:00:00-00:00"
  136. @classmethod
  137. def get_resources(cls):
  138. """Returns Ext Resources."""
  139. controller = resource.Resource(
  140. QuotaSetsController(directory.get_plugin()),
  141. faults=faults.FAULT_MAP)
  142. return [extensions.ResourceExtension(
  143. Quotasv2.get_alias(),
  144. controller,
  145. member_actions={DEFAULT_QUOTAS_ACTION: 'GET'},
  146. collection_actions={'tenant': 'GET'})]
  147. def get_extended_resources(self, version):
  148. if version == "2.0":
  149. return EXTENDED_ATTRIBUTES_2_0
  150. else:
  151. return {}