Midonet to support port association at floating IP creation

The Midonet plugin currently does not support associating floating IPs with
ports at floating IP creation time. This bug is created to add this support.

Change-Id: Ie57ebffa5185f26138c04b9836067417c6dc1388
Closes-Bug: #1249957
This commit is contained in:
Joe Mills 2013-11-11 06:49:17 +00:00
parent 0e2198ef75
commit cd33dbee09
2 changed files with 80 additions and 26 deletions

View File

@ -1026,6 +1026,40 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
"info=%r"), info)
return info
def _assoc_fip(self, fip):
router = self.client.get_router(fip["router_id"])
link_port = self.client.get_link_port(
self._get_provider_router(), router.get_id())
self.client.add_router_route(
self._get_provider_router(),
src_network_addr='0.0.0.0',
src_network_length=0,
dst_network_addr=fip["floating_ip_address"],
dst_network_length=32,
next_hop_port=link_port.get_peer_id())
props = {OS_FLOATING_IP_RULE_KEY: fip['id']}
tenant_id = router.get_tenant_id()
chain_names = _nat_chain_names(router.get_id())
for chain_type, name in chain_names.items():
src_ip, target_ip = _get_nat_ips(chain_type, fip)
if chain_type == 'pre-routing':
nat_type = 'dnat'
else:
nat_type = 'snat'
self.client.add_static_nat(tenant_id, name, src_ip,
target_ip,
link_port.get_id(),
nat_type, **props)
def create_floatingip(self, context, floatingip):
session = context.session
with session.begin(subtransactions=True):
fip = super(MidonetPluginV2, self).create_floatingip(
context, floatingip)
if fip['port_id']:
self._assoc_fip(fip)
return fip
def update_floatingip(self, context, id, floatingip):
"""Handle floating IP assocation and disassociation."""
LOG.debug(_("MidonetPluginV2.update_floatingip called: id=%(id)s "
@ -1038,32 +1072,7 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
fip = super(MidonetPluginV2, self).update_floatingip(
context, id, floatingip)
# Add a route for the floating IP on the provider router.
router = self.client.get_router(fip["router_id"])
link_port = self.client.get_link_port(
self._get_provider_router(), router.get_id())
self.client.add_router_route(
self._get_provider_router(),
src_network_addr='0.0.0.0',
src_network_length=0,
dst_network_addr=fip["floating_ip_address"],
dst_network_length=32,
next_hop_port=link_port.get_peer_id())
# Add static SNAT and DNAT rules on the tenant router.
props = {OS_FLOATING_IP_RULE_KEY: id}
tenant_id = router.get_tenant_id()
chain_names = _nat_chain_names(router.get_id())
for chain_type, name in chain_names.iteritems():
src_ip, target_ip = _get_nat_ips(chain_type, fip)
if chain_type == 'pre-routing':
nat_type = 'dnat'
else:
nat_type = 'snat'
self.client.add_static_nat(tenant_id, name, src_ip,
target_ip,
link_port.get_id(),
nat_type, **props)
self._assoc_fip(fip)
# disassociate floating IP
elif floatingip['floatingip']['port_id'] is None:

View File

@ -81,6 +81,51 @@ class TestMidonetL3NatTestCase(test_l3_plugin.L3NatDBIntTestCase,
def test_floatingip_with_invalid_create_port(self):
self._test_floatingip_with_invalid_create_port(MIDONET_PLUGIN_NAME)
def test_floatingip_assoc_no_port(self):
with self.subnet(cidr='200.0.0.0/24') as public_sub:
self._set_net_external(public_sub['subnet']['network_id'])
res = super(TestMidonetL3NatTestCase, self)._create_floatingip(
self.fmt, public_sub['subnet']['network_id'])
# Cleanup
floatingip = self.deserialize(self.fmt, res)
self._delete('floatingips', floatingip['floatingip']['id'])
self.assertFalse(self.instance.return_value.add_static_nat.called)
def test_floatingip_assoc_with_port(self):
with self.subnet(cidr='200.0.0.0/24') as public_sub:
self._set_net_external(public_sub['subnet']['network_id'])
with self.port() as private_port:
with self.router() as r:
# We need to hook up the private subnet to the external
# network in order to associate the fip.
sid = private_port['port']['fixed_ips'][0]['subnet_id']
private_sub = {'subnet': {'id': sid}}
self._add_external_gateway_to_router(
r['router']['id'],
public_sub['subnet']['network_id'])
self._router_interface_action('add', r['router']['id'],
private_sub['subnet']['id'],
None)
# Create the fip.
res = super(TestMidonetL3NatTestCase,
self)._create_floatingip(
self.fmt,
public_sub['subnet']['network_id'],
port_id=private_port['port']['id'])
# Cleanup the resources used for the test
floatingip = self.deserialize(self.fmt, res)
self._delete('floatingips', floatingip['floatingip']['id'])
self._remove_external_gateway_from_router(
r['router']['id'],
public_sub['subnet']['network_id'])
self._router_interface_action('remove',
r['router']['id'],
private_sub['subnet']['id'],
None)
self.assertTrue(self.instance.return_value.add_static_nat.called)
class TestMidonetSecurityGroupsTestCase(sg.SecurityGroupDBTestCase):