Merge "Remove quota classes extension from the V3 API"
This commit is contained in:
commit
3ca3dce140
@ -1,14 +0,0 @@
|
||||
{
|
||||
"quota_class_set": {
|
||||
"cores": 20,
|
||||
"fixed_ips": -1,
|
||||
"floating_ips": 10,
|
||||
"id": "test_class",
|
||||
"instances": 10,
|
||||
"key_pairs": 100,
|
||||
"metadata_items": 128,
|
||||
"ram": 51200,
|
||||
"security_group_rules": 20,
|
||||
"security_groups": 10
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"quota_class_set": {
|
||||
"instances": 50,
|
||||
"cores": 50,
|
||||
"ram": 51200,
|
||||
"floating_ips": 10,
|
||||
"fixed_ips": -1,
|
||||
"metadata_items": 128,
|
||||
"security_groups": 10,
|
||||
"security_group_rules": 20,
|
||||
"key_pairs": 100
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"quota_class_set": {
|
||||
"cores": 50,
|
||||
"fixed_ips": -1,
|
||||
"floating_ips": 10,
|
||||
"id": "test_class",
|
||||
"instances": 50,
|
||||
"key_pairs": 100,
|
||||
"metadata_items": 128,
|
||||
"ram": 51200,
|
||||
"security_group_rules": 20,
|
||||
"security_groups": 10
|
||||
}
|
||||
}
|
@ -194,8 +194,6 @@
|
||||
"compute_extension:v3:os-quota-sets:delete": "rule:admin_api",
|
||||
"compute_extension:v3:os-quota-sets:detail": "rule:admin_api",
|
||||
"compute_extension:quota_classes": "",
|
||||
"compute_extension:v3:os-quota-class-sets": "",
|
||||
"compute_extension:v3:os-quota-class-sets:discoverable": "",
|
||||
"compute_extension:rescue": "",
|
||||
"compute_extension:v3:os-rescue": "",
|
||||
"compute_extension:v3:os-rescue:discoverable": "",
|
||||
|
@ -1,98 +0,0 @@
|
||||
# Copyright 2012 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.
|
||||
|
||||
import webob
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
import nova.context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import quota
|
||||
from nova import utils
|
||||
|
||||
|
||||
QUOTAS = quota.QUOTAS
|
||||
FILTERED_QUOTAS = ['injected_files', 'injected_file_content_bytes',
|
||||
'injected_file_path_bytes']
|
||||
ALIAS = "os-quota-class-sets"
|
||||
authorize = extensions.extension_authorizer('compute', 'v3:' + ALIAS)
|
||||
|
||||
|
||||
class QuotaClassSetsController(wsgi.Controller):
|
||||
|
||||
def _format_quota_set(self, quota_class, quota_set):
|
||||
"""Convert the quota object to a result dict."""
|
||||
|
||||
result = dict(id=str(quota_class))
|
||||
|
||||
for resource in QUOTAS.resources:
|
||||
if resource not in FILTERED_QUOTAS:
|
||||
result[resource] = quota_set[resource]
|
||||
|
||||
return dict(quota_class_set=result)
|
||||
|
||||
@extensions.expected_errors(403)
|
||||
def show(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
try:
|
||||
nova.context.authorize_quota_class_context(context, id)
|
||||
return self._format_quota_set(id,
|
||||
QUOTAS.get_class_quotas(context, id))
|
||||
except exception.NotAuthorized:
|
||||
raise webob.exc.HTTPForbidden()
|
||||
|
||||
@extensions.expected_errors((400, 403))
|
||||
def update(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
quota_class = id
|
||||
if not self.is_valid_body(body, 'quota_class_set'):
|
||||
raise webob.exc.HTTPBadRequest("The request body invalid")
|
||||
quota_class_set = body['quota_class_set']
|
||||
for key in quota_class_set.keys():
|
||||
if key in QUOTAS and key not in FILTERED_QUOTAS:
|
||||
try:
|
||||
value = utils.validate_integer(
|
||||
body['quota_class_set'][key], key)
|
||||
except exception.InvalidInput as e:
|
||||
raise webob.exc.HTTPBadRequest(
|
||||
explanation=e.format_message())
|
||||
try:
|
||||
db.quota_class_update(context, quota_class, key, value)
|
||||
except exception.QuotaClassNotFound:
|
||||
db.quota_class_create(context, quota_class, key, value)
|
||||
except exception.AdminRequired:
|
||||
raise webob.exc.HTTPForbidden()
|
||||
return self._format_quota_set(
|
||||
quota_class,
|
||||
QUOTAS.get_class_quotas(context, quota_class))
|
||||
|
||||
|
||||
class QuotaClasses(extensions.V3APIExtensionBase):
|
||||
"""Quota classes management support."""
|
||||
|
||||
name = "QuotaClasses"
|
||||
alias = ALIAS
|
||||
version = 1
|
||||
|
||||
def get_resources(self):
|
||||
resources = [
|
||||
extensions.ResourceExtension(ALIAS, QuotaClassSetsController())]
|
||||
return resources
|
||||
|
||||
def get_controller_extensions(self):
|
||||
return []
|
@ -1,136 +0,0 @@
|
||||
# Copyright 2012 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.
|
||||
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.compute.plugins.v3 import quota_classes
|
||||
from nova import test
|
||||
from nova.tests.api.openstack import fakes
|
||||
|
||||
|
||||
def quota_set(class_name):
|
||||
return {'quota_class_set': {'id': class_name, 'metadata_items': 128,
|
||||
'ram': 51200, 'floating_ips': 10,
|
||||
'fixed_ips': -1, 'instances': 10,
|
||||
'cores': 20,
|
||||
'security_groups': 10,
|
||||
'security_group_rules': 20, 'key_pairs': 100}}
|
||||
|
||||
|
||||
class QuotaClassSetsTest(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(QuotaClassSetsTest, self).setUp()
|
||||
self.controller = quota_classes.QuotaClassSetsController()
|
||||
|
||||
def test_format_quota_set(self):
|
||||
raw_quota_set = {
|
||||
'instances': 10,
|
||||
'cores': 20,
|
||||
'ram': 51200,
|
||||
'floating_ips': 10,
|
||||
'fixed_ips': -1,
|
||||
'metadata_items': 128,
|
||||
'security_groups': 10,
|
||||
'security_group_rules': 20,
|
||||
'key_pairs': 100,
|
||||
}
|
||||
|
||||
quota_set = self.controller._format_quota_set('test_class',
|
||||
raw_quota_set)
|
||||
qs = quota_set['quota_class_set']
|
||||
|
||||
self.assertEqual(qs['id'], 'test_class')
|
||||
self.assertEqual(qs['instances'], 10)
|
||||
self.assertEqual(qs['cores'], 20)
|
||||
self.assertEqual(qs['ram'], 51200)
|
||||
self.assertEqual(qs['floating_ips'], 10)
|
||||
self.assertEqual(qs['fixed_ips'], -1)
|
||||
self.assertEqual(qs['metadata_items'], 128)
|
||||
self.assertEqual(qs['security_groups'], 10)
|
||||
self.assertEqual(qs['security_group_rules'], 20)
|
||||
self.assertEqual(qs['key_pairs'], 100)
|
||||
|
||||
def test_quotas_show_as_admin(self):
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class',
|
||||
use_admin_context=True)
|
||||
res_dict = self.controller.show(req, 'test_class')
|
||||
|
||||
self.assertEqual(res_dict, quota_set('test_class'))
|
||||
|
||||
def test_quotas_show_as_unauthorized_user(self):
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class')
|
||||
self.assertRaises(webob.exc.HTTPForbidden, self.controller.show,
|
||||
req, 'test_class')
|
||||
|
||||
def test_quotas_update_as_admin(self):
|
||||
req_body = {'quota_class_set': {'instances': 10, 'cores': 20,
|
||||
'ram': 51200, 'floating_ips': 10,
|
||||
'fixed_ips': -1, 'metadata_items': 128,
|
||||
'security_groups': 10,
|
||||
'security_group_rules': 20,
|
||||
'key_pairs': 100}}
|
||||
res_body = quota_set('test_class')
|
||||
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class',
|
||||
use_admin_context=True)
|
||||
res_dict = self.controller.update(req, 'test_class', req_body)
|
||||
|
||||
self.assertEqual(res_body, res_dict)
|
||||
|
||||
def test_quotas_update_with_non_integer(self):
|
||||
body = {'quota_class_set': {'instances': "abc"}}
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class',
|
||||
use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
req, 'test_class', body)
|
||||
|
||||
body = {'quota_class_set': {'instances': 50.5}}
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class',
|
||||
use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
req, 'test_class', body)
|
||||
|
||||
body = {'quota_class_set': {
|
||||
'instances': u'\u30aa\u30fc\u30d7\u30f3'}}
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class',
|
||||
use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
req, 'test_class', body)
|
||||
|
||||
def test_quotas_update_with_invalid_body(self):
|
||||
body = {'quota_class_set': None}
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class',
|
||||
use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
req, 'test_class', body)
|
||||
body = {}
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class',
|
||||
use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
req, 'test_class', body)
|
||||
|
||||
def test_quotas_update_as_user(self):
|
||||
body = {'quota_class_set': {'instances': 50, 'cores': 50,
|
||||
'ram': 51200, 'floating_ips': 10,
|
||||
'fixed_ips': -1, 'metadata_items': 128,
|
||||
'security_groups': 10,
|
||||
'security_group_rules': 20,
|
||||
'key_pairs': 100,
|
||||
}}
|
||||
|
||||
req = fakes.HTTPRequestV3.blank('/os-quota-class-sets/test_class')
|
||||
self.assertRaises(webob.exc.HTTPForbidden, self.controller.update,
|
||||
req, 'test_class', body)
|
@ -246,7 +246,6 @@ policy_data = """
|
||||
"compute_extension:v3:os-quota-sets:delete": "",
|
||||
"compute_extension:v3:os-quota-sets:detail": "",
|
||||
"compute_extension:quota_classes": "",
|
||||
"compute_extension:v3:os-quota-class-sets": "",
|
||||
"compute_extension:rescue": "",
|
||||
"compute_extension:v3:os-rescue": "",
|
||||
"compute_extension:security_group_default_rules": "",
|
||||
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"quota_class_set": {
|
||||
"cores": 20,
|
||||
"floating_ips": 10,
|
||||
"fixed_ips": -1,
|
||||
"id": "%(set_id)s",
|
||||
"instances": 10,
|
||||
"key_pairs": 100,
|
||||
"metadata_items": 128,
|
||||
"ram": 51200,
|
||||
"security_group_rules": 20,
|
||||
"security_groups": 10
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"quota_class_set": {
|
||||
"instances": 50,
|
||||
"cores": 50,
|
||||
"ram": 51200,
|
||||
"floating_ips": 10,
|
||||
"fixed_ips": -1,
|
||||
"metadata_items": 128,
|
||||
"security_groups": 10,
|
||||
"security_group_rules": 20,
|
||||
"key_pairs": 100
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"quota_class_set": {
|
||||
"cores": 50,
|
||||
"floating_ips": 10,
|
||||
"fixed_ips": -1,
|
||||
"instances": 50,
|
||||
"key_pairs": 100,
|
||||
"metadata_items": 128,
|
||||
"ram": 51200,
|
||||
"security_group_rules": 20,
|
||||
"security_groups": 10,
|
||||
"id": "test_class"
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
# Copyright 2012 Nebula, Inc.
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# 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.tests.integrated.v3 import api_sample_base
|
||||
|
||||
|
||||
class QuotaClassesSampleJsonTests(api_sample_base.ApiSampleTestBaseV3):
|
||||
extension_name = "os-quota-class-sets"
|
||||
set_id = 'test_class'
|
||||
|
||||
def test_show_quota_classes(self):
|
||||
# Get api sample to show quota classes.
|
||||
response = self._do_get('os-quota-class-sets/%s' % self.set_id)
|
||||
subs = {'set_id': self.set_id}
|
||||
self._verify_response('quota-classes-show-get-resp', subs,
|
||||
response, 200)
|
||||
|
||||
def test_update_quota_classes(self):
|
||||
# Get api sample to update quota classes.
|
||||
response = self._do_put('os-quota-class-sets/%s' % self.set_id,
|
||||
'quota-classes-update-post-req',
|
||||
{})
|
||||
self._verify_response('quota-classes-update-post-resp',
|
||||
{}, response, 200)
|
@ -94,7 +94,6 @@ nova.api.v3.extensions =
|
||||
multiple_create = nova.api.openstack.compute.plugins.v3.multiple_create:MultipleCreate
|
||||
pause_server = nova.api.openstack.compute.plugins.v3.pause_server:PauseServer
|
||||
pci = nova.api.openstack.compute.plugins.v3.pci:Pci
|
||||
quota_classes = nova.api.openstack.compute.plugins.v3.quota_classes:QuotaClasses
|
||||
quota_sets = nova.api.openstack.compute.plugins.v3.quota_sets:QuotaSets
|
||||
remote_consoles = nova.api.openstack.compute.plugins.v3.remote_consoles:RemoteConsoles
|
||||
rescue = nova.api.openstack.compute.plugins.v3.rescue:Rescue
|
||||
|
Loading…
Reference in New Issue
Block a user