use multiprovidernet api definition from neutron-lib
The multiprovidernet API extension's definition was rehomed into neutron-lib with commit If3367e6a14074a6225bba527e8f7e38c51280f85 This patch consumes it by: - Using the APIExtensionDescriptor and API definition for the extension. - Removing the rehomed (now duplicated) code from neutron. - Using lib's code were applicable. NeutronLibImpact Change-Id: I12c15c360f8bf5a45fbe70e5ed1202ef0e7ec0f0
This commit is contained in:
parent
93851ee6ff
commit
b78d47927e
|
@ -13,76 +13,11 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api import converters
|
||||
from neutron_lib.api.definitions import provider_net as pnet
|
||||
from neutron_lib.api.definitions import multiprovidernet as apidef
|
||||
from neutron_lib.api import extensions
|
||||
from neutron_lib.api import validators
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions as nexception
|
||||
import webob.exc
|
||||
|
||||
from neutron._i18n import _
|
||||
|
||||
SEGMENTS = 'segments'
|
||||
|
||||
|
||||
class SegmentsSetInConjunctionWithProviders(nexception.InvalidInput):
|
||||
message = _("Segments and provider values cannot both be set.")
|
||||
|
||||
|
||||
class SegmentsContainDuplicateEntry(nexception.InvalidInput):
|
||||
message = _("Duplicate segment entry in request.")
|
||||
|
||||
|
||||
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.keys()) != 3:
|
||||
msg = (_("Unrecognized attribute(s) '%s'") %
|
||||
', '.join(set(segment.keys()) -
|
||||
set([pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
|
||||
pnet.SEGMENTATION_ID])))
|
||||
raise webob.exc.HTTPBadRequest(msg)
|
||||
|
||||
|
||||
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 SegmentsContainDuplicateEntry()
|
||||
|
||||
validators.add_validator('convert_segments',
|
||||
_convert_and_validate_segments)
|
||||
|
||||
EXTENDED_ATTRIBUTES_2_0 = {
|
||||
'networks': {
|
||||
SEGMENTS: {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:convert_segments': None},
|
||||
'convert_list_to': converters.convert_kvp_list_to_dict,
|
||||
'default': constants.ATTR_NOT_SPECIFIED,
|
||||
'enforce_policy': True,
|
||||
'is_visible': True},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Multiprovidernet(extensions.ExtensionDescriptor):
|
||||
class Multiprovidernet(extensions.APIExtensionDescriptor):
|
||||
"""Extension class supporting multiple provider networks.
|
||||
|
||||
This class is used by neutron's extension framework to make
|
||||
|
@ -95,25 +30,4 @@ class Multiprovidernet(extensions.ExtensionDescriptor):
|
|||
'segments' attribute.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "Multi Provider Network"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "multi-provider"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return ("Expose mapping of virtual networks to multiple physical "
|
||||
"networks")
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2013-06-27T10:00:00-00:00"
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return EXTENDED_ATTRIBUTES_2_0
|
||||
else:
|
||||
return {}
|
||||
api_definition = apidef
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import external_net as extnet_apidef
|
||||
from neutron_lib.api.definitions import multiprovidernet as mpnet_apidef
|
||||
from neutron_lib.api.definitions import portbindings
|
||||
from neutron_lib.api.definitions import provider_net as provider
|
||||
from neutron_lib.api import validators
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions as exc
|
||||
from neutron_lib.exceptions import multiprovidernet as mpnet_exc
|
||||
from neutron_lib.exceptions import vlantransparent as vlan_exc
|
||||
from neutron_lib.plugins.ml2 import api
|
||||
from oslo_config import cfg
|
||||
|
@ -30,7 +32,6 @@ from neutron._i18n import _
|
|||
from neutron.conf.plugins.ml2 import config
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db import segments_db
|
||||
from neutron.extensions import multiprovidernet as mpnet
|
||||
from neutron.plugins.ml2.common import exceptions as ml2_exc
|
||||
from neutron.plugins.ml2 import models
|
||||
|
||||
|
@ -108,14 +109,15 @@ class TypeManager(stevedore.named.NamedExtensionManager):
|
|||
for attr in provider.ATTRIBUTES):
|
||||
# Verify that multiprovider and provider attributes are not set
|
||||
# at the same time.
|
||||
if validators.is_attr_set(network.get(mpnet.SEGMENTS)):
|
||||
raise mpnet.SegmentsSetInConjunctionWithProviders()
|
||||
if validators.is_attr_set(network.get(mpnet_apidef.SEGMENTS)):
|
||||
raise mpnet_exc.SegmentsSetInConjunctionWithProviders()
|
||||
segment = self._get_provider_segment(network)
|
||||
return [self._process_provider_segment(segment)]
|
||||
elif validators.is_attr_set(network.get(mpnet.SEGMENTS)):
|
||||
elif validators.is_attr_set(network.get(mpnet_apidef.SEGMENTS)):
|
||||
segments = [self._process_provider_segment(s)
|
||||
for s in network[mpnet.SEGMENTS]]
|
||||
mpnet.check_duplicate_segments(segments, self.is_partial_segment)
|
||||
for s in network[mpnet_apidef.SEGMENTS]]
|
||||
mpnet_apidef.check_duplicate_segments(
|
||||
segments, self.is_partial_segment)
|
||||
return segments
|
||||
|
||||
def _match_segment(self, segment, filters):
|
||||
|
@ -137,8 +139,8 @@ class TypeManager(stevedore.named.NamedExtensionManager):
|
|||
if any(validators.is_attr_set(network.get(attr))
|
||||
for attr in provider.ATTRIBUTES):
|
||||
segments = [self._get_provider_segment(network)]
|
||||
elif validators.is_attr_set(network.get(mpnet.SEGMENTS)):
|
||||
segments = self._get_attribute(network, mpnet.SEGMENTS)
|
||||
elif validators.is_attr_set(network.get(mpnet_apidef.SEGMENTS)):
|
||||
segments = self._get_attribute(network, mpnet_apidef.SEGMENTS)
|
||||
else:
|
||||
return True
|
||||
return any(self._match_segment(s, filters) for s in segments)
|
||||
|
@ -167,7 +169,7 @@ class TypeManager(stevedore.named.NamedExtensionManager):
|
|||
for attr in provider.ATTRIBUTES:
|
||||
network[attr] = None
|
||||
elif len(segments) > 1:
|
||||
network[mpnet.SEGMENTS] = [
|
||||
network[mpnet_apidef.SEGMENTS] = [
|
||||
{provider.NETWORK_TYPE: segment[api.NETWORK_TYPE],
|
||||
provider.PHYSICAL_NETWORK: segment[api.PHYSICAL_NETWORK],
|
||||
provider.SEGMENTATION_ID: segment[api.SEGMENTATION_ID]}
|
||||
|
|
|
@ -20,6 +20,7 @@ import mock
|
|||
import netaddr
|
||||
from neutron_lib.api.definitions import availability_zone as az_def
|
||||
from neutron_lib.api.definitions import external_net as extnet_apidef
|
||||
from neutron_lib.api.definitions import multiprovidernet as mpnet_apidef
|
||||
from neutron_lib.api.definitions import portbindings
|
||||
from neutron_lib.api.definitions import provider_net as pnet
|
||||
from neutron_lib.callbacks import events
|
||||
|
@ -46,7 +47,6 @@ from neutron.db import models_v2
|
|||
from neutron.db import provisioning_blocks
|
||||
from neutron.db import securitygroups_db as sg_db
|
||||
from neutron.db import segments_db
|
||||
from neutron.extensions import multiprovidernet as mpnet
|
||||
from neutron.objects import base as base_obj
|
||||
from neutron.objects import router as l3_obj
|
||||
from neutron.plugins.ml2.common import exceptions as ml2_exc
|
||||
|
@ -192,7 +192,7 @@ class TestMl2NetworksV2(test_plugin.TestNetworksV2,
|
|||
]
|
||||
# multiprovider networks
|
||||
self.mp_nets = [{'name': 'net4',
|
||||
mpnet.SEGMENTS:
|
||||
mpnet_apidef.SEGMENTS:
|
||||
[{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet2',
|
||||
pnet.SEGMENTATION_ID: 1},
|
||||
|
@ -306,13 +306,13 @@ class TestMl2NetworksV2(test_plugin.TestNetworksV2,
|
|||
# verify
|
||||
network = self.deserialize(self.fmt,
|
||||
req.get_response(self.api))['network']
|
||||
if mpnet.SEGMENTS not in net:
|
||||
if mpnet_apidef.SEGMENTS not in net:
|
||||
for k, v in net.items():
|
||||
self.assertEqual(net[k], network[k])
|
||||
self.assertNotIn(mpnet.SEGMENTS, network)
|
||||
self.assertNotIn(mpnet_apidef.SEGMENTS, network)
|
||||
else:
|
||||
segments = network[mpnet.SEGMENTS]
|
||||
expected_segments = net[mpnet.SEGMENTS]
|
||||
segments = network[mpnet_apidef.SEGMENTS]
|
||||
expected_segments = net[mpnet_apidef.SEGMENTS]
|
||||
self.assertEqual(len(expected_segments), len(segments))
|
||||
for expected, actual in zip(expected_segments, segments):
|
||||
self.assertEqual(expected, actual)
|
||||
|
@ -349,11 +349,12 @@ class TestMl2NetworksV2(test_plugin.TestNetworksV2,
|
|||
networks = self._lookup_network_by_segmentation_id(lookup_vlan_id, 2)
|
||||
|
||||
# get the mpnet
|
||||
networks = [n for n in networks['networks'] if mpnet.SEGMENTS in n]
|
||||
networks = [n for n in networks['networks']
|
||||
if mpnet_apidef.SEGMENTS in n]
|
||||
network = networks.pop()
|
||||
# verify attributes of the looked up item
|
||||
segments = network[mpnet.SEGMENTS]
|
||||
expected_segments = self.mp_nets[0][mpnet.SEGMENTS]
|
||||
segments = network[mpnet_apidef.SEGMENTS]
|
||||
expected_segments = self.mp_nets[0][mpnet_apidef.SEGMENTS]
|
||||
self.assertEqual(len(expected_segments), len(segments))
|
||||
for expected, actual in zip(expected_segments, segments):
|
||||
self.assertEqual(expected, actual)
|
||||
|
@ -401,7 +402,7 @@ class TestExternalNetwork(Ml2PluginV2TestCase):
|
|||
# External network will not have a segmentation id.
|
||||
self.assertIsNone(network['network'][pnet.SEGMENTATION_ID])
|
||||
# External network will not have multiple segments.
|
||||
self.assertNotIn(mpnet.SEGMENTS, network['network'])
|
||||
self.assertNotIn(mpnet_apidef.SEGMENTS, network['network'])
|
||||
|
||||
def test_external_network_type_vlan(self):
|
||||
cfg.CONF.set_default('external_network_type',
|
||||
|
@ -417,12 +418,12 @@ class TestExternalNetwork(Ml2PluginV2TestCase):
|
|||
# External network will have a segmentation id.
|
||||
self.assertIsNotNone(network['network'][pnet.SEGMENTATION_ID])
|
||||
# External network will not have multiple segments.
|
||||
self.assertNotIn(mpnet.SEGMENTS, network['network'])
|
||||
self.assertNotIn(mpnet_apidef.SEGMENTS, network['network'])
|
||||
|
||||
|
||||
class TestMl2NetworksWithVlanTransparencyBase(TestMl2NetworksV2):
|
||||
data = {'network': {'name': 'net1',
|
||||
mpnet.SEGMENTS:
|
||||
mpnet_apidef.SEGMENTS:
|
||||
[{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet1'}],
|
||||
'tenant_id': 'tenant_one',
|
||||
|
@ -1553,7 +1554,7 @@ class Test_GetNetworkMtu(Ml2PluginV2TestCase):
|
|||
|
||||
net = {
|
||||
'name': 'net1',
|
||||
mpnet.SEGMENTS: [
|
||||
mpnet_apidef.SEGMENTS: [
|
||||
{
|
||||
'network_type': 'driver1',
|
||||
'physical_network': 'physnet1'
|
||||
|
@ -1569,7 +1570,7 @@ class Test_GetNetworkMtu(Ml2PluginV2TestCase):
|
|||
|
||||
net = {
|
||||
'name': 'net1',
|
||||
mpnet.SEGMENTS: [
|
||||
mpnet_apidef.SEGMENTS: [
|
||||
{
|
||||
'network_type': 'driver1',
|
||||
'physical_network': 'physnet1'
|
||||
|
@ -1611,7 +1612,7 @@ class Test_GetNetworkMtu(Ml2PluginV2TestCase):
|
|||
|
||||
net = {
|
||||
'name': 'net1',
|
||||
mpnet.SEGMENTS: [
|
||||
mpnet_apidef.SEGMENTS: [
|
||||
{
|
||||
'network_type': 'driver1',
|
||||
'physical_network': 'physnet1'
|
||||
|
@ -2118,11 +2119,11 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
self.assertEqual('vlan', network['network'][pnet.NETWORK_TYPE])
|
||||
self.assertEqual('physnet1', network['network'][pnet.PHYSICAL_NETWORK])
|
||||
self.assertEqual(1, network['network'][pnet.SEGMENTATION_ID])
|
||||
self.assertNotIn(mpnet.SEGMENTS, network['network'])
|
||||
self.assertNotIn(mpnet_apidef.SEGMENTS, network['network'])
|
||||
|
||||
def test_create_network_single_multiprovider(self):
|
||||
data = {'network': {'name': 'net1',
|
||||
mpnet.SEGMENTS:
|
||||
mpnet_apidef.SEGMENTS:
|
||||
[{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet1',
|
||||
pnet.SEGMENTATION_ID: 1}],
|
||||
|
@ -2132,7 +2133,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
self.assertEqual('vlan', network['network'][pnet.NETWORK_TYPE])
|
||||
self.assertEqual('physnet1', network['network'][pnet.PHYSICAL_NETWORK])
|
||||
self.assertEqual(1, network['network'][pnet.SEGMENTATION_ID])
|
||||
self.assertNotIn(mpnet.SEGMENTS, network['network'])
|
||||
self.assertNotIn(mpnet_apidef.SEGMENTS, network['network'])
|
||||
|
||||
# Tests get_network()
|
||||
net_req = self.new_show_request('networks', network['network']['id'])
|
||||
|
@ -2140,11 +2141,11 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
self.assertEqual('vlan', network['network'][pnet.NETWORK_TYPE])
|
||||
self.assertEqual('physnet1', network['network'][pnet.PHYSICAL_NETWORK])
|
||||
self.assertEqual(1, network['network'][pnet.SEGMENTATION_ID])
|
||||
self.assertNotIn(mpnet.SEGMENTS, network['network'])
|
||||
self.assertNotIn(mpnet_apidef.SEGMENTS, network['network'])
|
||||
|
||||
def test_create_network_multiprovider(self):
|
||||
data = {'network': {'name': 'net1',
|
||||
mpnet.SEGMENTS:
|
||||
mpnet_apidef.SEGMENTS:
|
||||
[{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet1',
|
||||
pnet.SEGMENTATION_ID: 1},
|
||||
|
@ -2155,9 +2156,9 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
network_req = self.new_create_request('networks', data)
|
||||
network = self.deserialize(self.fmt,
|
||||
network_req.get_response(self.api))
|
||||
segments = network['network'][mpnet.SEGMENTS]
|
||||
segments = network['network'][mpnet_apidef.SEGMENTS]
|
||||
for segment_index, segment in enumerate(data['network']
|
||||
[mpnet.SEGMENTS]):
|
||||
[mpnet_apidef.SEGMENTS]):
|
||||
for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
|
||||
pnet.SEGMENTATION_ID]:
|
||||
self.assertEqual(segment.get(field),
|
||||
|
@ -2166,9 +2167,9 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
# Tests get_network()
|
||||
net_req = self.new_show_request('networks', network['network']['id'])
|
||||
network = self.deserialize(self.fmt, net_req.get_response(self.api))
|
||||
segments = network['network'][mpnet.SEGMENTS]
|
||||
segments = network['network'][mpnet_apidef.SEGMENTS]
|
||||
for segment_index, segment in enumerate(data['network']
|
||||
[mpnet.SEGMENTS]):
|
||||
[mpnet_apidef.SEGMENTS]):
|
||||
for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
|
||||
pnet.SEGMENTATION_ID]:
|
||||
self.assertEqual(segment.get(field),
|
||||
|
@ -2176,7 +2177,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
|
||||
def test_create_network_with_provider_and_multiprovider_fail(self):
|
||||
data = {'network': {'name': 'net1',
|
||||
mpnet.SEGMENTS:
|
||||
mpnet_apidef.SEGMENTS:
|
||||
[{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet1',
|
||||
pnet.SEGMENTATION_ID: 1}],
|
||||
|
@ -2191,7 +2192,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
|
||||
def test_create_network_duplicate_full_segments(self):
|
||||
data = {'network': {'name': 'net1',
|
||||
mpnet.SEGMENTS:
|
||||
mpnet_apidef.SEGMENTS:
|
||||
[{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet1',
|
||||
pnet.SEGMENTATION_ID: 1},
|
||||
|
@ -2205,7 +2206,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||
|
||||
def test_create_network_duplicate_partial_segments(self):
|
||||
data = {'network': {'name': 'net1',
|
||||
mpnet.SEGMENTS:
|
||||
mpnet_apidef.SEGMENTS:
|
||||
[{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet1'},
|
||||
{pnet.NETWORK_TYPE: 'vlan',
|
||||
|
@ -2380,7 +2381,7 @@ class TestMl2HostsNetworkAccess(Ml2PluginV2TestCase):
|
|||
net = self.driver.create_network(
|
||||
self.context,
|
||||
{'network': {'name': 'net1',
|
||||
mpnet.SEGMENTS: [
|
||||
mpnet_apidef.SEGMENTS: [
|
||||
{pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.PHYSICAL_NETWORK: 'physnet1',
|
||||
pnet.SEGMENTATION_ID: 1},
|
||||
|
@ -2880,7 +2881,8 @@ class TestML2Segments(Ml2PluginV2TestCase):
|
|||
mock.ANY, event, segments_plugin.Plugin(), self.context, seg1)
|
||||
# Make sure the mechanism manager can get the right amount of
|
||||
# segments of network
|
||||
self.assertEqual(3, len(self.net_context.current[mpnet.SEGMENTS]))
|
||||
self.assertEqual(
|
||||
3, len(self.net_context.current[mpnet_apidef.SEGMENTS]))
|
||||
|
||||
def test_reserve_segment_nofity_mechanism_manager(self):
|
||||
self._test_nofity_mechanism_manager(events.PRECOMMIT_CREATE)
|
||||
|
|
Loading…
Reference in New Issue