Merge "LBaaS: Fix incorrect pool status change"
This commit is contained in:
commit
0a9af87ef4
@ -341,6 +341,9 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
|
|||||||
raise loadbalancer.ProtocolMismatch(
|
raise loadbalancer.ProtocolMismatch(
|
||||||
vip_proto=v['protocol'],
|
vip_proto=v['protocol'],
|
||||||
pool_proto=pool['protocol'])
|
pool_proto=pool['protocol'])
|
||||||
|
if pool['status'] == constants.PENDING_DELETE:
|
||||||
|
raise loadbalancer.StateInvalid(state=pool['status'],
|
||||||
|
id=pool['id'])
|
||||||
else:
|
else:
|
||||||
pool = None
|
pool = None
|
||||||
|
|
||||||
@ -418,6 +421,10 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
|
|||||||
raise loadbalancer.ProtocolMismatch(
|
raise loadbalancer.ProtocolMismatch(
|
||||||
vip_proto=vip_db['protocol'],
|
vip_proto=vip_db['protocol'],
|
||||||
pool_proto=new_pool['protocol'])
|
pool_proto=new_pool['protocol'])
|
||||||
|
if new_pool['status'] == constants.PENDING_DELETE:
|
||||||
|
raise loadbalancer.StateInvalid(
|
||||||
|
state=new_pool['status'],
|
||||||
|
id=new_pool['id'])
|
||||||
|
|
||||||
if old_pool_id:
|
if old_pool_id:
|
||||||
old_pool = self._get_resource(
|
old_pool = self._get_resource(
|
||||||
@ -553,15 +560,17 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
|
|||||||
|
|
||||||
return self._make_pool_dict(pool_db)
|
return self._make_pool_dict(pool_db)
|
||||||
|
|
||||||
def delete_pool(self, context, id):
|
def _ensure_pool_delete_conditions(self, context, pool_id):
|
||||||
|
if context.session.query(Vip).filter_by(pool_id=pool_id).first():
|
||||||
|
raise loadbalancer.PoolInUse(pool_id=pool_id)
|
||||||
|
|
||||||
|
def delete_pool(self, context, pool_id):
|
||||||
# Check if the pool is in use
|
# Check if the pool is in use
|
||||||
vip = context.session.query(Vip).filter_by(pool_id=id).first()
|
self._ensure_pool_delete_conditions(context, pool_id)
|
||||||
if vip:
|
|
||||||
raise loadbalancer.PoolInUse(pool_id=id)
|
|
||||||
|
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
self._delete_pool_stats(context, id)
|
self._delete_pool_stats(context, pool_id)
|
||||||
pool_db = self._get_resource(context, Pool, id)
|
pool_db = self._get_resource(context, Pool, pool_id)
|
||||||
context.session.delete(pool_db)
|
context.session.delete(pool_db)
|
||||||
|
|
||||||
def get_pool(self, context, id, fields=None):
|
def get_pool(self, context, id, fields=None):
|
||||||
|
@ -21,6 +21,7 @@ from neutron import context
|
|||||||
from neutron.db import api as qdbapi
|
from neutron.db import api as qdbapi
|
||||||
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 st_db
|
from neutron.db import servicetype_db as st_db
|
||||||
|
from neutron.openstack.common import excutils
|
||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
from neutron.plugins.common import constants
|
from neutron.plugins.common import constants
|
||||||
from neutron.services.loadbalancer import agent_scheduler
|
from neutron.services.loadbalancer import agent_scheduler
|
||||||
@ -168,13 +169,28 @@ class LoadBalancerPlugin(ldb.LoadBalancerPluginDb,
|
|||||||
def _delete_db_pool(self, context, id):
|
def _delete_db_pool(self, context, id):
|
||||||
# proxy the call until plugin inherits from DBPlugin
|
# proxy the call until plugin inherits from DBPlugin
|
||||||
# rely on uuid uniqueness:
|
# rely on uuid uniqueness:
|
||||||
|
try:
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
self.service_type_manager.del_resource_associations(context, [id])
|
self.service_type_manager.del_resource_associations(
|
||||||
|
context, [id])
|
||||||
super(LoadBalancerPlugin, self).delete_pool(context, id)
|
super(LoadBalancerPlugin, self).delete_pool(context, id)
|
||||||
|
except Exception:
|
||||||
|
# that should not happen
|
||||||
|
# if it's still a case - something goes wrong
|
||||||
|
# log the error and mark the pool as ERROR
|
||||||
|
LOG.error(_('Failed to delete pool %s, putting it in ERROR state'),
|
||||||
|
id)
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
self.update_status(context, ldb.Pool,
|
||||||
|
id, constants.ERROR)
|
||||||
|
|
||||||
def delete_pool(self, context, id):
|
def delete_pool(self, context, id):
|
||||||
|
# check for delete conditions and update the status
|
||||||
|
# within a transaction to avoid a race
|
||||||
|
with context.session.begin(subtransactions=True):
|
||||||
self.update_status(context, ldb.Pool,
|
self.update_status(context, ldb.Pool,
|
||||||
id, constants.PENDING_DELETE)
|
id, constants.PENDING_DELETE)
|
||||||
|
self._ensure_pool_delete_conditions(context, id)
|
||||||
p = self.get_pool(context, id)
|
p = self.get_pool(context, id)
|
||||||
driver = self._get_driver_for_provider(p['provider'])
|
driver = self._get_driver_for_provider(p['provider'])
|
||||||
driver.delete_pool(context, p)
|
driver.delete_pool(context, p)
|
||||||
|
@ -679,6 +679,25 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
res = req.get_response(self.ext_api)
|
res = req.get_response(self.ext_api)
|
||||||
self.assertEqual(res.status_int, 204)
|
self.assertEqual(res.status_int, 204)
|
||||||
|
|
||||||
|
def test_delete_pool_preserve_state(self):
|
||||||
|
with self.pool(no_delete=True) as pool:
|
||||||
|
with self.vip(pool=pool):
|
||||||
|
req = self.new_delete_request('pools',
|
||||||
|
pool['pool']['id'])
|
||||||
|
res = req.get_response(self.ext_api)
|
||||||
|
self.assertEqual(res.status_int, 409)
|
||||||
|
req = self.new_show_request('pools',
|
||||||
|
pool['pool']['id'],
|
||||||
|
fmt=self.fmt)
|
||||||
|
res = req.get_response(self.ext_api)
|
||||||
|
self.assertEqual(res.status_int, 200)
|
||||||
|
res = self.deserialize(self.fmt,
|
||||||
|
req.get_response(self.ext_api))
|
||||||
|
self.assertEqual(res['pool']['status'],
|
||||||
|
constants.PENDING_CREATE)
|
||||||
|
req = self.new_delete_request('pools',
|
||||||
|
pool['pool']['id'])
|
||||||
|
|
||||||
def test_show_pool(self):
|
def test_show_pool(self):
|
||||||
name = "pool1"
|
name = "pool1"
|
||||||
keys = [('name', name),
|
keys = [('name', name),
|
||||||
|
Loading…
Reference in New Issue
Block a user