Skip to content

Commit 7f6d038

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Add network segment create, delete and update support"
2 parents 8064a87 + d46b267 commit 7f6d038

File tree

5 files changed

+148
-36
lines changed

5 files changed

+148
-36
lines changed

openstack/network/v2/_proxy.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,6 +2099,40 @@ def security_group_rules(self, **query):
20992099
return self._list(_security_group_rule.SecurityGroupRule,
21002100
paginated=False, **query)
21012101

2102+
def create_segment(self, **attrs):
2103+
"""Create a new segment from attributes
2104+
2105+
.. caution::
2106+
BETA: This API is a work in progress and is subject to change.
2107+
2108+
:param dict attrs: Keyword arguments which will be used to create
2109+
a :class:`~openstack.network.v2.segment.Segment`,
2110+
comprised of the properties on the Segment class.
2111+
2112+
:returns: The results of segment creation
2113+
:rtype: :class:`~openstack.network.v2.segment.Segment`
2114+
"""
2115+
return self._create(_segment.Segment, **attrs)
2116+
2117+
def delete_segment(self, segment, ignore_missing=True):
2118+
"""Delete a segment
2119+
2120+
.. caution::
2121+
BETA: This API is a work in progress and is subject to change.
2122+
2123+
:param segment: The value can be either the ID of a segment or a
2124+
:class:`~openstack.network.v2.segment.Segment`
2125+
instance.
2126+
:param bool ignore_missing: When set to ``False``
2127+
:class:`~openstack.exceptions.ResourceNotFound` will be
2128+
raised when the segment does not exist.
2129+
When set to ``True``, no exception will be set when
2130+
attempting to delete a nonexistent segment.
2131+
2132+
:returns: ``None``
2133+
"""
2134+
self._delete(_segment.Segment, segment, ignore_missing=ignore_missing)
2135+
21022136
def find_segment(self, name_or_id, ignore_missing=True):
21032137
"""Find a single segment
21042138
@@ -2141,6 +2175,7 @@ def segments(self, **query):
21412175
:param kwargs \*\*query: Optional query parameters to be sent to limit
21422176
the resources being returned. Available parameters include:
21432177
2178+
* name: Name of the segments
21442179
* network_id: ID of the network that owns the segments
21452180
* network_type: Network type for the segments
21462181
* physical_network: Physical network name for the segments
@@ -2151,6 +2186,23 @@ def segments(self, **query):
21512186
"""
21522187
return self._list(_segment.Segment, paginated=False, **query)
21532188

2189+
def update_segment(self, segment, **attrs):
2190+
"""Update a segment
2191+
2192+
.. caution::
2193+
BETA: This API is a work in progress and is subject to change.
2194+
2195+
:param segment: Either the id of a segment or a
2196+
:class:`~openstack.network.v2.segment.Segment`
2197+
instance.
2198+
:attrs kwargs: The attributes to update on the segment represented
2199+
by ``value``.
2200+
2201+
:returns: The update segment
2202+
:rtype: :class:`~openstack.network.v2.segment.Segment`
2203+
"""
2204+
return self._update(_segment.Segment, segment, **attrs)
2205+
21542206
def create_subnet(self, **attrs):
21552207
"""Create a new subnet from attributes
21562208

openstack/network/v2/segment.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,26 @@ class Segment(resource.Resource):
2222
service = network_service.NetworkService()
2323

2424
# capabilities
25-
allow_create = False
25+
allow_create = True
2626
allow_retrieve = True
27-
allow_update = False
28-
allow_delete = False
27+
allow_update = True
28+
allow_delete = True
2929
allow_list = True
3030

31-
# TODO(rtheis): Add description and name properties when support
32-
# is available.
33-
3431
# Properties
32+
#: The segment description.
33+
description = resource.prop('description')
34+
#: The segment name.
35+
name = resource.prop('name')
3536
#: The ID of the network associated with this segment.
3637
network_id = resource.prop('network_id')
3738
#: The type of network associated with this segment, such as
38-
#: ``flat``, ``gre``, ``vlan`` or ``vxlan``.
39+
#: ``flat``, ``geneve``, ``gre``, ``local``, ``vlan`` or ``vxlan``.
3940
network_type = resource.prop('network_type')
4041
#: The name of the physical network associated with this segment.
4142
physical_network = resource.prop('physical_network')
4243
#: The segmentation ID for this segment. The network type
4344
#: defines the segmentation model, VLAN ID for ``vlan`` network type
44-
#: and tunnel ID for ``gre`` and ``vxlan`` network types. *Type: int*
45+
#: and tunnel ID for ``geneve``, ``gre`` and ``vxlan`` network types.
46+
#: *Type: int*
4547
segmentation_id = resource.prop('segmentation_id', type=int)

openstack/tests/functional/network/v2/test_segment.py

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@
1010
# License for the specific language governing permissions and limitations
1111
# under the License.
1212

13-
import unittest
1413
import uuid
1514

1615
from openstack.network.v2 import network
1716
from openstack.network.v2 import segment
1817
from openstack.tests.functional import base
1918

2019

21-
# NOTE(rtheis): Routed networks is still a WIP and not enabled by default.
22-
@unittest.skip("bp/routed-networks")
2320
class TestSegment(base.BaseFunctionalTest):
2421

2522
NETWORK_NAME = uuid.uuid4().hex
@@ -28,45 +25,90 @@ class TestSegment(base.BaseFunctionalTest):
2825
SEGMENTATION_ID = None
2926
NETWORK_ID = None
3027
SEGMENT_ID = None
28+
SEGMENT_EXTENSION = None
3129

3230
@classmethod
3331
def setUpClass(cls):
3432
super(TestSegment, cls).setUpClass()
3533

34+
# NOTE(rtheis): The segment extension is not yet enabled by default.
35+
# Skip the tests if not enabled.
36+
cls.SEGMENT_EXTENSION = cls.conn.network.find_extension('segment')
37+
3638
# Create a network to hold the segment.
3739
net = cls.conn.network.create_network(name=cls.NETWORK_NAME)
3840
assert isinstance(net, network.Network)
3941
cls.assertIs(cls.NETWORK_NAME, net.name)
4042
cls.NETWORK_ID = net.id
4143

42-
# Get the segment for the network.
43-
for seg in cls.conn.network.segments():
44-
assert isinstance(seg, segment.Segment)
45-
if cls.NETWORK_ID == seg.network_id:
46-
cls.NETWORK_TYPE = seg.network_type
47-
cls.PHYSICAL_NETWORK = seg.physical_network
48-
cls.SEGMENTATION_ID = seg.segmentation_id
49-
cls.SEGMENT_ID = seg.id
50-
break
44+
if cls.SEGMENT_EXTENSION:
45+
# Get the segment for the network.
46+
for seg in cls.conn.network.segments():
47+
assert isinstance(seg, segment.Segment)
48+
if cls.NETWORK_ID == seg.network_id:
49+
cls.NETWORK_TYPE = seg.network_type
50+
cls.PHYSICAL_NETWORK = seg.physical_network
51+
cls.SEGMENTATION_ID = seg.segmentation_id
52+
cls.SEGMENT_ID = seg.id
53+
break
5154

5255
@classmethod
5356
def tearDownClass(cls):
5457
sot = cls.conn.network.delete_network(cls.NETWORK_ID,
5558
ignore_missing=False)
5659
cls.assertIs(None, sot)
5760

61+
def test_create_delete(self):
62+
if self.SEGMENT_EXTENSION:
63+
sot = self.conn.network.create_segment(
64+
description='test description',
65+
name='test name',
66+
network_id=self.NETWORK_ID,
67+
network_type='geneve',
68+
segmentation_id=2055,
69+
)
70+
self.assertIsInstance(sot, segment.Segment)
71+
del_sot = self.conn.network.delete_segment(sot.id)
72+
self.assertEqual('test description', sot.description)
73+
self.assertEqual('test name', sot.name)
74+
self.assertEqual(self.NETWORK_ID, sot.network_id)
75+
self.assertEqual('geneve', sot.network_type)
76+
self.assertIsNone(sot.physical_network)
77+
self.assertEqual(2055, sot.segmentation_id)
78+
self.assertIsNone(del_sot)
79+
else:
80+
self.skipTest('Segment extension disabled')
81+
5882
def test_find(self):
59-
sot = self.conn.network.find_segment(self.SEGMENT_ID)
60-
self.assertEqual(self.SEGMENT_ID, sot.id)
83+
if self.SEGMENT_EXTENSION:
84+
sot = self.conn.network.find_segment(self.SEGMENT_ID)
85+
self.assertEqual(self.SEGMENT_ID, sot.id)
86+
else:
87+
self.skipTest('Segment extension disabled')
6188

6289
def test_get(self):
63-
sot = self.conn.network.get_segment(self.SEGMENT_ID)
64-
self.assertEqual(self.SEGMENT_ID, sot.id)
65-
self.assertEqual(self.NETWORK_ID, sot.network_id)
66-
self.assertEqual(self.NETWORK_TYPE, sot.network_type)
67-
self.assertEqual(self.PHYSICAL_NETWORK, sot.physical_network)
68-
self.assertEqual(self.SEGMENTATION_ID, sot.segmentation_id)
90+
if self.SEGMENT_EXTENSION:
91+
sot = self.conn.network.get_segment(self.SEGMENT_ID)
92+
self.assertEqual(self.SEGMENT_ID, sot.id)
93+
self.assertIsNone(sot.name)
94+
self.assertEqual(self.NETWORK_ID, sot.network_id)
95+
self.assertEqual(self.NETWORK_TYPE, sot.network_type)
96+
self.assertEqual(self.PHYSICAL_NETWORK, sot.physical_network)
97+
self.assertEqual(self.SEGMENTATION_ID, sot.segmentation_id)
98+
else:
99+
self.skipTest('Segment extension disabled')
69100

70101
def test_list(self):
71-
ids = [o.id for o in self.conn.network.segments()]
72-
self.assertIn(self.SEGMENT_ID, ids)
102+
if self.SEGMENT_EXTENSION:
103+
ids = [o.id for o in self.conn.network.segments(name=None)]
104+
self.assertIn(self.SEGMENT_ID, ids)
105+
else:
106+
self.skipTest('Segment extension disabled')
107+
108+
def test_update(self):
109+
if self.SEGMENT_EXTENSION:
110+
sot = self.conn.network.update_segment(self.SEGMENT_ID,
111+
description='update')
112+
self.assertEqual('update', sot.description)
113+
else:
114+
self.skipTest('Segment extension disabled')

openstack/tests/unit/network/v2/test_proxy.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,15 @@ def test_security_group_rules(self):
725725
security_group_rule.SecurityGroupRule,
726726
paginated=False)
727727

728+
def test_segment_create_attrs(self):
729+
self.verify_create(self.proxy.create_segment, segment.Segment)
730+
731+
def test_segment_delete(self):
732+
self.verify_delete(self.proxy.delete_segment, segment.Segment, False)
733+
734+
def test_segment_delete_ignore(self):
735+
self.verify_delete(self.proxy.delete_segment, segment.Segment, True)
736+
728737
def test_segment_find(self):
729738
self.verify_find(self.proxy.find_segment, segment.Segment)
730739

@@ -734,6 +743,9 @@ def test_segment_get(self):
734743
def test_segments(self):
735744
self.verify_list(self.proxy.segments, segment.Segment, paginated=False)
736745

746+
def test_segment_update(self):
747+
self.verify_update(self.proxy.update_segment, segment.Segment)
748+
737749
def test_subnet_create_attrs(self):
738750
self.verify_create(self.proxy.create_subnet, subnet.Subnet)
739751

openstack/tests/unit/network/v2/test_segment.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616

1717
IDENTIFIER = 'IDENTIFIER'
1818
EXAMPLE = {
19+
'description': '1',
1920
'id': IDENTIFIER,
20-
'network_id': '1',
21-
'network_type': 'vxlan',
21+
'name': '2',
22+
'network_id': '3',
23+
'network_type': 'geneve',
2224
'physical_network': None,
23-
'segmentation_id': 2,
25+
'segmentation_id': 4,
2426
}
2527

2628

@@ -32,15 +34,17 @@ def test_basic(self):
3234
self.assertEqual('segments', sot.resources_key)
3335
self.assertEqual('/segments', sot.base_path)
3436
self.assertEqual('network', sot.service.service_type)
35-
self.assertFalse(sot.allow_create)
37+
self.assertTrue(sot.allow_create)
3638
self.assertTrue(sot.allow_retrieve)
37-
self.assertFalse(sot.allow_update)
38-
self.assertFalse(sot.allow_delete)
39+
self.assertTrue(sot.allow_update)
40+
self.assertTrue(sot.allow_delete)
3941
self.assertTrue(sot.allow_list)
4042

4143
def test_make_it(self):
4244
sot = segment.Segment(EXAMPLE)
45+
self.assertEqual(EXAMPLE['description'], sot.description)
4346
self.assertEqual(EXAMPLE['id'], sot.id)
47+
self.assertEqual(EXAMPLE['name'], sot.name)
4448
self.assertEqual(EXAMPLE['network_id'], sot.network_id)
4549
self.assertEqual(EXAMPLE['network_type'], sot.network_type)
4650
self.assertEqual(EXAMPLE['physical_network'], sot.physical_network)

0 commit comments

Comments
 (0)