]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Show default configuration Quotas
authorGary Kotton <gkotton@redhat.com>
Mon, 4 Mar 2013 10:21:28 +0000 (10:21 +0000)
committerGary Kotton <gkotton@redhat.com>
Thu, 7 Mar 2013 07:20:25 +0000 (07:20 +0000)
Fixes bug 1144076

The patch set shows the defualt quotas that exist in
the configuration file. This is if the DB_QUOTA_DRIVER
is not configured. In this case the user is required
to update the configuration file and restart the service.

Change-Id: I5517c0215e8cfa71453ee38c34d8249e74346fdf

quantum/extensions/quotasv2.py
quantum/quota.py
quantum/tests/unit/test_quota_per_tenant_ext.py

index e68b791e6b50af0dc50b1f57f9dc8ad3a0e330a4..41a95018eac80be097eb8a48f08126c7b58df0da 100644 (file)
@@ -41,7 +41,7 @@ class QuotaSetsController(wsgi.Controller):
     def __init__(self, plugin):
         self._resource_name = RESOURCE_NAME
         self._plugin = plugin
-        self._driver = importutils.import_class(DB_QUOTA_DRIVER)
+        self._driver = importutils.import_class(cfg.CONF.QUOTAS.quota_driver)
         self._update_extended_attributes = True
 
     def _update_attributes(self):
@@ -56,7 +56,7 @@ class QuotaSetsController(wsgi.Controller):
     def _get_body(self, request):
         body = self._deserialize(request.body,
                                  request.best_match_content_type())
-        if self._update_extended_attributes is True:
+        if self._update_extended_attributes:
             self._update_attributes()
 
         attr_info = EXTENDED_ATTRIBUTES_2_0[RESOURCE_COLLECTION]
@@ -69,7 +69,7 @@ class QuotaSetsController(wsgi.Controller):
             request.context, QUOTAS.resources, tenant_id)
 
     def create(self, request, body=None):
-        raise NotImplementedError()
+        raise webob.exc.HTTPNotImplemented()
 
     def index(self, request):
         context = request.context
@@ -127,7 +127,7 @@ class Quotasv2(extensions.ExtensionDescriptor):
 
     @classmethod
     def get_name(cls):
-        return "Quotas for each tenant"
+        return "Quota management support"
 
     @classmethod
     def get_alias(cls):
@@ -135,8 +135,10 @@ class Quotasv2(extensions.ExtensionDescriptor):
 
     @classmethod
     def get_description(cls):
-        return ("Expose functions for cloud admin to update quotas"
-                "for each tenant")
+        description = 'Expose functions for quotas management'
+        if cfg.CONF.QUOTAS.quota_driver == DB_QUOTA_DRIVER:
+            description += ' per tenant'
+        return description
 
     @classmethod
     def get_namespace(cls):
@@ -160,8 +162,3 @@ class Quotasv2(extensions.ExtensionDescriptor):
             return EXTENDED_ATTRIBUTES_2_0
         else:
             return {}
-
-    def check_env(self):
-        if cfg.CONF.QUOTAS.quota_driver != DB_QUOTA_DRIVER:
-            msg = _('Quota driver %s is needed.') % DB_QUOTA_DRIVER
-            raise exceptions.InvalidExtenstionEnv(reason=msg)
index 217fdeec5f75e91e4e8d55e255a134f19401edaf..2a9d4f0112df72c78f301480f2e1875cae379d49 100644 (file)
@@ -17,6 +17,7 @@
 """Quotas for instances, volumes, and floating ips."""
 
 from oslo.config import cfg
+import webob
 
 from quantum.common import exceptions
 from quantum.openstack.common import importutils
@@ -124,6 +125,26 @@ class ConfDriver(object):
             raise exceptions.OverQuota(overs=sorted(overs), quotas=quotas,
                                        usages={})
 
+    @staticmethod
+    def get_tenant_quotas(context, resources, tenant_id):
+        quotas = {}
+        sub_resources = dict((k, v) for k, v in resources.items())
+        for resource in sub_resources.values():
+            quotas[resource.name] = resource.default
+        return quotas
+
+    @staticmethod
+    def get_all_quotas(context, resources):
+        return []
+
+    @staticmethod
+    def delete_tenant_quota(context, tenant_id):
+        raise webob.exc.HTTPForbidden()
+
+    @staticmethod
+    def update_quota_limit(context, tenant_id, resource, limit):
+        raise webob.exc.HTTPForbidden()
+
 
 class BaseResource(object):
     """Describe a single resource for quota checking."""
index d86b0e6b1ed23542e77b297fd8d513db776c3ab9..0006562e293ad894f4b32a98ea4f1947c8e72205 100644 (file)
@@ -213,3 +213,106 @@ class QuotaExtensionTestCase(testlib_api.WebTestCase):
 
 class QuotaExtensionTestCaseXML(QuotaExtensionTestCase):
     fmt = 'xml'
+
+
+class QuotaExtensionCfgTestCase(testlib_api.WebTestCase):
+    fmt = 'json'
+
+    def setUp(self):
+        super(QuotaExtensionCfgTestCase, self).setUp()
+        db._ENGINE = None
+        db._MAKER = None
+        # Ensure 'stale' patched copies of the plugin are never returned
+        manager.QuantumManager._instance = None
+
+        # Ensure existing ExtensionManager is not used
+        extensions.PluginAwareExtensionManager._instance = None
+
+        # Save the global RESOURCE_ATTRIBUTE_MAP
+        self.saved_attr_map = {}
+        for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems():
+            self.saved_attr_map[resource] = attrs.copy()
+
+        # Create the default configurations
+        args = ['--config-file', test_extensions.etcdir('quantum.conf.test')]
+        config.parse(args=args)
+
+        # Update the plugin and extensions path
+        cfg.CONF.set_override('core_plugin', TARGET_PLUGIN)
+        cfg.CONF.set_override(
+            'quota_items',
+            ['network', 'subnet', 'port', 'extra1'],
+            group='QUOTAS')
+        quota.QUOTAS = quota.QuotaEngine()
+        quota.register_resources_from_config()
+        self._plugin_patcher = mock.patch(TARGET_PLUGIN, autospec=True)
+        self.plugin = self._plugin_patcher.start()
+        self.plugin.return_value.supported_extension_aliases = ['quotas']
+        # QUOTAS will regester the items in conf when starting
+        # extra1 here is added later, so have to do it manually
+        quota.QUOTAS.register_resource_by_name('extra1')
+        ext_mgr = extensions.PluginAwareExtensionManager.get_instance()
+        l2network_db_v2.initialize()
+        app = config.load_paste_app('extensions_test_app')
+        ext_middleware = extensions.ExtensionMiddleware(app, ext_mgr=ext_mgr)
+        self.api = webtest.TestApp(ext_middleware)
+        super(QuotaExtensionCfgTestCase, self).setUp()
+
+    def tearDown(self):
+        self._plugin_patcher.stop()
+        self.api = None
+        self.plugin = None
+        db._ENGINE = None
+        db._MAKER = None
+        cfg.CONF.reset()
+
+        # Restore the global RESOURCE_ATTRIBUTE_MAP
+        attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map
+        super(QuotaExtensionCfgTestCase, self).tearDown()
+
+    def test_quotas_default_values(self):
+        tenant_id = 'tenant_id1'
+        env = {'quantum.context': context.Context('', tenant_id)}
+        res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
+                           extra_environ=env)
+        quota = self.deserialize(res)
+        self.assertEqual(10, quota['quota']['network'])
+        self.assertEqual(10, quota['quota']['subnet'])
+        self.assertEqual(50, quota['quota']['port'])
+        self.assertEqual(-1, quota['quota']['extra1'])
+
+    def test_show_quotas_with_admin(self):
+        tenant_id = 'tenant_id1'
+        env = {'quantum.context': context.Context('', tenant_id + '2',
+                                                  is_admin=True)}
+        res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
+                           extra_environ=env)
+        self.assertEqual(200, res.status_int)
+
+    def test_show_quotas_without_admin_forbidden(self):
+        tenant_id = 'tenant_id1'
+        env = {'quantum.context': context.Context('', tenant_id + '2',
+                                                  is_admin=False)}
+        res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
+                           extra_environ=env, expect_errors=True)
+        self.assertEqual(403, res.status_int)
+
+    def test_update_quotas_forbidden(self):
+        tenant_id = 'tenant_id1'
+        quotas = {'quota': {'network': 100}}
+        res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt),
+                           self.serialize(quotas),
+                           expect_errors=True)
+        self.assertEqual(403, res.status_int)
+
+    def test_delete_quotas_forbidden(self):
+        tenant_id = 'tenant_id1'
+        env = {'quantum.context': context.Context('', tenant_id,
+                                                  is_admin=False)}
+        res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt),
+                              extra_environ=env, expect_errors=True)
+        self.assertEqual(403, res.status_int)
+
+
+class QuotaExtensionCfgTestCaseXML(QuotaExtensionCfgTestCase):
+    fmt = 'xml'