Fix creation of port when network has admin's QoS policy set

In case when admin user creats QoS policy and will attach it to
user's namespace there was an issue with getting such QoS policy
with user's context to validate it.

This patch changes it, that QoS policy is always get with elevated
context during port/network create/update validation.

Change-Id: I464888ca3920b42edd6ab638f6a317ee51ef0994
Closes-Bug: #1750591
This commit is contained in:
Sławek Kapłoński 2018-02-22 13:36:43 +01:00
parent 4a13ada48f
commit 8c23e35709
2 changed files with 23 additions and 9 deletions

View File

@ -93,7 +93,8 @@ class QoSPlugin(qos.QoSPluginBase):
if policy_id is None:
return
policy = policy_object.QosPolicy.get_object(context, id=policy_id)
policy = policy_object.QosPolicy.get_object(
context.elevated(), id=policy_id)
self.validate_policy_for_port(policy, port)
def _validate_update_port_callback(self, resource, event, trigger,
@ -108,7 +109,9 @@ class QoSPlugin(qos.QoSPluginBase):
updated_port = ports_object.Port.get_object(
context, id=kwargs['port']['id'])
policy = policy_object.QosPolicy.get_object(context, id=policy_id)
policy = policy_object.QosPolicy.get_object(
context.elevated(), id=policy_id)
self.validate_policy_for_port(policy, updated_port)
@ -124,7 +127,8 @@ class QoSPlugin(qos.QoSPluginBase):
if policy_id is None or policy_id == original_policy_id:
return
policy = policy_object.QosPolicy.get_object(context, id=policy_id)
policy = policy_object.QosPolicy.get_object(
context.elevated(), id=policy_id)
ports = ports_object.Port.get_objects(
context, network_id=updated_network['id'])
# Filter only this ports which don't have overwritten policy

View File

@ -67,6 +67,7 @@ class TestQosPlugin(base.BaseQosTestCase):
'.ResourcesPushRpcApi.push').start()
self.ctxt = context.Context('fake_user', 'fake_tenant')
self.admin_ctxt = context.get_admin_context()
mock.patch.object(self.ctxt.session, 'refresh').start()
mock.patch.object(self.ctxt.session, 'expunge').start()
@ -145,6 +146,7 @@ class TestQosPlugin(base.BaseQosTestCase):
network_mock = mock.MagicMock(
id=uuidutils.generate_uuid(), qos_policy_id=network_policy_id)
policy_mock = mock.MagicMock(id=policy_id)
admin_ctxt = mock.Mock()
expected_policy_id = policy_id or network_policy_id
with mock.patch(
'neutron.objects.ports.Port.get_object',
@ -157,11 +159,13 @@ class TestQosPlugin(base.BaseQosTestCase):
return_value=policy_mock
) as get_policy, mock.patch.object(
self.qos_plugin, "validate_policy_for_port"
) as validate_policy_for_port:
) as validate_policy_for_port, mock.patch.object(
self.ctxt, "elevated", return_value=admin_ctxt
):
self.qos_plugin._validate_create_port_callback(
"PORT", "precommit_create", "test_plugin", **kwargs)
if policy_id or network_policy_id:
get_policy.assert_called_once_with(self.ctxt,
get_policy.assert_called_once_with(admin_ctxt,
id=expected_policy_id)
validate_policy_for_port.assert_called_once_with(policy_mock,
port_mock)
@ -201,6 +205,7 @@ class TestQosPlugin(base.BaseQosTestCase):
}
port_mock = mock.MagicMock(id=port_id, qos_policy_id=policy_id)
policy_mock = mock.MagicMock(id=policy_id)
admin_ctxt = mock.Mock()
with mock.patch(
'neutron.objects.ports.Port.get_object',
return_value=port_mock
@ -209,7 +214,9 @@ class TestQosPlugin(base.BaseQosTestCase):
return_value=policy_mock
) as get_policy, mock.patch.object(
self.qos_plugin, "validate_policy_for_port"
) as validate_policy_for_port:
) as validate_policy_for_port, mock.patch.object(
self.ctxt, "elevated", return_value=admin_ctxt
):
self.qos_plugin._validate_update_port_callback(
"PORT", "precommit_update", "test_plugin", **kwargs)
if policy_id is None or policy_id == original_policy_id:
@ -218,7 +225,7 @@ class TestQosPlugin(base.BaseQosTestCase):
validate_policy_for_port.assert_not_called()
else:
get_port.assert_called_once_with(self.ctxt, id=port_id)
get_policy.assert_called_once_with(self.ctxt, id=policy_id)
get_policy.assert_called_once_with(admin_ctxt, id=policy_id)
validate_policy_for_port.assert_called_once_with(policy_mock,
port_mock)
@ -256,6 +263,7 @@ class TestQosPlugin(base.BaseQosTestCase):
id=uuidutils.generate_uuid(), qos_policy_id=None)
ports = [port_mock_with_own_policy, port_mock_without_own_policy]
policy_mock = mock.MagicMock(id=policy_id)
admin_ctxt = mock.Mock()
with mock.patch(
'neutron.objects.ports.Port.get_objects',
return_value=ports
@ -264,7 +272,9 @@ class TestQosPlugin(base.BaseQosTestCase):
return_value=policy_mock
) as get_policy, mock.patch.object(
self.qos_plugin, "validate_policy_for_ports"
) as validate_policy_for_ports:
) as validate_policy_for_ports, mock.patch.object(
self.ctxt, "elevated", return_value=admin_ctxt
):
self.qos_plugin._validate_update_network_callback(
"NETWORK", "precommit_update", "test_plugin", **kwargs)
if policy_id is None or policy_id == original_policy_id:
@ -272,7 +282,7 @@ class TestQosPlugin(base.BaseQosTestCase):
get_ports.assert_not_called()
validate_policy_for_ports.assert_not_called()
else:
get_policy.assert_called_once_with(self.ctxt, id=policy_id)
get_policy.assert_called_once_with(admin_ctxt, id=policy_id)
get_ports.assert_called_once_with(self.ctxt,
network_id=network_id)
validate_policy_for_ports.assert_called_once_with(