Honor both floating_ip_address and subnet_id when creating FIP

In the current code, if user specifies floating-ip-address
and subnet, we only process the subnet when creating
the fip port.

This patch adds floating_ip_address and subnet_id to
fip port's fixed_ips, if floating_ip_address is not in the subnet,
InvalidIpForSubnet exception will be raised.

This patch also fixes a default value error in tests.

Change-Id: I436353690839281ca7e13eaf792249306b71dd4b
Closes-Bug: #1732890
This commit is contained in:
Dongcan Ye 2017-11-21 11:46:56 +08:00
parent c021ba6e39
commit 088e317cd2
4 changed files with 66 additions and 7 deletions

View File

@ -1282,13 +1282,17 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
'device_owner': DEVICE_OWNER_FLOATINGIP,
'status': constants.PORT_STATUS_NOTAPPLICABLE,
'name': ''}
if fip.get('floating_ip_address'):
port['fixed_ips'] = [
{'ip_address': fip['floating_ip_address']}]
if fip.get('subnet_id'):
port['fixed_ips'] = [
{'subnet_id': fip['subnet_id']}]
# Both subnet_id and floating_ip_address are accepted, if
# floating_ip_address is not in the subnet,
# InvalidIpForSubnet exception will be raised.
fixed_ip = {}
if fip['subnet_id']:
fixed_ip['subnet_id'] = fip['subnet_id']
if fip['floating_ip_address']:
fixed_ip['ip_address'] = fip['floating_ip_address']
if fixed_ip:
port['fixed_ips'] = [fixed_ip]
# 'status' in port dict could not be updated by default, use
# check_allow_post to stop the verification of system

View File

@ -335,6 +335,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
'router_id': router['id'],
'port_id': int_port['port']['id'],
'tenant_id': int_port['port']['tenant_id'],
'subnet_id': None,
'floating_ip_address': None,
'dns_name': '', 'dns_domain': ''}
with mock.patch.object(
self.l3_plugin, '_l3_rpc_notifier') as l3_notif:
@ -424,6 +426,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
floating_ip = {'floating_network_id': ext_net_id,
'router_id': router1['id'],
'port_id': int_port1['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': int_port1['port']['tenant_id'],
'dns_name': '', 'dns_domain': ''}
floating_ip = self.l3_plugin.create_floatingip(
@ -528,6 +532,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
'router_id': router['id'],
'port_id': int_port['port']['id'],
'tenant_id': int_port['port']['tenant_id'],
'subnet_id': None,
'floating_ip_address': None,
'dns_name': '', 'dns_domain': ''}
floating_ip = self.l3_plugin.create_floatingip(
self.context, {'floatingip': floating_ip})
@ -732,6 +738,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
floating_ip = {'floating_network_id': ext_net['network']['id'],
'router_id': router['id'],
'port_id': vrrp_port['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': vrrp_port['port']['tenant_id']}
floating_ip = self.l3_plugin.create_floatingip(
self.context, {'floatingip': floating_ip})
@ -799,6 +807,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
fip1 = {'floating_network_id': ext_net['network']['id'],
'router_id': router['id'],
'port_id': int_port1['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': int_port1['port']['tenant_id']}
self.l3_plugin.create_floatingip(
self.context, {'floatingip': fip1})
@ -810,6 +820,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
fip2 = {'floating_network_id': ext_net['network']['id'],
'router_id': router['id'],
'port_id': int_port2['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': int_port2['port']['tenant_id']}
self.l3_plugin.create_floatingip(
self.context, {'floatingip': fip2})
@ -874,6 +886,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
floating_ip = {'floating_network_id': ext_net['network']['id'],
'router_id': router['id'],
'port_id': int_port1['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': int_port1['port']['tenant_id']}
floating_ip = self.l3_plugin.create_floatingip(
self.context, {'floatingip': floating_ip})
@ -954,6 +968,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
floating_ip = {'floating_network_id': ext_net['network']['id'],
'router_id': router['id'],
'port_id': vm_port['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': vm_port['tenant_id']}
floating_ip = self.l3_plugin.create_floatingip(
self.context, {'floatingip': floating_ip})
@ -1076,6 +1092,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
floating_ip = {'floating_network_id': ext_net['network']['id'],
'router_id': router['id'],
'port_id': vrrp_port['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': vrrp_port['port']['tenant_id']}
floating_ip = self.l3_plugin.create_floatingip(
self.context, {'floatingip': floating_ip})
@ -1207,6 +1225,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
floating_ip = {'floating_network_id': ext_net['network']['id'],
'router_id': router['id'],
'port_id': vrrp_port['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': vrrp_port['port']['tenant_id']}
floating_ip = self.l3_plugin.create_floatingip(
self.context, {'floatingip': floating_ip})
@ -1422,6 +1442,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
floating_ip = {'floating_network_id': ext_net_id,
'router_id': router['id'],
'port_id': vm_port['port']['id'],
'subnet_id': None,
'floating_ip_address': None,
'tenant_id': vm_port['port']['tenant_id'],
'dns_name': '', 'dns_domain': ''}
floating_ip = self.l3_plugin.create_floatingip(

View File

@ -435,7 +435,7 @@ class L3NatTestCaseMixin(object):
def _create_floatingip(self, fmt, network_id, port_id=None,
fixed_ip=None, set_context=False,
floating_ip=None, subnet_id=False,
floating_ip=None, subnet_id=None,
tenant_id=None, **kwargs):
tenant_id = tenant_id or self._tenant_id
data = {'floatingip': {'floating_network_id': network_id,
@ -2669,6 +2669,37 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
set_context=True)
self.assertEqual(exc.HTTPCreated.code, res.status_int)
def test_create_floatingip_with_subnet_id_and_fip_address(self):
with self.network() as ext_net:
self._set_net_external(ext_net['network']['id'])
with self.subnet(ext_net, cidr='10.10.10.0/24') as ext_subnet:
with self.router():
res = self._create_floatingip(
self.fmt,
ext_net['network']['id'],
subnet_id=ext_subnet['subnet']['id'],
floating_ip='10.10.10.100')
fip = self.deserialize(self.fmt, res)
self.assertEqual(exc.HTTPCreated.code, res.status_int)
self.assertEqual('10.10.10.100',
fip['floatingip']['floating_ip_address'])
def test_create_floatingip_with_subnet_and_invalid_fip_address(self):
with self.network() as ext_net:
self._set_net_external(ext_net['network']['id'])
with self.subnet(ext_net, cidr='10.10.10.0/24') as ext_subnet:
with self.router():
res = self._create_floatingip(
self.fmt,
ext_net['network']['id'],
subnet_id=ext_subnet['subnet']['id'],
floating_ip='20.20.20.200')
data = self.deserialize(self.fmt, res)
self.assertEqual(exc.HTTPBadRequest.code, res.status_int)
msg = str(n_exc.InvalidIpForSubnet(ip_address='20.20.20.200'))
self.assertEqual('InvalidIpForSubnet', data['NeutronError']['type'])
self.assertEqual(msg, data['NeutronError']['message'])
def test_create_floatingip_with_multisubnet_id(self):
with self.network() as network:
self._set_net_external(network['network']['id'])

View File

@ -946,6 +946,8 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
context.get_admin_context(),
{'floatingip': {'floating_network_id': n['network']['id'],
'tenant_id': n['network']['tenant_id'],
'subnet_id': None,
'floating_ip_address': None,
'dns_name': '', 'dns_domain': ''}}
)
self._delete('networks', n['network']['id'])