Merge "fix the an Unexpected API Error issue in flavor API"
This commit is contained in:
commit
b0f6fdbc76
@ -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": "",
|
||||
|
@ -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']
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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": "",
|
||||
|
Loading…
x
Reference in New Issue
Block a user