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:
parent
ab35d88929
commit
76326b19cc
@ -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
|
||||
|
@ -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:
|
@ -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
|
||||
|
||||
|
71
openstack/network/v2/network_segment_range.py
Normal file
71
openstack/network/v2/network_segment_range.py
Normal 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)
|
@ -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)
|
@ -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)
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user