Merge "Handle neutron-client conflict" into stable/2024.1

This commit is contained in:
Zuul 2024-11-27 19:43:20 +00:00 committed by Gerrit Code Review
commit 8555afb07d
4 changed files with 42 additions and 1 deletions

View File

@ -439,7 +439,8 @@ class SecurityGroupActionController(wsgi.Controller):
except (exception.SecurityGroupNotFound,
exception.InstanceNotFound) as exp:
raise exc.HTTPNotFound(explanation=exp.format_message())
except exception.NoUniqueMatch as exp:
except (exception.NoUniqueMatch,
exception.SecurityGroupConnectionStateConflict) as exp:
raise exc.HTTPConflict(explanation=exp.format_message())
except exception.SecurityGroupCannotBeApplied as exp:
raise exc.HTTPBadRequest(explanation=exp.format_message())

View File

@ -1056,6 +1056,12 @@ class SecurityGroupCannotBeApplied(Invalid):
" in order to apply security groups.")
class SecurityGroupConnectionStateConflict(Invalid):
code = 409
msg_fmt = _("Cannot apply both stateful and stateless security groups on "
"the same port.")
class NoUniqueMatch(NovaException):
msg_fmt = _("No Unique Match Found.")
code = 409

View File

@ -649,6 +649,8 @@ def add_to_instance(context, instance, security_group_name):
except n_exc.NeutronClientException as e:
if e.status_code == 400:
raise exception.SecurityGroupCannotBeApplied(str(e))
elif e.status_code == 409:
raise exception.SecurityGroupConnectionStateConflict(str(e))
else:
raise e
except Exception:

View File

@ -373,6 +373,38 @@ class TestNeutronDriver(test.NoDBTestCase):
self.mocked_client.update_port.assert_called_once_with(
port_id, {'port': {'security_groups': [sg_id]}})
def test_add_to_instance_with_conflicting_sg(self):
sg1_name = 'sg-stateful'
sg1_id = '85cc3048-abc3-43cc-89b3-377341426ac5'
port_id = 1
port_list = {'ports': [{'id': port_id, 'device_id': uuids.instance,
'fixed_ips': [{'ip_address': '10.0.0.1'}],
'port_security_enabled': True, 'security_groups': []}]}
self.mocked_client.list_ports.return_value = port_list
with mock.patch.object(neutronv20, 'find_resourceid_by_name_or_id',
return_value=sg1_id):
sg_api.add_to_instance(
self.context, objects.Instance(uuid=uuids.instance), sg1_name)
self.mocked_client.list_ports.assert_called_once_with(
device_id=uuids.instance)
self.mocked_client.update_port.assert_called_once_with(
port_id, {'port': {'security_groups': [sg1_id]}})
sg2_name = 'sg-stateless'
sg2_id = '85cc3048-abc3-43cc-89b3-377341426ac5'
port_id = 1
port_list = {'ports': [{'id': port_id, 'device_id': uuids.instance,
'fixed_ips': [{'ip_address': '10.0.0.1'}],
'port_security_enabled': True, 'security_groups': []}]}
self.mocked_client.list_ports.return_value = port_list
self.mocked_client.update_port.side_effect = (
n_exc.Conflict(message='error'))
with mock.patch.object(neutronv20, 'find_resourceid_by_name_or_id',
return_value=sg2_id):
self.assertRaises(exception.SecurityGroupConnectionStateConflict,
sg_api.add_to_instance, self.context,
objects.Instance(uuid=uuids.instance), sg2_name)
def test_add_to_instance_duplicate_sg_name(self):
sg_name = 'web_server'
with mock.patch.object(neutronv20, 'find_resourceid_by_name_or_id',