From 21e0942c0c15949b96a42df2a46e0201b7704643 Mon Sep 17 00:00:00 2001 From: boden Date: Wed, 21 Mar 2018 18:33:49 +0000 Subject: [PATCH] Revert "use segment api def from neutron-lib" This reverts commit ec1d5def67d404972d3a46a2c281380b061c5219. For more details see https://bugs.launchpad.net/neutron/+bug/1757513 Related-Bug: #1757513 Change-Id: I29a96295d3f715cb68a2be1e8345b78c8e490948 --- neutron/db/ipam_backend_mixin.py | 6 +- neutron/db/models/segment.py | 4 +- neutron/extensions/segment.py | 106 ++++++++++++++++-- neutron/services/segments/db.py | 8 +- neutron/tests/unit/extensions/test_segment.py | 12 +- 5 files changed, 106 insertions(+), 30 deletions(-) diff --git a/neutron/db/ipam_backend_mixin.py b/neutron/db/ipam_backend_mixin.py index 141b92984d8..892ae1ffe2e 100644 --- a/neutron/db/ipam_backend_mixin.py +++ b/neutron/db/ipam_backend_mixin.py @@ -20,7 +20,6 @@ import itertools import netaddr from neutron_lib.api.definitions import ip_allocation as ipalloc_apidef from neutron_lib.api.definitions import portbindings -from neutron_lib.api.definitions import segment as seg_apidef from neutron_lib.api import validators from neutron_lib import constants as const from neutron_lib import exceptions as exc @@ -40,6 +39,7 @@ from neutron.db import db_base_plugin_common from neutron.db.models import segment as segment_model from neutron.db.models import subnet_service_type as sst_model from neutron.db import models_v2 +from neutron.extensions import segment from neutron.ipam import exceptions as ipam_exceptions from neutron.ipam import utils as ipam_utils from neutron.objects import network as network_obj @@ -732,8 +732,8 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon): def _make_subnet_args(self, detail, subnet, subnetpool_id): args = super(IpamBackendMixin, self)._make_subnet_args( detail, subnet, subnetpool_id) - if validators.is_attr_set(subnet.get(seg_apidef.SEGMENT_ID)): - args['segment_id'] = subnet[seg_apidef.SEGMENT_ID] + if validators.is_attr_set(subnet.get(segment.SEGMENT_ID)): + args['segment_id'] = subnet[segment.SEGMENT_ID] if validators.is_attr_set(subnet.get('service_types')): args['service_types'] = subnet['service_types'] return args diff --git a/neutron/db/models/segment.py b/neutron/db/models/segment.py index 352a620ee04..df37fbf450b 100644 --- a/neutron/db/models/segment.py +++ b/neutron/db/models/segment.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron_lib.api.definitions import segment as seg_apidef from neutron_lib.db import constants as db_const from neutron_lib.db import model_base import sqlalchemy as sa @@ -22,6 +21,7 @@ from sqlalchemy import orm from neutron.db import models_v2 from neutron.db import standard_attr +from neutron.extensions import segment # Some standalone plugins need a DB table to store provider @@ -51,7 +51,7 @@ class NetworkSegment(standard_attr.HasStandardAttributes, backref=orm.backref("segments", lazy='subquery', cascade='delete')) - api_collections = [seg_apidef.COLLECTION_NAME] + api_collections = [segment.SEGMENTS] class SegmentHostMapping(model_base.BASEV2): diff --git a/neutron/extensions/segment.py b/neutron/extensions/segment.py index e05e2700e0f..0eb19f4f3be 100644 --- a/neutron/extensions/segment.py +++ b/neutron/extensions/segment.py @@ -14,34 +14,120 @@ import abc -from neutron_lib.api.definitions import segment as apidef +from neutron_lib.api import converters +from neutron_lib.api.definitions import provider_net as providernet +from neutron_lib.api.definitions import subnet as subnet_def from neutron_lib.api import extensions as api_extensions +from neutron_lib import constants +from neutron_lib.db import constants as db_const from neutron_lib.plugins import directory import six from neutron.api import extensions from neutron.api.v2 import base +SEGMENT = 'segment' +SEGMENTS = '%ss' % SEGMENT +SEGMENT_ID = 'segment_id' -class Segment(api_extensions.APIExtensionDescriptor): +NETWORK_TYPE = 'network_type' +PHYSICAL_NETWORK = 'physical_network' +SEGMENTATION_ID = 'segmentation_id' +NAME_LEN = db_const.NAME_FIELD_SIZE +DESC_LEN = db_const.DESCRIPTION_FIELD_SIZE + +# Attribute Map +RESOURCE_ATTRIBUTE_MAP = { + SEGMENTS: { + 'id': {'allow_post': False, + 'allow_put': False, + 'validate': {'type:uuid': None}, + 'is_visible': True, + 'primary_key': True}, + 'tenant_id': {'allow_post': True, + 'allow_put': False, + 'validate': {'type:string': + db_const.PROJECT_ID_FIELD_SIZE}, + 'is_visible': False}, + 'network_id': {'allow_post': True, + 'allow_put': False, + 'validate': {'type:uuid': None}, + 'is_visible': True}, + PHYSICAL_NETWORK: {'allow_post': True, + 'allow_put': False, + 'default': constants.ATTR_NOT_SPECIFIED, + 'validate': {'type:string': + providernet.PHYSICAL_NETWORK_MAX_LEN}, + 'is_visible': True}, + NETWORK_TYPE: {'allow_post': True, + 'allow_put': False, + 'validate': {'type:string': + providernet.NETWORK_TYPE_MAX_LEN}, + 'is_visible': True}, + SEGMENTATION_ID: {'allow_post': True, + 'allow_put': False, + 'default': constants.ATTR_NOT_SPECIFIED, + 'convert_to': converters.convert_to_int, + 'is_visible': True}, + 'name': {'allow_post': True, + 'allow_put': True, + 'default': constants.ATTR_NOT_SPECIFIED, + 'validate': {'type:string_or_none': NAME_LEN}, + 'is_visible': True}, + 'description': {'allow_post': True, + 'allow_put': True, + 'default': constants.ATTR_NOT_SPECIFIED, + 'validate': {'type:string_or_none': DESC_LEN}, + 'is_visible': True}, + }, + subnet_def.COLLECTION_NAME: { + SEGMENT_ID: {'allow_post': True, + 'allow_put': False, + 'default': None, + 'validate': {'type:uuid_or_none': None}, + 'is_visible': True, }, + }, +} + + +class Segment(api_extensions.ExtensionDescriptor): """Extension class supporting Segments.""" - api_definition = apidef + @classmethod + def get_name(cls): + return "Segment" + + @classmethod + def get_alias(cls): + return "segment" + + @classmethod + def get_description(cls): + return "Segments extension." + + @classmethod + def get_updated(cls): + return "2016-02-24T17:00:00-00:00" @classmethod def get_resources(cls): """Returns Extended Resource for service type management.""" - resource_attributes = apidef.RESOURCE_ATTRIBUTE_MAP[ - apidef.COLLECTION_NAME] + resource_attributes = RESOURCE_ATTRIBUTE_MAP[SEGMENTS] controller = base.create_resource( - apidef.COLLECTION_NAME, - apidef.RESOURCE_NAME, - directory.get_plugin(apidef.COLLECTION_NAME), + SEGMENTS, + SEGMENT, + directory.get_plugin(SEGMENTS), resource_attributes) - return [extensions.ResourceExtension(apidef.COLLECTION_NAME, + return [extensions.ResourceExtension(SEGMENTS, controller, attr_map=resource_attributes)] + def get_extended_resources(self, version): + if version == "2.0": + return RESOURCE_ATTRIBUTE_MAP + else: + return {} + @six.add_metaclass(abc.ABCMeta) class SegmentPluginBase(object): @@ -143,4 +229,4 @@ class SegmentPluginBase(object): @classmethod def get_plugin_type(cls): - return apidef.COLLECTION_NAME + return SEGMENTS diff --git a/neutron/services/segments/db.py b/neutron/services/segments/db.py index 19cd1ef70c2..a2ff5bc8748 100644 --- a/neutron/services/segments/db.py +++ b/neutron/services/segments/db.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron_lib.api.definitions import segment as seg_apidef from neutron_lib.callbacks import events from neutron_lib.callbacks import registry from neutron_lib.callbacks import resources @@ -30,6 +29,7 @@ from neutron.db import _utils as db_utils from neutron.db import api as db_api from neutron.db import common_db_mixin from neutron.db import segments_db as db +from neutron.extensions import segment as extension from neutron import manager from neutron.objects import base as base_obj from neutron.objects import network @@ -74,11 +74,11 @@ class SegmentDbMixin(common_db_mixin.CommonDbMixin): def _create_segment_db(self, context, segment_id, segment): with db_api.context_manager.writer.using(context): network_id = segment['network_id'] - physical_network = segment[seg_apidef.PHYSICAL_NETWORK] + physical_network = segment[extension.PHYSICAL_NETWORK] if physical_network == constants.ATTR_NOT_SPECIFIED: physical_network = None - network_type = segment[seg_apidef.NETWORK_TYPE] - segmentation_id = segment[seg_apidef.SEGMENTATION_ID] + network_type = segment[extension.NETWORK_TYPE] + segmentation_id = segment[extension.SEGMENTATION_ID] if segmentation_id == constants.ATTR_NOT_SPECIFIED: segmentation_id = None name = segment['name'] diff --git a/neutron/tests/unit/extensions/test_segment.py b/neutron/tests/unit/extensions/test_segment.py index e4bf666cc52..fcb6d9f27b7 100644 --- a/neutron/tests/unit/extensions/test_segment.py +++ b/neutron/tests/unit/extensions/test_segment.py @@ -20,7 +20,6 @@ import netaddr from neutron_lib.api.definitions import ip_allocation as ipalloc_apidef from neutron_lib.api.definitions import l2_adjacency as l2adj_apidef from neutron_lib.api.definitions import portbindings -from neutron_lib.api.definitions import segment as seg_apidef from neutron_lib.callbacks import events from neutron_lib.callbacks import exceptions from neutron_lib.callbacks import registry @@ -41,7 +40,6 @@ 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.db import standard_attr from neutron.extensions import segment as ext_segment from neutron.objects import network from neutron.services.segments import db @@ -79,13 +77,6 @@ class SegmentTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase): self.patch_notifier = mock.patch( 'neutron.notifiers.batch_notifier.BatchNotifier._notify') self.patch_notifier.start() - - # NOTE(boden): mock behavior of standardattrdescription to not - # overwrite description of segment API - mock.patch.object(standard_attr, - 'get_standard_attr_resource_model_map', - return_value={}).start() - if not plugin: plugin = TEST_PLUGIN_KLASS service_plugins = {'segments_plugin_name': SERVICE_PLUGIN_KLASS} @@ -1479,8 +1470,7 @@ class TestNovaSegmentNotifier(SegmentAwareIpamTestCase): # Need notifier here self.patch_notifier.stop() self._mock_keystone_auth() - self.segments_plugin = directory.get_plugin( - seg_apidef.COLLECTION_NAME) + self.segments_plugin = directory.get_plugin(ext_segment.SEGMENTS) nova_updater = self.segments_plugin.nova_updater nova_updater.p_client = mock.MagicMock()