From 8912ea55755f61a85cf3406d9fab5f0af502d09d Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Fri, 18 Dec 2020 11:06:18 +0000 Subject: [PATCH] Add port device profile extension Added a new port extension: device profile (``port_device_profile``). This extension adds the "device_profile" parameter to the "port" API and specifies the device profile per port. This parameter is a string. This parameter is passed to Nova and Nova retrieves the requested device profile from Cyborg. Reference: https://docs.openstack.org/api-ref/accelerator/v2/index.html# device-profiles For backwards compatibility, this parameter will be "None" by default. Closes-Bug: #1906602 Depends-On: https://review.opendev.org/c/openstack/neutron-lib/+/767586 Change-Id: I1202a8388e64ae4270ef4ca118993504ae7c1731 --- lower-constraints.txt | 4 +- neutron/common/ovn/extensions.py | 2 + .../alembic_migrations/versions/EXPAND_HEAD | 2 +- .../1e0744e4ffea_port_device_profile.py | 43 ++++++++++++++ neutron/db/models/port_device_profile.py | 34 +++++++++++ neutron/db/port_device_profile_db.py | 38 ++++++++++++ neutron/extensions/port_device_profile.py | 20 +++++++ .../port/extensions/port_device_profile.py | 36 ++++++++++++ neutron/objects/ports.py | 11 +++- .../ml2/extensions/port_device_profile.py | 42 ++++++++++++++ neutron/plugins/ml2/plugin.py | 2 + .../tests/contrib/hooks/api_all_extensions | 1 + .../tests/unit/db/test_db_base_plugin_v2.py | 4 +- .../extensions/test_port_device_profile.py | 58 +++++++++++++++++++ neutron/tests/unit/objects/test_base.py | 3 + neutron/tests/unit/objects/test_objects.py | 3 +- neutron/tests/unit/objects/test_ports.py | 6 ++ ...ce-profile-extension-30ffdaf6a89b89dc.yaml | 13 +++++ requirements.txt | 4 +- setup.cfg | 1 + 20 files changed, 318 insertions(+), 9 deletions(-) create mode 100644 neutron/db/migration/alembic_migrations/versions/wallaby/expand/1e0744e4ffea_port_device_profile.py create mode 100644 neutron/db/models/port_device_profile.py create mode 100644 neutron/db/port_device_profile_db.py create mode 100644 neutron/extensions/port_device_profile.py create mode 100644 neutron/objects/port/extensions/port_device_profile.py create mode 100644 neutron/plugins/ml2/extensions/port_device_profile.py create mode 100644 neutron/tests/unit/extensions/test_port_device_profile.py create mode 100644 releasenotes/notes/port-device-profile-extension-30ffdaf6a89b89dc.yaml diff --git a/lower-constraints.txt b/lower-constraints.txt index e37988b279a..89221aafcbf 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -51,7 +51,7 @@ msgpack-python==0.4.0 munch==2.1.0 netaddr==0.7.18 netifaces==0.10.4 -neutron-lib==2.6.1 +neutron-lib==2.8.0 openstacksdk==0.31.2 os-client-config==1.28.0 os-ken==0.3.0 @@ -60,7 +60,7 @@ os-vif==1.15.1 osc-lib==1.8.0 oslo.cache==1.26.0 oslo.concurrency==3.26.0 -oslo.config==6.8.0 +oslo.config==8.0.0 oslo.context==2.22.0 oslo.db==4.44.0 oslo.i18n==3.20.0 diff --git a/neutron/common/ovn/extensions.py b/neutron/common/ovn/extensions.py index 0c3ce333757..9f2e8955d6f 100644 --- a/neutron/common/ovn/extensions.py +++ b/neutron/common/ovn/extensions.py @@ -33,6 +33,7 @@ from neutron_lib.api.definitions import network_ip_availability from neutron_lib.api.definitions import network_mtu from neutron_lib.api.definitions import network_mtu_writable from neutron_lib.api.definitions import pagination +from neutron_lib.api.definitions import port_device_profile from neutron_lib.api.definitions import port_numa_affinity_policy from neutron_lib.api.definitions import port_resource_request from neutron_lib.api.definitions import port_security @@ -87,6 +88,7 @@ ML2_SUPPORTED_API_EXTENSIONS = [ network_mtu_writable.ALIAS, network_availability_zone.ALIAS, network_ip_availability.ALIAS, + port_device_profile.ALIAS, port_numa_affinity_policy.ALIAS, port_security.ALIAS, provider_net.ALIAS, diff --git a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD index 765e9656280..7000cdb47ff 100644 --- a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD +++ b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD @@ -1 +1 @@ -26d1e9f5c766 +1e0744e4ffea diff --git a/neutron/db/migration/alembic_migrations/versions/wallaby/expand/1e0744e4ffea_port_device_profile.py b/neutron/db/migration/alembic_migrations/versions/wallaby/expand/1e0744e4ffea_port_device_profile.py new file mode 100644 index 00000000000..a9ca6fc49bc --- /dev/null +++ b/neutron/db/migration/alembic_migrations/versions/wallaby/expand/1e0744e4ffea_port_device_profile.py @@ -0,0 +1,43 @@ +# 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.db import constants as db_const +import sqlalchemy as sa + + +"""port_device_profile + +Revision ID: 1e0744e4ffea +Revises: 26d1e9f5c766 +Create Date: 2020-12-18 10:12:14.865465 + +""" + +# revision identifiers, used by Alembic. +revision = '1e0744e4ffea' +down_revision = '26d1e9f5c766' + + +def upgrade(): + op.create_table('portdeviceprofiles', + sa.Column('port_id', + sa.String(length=db_const.UUID_FIELD_SIZE), + sa.ForeignKey('ports.id', ondelete='CASCADE'), + primary_key=True), + sa.Column('device_profile', + sa.String(255), + nullable=True) + ) diff --git a/neutron/db/models/port_device_profile.py b/neutron/db/models/port_device_profile.py new file mode 100644 index 00000000000..d01bbb2b938 --- /dev/null +++ b/neutron/db/models/port_device_profile.py @@ -0,0 +1,34 @@ +# Copyright 2020 Red Hat, 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.db import constants as db_const +from neutron_lib.db import model_base +import sqlalchemy as sa + +from neutron.db import models_v2 + + +class PortDeviceProfile(model_base.BASEV2): + __tablename__ = 'portdeviceprofiles' + port_id = sa.Column(sa.String(db_const.UUID_FIELD_SIZE), + sa.ForeignKey('ports.id', ondelete='CASCADE'), + primary_key=True) + device_profile = sa.Column('device_profile', sa.String(length=255)) + port = sa.orm.relationship( + models_v2.Port, load_on_pending=True, + backref=sa.orm.backref('device_profile', uselist=False, + cascade='delete', lazy='joined')) + + revises_on_change = ('port', ) diff --git a/neutron/db/port_device_profile_db.py b/neutron/db/port_device_profile_db.py new file mode 100644 index 00000000000..32e8698261a --- /dev/null +++ b/neutron/db/port_device_profile_db.py @@ -0,0 +1,38 @@ +# Copyright (c) 2020 Red Hat, Inc. +# +# 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_device_profile as pdp + +from neutron.objects.port.extensions import port_device_profile as pdp_obj + + +class PortDeviceProfileMixin(object): + """Mixin class to add device profile (Cyborg) to a port""" + + def _process_create_port(self, context, data, result): + if not data.get(pdp.DEVICE_PROFILE): + result[pdp.DEVICE_PROFILE] = None + return + + obj = pdp_obj.PortDeviceProfile( + context, port_id=result['id'], + device_profile=data[pdp.DEVICE_PROFILE]) + obj.create() + result[pdp.DEVICE_PROFILE] = data[pdp.DEVICE_PROFILE] + + def _extend_port_dict(self, port_db, result): + if port_db.device_profile: + result[pdp.DEVICE_PROFILE] = port_db.device_profile.device_profile + else: + result[pdp.DEVICE_PROFILE] = None diff --git a/neutron/extensions/port_device_profile.py b/neutron/extensions/port_device_profile.py new file mode 100644 index 00000000000..8aecb21c768 --- /dev/null +++ b/neutron/extensions/port_device_profile.py @@ -0,0 +1,20 @@ +# Copyright (c) 2020 Red Hat, Inc. +# +# 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_device_profile +from neutron_lib.api import extensions as api_extensions + + +class Port_device_profile(api_extensions.APIExtensionDescriptor): + api_definition = port_device_profile diff --git a/neutron/objects/port/extensions/port_device_profile.py b/neutron/objects/port/extensions/port_device_profile.py new file mode 100644 index 00000000000..f8f44e52e9d --- /dev/null +++ b/neutron/objects/port/extensions/port_device_profile.py @@ -0,0 +1,36 @@ +# Copyright (c) 2020 Red Hat, Inc. +# +# 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.objects import common_types +from oslo_versionedobjects import fields as obj_fields + +from neutron.db.models import port_device_profile +from neutron.objects import base + + +@base.NeutronObjectRegistry.register +class PortDeviceProfile(base.NeutronDbObject): + # Version 1.0: Initial version + VERSION = '1.0' + + db_model = port_device_profile.PortDeviceProfile + + primary_keys = ['port_id'] + + fields = { + 'port_id': common_types.UUIDField(), + 'device_profile': obj_fields.StringField(nullable=True), + } + + foreign_keys = {'Port': {'port_id': 'id'}} diff --git a/neutron/objects/ports.py b/neutron/objects/ports.py index 0cd7e39638d..9a32a0a856d 100644 --- a/neutron/objects/ports.py +++ b/neutron/objects/ports.py @@ -274,7 +274,8 @@ class Port(base.NeutronDbObject): # Version 1.4: Attribute binding becomes ListOfObjectsField # Version 1.5: Added qos_network_policy_id field # Version 1.6: Added numa_affinity_policy field - VERSION = '1.6' + # Version 1.7: Added port_device field + VERSION = '1.7' db_model = models_v2.Port @@ -325,6 +326,7 @@ class Port(base.NeutronDbObject): 'PortBindingLevel', nullable=True ), 'numa_affinity_policy': obj_fields.StringField(nullable=True), + 'device_profile': obj_fields.StringField(nullable=True), # TODO(ihrachys): consider adding a 'dns_assignment' fully synthetic # field in later object iterations @@ -339,6 +341,7 @@ class Port(base.NeutronDbObject): 'bindings', 'binding_levels', 'data_plane_status', + 'device_profile', 'dhcp_options', 'distributed_bindings', 'dns', @@ -509,6 +512,10 @@ class Port(base.NeutronDbObject): db_obj.numa_affinity_policy.numa_affinity_policy) fields_to_change.append('numa_affinity_policy') + if db_obj.get('device_profile'): + self.device_profile = db_obj.device_profile.device_profile + fields_to_change.append('device_profile') + self.obj_reset_changes(fields_to_change) def obj_make_compatible(self, primitive, target_version): @@ -539,6 +546,8 @@ class Port(base.NeutronDbObject): primitive.pop('qos_network_policy_id', None) if _target_version < (1, 6): primitive.pop('numa_affinity_policy', None) + if _target_version < (1, 7): + primitive.pop('device_profile', None) @classmethod def get_ports_by_router_and_network(cls, context, router_id, owner, diff --git a/neutron/plugins/ml2/extensions/port_device_profile.py b/neutron/plugins/ml2/extensions/port_device_profile.py new file mode 100644 index 00000000000..dafa60f8631 --- /dev/null +++ b/neutron/plugins/ml2/extensions/port_device_profile.py @@ -0,0 +1,42 @@ +# Copyright 2020 Red Hat, 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_device_profile as pdp +from neutron_lib.plugins.ml2 import api +from oslo_log import log as logging + +from neutron.db import port_device_profile_db + + +LOG = logging.getLogger(__name__) + + +class PortDeviceProfileExtensionDriver( + api.ExtensionDriver, port_device_profile_db.PortDeviceProfileMixin): + + _supported_extension_alias = pdp.ALIAS + + def initialize(self): + LOG.info('PortDeviceProfileExtensionDriver initialization complete') + + @property + def extension_alias(self): + return self._supported_extension_alias + + def process_create_port(self, context, data, result): + self._process_create_port(context, data, result) + + def extend_port_dict(self, session, port_db, result): + self._extend_port_dict(port_db, result) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index d5a8f5c3772..c5275325167 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -39,6 +39,7 @@ from neutron_lib.api.definitions import network_availability_zone from neutron_lib.api.definitions import network_mtu as mtu_apidef from neutron_lib.api.definitions import network_mtu_writable as mtuw_apidef from neutron_lib.api.definitions import port as port_def +from neutron_lib.api.definitions import port_device_profile as pdp_def from neutron_lib.api.definitions import port_mac_address_regenerate from neutron_lib.api.definitions import port_numa_affinity_policy as pnap_def from neutron_lib.api.definitions import port_security as psec @@ -221,6 +222,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, stateful_security_group.ALIAS, addrgrp_def.ALIAS, pnap_def.ALIAS, + pdp_def.ALIAS, ] # List of agent types for which all binding_failed ports should try to be diff --git a/neutron/tests/contrib/hooks/api_all_extensions b/neutron/tests/contrib/hooks/api_all_extensions index 773f6646095..5f44bd1e508 100644 --- a/neutron/tests/contrib/hooks/api_all_extensions +++ b/neutron/tests/contrib/hooks/api_all_extensions @@ -54,6 +54,7 @@ NETWORK_API_EXTENSIONS+=",router-admin-state-down-before-update" NETWORK_API_EXTENSIONS+=",router_availability_zone" NETWORK_API_EXTENSIONS+=",security-group" NETWORK_API_EXTENSIONS+=",security-groups-remote-address-group" +NETWORK_API_EXTENSIONS+=",port-device-profile" NETWORK_API_EXTENSIONS+=",port-mac-address-regenerate" NETWORK_API_EXTENSIONS+=",port-numa-affinity-policy" NETWORK_API_EXTENSIONS+=",port-security-groups-filtering" diff --git a/neutron/tests/unit/db/test_db_base_plugin_v2.py b/neutron/tests/unit/db/test_db_base_plugin_v2.py index 039be26748d..5db9c53d31a 100644 --- a/neutron/tests/unit/db/test_db_base_plugin_v2.py +++ b/neutron/tests/unit/db/test_db_base_plugin_v2.py @@ -450,8 +450,8 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase): for arg in (('admin_state_up', 'device_id', 'mac_address', 'name', 'fixed_ips', 'tenant_id', 'device_owner', 'security_groups', - 'propagate_uplink_status', 'numa_affinity_policy') + - (arg_list or ())): + 'propagate_uplink_status', 'numa_affinity_policy', + 'device_profile') + (arg_list or ())): # Arg must be present if arg in kwargs: data['port'][arg] = kwargs[arg] diff --git a/neutron/tests/unit/extensions/test_port_device_profile.py b/neutron/tests/unit/extensions/test_port_device_profile.py new file mode 100644 index 00000000000..9565e88d118 --- /dev/null +++ b/neutron/tests/unit/extensions/test_port_device_profile.py @@ -0,0 +1,58 @@ +# Copyright (c) 2020 Red Hat, Inc. +# +# 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. + +import ddt +from neutron_lib.api.definitions import port_device_profile as apidef +from neutron_lib.db import api as db_api + +from neutron.db import db_base_plugin_v2 +from neutron.db import port_device_profile_db as pdp_db +from neutron.tests.unit.db import test_db_base_plugin_v2 + + +class PortDeviceProfileExtensionTestPlugin( + db_base_plugin_v2.NeutronDbPluginV2, + pdp_db.PortDeviceProfileMixin): + """Test plugin to mixin the port device profile extension.""" + + supported_extension_aliases = [apidef.ALIAS] + + def create_port(self, context, port): + with db_api.CONTEXT_WRITER.using(context): + new_port = super(PortDeviceProfileExtensionTestPlugin, + self).create_port(context, port) + self._process_create_port(context, port['port'], new_port) + return new_port + + +@ddt.ddt +class PortDeviceProfileExtensionTestCase( + test_db_base_plugin_v2.NeutronDbPluginV2TestCase): + """Test API extension numa_affinity_policy attributes.""" + + def setUp(self, *args): + plugin = ('neutron.tests.unit.extensions.test_port_device_profile.' + 'PortDeviceProfileExtensionTestPlugin') + super(PortDeviceProfileExtensionTestCase, self).setUp(plugin=plugin) + + @ddt.data('device_profile_1', None) + def test_create_and_check_port_device_profile(self, device_profile): + keys = [('name', 'name_1'), + ('admin_state_up', True), + ('status', self.port_create_status), + ('device_profile', device_profile)] + with self.port(name='name_1', device_profile=device_profile) as port: + for k, v in keys: + self.assertEqual(v, port['port'][k]) + return port diff --git a/neutron/tests/unit/objects/test_base.py b/neutron/tests/unit/objects/test_base.py index bb67c56cbed..f74353ae494 100644 --- a/neutron/tests/unit/objects/test_base.py +++ b/neutron/tests/unit/objects/test_base.py @@ -44,6 +44,7 @@ from neutron.objects import base from neutron.objects.db import api as obj_db_api from neutron.objects import flavor from neutron.objects import network as net_obj +from neutron.objects.port.extensions import port_device_profile from neutron.objects.port.extensions import port_numa_affinity_policy from neutron.objects import ports from neutron.objects.qos import policy as qos_policy @@ -542,6 +543,8 @@ FIELD_TYPE_VALUE_GENERATOR_MAP = { obj_fields.StringField: lambda: helpers.get_random_string(10), port_numa_affinity_policy.NumaAffinityPoliciesEnumField: tools.get_random_port_numa_affinity_policy, + port_device_profile.PortDeviceProfile: + lambda: helpers.get_random_string(255) } diff --git a/neutron/tests/unit/objects/test_objects.py b/neutron/tests/unit/objects/test_objects.py index ab7da752fdb..1d890fec463 100644 --- a/neutron/tests/unit/objects/test_objects.py +++ b/neutron/tests/unit/objects/test_objects.py @@ -69,7 +69,8 @@ object_data = { 'NetworkSegment': '1.0-57b7f2960971e3b95ded20cbc59244a8', 'NetworkSegmentRange': '1.0-bdec1fffc9058ea676089b1f2f2b3cf3', 'NetworkSubnetLock': '1.0-140de39d4b86ae346dc3d70b885bea53', - 'Port': '1.6-c9a1ecc035181aeb0af76eb395c09ac0', + 'Port': '1.7-d8c1cfe42cfa3719a5d810eeab79e006', + 'PortDeviceProfile': '1.0-b98c7083cc3e93d176fd7a91ae13af32', 'PortNumaAffinityPolicy': '1.0-38fcea43e7bfb2536461f3d053c43aa3', 'PortBinding': '1.0-3306deeaa6deb01e33af06777d48d578', 'PortBindingLevel': '1.1-50d47f63218f87581b6cd9a62db574e5', diff --git a/neutron/tests/unit/objects/test_ports.py b/neutron/tests/unit/objects/test_ports.py index 6d8f0803858..fa3c832ebb6 100644 --- a/neutron/tests/unit/objects/test_ports.py +++ b/neutron/tests/unit/objects/test_ports.py @@ -488,6 +488,12 @@ class PortDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, self.assertNotIn('numa_affinity_policy', port_v1_5['versioned_object.data']) + def test_v1_7_to_v1_6_drops_device_profile(self): + port_new = self._create_test_port() + port_v1_6 = port_new.obj_to_primitive(target_version='1.6') + self.assertNotIn('device_profile', + port_v1_6['versioned_object.data']) + def test_get_ports_ids_by_security_groups_except_router(self): sg_id = self._create_test_security_group_id() filter_owner = constants.ROUTER_INTERFACE_OWNERS_SNAT diff --git a/releasenotes/notes/port-device-profile-extension-30ffdaf6a89b89dc.yaml b/releasenotes/notes/port-device-profile-extension-30ffdaf6a89b89dc.yaml new file mode 100644 index 00000000000..124090e48e6 --- /dev/null +++ b/releasenotes/notes/port-device-profile-extension-30ffdaf6a89b89dc.yaml @@ -0,0 +1,13 @@ +--- +features: + - | + Introduce the attribute ``port_device_profile`` to ports that + specifies the device profile needed per port. This parameter is + a string. This parameter is passed to Nova and Nova retrieves + the requested profile from Cyborg: + `Device profiles `_. + + Operators can turn on this feature via the configuration option:: + + [ml2] + extension_drivers = port_device_profile diff --git a/requirements.txt b/requirements.txt index eff2b18a090..b474989fb1d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ Jinja2>=2.10 # BSD License (3 clause) keystonemiddleware>=5.1.0 # Apache-2.0 netaddr>=0.7.18 # BSD netifaces>=0.10.4 # MIT -neutron-lib>=2.6.1 # Apache-2.0 +neutron-lib>=2.8.0 # Apache-2.0 python-neutronclient>=6.7.0 # Apache-2.0 tenacity>=6.0.0 # Apache-2.0 SQLAlchemy>=1.2.0 # MIT @@ -26,7 +26,7 @@ alembic>=0.9.6 # MIT stevedore>=1.20.0 # Apache-2.0 oslo.cache>=1.26.0 # Apache-2.0 oslo.concurrency>=3.26.0 # Apache-2.0 -oslo.config>=6.8.0 # Apache-2.0 +oslo.config>=8.0.0 # Apache-2.0 oslo.context>=2.22.0 # Apache-2.0 oslo.db>=4.44.0 # Apache-2.0 oslo.i18n>=3.20.0 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg index 133ec719fc3..b8d3ecc4519 100644 --- a/setup.cfg +++ b/setup.cfg @@ -113,6 +113,7 @@ neutron.ml2.extension_drivers = dns = neutron.plugins.ml2.extensions.dns_integration:DNSExtensionDriverML2 data_plane_status = neutron.plugins.ml2.extensions.data_plane_status:DataPlaneStatusExtensionDriver dns_domain_ports = neutron.plugins.ml2.extensions.dns_integration:DNSDomainPortsExtensionDriver + port_device_profile = neutron.plugins.ml2.extensions.port_device_profile:PortDeviceProfileExtensionDriver port_numa_affinity_policy = neutron.plugins.ml2.extensions.port_numa_affinity_policy:PortNumaAffinityPolicyExtensionDriver uplink_status_propagation = neutron.plugins.ml2.extensions.uplink_status_propagation:UplinkStatusPropagationExtensionDriver tag_ports_during_bulk_creation = neutron.plugins.ml2.extensions.tag_ports_during_bulk_creation:TagPortsDuringBulkCreationExtensionDriver