Delete a quota through admin api.
Added 'extended-quotas' extension that has provides ability for admins to be able to delete a non-default quota (absolute limit) for a tenant, so that tenant's quota will revert back to the configured default. Implements blueprint admin-api-for-delete-quota Change-Id: I7375420a466823b3e099aebff71a8f7d7f922afb
This commit is contained in:
parent
af7048590d
commit
cdd998c418
@ -408,6 +408,14 @@
|
||||
"namespace": "http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1",
|
||||
"updated": "2012-03-12T00:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"alias": "os-extended-quotas",
|
||||
"description": "Adds ability for admins to delete quota",
|
||||
"links": [],
|
||||
"name": "ExtendedQuotas",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/quota-delete/api/v1.1",
|
||||
"updated": "2013-05-23T00:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"alias": "os-quota-sets",
|
||||
"description": "Quotas management support.",
|
||||
|
@ -171,6 +171,9 @@
|
||||
<extension alias="os-quota-class-sets" updated="2012-03-12T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1" name="QuotaClasses">
|
||||
<description>Quota classes management support.</description>
|
||||
</extension>
|
||||
<extension alias="os-extended-quotas" updated="2013-05-23T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/quota-delete/api/v1.1" name="ExtendedQuotas">
|
||||
<description>Adds ability for admins to delete quota.</description>
|
||||
</extension>
|
||||
<extension alias="os-quota-sets" updated="2011-08-08T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1" name="Quotas">
|
||||
<description>Quotas management support.</description>
|
||||
</extension>
|
||||
|
@ -80,6 +80,7 @@
|
||||
"compute_extension:networks_associate": "rule:admin_api",
|
||||
"compute_extension:quotas:show": "",
|
||||
"compute_extension:quotas:update": "rule:admin_api",
|
||||
"compute_extension:quotas:delete": "rule:admin_api",
|
||||
"compute_extension:quota_classes": "",
|
||||
"compute_extension:rescue": "",
|
||||
"compute_extension:security_group_default_rules": "rule:admin_api",
|
||||
|
25
nova/api/openstack/compute/contrib/extended_quotas.py
Normal file
25
nova/api/openstack/compute/contrib/extended_quotas.py
Normal file
@ -0,0 +1,25 @@
|
||||
# Copyright 2013 Rackspace Hosting
|
||||
# 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 nova.api.openstack import extensions
|
||||
|
||||
|
||||
class Extended_quotas(extensions.ExtensionDescriptor):
|
||||
"""Adds ability for admins to delete quota."""
|
||||
|
||||
name = "ExtendedQuotas"
|
||||
alias = "os-extended-quotas"
|
||||
namespace = "http://docs.openstack.org/compute/ext/quota-delete/api/v1.1"
|
||||
updated = "2013-05-23T00:00:00+00:00"
|
@ -33,6 +33,7 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
authorize_update = extensions.extension_authorizer('compute', 'quotas:update')
|
||||
authorize_show = extensions.extension_authorizer('compute', 'quotas:show')
|
||||
authorize_delete = extensions.extension_authorizer('compute', 'quotas:delete')
|
||||
|
||||
|
||||
class QuotaTemplate(xmlutil.TemplateBuilder):
|
||||
@ -49,6 +50,9 @@ class QuotaTemplate(xmlutil.TemplateBuilder):
|
||||
|
||||
class QuotaSetsController(object):
|
||||
|
||||
def __init__(self, ext_mgr):
|
||||
self.ext_mgr = ext_mgr
|
||||
|
||||
def _format_quota_set(self, project_id, quota_set):
|
||||
"""Convert the quota object to a result dict."""
|
||||
|
||||
@ -124,6 +128,18 @@ class QuotaSetsController(object):
|
||||
authorize_show(context)
|
||||
return self._format_quota_set(id, QUOTAS.get_defaults(context))
|
||||
|
||||
def delete(self, req, id):
|
||||
if self.ext_mgr.is_loaded('os-extended-quotas'):
|
||||
context = req.environ['nova.context']
|
||||
authorize_delete(context)
|
||||
try:
|
||||
nova.context.authorize_project_context(context, id)
|
||||
QUOTAS.destroy_all_by_project(context, id)
|
||||
return webob.Response(status_int=202)
|
||||
except exception.NotAuthorized:
|
||||
raise webob.exc.HTTPForbidden()
|
||||
raise webob.exc.HTTPNotFound()
|
||||
|
||||
|
||||
class Quotas(extensions.ExtensionDescriptor):
|
||||
"""Quotas management support."""
|
||||
@ -137,7 +153,7 @@ class Quotas(extensions.ExtensionDescriptor):
|
||||
resources = []
|
||||
|
||||
res = extensions.ResourceExtension('os-quota-sets',
|
||||
QuotaSetsController(),
|
||||
QuotaSetsController(self.ext_mgr),
|
||||
member_actions={'defaults': 'GET'})
|
||||
resources.append(res)
|
||||
|
||||
|
@ -19,7 +19,10 @@ from lxml import etree
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.compute.contrib import quotas
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import context as context_maker
|
||||
from nova import quota
|
||||
from nova import test
|
||||
from nova.tests.api.openstack import fakes
|
||||
|
||||
@ -37,7 +40,8 @@ class QuotaSetsTest(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(QuotaSetsTest, self).setUp()
|
||||
self.controller = quotas.QuotaSetsController()
|
||||
self.ext_mgr = self.mox.CreateMock(extensions.ExtensionManager)
|
||||
self.controller = quotas.QuotaSetsController(self.ext_mgr)
|
||||
|
||||
def test_format_quota_set(self):
|
||||
raw_quota_set = {
|
||||
@ -201,6 +205,33 @@ class QuotaSetsTest(test.TestCase):
|
||||
res_dict = self.controller.update(req, 'update_me', body)
|
||||
self.assertEqual(res_dict, expected_resp)
|
||||
|
||||
def test_delete_quotas_when_extension_not_loaded(self):
|
||||
self.ext_mgr.is_loaded('os-extended-quotas').AndReturn(False)
|
||||
self.mox.ReplayAll()
|
||||
req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/1234')
|
||||
self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
|
||||
req, 1234)
|
||||
|
||||
def test_quotas_delete_as_unauthorized_user(self):
|
||||
self.ext_mgr.is_loaded('os-extended-quotas').AndReturn(True)
|
||||
self.mox.ReplayAll()
|
||||
req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/1234')
|
||||
self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete,
|
||||
req, 1234)
|
||||
|
||||
def test_quotas_delete_as_admin(self):
|
||||
context = context_maker.get_admin_context()
|
||||
self.req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/1234')
|
||||
self.req.environ['nova.context'] = context
|
||||
self.ext_mgr.is_loaded('os-extended-quotas').AndReturn(True)
|
||||
self.mox.StubOutWithMock(quota.QUOTAS,
|
||||
"destroy_all_by_project")
|
||||
quota.QUOTAS.destroy_all_by_project(context, 1234)
|
||||
self.mox.ReplayAll()
|
||||
res = self.controller.delete(self.req, 1234)
|
||||
self.mox.VerifyAll()
|
||||
self.assertEqual(res.status_int, 202)
|
||||
|
||||
|
||||
class QuotaXMLSerializerTest(test.TestCase):
|
||||
def setUp(self):
|
||||
|
@ -195,6 +195,7 @@ class ExtensionControllerTest(ExtensionTestCase):
|
||||
"MultipleCreate",
|
||||
"QuotaClasses",
|
||||
"Quotas",
|
||||
"ExtendedQuotas",
|
||||
"Rescue",
|
||||
"SchedulerHints",
|
||||
"SecurityGroupDefaultRules",
|
||||
|
@ -159,6 +159,7 @@ policy_data = """
|
||||
"compute_extension:os-tenant-networks": "",
|
||||
"compute_extension:quotas:show": "",
|
||||
"compute_extension:quotas:update": "",
|
||||
"compute_extension:quotas:delete": "",
|
||||
"compute_extension:quota_classes": "",
|
||||
"compute_extension:rescue": "",
|
||||
"compute_extension:security_group_default_rules": "",
|
||||
|
@ -416,6 +416,14 @@
|
||||
"namespace": "http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1",
|
||||
"updated": "%(timestamp)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-extended-quotas",
|
||||
"description": "%(text)s",
|
||||
"links": [],
|
||||
"name": "ExtendedQuotas",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/quota-delete/api/v1.1",
|
||||
"updated": "%(timestamp)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-quota-sets",
|
||||
"description": "%(text)s",
|
||||
|
@ -156,6 +156,9 @@
|
||||
<extension alias="os-quota-class-sets" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1" name="QuotaClasses">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-extended-quotas" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/quota-delete/api/v1.1" name="ExtendedQuotas">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-quota-sets" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1" name="Quotas">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
|
@ -2277,6 +2277,22 @@ class QuotasSampleXmlTests(QuotasSampleJsonTests):
|
||||
ctype = "xml"
|
||||
|
||||
|
||||
class ExtendedQuotasSampleJsonTests(ApiSampleTestBase):
|
||||
extends_name = "nova.api.openstack.compute.contrib.quotas.Quotas"
|
||||
extension_name = ("nova.api.openstack.compute.contrib"
|
||||
".extended_quotas.Extended_quotas")
|
||||
|
||||
def test_delete_quotas(self):
|
||||
# Get api sample to delete quota.
|
||||
response = self._do_delete('os-quota-sets/fake_tenant')
|
||||
self.assertEqual(response.status, 202)
|
||||
self.assertEqual(response.read(), '')
|
||||
|
||||
|
||||
class ExtendedQuotasSampleXmlTests(ExtendedQuotasSampleJsonTests):
|
||||
ctype = "xml"
|
||||
|
||||
|
||||
class ExtendedIpsSampleJsonTests(ServersSampleBase):
|
||||
extension_name = ("nova.api.openstack.compute.contrib"
|
||||
".extended_ips.Extended_ips")
|
||||
|
Loading…
Reference in New Issue
Block a user