Merge "Adding code to prevent vip port deletion from port api"
This commit is contained in:
commit
3e241a78f6
|
@ -14,6 +14,10 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
|
from neutron.callbacks import events
|
||||||
|
from neutron.callbacks import registry
|
||||||
|
from neutron.callbacks import resources
|
||||||
|
from neutron.common import constants as n_constants
|
||||||
from neutron.common import exceptions as n_exc
|
from neutron.common import exceptions as n_exc
|
||||||
from neutron.db import common_db_mixin as base_db
|
from neutron.db import common_db_mixin as base_db
|
||||||
from neutron.db import model_base
|
from neutron.db import model_base
|
||||||
|
@ -337,7 +341,7 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase,
|
||||||
'mac_address': attributes.ATTR_NOT_SPECIFIED,
|
'mac_address': attributes.ATTR_NOT_SPECIFIED,
|
||||||
'admin_state_up': False,
|
'admin_state_up': False,
|
||||||
'device_id': '',
|
'device_id': '',
|
||||||
'device_owner': '',
|
'device_owner': n_constants.DEVICE_OWNER_LOADBALANCER,
|
||||||
'fixed_ips': [fixed_ip]
|
'fixed_ips': [fixed_ip]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,6 +482,24 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase,
|
||||||
if vip.port: # this is a Neutron port
|
if vip.port: # this is a Neutron port
|
||||||
self._core_plugin.delete_port(context, vip.port.id)
|
self._core_plugin.delete_port(context, vip.port.id)
|
||||||
|
|
||||||
|
def prevent_lbaas_port_deletion(self, context, port_id):
|
||||||
|
try:
|
||||||
|
port_db = self._core_plugin._get_port(context, port_id)
|
||||||
|
except n_exc.PortNotFound:
|
||||||
|
return
|
||||||
|
# Check only if the owner is loadbalancer.
|
||||||
|
if port_db['device_owner'] == n_constants.DEVICE_OWNER_LOADBALANCER:
|
||||||
|
filters = {'port_id': [port_id]}
|
||||||
|
if len(self.get_vips(context, filters=filters)) > 0:
|
||||||
|
reason = _('has device owner %s') % port_db['device_owner']
|
||||||
|
raise n_exc.ServicePortInUse(port_id=port_db['id'],
|
||||||
|
reason=reason)
|
||||||
|
|
||||||
|
def subscribe(self):
|
||||||
|
registry.subscribe(
|
||||||
|
_prevent_lbaas_port_delete_callback, resources.PORT,
|
||||||
|
events.BEFORE_DELETE)
|
||||||
|
|
||||||
def get_vip(self, context, id, fields=None):
|
def get_vip(self, context, id, fields=None):
|
||||||
vip = self._get_resource(context, Vip, id)
|
vip = self._get_resource(context, Vip, id)
|
||||||
return self._make_vip_dict(vip, fields)
|
return self._make_vip_dict(vip, fields)
|
||||||
|
@ -815,3 +837,13 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase,
|
||||||
return self._get_collection(context, HealthMonitor,
|
return self._get_collection(context, HealthMonitor,
|
||||||
self._make_health_monitor_dict,
|
self._make_health_monitor_dict,
|
||||||
filters=filters, fields=fields)
|
filters=filters, fields=fields)
|
||||||
|
|
||||||
|
|
||||||
|
def _prevent_lbaas_port_delete_callback(resource, event, trigger, **kwargs):
|
||||||
|
context = kwargs['context']
|
||||||
|
port_id = kwargs['port_id']
|
||||||
|
port_check = kwargs['port_check']
|
||||||
|
lbaasplugin = manager.NeutronManager.get_service_plugins().get(
|
||||||
|
constants.LOADBALANCER)
|
||||||
|
if lbaasplugin and port_check:
|
||||||
|
lbaasplugin.prevent_lbaas_port_deletion(context, port_id)
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
|
from neutron.callbacks import events
|
||||||
|
from neutron.callbacks import registry
|
||||||
|
from neutron.callbacks import resources
|
||||||
|
from neutron.common import constants as n_constants
|
||||||
|
from neutron.common import exceptions as n_exc
|
||||||
from neutron.db import common_db_mixin as base_db
|
from neutron.db import common_db_mixin as base_db
|
||||||
from neutron import manager
|
from neutron import manager
|
||||||
from neutron.plugins.common import constants
|
from neutron.plugins.common import constants
|
||||||
|
@ -94,7 +99,7 @@ class LoadBalancerPluginDbv2(base_db.CommonDbMixin,
|
||||||
'mac_address': attributes.ATTR_NOT_SPECIFIED,
|
'mac_address': attributes.ATTR_NOT_SPECIFIED,
|
||||||
'admin_state_up': False,
|
'admin_state_up': False,
|
||||||
'device_id': '',
|
'device_id': '',
|
||||||
'device_owner': '',
|
'device_owner': n_constants.DEVICE_OWNER_LOADBALANCERV2,
|
||||||
'fixed_ips': [fixed_ip]
|
'fixed_ips': [fixed_ip]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,6 +238,23 @@ class LoadBalancerPluginDbv2(base_db.CommonDbMixin,
|
||||||
if lb_db.vip_port:
|
if lb_db.vip_port:
|
||||||
self._core_plugin.delete_port(context, lb_db.vip_port_id)
|
self._core_plugin.delete_port(context, lb_db.vip_port_id)
|
||||||
|
|
||||||
|
def prevent_lbaasv2_port_deletion(self, context, port_id):
|
||||||
|
try:
|
||||||
|
port_db = self._core_plugin._get_port(context, port_id)
|
||||||
|
except n_exc.PortNotFound:
|
||||||
|
return
|
||||||
|
if port_db['device_owner'] == n_constants.DEVICE_OWNER_LOADBALANCERV2:
|
||||||
|
filters = {'vip_port_id': [port_id]}
|
||||||
|
if len(self.get_loadbalancers(context, filters=filters)) > 0:
|
||||||
|
reason = _('has device owner %s') % port_db['device_owner']
|
||||||
|
raise n_exc.ServicePortInUse(port_id=port_db['id'],
|
||||||
|
reason=reason)
|
||||||
|
|
||||||
|
def subscribe(self):
|
||||||
|
registry.subscribe(
|
||||||
|
_prevent_lbaasv2_port_delete_callback, resources.PORT,
|
||||||
|
events.BEFORE_DELETE)
|
||||||
|
|
||||||
def get_loadbalancers(self, context, filters=None):
|
def get_loadbalancers(self, context, filters=None):
|
||||||
lb_dbs = self._get_resources(context, models.LoadBalancer,
|
lb_dbs = self._get_resources(context, models.LoadBalancer,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
|
@ -549,3 +571,13 @@ class LoadBalancerPluginDbv2(base_db.CommonDbMixin,
|
||||||
loadbalancer_id)
|
loadbalancer_id)
|
||||||
return data_models.LoadBalancerStatistics.from_sqlalchemy_model(
|
return data_models.LoadBalancerStatistics.from_sqlalchemy_model(
|
||||||
loadbalancer.stats)
|
loadbalancer.stats)
|
||||||
|
|
||||||
|
|
||||||
|
def _prevent_lbaasv2_port_delete_callback(resource, event, trigger, **kwargs):
|
||||||
|
context = kwargs['context']
|
||||||
|
port_id = kwargs['port_id']
|
||||||
|
port_check = kwargs['port_check']
|
||||||
|
lbaasv2plugin = manager.NeutronManager.get_service_plugins().get(
|
||||||
|
constants.LOADBALANCERV2)
|
||||||
|
if lbaasv2plugin and port_check:
|
||||||
|
lbaasv2plugin.db.prevent_lbaasv2_port_deletion(context, port_id)
|
||||||
|
|
|
@ -77,6 +77,7 @@ class LoadBalancerPlugin(ldb.LoadBalancerPluginDb,
|
||||||
"""Initialization for the loadbalancer service plugin."""
|
"""Initialization for the loadbalancer service plugin."""
|
||||||
self.service_type_manager = st_db.ServiceTypeManager.get_instance()
|
self.service_type_manager = st_db.ServiceTypeManager.get_instance()
|
||||||
self._load_drivers()
|
self._load_drivers()
|
||||||
|
super(LoadBalancerPlugin, self).subscribe()
|
||||||
|
|
||||||
def _load_drivers(self):
|
def _load_drivers(self):
|
||||||
"""Loads plugin-drivers specified in configuration."""
|
"""Loads plugin-drivers specified in configuration."""
|
||||||
|
@ -382,6 +383,7 @@ class LoadBalancerPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2):
|
||||||
self.db = ldbv2.LoadBalancerPluginDbv2()
|
self.db = ldbv2.LoadBalancerPluginDbv2()
|
||||||
self.service_type_manager = st_db.ServiceTypeManager.get_instance()
|
self.service_type_manager = st_db.ServiceTypeManager.get_instance()
|
||||||
self._load_drivers()
|
self._load_drivers()
|
||||||
|
self.db.subscribe()
|
||||||
|
|
||||||
def _load_drivers(self):
|
def _load_drivers(self):
|
||||||
"""Loads plugin-drivers specified in configuration."""
|
"""Loads plugin-drivers specified in configuration."""
|
||||||
|
|
|
@ -18,6 +18,7 @@ import contextlib
|
||||||
import mock
|
import mock
|
||||||
from neutron.api import extensions
|
from neutron.api import extensions
|
||||||
from neutron.common import config
|
from neutron.common import config
|
||||||
|
from neutron.common import constants as n_constants
|
||||||
from neutron.common import exceptions as n_exc
|
from neutron.common import exceptions as n_exc
|
||||||
from neutron import context
|
from neutron import context
|
||||||
from neutron.db import servicetype_db as sdb
|
from neutron.db import servicetype_db as sdb
|
||||||
|
@ -1618,3 +1619,21 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
||||||
SystemExit,
|
SystemExit,
|
||||||
loadbalancer_plugin.LoadBalancerPlugin
|
loadbalancer_plugin.LoadBalancerPlugin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_port_delete_via_port_api(self):
|
||||||
|
port = {
|
||||||
|
'id': 'my_port_id',
|
||||||
|
'device_owner': n_constants.DEVICE_OWNER_LOADBALANCER
|
||||||
|
}
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
port['device_owner'] = n_constants.DEVICE_OWNER_LOADBALANCER
|
||||||
|
myvips = [{'name': 'vip1'}]
|
||||||
|
with mock.patch.object(manager.NeutronManager, 'get_plugin') as gp:
|
||||||
|
self.plugin.get_vips = mock.Mock(return_value=myvips)
|
||||||
|
plugin = mock.Mock()
|
||||||
|
gp.return_value = plugin
|
||||||
|
plugin._get_port.return_value = port
|
||||||
|
self.assertRaises(n_exc.ServicePortInUse,
|
||||||
|
self.plugin.prevent_lbaas_port_deletion,
|
||||||
|
ctx,
|
||||||
|
port['id'])
|
||||||
|
|
|
@ -21,6 +21,8 @@ import six
|
||||||
from neutron.api import extensions
|
from neutron.api import extensions
|
||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
from neutron.common import config
|
from neutron.common import config
|
||||||
|
from neutron.common import constants as n_constants
|
||||||
|
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 import servicetype_db as sdb
|
from neutron.db import servicetype_db as sdb
|
||||||
|
@ -31,6 +33,7 @@ from oslo_config import cfg
|
||||||
import testtools
|
import testtools
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
|
from neutron import manager
|
||||||
from neutron_lbaas.common.cert_manager import cert_manager
|
from neutron_lbaas.common.cert_manager import cert_manager
|
||||||
from neutron_lbaas.common import exceptions
|
from neutron_lbaas.common import exceptions
|
||||||
from neutron_lbaas.db.loadbalancer import models
|
from neutron_lbaas.db.loadbalancer import models
|
||||||
|
@ -657,6 +660,25 @@ class LbaasLoadBalancerTests(LbaasPluginDbTestCase):
|
||||||
self.assertEqual(body['loadbalancer'][k],
|
self.assertEqual(body['loadbalancer'][k],
|
||||||
expected_values[k])
|
expected_values[k])
|
||||||
|
|
||||||
|
def test_port_delete_via_port_api(self):
|
||||||
|
port = {
|
||||||
|
'id': 'my_port_id',
|
||||||
|
'device_owner': n_constants.DEVICE_OWNER_LOADBALANCERV2
|
||||||
|
}
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
port['device_owner'] = n_constants.DEVICE_OWNER_LOADBALANCERV2
|
||||||
|
myloadbalancers = [{'name': 'lb1'}]
|
||||||
|
with mock.patch.object(manager.NeutronManager, 'get_plugin') as gp:
|
||||||
|
self.plugin.db.get_loadbalancers = mock.Mock(
|
||||||
|
return_value=myloadbalancers)
|
||||||
|
plugin = mock.Mock()
|
||||||
|
gp.return_value = plugin
|
||||||
|
plugin._get_port.return_value = port
|
||||||
|
self.assertRaises(n_exc.ServicePortInUse,
|
||||||
|
self.plugin.db.prevent_lbaasv2_port_deletion,
|
||||||
|
ctx,
|
||||||
|
port['id'])
|
||||||
|
|
||||||
|
|
||||||
class ListenerTestBase(LbaasPluginDbTestCase):
|
class ListenerTestBase(LbaasPluginDbTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue