NSX|V: prevent a floating IP being configure on a no snat router

Ensure that a router that has no snat set will not have floating
IPs configured.

(Cherry picked from: Id186bb13fae032a6d538cd25f7934d503e7699ab)

Change-Id: Ib0a5716363fa2a6248183f5b07b326a853ae6490
This commit is contained in:
Adit Sarfaty 2017-06-21 11:08:03 +03:00
parent 7a9f1fe386
commit d75ef535f7
2 changed files with 66 additions and 0 deletions

View File

@ -3074,6 +3074,17 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
network_id = info.get('network_id')
router_db = self._get_router(context, router_id)
org_enable_snat = router_db.enable_snat
# Ensure that a router cannot have SNAT disabled if there are
# floating IP's assigned
if ('enable_snat' in info and
org_enable_snat != info.get('enable_snat') and
info.get('enable_snat') is False and
self.router_gw_port_has_floating_ips(context, router_id)):
msg = _("Unable to set SNAT disabled. Floating IPs "
"assigned.")
raise n_exc.InvalidInput(error_message=msg)
# for multiple external subnets support, we need to set gw
# port first on subnet which has gateway. If can't get one
# subnet with gateway or allocate one available ip from
@ -3372,6 +3383,18 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
if router_id:
self._update_edge_router(context, router_id)
def get_router_for_floatingip(self, context, internal_port,
internal_subnet, external_network_id):
router_id = super(NsxVPluginV2, self).get_router_for_floatingip(
context, internal_port, internal_subnet, external_network_id)
if router_id:
router = self._get_router(context.elevated(), router_id)
if not router.enable_snat:
msg = _("Unable to assign a floating IP to a router that "
"has SNAT disabled")
raise n_exc.InvalidInput(error_message=msg)
return router_id
def disassociate_floatingips(self, context, port_id):
router_id = None
try:

View File

@ -2838,6 +2838,49 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
super(TestExclusiveRouterTestCase, self).test_floatingip_update(
constants.FLOATINGIP_STATUS_DOWN)
def test_floating_ip_no_snat(self):
"""Cannot add floating ips to a router with disabled snat"""
with self.router() as r1,\
self.subnet() as ext_subnet,\
self.subnet(cidr='11.0.0.0/24') as s1,\
self.port(subnet=s1) as private_port:
# Add interfaces to the router
self._router_interface_action(
'add', r1['router']['id'],
s1['subnet']['id'], None)
self._set_net_external(ext_subnet['subnet']['network_id'])
self._add_external_gateway_to_router(
r1['router']['id'],
ext_subnet['subnet']['network_id'])
# disable snat
self._update_router_enable_snat(
r1['router']['id'],
ext_subnet['subnet']['network_id'],
False)
# create a floating ip and associate it to the router should fail
self.assertRaises(
object,
self._make_floatingip,
self.fmt, ext_subnet['subnet']['network_id'],
private_port['port']['id'])
# now enable snat and try again
self._update_router_enable_snat(
r1['router']['id'],
ext_subnet['subnet']['network_id'],
True)
self._make_floatingip(
self.fmt, ext_subnet['subnet']['network_id'],
private_port['port']['id'])
# now shouldn't be able to disable snat
self.assertRaises(
object,
self._update_router_enable_snat,
r1['router']['id'],
ext_subnet['subnet']['network_id'],
False)
def test_floatingip_disassociate(self):
with self.port() as p:
private_sub = {'subnet': {'id':