Ensure bulk creations have quota validations
Fixes bug 1093749 The patch set also returns a proper error instead of a internal server error when the quotas are reached. Change-Id: Ifc74ffa8b54faa70f5558bf5263830f5e71f58ae
This commit is contained in:
parent
5e4368b32f
commit
164db207fd
@ -49,6 +49,7 @@ FAULT_MAP = {exceptions.NotFound: webob.exc.HTTPNotFound,
|
|||||||
AttributeError: webob.exc.HTTPBadRequest,
|
AttributeError: webob.exc.HTTPBadRequest,
|
||||||
ValueError: webob.exc.HTTPBadRequest,
|
ValueError: webob.exc.HTTPBadRequest,
|
||||||
exceptions.IpAddressGenerationFailure: webob.exc.HTTPConflict,
|
exceptions.IpAddressGenerationFailure: webob.exc.HTTPConflict,
|
||||||
|
exceptions.OverQuota: webob.exc.HTTPConflict,
|
||||||
}
|
}
|
||||||
|
|
||||||
QUOTAS = quota.QUOTAS
|
QUOTAS = quota.QUOTAS
|
||||||
@ -293,8 +294,11 @@ class Controller(object):
|
|||||||
if self._collection in body:
|
if self._collection in body:
|
||||||
# Have to account for bulk create
|
# Have to account for bulk create
|
||||||
items = body[self._collection]
|
items = body[self._collection]
|
||||||
|
deltas = {}
|
||||||
|
bulk = True
|
||||||
else:
|
else:
|
||||||
items = [body]
|
items = [body]
|
||||||
|
bulk = False
|
||||||
for item in items:
|
for item in items:
|
||||||
self._validate_network_tenant_ownership(request,
|
self._validate_network_tenant_ownership(request,
|
||||||
item[self._resource])
|
item[self._resource])
|
||||||
@ -303,10 +307,16 @@ class Controller(object):
|
|||||||
item[self._resource],
|
item[self._resource],
|
||||||
plugin=self._plugin)
|
plugin=self._plugin)
|
||||||
try:
|
try:
|
||||||
|
tenant_id = item[self._resource]['tenant_id']
|
||||||
count = QUOTAS.count(request.context, self._resource,
|
count = QUOTAS.count(request.context, self._resource,
|
||||||
self._plugin, self._collection,
|
self._plugin, self._collection,
|
||||||
item[self._resource]['tenant_id'])
|
tenant_id)
|
||||||
kwargs = {self._resource: count + 1}
|
if bulk:
|
||||||
|
delta = deltas.get(tenant_id, 0) + 1
|
||||||
|
deltas[tenant_id] = delta
|
||||||
|
else:
|
||||||
|
delta = 1
|
||||||
|
kwargs = {self._resource: count + delta}
|
||||||
except exceptions.QuotaResourceUnknown as e:
|
except exceptions.QuotaResourceUnknown as e:
|
||||||
# We don't want to quota this resource
|
# We don't want to quota this resource
|
||||||
LOG.debug(e)
|
LOG.debug(e)
|
||||||
|
@ -172,6 +172,21 @@ class QuantumDbPluginV2TestCase(unittest2.TestCase):
|
|||||||
data = self._deserializers[ctype].deserialize(response.body)['body']
|
data = self._deserializers[ctype].deserialize(response.body)['body']
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _create_bulk_from_list(self, fmt, resource, objects, **kwargs):
|
||||||
|
""" Creates a bulk request from a list of objects """
|
||||||
|
collection = "%ss" % resource
|
||||||
|
req_data = {collection: objects}
|
||||||
|
req = self.new_create_request(collection, req_data, fmt)
|
||||||
|
if ('set_context' in kwargs and
|
||||||
|
kwargs['set_context'] is True and
|
||||||
|
'tenant_id' in kwargs):
|
||||||
|
# create a specific auth context for this request
|
||||||
|
req.environ['quantum.context'] = context.Context(
|
||||||
|
'', kwargs['tenant_id'])
|
||||||
|
elif 'context' in kwargs:
|
||||||
|
req.environ['quantum.context'] = kwargs['context']
|
||||||
|
return req.get_response(self.api)
|
||||||
|
|
||||||
def _create_bulk(self, fmt, number, resource, data, name='test', **kwargs):
|
def _create_bulk(self, fmt, number, resource, data, name='test', **kwargs):
|
||||||
""" Creates a bulk request for any kind of resource """
|
""" Creates a bulk request for any kind of resource """
|
||||||
objects = []
|
objects = []
|
||||||
@ -386,8 +401,8 @@ class QuantumDbPluginV2TestCase(unittest2.TestCase):
|
|||||||
patched_plugin.side_effect = second_call
|
patched_plugin.side_effect = second_call
|
||||||
return orig(*args, **kwargs)
|
return orig(*args, **kwargs)
|
||||||
|
|
||||||
def _validate_behavior_on_bulk_failure(self, res, collection):
|
def _validate_behavior_on_bulk_failure(self, res, collection, errcode=400):
|
||||||
self.assertEqual(res.status_int, 400)
|
self.assertEqual(res.status_int, errcode)
|
||||||
req = self.new_list_request(collection)
|
req = self.new_list_request(collection)
|
||||||
res = req.get_response(self.api)
|
res = req.get_response(self.api)
|
||||||
self.assertEqual(res.status_int, 200)
|
self.assertEqual(res.status_int, 200)
|
||||||
@ -1621,6 +1636,50 @@ class TestNetworksV2(QuantumDbPluginV2TestCase):
|
|||||||
res = self._create_network_bulk('json', 2, 'test', True)
|
res = self._create_network_bulk('json', 2, 'test', True)
|
||||||
self._validate_behavior_on_bulk_success(res, 'networks')
|
self._validate_behavior_on_bulk_success(res, 'networks')
|
||||||
|
|
||||||
|
def test_create_networks_bulk_native_quotas(self):
|
||||||
|
if self._skip_native_bulk:
|
||||||
|
self.skipTest("Plugin does not support native bulk network create")
|
||||||
|
quota = 4
|
||||||
|
cfg.CONF.set_override('quota_network', quota, group='QUOTAS')
|
||||||
|
res = self._create_network_bulk('json', quota + 1, 'test', True)
|
||||||
|
self._validate_behavior_on_bulk_failure(res, 'networks', errcode=409)
|
||||||
|
|
||||||
|
def test_create_networks_bulk_tenants_and_quotas(self):
|
||||||
|
if self._skip_native_bulk:
|
||||||
|
self.skipTest("Plugin does not support native bulk network create")
|
||||||
|
quota = 2
|
||||||
|
cfg.CONF.set_override('quota_network', quota, group='QUOTAS')
|
||||||
|
networks = [{'network': {'name': 'n1',
|
||||||
|
'tenant_id': self._tenant_id}},
|
||||||
|
{'network': {'name': 'n2',
|
||||||
|
'tenant_id': self._tenant_id}},
|
||||||
|
{'network': {'name': 'n1',
|
||||||
|
'tenant_id': 't1'}},
|
||||||
|
{'network': {'name': 'n2',
|
||||||
|
'tenant_id': 't1'}}]
|
||||||
|
|
||||||
|
res = self._create_bulk_from_list('json', 'network', networks)
|
||||||
|
self.assertEqual(res.status_int, 201)
|
||||||
|
|
||||||
|
def test_create_networks_bulk_tenants_and_quotas_fail(self):
|
||||||
|
if self._skip_native_bulk:
|
||||||
|
self.skipTest("Plugin does not support native bulk network create")
|
||||||
|
quota = 2
|
||||||
|
cfg.CONF.set_override('quota_network', quota, group='QUOTAS')
|
||||||
|
networks = [{'network': {'name': 'n1',
|
||||||
|
'tenant_id': self._tenant_id}},
|
||||||
|
{'network': {'name': 'n2',
|
||||||
|
'tenant_id': self._tenant_id}},
|
||||||
|
{'network': {'name': 'n1',
|
||||||
|
'tenant_id': 't1'}},
|
||||||
|
{'network': {'name': 'n3',
|
||||||
|
'tenant_id': self._tenant_id}},
|
||||||
|
{'network': {'name': 'n2',
|
||||||
|
'tenant_id': 't1'}}]
|
||||||
|
|
||||||
|
res = self._create_bulk_from_list('json', 'network', networks)
|
||||||
|
self.assertEqual(res.status_int, 409)
|
||||||
|
|
||||||
def test_create_networks_bulk_emulated(self):
|
def test_create_networks_bulk_emulated(self):
|
||||||
real_has_attr = hasattr
|
real_has_attr = hasattr
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user