[OVN] Use new distributed device_owner for OVN distributed services
OVN distributed services like Metadata and DHCP uses now DEVICE_OWNER_DHCP device_owner which isn't distributed by its nature. To fully use benefits of OVN Distributed ports (localports) [1] and to not overlap with Neutron logic created for not-distributed ports we should use new device_owner. In this change we need also to bump minimum required neutron-lib to 2.4.0. [1] https://www.ovn.org/support/dist-docs/ovn-nb.5.txt Change-Id: I0a69f1bddaa7030c7287216e62ec1ac6dd381475
This commit is contained in:
parent
da45bbbff4
commit
b2b40b6a8c
@ -51,7 +51,7 @@ msgpack-python==0.4.0
|
||||
munch==2.1.0
|
||||
netaddr==0.7.18
|
||||
netifaces==0.10.4
|
||||
neutron-lib==2.3.0
|
||||
neutron-lib==2.4.0
|
||||
openstacksdk==0.31.2
|
||||
os-client-config==1.28.0
|
||||
os-ken==0.3.0
|
||||
|
@ -75,4 +75,5 @@ IDPOOL_SELECT_SIZE = 100
|
||||
# finds out that all existing IP Allocations are associated with ports
|
||||
# with these owners, it will allow subnet deletion to proceed with the
|
||||
# IP allocations being cleaned up by cascade.
|
||||
AUTO_DELETE_PORT_OWNERS = [constants.DEVICE_OWNER_DHCP]
|
||||
AUTO_DELETE_PORT_OWNERS = [constants.DEVICE_OWNER_DHCP,
|
||||
constants.DEVICE_OWNER_DISTRIBUTED]
|
||||
|
@ -1 +1 @@
|
||||
dfe425060830
|
||||
fd6107509ccd
|
||||
|
@ -0,0 +1,52 @@
|
||||
# Copyright 2020 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.
|
||||
#
|
||||
|
||||
from alembic import op
|
||||
from neutron_lib import constants
|
||||
import sqlalchemy as sa
|
||||
|
||||
"""ovn_distributed_device_owner
|
||||
|
||||
Revision ID: fd6107509ccd
|
||||
Revises: 5c85685d616d
|
||||
Create Date: 2020-06-01 11:16:58.312355
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'fd6107509ccd'
|
||||
down_revision = 'dfe425060830'
|
||||
|
||||
PORTS_TABLE = 'ports'
|
||||
OVN_METADATA_PREFIX = 'ovnmeta'
|
||||
|
||||
|
||||
def upgrade():
|
||||
update_device_owner_ovn_distributed_ports()
|
||||
|
||||
|
||||
def update_device_owner_ovn_distributed_ports():
|
||||
ports = sa.Table(PORTS_TABLE,
|
||||
sa.MetaData(),
|
||||
sa.Column('device_owner', sa.String(255)),
|
||||
sa.Column('device_id', sa.String(255)))
|
||||
|
||||
session = sa.orm.Session(bind=op.get_bind())
|
||||
with session.begin(subtransactions=True):
|
||||
session.execute(ports.update().values(
|
||||
device_owner=constants.DEVICE_OWNER_DISTRIBUTED).where(
|
||||
ports.c.device_owner == constants.DEVICE_OWNER_DHCP).where(
|
||||
ports.c.device_id.like('{}%'.format(OVN_METADATA_PREFIX))))
|
||||
session.commit()
|
@ -285,7 +285,8 @@ class AddressRequestFactory(object):
|
||||
elif ip_dict.get('eui64_address'):
|
||||
return AutomaticAddressRequest(prefix=ip_dict['subnet_cidr'],
|
||||
mac=ip_dict['mac'])
|
||||
elif port['device_owner'] == constants.DEVICE_OWNER_DHCP:
|
||||
elif (port['device_owner'] == constants.DEVICE_OWNER_DHCP or
|
||||
port['device_owner'] == constants.DEVICE_OWNER_DISTRIBUTED):
|
||||
# preserve previous behavior of DHCP ports choosing start of pool
|
||||
return PreferNextAddressRequest()
|
||||
else:
|
||||
|
@ -259,7 +259,11 @@ class OVNClient(object):
|
||||
|
||||
# Only adjust the OVN type if the port is not owned by Neutron
|
||||
# DHCP agents.
|
||||
if (port['device_owner'] == const.DEVICE_OWNER_DHCP and
|
||||
# TODO(mjozefcz): Remove const.DEVICE_OWNER_DHCP
|
||||
# from get_ports in W-release.
|
||||
if (port['device_owner'] in [
|
||||
const.DEVICE_OWNER_DISTRIBUTED,
|
||||
const.DEVICE_OWNER_DHCP] and
|
||||
not utils.is_neutron_dhcp_agent_port(port)):
|
||||
port_type = 'localport'
|
||||
|
||||
@ -2030,9 +2034,19 @@ class OVNClient(object):
|
||||
if not ovn_conf.is_ovn_metadata_enabled():
|
||||
return
|
||||
|
||||
# TODO(mjozefcz): Remove const.DEVICE_OWNER_DHCP
|
||||
# from get_ports in W-release.
|
||||
ports = self._plugin.get_ports(context, filters=dict(
|
||||
network_id=[network_id], device_owner=[const.DEVICE_OWNER_DHCP]))
|
||||
|
||||
network_id=[network_id],
|
||||
device_owner=[
|
||||
const.DEVICE_OWNER_DHCP,
|
||||
const.DEVICE_OWNER_DISTRIBUTED]))
|
||||
# TODO(mjozefcz): Remove this compatibility code in W release.
|
||||
# First look for const.DEVICE_OWNER_DISTRIBUTED and then for
|
||||
# const.DEVICE_OWNER_DHCP.
|
||||
for port in ports:
|
||||
if port['device_owner'] == const.DEVICE_OWNER_DISTRIBUTED:
|
||||
return port
|
||||
# Metadata ports are DHCP ports not belonging to the Neutron
|
||||
# DHCP agents
|
||||
for port in ports:
|
||||
@ -2054,7 +2068,7 @@ class OVNClient(object):
|
||||
port = {'port':
|
||||
{'network_id': network['id'],
|
||||
'tenant_id': network['project_id'],
|
||||
'device_owner': const.DEVICE_OWNER_DHCP,
|
||||
'device_owner': const.DEVICE_OWNER_DISTRIBUTED,
|
||||
'device_id': 'ovnmeta-%s' % network['id']}}
|
||||
# TODO(boden): rehome create_port into neutron-lib
|
||||
p_utils.create_port(self._plugin, context, port)
|
||||
|
@ -742,10 +742,14 @@ class OvnNbSynchronizer(OvnDbSynchronizer):
|
||||
if not ovn_conf.is_ovn_metadata_enabled():
|
||||
return
|
||||
LOG.debug('OVN sync metadata ports started')
|
||||
# TODO(mjozefcz): Remove constants.DEVICE_OWNER_DHCP
|
||||
# from get_ports in W-release.
|
||||
for net in self.core_plugin.get_networks(ctx):
|
||||
dhcp_ports = self.core_plugin.get_ports(ctx, filters=dict(
|
||||
network_id=[net['id']],
|
||||
device_owner=[constants.DEVICE_OWNER_DHCP]))
|
||||
device_owner=[
|
||||
constants.DEVICE_OWNER_DISTRIBUTED,
|
||||
constants.DEVICE_OWNER_DHCP]))
|
||||
|
||||
for port in dhcp_ports:
|
||||
# Do not touch the Neutron DHCP agents ports
|
||||
|
@ -879,7 +879,7 @@ class TestOvnNbSync(base.TestOVNFunctionalBase):
|
||||
db_metadata_ports_ids = set()
|
||||
db_metadata_ports_nets = set()
|
||||
for port in db_ports['ports']:
|
||||
if (port['device_owner'] == constants.DEVICE_OWNER_DHCP and
|
||||
if (port['device_owner'] == constants.DEVICE_OWNER_DISTRIBUTED and
|
||||
port['device_id'].startswith('ovnmeta')):
|
||||
db_metadata_ports_ids.add(port['id'])
|
||||
db_metadata_ports_nets.add(port['network_id'])
|
||||
@ -1341,7 +1341,7 @@ class TestOvnNbSync(base.TestOVNFunctionalBase):
|
||||
db_ports = self._list('ports')
|
||||
db_metadata_ports = [port for port in db_ports['ports'] if
|
||||
port['device_owner'] ==
|
||||
constants.DEVICE_OWNER_DHCP and
|
||||
constants.DEVICE_OWNER_DISTRIBUTED and
|
||||
port['device_id'].startswith('ovnmeta')]
|
||||
lswitches = {}
|
||||
ports_to_delete = len(db_metadata_ports) / 2
|
||||
|
@ -317,6 +317,13 @@ class TestAddressRequestFactory(base.BaseTestCase):
|
||||
ipam_req.AddressRequestFactory.get_request(None, port, ip),
|
||||
ipam_req.PreferNextAddressRequest)
|
||||
|
||||
def test_prefernext_address_request_on_distributed_port(self):
|
||||
ip = {}
|
||||
port = {'device_owner': constants.DEVICE_OWNER_DISTRIBUTED}
|
||||
self.assertIsInstance(
|
||||
ipam_req.AddressRequestFactory.get_request(None, port, ip),
|
||||
ipam_req.PreferNextAddressRequest)
|
||||
|
||||
|
||||
class TestSubnetRequestFactory(IpamSubnetRequestTestCase):
|
||||
|
||||
|
@ -2906,16 +2906,21 @@ class TestOVNMechanismDriverMetadataPort(test_plugin.Ml2PluginV2TestCase):
|
||||
p.start()
|
||||
self.addCleanup(p.stop)
|
||||
|
||||
def _create_fake_dhcp_port(self, device_id):
|
||||
return {'network_id': 'fake', 'device_owner': const.DEVICE_OWNER_DHCP,
|
||||
def _create_fake_dhcp_port(self, device_id, neutron_port=False):
|
||||
port = {'network_id': 'fake',
|
||||
'device_owner': const.DEVICE_OWNER_DISTRIBUTED,
|
||||
'device_id': device_id}
|
||||
if neutron_port:
|
||||
port['device_owner'] = const.DEVICE_OWNER_DHCP
|
||||
return port
|
||||
|
||||
@mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2, 'get_ports')
|
||||
def test__find_metadata_port(self, mock_get_ports):
|
||||
ports = [
|
||||
self._create_fake_dhcp_port('dhcp-0'),
|
||||
self._create_fake_dhcp_port('dhcp-1'),
|
||||
self._create_fake_dhcp_port(const.DEVICE_ID_RESERVED_DHCP_PORT),
|
||||
self._create_fake_dhcp_port('dhcp-0', neutron_port=True),
|
||||
self._create_fake_dhcp_port('dhcp-1', neutron_port=True),
|
||||
self._create_fake_dhcp_port(const.DEVICE_ID_RESERVED_DHCP_PORT,
|
||||
neutron_port=True),
|
||||
self._create_fake_dhcp_port('ovnmeta-0')]
|
||||
mock_get_ports.return_value = ports
|
||||
|
||||
@ -2923,6 +2928,20 @@ class TestOVNMechanismDriverMetadataPort(test_plugin.Ml2PluginV2TestCase):
|
||||
self.ctx, 'fake-net-id')
|
||||
self.assertEqual('ovnmeta-0', md_port['device_id'])
|
||||
|
||||
@mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2, 'get_ports')
|
||||
def test__find_metadata_port_compat(self, mock_get_ports):
|
||||
ports = [
|
||||
self._create_fake_dhcp_port('dhcp-0', neutron_port=True),
|
||||
self._create_fake_dhcp_port('dhcp-1', neutron_port=True),
|
||||
self._create_fake_dhcp_port(const.DEVICE_ID_RESERVED_DHCP_PORT,
|
||||
neutron_port=True),
|
||||
self._create_fake_dhcp_port('ovnmeta-0', neutron_port=True)]
|
||||
mock_get_ports.return_value = ports
|
||||
|
||||
md_port = self.mech_driver._ovn_client._find_metadata_port(
|
||||
self.ctx, 'fake-net-id')
|
||||
self.assertEqual('ovnmeta-0', md_port['device_id'])
|
||||
|
||||
def test_metadata_port_on_network_create(self):
|
||||
"""Check metadata port create.
|
||||
|
||||
@ -2958,7 +2977,7 @@ class TestOVNMechanismDriverMetadataPort(test_plugin.Ml2PluginV2TestCase):
|
||||
# Create a network:dhcp owner port just as how Neutron DHCP
|
||||
# agent would do.
|
||||
with self.port(subnet=subnet1,
|
||||
device_owner=const.DEVICE_OWNER_DHCP,
|
||||
device_owner=const.DEVICE_OWNER_DISTRIBUTED,
|
||||
device_id='dhcpxxxx',
|
||||
set_context=True, tenant_id='test'):
|
||||
with self.subnet(network=net1, cidr='20.0.0.0/24'):
|
||||
|
@ -16,7 +16,7 @@ Jinja2>=2.10 # BSD License (3 clause)
|
||||
keystonemiddleware>=4.17.0 # Apache-2.0
|
||||
netaddr>=0.7.18 # BSD
|
||||
netifaces>=0.10.4 # MIT
|
||||
neutron-lib>=2.3.0 # Apache-2.0
|
||||
neutron-lib>=2.4.0 # Apache-2.0
|
||||
python-neutronclient>=6.7.0 # Apache-2.0
|
||||
tenacity>=4.4.0 # Apache-2.0
|
||||
SQLAlchemy>=1.2.0 # MIT
|
||||
|
Loading…
Reference in New Issue
Block a user