Skip to content

Commit d46b267

Browse files
committed
Add network segment create, delete and update support
Add network segment create, delete and update support. This patch set includes the following: - Proxy create, delete and update interfaces - Support for new name and description properties - Documentation update for supported network types - Unit test updates - Functional test updates The documentation provides a caution notice since this support is a work in progress and is subject to change. Change-Id: Ib194125162057fccb4e951587c2fa4ec2e2f098c Partially-Implements: blueprint routed-networks
1 parent d7ee3ad commit d46b267

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
@@ -1602,6 +1602,40 @@ def security_group_rules(self, **query):
16021602
return self._list(_security_group_rule.SecurityGroupRule,
16031603
paginated=False, **query)
16041604

1605+
def create_segment(self, **attrs):
1606+
"""Create a new segment from attributes
1607+
1608+
.. caution::
1609+
BETA: This API is a work in progress and is subject to change.
1610+
1611+
:param dict attrs: Keyword arguments which will be used to create
1612+
a :class:`~openstack.network.v2.segment.Segment`,
1613+
comprised of the properties on the Segment class.
1614+
1615+
:returns: The results of segment creation
1616+
:rtype: :class:`~openstack.network.v2.segment.Segment`
1617+
"""
1618+
return self._create(_segment.Segment, **attrs)
1619+
1620+
def delete_segment(self, segment, ignore_missing=True):
1621+
"""Delete a segment
1622+
1623+
.. caution::
1624+
BETA: This API is a work in progress and is subject to change.
1625+
1626+
:param segment: The value can be either the ID of a segment or a
1627+
:class:`~openstack.network.v2.segment.Segment`
1628+
instance.
1629+
:param bool ignore_missing: When set to ``False``
1630+
:class:`~openstack.exceptions.ResourceNotFound` will be
1631+
raised when the segment does not exist.
1632+
When set to ``True``, no exception will be set when
1633+
attempting to delete a nonexistent segment.
1634+
1635+
:returns: ``None``
1636+
"""
1637+
self._delete(_segment.Segment, segment, ignore_missing=ignore_missing)
1638+
16051639
def find_segment(self, name_or_id, ignore_missing=True):
16061640
"""Find a single segment
16071641
@@ -1644,6 +1678,7 @@ def segments(self, **query):
16441678
:param kwargs \*\*query: Optional query parameters to be sent to limit
16451679
the resources being returned. Available parameters include:
16461680
1681+
* name: Name of the segments
16471682
* network_id: ID of the network that owns the segments
16481683
* network_type: Network type for the segments
16491684
* physical_network: Physical network name for the segments
@@ -1654,6 +1689,23 @@ def segments(self, **query):
16541689
"""
16551690
return self._list(_segment.Segment, paginated=False, **query)
16561691

1692+
def update_segment(self, segment, **attrs):
1693+
"""Update a segment
1694+
1695+
.. caution::
1696+
BETA: This API is a work in progress and is subject to change.
1697+
1698+
:param segment: Either the id of a segment or a
1699+
:class:`~openstack.network.v2.segment.Segment`
1700+
instance.
1701+
:attrs kwargs: The attributes to update on the segment represented
1702+
by ``value``.
1703+
1704+
:returns: The update segment
1705+
:rtype: :class:`~openstack.network.v2.segment.Segment`
1706+
"""
1707+
return self._update(_segment.Segment, segment, **attrs)
1708+
16571709
def create_subnet(self, **attrs):
16581710
"""Create a new subnet from attributes
16591711

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
@@ -571,6 +571,15 @@ def test_security_group_rules(self):
571571
security_group_rule.SecurityGroupRule,
572572
paginated=False)
573573

574+
def test_segment_create_attrs(self):
575+
self.verify_create(self.proxy.create_segment, segment.Segment)
576+
577+
def test_segment_delete(self):
578+
self.verify_delete(self.proxy.delete_segment, segment.Segment, False)
579+
580+
def test_segment_delete_ignore(self):
581+
self.verify_delete(self.proxy.delete_segment, segment.Segment, True)
582+
574583
def test_segment_find(self):
575584
self.verify_find(self.proxy.find_segment, segment.Segment)
576585

@@ -580,6 +589,9 @@ def test_segment_get(self):
580589
def test_segments(self):
581590
self.verify_list(self.proxy.segments, segment.Segment, paginated=False)
582591

592+
def test_segment_update(self):
593+
self.verify_update(self.proxy.update_segment, segment.Segment)
594+
583595
def test_subnet_create_attrs(self):
584596
self.verify_create(self.proxy.create_subnet, subnet.Subnet)
585597

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)