Don't try and update port security if its not changing

Default policy in neutron doesn't allow port security to change
if network not owned by the user. To allow users to update other
attributes of a port don't send port_security_enabled attribute
to neutron unless it changes.

If user tries to change port security on a port in a network not
owned by them it will still error as it does now.

Partial-Bug: #1841050

Change-Id: I301336103cabc3f1cab3ee72d7743385ff1a10d6
(cherry picked from commit d059b0bc40)
This commit is contained in:
Sam Morrison 2021-11-23 13:56:23 +11:00 committed by Brendan Shephard
parent a9ae00b164
commit 618e444696
3 changed files with 22 additions and 4 deletions

View File

@ -480,7 +480,7 @@ class NetworkPortTests(test.BaseAdminViewTests):
self.assertRedirectsNoFollow(res, redir_url)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_port_get, 2,
self.mock_port_get, 3,
mock.call(test.IsHttpRequest(), port.id))
self._check_is_extension_supported(
{'binding': 1,
@ -495,6 +495,10 @@ class NetworkPortTests(test.BaseAdminViewTests):
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
if form_data.get('port_security_enabled') == port.port_security_enabled:
extension_kwargs.pop('port_security_enabled')
self.mock_port_update.assert_called_once_with(
test.IsHttpRequest(), port.id,
name=port.name,
@ -554,7 +558,7 @@ class NetworkPortTests(test.BaseAdminViewTests):
self.assertRedirectsNoFollow(res, redir_url)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_port_get, 2,
self.mock_port_get, 3,
mock.call(test.IsHttpRequest(), port.id))
self._check_is_extension_supported(
{'binding': 1,
@ -569,6 +573,8 @@ class NetworkPortTests(test.BaseAdminViewTests):
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
if form_data.get('port_security_enabled') == port.port_security_enabled:
extension_kwargs.pop('port_security_enabled')
self.mock_port_update.assert_called_once_with(
test.IsHttpRequest(), port.id,
name=port.name,

View File

@ -185,13 +185,15 @@ class NetworkPortTests(test.TestCase):
self.assertRedirectsNoFollow(res, redir_url)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_port_get, 2,
self.mock_port_get, 3,
mock.call(test.IsHttpRequest(), port.id))
self._check_is_extension_supported({'binding': 1,
'mac-learning': 1,
'port-security': 1})
self.mock_security_group_list.assert_called_once_with(
test.IsHttpRequest(), tenant_id=self.tenant.id)
if form_data.get('port_security_enabled') == port.port_security_enabled:
extension_kwargs.pop('port_security_enabled')
self.mock_port_update.assert_called_once_with(
test.IsHttpRequest(), port.id, name=port.name,
admin_state_up=port.admin_state_up,
@ -244,7 +246,7 @@ class NetworkPortTests(test.TestCase):
self.assertRedirectsNoFollow(res, redir_url)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_port_get, 2,
self.mock_port_get, 3,
mock.call(test.IsHttpRequest(), port.id))
self._check_is_extension_supported({'binding': 1,
'mac-learning': 1,
@ -259,6 +261,8 @@ class NetworkPortTests(test.TestCase):
if port_security:
extension_kwargs['port_security_enabled'] = True
extension_kwargs['security_groups'] = sg_ids
if form_data.get('port_security_enabled') == port.port_security_enabled:
extension_kwargs.pop('port_security_enabled')
self.mock_port_update.assert_called_once_with(
test.IsHttpRequest(), port.id, name=port.name,
admin_state_up=port.admin_state_up,

View File

@ -405,10 +405,18 @@ class UpdatePort(workflows.Workflow):
name = self.context['name'] or self.context['port_id']
return message % name
def _port_security_unchanged(self, request, port_id, params):
new = params.get('port_security_enabled')
port = api.neutron.port_get(request, port_id)
existing = port.get('port_security_enabled')
return existing == new
def handle(self, request, data):
port_id = self.context['port_id']
LOG.debug('params = %s', data)
params = self._construct_parameters(data)
if self._port_security_unchanged(request, port_id, params):
params.pop('port_security_enabled')
try:
api.neutron.port_update(request, port_id, **params)
return True