Merge "Fix update of network's segmentation id for network with ports"
This commit is contained in:
commit
8c08045c69
neutron
@ -550,3 +550,27 @@ class Port(base.NeutronDbObject):
|
||||
ml2_models.PortBinding.vnic_type == vnic_type,
|
||||
ml2_models.PortBinding.host == host)
|
||||
return [cls._load_object(context, db_obj) for db_obj in query.all()]
|
||||
|
||||
@classmethod
|
||||
def check_network_ports_by_binding_types(
|
||||
cls, context, network_id, binding_types, negative_search=False):
|
||||
"""This method is to check whether networks have ports with given
|
||||
binding_types.
|
||||
|
||||
:param context:
|
||||
:param network_id: ID of network to check
|
||||
:param binding_types: list of binding types to look for
|
||||
:param negative_search: if set to true, ports with with binding_type
|
||||
other than "binding_types" will be counted
|
||||
:return: True if any port is found, False otherwise
|
||||
"""
|
||||
query = context.session.query(models_v2.Port).join(
|
||||
ml2_models.PortBinding)
|
||||
query = query.filter(models_v2.Port.network_id == network_id)
|
||||
if negative_search:
|
||||
query = query.filter(
|
||||
ml2_models.PortBinding.vif_type.notin_(binding_types))
|
||||
else:
|
||||
query = query.filter(
|
||||
ml2_models.PortBinding.vif_type.in_(binding_types))
|
||||
return bool(query.count())
|
||||
|
@ -65,7 +65,6 @@ from neutron_lib.db import utils as db_utils
|
||||
from neutron_lib import exceptions as exc
|
||||
from neutron_lib.exceptions import allowedaddresspairs as addr_exc
|
||||
from neutron_lib.exceptions import port_security as psec_exc
|
||||
from neutron_lib.objects import utils as obj_utils
|
||||
from neutron_lib.plugins import constants as plugin_constants
|
||||
from neutron_lib.plugins import directory
|
||||
from neutron_lib.plugins.ml2 import api
|
||||
@ -852,12 +851,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
vif_types.append(
|
||||
mech_driver.obj.get_supported_vif_type(agent))
|
||||
|
||||
filter_obj = obj_utils.NotIn(vif_types)
|
||||
filters = {portbindings.VIF_TYPE:
|
||||
filter_obj.filter(models.PortBinding.vif_type),
|
||||
'network_id': [network['id']]}
|
||||
if super(Ml2Plugin, self).get_ports_count(context,
|
||||
filters=filters):
|
||||
if ports_obj.Port.check_network_ports_by_binding_types(
|
||||
context, network['id'], vif_types, negative_search=True):
|
||||
msg = (_('Provider network attribute %(attr)s cannot be updated '
|
||||
'if any port in the network has not the following '
|
||||
'%(vif_field)s: %(vif_types)s') %
|
||||
|
@ -520,3 +520,28 @@ class PortDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
self.assertEqual(1, len(
|
||||
ports.Port.get_ports_by_vnic_type_and_host(
|
||||
self.context, 'vnic_type1', 'host1')))
|
||||
|
||||
def test_check_network_ports_by_binding_types(self):
|
||||
port1 = self._create_test_port()
|
||||
network_id = port1.network_id
|
||||
ports.PortBinding(
|
||||
self.context,
|
||||
host='host1', port_id=port1.id, status='ACTIVE',
|
||||
vnic_type='vnic_type1', vif_type='vif_type1').create()
|
||||
|
||||
port2 = self._create_test_port(network_id=network_id)
|
||||
ports.PortBinding(
|
||||
self.context,
|
||||
host='host2', port_id=port2.id, status='ACTIVE',
|
||||
vnic_type='vnic_type2', vif_type='vif_type2').create()
|
||||
|
||||
self.assertTrue(
|
||||
ports.Port.check_network_ports_by_binding_types(
|
||||
self.context, network_id,
|
||||
binding_types=['vif_type1', 'vif_type2']))
|
||||
|
||||
self.assertFalse(
|
||||
ports.Port.check_network_ports_by_binding_types(
|
||||
self.context, network_id,
|
||||
binding_types=['vif_type1', 'vif_type2'],
|
||||
negative_search=True))
|
||||
|
@ -36,7 +36,6 @@ from neutron_lib import context
|
||||
from neutron_lib.db import api as db_api
|
||||
from neutron_lib import exceptions as exc
|
||||
from neutron_lib import fixture
|
||||
from neutron_lib.objects import utils as obj_utils
|
||||
from neutron_lib.plugins import constants as plugin_constants
|
||||
from neutron_lib.plugins import directory
|
||||
from neutron_lib.plugins.ml2 import api as driver_api
|
||||
@ -50,7 +49,6 @@ import webob
|
||||
from neutron._i18n import _
|
||||
from neutron.common import utils
|
||||
from neutron.db import agents_db
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from neutron.db import provisioning_blocks
|
||||
from neutron.db import securitygroups_db as sg_db
|
||||
from neutron.db import segments_db
|
||||
@ -466,9 +464,9 @@ class TestMl2NetworksV2(test_plugin.TestNetworksV2,
|
||||
def test__update_segmentation_id_ports_wrong_vif_type(self):
|
||||
plugin = directory.get_plugin()
|
||||
with self.network() as net:
|
||||
with mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
'get_ports_count') as mock_get_ports_count:
|
||||
mock_get_ports_count.return_value = 1
|
||||
with mock.patch.object(
|
||||
port_obj.Port, 'check_network_ports_by_binding_types',
|
||||
return_value=True):
|
||||
self.assertRaises(
|
||||
exc.InvalidInput, plugin._update_segmentation_id,
|
||||
self.context, net['network'], {})
|
||||
@ -486,25 +484,22 @@ class TestMl2NetworksV2(test_plugin.TestNetworksV2,
|
||||
|
||||
with self.network(**{'arg_list': (mpnet_apidef.SEGMENTS, ),
|
||||
mpnet_apidef.SEGMENTS: segments}) as net, \
|
||||
mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
'get_ports_count') as mock_get_ports_count, \
|
||||
mock.patch.object(
|
||||
port_obj.Port, 'check_network_ports_by_binding_types',
|
||||
return_value=False) as check_network_ports_mock, \
|
||||
mock.patch.object(plugin.type_manager,
|
||||
'update_network_segment'), \
|
||||
mock.patch.object(plugin, 'get_agents') as mock_get_agents, \
|
||||
mock.patch.object(obj_utils, 'NotIn') as mock_not_in:
|
||||
mock_get_ports_count.return_value = 0
|
||||
mock.patch.object(plugin, 'get_agents') as mock_get_agents:
|
||||
net_data = {pnet.SEGMENTATION_ID: 1000}
|
||||
plugin._update_segmentation_id(self.context, net['network'],
|
||||
net_data)
|
||||
|
||||
mock_get_agents.assert_not_called()
|
||||
mock_not_in.assert_called_once_with([
|
||||
portbindings.VIF_TYPE_UNBOUND,
|
||||
portbindings.VIF_TYPE_BINDING_FAILED])
|
||||
filters = {portbindings.VIF_TYPE: mock.ANY,
|
||||
'network_id': [net['network']['id']]}
|
||||
mock_get_ports_count.assert_called_once_with(
|
||||
self.context, filters=filters)
|
||||
check_network_ports_mock.assert_called_once_with(
|
||||
self.context, net['network']['id'],
|
||||
[portbindings.VIF_TYPE_UNBOUND,
|
||||
portbindings.VIF_TYPE_BINDING_FAILED],
|
||||
negative_search=True)
|
||||
|
||||
|
||||
class TestMl2NetworksV2AgentMechDrivers(Ml2PluginV2TestCase):
|
||||
@ -518,26 +513,23 @@ class TestMl2NetworksV2AgentMechDrivers(Ml2PluginV2TestCase):
|
||||
pnet.SEGMENTATION_ID: 1}]
|
||||
with self.network(**{'arg_list': (mpnet_apidef.SEGMENTS, ),
|
||||
mpnet_apidef.SEGMENTS: segments}) as net, \
|
||||
mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
'get_ports_count') as mock_get_ports_count, \
|
||||
mock.patch.object(
|
||||
port_obj.Port, 'check_network_ports_by_binding_types',
|
||||
return_value=False) as check_network_ports_mock, \
|
||||
mock.patch.object(plugin.type_manager,
|
||||
'update_network_segment'), \
|
||||
mock.patch.object(plugin, 'get_agents',
|
||||
return_value=[mock.ANY]), \
|
||||
mock.patch.object(obj_utils, 'NotIn') as mock_not_in:
|
||||
mock_get_ports_count.return_value = 0
|
||||
return_value=[mock.ANY]):
|
||||
net_data = {pnet.SEGMENTATION_ID: 1000}
|
||||
plugin._update_segmentation_id(self.context, net['network'],
|
||||
net_data)
|
||||
|
||||
mock_not_in.assert_called_once_with([
|
||||
portbindings.VIF_TYPE_UNBOUND,
|
||||
portbindings.VIF_TYPE_BINDING_FAILED,
|
||||
mech_test.VIF_TYPE_TEST])
|
||||
filters = {portbindings.VIF_TYPE: mock.ANY,
|
||||
'network_id': [net['network']['id']]}
|
||||
mock_get_ports_count.assert_called_once_with(
|
||||
self.context, filters=filters)
|
||||
check_network_ports_mock.assert_called_once_with(
|
||||
self.context, net['network']['id'],
|
||||
[portbindings.VIF_TYPE_UNBOUND,
|
||||
portbindings.VIF_TYPE_BINDING_FAILED,
|
||||
mech_test.VIF_TYPE_TEST],
|
||||
negative_search=True)
|
||||
|
||||
|
||||
class TestExternalNetwork(Ml2PluginV2TestCase):
|
||||
|
Loading…
x
Reference in New Issue
Block a user