Fix internal server error during updating QoS rule

QoS rule can be edited or created only by admin users. Because
rule object don't have tenant_id attribute there was error
in checking tenant_id of object and neutron server got internal
server error.

Now if updating object doesn't have tenant_id at all (like in
case of QoS rules), 404 error will be returned to the user.

New API tests for checking this case are added for QoS.

Change-Id: Ia82ad84a3a07df4df8eaeaed6c47d31be9493cbd
Closes-Bug: #1515564
This commit is contained in:
Sławek Kapłoński 2016-08-20 21:00:51 +00:00
parent b70803a144
commit 38b1b47fe7
3 changed files with 59 additions and 2 deletions

View File

@ -602,10 +602,12 @@ class Controller(object):
pluralized=self._collection)
except oslo_policy.PolicyNotAuthorized:
with excutils.save_and_reraise_exception() as ctxt:
# If a tenant is modifying it's own object, it's safe to return
# If a tenant is modifying its own object, it's safe to return
# a 403. Otherwise, pretend that it doesn't exist to avoid
# giving away information.
if request.context.tenant_id != orig_obj['tenant_id']:
orig_obj_tenant_id = orig_obj.get("tenant_id")
if (request.context.tenant_id != orig_obj_tenant_id or
orig_obj_tenant_id is None):
ctxt.reraise = False
msg = _('The resource could not be found.')
raise webob.exc.HTTPNotFound(msg)

View File

@ -75,6 +75,28 @@ class QosTestJSON(base.BaseAdminNetworkTest):
self.assertTrue(retrieved_policy['shared'])
self.assertEqual([], retrieved_policy['rules'])
@test.idempotent_id('6e880e0f-bbfc-4e54-87c6-680f90e1b618')
def test_policy_update_forbidden_for_regular_tenants_own_policy(self):
policy = self.create_qos_policy(name='test-policy',
description='',
shared=False,
tenant_id=self.client.tenant_id)
self.assertRaises(
exceptions.Forbidden,
self.client.update_qos_policy,
policy['id'], description='test policy')
@test.idempotent_id('4ecfd7e7-47b6-4702-be38-be9235901a87')
def test_policy_update_forbidden_for_regular_tenants_foreign_policy(self):
policy = self.create_qos_policy(name='test-policy',
description='',
shared=False,
tenant_id=self.admin_client.tenant_id)
self.assertRaises(
exceptions.NotFound,
self.client.update_qos_policy,
policy['id'], description='test policy')
@test.idempotent_id('ee263db4-009a-4641-83e5-d0e83506ba4c')
def test_shared_policy_update(self):
policy = self.create_qos_policy(name='test-policy',
@ -426,6 +448,34 @@ class QosBandwidthLimitRuleTestJSON(base.BaseAdminNetworkTest):
self.client.create_bandwidth_limit_rule,
'policy', 1, 2)
@test.idempotent_id('1bfc55d9-6fd8-4293-ab3a-b1d69bf7cd2e')
def test_rule_update_forbidden_for_regular_tenants_own_policy(self):
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False,
tenant_id=self.client.tenant_id)
rule = self.create_qos_bandwidth_limit_rule(policy_id=policy['id'],
max_kbps=1,
max_burst_kbps=1)
self.assertRaises(
exceptions.NotFound,
self.client.update_bandwidth_limit_rule,
policy['id'], rule['id'], max_kbps=2, max_burst_kbps=4)
@test.idempotent_id('9a607936-4b6f-4c2f-ad21-bd5b3d4fc91f')
def test_rule_update_forbidden_for_regular_tenants_foreign_policy(self):
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False,
tenant_id=self.admin_client.tenant_id)
rule = self.create_qos_bandwidth_limit_rule(policy_id=policy['id'],
max_kbps=1,
max_burst_kbps=1)
self.assertRaises(
exceptions.NotFound,
self.client.update_bandwidth_limit_rule,
policy['id'], rule['id'], max_kbps=2, max_burst_kbps=4)
@test.idempotent_id('ce0bd0c2-54d9-4e29-85f1-cfb36ac3ebe2')
def test_get_rules_by_policy(self):
policy1 = self.create_qos_policy(name='test-policy1',

View File

@ -1099,6 +1099,11 @@ class JSONV2TestCase(APIv2TestBase, testlib_api.WebTestCase):
self._test_update(tenant_id + "bad", tenant_id,
exc.HTTPNotFound.code, expect_errors=True)
def test_update_keystone_no_tenant(self):
tenant_id = _uuid()
self._test_update(tenant_id, None,
exc.HTTPNotFound.code, expect_errors=True)
def test_update_readonly_field(self):
data = {'network': {'status': "NANANA"}}
res = self.api.put(_get_path('networks', id=_uuid()),