Merge "Move loadbalancer vip port creation outside of transaction"
This commit is contained in:
commit
1af7d92e79
|
@ -337,6 +337,8 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase,
|
||||||
|
|
||||||
port = self._core_plugin.create_port(context, {'port': port_data})
|
port = self._core_plugin.create_port(context, {'port': port_data})
|
||||||
vip_db.port_id = port['id']
|
vip_db.port_id = port['id']
|
||||||
|
# explicitly sync session with db
|
||||||
|
context.session.flush()
|
||||||
|
|
||||||
def create_vip(self, context, vip):
|
def create_vip(self, context, vip):
|
||||||
v = vip['vip']
|
v = vip['vip']
|
||||||
|
@ -384,18 +386,22 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase,
|
||||||
context.session.flush()
|
context.session.flush()
|
||||||
except exception.DBDuplicateEntry:
|
except exception.DBDuplicateEntry:
|
||||||
raise loadbalancer.VipExists(pool_id=v['pool_id'])
|
raise loadbalancer.VipExists(pool_id=v['pool_id'])
|
||||||
|
|
||||||
# create a port to reserve address for IPAM
|
|
||||||
self._create_port_for_vip(
|
|
||||||
context,
|
|
||||||
vip_db,
|
|
||||||
v['subnet_id'],
|
|
||||||
v.get('address')
|
|
||||||
)
|
|
||||||
|
|
||||||
if pool:
|
if pool:
|
||||||
pool['vip_id'] = vip_db['id']
|
pool['vip_id'] = vip_db['id']
|
||||||
|
|
||||||
|
try:
|
||||||
|
# create a port to reserve address for IPAM
|
||||||
|
# do it outside the transaction to avoid rpc calls
|
||||||
|
self._create_port_for_vip(
|
||||||
|
context, vip_db, v['subnet_id'], v.get('address'))
|
||||||
|
except Exception:
|
||||||
|
# catch any kind of exceptions
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
context.session.delete(vip_db)
|
||||||
|
if pool:
|
||||||
|
pool['vip_id'] = None
|
||||||
|
context.session.flush()
|
||||||
|
|
||||||
return self._make_vip_dict(vip_db)
|
return self._make_vip_dict(vip_db)
|
||||||
|
|
||||||
def update_vip(self, context, id, vip):
|
def update_vip(self, context, id, vip):
|
||||||
|
|
|
@ -23,12 +23,14 @@ import webob.exc
|
||||||
|
|
||||||
from neutron.api import extensions
|
from neutron.api import extensions
|
||||||
from neutron.common import config
|
from neutron.common import config
|
||||||
|
from neutron.common import exceptions as n_exc
|
||||||
from neutron import context
|
from neutron import context
|
||||||
import neutron.db.l3_db # noqa
|
import neutron.db.l3_db # noqa
|
||||||
from neutron.db.loadbalancer import loadbalancer_db as ldb
|
from neutron.db.loadbalancer import loadbalancer_db as ldb
|
||||||
from neutron.db import servicetype_db as sdb
|
from neutron.db import servicetype_db as sdb
|
||||||
import neutron.extensions
|
import neutron.extensions
|
||||||
from neutron.extensions import loadbalancer
|
from neutron.extensions import loadbalancer
|
||||||
|
from neutron import manager
|
||||||
from neutron.plugins.common import constants
|
from neutron.plugins.common import constants
|
||||||
from neutron.services.loadbalancer import (
|
from neutron.services.loadbalancer import (
|
||||||
plugin as loadbalancer_plugin
|
plugin as loadbalancer_plugin
|
||||||
|
@ -369,6 +371,26 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
||||||
)
|
)
|
||||||
return vip
|
return vip
|
||||||
|
|
||||||
|
def test_create_vip_create_port_fails(self):
|
||||||
|
with self.subnet() as subnet:
|
||||||
|
with self.pool() as pool:
|
||||||
|
lb_plugin = (manager.NeutronManager.
|
||||||
|
get_instance().
|
||||||
|
get_service_plugins()[constants.LOADBALANCER])
|
||||||
|
with mock.patch.object(
|
||||||
|
lb_plugin, '_create_port_for_vip') as cp:
|
||||||
|
#some exception that can show up in port creation
|
||||||
|
cp.side_effect = n_exc.IpAddressGenerationFailure(
|
||||||
|
net_id=subnet['subnet']['network_id'])
|
||||||
|
self._create_vip(self.fmt, "vip",
|
||||||
|
pool['pool']['id'], "HTTP", "80", True,
|
||||||
|
subnet_id=subnet['subnet']['id'],
|
||||||
|
expected_res_status=409)
|
||||||
|
req = self.new_list_request('vips')
|
||||||
|
res = self.deserialize(self.fmt,
|
||||||
|
req.get_response(self.ext_api))
|
||||||
|
self.assertFalse(res['vips'])
|
||||||
|
|
||||||
def test_create_vip_twice_for_same_pool(self):
|
def test_create_vip_twice_for_same_pool(self):
|
||||||
"""Test loadbalancer db plugin via extension and directly."""
|
"""Test loadbalancer db plugin via extension and directly."""
|
||||||
with self.subnet() as subnet:
|
with self.subnet() as subnet:
|
||||||
|
|
Loading…
Reference in New Issue