Merge "Fix flavor_access extension follow API V3 rules"

This commit is contained in:
Jenkins
2013-07-31 16:52:10 +00:00
committed by Gerrit Code Review
2 changed files with 140 additions and 60 deletions

View File

@@ -71,11 +71,9 @@ class FlavorAccessTemplate(xmlutil.TemplateBuilder):
def _marshall_flavor_access(flavor_id):
rval = []
try:
access_list = flavors.\
get_flavor_access_by_flavor_id(flavor_id)
except exception.FlavorNotFound:
explanation = _("Flavor not found.")
raise webob.exc.HTTPNotFound(explanation=explanation)
access_list = flavors.get_flavor_access_by_flavor_id(flavor_id)
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
for access in access_list:
rval.append({'flavor_id': flavor_id,
@@ -90,6 +88,7 @@ class FlavorAccessController(object):
def __init__(self):
super(FlavorAccessController, self).__init__()
@extensions.expected_errors(404)
@wsgi.serializers(xml=FlavorAccessTemplate)
def index(self, req, flavor_id):
context = req.environ['nova.context']
@@ -97,9 +96,8 @@ class FlavorAccessController(object):
try:
flavor = flavors.get_flavor_by_flavor_id(flavor_id)
except exception.FlavorNotFound:
explanation = _("Flavor not found.")
raise webob.exc.HTTPNotFound(explanation=explanation)
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
# public flavor to all projects
if flavor['is_public']:
@@ -112,11 +110,6 @@ class FlavorAccessController(object):
class FlavorActionController(wsgi.Controller):
"""The flavor access API controller for the OpenStack API."""
def _check_body(self, body):
if body is None or body == "":
raise webob.exc.HTTPBadRequest(explanation=_("No request body"))
def _get_flavor_refs(self, context):
"""Return a dictionary mapping flavorid to flavor_ref."""
@@ -163,36 +156,51 @@ class FlavorActionController(wsgi.Controller):
self._extend_flavor(resp_obj.obj['flavor'], db_flavor)
@extensions.expected_errors((400, 404, 409))
@wsgi.serializers(xml=FlavorAccessTemplate)
@wsgi.action("addTenantAccess")
def _addTenantAccess(self, req, id, body):
@wsgi.action("add_tenant_access")
def _add_tenant_access(self, req, id, body):
context = req.environ['nova.context']
authorize(context)
self._check_body(body)
if not self.is_valid_body(body, 'add_tenant_access'):
raise webob.exc.HTTPBadRequest(explanation=_("Invalid request"))
vals = body['addTenantAccess']
tenant = vals['tenant']
vals = body['add_tenant_access']
try:
tenant = vals['tenant_id']
except KeyError:
raise webob.exc.HTTPBadRequest(
explanation=_("tenant_id is required"))
try:
flavors.add_flavor_access(id, tenant, context)
except exception.FlavorAccessExists as err:
raise webob.exc.HTTPConflict(explanation=err.format_message())
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
return _marshall_flavor_access(id)
@extensions.expected_errors((400, 404))
@wsgi.serializers(xml=FlavorAccessTemplate)
@wsgi.action("removeTenantAccess")
def _removeTenantAccess(self, req, id, body):
@wsgi.action("remove_tenant_access")
def _remove_tenant_access(self, req, id, body):
context = req.environ['nova.context']
authorize(context)
self._check_body(body)
if not self.is_valid_body(body, 'remove_tenant_access'):
raise webob.exc.HTTPBadRequest(explanation=_("Invalid request"))
vals = body['removeTenantAccess']
tenant = vals['tenant']
vals = body['remove_tenant_access']
try:
tenant = vals['tenant_id']
except KeyError:
raise webob.exc.HTTPBadRequest(
explanation=_("tenant_id is required"))
try:
flavors.remove_flavor_access(id, tenant, context)
except exception.FlavorAccessNotFound as e:
except (exception.FlavorAccessNotFound,
exception.FlavorNotFound) as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
return _marshall_flavor_access(id)

View File

@@ -136,8 +136,8 @@ class FlavorAccessTest(test.TestCase):
def test_list_flavor_access_public(self):
# query os-flavor-access on public flavor should return 404
req = fakes.HTTPRequest.blank('/v3/fake/flavors/os-flavor-access',
use_admin_context=True)
req = fakes.HTTPRequestV3.blank('/flavors/os-flavor-access',
use_admin_context=True)
self.assertRaises(exc.HTTPNotFound,
self.flavor_access_controller.index,
self.req, '1')
@@ -151,38 +151,38 @@ class FlavorAccessTest(test.TestCase):
def test_list_flavor_with_admin_default_proj1(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors',
use_admin_context=True)
req = fakes.HTTPRequestV3.blank('/flavors',
use_admin_context=True)
req.environ['nova.context'].project_id = 'proj1'
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_admin_default_proj2(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}, {'id': '2'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors',
use_admin_context=True)
req = fakes.HTTPRequestV3.blank('/flavors',
use_admin_context=True)
req.environ['nova.context'].project_id = 'proj2'
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_admin_ispublic_true(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors?is_public=true',
use_admin_context=True)
req = fakes.HTTPRequestV3.blank('/flavors?is_public=true',
use_admin_context=True)
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_admin_ispublic_false(self):
expected = {'flavors': [{'id': '2'}, {'id': '3'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors?is_public=false',
use_admin_context=True)
req = fakes.HTTPRequestV3.blank('/flavors?is_public=false',
use_admin_context=True)
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_admin_ispublic_false_proj2(self):
expected = {'flavors': [{'id': '2'}, {'id': '3'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors?is_public=false',
use_admin_context=True)
req = fakes.HTTPRequestV3.blank('/flavors?is_public=false',
use_admin_context=True)
req.environ['nova.context'].project_id = 'proj2'
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
@@ -190,36 +190,36 @@ class FlavorAccessTest(test.TestCase):
def test_list_flavor_with_admin_ispublic_none(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}, {'id': '2'},
{'id': '3'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors?is_public=none',
use_admin_context=True)
req = fakes.HTTPRequestV3.blank('/flavors?is_public=none',
use_admin_context=True)
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_no_admin_default(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors',
use_admin_context=False)
req = fakes.HTTPRequestV3.blank('/flavors',
use_admin_context=False)
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_no_admin_ispublic_true(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors?is_public=true',
use_admin_context=False)
req = fakes.HTTPRequestV3.blank('/flavors?is_public=true',
use_admin_context=False)
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_no_admin_ispublic_false(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors?is_public=false',
use_admin_context=False)
req = fakes.HTTPRequestV3.blank('/flavors?is_public=false',
use_admin_context=False)
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
def test_list_flavor_with_no_admin_ispublic_none(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequest.blank('/v3/fake/flavors?is_public=none',
use_admin_context=False)
req = fakes.HTTPRequestV3.blank('/flavors?is_public=none',
use_admin_context=False)
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
@@ -253,25 +253,61 @@ class FlavorAccessTest(test.TestCase):
stub_add_flavor_access)
expected = {'flavor_access':
[{'flavor_id': '3', 'tenant_id': 'proj3'}]}
body = {'addTenantAccess': {'tenant': 'proj2'}}
req = fakes.HTTPRequest.blank('/v3/fake/flavors/2/action',
use_admin_context=True)
body = {'add_tenant_access': {'tenant_id': 'proj2'}}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
result = self.flavor_action_controller.\
_addTenantAccess(req, '3', body)
_add_tenant_access(req, '3', body)
self.assertEqual(result, expected)
def test_add_tenant_access_with_non_existed_flavor(self):
def stub_add_flavor_access(flavorid, projectid, ctxt=None):
raise exception.FlavorNotFound(flavor_id=flavorid)
self.stubs.Set(flavors, 'add_flavor_access',
stub_add_flavor_access)
body = {'add_tenant_access': {'tenant_id': 'proj2'}}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPNotFound,
self.flavor_action_controller._add_tenant_access,
req, '3', body)
def test_add_tenant_access_without_tenant_id(self):
def stub_add_flavor_access(flavorid, projectid, ctxt=None):
raise exception.FlavorNotFound(flavor_id=flavorid)
self.stubs.Set(flavors, 'add_flavor_access',
stub_add_flavor_access)
body = {'add_tenant_access': {}}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPBadRequest,
self.flavor_action_controller._add_tenant_access,
req, '3', body)
def test_add_tenant_access_with_invalid_request(self):
def stub_add_flavor_access(flavorid, projectid, ctxt=None):
raise exception.FlavorNotFound(flavor_id=flavorid)
self.stubs.Set(flavors, 'add_flavor_access',
stub_add_flavor_access)
body = {'add_tenant_access': None}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPBadRequest,
self.flavor_action_controller._add_tenant_access,
req, '3', body)
def test_add_tenant_access_with_already_added_access(self):
def stub_add_flavor_access(flavorid, projectid, ctxt=None):
raise exception.FlavorAccessExists(flavor_id=flavorid,
project_id=projectid)
self.stubs.Set(flavors, 'add_flavor_access',
stub_add_flavor_access)
body = {'addTenantAccess': {'tenant': 'proj2'}}
req = fakes.HTTPRequest.blank('/v3/fake/flavors/2/action',
use_admin_context=True)
body = {'add_tenant_access': {'tenant_id': 'proj2'}}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPConflict,
self.flavor_action_controller._addTenantAccess,
self.req, '3', body)
self.flavor_action_controller._add_tenant_access,
req, '3', body)
def test_remove_tenant_access_with_bad_access(self):
def stub_remove_flavor_access(flavorid, projectid, ctxt=None):
@@ -279,12 +315,48 @@ class FlavorAccessTest(test.TestCase):
project_id=projectid)
self.stubs.Set(flavors, 'remove_flavor_access',
stub_remove_flavor_access)
body = {'removeTenantAccess': {'tenant': 'proj2'}}
req = fakes.HTTPRequest.blank('/v3/fake/flavors/2/action',
use_admin_context=True)
body = {'remove_tenant_access': {'tenant_id': 'proj2'}}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPNotFound,
self.flavor_action_controller._removeTenantAccess,
self.req, '3', body)
self.flavor_action_controller._remove_tenant_access,
req, '3', body)
def test_remove_tenant_access_with_non_existed_flavor(self):
def stub_remove_flavor_access(flavorid, projectid, ctxt=None):
raise exception.FlavorNotFound(flavor_id=flavorid)
self.stubs.Set(flavors, 'remove_flavor_access',
stub_remove_flavor_access)
body = {'remove_tenant_access': {'tenant_id': 'proj2'}}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPNotFound,
self.flavor_action_controller._remove_tenant_access,
req, '3', body)
def test_remove_tenant_access_without_tenant_id(self):
def stub_remove_flavor_access(flavorid, projectid, ctxt=None):
raise exception.FlavorNotFound(flavor_id=flavorid)
self.stubs.Set(flavors, 'remove_flavor_access',
stub_remove_flavor_access)
body = {'remove_tenant_access': {}}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPBadRequest,
self.flavor_action_controller._remove_tenant_access,
req, '3', body)
def test_remove_tenant_access_with_invalid_request(self):
def stub_remove_flavor_access(flavorid, projectid, ctxt=None):
raise exception.FlavorNotFound(flavor_id=flavorid)
self.stubs.Set(flavors, 'remove_flavor_access',
stub_remove_flavor_access)
body = {'remove_tenant_access': None}
req = fakes.HTTPRequestV3.blank('/flavors/3/action',
use_admin_context=True)
self.assertRaises(exc.HTTPBadRequest,
self.flavor_action_controller._remove_tenant_access,
req, '3', body)
class FlavorAccessSerializerTest(test.TestCase):