From d059b0bc40f04befc60657cd6504cc5711934b90 Mon Sep 17 00:00:00 2001 From: Sam Morrison Date: Tue, 23 Nov 2021 13:56:23 +1100 Subject: [PATCH] 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 --- .../dashboards/admin/networks/ports/tests.py | 10 ++++++++-- .../dashboards/project/networks/ports/tests.py | 8 ++++++-- .../dashboards/project/networks/ports/workflows.py | 8 ++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/openstack_dashboard/dashboards/admin/networks/ports/tests.py b/openstack_dashboard/dashboards/admin/networks/ports/tests.py index bd2e9f8fb7..cc8a6c619a 100644 --- a/openstack_dashboard/dashboards/admin/networks/ports/tests.py +++ b/openstack_dashboard/dashboards/admin/networks/ports/tests.py @@ -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, diff --git a/openstack_dashboard/dashboards/project/networks/ports/tests.py b/openstack_dashboard/dashboards/project/networks/ports/tests.py index a41936653e..7fed538d03 100644 --- a/openstack_dashboard/dashboards/project/networks/ports/tests.py +++ b/openstack_dashboard/dashboards/project/networks/ports/tests.py @@ -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, diff --git a/openstack_dashboard/dashboards/project/networks/ports/workflows.py b/openstack_dashboard/dashboards/project/networks/ports/workflows.py index 8638d60ff8..425b6240ce 100644 --- a/openstack_dashboard/dashboards/project/networks/ports/workflows.py +++ b/openstack_dashboard/dashboards/project/networks/ports/workflows.py @@ -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