NSX: properly handle floating ip status

Ensure the floating IP status is put ACTIVE or DOWN when it
is associated or disassociated.
This is done directly on the plugin class as the NSX backend
applies relevant NAT rules synchronously.

Change-Id: Ie747c4eae2ac33016fdabaade2335f7d2d24eec9
Closes-Bug: #1334708
This commit is contained in:
Salvatore Orlando 2014-06-27 11:50:00 -07:00
parent 320b9bd196
commit 3709a1be92
4 changed files with 36 additions and 4 deletions

View File

@ -1892,6 +1892,14 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
pass
return (port_id, internal_ip, router_id)
def _floatingip_status(self, floatingip_db, associated):
if (associated and
floatingip_db['status'] != constants.FLOATINGIP_STATUS_ACTIVE):
return constants.FLOATINGIP_STATUS_ACTIVE
elif (not associated and
floatingip_db['status'] != constants.FLOATINGIP_STATUS_DOWN):
return constants.FLOATINGIP_STATUS_DOWN
def _update_fip_assoc(self, context, fip, floatingip_db, external_port):
"""Update floating IP association data.
@ -1984,10 +1992,12 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
'internal_ip': internal_ip})
msg = _("Failed to update NAT rules for floatingip update")
raise nsx_exc.NsxPluginException(err_msg=msg)
floatingip_db.update({'fixed_ip_address': internal_ip,
'fixed_port_id': port_id,
'router_id': router_id})
# Update also floating ip status (no need to call base class method)
floatingip_db.update(
{'fixed_ip_address': internal_ip,
'fixed_port_id': port_id,
'router_id': router_id,
'status': self._floatingip_status(floatingip_db, router_id)})
def delete_floatingip(self, context, id):
fip_db = self._get_floatingip(context, id)

View File

@ -17,6 +17,7 @@
import netaddr
from oslo.config import cfg
from neutron.common import constants
from neutron.common import exceptions as n_exc
from neutron.db.firewall import firewall_db
from neutron.db import l3_db
@ -758,6 +759,10 @@ class NsxAdvancedPlugin(sr_db.ServiceRouter_mixin,
# do sync work (rollback, re-configure, or make router down)
self._update_nat_rules(context, router)
self._update_interface(context, router)
elif not router_id:
# The floating IP has been disassociated and should be set to DOWN
self.update_floatingip_status(context, fip['id'],
constants.FLOATINGIP_STATUS_DOWN)
return fip
def delete_floatingip(self, context, id):

View File

@ -947,6 +947,13 @@ class TestL3NatTestCase(L3NatTest,
# Test that route is deleted after dhcp port is removed
self.assertEqual(len(subnets[0]['host_routes']), 0)
def _test_floatingip_update(self, expected_status):
super(TestL3NatTestCase, self).test_floatingip_update(
expected_status)
def test_floatingip_update(self):
self._test_floatingip_update(constants.FLOATINGIP_STATUS_DOWN)
def test_floatingip_disassociate(self):
with self.port() as p:
private_sub = {'subnet': {'id':
@ -956,12 +963,18 @@ class TestL3NatTestCase(L3NatTest,
body = self._update('floatingips', fip['floatingip']['id'],
{'floatingip': {'port_id': port_id}})
self.assertEqual(body['floatingip']['port_id'], port_id)
# Floating IP status should be active
self.assertEqual(constants.FLOATINGIP_STATUS_ACTIVE,
body['floatingip']['status'])
# Disassociate
body = self._update('floatingips', fip['floatingip']['id'],
{'floatingip': {'port_id': None}})
body = self._show('floatingips', fip['floatingip']['id'])
self.assertIsNone(body['floatingip']['port_id'])
self.assertIsNone(body['floatingip']['fixed_ip_address'])
# Floating IP status should be down
self.assertEqual(constants.FLOATINGIP_STATUS_DOWN,
body['floatingip']['status'])
def test_create_router_maintenance_returns_503(self):
with self._create_l3_ext_network() as net:

View File

@ -20,6 +20,7 @@ import mock
from oslo.config import cfg
from neutron.api.v2 import attributes
from neutron.common import constants
from neutron import context
from neutron.extensions import l3
from neutron import manager as n_manager
@ -232,6 +233,9 @@ class ServiceRouterTestCase(ServiceRouterTest,
self)._test_router_update_gateway_on_l3_ext_net(
vlan_id, validate_ext_gw=False)
def test_floatingip_update(self):
self._test_floatingip_update(constants.FLOATINGIP_STATUS_ACTIVE)
class TestProxyCreateLswitch(base.BaseTestCase):
def setUp(self):