Validate limit query parameter for List Software Config API
This change adds validation of the limit query parameter in List Software Config API, as was implemented for List Stack API, to avoid internal error at database query. story: 2009707 task: 44054 Change-Id: Ib57919faebbd4eb6aa13857e242eb5f3dc448a02
This commit is contained in:
parent
5e14163f9c
commit
ef67b861dd
@ -43,6 +43,14 @@ class SoftwareConfigController(object):
|
|||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise exc.HTTPBadRequest(str(e))
|
raise exc.HTTPBadRequest(str(e))
|
||||||
|
|
||||||
|
def _extract_int_param(self, name, value,
|
||||||
|
allow_zero=True, allow_negative=False):
|
||||||
|
try:
|
||||||
|
return param_utils.extract_int(name, value,
|
||||||
|
allow_zero, allow_negative)
|
||||||
|
except ValueError as e:
|
||||||
|
raise exc.HTTPBadRequest(str(e))
|
||||||
|
|
||||||
def _index(self, req, use_admin_cnxt=False):
|
def _index(self, req, use_admin_cnxt=False):
|
||||||
param_types = {
|
param_types = {
|
||||||
'limit': util.PARAM_TYPE_SINGLE,
|
'limit': util.PARAM_TYPE_SINGLE,
|
||||||
@ -50,6 +58,10 @@ class SoftwareConfigController(object):
|
|||||||
}
|
}
|
||||||
params = util.get_allowed_params(req.params, param_types)
|
params = util.get_allowed_params(req.params, param_types)
|
||||||
|
|
||||||
|
key = rpc_api.PARAM_LIMIT
|
||||||
|
if key in params:
|
||||||
|
params[key] = self._extract_int_param(key, params[key])
|
||||||
|
|
||||||
if use_admin_cnxt:
|
if use_admin_cnxt:
|
||||||
cnxt = context.get_admin_context()
|
cnxt = context.get_admin_context()
|
||||||
else:
|
else:
|
||||||
|
@ -46,6 +46,41 @@ class SoftwareConfigControllerTest(tools.ControllerTest, common.HeatTestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{'software_configs': []}, resp)
|
{'software_configs': []}, resp)
|
||||||
|
|
||||||
|
@mock.patch.object(policy.Enforcer, 'enforce')
|
||||||
|
def test_index_limit_negative(self, mock_enforce):
|
||||||
|
self._mock_enforce_setup(mock_enforce, 'index')
|
||||||
|
params = {'limit': -1}
|
||||||
|
|
||||||
|
with mock.patch.object(
|
||||||
|
self.controller.rpc_client,
|
||||||
|
'list_software_configs',
|
||||||
|
return_value=[]) as mock_call:
|
||||||
|
req = self._get('/software_configs', params=params)
|
||||||
|
ex = self.assertRaises(webob.exc.HTTPBadRequest,
|
||||||
|
self.controller.index, req,
|
||||||
|
tenant_id=self.tenant)
|
||||||
|
self.assertEqual("Value '-1' is invalid for 'limit' which only "
|
||||||
|
"accepts non-negative integer.",
|
||||||
|
str(ex))
|
||||||
|
self.assertFalse(mock_call.called)
|
||||||
|
|
||||||
|
@mock.patch.object(policy.Enforcer, 'enforce')
|
||||||
|
def test_index_limit_not_int(self, mock_enforce):
|
||||||
|
self._mock_enforce_setup(mock_enforce, 'index')
|
||||||
|
params = {'limit': 'not-an-int'}
|
||||||
|
|
||||||
|
with mock.patch.object(
|
||||||
|
self.controller.rpc_client,
|
||||||
|
'list_software_configs',
|
||||||
|
return_value=[]) as mock_call:
|
||||||
|
req = self._get('/software_configs', params=params)
|
||||||
|
ex = self.assertRaises(webob.exc.HTTPBadRequest,
|
||||||
|
self.controller.index, req,
|
||||||
|
tenant_id=self.tenant)
|
||||||
|
self.assertEqual("Only integer is acceptable by 'limit'.",
|
||||||
|
str(ex))
|
||||||
|
self.assertFalse(mock_call.called)
|
||||||
|
|
||||||
@mock.patch.object(policy.Enforcer, 'enforce')
|
@mock.patch.object(policy.Enforcer, 'enforce')
|
||||||
def test_show(self, mock_enforce):
|
def test_show(self, mock_enforce):
|
||||||
self._mock_enforce_setup(mock_enforce, 'show')
|
self._mock_enforce_setup(mock_enforce, 'show')
|
||||||
|
@ -337,6 +337,20 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase):
|
|||||||
self.assertIn('filters', engine_args)
|
self.assertIn('filters', engine_args)
|
||||||
self.assertNotIn('balrog', engine_args)
|
self.assertNotIn('balrog', engine_args)
|
||||||
|
|
||||||
|
@mock.patch.object(rpc_client.EngineClient, 'call')
|
||||||
|
def test_index_limit_negative(self, mock_call, mock_enforce):
|
||||||
|
self._mock_enforce_setup(mock_enforce, 'index', True)
|
||||||
|
params = {'limit': -1}
|
||||||
|
req = self._get('/stacks', params=params)
|
||||||
|
|
||||||
|
ex = self.assertRaises(webob.exc.HTTPBadRequest,
|
||||||
|
self.controller.index, req,
|
||||||
|
tenant_id=self.tenant)
|
||||||
|
self.assertEqual("Value '-1' is invalid for 'limit' which only "
|
||||||
|
"accepts non-negative integer.",
|
||||||
|
str(ex))
|
||||||
|
self.assertFalse(mock_call.called)
|
||||||
|
|
||||||
@mock.patch.object(rpc_client.EngineClient, 'call')
|
@mock.patch.object(rpc_client.EngineClient, 'call')
|
||||||
def test_index_limit_not_int(self, mock_call, mock_enforce):
|
def test_index_limit_not_int(self, mock_call, mock_enforce):
|
||||||
self._mock_enforce_setup(mock_enforce, 'index', True)
|
self._mock_enforce_setup(mock_enforce, 'index', True)
|
||||||
@ -1936,6 +1950,31 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase):
|
|||||||
version='1.36'
|
version='1.36'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_update_timeout_negative(self, mock_enforce):
|
||||||
|
self._mock_enforce_setup(mock_enforce, 'update', True)
|
||||||
|
identity = identifier.HeatIdentifier(self.tenant, 'wibble', '6')
|
||||||
|
template = {u'Foo': u'bar'}
|
||||||
|
parameters = {u'InstanceType': u'm1.xlarge'}
|
||||||
|
body = {'template': template,
|
||||||
|
'parameters': parameters,
|
||||||
|
'files': {},
|
||||||
|
'timeout_mins': -1}
|
||||||
|
|
||||||
|
req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity,
|
||||||
|
json.dumps(body))
|
||||||
|
|
||||||
|
mock_call = self.patchobject(rpc_client.EngineClient, 'call')
|
||||||
|
ex = self.assertRaises(webob.exc.HTTPBadRequest,
|
||||||
|
self.controller.update, req,
|
||||||
|
tenant_id=identity.tenant,
|
||||||
|
stack_name=identity.stack_name,
|
||||||
|
stack_id=identity.stack_id,
|
||||||
|
body=body)
|
||||||
|
self.assertEqual("Value '-1' is invalid for 'timeout_mins' which only "
|
||||||
|
"accepts non-negative integer.",
|
||||||
|
str(ex))
|
||||||
|
self.assertFalse(mock_call.called)
|
||||||
|
|
||||||
def test_update_timeout_not_int(self, mock_enforce):
|
def test_update_timeout_not_int(self, mock_enforce):
|
||||||
self._mock_enforce_setup(mock_enforce, 'update', True)
|
self._mock_enforce_setup(mock_enforce, 'update', True)
|
||||||
identity = identifier.HeatIdentifier(self.tenant, 'wibble', '6')
|
identity = identifier.HeatIdentifier(self.tenant, 'wibble', '6')
|
||||||
@ -2149,6 +2188,31 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase):
|
|||||||
version='1.36'
|
version='1.36'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_update_with_patch_timeout_negative(self, mock_enforce):
|
||||||
|
self._mock_enforce_setup(mock_enforce, 'update_patch', True)
|
||||||
|
identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '6')
|
||||||
|
template = {u'Foo': u'bar'}
|
||||||
|
parameters = {u'InstanceType': u'm1.xlarge'}
|
||||||
|
body = {'template': template,
|
||||||
|
'parameters': parameters,
|
||||||
|
'files': {},
|
||||||
|
'timeout_mins': -1}
|
||||||
|
|
||||||
|
req = self._patch('/stacks/%(stack_name)s/%(stack_id)s' % identity,
|
||||||
|
json.dumps(body))
|
||||||
|
|
||||||
|
mock_call = self.patchobject(rpc_client.EngineClient, 'call')
|
||||||
|
ex = self.assertRaises(webob.exc.HTTPBadRequest,
|
||||||
|
self.controller.update_patch, req,
|
||||||
|
tenant_id=identity.tenant,
|
||||||
|
stack_name=identity.stack_name,
|
||||||
|
stack_id=identity.stack_id,
|
||||||
|
body=body)
|
||||||
|
self.assertEqual("Value '-1' is invalid for 'timeout_mins' which only "
|
||||||
|
"accepts non-negative integer.",
|
||||||
|
str(ex))
|
||||||
|
self.assertFalse(mock_call.called)
|
||||||
|
|
||||||
def test_update_with_patch_timeout_not_int(self, mock_enforce):
|
def test_update_with_patch_timeout_not_int(self, mock_enforce):
|
||||||
self._mock_enforce_setup(mock_enforce, 'update_patch', True)
|
self._mock_enforce_setup(mock_enforce, 'update_patch', True)
|
||||||
identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '6')
|
identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '6')
|
||||||
|
Loading…
Reference in New Issue
Block a user