Ignore exc on FIP association if state is correct

If we're getting Conflict exception on FIP association we should check
if that FIP isn't already associated correctly and if that's the case
ignore the exception. This commit implements that behavior.

This solves the case when kuryr-controller is restarted after FIP
association but before that fact is saved into LBaaSState annotation.

Change-Id: I1126906516b787a5ce4dc5421f5323ad4f4b331c
Closes-Bug: 1798549
This commit is contained in:
Michał Dulko 2018-10-18 10:54:21 +02:00
parent 4595eecf26
commit a5ee0fdb06
2 changed files with 34 additions and 2 deletions

View File

@ -138,10 +138,20 @@ class FipPubIpDriver(BasePubIpDriver):
try:
response = neutron.update_floatingip(
res_id, {'floatingip': {'port_id': vip_port_id, }})
except n_exc.NeutronClientException as ex:
except n_exc.Conflict:
LOG.warning("Conflict when assigning floating IP with id %s. "
"Checking if it's already assigned correctly.", res_id)
fip = neutron.get_floatingip(res_id)
used_port_id = fip['port_id']
if used_port_id != vip_port_id:
LOG.exception("Floating IP already used by port %s.",
used_port_id)
raise
except n_exc.NeutronClientException:
LOG.error("Failed to update_floatingip ,floating_ip_id=%s,"
"response=%s!", res_id, response)
raise ex
raise
def associate(self, res_id, vip_port_id):
self._update(res_id, vip_port_id)

View File

@ -121,6 +121,28 @@ class TestFipPubIpDriver(test_base.TestCase):
self.assertRaises(n_exc.NeutronClientException, self.driver.associate,
res_id, vip_port_id)
def test_associate_conflict_correct(self):
driver = d_public_ip.FipPubIpDriver()
res_id = mock.sentinel.res_id
vip_port_id = mock.sentinel.vip_port_id
neutron = self.useFixture(k_fix.MockNeutronClient()).client
neutron.update_floatingip.side_effect = n_exc.Conflict
neutron.get_floatingip.return_value = {'id': res_id,
'port_id': vip_port_id}
self.assertIsNone(driver.associate(res_id, vip_port_id))
def test_associate_conflict_incorrect(self):
driver = d_public_ip.FipPubIpDriver()
res_id = mock.sentinel.res_id
vip_port_id = mock.sentinel.vip_port_id
neutron = self.useFixture(k_fix.MockNeutronClient()).client
neutron.update_floatingip.side_effect = n_exc.Conflict
neutron.get_floatingip.return_value = {'id': res_id, 'port_id': 'foo'}
self.assertRaises(n_exc.Conflict, driver.associate, res_id,
vip_port_id)
def test_associate_succeeded(self):
res_id = mock.sentinel.res_id
vip_port_id = mock.sentinel.vip_port_id