Merge "Add validation of limit value in querying flavors and poolss"
This commit is contained in:
commit
522fa86c45
@ -325,6 +325,14 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
path, capabilities = expected[4][:2]
|
path, capabilities = expected[4][:2]
|
||||||
self._flavor_expect(flavor_list[0], path, self.doc['pool_group'])
|
self._flavor_expect(flavor_list[0], path, self.doc['pool_group'])
|
||||||
|
|
||||||
|
def test_listing_error_with_invalid_limit(self):
|
||||||
|
self.simulate_delete(self.flavor_path)
|
||||||
|
query = 'limit={0}&detailed={1}'.format(0, True)
|
||||||
|
|
||||||
|
with flavors(self, 10, self.doc['pool_group']):
|
||||||
|
self.simulate_get(self.url_prefix + '/flavors', query_string=query)
|
||||||
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
def test_queue_create_works(self):
|
def test_queue_create_works(self):
|
||||||
metadata = {'_flavor': self.flavor}
|
metadata = {'_flavor': self.flavor}
|
||||||
self.simulate_put(self.queue_path, body=jsonutils.dumps(metadata))
|
self.simulate_put(self.queue_path, body=jsonutils.dumps(metadata))
|
||||||
|
@ -361,3 +361,11 @@ class TestPoolsMongoDB(base.V2Base):
|
|||||||
self.assertEqual(6, len(pool_list))
|
self.assertEqual(6, len(pool_list))
|
||||||
path, weight = expected[4][:2]
|
path, weight = expected[4][:2]
|
||||||
self._pool_expect(pool_list[0], path, weight, self.doc['uri'])
|
self._pool_expect(pool_list[0], path, weight, self.doc['uri'])
|
||||||
|
|
||||||
|
def test_listing_error_with_invalid_limit(self):
|
||||||
|
self.simulate_delete(self.pool)
|
||||||
|
query = 'limit={0}&detailed={1}'.format(0, True)
|
||||||
|
|
||||||
|
with pools(self, 10, self.doc['uri'], 'my-group'):
|
||||||
|
self.simulate_get(self.url_prefix + '/pools', query_string=query)
|
||||||
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
@ -79,6 +79,12 @@ _TRANSPORT_LIMITS_OPTIONS = (
|
|||||||
cfg.ListOpt('subscriber_types', default=['http', 'https', 'mailto',
|
cfg.ListOpt('subscriber_types', default=['http', 'https', 'mailto',
|
||||||
'trust+http', 'trust+https'],
|
'trust+http', 'trust+https'],
|
||||||
help='Defines supported subscriber types.'),
|
help='Defines supported subscriber types.'),
|
||||||
|
|
||||||
|
cfg.IntOpt('max_flavors_per_page', default=20,
|
||||||
|
help='Defines the maximum number of flavors per page.'),
|
||||||
|
|
||||||
|
cfg.IntOpt('max_pools_per_page', default=20,
|
||||||
|
help='Defines the maximum number of pools per page.'),
|
||||||
)
|
)
|
||||||
|
|
||||||
_TRANSPORT_LIMITS_GROUP = 'transport'
|
_TRANSPORT_LIMITS_GROUP = 'transport'
|
||||||
@ -585,3 +591,29 @@ class Validator(object):
|
|||||||
:param limit_conf_name: configuration name
|
:param limit_conf_name: configuration name
|
||||||
"""
|
"""
|
||||||
return self._limits_conf[limit_conf_name]
|
return self._limits_conf[limit_conf_name]
|
||||||
|
|
||||||
|
def flavor_listing(self, limit=None, **kwargs):
|
||||||
|
"""Restrictions involving a list of pools.
|
||||||
|
|
||||||
|
:param limit: The expected number of flavors in the list
|
||||||
|
:param kwargs: Ignored arguments passed to storage API
|
||||||
|
:raises: ValidationFailed if the limit is exceeded
|
||||||
|
"""
|
||||||
|
|
||||||
|
uplimit = self._limits_conf.max_flavors_per_page
|
||||||
|
if limit is not None and not (0 < limit <= uplimit):
|
||||||
|
msg = _(u'Limit must be at least 1 and no greater than {0}.')
|
||||||
|
raise ValidationFailed(msg, self._limits_conf.max_flavors_per_page)
|
||||||
|
|
||||||
|
def pool_listing(self, limit=None, **kwargs):
|
||||||
|
"""Restrictions involving a list of pools.
|
||||||
|
|
||||||
|
:param limit: The expected number of flavors in the list
|
||||||
|
:param kwargs: Ignored arguments passed to storage API
|
||||||
|
:raises: ValidationFailed if the limit is exceeded
|
||||||
|
"""
|
||||||
|
|
||||||
|
uplimit = self._limits_conf.max_pools_per_page
|
||||||
|
if limit is not None and not (0 < limit <= uplimit):
|
||||||
|
msg = _(u'Limit must be at least 1 and no greater than {0}.')
|
||||||
|
raise ValidationFailed(msg, self._limits_conf.max_pools_per_page)
|
||||||
|
@ -133,14 +133,16 @@ def private_endpoints(driver, conf):
|
|||||||
if conf.pooling:
|
if conf.pooling:
|
||||||
pools_controller = driver._control.pools_controller
|
pools_controller = driver._control.pools_controller
|
||||||
flavors_controller = driver._control.flavors_controller
|
flavors_controller = driver._control.flavors_controller
|
||||||
|
validate = driver._validate
|
||||||
|
|
||||||
catalogue.extend([
|
catalogue.extend([
|
||||||
('/pools',
|
('/pools',
|
||||||
pools.Listing(pools_controller)),
|
pools.Listing(pools_controller, validate)),
|
||||||
('/pools/{pool}',
|
('/pools/{pool}',
|
||||||
pools.Resource(pools_controller)),
|
pools.Resource(pools_controller)),
|
||||||
('/flavors',
|
('/flavors',
|
||||||
flavors.Listing(flavors_controller, pools_controller)),
|
flavors.Listing(flavors_controller, pools_controller,
|
||||||
|
validate)),
|
||||||
('/flavors/{flavor}',
|
('/flavors/{flavor}',
|
||||||
flavors.Resource(flavors_controller, pools_controller)),
|
flavors.Resource(flavors_controller, pools_controller)),
|
||||||
])
|
])
|
||||||
|
@ -25,6 +25,7 @@ from zaqar.i18n import _
|
|||||||
from zaqar.storage import errors
|
from zaqar.storage import errors
|
||||||
from zaqar.transport import acl
|
from zaqar.transport import acl
|
||||||
from zaqar.transport import utils as transport_utils
|
from zaqar.transport import utils as transport_utils
|
||||||
|
from zaqar.transport import validation
|
||||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||||
from zaqar.transport.wsgi import utils as wsgi_utils
|
from zaqar.transport.wsgi import utils as wsgi_utils
|
||||||
|
|
||||||
@ -37,9 +38,10 @@ class Listing(object):
|
|||||||
:param flavors_controller: means to interact with storage
|
:param flavors_controller: means to interact with storage
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, flavors_controller, pools_controller):
|
def __init__(self, flavors_controller, pools_controller, validate):
|
||||||
self._ctrl = flavors_controller
|
self._ctrl = flavors_controller
|
||||||
self._pools_ctrl = pools_controller
|
self._pools_ctrl = pools_controller
|
||||||
|
self._validate = validate
|
||||||
|
|
||||||
@decorators.TransportLog("Flavors collection")
|
@decorators.TransportLog("Flavors collection")
|
||||||
@acl.enforce("flavors:get_all")
|
@acl.enforce("flavors:get_all")
|
||||||
@ -69,6 +71,12 @@ class Listing(object):
|
|||||||
request.get_param_as_int('limit', store=store)
|
request.get_param_as_int('limit', store=store)
|
||||||
detailed = request.get_param_as_bool('detailed')
|
detailed = request.get_param_as_bool('detailed')
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._validate.flavor_listing(**store)
|
||||||
|
except validation.ValidationFailed as ex:
|
||||||
|
LOG.debug(ex)
|
||||||
|
raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex))
|
||||||
|
|
||||||
cursor = self._ctrl.list(project=project_id, **store)
|
cursor = self._ctrl.list(project=project_id, **store)
|
||||||
flavors = list(next(cursor))
|
flavors = list(next(cursor))
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ from zaqar.storage import errors
|
|||||||
from zaqar.storage import utils as storage_utils
|
from zaqar.storage import utils as storage_utils
|
||||||
from zaqar.transport import acl
|
from zaqar.transport import acl
|
||||||
from zaqar.transport import utils as transport_utils
|
from zaqar.transport import utils as transport_utils
|
||||||
|
from zaqar.transport import validation
|
||||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||||
from zaqar.transport.wsgi import utils as wsgi_utils
|
from zaqar.transport.wsgi import utils as wsgi_utils
|
||||||
|
|
||||||
@ -61,8 +62,9 @@ class Listing(object):
|
|||||||
:param pools_controller: means to interact with storage
|
:param pools_controller: means to interact with storage
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, pools_controller):
|
def __init__(self, pools_controller, validate):
|
||||||
self._ctrl = pools_controller
|
self._ctrl = pools_controller
|
||||||
|
self._validate = validate
|
||||||
|
|
||||||
@decorators.TransportLog("Pools collection")
|
@decorators.TransportLog("Pools collection")
|
||||||
@acl.enforce("pools:get_all")
|
@acl.enforce("pools:get_all")
|
||||||
@ -91,6 +93,12 @@ class Listing(object):
|
|||||||
request.get_param_as_int('limit', store=store)
|
request.get_param_as_int('limit', store=store)
|
||||||
request.get_param_as_bool('detailed', store=store)
|
request.get_param_as_bool('detailed', store=store)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._validate.pool_listing(**store)
|
||||||
|
except validation.ValidationFailed as ex:
|
||||||
|
LOG.debug(ex)
|
||||||
|
raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex))
|
||||||
|
|
||||||
cursor = self._ctrl.list(**store)
|
cursor = self._ctrl.list(**store)
|
||||||
pools = list(next(cursor))
|
pools = list(next(cursor))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user