rehome multi provider net extension api definition

This patch rehomes the multi provider net extension's API definition and
exceptions into neutron-lib. In addition a new validation and type is
added as well as a utility function for checking duplicate segments.
UTs and a release note are also included.

Change-Id: If3367e6a14074a6225bba527e8f7e38c51280f85
This commit is contained in:
Boden R
2017-08-16 15:08:50 -06:00
parent 2ebcd88430
commit 0bd451f224
7 changed files with 240 additions and 0 deletions

View File

@@ -40,6 +40,7 @@ from neutron_lib.api.definitions import l3_flavors
from neutron_lib.api.definitions import logging
from neutron_lib.api.definitions import logging_resource
from neutron_lib.api.definitions import metering
from neutron_lib.api.definitions import multiprovidernet
from neutron_lib.api.definitions import network
from neutron_lib.api.definitions import network_availability_zone
from neutron_lib.api.definitions import network_ip_availability
@@ -93,6 +94,7 @@ _ALL_API_DEFINITIONS = {
logging,
logging_resource,
metering,
multiprovidernet,
network,
network_availability_zone,
network_ip_availability,

View File

@@ -0,0 +1,71 @@
# Copyright (c) 2013 OpenStack Foundation.
# 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 import converters
from neutron_lib.api.definitions import network
from neutron_lib.api import validators
from neutron_lib.api.validators import multiprovidernet as mp_validator
from neutron_lib import constants
from neutron_lib.exceptions import multiprovidernet as mp_exc
def check_duplicate_segments(segments, is_partial_func=None):
"""Helper function checking duplicate segments.
If is_partial_funcs is specified and not None, then
SegmentsContainDuplicateEntry is raised if two segments are identical and
non partially defined (is_partial_func(segment) == False).
Otherwise SegmentsContainDuplicateEntry is raised if two segment are
identical.
"""
if is_partial_func is not None:
segments = [s for s in segments if not is_partial_func(s)]
fully_specifieds = [tuple(sorted(s.items())) for s in segments]
if len(set(fully_specifieds)) != len(fully_specifieds):
raise mp_exc.SegmentsContainDuplicateEntry()
validators.add_validator(
'network_segments', mp_validator.convert_and_validate_segments)
SEGMENTS = 'segments'
ALIAS = 'multi-provider'
IS_SHIM_EXTENSION = False
IS_STANDARD_ATTR_EXTENSION = False
NAME = 'Multi Provider Network'
API_PREFIX = ''
DESCRIPTION = ("Expose mapping of virtual networks to multiple physical "
"networks")
UPDATED_TIMESTAMP = '2013-06-27T10:00:00-00:00'
RESOURCE_NAME = network.RESOURCE_NAME
COLLECTION_NAME = network.COLLECTION_NAME
RESOURCE_ATTRIBUTE_MAP = {
COLLECTION_NAME: {
SEGMENTS: {
'allow_post': True, 'allow_put': True,
'validate': {'type:network_segments': None},
'convert_list_to': converters.convert_kvp_list_to_dict,
'default': constants.ATTR_NOT_SPECIFIED,
'enforce_policy': True,
'is_visible': True
},
}
}
SUB_RESOURCE_ATTRIBUTE_MAP = {}
ACTION_MAP = {}
REQUIRED_EXTENSIONS = []
OPTIONAL_EXTENSIONS = []
ACTION_STATUS = {}

View File

@@ -0,0 +1,39 @@
# Copyright (c) 2013 OpenStack Foundation.
# 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 webob import exc
from neutron_lib._i18n import _
from neutron_lib.api import converters
from neutron_lib.api.definitions import provider_net as pnet
from neutron_lib import constants
def convert_and_validate_segments(segments, valid_values=None):
for segment in segments:
segment.setdefault(pnet.NETWORK_TYPE, constants.ATTR_NOT_SPECIFIED)
segment.setdefault(pnet.PHYSICAL_NETWORK, constants.ATTR_NOT_SPECIFIED)
segmentation_id = segment.get(pnet.SEGMENTATION_ID)
if segmentation_id:
segment[pnet.SEGMENTATION_ID] = converters.convert_to_int(
segmentation_id)
else:
segment[pnet.SEGMENTATION_ID] = constants.ATTR_NOT_SPECIFIED
if len(segment) != 3:
msg = (_("Unrecognized attribute(s) '%s'") %
', '.join(set(segment.keys()) -
set([pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
pnet.SEGMENTATION_ID])))
raise exc.HTTPBadRequest(msg)

View File

@@ -0,0 +1,25 @@
# Copyright (c) 2013 OpenStack Foundation.
# 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._i18n import _
from neutron_lib import exceptions
class SegmentsSetInConjunctionWithProviders(exceptions.InvalidInput):
message = _("Segments and provider values cannot both be set.")
class SegmentsContainDuplicateEntry(exceptions.InvalidInput):
message = _("Duplicate segment entry in request.")

View File

@@ -0,0 +1,46 @@
# 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 multiprovidernet
from neutron_lib.api.definitions import provider_net
from neutron_lib.exceptions import multiprovidernet as mp_exc
from neutron_lib.tests.unit.api.definitions import base
from neutron_lib.tests.unit.api.validators import test_multiprovidernet \
as test_mpnet
class MultiProviderNetworkDefinitionTestCase(base.DefinitionBaseTestCase):
extension_module = multiprovidernet
extension_attributes = (multiprovidernet.SEGMENTS,)
def test_check_duplicate_segments_with_dups(self):
self.assertRaises(mp_exc.SegmentsContainDuplicateEntry,
multiprovidernet.check_duplicate_segments,
[test_mpnet._build_segment('nt0', 'pn0', 2),
test_mpnet._build_segment('nt0', 'pn0', 2)])
def test_check_duplicate_segments_with_dups_and_partial(self):
def _seg_partial(seg):
return seg[provider_net.PHYSICAL_NETWORK] == 'pn0'
self.assertIsNone(
multiprovidernet.check_duplicate_segments(
[test_mpnet._build_segment('nt0', 'pn0', 2),
test_mpnet._build_segment('nt1', 'pn1', 2)],
is_partial_func=_seg_partial))
def test_check_duplicate_segments_no_dups(self):
self.assertIsNone(
multiprovidernet.check_duplicate_segments(
[test_mpnet._build_segment('nt0', 'pn0', 2),
test_mpnet._build_segment('nt0', 'pn0', 3)]))

View File

@@ -0,0 +1,49 @@
# 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 webob import exc
from neutron_lib.api.definitions import provider_net
from neutron_lib.api.validators import multiprovidernet as mp_validator
from neutron_lib import constants
from neutron_lib.tests import _base as base
def _build_segment(net_type=constants.ATTR_NOT_SPECIFIED,
phy_net=constants.ATTR_NOT_SPECIFIED,
seg_id=constants.ATTR_NOT_SPECIFIED):
return {
provider_net.NETWORK_TYPE: net_type,
provider_net.PHYSICAL_NETWORK: phy_net,
provider_net.SEGMENTATION_ID: seg_id
}
class TestMultiprovidernetValidators(base.BaseTestCase):
def test_convert_and_validate_segments_default_values(self):
segs = [{}]
mp_validator.convert_and_validate_segments(segs)
self.assertEqual(
[_build_segment()], segs)
def test_convert_and_validate_segments_seg_id_to_int(self):
segs = [_build_segment(seg_id="9")]
mp_validator.convert_and_validate_segments(segs)
self.assertEqual(_build_segment(seg_id=9), segs[0])
def test_convert_and_validate_segments_invalid_key(self):
segs = [_build_segment(seg_id=2)]
segs[0]['some_key'] = 'some_value'
self.assertRaises(exc.HTTPBadRequest,
mp_validator.convert_and_validate_segments,
segs)

View File

@@ -0,0 +1,8 @@
---
features:
- The ``multi-provider`` extension's API definition is available in
``neutron_lib.api.defintions.multiprovidernet``.
- Exceptions for the ``multi-provider`` extension can be found in
``neutron_lib.exceptions.multiprovidernet``.
- The validation type ``type:network_segments`` is now available for
API attribute validation.