Add network segment range resource

Add network segment range resource in support of network segment range
management.

This patch set includes the following:
- Network segment range resource
- Proxy CRUD interfaces for the network segment range resource
- Documentation updates
- Unit tests
- Function tests (currently skipped)

Co-authored-by: Allain Legacy <Allain.legacy@windriver.com>

Partially-implements: blueprint network-segment-range-management
Change-Id: I62ddf40387fd589e788ac45235fbe6bdc6612ad8
This commit is contained in:
Kailun Qin 2018-12-15 23:21:54 +08:00
parent ab35d88929
commit 76326b19cc
7 changed files with 396 additions and 0 deletions

View File

@ -18,6 +18,7 @@ Network Resources
v2/metering_label_rule
v2/network
v2/network_ip_availability
v2/network_segment_range
v2/pool
v2/pool_member
v2/port

View File

@ -0,0 +1,13 @@
openstack.network.v2.network_segment_range
==========================================
.. automodule:: openstack.network.v2.network_segment_range
The NetworkSegmentRange Class
-----------------------------
The ``NetworkSegmentRange`` class inherits from :class:`~openstack.resource
.Resource`.
.. autoclass:: openstack.network.v2.network_segment_range.NetworkSegmentRange
:members:

View File

@ -29,6 +29,8 @@ from openstack.network.v2 import metering_label as _metering_label
from openstack.network.v2 import metering_label_rule as _metering_label_rule
from openstack.network.v2 import network as _network
from openstack.network.v2 import network_ip_availability
from openstack.network.v2 import network_segment_range as \
_network_segment_range
from openstack.network.v2 import pool as _pool
from openstack.network.v2 import pool_member as _pool_member
from openstack.network.v2 import port as _port
@ -1345,6 +1347,122 @@ class Proxy(proxy.Proxy):
return self._list(network_ip_availability.NetworkIPAvailability,
paginated=False, **query)
def create_network_segment_range(self, **attrs):
"""Create a new network segment range from attributes
:param dict attrs: Keyword arguments which will be used to create a
:class:`~openstack.network.v2.
network_segment_range.NetworkSegmentRange`,
comprised of the properties on the
NetworkSegmentRange class.
:returns: The results of network segment range creation
:rtype: :class:`~openstack.network.v2.network_segment_range
.NetworkSegmentRange`
"""
return self._create(_network_segment_range.NetworkSegmentRange,
**attrs)
def delete_network_segment_range(self, network_segment_range,
ignore_missing=True):
"""Delete a network segment range
:param network_segment_range: The value can be either the ID of a
network segment range or a
:class:`~openstack.network.v2.network_segment_range.
NetworkSegmentRange` instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the network segment range does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent network segment range.
:returns: ``None``
"""
self._delete(_network_segment_range.NetworkSegmentRange,
network_segment_range, ignore_missing=ignore_missing)
def find_network_segment_range(self, name_or_id, ignore_missing=True,
**args):
"""Find a single network segment range
:param name_or_id: The name or ID of a network segment range.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the resource does not exist.
When set to ``True``, None will be returned when
attempting to find a nonexistent resource.
:param dict args: Any additional parameters to be passed into
underlying methods. such as query filters.
:returns: One :class:`~openstack.network.v2.network_segment_range
.NetworkSegmentRange` or None
"""
return self._find(_network_segment_range.NetworkSegmentRange,
name_or_id, ignore_missing=ignore_missing, **args)
def get_network_segment_range(self, network_segment_range):
"""Get a single network segment range
:param network_segment_range: The value can be the ID of a network
segment range or a :class:`~openstack.network.v2.
network_segment_range.NetworkSegmentRange` instance.
:returns: One :class:`~openstack.network.v2._network_segment_range.
NetworkSegmentRange`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(_network_segment_range.NetworkSegmentRange,
network_segment_range)
def network_segment_ranges(self, **query):
"""Return a generator of network segment ranges
:param kwargs query: Optional query parameters to be sent to limit
the resources being returned. Available parameters include:
* ``name``: Name of the segments
* ``default``: The network segment range is loaded from the host
configuration file.
* ``shared``: The network segment range is shared with other
projects
* ``project_id``: ID of the project that owns the network
segment range
* ``network_type``: Network type for the network segment ranges
* ``physical_network``: Physical network name for the network
segment ranges
* ``minimum``: Minimum segmentation ID for the network segment
ranges
* ``maximum``: Maximum Segmentation ID for the network segment
ranges
* ``used``: Mapping of which segmentation ID in the range is
used by which tenant
* ``available``: List of available segmentation IDs in this
network segment range
:returns: A generator of network segment range objects
:rtype: :class:`~openstack.network.v2._network_segment_range.
NetworkSegmentRange`
"""
return self._list(_network_segment_range.NetworkSegmentRange,
paginated=False, **query)
def update_network_segment_range(self, network_segment_range, **attrs):
"""Update a network segment range
:param network_segment_range: Either the id of a network segment range
or a :class:`~openstack.network.v2._network_segment_range.
NetworkSegmentRange` instance.
:attrs kwargs: The attributes to update on the network segment range
represented by ``value``.
:returns: The updated network segment range
:rtype: :class:`~openstack.network.v2._network_segment_range.
NetworkSegmentRange`
"""
return self._update(_network_segment_range.NetworkSegmentRange,
network_segment_range, **attrs)
def create_pool(self, **attrs):
"""Create a new pool from attributes

View File

@ -0,0 +1,71 @@
# Copyright (c) 2018, Intel Corporation.
# 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 openstack import resource
class NetworkSegmentRange(resource.Resource):
resource_key = 'network_segment_range'
resources_key = 'network_segment_ranges'
base_path = '/network_segment_ranges'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
_query_mapping = resource.QueryParameters(
'name', 'default', 'shared', 'project_id',
'network_type', 'physical_network', 'minimum', 'maximum',
'used', 'available'
)
# Properties
#: The network segment range name.
name = resource.Body('name')
#: The network segment range is loaded from the host configuration file.
#: *Type: bool*
default = resource.Body('default', type=bool)
#: The network segment range is shared with other projects.
#: *Type: bool*
shared = resource.Body('shared', type=bool)
#: The ID of the project associated with this network segment range.
project_id = resource.Body('project_id')
#: The type of network associated with this network segment range, such as
#: ``geneve``, ``gre``, ``vlan`` or ``vxlan``.
network_type = resource.Body('network_type')
#: The name of the physical network associated with this network segment
#: range.
physical_network = resource.Body('physical_network')
#: The minimum segmentation ID for this network segment range. The
#: network type defines the segmentation model, VLAN ID for ``vlan``
#: network type and tunnel ID for ``geneve``, ``gre`` and ``vxlan``
#: network types.
#: *Type: int*
minimum = resource.Body('minimum', type=int)
#: The maximum segmentation ID for this network segment range. The
#: network type defines the segmentation model, VLAN ID for ``vlan``
#: network type and tunnel ID for ``geneve``, ``gre`` and ``vxlan``
#: network types.
#: *Type: int*
maximum = resource.Body('maximum', type=int)
#: Mapping of which segmentation ID in the range is used by which tenant.
#: *Type: dict*
used = resource.Body('used', type=dict)
#: List of available segmentation IDs in this network segment range.
#: *Type: list*
available = resource.Body('available', type=list)

View File

@ -0,0 +1,99 @@
# Copyright (c) 2018, Intel Corporation.
# 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 openstack.network.v2 import network_segment_range
from openstack.tests.functional import base
class TestNetworkSegmentRange(base.BaseFunctionalTest):
NETWORK_SEGMENT_RANGE_ID = None
NAME = 'test_name'
DEFAULT = False
SHARED = False
PROJECT_ID = '2018'
NETWORK_TYPE = 'vlan'
PHYSICAL_NETWORK = 'phys_net'
MINIMUM = 100
MAXIMUM = 200
def setUp(self):
super(TestNetworkSegmentRange, self).setUp()
# NOTE(kailun): The network segment range extension is not yet enabled
# by default.
# Skip the tests if not enabled.
if not self.conn.network.find_extension('network-segment-range'):
self.skipTest('Network Segment Range extension disabled')
test_seg_range = self.conn.network.create_network_segment_range(
name=self.NAME,
default=self.DEFAULT,
shared=self.SHARED,
project_id=self.PROJECT_ID,
network_type=self.NETWORK_TYPE,
physical_network=self.PHYSICAL_NETWORK,
minimum=self.MINIMUM,
maximum=self.MAXIMUM,
)
self.assertIsInstance(test_seg_range,
network_segment_range.NetworkSegmentRange)
self.NETWORK_SEGMENT_RANGE_ID = test_seg_range.id
self.assertEqual(self.NAME, test_seg_range.name)
self.assertEqual(self.DEFAULT, test_seg_range.default)
self.assertEqual(self.SHARED, test_seg_range.shared)
self.assertEqual(self.PROJECT_ID, test_seg_range.project_id)
self.assertEqual(self.NETWORK_TYPE, test_seg_range.network_type)
self.assertEqual(self.PHYSICAL_NETWORK,
test_seg_range.physical_network)
self.assertEqual(self.MINIMUM, test_seg_range.minimum)
self.assertEqual(self.MAXIMUM, test_seg_range.maximum)
def tearDown(self):
super(TestNetworkSegmentRange, self).tearDown()
def test_create_delete(self):
del_test_seg_range = self.conn.network.delete_network_segment_range(
self.NETWORK_SEGMENT_RANGE_ID)
self.assertIsNone(del_test_seg_range)
def test_find(self):
test_seg_range = self.conn.network.find_network_segment_range(
self.NETWORK_SEGMENT_RANGE_ID)
self.assertEqual(self.NETWORK_SEGMENT_RANGE_ID, test_seg_range.id)
def test_get(self):
test_seg_range = self.conn.network.get_network_segment_range(
self.NETWORK_SEGMENT_RANGE_ID)
self.assertEqual(self.NETWORK_SEGMENT_RANGE_ID, test_seg_range.id)
self.assertEqual(self.NAME, test_seg_range.name)
self.assertEqual(self.DEFAULT, test_seg_range.default)
self.assertEqual(self.SHARED, test_seg_range.shared)
self.assertEqual(self.PROJECT_ID, test_seg_range.project_id)
self.assertEqual(self.NETWORK_TYPE, test_seg_range.network_type)
self.assertEqual(self.PHYSICAL_NETWORK,
test_seg_range.physical_network)
self.assertEqual(self.MINIMUM, test_seg_range.minimum)
self.assertEqual(self.MAXIMUM, test_seg_range.maximum)
def test_list(self):
ids = [o.id for o in self.conn.network.network_segment_ranges(
name=None)]
self.assertIn(self.NETWORK_SEGMENT_RANGE_ID, ids)
def test_update(self):
update_seg_range = self.conn.network.update_segment(
self.NETWORK_SEGMENT_RANGE_ID, name='update_test_name')
self.assertEqual('update_test_name', update_seg_range.name)

View File

@ -0,0 +1,64 @@
# Copyright (c) 2018, Intel Corporation.
# 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 openstack.tests.unit import base
from openstack.network.v2 import network_segment_range
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
'id': IDENTIFIER,
'name': '1',
'default': False,
'shared': False,
'project_id': '2',
'network_type': '3',
'physical_network': '4',
'minimum': 5,
'maximum': 6,
'used': {},
'available': [],
}
class TestNetworkSegmentRange(base.TestCase):
def test_basic(self):
test_seg_range = network_segment_range.NetworkSegmentRange()
self.assertEqual('network_segment_range', test_seg_range.resource_key)
self.assertEqual('network_segment_ranges',
test_seg_range.resources_key)
self.assertEqual('/network_segment_ranges', test_seg_range.base_path)
self.assertTrue(test_seg_range.allow_create)
self.assertTrue(test_seg_range.allow_fetch)
self.assertTrue(test_seg_range.allow_commit)
self.assertTrue(test_seg_range.allow_delete)
self.assertTrue(test_seg_range.allow_list)
def test_make_it(self):
test_seg_range = network_segment_range.NetworkSegmentRange(**EXAMPLE)
self.assertEqual(EXAMPLE['id'], test_seg_range.id)
self.assertEqual(EXAMPLE['name'], test_seg_range.name)
self.assertEqual(EXAMPLE['default'], test_seg_range.default)
self.assertEqual(EXAMPLE['shared'], test_seg_range.shared)
self.assertEqual(EXAMPLE['project_id'], test_seg_range.project_id)
self.assertEqual(EXAMPLE['network_type'], test_seg_range.network_type)
self.assertEqual(EXAMPLE['physical_network'],
test_seg_range.physical_network)
self.assertEqual(EXAMPLE['minimum'], test_seg_range.minimum)
self.assertEqual(EXAMPLE['maximum'], test_seg_range.maximum)
self.assertEqual(EXAMPLE['used'], test_seg_range.used)
self.assertEqual(EXAMPLE['available'], test_seg_range.available)

View File

@ -32,6 +32,7 @@ from openstack.network.v2 import metering_label
from openstack.network.v2 import metering_label_rule
from openstack.network.v2 import network
from openstack.network.v2 import network_ip_availability
from openstack.network.v2 import network_segment_range
from openstack.network.v2 import pool
from openstack.network.v2 import pool_member
from openstack.network.v2 import port
@ -962,6 +963,35 @@ class TestNetworkProxy(test_proxy_base.TestProxyBase):
self.verify_update(self.proxy.update_firewall_rule,
firewall_rule.FirewallRule)
def test_network_segment_range_create_attrs(self):
self.verify_create(self.proxy.create_network_segment_range,
network_segment_range.NetworkSegmentRange)
def test_network_segment_range_delete(self):
self.verify_delete(self.proxy.delete_network_segment_range,
network_segment_range.NetworkSegmentRange, False)
def test_network_segment_range_delete_ignore(self):
self.verify_delete(self.proxy.delete_network_segment_range,
network_segment_range.NetworkSegmentRange, True)
def test_network_segment_range_find(self):
self.verify_find(self.proxy.find_network_segment_range,
network_segment_range.NetworkSegmentRange)
def test_network_segment_range_get(self):
self.verify_get(self.proxy.get_network_segment_range,
network_segment_range.NetworkSegmentRange)
def test_network_segment_ranges(self):
self.verify_list(self.proxy.network_segment_ranges,
network_segment_range.NetworkSegmentRange,
paginated=False)
def test_network_segment_range_update(self):
self.verify_update(self.proxy.update_network_segment_range,
network_segment_range.NetworkSegmentRange)
def test_security_group_create_attrs(self):
self.verify_create(self.proxy.create_security_group,
security_group.SecurityGroup)