Merge "fix the an Unexpected API Error issue in flavor API"

This commit is contained in:
Jenkins 2013-10-07 12:42:04 +00:00 committed by Gerrit Code Review
commit b0f6fdbc76
6 changed files with 118 additions and 17 deletions

View File

@ -109,8 +109,12 @@
"compute_extension:v3:os-extended-volumes:detach": "",
"compute_extension:fixed_ips": "rule:admin_api",
"compute_extension:flavor_access": "",
"compute_extension:flavor_access:addTenantAccess": "rule:admin_api",
"compute_extension:flavor_access:removeTenantAccess": "rule:admin_api",
"compute_extension:v3:os-flavor-access": "",
"compute_extension:v3:os-flavor-access:discoverable": "",
"compute_extension:v3:os-flavor-access:remove_tenant_access": "rule:admin_api",
"compute_extension:v3:os-flavor-access:add_tenant_access": "rule:admin_api",
"compute_extension:flavor_disabled": "",
"compute_extension:v3:os-flavor-disabled": "",
"compute_extension:v3:os-flavor-disabled:discoverable": "",

View File

@ -27,7 +27,9 @@ from nova import exception
from nova.openstack.common.gettextutils import _
authorize = extensions.soft_extension_authorizer('compute', 'flavor_access')
soft_authorize = extensions.soft_extension_authorizer('compute',
'flavor_access')
authorize = extensions.extension_authorizer('compute', 'flavor_access')
def make_flavor(elem):
@ -133,7 +135,7 @@ class FlavorActionController(wsgi.Controller):
@wsgi.extends
def show(self, req, resp_obj, id):
context = req.environ['nova.context']
if authorize(context):
if soft_authorize(context):
# Attach our slave template to the response object
resp_obj.attach(xml=FlavorTemplate())
db_flavor = req.get_db_flavor(id)
@ -143,7 +145,7 @@ class FlavorActionController(wsgi.Controller):
@wsgi.extends
def detail(self, req, resp_obj):
context = req.environ['nova.context']
if authorize(context):
if soft_authorize(context):
# Attach our slave template to the response object
resp_obj.attach(xml=FlavorsTemplate())
@ -155,7 +157,7 @@ class FlavorActionController(wsgi.Controller):
@wsgi.extends(action='create')
def create(self, req, body, resp_obj):
context = req.environ['nova.context']
if authorize(context):
if soft_authorize(context):
# Attach our slave template to the response object
resp_obj.attach(xml=FlavorTemplate())
@ -167,7 +169,8 @@ class FlavorActionController(wsgi.Controller):
@wsgi.action("addTenantAccess")
def _addTenantAccess(self, req, id, body):
context = req.environ['nova.context']
authorize(context)
authorize(context, action="addTenantAccess")
self._check_body(body)
vals = body['addTenantAccess']
@ -184,7 +187,8 @@ class FlavorActionController(wsgi.Controller):
@wsgi.action("removeTenantAccess")
def _removeTenantAccess(self, req, id, body):
context = req.environ['nova.context']
authorize(context)
authorize(context, action="removeTenantAccess")
self._check_body(body)
vals = body['removeTenantAccess']

View File

@ -27,7 +27,9 @@ from nova import exception
from nova.openstack.common.gettextutils import _
ALIAS = 'os-flavor-access'
authorize = extensions.soft_extension_authorizer('compute', 'v3:' + ALIAS)
soft_authorize = extensions.soft_extension_authorizer('compute',
'v3:' + ALIAS)
authorize = extensions.extension_authorizer('compute', 'v3:%s' % ALIAS)
def make_flavor(elem):
@ -126,7 +128,7 @@ class FlavorActionController(wsgi.Controller):
@wsgi.extends
def show(self, req, resp_obj, id):
context = req.environ['nova.context']
if authorize(context):
if soft_authorize(context):
# Attach our slave template to the response object
resp_obj.attach(xml=FlavorTemplate())
db_flavor = req.get_db_flavor(id)
@ -136,7 +138,7 @@ class FlavorActionController(wsgi.Controller):
@wsgi.extends
def detail(self, req, resp_obj):
context = req.environ['nova.context']
if authorize(context):
if soft_authorize(context):
# Attach our slave template to the response object
resp_obj.attach(xml=FlavorsTemplate())
@ -148,7 +150,7 @@ class FlavorActionController(wsgi.Controller):
@wsgi.extends(action='create')
def create(self, req, body, resp_obj):
context = req.environ['nova.context']
if authorize(context):
if soft_authorize(context):
# Attach our slave template to the response object
resp_obj.attach(xml=FlavorTemplate())
@ -156,12 +158,13 @@ class FlavorActionController(wsgi.Controller):
self._extend_flavor(resp_obj.obj['flavor'], db_flavor)
@extensions.expected_errors((400, 404, 409))
@extensions.expected_errors((400, 403, 404, 409))
@wsgi.serializers(xml=FlavorAccessTemplate)
@wsgi.action("add_tenant_access")
def _add_tenant_access(self, req, id, body):
context = req.environ['nova.context']
authorize(context)
authorize(context, action="add_tenant_access")
if not self.is_valid_body(body, 'add_tenant_access'):
raise webob.exc.HTTPBadRequest(explanation=_("Invalid request"))
@ -178,15 +181,17 @@ class FlavorActionController(wsgi.Controller):
raise webob.exc.HTTPConflict(explanation=err.format_message())
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
except exception.AdminRequired as e:
raise webob.exc.HTTPForbidden(explanation=e.format_message())
return _marshall_flavor_access(id)
@extensions.expected_errors((400, 404))
@extensions.expected_errors((400, 403, 404))
@wsgi.serializers(xml=FlavorAccessTemplate)
@wsgi.action("remove_tenant_access")
def _remove_tenant_access(self, req, id, body):
context = req.environ['nova.context']
authorize(context)
authorize(context, action="remove_tenant_access")
if not self.is_valid_body(body, 'remove_tenant_access'):
raise webob.exc.HTTPBadRequest(explanation=_("Invalid request"))
@ -202,7 +207,8 @@ class FlavorActionController(wsgi.Controller):
except (exception.FlavorAccessNotFound,
exception.FlavorNotFound) as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
except exception.AdminRequired as e:
raise webob.exc.HTTPForbidden(explanation=e.format_message())
return _marshall_flavor_access(id)

View File

@ -153,6 +153,20 @@ class FlavorAccessTest(test.NoDBTestCase):
result = self.flavor_access_controller.index(self.req, '2')
self.assertEqual(result, expected)
def test_list_with_no_context(self):
req = fakes.HTTPRequest.blank('/v2/flavors/fake/flavors')
def fake_authorize(context, target=None, action=None):
raise exception.PolicyNotAuthorized(action='index')
self.stubs.Set(flavor_access,
'authorize',
fake_authorize)
self.assertRaises(exception.PolicyNotAuthorized,
self.flavor_access_controller.index,
req, 'fake')
def test_list_flavor_with_admin_default_proj1(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequest.blank('/v2/fake/flavors',
@ -264,6 +278,14 @@ class FlavorAccessTest(test.NoDBTestCase):
_addTenantAccess(req, '3', body)
self.assertEqual(result, expected)
def test_add_tenant_access_with_no_admin_user(self):
req = fakes.HTTPRequest.blank('/v2/fake/flavors/2/action',
use_admin_context=False)
body = {'addTenantAccess': {'tenant': 'proj2'}}
self.assertRaises(exception.PolicyNotAuthorized,
self.flavor_action_controller._addTenantAccess,
req, '2', 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,
@ -290,6 +312,14 @@ class FlavorAccessTest(test.NoDBTestCase):
self.flavor_action_controller._removeTenantAccess,
self.req, '3', body)
def test_remove_tenant_access_with_no_admin_user(self):
req = fakes.HTTPRequest.blank('/v2/fake/flavors/2/action',
use_admin_context=False)
body = {'removeTenantAccess': {'tenant': 'proj2'}}
self.assertRaises(exception.PolicyNotAuthorized,
self.flavor_action_controller._removeTenantAccess,
req, '2', body)
class FlavorAccessSerializerTest(test.NoDBTestCase):
def test_serializer_empty(self):

View File

@ -140,7 +140,7 @@ class FlavorAccessTest(test.NoDBTestCase):
def test_list_flavor_access_public(self):
# query os-flavor-access on public flavor should return 404
req = fakes.HTTPRequestV3.blank('/flavors/os-flavor-access',
req = fakes.HTTPRequestV3.blank('/flavors/fake/os-flavor-access',
use_admin_context=True)
self.assertRaises(exc.HTTPNotFound,
self.flavor_access_controller.index,
@ -153,6 +153,18 @@ class FlavorAccessTest(test.NoDBTestCase):
result = self.flavor_access_controller.index(self.req, '2')
self.assertEqual(result, expected)
def test_list_with_no_context(self):
req = fakes.HTTPRequestV3.blank('/flavors/2/os-flavor-access')
def fake_authorize(context, target=None, action=None):
raise exception.PolicyNotAuthorized(action='index')
self.stubs.Set(flavor_access, 'authorize', fake_authorize)
self.assertRaises(exception.PolicyNotAuthorized,
self.flavor_access_controller.index,
req, '2')
def test_list_flavor_with_admin_default_proj1(self):
expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
req = fakes.HTTPRequestV3.blank('/flavors',
@ -276,6 +288,25 @@ class FlavorAccessTest(test.NoDBTestCase):
self.flavor_action_controller._add_tenant_access,
req, '3', body)
def test_add_tenant_access_with_no_admin_user(self):
req = fakes.HTTPRequestV3.blank('/flavors/2/action')
body = {'add_tenant_access': {'tenant_id': 'proj2'}}
self.assertRaises(exception.PolicyNotAuthorized,
self.flavor_action_controller._add_tenant_access,
req, '2', body)
def test_add_tenant_access_without_policy_check(self):
req = fakes.HTTPRequestV3.blank('/flavors/2/action')
body = {'add_tenant_access': {'tenant_id': 'proj2'}}
def fake_authorize(context, target=None, action=None):
pass
self.stubs.Set(flavor_access, 'authorize', fake_authorize)
self.assertRaises(exc.HTTPForbidden,
self.flavor_action_controller._add_tenant_access,
req, '2', 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)
@ -362,6 +393,26 @@ class FlavorAccessTest(test.NoDBTestCase):
self.flavor_action_controller._remove_tenant_access,
req, '3', body)
def test_remove_tenant_access_with_no_admin_user(self):
req = fakes.HTTPRequestV3.blank('flavors/2/action',
use_admin_context=False)
body = {'remove_tenant_access': {'tenant_id': 'proj2'}}
self.assertRaises(exception.PolicyNotAuthorized,
self.flavor_action_controller._remove_tenant_access,
req, '2', body)
def test_remove_tenant_access_without_policy_check(self):
req = fakes.HTTPRequestV3.blank('/flavors/2/action')
body = {'remove_tenant_access': {'tenant_id': 'proj2'}}
def fake_authorize(context, target=None, action=None):
pass
self.stubs.Set(flavor_access, 'authorize', fake_authorize)
self.assertRaises(exc.HTTPForbidden,
self.flavor_action_controller._remove_tenant_access,
req, '2', body)
class FlavorAccessSerializerTest(test.NoDBTestCase):
def test_serializer_empty(self):

View File

@ -172,7 +172,13 @@ policy_data = """
"compute_extension:v3:os-extended-volumes:detach": "",
"compute_extension:fixed_ips": "",
"compute_extension:flavor_access": "",
"compute_extension:flavor_access:addTenantAccess": "rule:admin_api",
"compute_extension:flavor_access:removeTenantAccess": "rule:admin_api",
"compute_extension:v3:os-flavor-access": "",
"compute_extension:v3:os-flavor-access:remove_tenant_access":
"rule:admin_api",
"compute_extension:v3:os-flavor-access:add_tenant_access":
"rule:admin_api",
"compute_extension:flavor_disabled": "",
"compute_extension:v3:os-flavor-disabled": "",
"compute_extension:flavor_rxtx": "",