Merge "Remove any IPAM allocation if port bulk creation fails"
This commit is contained in:
commit
b65371d4da
|
@ -1665,10 +1665,9 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
for port in port_list:
|
||||
self._before_create_port(context, port)
|
||||
|
||||
port_list, net_cache = self.allocate_macs_and_ips_for_ports(
|
||||
context, port_list)
|
||||
|
||||
try:
|
||||
port_list, net_cache = self.allocate_macs_and_ips_for_ports(
|
||||
context, port_list)
|
||||
return self._create_port_bulk(context, port_list, net_cache)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
@ -1676,7 +1675,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
# deallocated now
|
||||
for port in port_list:
|
||||
self.ipam.deallocate_ips_from_port(
|
||||
context, port, port['ipams'])
|
||||
context, port, port.get('ipams'))
|
||||
|
||||
@db_api.retry_if_session_inactive()
|
||||
def _create_port_bulk(self, context, port_list, network_cache):
|
||||
|
|
|
@ -56,6 +56,7 @@ from neutron.db import ipam_pluggable_backend
|
|||
from neutron.db import provisioning_blocks
|
||||
from neutron.db import securitygroups_db as sg_db
|
||||
from neutron.db import segments_db
|
||||
from neutron.ipam import driver
|
||||
from neutron.objects import base as base_obj
|
||||
from neutron.objects import network as network_obj
|
||||
from neutron.objects import ports as port_obj
|
||||
|
@ -1753,6 +1754,37 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
|
|||
ports_out = self.plugin.create_port_bulk(ctx, ports_in)
|
||||
self.assertEqual(edo, ports_out[0]['extra_dhcp_opts'])
|
||||
|
||||
def test_create_ports_bulk_with_wrong_fixed_ips(self):
|
||||
cidr = '10.0.10.0/24'
|
||||
with self.network() as net:
|
||||
with self.subnet(net, cidr=cidr) as snet:
|
||||
net_id = net['network']['id']
|
||||
data = [{'network_id': net_id,
|
||||
'fixed_ips': [{'subnet_id': snet['subnet']['id'],
|
||||
'ip_address': '10.0.10.100'}]
|
||||
},
|
||||
{'network_id': net_id,
|
||||
'fixed_ips': [{'subnet_id': snet['subnet']['id'],
|
||||
'ip_address': '10.0.20.101'}]
|
||||
}]
|
||||
res = self._create_bulk_from_list(self.fmt, 'port',
|
||||
data, as_admin=True)
|
||||
self.assertEqual(webob.exc.HTTPBadRequest.code, res.status_int)
|
||||
self.assertIn('IP address 10.0.20.101 is not a valid IP for '
|
||||
'the specified subnet.',
|
||||
res.json['NeutronError']['message'])
|
||||
|
||||
ipam_driver = driver.Pool.get_instance(None, self.context)
|
||||
ipam_allocator = ipam_driver.get_allocator([cidr])
|
||||
with db_api.CONTEXT_READER.using(self.context):
|
||||
ipam_subnet = ipam_allocator._driver.get_subnet(
|
||||
snet['subnet']['id'])
|
||||
allocations = ipam_subnet.subnet_manager.list_allocations(
|
||||
self.context)
|
||||
# There are no leftovers (e.g.: 10.0.10.100) in the
|
||||
# "IpamAllocation" registers
|
||||
self.assertEqual([], allocations)
|
||||
|
||||
def test_delete_port_no_notify_in_disassociate_floatingips(self):
|
||||
ctx = context.get_admin_context()
|
||||
plugin = directory.get_plugin()
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
During the port bulk creation, if an IPAM allocation fails (for example, if
|
||||
the IP address is outside of the subnet CIDR), the other IPAM allocations
|
||||
already created are deleted before raising the exception. Fixes bug
|
||||
`2039550 <https://launchpad.net/bugs/2039550>`_.
|
Loading…
Reference in New Issue