Browse Source

Merge "Remove "PortBindingMixin" class and related DB table"

changes/83/816383/5
Zuul 4 months ago committed by Gerrit Code Review
parent
commit
c22c8f2dc7
  1. 2
      neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD
  2. 42
      neutron/db/migration/alembic_migrations/versions/yoga/expand/8160f7a9cebb_drop_portbindingports_table.py
  3. 33
      neutron/db/models/portbinding.py
  4. 41
      neutron/db/portbindings_base.py
  5. 111
      neutron/db/portbindings_db.py
  6. 25
      neutron/tests/unit/db/test_ipam_backend_mixin.py
  7. 294
      neutron/tests/unit/extensions/test_segment.py
  8. 36
      neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py
  9. 8
      releasenotes/notes/drop-portbindingports-table-575c6d059c698bf0.yaml

2
neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD

@ -1 +1 @@
1ffef8d6f371
8160f7a9cebb

42
neutron/db/migration/alembic_migrations/versions/yoga/expand/8160f7a9cebb_drop_portbindingports_table.py

@ -0,0 +1,42 @@
# Copyright 2022 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""drop portbindingports table
Revision ID: 8160f7a9cebb
Revises: 1ffef8d6f371
Create Date: 2022-01-08 01:55:56.519076
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '8160f7a9cebb'
down_revision = '1ffef8d6f371'
def upgrade():
op.drop_table('portbindingports')
def expand_drop_exceptions():
"""Support dropping 'portbindingports' table"""
return {
sa.Table: ['portbindingports']
}

33
neutron/db/models/portbinding.py

@ -1,33 +0,0 @@
# Copyright 2013 IBM Corp.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron_lib.db import model_base
import sqlalchemy as sa
from sqlalchemy import orm
from neutron.db import models_v2
class PortBindingPort(model_base.BASEV2):
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id', ondelete="CASCADE"),
primary_key=True)
host = sa.Column(sa.String(255), nullable=False)
port = orm.relationship(
models_v2.Port, load_on_pending=True,
backref=orm.backref("portbinding",
lazy='joined', uselist=False,
cascade='delete'))
revises_on_change = ('port', )

41
neutron/db/portbindings_base.py

@ -1,41 +0,0 @@
# Copyright 2013 UnitedStack Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron_lib.api.definitions import port as port_def
from neutron_lib.db import resource_extend
from neutron_lib.plugins import directory
@resource_extend.has_resource_extenders
class PortBindingBaseMixin(object):
# Initialized by core plugin or ml2 mechanism driver(s)
base_binding_dict = None
def _process_portbindings_create_and_update(self, context, port_data,
port):
self.extend_port_dict_binding(port, None)
def extend_port_dict_binding(self, port_res, port_db):
if self.base_binding_dict:
port_res.update(self.base_binding_dict)
@staticmethod
@resource_extend.extends([port_def.COLLECTION_NAME])
def _extend_port_dict_binding(port_res, port_db):
plugin = directory.get_plugin()
if not isinstance(plugin, PortBindingBaseMixin):
return
plugin.extend_port_dict_binding(port_res, port_db)

111
neutron/db/portbindings_db.py

@ -1,111 +0,0 @@
# Copyright 2013 IBM Corp.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron_lib.api.definitions import port as port_def
from neutron_lib.api.definitions import portbindings
from neutron_lib.api import validators
from neutron_lib.db import api as db_api
from neutron_lib.db import model_query
from neutron_lib.db import resource_extend
from neutron_lib.plugins import directory
from neutron.db.models import portbinding as pmodels
from neutron.db import models_v2
from neutron.db import portbindings_base
def _port_model_hook(context, original_model, query):
query = query.outerjoin(
pmodels.PortBindingPort,
(original_model.id == pmodels.PortBindingPort.port_id))
return query
def _port_result_filter_hook(query, filters):
values = filters and filters.get(portbindings.HOST_ID, [])
if not values:
return query
query = query.filter(pmodels.PortBindingPort.host.in_(values))
return query
@resource_extend.has_resource_extenders
class PortBindingMixin(portbindings_base.PortBindingBaseMixin):
def __new__(cls, *args, **kwargs):
model_query.register_hook(
models_v2.Port,
"portbindings_port",
query_hook=_port_model_hook,
filter_hook=None,
result_filters=_port_result_filter_hook)
return super(PortBindingMixin, cls).__new__(cls, *args, **kwargs)
def _process_portbindings_create_and_update(self, context, port_data,
port):
binding_profile = port.get(portbindings.PROFILE)
binding_profile_set = validators.is_attr_set(binding_profile)
if not binding_profile_set and binding_profile is not None:
del port[portbindings.PROFILE]
binding_vnic = port.get(portbindings.VNIC_TYPE)
binding_vnic_set = validators.is_attr_set(binding_vnic)
if not binding_vnic_set and binding_vnic is not None:
del port[portbindings.VNIC_TYPE]
# REVISIT(irenab) Add support for vnic_type for plugins that
# can handle more than one type.
# Currently implemented for ML2 plugin that does not use
# PortBindingMixin.
host = port_data.get(portbindings.HOST_ID)
host_set = validators.is_attr_set(host)
with db_api.CONTEXT_WRITER.using(context):
bind_port = context.session.query(
pmodels.PortBindingPort).filter_by(port_id=port['id']).first()
if host_set:
if not bind_port:
context.session.add(
pmodels.PortBindingPort(port_id=port['id'], host=host))
else:
bind_port.host = host
else:
host = bind_port.host if bind_port else None
self._extend_port_dict_binding_host(port, host)
def get_port_host(self, context, port_id):
with db_api.CONTEXT_READER.using(context):
bind_port = (
context.session.query(pmodels.PortBindingPort.host).
filter_by(port_id=port_id).
first()
)
return bind_port.host if bind_port else None
def _extend_port_dict_binding_host(self, port_res, host):
super(PortBindingMixin, self).extend_port_dict_binding(
port_res, None)
port_res[portbindings.HOST_ID] = host
def extend_port_dict_binding(self, port_res, port_db):
host = port_db.portbinding.host if port_db.portbinding else None
self._extend_port_dict_binding_host(port_res, host)
@staticmethod
@resource_extend.extends([port_def.COLLECTION_NAME])
def _extend_port_dict_binding(port_res, port_db):
plugin = directory.get_plugin()
if not isinstance(plugin, PortBindingMixin):
return
plugin.extend_port_dict_binding(port_res, port_db)

25
neutron/tests/unit/db/test_ipam_backend_mixin.py

@ -23,10 +23,9 @@ from neutron_lib.exceptions import address_scope as addr_scope_exc
from oslo_utils import uuidutils
import webob.exc
from neutron.db import db_base_plugin_v2
from neutron.db import ipam_backend_mixin
from neutron.db import portbindings_db
from neutron.objects import subnet as subnet_obj
from neutron.plugins.ml2 import plugin as ml2_plugin
from neutron.services.segments import db as segments_db
from neutron.tests import base
from neutron.tests.unit.db import test_db_base_plugin_v2
@ -346,33 +345,23 @@ class TestIpamBackendMixin(base.BaseTestCase):
None)
class TestPlugin(db_base_plugin_v2.NeutronDbPluginV2,
portbindings_db.PortBindingMixin,
segments_db.SegmentDbMixin):
class TestPlugin(ml2_plugin.Ml2Plugin, segments_db.SegmentDbMixin):
__native_pagination_support = True
__native_sorting_support = True
supported_extension_aliases = [portbindings.ALIAS]
def get_plugin_description(self):
return "Test Plugin"
@classmethod
def get_plugin_type(cls):
return "test_plugin"
def create_port(self, context, port):
port_dict = super(TestPlugin, self).create_port(context, port)
self._process_portbindings_create_and_update(
context, port['port'], port_dict)
return port_dict
class TestPortUpdateIpam(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
def setUp(self, plugin=None):
if not plugin:
plugin = 'neutron.tests.unit.db.test_ipam_backend_mixin.TestPlugin'
super(TestPortUpdateIpam, self).setUp(plugin=plugin)
ml2_plugin.MAX_BIND_TRIES = 0
self.addCleanup(self._cleanup)
def _cleanup(self):
ml2_plugin.MAX_BIND_TRIES = 10
def test_port_update_allocate_from_net_subnet(self):
"""Tests that a port can get address by updating fixed_ips"""

294
neutron/tests/unit/extensions/test_segment.py

@ -40,11 +40,11 @@ from neutron.conf.plugins.ml2.drivers import driver_type
from neutron.db import agents_db
from neutron.db import agentschedulers_db
from neutron.db import db_base_plugin_v2
from neutron.db import portbindings_db
from neutron.db import segments_db
from neutron.extensions import segment as ext_segment
from neutron.extensions import standardattrdescription as ext_stddesc
from neutron.objects import network
from neutron.objects import network as network_obj
from neutron.plugins.ml2 import plugin as ml2_plugin
from neutron.services.segments import db
from neutron.services.segments import exceptions as segment_exc
from neutron.services.segments import plugin as seg_plugin
@ -75,6 +75,9 @@ class SegmentTestExtensionManager(object):
class SegmentTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
VLAN_MIN = 200
VLAN_MAX = 209
def setUp(self, plugin=None):
# Remove MissingAuthPlugin exception from logs
self.patch_notifier = mock.patch(
@ -84,9 +87,22 @@ class SegmentTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
plugin = TEST_PLUGIN_KLASS
service_plugins = {'segments_plugin_name': SERVICE_PLUGIN_KLASS}
cfg.CONF.set_override('service_plugins', [SERVICE_PLUGIN_KLASS])
driver_type.register_ml2_drivers_vlan_opts()
cfg.CONF.set_override(
'network_vlan_ranges',
['physnet:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX),
'physnet0:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX),
'physnet1:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX),
'physnet2:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX)],
group='ml2_type_vlan')
ext_mgr = SegmentTestExtensionManager()
super(SegmentTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr,
service_plugins=service_plugins)
ml2_plugin.MAX_BIND_TRIES = 0
self.addCleanup(self._cleanup)
def _cleanup(self):
ml2_plugin.MAX_BIND_TRIES = 10
def _create_segment(self, fmt, expected_res_status=None, **kwargs):
segment = {'segment': {}}
@ -110,7 +126,7 @@ class SegmentTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
return self.deserialize(fmt, res)
def segment(self, **kwargs):
kwargs.setdefault('network_type', 'net_type')
kwargs.setdefault('network_type', constants.TYPE_VLAN)
return self._make_segment(
self.fmt, tenant_id=self._tenant_id, **kwargs)
@ -123,9 +139,7 @@ class SegmentTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
return segment
class SegmentTestPlugin(db_base_plugin_v2.NeutronDbPluginV2,
portbindings_db.PortBindingMixin,
db.SegmentDbMixin):
class SegmentTestPlugin(ml2_plugin.Ml2Plugin, db.SegmentDbMixin):
__native_pagination_support = True
__native_sorting_support = True
@ -133,26 +147,6 @@ class SegmentTestPlugin(db_base_plugin_v2.NeutronDbPluginV2,
ipalloc_apidef.ALIAS,
"subnet-service-types"]
def get_plugin_description(self):
return "Network Segments"
@classmethod
def get_plugin_type(cls):
return "segments"
def create_port(self, context, port):
port_dict = super(SegmentTestPlugin, self).create_port(context, port)
self._process_portbindings_create_and_update(
context, port['port'], port_dict)
return port_dict
def update_port(self, context, id, port):
port_dict = super(SegmentTestPlugin, self).update_port(
context, id, port)
self._process_portbindings_create_and_update(
context, port['port'], port_dict)
return port_dict
class TestSegmentNameDescription(SegmentTestCase):
def setUp(self):
@ -167,8 +161,8 @@ class TestSegmentNameDescription(SegmentTestCase):
d.setdefault('network_id', self.network['id'])
d.setdefault('name', None)
d.setdefault('description', 'desc')
d.setdefault('physical_network', 'phys_net')
d.setdefault('network_type', 'net_type')
d.setdefault('physical_network', 'physnet')
d.setdefault('network_type', constants.TYPE_VLAN)
d.setdefault('segmentation_id', 200)
return super(TestSegmentNameDescription, self)._test_create_segment(
expected, **kwargs)
@ -225,11 +219,11 @@ class TestSegment(SegmentTestCase):
with self.network() as network:
network = network['network']
expected_segment = {'network_id': network['id'],
'physical_network': 'phys_net',
'network_type': 'net_type',
'physical_network': 'physnet',
'network_type': constants.TYPE_VLAN,
'segmentation_id': 200}
self._test_create_segment(network_id=network['id'],
physical_network='phys_net',
physical_network='physnet',
segmentation_id=200,
expected=expected_segment)
@ -237,7 +231,7 @@ class TestSegment(SegmentTestCase):
exc = self.assertRaises(webob.exc.HTTPClientError,
self._test_create_segment,
network_id=uuidutils.generate_uuid(),
physical_network='phys_net',
physical_network='physnet',
segmentation_id=200)
self.assertEqual(HTTP_NOT_FOUND, exc.code)
self.assertIn('NetworkNotFound', exc.explanation)
@ -246,39 +240,36 @@ class TestSegment(SegmentTestCase):
with self.network() as network:
network = network['network']
expected_segment = {'network_id': network['id'],
'physical_network': None,
'network_type': 'net_type',
'physical_network': 'physnet0',
'network_type': constants.TYPE_VLAN,
'segmentation_id': 200}
self._test_create_segment(network_id=network['id'],
physical_network='physnet0',
segmentation_id=200,
expected=expected_segment)
def test_create_segment_no_segmentation_id(self):
def _mock_reserve_segmentation_id(rtype, event, trigger,
payload=None):
segment = payload.latest_state
if not segment.get('segmentation_id'):
segment['segmentation_id'] = 200
with self.network() as network:
network = network['network']
registry.subscribe(_mock_reserve_segmentation_id, resources.SEGMENT,
events.PRECOMMIT_CREATE)
expected_segment = {'network_id': network['id'],
'physical_network': 'phys_net',
'network_type': 'net_type',
'segmentation_id': 200}
self._test_create_segment(network_id=network['id'],
physical_network='phys_net',
expected=expected_segment)
'physical_network': 'physnet',
'network_type': constants.TYPE_VLAN}
segment = self.segment(
network_id=network['id'], physical_network='physnet')['segment']
for key, value in expected_segment.items():
self.assertEqual(value, segment[key])
# NOTE(ralonsoh): segmentation ID is assigned randomly from the physnet
# available segments, stored in the DB.
self.assertIn(segment['segmentation_id'],
range(self.VLAN_MIN, self.VLAN_MAX + 1))
def test_create_segment_with_exception_in_core_plugin(self):
cxt = context.get_admin_context()
with self.network() as network:
network = network['network']
local_segment = self._list('segments')['segments'][0]
with mock.patch.object(registry, 'publish') as publish:
publish.side_effect = exceptions.CallbackFailure(errors=Exception)
self.assertRaises(webob.exc.HTTPClientError,
@ -287,32 +278,36 @@ class TestSegment(SegmentTestCase):
segmentation_id=200)
network_segments = segments_db.get_network_segments(cxt, network['id'])
self.assertEqual([], network_segments)
self.assertEqual(1, len(network_segments))
self.assertEqual(local_segment['id'], network_segments[0]['id'])
def test_create_segments_in_certain_order(self):
cxt = context.get_admin_context()
with self.network() as network:
network = network['network']
segment1 = self.segment(
network_id=network['id'], segmentation_id=200)
network_id=network['id'], segmentation_id=200,
physical_network='physnet0')
segment2 = self.segment(
network_id=network['id'], segmentation_id=201)
network_id=network['id'], segmentation_id=201,
physical_network='physnet1')
segment3 = self.segment(
network_id=network['id'], segmentation_id=202)
network_id=network['id'], segmentation_id=202,
physical_network='physnet2')
network_segments = segments_db.get_network_segments(cxt,
network['id'])
self.assertEqual(segment1['segment']['id'],
network_segments[0]['id'])
self.assertEqual(segment2['segment']['id'],
network_segments[1]['id'])
self.assertEqual(segment3['segment']['id'],
network_segments[2]['id'])
segment_ids = (ns['id'] for ns in network_segments)
self.assertIn(segment1['segment']['id'], segment_ids)
self.assertIn(segment2['segment']['id'], segment_ids)
self.assertIn(segment3['segment']['id'], segment_ids)
def test_delete_segment(self):
with self.network() as network:
network = network['network']
self.segment(network_id=network['id'], segmentation_id=200)
segment = self.segment(network_id=network['id'], segmentation_id=201)
self.segment(network_id=network['id'], segmentation_id=200,
physical_network='physnet0')
segment = self.segment(network_id=network['id'], segmentation_id=201,
physical_network='physnet1')
self._delete('segments', segment['segment']['id'])
self._show('segments', segment['segment']['id'],
expected_code=webob.exc.HTTPNotFound.code)
@ -322,7 +317,8 @@ class TestSegment(SegmentTestCase):
net = network['network']
segment = self._test_create_segment(network_id=net['id'],
segmentation_id=200)
segmentation_id=200,
physical_network='physnet0')
segment_id = segment['segment']['id']
with self.subnet(network=network, segment_id=segment_id):
self._delete('segments', segment_id,
@ -334,7 +330,7 @@ class TestSegment(SegmentTestCase):
with self.network() as network:
network = network['network']
segment = self._test_create_segment(network_id=network['id'],
physical_network='phys_net',
physical_network='physnet',
segmentation_id=200)
req = self.new_show_request('segments', segment['segment']['id'])
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
@ -344,57 +340,62 @@ class TestSegment(SegmentTestCase):
with self.network() as network:
network = network['network']
self._test_create_segment(network_id=network['id'],
physical_network='phys_net1',
physical_network='physnet1',
segmentation_id=200)
self._test_create_segment(network_id=network['id'],
physical_network='phys_net2',
physical_network='physnet2',
segmentation_id=201)
res = self._list('segments')
self.assertEqual(2, len(res['segments']))
self.assertEqual(3, len(res['segments']))
def test_list_segments_with_sort(self):
with self.network() as network:
network = network['network']
local_segment = {'segment': self._list('segments')['segments'][0]}
s1 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net1',
physical_network='physnet1',
segmentation_id=200)
s2 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net2',
physical_network='physnet2',
segmentation_id=201)
self._test_list_with_sort('segment',
(s2, s1),
(s2, s1, local_segment),
[('physical_network', 'desc')],
query_params='network_id=%s' % network['id'])
def test_list_segments_with_pagination(self):
with self.network() as network:
network = network['network']
local_segment = {'segment': self._list('segments')['segments'][0]}
s1 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net1',
physical_network='physnet0',
segmentation_id=200)
s2 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net2',
physical_network='physnet1',
segmentation_id=201)
s3 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net3',
physical_network='physnet2',
segmentation_id=202)
self._test_list_with_pagination(
'segment',
(s1, s2, s3),
('physical_network', 'asc'), 2, 2,
(local_segment, s1, s2, s3),
('physical_network', 'asc'), 3, 2,
query_params='network_id=%s' % network['id'])
def test_list_segments_with_pagination_reverse(self):
with self.network() as network:
network = network['network']
s1 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net1',
physical_network='physnet0',
segmentation_id=200)
s2 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net2',
physical_network='physnet1',
segmentation_id=201)
s3 = self._test_create_segment(network_id=network['id'],
physical_network='phys_net3',
physical_network='physnet2',
segmentation_id=202)
self._test_list_with_pagination_reverse(
'segment',
@ -406,7 +407,8 @@ class TestSegment(SegmentTestCase):
with self.network() as network:
net = network['network']
segment = self._test_create_segment(network_id=net['id'],
segmentation_id=200)
segmentation_id=200,
physical_network='physnet2')
segment['segment']['segmentation_id'] = '201'
self._update('segments', segment['segment']['id'], segment,
expected_code=webob.exc.HTTPClientError.code)
@ -443,7 +445,8 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
net = network['network']
segment = self._test_create_segment(network_id=net['id'],
segmentation_id=200)
segmentation_id=200,
physical_network='physnet1')
segment_id = segment['segment']['id']
with self.subnet(network=network, segment_id=segment_id) as subnet:
@ -461,7 +464,8 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
net = network1['network']
segment = self._test_create_segment(network_id=net['id'],
segmentation_id=200)
segmentation_id=200,
physical_network='physnet1')
res = self._create_subnet(self.fmt,
net_id=network2['network']['id'],
@ -491,7 +495,8 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
net = network['network']
segment = self._test_create_segment(network_id=net['id'],
segmentation_id=200)
segmentation_id=200,
physical_network='physnet1')
res = self._create_subnet(self.fmt,
net_id=net['id'],
@ -506,7 +511,8 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
net = network['network']
segment = self._test_create_segment(network_id=net['id'],
segmentation_id=200)
segmentation_id=200,
physical_network='physnet1')
segment_id = segment['segment']['id']
with self.subnet(network=network, segment_id=segment_id) as subnet:
@ -526,8 +532,8 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
net = network['network']
# Can't create a dynamic segment through the API
segment = {segments_db.NETWORK_TYPE: 'phys_net',
segments_db.PHYSICAL_NETWORK: 'net_type',
segment = {segments_db.NETWORK_TYPE: 'physnet',
segments_db.PHYSICAL_NETWORK: constants.TYPE_VLAN,
segments_db.SEGMENTATION_ID: 200}
segments_db.add_network_segment(cxt,
network_id=net['id'],
@ -544,32 +550,30 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
def test_associate_existing_subnet_with_segment(self):
with self.network() as network:
net = network['network']
pass
segment = self._test_create_segment(network_id=net['id'],
physical_network='phys_net',
segmentation_id=200)['segment']
segment_id = self._list('segments')['segments'][0]['id']
with self.subnet(network=network, segment_id=None) as subnet:
subnet = subnet['subnet']
data = {'subnet': {'segment_id': segment['id']}}
data = {'subnet': {'segment_id': segment_id}}
request = self.new_update_request('subnets', data, subnet['id'])
response = request.get_response(self.api)
res = self.deserialize(self.fmt, response)
self.assertEqual(webob.exc.HTTPOk.code, response.status_int)
self.assertEqual(res['subnet']['segment_id'], segment['id'])
self.assertEqual(res['subnet']['segment_id'], segment_id)
def test_update_subnet_with_current_segment_id(self):
with self.network() as network:
net = network['network']
segment1 = self._test_create_segment(network_id=net['id'],
physical_network='phys_net1',
physical_network='physnet1',
segmentation_id=200)['segment']
self._test_create_segment(network_id=net['id'],
physical_network='phys_net2',
segmentation_id=200)['segment']
physical_network='physnet2',
segmentation_id=200)
with self.subnet(network=network, segment_id=segment1['id']) as subnet:
subnet = subnet['subnet']
@ -586,11 +590,11 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
net = network['network']
segment1 = self._test_create_segment(network_id=net['id'],
physical_network='phys_net1',
physical_network='physnet1',
segmentation_id=201)['segment']
self._test_create_segment(network_id=net['id'],
physical_network='phys_net2',
segmentation_id=202)['segment']
physical_network='physnet2',
segmentation_id=202)
with self.subnet(network=network, segment_id=None) as subnet:
subnet = subnet['subnet']
@ -606,7 +610,7 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
net = network['network']
segment1 = self._test_create_segment(network_id=net['id'],
physical_network='phys_net1',
physical_network='physnet1',
segmentation_id=201)['segment']
with self.subnet(network=network, segment_id=None,
@ -628,15 +632,12 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
with self.network() as network:
net = network['network']
segment1 = self._test_create_segment(network_id=net['id'],
physical_network='phys_net2',
segmentation_id=201)['segment']
with self.subnet(network=network, segment_id=segment1['id']) as subnet:
segment_id = self._list('segments')['segments'][0]['id']
with self.subnet(network=network, segment_id=segment_id) as subnet:
subnet = subnet['subnet']
segment2 = self._test_create_segment(network_id=net['id'],
physical_network='phys_net3',
physical_network='physnet0',
segmentation_id=202)['segment']
data = {'subnet': {'segment_id': segment2['id']}}
@ -653,16 +654,6 @@ class HostSegmentMappingTestCase(SegmentTestCase):
cfg.CONF.set_override('mechanism_drivers',
self._mechanism_drivers,
group='ml2')
# NOTE(dasm): ml2_type_vlan requires to be registered before used.
# This piece was refactored and removed from .config, so it causes
# a problem, when tests are executed with pdb.
# There is no problem when tests are running without debugger.
driver_type.register_ml2_drivers_vlan_opts()
cfg.CONF.set_override('network_vlan_ranges',
['phys_net1', 'phys_net2'],
group='ml2_type_vlan')
if not plugin:
plugin = 'ml2'
super(HostSegmentMappingTestCase, self).setUp(plugin=plugin)
@ -670,7 +661,7 @@ class HostSegmentMappingTestCase(SegmentTestCase):
def _get_segments_for_host(self, host):
ctx = context.get_admin_context()
segment_host_mapping = network.SegmentHostMapping.get_objects(
segment_host_mapping = network_obj.SegmentHostMapping.get_objects(
ctx, host=host)
return {seg_host['segment_id']: seg_host
for seg_host in segment_host_mapping}
@ -681,7 +672,7 @@ class HostSegmentMappingTestCase(SegmentTestCase):
plugin=self.plugin, start_flag=start_flag)
def _test_one_segment_one_host(self, host):
physical_network = 'phys_net1'
physical_network = 'physnet1'
with self.network() as network:
network = network['network']
segment = self._test_create_segment(
@ -707,15 +698,15 @@ class TestMl2HostSegmentMappingNoAgent(HostSegmentMappingTestCase):
def test_update_segment_host_mapping(self):
ctx = context.get_admin_context()
host = 'host1'
physnets = ['phys_net1']
physnets = ['physnet1']
with self.network() as network:
network = network['network']
segment = self._test_create_segment(
network_id=network['id'], physical_network='phys_net1',
network_id=network['id'], physical_network='physnet1',
segmentation_id=200, network_type=constants.TYPE_VLAN)['segment']
self._test_create_segment(
network_id=network['id'], physical_network='phys_net2',
segmentation_id=201, network_type=constants.TYPE_VLAN)['segment']
network_id=network['id'], physical_network='physnet2',
segmentation_id=201, network_type=constants.TYPE_VLAN)
segments = db.get_segments_with_phys_nets(ctx, physnets)
segment_ids = {segment['id'] for segment in segments}
db.update_segment_host_mapping(ctx, host, segment_ids)
@ -731,7 +722,7 @@ class TestMl2HostSegmentMappingNoAgent(HostSegmentMappingTestCase):
with self.network() as network:
network = network['network']
segment = self._test_create_segment(
network_id=network['id'], physical_network='phys_net1',
network_id=network['id'], physical_network='physnet1',
segmentation_id=200, network_type=constants.TYPE_VLAN)['segment']
db.map_segment_to_hosts(ctx, segment['id'], hosts)
updated_segment = self.plugin.get_segment(ctx, segment['id'])
@ -745,7 +736,7 @@ class TestMl2HostSegmentMappingNoAgent(HostSegmentMappingTestCase):
for i in range(1, 3):
host = "host%s" % i
segment = self._test_create_segment(
network_id=network_id, physical_network='phys_net%s' % i,
network_id=network_id, physical_network='physnet%s' % i,
segmentation_id=200 + i, network_type=constants.TYPE_VLAN)
db.update_segment_host_mapping(
ctx, host, {segment['segment']['id']})
@ -766,7 +757,7 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase):
def test_updated_agent_changed_physical_networks(self):
host = 'host1'
physical_networks = ['phys_net1', 'phys_net2']
physical_networks = ['physnet1', 'physnet2']
networks = []
segments = []
for i, phy_net in enumerate(physical_networks):
@ -797,7 +788,7 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase):
def test_same_segment_two_hosts(self):
host1 = 'host1'
host2 = 'host2'
physical_network = 'phys_net1'
physical_network = 'physnet1'
segment = self._test_one_segment_one_host(host1)
self._register_agent(host2, mappings={physical_network: 'br-eth-1'},
plugin=self.plugin)
@ -810,7 +801,7 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase):
def test_update_agent_only_change_agent_host_mapping(self):
host1 = 'host1'
host2 = 'host2'
physical_network = 'phys_net1'
physical_network = 'physnet1'
with self.network() as network:
network = network['network']
segment1 = self._test_create_segment(
@ -824,7 +815,7 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase):
plugin=self.plugin)
# Update agent at host2 should only change mapping with host2.
other_phys_net = 'phys_net2'
other_phys_net = 'physnet2'
segment2 = self._test_create_segment(
network_id=network['id'],
physical_network=other_phys_net,
@ -846,7 +837,7 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase):
def test_new_segment_after_host_reg(self):
host1 = 'host1'
physical_network = 'phys_net1'
physical_network = 'physnet1'
segment = self._test_one_segment_one_host(host1)
with self.network() as network:
network = network['network']
@ -867,7 +858,7 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase):
@mock.patch(mock_path)
def test_agent_with_no_mappings(self, mock):
host = 'host1'
physical_network = 'phys_net1'
physical_network = 'physnet1'
with self.network() as network:
network = network['network']
self._test_create_segment(
@ -926,7 +917,7 @@ class TestHostSegmentMappingNoSupportFromPlugin(HostSegmentMappingTestCase):
@mock.patch(mock_path)
def test_host_segments_not_updated(self, mock):
host = 'host1'
physical_network = 'phys_net1'
physical_network = 'physnet1'
with self.network() as network:
network = network['network']
self._test_create_segment(network_id=network['id'],
@ -947,7 +938,7 @@ class TestMl2HostSegmentMappingAgentServerSynch(HostSegmentMappingTestCase):
@mock.patch(mock_path)
def test_starting_server_processes_agents(self, mock_function):
host = 'agent_updating_starting_server'
physical_network = 'phys_net1'
physical_network = 'physnet1'
self._register_agent(host, mappings={physical_network: 'br-eth-1'},
plugin=self.plugin, start_flag=False)
self.assertIn(host, db.reported_hosts)
@ -958,7 +949,7 @@ class TestMl2HostSegmentMappingAgentServerSynch(HostSegmentMappingTestCase):
@mock.patch(mock_path)
def test_starting_agent_is_processed(self, mock_function):
host = 'starting_agent'
physical_network = 'phys_net1'
physical_network = 'physnet1'
self._register_agent(host, mappings={physical_network: 'br-eth-1'},
plugin=self.plugin, start_flag=False)
self.assertIn(host, db.reported_hosts)
@ -972,7 +963,7 @@ class TestMl2HostSegmentMappingAgentServerSynch(HostSegmentMappingTestCase):
@mock.patch(mock_path)
def test_no_starting_agent_is_not_processed(self, mock_function):
host = 'agent_with_no_start_update'
physical_network = 'phys_net1'
physical_network = 'physnet1'
self._register_agent(host, mappings={physical_network: 'br-eth-1'},
plugin=self.plugin, start_flag=False)
self.assertIn(host, db.reported_hosts)
@ -988,7 +979,7 @@ class SegmentAwareIpamTestCase(SegmentTestCase):
def _setup_host_mappings(self, mappings=()):
ctx = context.get_admin_context()
for segment_id, host in mappings:
network.SegmentHostMapping(
network_obj.SegmentHostMapping(
ctx, segment_id=segment_id, host=host).create()
def _create_test_segment_with_subnet(self,
@ -1845,22 +1836,7 @@ class TestSegmentAwareIpam(SegmentAwareIpamTestCase):
class TestSegmentAwareIpamML2(TestSegmentAwareIpam):
VLAN_MIN = 200
VLAN_MAX = 209
def setUp(self):
# NOTE(mlavalle): ml2_type_vlan requires to be registered before used.
# This piece was refactored and removed from .config, so it causes
# a problem, when tests are executed with pdb.
# There is no problem when tests are running without debugger.
driver_type.register_ml2_drivers_vlan_opts()
cfg.CONF.set_override(
'network_vlan_ranges',
['physnet:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX),
'physnet0:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX),
'physnet1:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX),
'physnet2:%s:%s' % (self.VLAN_MIN, self.VLAN_MAX)],
group='ml2_type_vlan')
super(TestSegmentAwareIpamML2, self).setUp(plugin='ml2')
def test_segmentation_id_stored_in_db(self):
@ -2567,18 +2543,18 @@ class TestDhcpAgentSegmentScheduling(HostSegmentMappingTestCase):
def test_network_scheduling_on_segment_creation(self):
self._register_dhcp_agents()
self._test_create_network_and_segment('phys_net1')
self._test_create_network_and_segment('physnet1')
def test_segment_scheduling_no_host_mapping(self):
self._register_dhcp_agents()
network, segment = self._test_create_network_and_segment('phys_net1')
network, segment = self._test_create_network_and_segment('physnet1')
self._test_create_subnet(network, segment)
dhcp_agents = self.dhcp_agent_db.get_dhcp_agents_hosting_networks(
self.ctx, [network['id']])
self.assertEqual(0, len(dhcp_agents))
def test_segment_scheduling_with_host_mapping(self):
phys_net1 = 'phys_net1'
phys_net1 = 'physnet1'
self._register_dhcp_agents()
network, segment = self._test_create_network_and_segment(phys_net1)
self._register_agent(DHCP_HOSTA,
@ -2591,8 +2567,8 @@ class TestDhcpAgentSegmentScheduling(HostSegmentMappingTestCase):
self.assertEqual(DHCP_HOSTA, dhcp_agents[0]['host'])
def test_segment_scheduling_with_multiple_host_mappings(self):
phys_net1 = 'phys_net1'
phys_net2 = 'phys_net2'
phys_net1 = 'physnet1'
phys_net2 = 'physnet2'
self._register_dhcp_agents([DHCP_HOSTA, DHCP_HOSTB, 'MEHA', 'MEHB'])
network, segment1 = self._test_create_network_and_segment(phys_net1)
segment2 = self._test_create_segment(network_id=network['id'],
@ -2843,18 +2819,14 @@ class TestSegmentHostMappingNoStore(
@mock.patch('neutron.services.segments.db.map_segment_to_hosts')
def test_no_segmenthostmapping_when_disable_segment(
self, mock_map_segment_to_hosts, mock_update_segment_mapping):
with self.network(
arg_list=('provider:network_type',
'provider:physical_network',
'provider:segmentation_id'),
**{'provider:network_type': 'vlan',
'provider:physical_network': 'phys_net1',
'provider:segmentation_id': '400'}) as network:
network['network']
with self.network(**{'provider:network_type': 'vlan',
'provider:physical_network': 'physnet1',
'provider:segmentation_id': '400'}):
pass
mock_map_segment_to_hosts.assert_not_called()
host1 = 'test_host'
physical_network = 'phys_net1'
physical_network = 'physnet1'
helpers.register_ovs_agent(
host=host1,
bridge_mappings={physical_network: 'br-eth-1'},

36
neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py

@ -2361,7 +2361,7 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
with self.network() as network:
network = network['network']
segment1 = self._test_create_segment(
network_id=network['id'], physical_network='phys_net1',
network_id=network['id'], physical_network='physnet1',
segmentation_id=200, network_type='vlan')['segment']
# As geneve networks mtu shouldn't be more than 1442 considering the
@ -2375,7 +2375,7 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
network_id=network['id'],
segmentation_id=200,
network_type='geneve')
self.mech_driver.update_segment_host_mapping(host, ['phys_net1'])
self.mech_driver.update_segment_host_mapping(host, ['physnet1'])
segments_host_db = self._get_segments_for_host(host)
self.assertEqual({segment1['id']}, set(segments_host_db))
return network['id'], host
@ -2385,9 +2385,9 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
# Update the mapping
segment2 = self._test_create_segment(
network_id=network_id, physical_network='phys_net2',
network_id=network_id, physical_network='physnet2',
segmentation_id=201, network_type='vlan')['segment']
self.mech_driver.update_segment_host_mapping(host, ['phys_net2'])
self.mech_driver.update_segment_host_mapping(host, ['physnet2'])
segments_host_db = self._get_segments_for_host(host)
self.assertEqual({segment2['id']}, set(segments_host_db))
@ -2400,8 +2400,8 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
self.assertEqual({}, segments_host_db)
def test_update_segment_host_mapping_with_new_segment(self):
hostname_with_physnets = {'hostname1': ['phys_net1', 'phys_net2'],
'hostname2': ['phys_net1']}
hostname_with_physnets = {'hostname1': ['physnet1', 'physnet2'],
'hostname2': ['physnet1']}
ovn_sb_api = self.mech_driver.sb_ovn
ovn_sb_api.get_chassis_hostname_and_physnets.return_value = (
hostname_with_physnets)
@ -2409,7 +2409,7 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
with self.network() as network:
network_id = network['network']['id']
segment = self._test_create_segment(
network_id=network_id, physical_network='phys_net2',
network_id=network_id, physical_network='physnet2',
segmentation_id=201, network_type='vlan')['segment']
segments_host_db1 = self._get_segments_for_host('hostname1')
# A new SegmentHostMapping should be created for hostname1
@ -2423,28 +2423,28 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
with self.network() as network:
net = network['network']
new_segment = self._test_create_segment(
network_id=net['id'], physical_network='phys_net1',
network_id=net['id'], physical_network='physnet1',
segmentation_id=200, network_type='vlan')['segment']
ovn_nb_api.create_lswitch_port.assert_called_once_with(
addresses=[ovn_const.UNKNOWN_ADDR],
external_ids={},
lport_name=ovn_utils.ovn_provnet_port_name(new_segment['id']),
lswitch_name=ovn_utils.ovn_name(net['id']),
options={'network_name': 'phys_net1',
options={'network_name': 'physnet1',
ovn_const.LSP_OPTIONS_MCAST_FLOOD_REPORTS: 'true',
ovn_const.LSP_OPTIONS_MCAST_FLOOD: 'false'},
tag=200,
type='localnet')
ovn_nb_api.create_lswitch_port.reset_mock()
new_segment = self._test_create_segment(
network_id=net['id'], physical_network='phys_net2',
network_id=net['id'], physical_network='physnet2',
segmentation_id=300, network_type='vlan')['segment']
ovn_nb_api.create_lswitch_port.assert_called_once_with(
addresses=[ovn_const.UNKNOWN_ADDR],
external_ids={},
lport_name=ovn_utils.ovn_provnet_port_name(new_segment['id']),
lswitch_name=ovn_utils.ovn_name(net['id']),
options={'network_name': 'phys_net2',
options={'network_name': 'physnet2',
ovn_const.LSP_OPTIONS_MCAST_FLOOD_REPORTS: 'true',
ovn_const.LSP_OPTIONS_MCAST_FLOOD: 'false'},
tag=300,
@ -2458,7 +2458,7 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
with self.network() as network:
net = network['network']
segment = self._test_create_segment(
network_id=net['id'], physical_network='phys_net1',
network_id=net['id'], physical_network='physnet1',
segmentation_id=200, network_type='vlan')['segment']
self._delete('segments', segment['id'])
ovn_nb_api.delete_lswitch_port.assert_called_once_with(
@ -2470,22 +2470,22 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
with self.network() as network:
net = network['network']
seg_1 = self._test_create_segment(
network_id=net['id'], physical_network='phys_net1',
network_id=net['id'], physical_network='physnet1',
segmentation_id=200, network_type='vlan')['segment']
seg_2 = self._test_create_segment(
network_id=net['id'], physical_network='phys_net2',
network_id=net['id'], physical_network='physnet2',
segmentation_id=300, network_type='vlan')['segment']
# Lets pretend that segment_1 is old and its localnet
# port is based on neutron network id.
ovn_nb_api.fake_ls_row.ports = [
fakes.FakeOVNPort.create_one_port(
attrs={
'options': {'network_name': 'phys_net1'},
'options': {'network_name': 'physnet1'},
'tag': 200,
'name': ovn_utils.ovn_provnet_port_name(net['id'])}),
fakes.FakeOVNPort.create_one_port(
attrs={
'options': {'network_name': 'phys_net2'},
'options': {'network_name': 'physnet2'},
'tag': 300,
'name': ovn_utils.ovn_provnet_port_name(seg_2['id'])})]
self._delete('segments', seg_1['id'])
@ -2511,7 +2511,7 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
with self.network() as n:
self.net = n
self.seg_1 = self._test_create_segment(
network_id=self.net['network']['id'], physical_network='phys_net1',
network_id=self.net['network']['id'], physical_network='physnet1',
segmentation_id=200, network_type='vlan')['segment']
with self.subnet(network=self.net, cidr='10.0.1.0/24',
segment_id=self.seg_1['id']) as subnet:
@ -2519,7 +2519,7 @@ class TestOVNMechanismDriverSegment(MechDriverSetupBase,
# Create second segment and subnet linked to it
self.seg_2 = self._test_create_segment(
network_id=self.net['network']['id'], physical_network='phys_net2',
network_id=self.net['network']['id'], physical_network='physnet2',
segmentation_id=300, network_type='vlan')['segment']
with self.subnet(network=self.net, cidr='10.0.2.0/24',
segment_id=self.seg_2['id']) as subnet:

8
releasenotes/notes/drop-portbindingports-table-575c6d059c698bf0.yaml

@ -0,0 +1,8 @@
---
other:
- |
Class "PortBindingMixin" is removed. Last time this class was used in-tree
was in Kilo release, in "N1kvNeutronPluginV2" and "SdnvePluginV2" classes.
No active project is using it anymore.
Table "portbindingports" is dropped from the database; it was used only in
"PortBindingMixin".
Loading…
Cancel
Save