diff options
author | Matt Riedemann <mriedem.os@gmail.com> | 2017-05-25 15:00:24 -0400 |
---|---|---|
committer | Matt Riedemann <mriedem.os@gmail.com> | 2017-05-25 15:11:01 -0400 |
commit | 452f21183f2f80cc5673ebd3fd3e5daf039caacc (patch) | |
tree | 7d9c64443c4a0ce24bc7a98640e16ce6299694c3 /nova/tests/unit | |
parent | 65402e1aeb770d077620f2935a0cb305474aa7a1 (diff) | |
download | nova-452f21183f2f80cc5673ebd3fd3e5daf039caacc.tar.gz |
Handle conflict from neutron when addFloatingIP fails
Neutron can raise a Conflict exception when attempting
to associate a floating IP to a server when the fixed
address is already associated to another floating IP.
This has always resulted in a 400 response, however, it
would also trace an ERROR in the nova-api logs, which is
something we shouldn't be doing for an expected type of
failure.
This handles the Conflict in the neutronv2 API client code
and re-raises an exception that the REST API controller code
can handle and return as a 400 without the stacktrace in the
logs.
Change-Id: I27d3241300f75e2aa79a32348a3843e09123cb10
Closes-Bug: #1693576
Diffstat (limited to 'nova/tests/unit')
-rw-r--r-- | nova/tests/unit/api/openstack/compute/test_floating_ips.py | 9 | ||||
-rw-r--r-- | nova/tests/unit/network/test_neutronv2.py | 30 |
2 files changed, 39 insertions, 0 deletions
diff --git a/nova/tests/unit/api/openstack/compute/test_floating_ips.py b/nova/tests/unit/api/openstack/compute/test_floating_ips.py index 1cb214142d..0fc45b6f72 100644 --- a/nova/tests/unit/api/openstack/compute/test_floating_ips.py +++ b/nova/tests/unit/api/openstack/compute/test_floating_ips.py @@ -634,6 +634,15 @@ class FloatingIpTestV21(test.TestCase): self.manager._add_floating_ip, self.fake_req, TEST_INST, body=body) + @mock.patch.object(network.api.API, 'associate_floating_ip', + side_effect=exception.FloatingIpAssociateFailed( + address='10.10.10.11')) + def test_associate_floating_ip_failed(self, associate_mock): + body = dict(addFloatingIp=dict(address='10.10.10.11')) + self.assertRaises(webob.exc.HTTPBadRequest, + self.manager._add_floating_ip, self.fake_req, + TEST_INST, body=body) + def test_associate_floating_ip_bad_address_key(self): body = dict(addFloatingIp=dict(bad_address='10.10.10.11')) req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') diff --git a/nova/tests/unit/network/test_neutronv2.py b/nova/tests/unit/network/test_neutronv2.py index 18bb9c0aa2..9f99638bd8 100644 --- a/nova/tests/unit/network/test_neutronv2.py +++ b/nova/tests/unit/network/test_neutronv2.py @@ -4783,6 +4783,36 @@ class TestNeutronv2WithMock(test.TestCase): self.context, pci_requests, requested_networks) self.assertFalse(getclient.called) + @mock.patch.object(neutronapi, 'get_client') + def test_associate_floating_ip_conflict(self, mock_get_client): + """Tests that if Neutron raises a Conflict we handle it and re-raise + as a nova-specific exception. + """ + mock_get_client.return_value.update_floatingip.side_effect = ( + exceptions.Conflict( + "Cannot associate floating IP 172.24.5.15 " + "(60a8f00b-4404-4518-ad66-00448a155904) with port " + "95ee1ffb-6d41-447d-a90e-b6ce5d9c92fa using fixed IP " + "10.1.0.9, as that fixed IP already has a floating IP on " + "external network bdcda645-f612-40ab-a956-0d95af42cf7c.") + ) + with test.nested( + mock.patch.object( + self.api, '_get_port_id_by_fixed_address', + return_value='95ee1ffb-6d41-447d-a90e-b6ce5d9c92fa'), + mock.patch.object( + self.api, '_get_floating_ip_by_address', + return_value={'id': uuids.floating_ip_id}) + ) as ( + _get_floating_ip_by_address, _get_port_id_by_fixed_address + ): + instance = fake_instance.fake_instance_obj( + self.context, uuid='2a2200ec-02fe-484e-885b-9bae7b21ecba') + self.assertRaises(exception.FloatingIpAssociateFailed, + self.api.associate_floating_ip, + self.context, instance, + '172.24.5.15', '10.1.0.9') + class TestNeutronv2ModuleMethods(test.NoDBTestCase): |