summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-06-20 21:42:52 +0000
committerGerrit Code Review <review@openstack.org>2016-06-20 21:42:52 +0000
commit8c850cadcfc481319b91850ba759e68256fee138 (patch)
tree553a32f043a51c81bb879a77a052e453b047be16
parentf5ae23ab86c662e2f75952e6aa62c02ab3855b9b (diff)
parent6a6b192ddeb80b516778b1d6e3d34f4261dca85d (diff)
downloadpython-openstackclient-8c850cadcfc481319b91850ba759e68256fee138.tar.gz
Merge "Add "--network-segment" option to "subnet create""
-rw-r--r--doc/source/command-beta.rst58
-rw-r--r--doc/source/command-objects/subnet.rst9
-rw-r--r--openstackclient/network/v2/subnet.py10
-rw-r--r--openstackclient/tests/network/v2/fakes.py9
-rw-r--r--openstackclient/tests/network/v2/test_subnet.py90
-rw-r--r--releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml6
6 files changed, 157 insertions, 25 deletions
diff --git a/doc/source/command-beta.rst b/doc/source/command-beta.rst
index f0a4f851..bc8c04c5 100644
--- a/doc/source/command-beta.rst
+++ b/doc/source/command-beta.rst
@@ -12,23 +12,29 @@ To address these challenges, an OpenStackClient command may
be labeled as a beta command according to the guidelines
below. Such commands may introduce backwards incompatible
changes and may use REST API enhancements not yet released.
+This also applies to command options associated with the beta
+command object.
-See the examples below on how to label a command as a beta
-by updating the command documentation, help and implementation.
+See the examples below on how to label an entire command or
+a specific option as a beta by updating the documentation
+and implementation.
-The initial release note must label the new command as a beta.
-No further release notes are required until the command
-is no longer a beta. At which time, the command beta label
-or the command itself must be removed and a new release note
+The initial release note must label the new command or option
+as a beta. No further release notes are required until the command
+or option is no longer a beta. At which time, the beta label or
+the command or option itself must be removed and a new release note
must be provided.
+Beta Command Example
+--------------------
+
Documentation
--------------
+~~~~~~~~~~~~~
The command documentation must label the command as a beta.
example list
-~~~~~~~~~~~~
+++++++++++++
List examples
@@ -42,7 +48,7 @@ List examples
os example list
Help
-----
+~~~~
The command help must label the command as a beta.
@@ -57,7 +63,7 @@ The command help must label the command as a beta.
"""
Implementation
---------------
+~~~~~~~~~~~~~~
The command must raise a ``CommandError`` exception if beta commands
are not enabled via ``--os-beta-command`` global option.
@@ -66,3 +72,35 @@ are not enabled via ``--os-beta-command`` global option.
def take_action(self, parsed_args):
self.validate_os_beta_command_enabled()
+
+Beta Option Example
+-------------------
+
+Documentation
+~~~~~~~~~~~~~
+
+The option documentation must label the option as a beta.
+
+.. option:: --example <example>
+
+ Example
+
+ .. caution:: This is a beta command option and subject
+ to change. Use global option ``--os-beta-command``
+ to enable this command option.
+
+Implementation
+~~~~~~~~~~~~~~
+
+The option must not be added if beta commands are not
+enabled via ``--os-beta-command`` global option.
+
+.. code-block:: python
+
+ def get_parser(self, prog_name):
+ if self.app.options.os_beta_command:
+ parser.add_argument(
+ '--example',
+ metavar='<example>',
+ help=_("Example")
+ )
diff --git a/doc/source/command-objects/subnet.rst b/doc/source/command-objects/subnet.rst
index c52d73f9..fe77ccfd 100644
--- a/doc/source/command-objects/subnet.rst
+++ b/doc/source/command-objects/subnet.rst
@@ -28,6 +28,7 @@ Create new subnet
[--ip-version {4,6}]
[--ipv6-ra-mode {dhcpv6-stateful,dhcpv6-stateless,slaac}]
[--ipv6-address-mode {dhcpv6-stateful,dhcpv6-stateless,slaac}]
+ [--network-segment <network-segment>]
--network <network>
<name>
@@ -107,6 +108,14 @@ Create new subnet
IPv6 address mode, valid modes: [dhcpv6-stateful, dhcpv6-stateless, slaac]
+.. option:: --network-segment <network-segment>
+
+ Network segment to associate with this subnet (ID only)
+
+ .. caution:: This is a beta command option and subject
+ to change. Use global option ``--os-beta-command``
+ to enable this command option.
+
.. option:: --network <network>
Network this subnet belongs to (name or ID)
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
index a2e32622..752923f7 100644
--- a/openstackclient/network/v2/subnet.py
+++ b/openstackclient/network/v2/subnet.py
@@ -142,6 +142,9 @@ def _get_attrs(client_manager, parsed_args, is_create=True):
attrs['ipv6_ra_mode'] = parsed_args.ipv6_ra_mode
if parsed_args.ipv6_address_mode is not None:
attrs['ipv6_address_mode'] = parsed_args.ipv6_address_mode
+ if 'network_segment' in parsed_args:
+ attrs['segment_id'] = client.find_segment(
+ parsed_args.network_segment, ignore_missing=False).id
if 'gateway' in parsed_args and parsed_args.gateway is not None:
gateway = parsed_args.gateway.lower()
@@ -255,6 +258,13 @@ class CreateSubnet(command.ShowOne):
help=_("IPv6 address mode, "
"valid modes: [dhcpv6-stateful, dhcpv6-stateless, slaac]")
)
+ if self.app.options.os_beta_command:
+ parser.add_argument(
+ '--network-segment',
+ metavar='<network-segment>',
+ help=_("Network segment to associate with this subnet "
+ "(ID only)")
+ )
parser.add_argument(
'--network',
required=True,
diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py
index a23efc2d..50d9899c 100644
--- a/openstackclient/tests/network/v2/fakes.py
+++ b/openstackclient/tests/network/v2/fakes.py
@@ -352,7 +352,7 @@ class FakeNetworkSegment(object):
# Set default attributes.
network_segment_attrs = {
- 'id': 'segment-id-' + uuid.uuid4().hex,
+ 'id': 'network-segment-id-' + uuid.uuid4().hex,
'network_id': 'network-id-' + uuid.uuid4().hex,
'network_type': 'vlan',
'physical_network': 'physical-network-name-' + uuid.uuid4().hex,
@@ -738,9 +738,10 @@ class FakeSubnet(object):
'host_routes': [],
'ip_version': 4,
'gateway_ip': '10.10.10.1',
- 'ipv6_address_mode': 'None',
- 'ipv6_ra_mode': 'None',
- 'subnetpool_id': 'None',
+ 'ipv6_address_mode': None,
+ 'ipv6_ra_mode': None,
+ 'segment_id': None,
+ 'subnetpool_id': None,
}
# Overwrite default attributes.
diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py
index a57a0308..99b558c0 100644
--- a/openstackclient/tests/network/v2/test_subnet.py
+++ b/openstackclient/tests/network/v2/test_subnet.py
@@ -91,6 +91,14 @@ class TestCreateSubnet(TestSubnet):
}
)
+ # The network segment to be returned from find_segment
+ _network_segment = \
+ network_fakes.FakeNetworkSegment.create_one_network_segment(
+ attrs={
+ 'network_id': _subnet.network_id,
+ }
+ )
+
columns = (
'allocation_pools',
'cidr',
@@ -105,6 +113,7 @@ class TestCreateSubnet(TestSubnet):
'name',
'network_id',
'project_id',
+ 'segment_id',
'subnetpool_id',
)
@@ -122,6 +131,7 @@ class TestCreateSubnet(TestSubnet):
_subnet.name,
_subnet.network_id,
_subnet.project_id,
+ _subnet.segment_id,
_subnet.subnetpool_id,
)
@@ -139,6 +149,7 @@ class TestCreateSubnet(TestSubnet):
_subnet_from_pool.name,
_subnet_from_pool.network_id,
_subnet_from_pool.project_id,
+ _subnet_from_pool.segment_id,
_subnet_from_pool.subnetpool_id,
)
@@ -156,6 +167,7 @@ class TestCreateSubnet(TestSubnet):
_subnet_ipv6.name,
_subnet_ipv6.network_id,
_subnet_ipv6.project_id,
+ _subnet_ipv6.segment_id,
_subnet_ipv6.subnetpool_id,
)
@@ -189,6 +201,15 @@ class TestCreateSubnet(TestSubnet):
loaded=True,
)
+ # Mock SDK calls for all tests.
+ self.network.find_network = mock.Mock(return_value=self._network)
+ self.network.find_segment = mock.Mock(
+ return_value=self._network_segment
+ )
+ self.network.find_subnet_pool = mock.Mock(
+ return_value=self._subnet_pool
+ )
+
def test_create_no_options(self):
arglist = []
verifylist = []
@@ -199,11 +220,9 @@ class TestCreateSubnet(TestSubnet):
self.check_parser, self.cmd, arglist, verifylist)
def test_create_default_options(self):
- # Mock create_subnet and find_network sdk calls to return the
- # values we want for this test
+ # Mock SDK calls for this test.
self.network.create_subnet = mock.Mock(return_value=self._subnet)
self._network.id = self._subnet.network_id
- self.network.find_network = mock.Mock(return_value=self._network)
arglist = [
"--subnet-range", self._subnet.cidr,
@@ -233,14 +252,10 @@ class TestCreateSubnet(TestSubnet):
self.assertEqual(self.data, data)
def test_create_from_subnet_pool_options(self):
- # Mock create_subnet, find_subnet_pool, and find_network sdk calls
- # to return the values we want for this test
+ # Mock SDK calls for this test.
self.network.create_subnet = \
mock.Mock(return_value=self._subnet_from_pool)
self._network.id = self._subnet_from_pool.network_id
- self.network.find_network = mock.Mock(return_value=self._network)
- self.network.find_subnet_pool = \
- mock.Mock(return_value=self._subnet_pool)
arglist = [
self._subnet_from_pool.name,
@@ -293,11 +308,9 @@ class TestCreateSubnet(TestSubnet):
self.assertEqual(self.data_subnet_pool, data)
def test_create_options_subnet_range_ipv6(self):
- # Mock create_subnet and find_network sdk calls to return the
- # values we want for this test
+ # Mock SDK calls for this test.
self.network.create_subnet = mock.Mock(return_value=self._subnet_ipv6)
self._network.id = self._subnet_ipv6.network_id
- self.network.find_network = mock.Mock(return_value=self._network)
arglist = [
self._subnet_ipv6.name,
@@ -360,6 +373,59 @@ class TestCreateSubnet(TestSubnet):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data_ipv6, data)
+ def test_create_no_beta_command_options(self):
+ arglist = [
+ "--subnet-range", self._subnet.cidr,
+ "--network-segment", self._network_segment.id,
+ "--network", self._subnet.network_id,
+ self._subnet.name,
+ ]
+ verifylist = [
+ ('name', self._subnet.name),
+ ('subnet_range', self._subnet.cidr),
+ ('network-segment', self._network_segment.id),
+ ('network', self._subnet.network_id),
+ ]
+ self.app.options.os_beta_command = False
+ self.assertRaises(tests_utils.ParserException,
+ self.check_parser, self.cmd, arglist, verifylist)
+
+ def test_create_with_network_segment(self):
+ # Mock SDK calls for this test.
+ self.network.create_subnet = mock.Mock(return_value=self._subnet)
+ self._network.id = self._subnet.network_id
+
+ arglist = [
+ "--subnet-range", self._subnet.cidr,
+ "--network-segment", self._network_segment.id,
+ "--network", self._subnet.network_id,
+ self._subnet.name,
+ ]
+ verifylist = [
+ ('name', self._subnet.name),
+ ('subnet_range', self._subnet.cidr),
+ ('network_segment', self._network_segment.id),
+ ('network', self._subnet.network_id),
+ ('ip_version', self._subnet.ip_version),
+ ('gateway', 'auto'),
+
+ ]
+
+ self.app.options.os_beta_command = True
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_subnet.assert_called_once_with(**{
+ 'cidr': self._subnet.cidr,
+ 'enable_dhcp': self._subnet.enable_dhcp,
+ 'ip_version': self._subnet.ip_version,
+ 'name': self._subnet.name,
+ 'network_id': self._subnet.network_id,
+ 'segment_id': self._network_segment.id,
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
class TestDeleteSubnet(TestSubnet):
@@ -646,6 +712,7 @@ class TestShowSubnet(TestSubnet):
'name',
'network_id',
'project_id',
+ 'segment_id',
'subnetpool_id',
)
@@ -663,6 +730,7 @@ class TestShowSubnet(TestSubnet):
_subnet.name,
_subnet.network_id,
_subnet.tenant_id,
+ _subnet.segment_id,
_subnet.subnetpool_id,
)
diff --git a/releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml b/releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml
new file mode 100644
index 00000000..6c4a185c
--- /dev/null
+++ b/releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - Add ``--network-segment`` option to the ``subnet create`` command.
+ This is a beta command option and subject to change. Use global option
+ ``--os-beta-command`` to enable this option.
+ [Blueprint `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]