API: enforce bay type when do rc/service/pod api actions

Currently, we require pass bay_ident to rc actions, but this bay_ident's
type is only enforced by creation actions.

If we pass a bad type bay(e.g. swarm bay or mesos bay), REST API will return
500 error. This patch will enforce bay type before every API method.

Closes-Bug: #1526173
Change-Id: I93bd4362c6c084c29100d0c19564e49ca62a1927
This commit is contained in:
Eli Qiao 2015-12-16 16:30:40 +08:00
parent 8ee7598945
commit 4699862fc8
8 changed files with 217 additions and 72 deletions

View File

@ -191,26 +191,29 @@ class PodsController(rest.RestController):
sort_dir=sort_dir)
@policy.enforce_wsgi("pod")
@expose.expose(PodCollection, types.uuid, int, wtypes.text,
wtypes.text, types.uuid_or_name)
def get_all(self, marker=None, limit=None, sort_key='id',
sort_dir='asc', bay_ident=None):
@expose.expose(PodCollection, types.uuid, types.uuid_or_name, int,
wtypes.text, wtypes.text)
@validation.enforce_bay_types('kubernetes')
def get_all(self, marker=None, bay_ident=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of pods.
:param marker: pagination marker for large data sets.
:param bay_ident: UUID or logical name of the Bay.
:param limit: maximum number of resources to return in a single result.
:param sort_key: column to sort results by. Default: id.
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
:param bay_ident: UUID or logical name of the Bay.
"""
return self._get_pods_collection(marker, limit, sort_key,
sort_dir, bay_ident)
@policy.enforce_wsgi("pod")
@expose.expose(PodCollection, types.uuid, int, wtypes.text,
wtypes.text, types.uuid_or_name)
def detail(self, marker=None, limit=None, sort_key='id',
sort_dir='asc', bay_ident=None):
@expose.expose(PodCollection, types.uuid, types.uuid_or_name, int,
wtypes.text, wtypes.text)
@validation.enforce_bay_types('kubernetes')
def detail(self, marker=None, bay_ident=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of pods with detail.
:param marker: pagination marker for large data sets.
@ -234,6 +237,7 @@ class PodsController(rest.RestController):
@policy.enforce_wsgi("pod", "get")
@expose.expose(Pod, types.uuid_or_name,
types.uuid_or_name)
@validation.enforce_bay_types('kubernetes')
def get_one(self, pod_ident, bay_ident):
"""Retrieve information about the given pod.
@ -268,6 +272,7 @@ class PodsController(rest.RestController):
@wsme.validate(types.uuid, [PodPatchType])
@expose.expose(Pod, types.uuid_or_name,
types.uuid_or_name, body=[PodPatchType])
@validation.enforce_bay_types('kubernetes')
def patch(self, pod_ident, bay_ident, patch):
"""Update an existing pod.
@ -292,6 +297,7 @@ class PodsController(rest.RestController):
@policy.enforce_wsgi("pod")
@expose.expose(None, types.uuid_or_name,
types.uuid_or_name, status_code=204)
@validation.enforce_bay_types('kubernetes')
def delete(self, pod_ident, bay_ident):
"""Delete a pod.

View File

@ -220,10 +220,11 @@ class ReplicationControllersController(rest.RestController):
sort_dir=sort_dir)
@policy.enforce_wsgi("rc")
@expose.expose(ReplicationControllerCollection, types.uuid, int,
wtypes.text, wtypes.text, types.uuid_or_name)
def get_all(self, marker=None, limit=None, sort_key='id',
sort_dir='asc', bay_ident=None):
@expose.expose(ReplicationControllerCollection, types.uuid,
types.uuid_or_name, int, wtypes.text, wtypes.text)
@validation.enforce_bay_types('kubernetes')
def get_all(self, marker=None, bay_ident=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of ReplicationControllers.
:param marker: pagination marker for large data sets.
@ -236,10 +237,11 @@ class ReplicationControllersController(rest.RestController):
sort_dir, bay_ident)
@policy.enforce_wsgi("rc")
@expose.expose(ReplicationControllerCollection, types.uuid, int,
wtypes.text, wtypes.text, types.uuid_or_name)
def detail(self, marker=None, limit=None, sort_key='id',
sort_dir='asc', bay_ident=None):
@expose.expose(ReplicationControllerCollection, types.uuid,
types.uuid_or_name, int, wtypes.text, wtypes.text)
@validation.enforce_bay_types('kubernetes')
def detail(self, marker=None, bay_ident=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of ReplicationControllers with detail.
:param marker: pagination marker for large data sets.
@ -263,6 +265,7 @@ class ReplicationControllersController(rest.RestController):
@policy.enforce_wsgi("rc", "get")
@expose.expose(ReplicationController, types.uuid_or_name,
types.uuid_or_name)
@validation.enforce_bay_types('kubernetes')
def get_one(self, rc_ident, bay_ident):
"""Retrieve information about the given ReplicationController.
@ -300,6 +303,7 @@ class ReplicationControllersController(rest.RestController):
@wsme.validate(types.uuid, [ReplicationControllerPatchType])
@expose.expose(ReplicationController, types.uuid_or_name,
types.uuid_or_name, body=[ReplicationControllerPatchType])
@validation.enforce_bay_types('kubernetes')
def patch(self, rc_ident, bay_ident, patch):
"""Update an existing rc.
@ -326,6 +330,7 @@ class ReplicationControllersController(rest.RestController):
@policy.enforce_wsgi("rc")
@expose.expose(None, types.uuid_or_name,
types.uuid_or_name, status_code=204)
@validation.enforce_bay_types('kubernetes')
def delete(self, rc_ident, bay_ident):
"""Delete a ReplicationController.

View File

@ -199,10 +199,11 @@ class ServicesController(rest.RestController):
sort_dir=sort_dir)
@policy.enforce_wsgi("service")
@expose.expose(ServiceCollection, types.uuid, int, wtypes.text,
wtypes.text, types.uuid_or_name)
def get_all(self, marker=None, limit=None, sort_key='id',
sort_dir='asc', bay_ident=None):
@expose.expose(ServiceCollection, types.uuid, types.uuid_or_name, int,
wtypes.text, wtypes.text)
@validation.enforce_bay_types('kubernetes')
def get_all(self, marker=None, bay_ident=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of services.
:param marker: pagination marker for large data sets.
@ -215,10 +216,11 @@ class ServicesController(rest.RestController):
sort_dir, bay_ident)
@policy.enforce_wsgi("service")
@expose.expose(ServiceCollection, types.uuid, int, wtypes.text,
wtypes.text, types.uuid_or_name)
def detail(self, marker=None, limit=None, sort_key='id',
sort_dir='asc', bay_ident=None):
@expose.expose(ServiceCollection, types.uuid, types.uuid_or_name, int,
wtypes.text, wtypes.text)
@validation.enforce_bay_types('kubernetes')
def detail(self, marker=None, bay_ident=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of services with detail.
:param marker: pagination marker for large data sets.
@ -242,6 +244,7 @@ class ServicesController(rest.RestController):
@policy.enforce_wsgi("service", "get")
@expose.expose(Service, types.uuid_or_name,
types.uuid_or_name)
@validation.enforce_bay_types('kubernetes')
def get_one(self, service_ident, bay_ident):
"""Retrieve information about the given service.
@ -280,6 +283,7 @@ class ServicesController(rest.RestController):
@wsme.validate(types.uuid, [ServicePatchType])
@expose.expose(Service, types.uuid_or_name,
types.uuid_or_name, body=[ServicePatchType])
@validation.enforce_bay_types('kubernetes')
def patch(self, service_ident, bay_ident, patch):
"""Update an existing service.
@ -305,6 +309,7 @@ class ServicesController(rest.RestController):
@policy.enforce_wsgi("service")
@expose.expose(None, types.uuid_or_name,
types.uuid_or_name, status_code=204)
@validation.enforce_bay_types('kubernetes')
def delete(self, service_ident, bay_ident):
"""Delete a service.

View File

@ -19,6 +19,7 @@ import pecan
from magnum.api import utils as api_utils
from magnum.common import exception
from magnum.common import utils
from magnum import objects
@ -55,10 +56,21 @@ cfg.CONF.register_opts(baymodel_opts, group='baymodel')
def enforce_bay_types(*bay_types):
"""Enforce that bay_type is in supported list."""
@decorator.decorator
def wrapper(func, *args, **kwargs):
# Note(eliqiao): This decorator has some assumptions
# args[1] should be an APIBase instance or
# args[2] should be a bay_ident
obj = args[1]
bay = objects.Bay.get_by_uuid(pecan.request.context, obj.bay_uuid)
if hasattr(obj, 'bay_uuid'):
bay = objects.Bay.get_by_uuid(pecan.request.context, obj.bay_uuid)
else:
bay_ident = args[2]
if utils.is_uuid_like(bay_ident):
bay = objects.Bay.get_by_uuid(pecan.request.context, bay_ident)
else:
bay = objects.Bay.get_by_name(pecan.request.context, bay_ident)
baymodel = objects.BayModel.get_by_uuid(pecan.request.context,
bay.baymodel_id)
if baymodel.coe not in bay_types:

View File

@ -41,13 +41,16 @@ class TestListPod(api_base.FunctionalTest):
def setUp(self):
super(TestListPod, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.pod = obj_utils.create_test_pod(self.context)
@mock.patch.object(rpcapi.API, 'pod_list')
def test_empty(self, mock_pod_list):
mock_pod_list.return_value = []
response = self.get_json('/pods')
response = self.get_json('/pods?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual([], response['pods'])
def _assert_pod_fields(self, pod):
@ -118,7 +121,8 @@ class TestListPod(api_base.FunctionalTest):
pod_list.append(pod.uuid)
mock_pod_list.return_value = [pod]
response = self.get_json('/pods?limit=3&marker=%s' % pod_list[2])
response = self.get_json('/pods?limit=3&marker=%s&bay_ident=5d12f6fd-'
'a196-4bf0-ae4c-1f639a523a52' % pod_list[2])
self.assertEqual(1, len(response['pods']))
self.assertEqual(pod_list[-1], response['pods'][0]['uuid'])
@ -126,7 +130,8 @@ class TestListPod(api_base.FunctionalTest):
def test_detail(self, mock_pod_list):
pod = obj_utils.create_test_pod(self.context)
mock_pod_list.return_value = [pod]
response = self.get_json('/pods/detail')
response = self.get_json('/pods/detail?bay_ident=5d12f6fd-a196-4bf0-'
'ae4c-1f639a523a52')
self.assertEqual(pod.uuid, response['pods'][0]["uuid"])
self._assert_pod_fields(response['pods'][0])
@ -139,7 +144,8 @@ class TestListPod(api_base.FunctionalTest):
pod_list.append(pod.uuid)
mock_pod_list.return_value = [pod]
response = self.get_json('/pods/detail?limit=3&marker=%s'
response = self.get_json('/pods/detail?limit=3&marker=%s&bay_ident='
'5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
% pod_list[2])
self.assertEqual(1, len(response['pods']))
self.assertEqual(pod_list[-1], response['pods'][0]['uuid'])
@ -161,7 +167,8 @@ class TestListPod(api_base.FunctionalTest):
uuid=utils.generate_uuid())
pod_list.append(pod.uuid)
mock_pod_list.return_value = [pod]
response = self.get_json('/pods')
response = self.get_json('/pods?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual(len(pod_list), len(response['pods']))
uuids = [p['uuid'] for p in response['pods']]
self.assertEqual(sorted(pod_list), sorted(uuids))
@ -183,7 +190,8 @@ class TestListPod(api_base.FunctionalTest):
id=id_,
uuid=utils.generate_uuid())
mock_pod_list.return_value = [pod]
response = self.get_json('/pods/?limit=1')
response = self.get_json('/pods/?limit=1&bay_ident=5d12f6fd-a196-'
'4bf0-ae4c-1f639a523a52')
self.assertEqual(1, len(response['pods']))
@mock.patch.object(rpcapi.API, 'pod_list')
@ -193,7 +201,8 @@ class TestListPod(api_base.FunctionalTest):
pod = obj_utils.create_test_pod(self.context, id=id_,
uuid=utils.generate_uuid())
mock_pod_list.return_value = [pod]
response = self.get_json('/pods')
response = self.get_json('/pods?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual(1, len(response['pods']))
@ -201,7 +210,9 @@ class TestPatch(api_base.FunctionalTest):
def setUp(self):
super(TestPatch, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.pod = obj_utils.create_test_pod(self.context,
desc='pod_example_A_desc',
status='Running')
@ -497,7 +508,9 @@ class TestDelete(api_base.FunctionalTest):
def setUp(self):
super(TestDelete, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.pod = obj_utils.create_test_pod(self.context)
@mock.patch.object(rpcapi.API, 'pod_delete')

View File

@ -41,13 +41,16 @@ class TestListRC(api_base.FunctionalTest):
def setUp(self):
super(TestListRC, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.rc = obj_utils.create_test_rc(self.context)
@mock.patch.object(rpcapi.API, 'rc_list')
def test_empty(self, mock_rc_list):
mock_rc_list.return_value = []
response = self.get_json('/rcs')
response = self.get_json('/rcs?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual([], response['rcs'])
def _assert_rc_fields(self, rc):
@ -109,7 +112,8 @@ class TestListRC(api_base.FunctionalTest):
rc_list.append(rc.uuid)
mock_rc_list.return_value = [rc]
response = self.get_json('/rcs?limit=3&marker=%s' % rc_list[2])
response = self.get_json('/rcs?limit=3&marker=%s&bay_ident=5d12f6fd-'
'a196-4bf0-ae4c-1f639a523a52' % rc_list[2])
self.assertEqual(1, len(response['rcs']))
self.assertEqual(rc_list[-1], response['rcs'][0]['uuid'])
@ -117,7 +121,8 @@ class TestListRC(api_base.FunctionalTest):
def test_detail(self, mock_rc_list):
rc = obj_utils.create_test_rc(self.context)
mock_rc_list.return_value = [rc]
response = self.get_json('/rcs/detail')
response = self.get_json('/rcs/detail?bay_ident=5d12f6fd-a196-4bf0-'
'ae4c-1f639a523a52')
self.assertEqual(rc.uuid, response['rcs'][0]["uuid"])
self._assert_rc_fields(response['rcs'][0])
@ -130,7 +135,8 @@ class TestListRC(api_base.FunctionalTest):
rc_list.append(rc.uuid)
mock_rc_list.return_value = [rc]
response = self.get_json('/rcs/detail?limit=3&marker=%s'
response = self.get_json('/rcs/detail?limit=3&marker=%s&bay_ident='
'5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
% (rc_list[2]))
self.assertEqual(1, len(response['rcs']))
@ -151,7 +157,8 @@ class TestListRC(api_base.FunctionalTest):
uuid=utils.generate_uuid())
rc_list.append(rc.uuid)
mock_rc_list.return_value = [rc]
response = self.get_json('/rcs')
response = self.get_json('/rcs?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual(len(rc_list), len(response['rcs']))
uuids = [r['uuid'] for r in response['rcs']]
self.assertEqual(sorted(rc_list), sorted(uuids))
@ -172,7 +179,8 @@ class TestListRC(api_base.FunctionalTest):
rc = obj_utils.create_test_rc(self.context, id=id_,
uuid=utils.generate_uuid())
mock_rc_list.return_value = [rc]
response = self.get_json('/rcs/?limit=1')
response = self.get_json('/rcs/?limit=1&bay_ident=5d12f6fd-a196-4bf0'
'-ae4c-1f639a523a52')
self.assertEqual(1, len(response['rcs']))
@mock.patch.object(rpcapi.API, 'rc_list')
@ -182,7 +190,8 @@ class TestListRC(api_base.FunctionalTest):
rc = obj_utils.create_test_rc(self.context, id=id_,
uuid=utils.generate_uuid())
mock_rc_list.return_value = [rc]
response = self.get_json('/rcs')
response = self.get_json('/rcs?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual(1, len(response['rcs']))
@ -190,7 +199,9 @@ class TestPatch(api_base.FunctionalTest):
def setUp(self):
super(TestPatch, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.rc = obj_utils.create_test_rc(self.context,
images=['rc_example_A_image'])
self.another_bay = obj_utils.create_test_bay(
@ -513,7 +524,9 @@ class TestDelete(api_base.FunctionalTest):
def setUp(self):
super(TestDelete, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.rc = obj_utils.create_test_rc(self.context)
@mock.patch.object(rpcapi.API, 'rc_delete')

View File

@ -41,13 +41,16 @@ class TestListService(api_base.FunctionalTest):
def setUp(self):
super(TestListService, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.service = obj_utils.create_test_service(self.context)
@mock.patch.object(rpcapi.API, 'service_list')
def test_empty(self, mock_pod_list):
mock_pod_list.return_value = []
response = self.get_json('/services')
response = self.get_json('/services?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual([], response['services'])
def _assert_service_fields(self, service):
@ -120,7 +123,8 @@ class TestListService(api_base.FunctionalTest):
service_list.append(service.uuid)
mock_service_list.return_value = [service]
response = self.get_json('/services?limit=3&marker=%s'
response = self.get_json('/services?limit=3&marker=%s&bay_ident='
'5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
% service_list[2])
self.assertEqual(1, len(response['services']))
self.assertEqual(service_list[-1], response['services'][0]['uuid'])
@ -129,7 +133,8 @@ class TestListService(api_base.FunctionalTest):
def test_detail(self, mock_service_list):
service = obj_utils.create_test_service(self.context)
mock_service_list.return_value = [service]
response = self.get_json('/services/detail')
response = self.get_json('/services/detail?bay_ident=5d12f6fd-a196-'
'4bf0-ae4c-1f639a523a52')
self.assertEqual(service.uuid, response['services'][0]["uuid"])
self._assert_service_fields(response['services'][0])
@ -142,7 +147,8 @@ class TestListService(api_base.FunctionalTest):
service_list.append(service.uuid)
mock_service_list.return_value = [service]
response = self.get_json('/services/detail?limit=3&marker=%s'
response = self.get_json('/services/detail?limit=3&marker=%s&bay_ident'
'=5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
% service_list[2])
self.assertEqual(1, len(response['services']))
self.assertEqual(service_list[-1], response['services'][0]['uuid'])
@ -164,7 +170,8 @@ class TestListService(api_base.FunctionalTest):
uuid=utils.generate_uuid())
service_list.append(service.uuid)
mock_service_list.return_value = [service]
response = self.get_json('/services')
response = self.get_json('/services?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual(len(service_list), len(response['services']))
uuids = [s['uuid'] for s in response['services']]
self.assertEqual(sorted(service_list), sorted(uuids))
@ -187,7 +194,8 @@ class TestListService(api_base.FunctionalTest):
self.context, id=id_,
uuid=utils.generate_uuid())
mock_service_list.return_value = [service]
response = self.get_json('/services/?limit=1')
response = self.get_json('/services/?limit=1&bay_ident=5d12f6fd-a196-'
'4bf0-ae4c-1f639a523a52')
self.assertEqual(1, len(response['services']))
next_marker = response['services'][-1]['uuid']
@ -201,7 +209,8 @@ class TestListService(api_base.FunctionalTest):
self.context, id=id_,
uuid=utils.generate_uuid())
mock_service_list.return_value = [service]
response = self.get_json('/services')
response = self.get_json('/services?bay_ident=5d12f6fd-a196-4bf0-ae4c-'
'1f639a523a52')
self.assertEqual(1, len(response['services']))
@ -211,6 +220,8 @@ class TestPatch(api_base.FunctionalTest):
super(TestPatch, self).setUp()
self.bay = obj_utils.create_test_bay(self.context,
uuid=utils.generate_uuid())
obj_utils.create_test_baymodel(self.context, uuid=self.bay.baymodel_id,
coe='kubernetes')
self.bay2 = obj_utils.create_test_bay(self.context,
uuid=utils.generate_uuid())
self.service = obj_utils.create_test_service(self.context,
@ -261,13 +272,13 @@ class TestPatch(api_base.FunctionalTest):
err = rest.ApiException(status=404)
mock_service_update.side_effect = err
response = self.patch_json(
'/services/%s/%s' % (utils.generate_uuid(),
'5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
'/services/%s?bay_ident=%s' %
(utils.generate_uuid(), '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
[{'path': '/bay_uuid',
'value': self.bay2.uuid,
'op': 'replace'}],
expect_errors=True)
self.assertEqual(400, response.status_int)
self.assertEqual(404, response.status_int)
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
@ -384,7 +395,7 @@ class TestPatch(api_base.FunctionalTest):
uuid=utils.generate_uuid())
response = self.patch_json(
'/services/test_service/5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
'/services/test_service?bay_ident=%s' % self.bay.uuid,
[{'path': '/bay_uuid',
'value': self.bay2.uuid,
'op': 'replace'}],
@ -508,7 +519,9 @@ class TestDelete(api_base.FunctionalTest):
def setUp(self):
super(TestDelete, self).setUp()
obj_utils.create_test_bay(self.context)
bay = obj_utils.create_test_bay(self.context)
obj_utils.create_test_baymodel(self.context, uuid=bay.baymodel_id,
coe='kubernetes')
self.service = obj_utils.create_test_service(self.context)
@mock.patch.object(rpcapi.API, 'service_delete')

View File

@ -30,16 +30,17 @@ class TestValidation(base.BaseTestCase):
mock_pecan_request,
bay_type,
allowed_bay_types,
assert_raised=False):
assert_raised=False,
*args):
@v.enforce_bay_types(*allowed_bay_types)
def test(self, obj):
return obj.name
def test(self, *args):
if hasattr(args[0], 'bay_uuid'):
return args[0].name
else:
return args[1]
context = mock_pecan_request.context
obj = mock.MagicMock()
obj.name = 'test_object'
obj.bay_uuid = 'bay_uuid'
bay = mock.MagicMock()
bay.baymodel_id = 'baymodel_id'
baymodel = mock.MagicMock()
@ -49,13 +50,19 @@ class TestValidation(base.BaseTestCase):
mock_baymodel_get_by_uuid.return_value = baymodel
if assert_raised:
self.assertRaises(exception.InvalidParameterValue, test, self, obj)
self.assertRaises(
exception.InvalidParameterValue, test, self, *args)
else:
ret = test(self, obj)
mock_bay_get_by_uuid.assert_called_once_with(context, 'bay_uuid')
ret = test(self, *args)
mock_baymodel_get_by_uuid.assert_called_once_with(
context, 'baymodel_id')
self.assertEqual('test_object', ret)
if hasattr(args[0], 'bay_uuid'):
mock_bay_get_by_uuid.assert_called_once_with(context,
args[0].bay_uuid)
self.assertEqual(args[0].name, ret)
else:
mock_bay_get_by_uuid.assert_called_once_with(context, args[1])
self.assertEqual(args[1], ret)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.BayModel.get_by_uuid')
@ -66,11 +73,14 @@ class TestValidation(base.BaseTestCase):
mock_baymodel_get_by_uuid,
mock_pecan_request):
obj = mock.MagicMock()
obj.name = 'test_object'
obj.bay_uuid = 'bay_uuid'
bay_type = 'type1'
allowed_bay_types = ['type1']
self._test_enforce_bay_types(
mock_bay_get_by_uuid, mock_baymodel_get_by_uuid,
mock_pecan_request, bay_type, allowed_bay_types)
mock_pecan_request, bay_type, allowed_bay_types, False, obj)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.BayModel.get_by_uuid')
@ -81,11 +91,14 @@ class TestValidation(base.BaseTestCase):
mock_baymodel_get_by_uuid,
mock_pecan_request):
obj = mock.MagicMock()
obj.name = 'test_object'
obj.bay_uuid = 'bay_uuid'
bay_type = 'type1'
allowed_bay_types = ['type1', 'type2']
self._test_enforce_bay_types(
mock_bay_get_by_uuid, mock_baymodel_get_by_uuid,
mock_pecan_request, bay_type, allowed_bay_types)
mock_pecan_request, bay_type, allowed_bay_types, False, obj)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.BayModel.get_by_uuid')
@ -96,12 +109,77 @@ class TestValidation(base.BaseTestCase):
mock_baymodel_get_by_uuid,
mock_pecan_request):
obj = mock.MagicMock()
obj.name = 'test_object'
obj.bay_uuid = 'bay_uuid'
bay_type = 'type1'
allowed_bay_types = ['type2']
self._test_enforce_bay_types(
mock_bay_get_by_uuid, mock_baymodel_get_by_uuid,
mock_pecan_request, bay_type, allowed_bay_types,
assert_raised=True)
True, obj)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.BayModel.get_by_uuid')
@mock.patch('magnum.objects.Bay.get_by_uuid')
def test_enforce_bay_types_with_bay_uuid(self, mock_bay_get_by_uuid,
mock_baymodel_get_by_uuid,
mock_pecan_request):
bay_ident = 'e74c40e0-d825-11e2-a28f-0800200c9a66'
bay_type = 'type1'
allowed_bay_types = ['type1']
self._test_enforce_bay_types(
mock_bay_get_by_uuid, mock_baymodel_get_by_uuid,
mock_pecan_request, bay_type, allowed_bay_types, False,
None, bay_ident)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.BayModel.get_by_uuid')
@mock.patch('magnum.objects.Bay.get_by_uuid')
def test_enforce_bay_types_with_bay_uuid_not_allowed(
self, mock_bay_get_by_uuid,
mock_baymodel_get_by_uuid, mock_pecan_request):
bay_ident = 'e74c40e0-d825-11e2-a28f-0800200c9a66'
bay_type = 'type1'
allowed_bay_types = ['type2']
self._test_enforce_bay_types(
mock_bay_get_by_uuid, mock_baymodel_get_by_uuid,
mock_pecan_request, bay_type, allowed_bay_types, True,
None, bay_ident)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.BayModel.get_by_uuid')
@mock.patch('magnum.objects.Bay.get_by_name')
def test_enforce_bay_types_with_bay_name(self, mock_bay_get_by_uuid,
mock_baymodel_get_by_uuid,
mock_pecan_request):
bay_ident = 'bay_name'
bay_type = 'type1'
allowed_bay_types = ['type1']
self._test_enforce_bay_types(
mock_bay_get_by_uuid, mock_baymodel_get_by_uuid,
mock_pecan_request, bay_type, allowed_bay_types, False,
None, bay_ident)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.BayModel.get_by_uuid')
@mock.patch('magnum.objects.Bay.get_by_name')
def test_enforce_bay_types_with_bay_name_not_allowed(
self, mock_bay_get_by_uuid,
mock_baymodel_get_by_uuid, mock_pecan_request):
bay_ident = 'bay_name'
bay_type = 'type1'
allowed_bay_types = ['type2']
self._test_enforce_bay_types(
mock_bay_get_by_uuid, mock_baymodel_get_by_uuid,
mock_pecan_request, bay_type, allowed_bay_types, True,
None, bay_ident)
def _test_enforce_network_driver_types_create(
self,