Merge "allow delete_port to work when there are multiple floating ips"
This commit is contained in:
commit
b9ae41faae
@ -828,23 +828,21 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
|
||||
'port_owner': port_db['device_owner']})
|
||||
|
||||
def disassociate_floatingips(self, context, port_id):
|
||||
router_ids = set()
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
try:
|
||||
fip_qry = context.session.query(FloatingIP)
|
||||
floating_ip = fip_qry.filter_by(fixed_port_id=port_id).one()
|
||||
router_id = floating_ip['router_id']
|
||||
fip_qry = context.session.query(FloatingIP)
|
||||
floating_ips = fip_qry.filter_by(fixed_port_id=port_id)
|
||||
for floating_ip in floating_ips:
|
||||
router_ids.add(floating_ip['router_id'])
|
||||
floating_ip.update({'fixed_port_id': None,
|
||||
'fixed_ip_address': None,
|
||||
'router_id': None})
|
||||
except exc.NoResultFound:
|
||||
return
|
||||
except exc.MultipleResultsFound:
|
||||
# should never happen
|
||||
raise Exception(_('Multiple floating IPs found for port %s')
|
||||
% port_id)
|
||||
if router_id:
|
||||
|
||||
if router_ids:
|
||||
self.l3_rpc_notifier.routers_updated(
|
||||
context, [router_id])
|
||||
context, list(router_ids),
|
||||
'disassociate_floatingips')
|
||||
|
||||
def _build_routers_list(self, routers, gw_ports):
|
||||
gw_port_id_gw_port_dict = dict((gw_port['id'], gw_port)
|
||||
|
@ -1110,8 +1110,9 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
"""Disassociate floating IPs (if any) from this port."""
|
||||
try:
|
||||
fip_qry = context.session.query(l3_db.FloatingIP)
|
||||
fip_db = fip_qry.filter_by(fixed_port_id=port_id).one()
|
||||
self._remove_nat_rules(context, fip_db)
|
||||
fip_dbs = fip_qry.filter_by(fixed_port_id=port_id)
|
||||
for fip_db in fip_dbs:
|
||||
self._remove_nat_rules(context, fip_db)
|
||||
except sa_exc.NoResultFound:
|
||||
pass
|
||||
|
||||
|
@ -1980,15 +1980,17 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
def disassociate_floatingips(self, context, port_id):
|
||||
try:
|
||||
fip_qry = context.session.query(l3_db.FloatingIP)
|
||||
fip_db = fip_qry.filter_by(fixed_port_id=port_id).one()
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, fip_db.router_id)
|
||||
self._retrieve_and_delete_nat_rules(context,
|
||||
fip_db.floating_ip_address,
|
||||
fip_db.fixed_ip_address,
|
||||
nsx_router_id,
|
||||
min_num_rules_expected=1)
|
||||
self._remove_floatingip_address(context, fip_db)
|
||||
fip_dbs = fip_qry.filter_by(fixed_port_id=port_id)
|
||||
|
||||
for fip_db in fip_dbs:
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, fip_db.router_id)
|
||||
self._retrieve_and_delete_nat_rules(context,
|
||||
fip_db.floating_ip_address,
|
||||
fip_db.fixed_ip_address,
|
||||
nsx_router_id,
|
||||
min_num_rules_expected=1)
|
||||
self._remove_floatingip_address(context, fip_db)
|
||||
except sa_exc.NoResultFound:
|
||||
LOG.debug(_("The port '%s' is not associated with floating IPs"),
|
||||
port_id)
|
||||
|
@ -753,20 +753,25 @@ class NsxAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
self._update_nat_rules(context, router)
|
||||
|
||||
def disassociate_floatingips(self, context, port_id):
|
||||
routers = set()
|
||||
|
||||
try:
|
||||
fip_qry = context.session.query(l3_db.FloatingIP)
|
||||
fip_db = fip_qry.filter_by(fixed_port_id=port_id).one()
|
||||
router_id = fip_db.router_id
|
||||
fip_dbs = fip_qry.filter_by(fixed_port_id=port_id)
|
||||
for fip_db in fip_dbs:
|
||||
routers.add(fip_db.router_id)
|
||||
except sa_exc.NoResultFound:
|
||||
router_id = None
|
||||
pass
|
||||
super(NsxAdvancedPlugin, self).disassociate_floatingips(context,
|
||||
port_id)
|
||||
if router_id and self._is_advanced_service_router(context, router_id):
|
||||
router = self._get_router(context, router_id)
|
||||
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||
# do sync work (rollback, re-configure, or make router down)
|
||||
self._update_interface(context, router)
|
||||
self._update_nat_rules(context, router)
|
||||
|
||||
for router_id in routers:
|
||||
if self._is_advanced_service_router(context, router_id):
|
||||
router = self._get_router(context, router_id)
|
||||
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||
# do sync work (rollback, re-configure, or make router down)
|
||||
self._update_interface(context, router)
|
||||
self._update_nat_rules(context, router)
|
||||
|
||||
#
|
||||
# FWaaS plugin implementation
|
||||
|
@ -1285,6 +1285,72 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
|
||||
self.assertEqual(body['floatingip']['fixed_ip_address'],
|
||||
ip_address)
|
||||
|
||||
def test_floatingip_create_different_fixed_ip_same_port(self):
|
||||
'''This tests that it is possible to delete a port that has
|
||||
multiple floating ip addresses associated with it (each floating
|
||||
address associated with a unique fixed address).
|
||||
'''
|
||||
|
||||
with self.router() as r:
|
||||
with self.subnet(cidr='11.0.0.0/24') as public_sub:
|
||||
self._set_net_external(public_sub['subnet']['network_id'])
|
||||
self._add_external_gateway_to_router(
|
||||
r['router']['id'],
|
||||
public_sub['subnet']['network_id'])
|
||||
|
||||
with self.subnet() as private_sub:
|
||||
ip_range = list(netaddr.IPNetwork(
|
||||
private_sub['subnet']['cidr']))
|
||||
fixed_ips = [{'ip_address': str(ip_range[-3])},
|
||||
{'ip_address': str(ip_range[-2])}]
|
||||
|
||||
self._router_interface_action(
|
||||
'add', r['router']['id'],
|
||||
private_sub['subnet']['id'], None)
|
||||
|
||||
with self.port(subnet=private_sub,
|
||||
fixed_ips=fixed_ips) as p:
|
||||
|
||||
fip1 = self._make_floatingip(
|
||||
self.fmt,
|
||||
public_sub['subnet']['network_id'],
|
||||
p['port']['id'],
|
||||
fixed_ip=str(ip_range[-2]))
|
||||
fip2 = self._make_floatingip(
|
||||
self.fmt,
|
||||
public_sub['subnet']['network_id'],
|
||||
p['port']['id'],
|
||||
fixed_ip=str(ip_range[-3]))
|
||||
|
||||
# Test that floating ips are assigned successfully.
|
||||
body = self._show('floatingips',
|
||||
fip1['floatingip']['id'])
|
||||
self.assertEqual(
|
||||
body['floatingip']['port_id'],
|
||||
fip1['floatingip']['port_id'])
|
||||
|
||||
body = self._show('floatingips',
|
||||
fip2['floatingip']['id'])
|
||||
self.assertEqual(
|
||||
body['floatingip']['port_id'],
|
||||
fip2['floatingip']['port_id'])
|
||||
|
||||
# Test that port has been successfully deleted.
|
||||
body = self._show('ports', p['port']['id'],
|
||||
expected_code=exc.HTTPNotFound.code)
|
||||
|
||||
for fip in [fip1, fip2]:
|
||||
self._delete('floatingips',
|
||||
fip['floatingip']['id'])
|
||||
|
||||
self._router_interface_action(
|
||||
'remove', r['router']['id'],
|
||||
private_sub['subnet']['id'], None)
|
||||
|
||||
self._remove_external_gateway_from_router(
|
||||
r['router']['id'],
|
||||
public_sub['subnet']['network_id'])
|
||||
|
||||
def test_floatingip_update_different_fixed_ip_same_port(self):
|
||||
with self.subnet() as s:
|
||||
ip_range = list(netaddr.IPNetwork(s['subnet']['cidr']))
|
||||
|
Loading…
x
Reference in New Issue
Block a user