summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-05-30 06:20:21 +0000
committerGerrit Code Review <review@openstack.org>2016-05-30 06:20:21 +0000
commit37bc7bbf91583684b8b1ad2cff9f28e3b4e7bea7 (patch)
treeccef1954ea389c778c92bff993fba8ff1e7dc54f
parentd532e3b5f24a462846743f2866666b7b58aa2041 (diff)
parent6a55e05cbf72509898ccc490ca894d766f34d9dc (diff)
downloadpython-openstackclient-37bc7bbf91583684b8b1ad2cff9f28e3b4e7bea7.tar.gz
Merge "Add network segment command object"
-rw-r--r--doc/source/command-objects/network-segment.rst54
-rw-r--r--doc/source/commands.rst1
-rw-r--r--functional/tests/network/v2/test_network_segment.py60
-rw-r--r--openstackclient/network/v2/network_segment.py124
-rw-r--r--openstackclient/tests/fakes.py5
-rw-r--r--openstackclient/tests/network/v2/fakes.py52
-rw-r--r--openstackclient/tests/network/v2/test_network_segment.py199
-rw-r--r--openstackclient/tests/utils.py1
-rw-r--r--releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml7
-rw-r--r--setup.cfg3
10 files changed, 506 insertions, 0 deletions
diff --git a/doc/source/command-objects/network-segment.rst b/doc/source/command-objects/network-segment.rst
new file mode 100644
index 00000000..8e177d6a
--- /dev/null
+++ b/doc/source/command-objects/network-segment.rst
@@ -0,0 +1,54 @@
+===============
+network segment
+===============
+
+A **network segment** is an isolated Layer 2 segment within a network.
+A network may contain multiple network segments. Depending on the
+network configuration, Layer 2 connectivity between network segments
+within a network may not be guaranteed.
+
+Network v2
+
+network segment list
+--------------------
+
+List network segments
+
+.. caution:: This is a beta command and subject to change.
+ Use global option ``--enable-beta-commands`` to
+ enable this command.
+
+.. program:: network segment list
+.. code:: bash
+
+ os network segment list
+ [--long]
+ [--network <network>]
+
+.. option:: --long
+
+ List additional fields in output
+
+.. option:: --network <network>
+
+ List network segments that belong to this network (name or ID)
+
+network segment show
+--------------------
+
+Display network segment details
+
+.. caution:: This is a beta command and subject to change.
+ Use global option ``--enable-beta-commands`` to
+ enable this command.
+
+.. program:: network segment show
+.. code:: bash
+
+ os network segment show
+ <network-segment>
+
+.. _network_segment_show-segment:
+.. describe:: <network-segment>
+
+ Network segment to display (ID only)
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index a6d94047..2d38c8a1 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -104,6 +104,7 @@ referring to both Compute and Volume quotas.
* ``mapping``: (**Identity**) a definition to translate identity provider attributes to Identity concepts
* ``module``: (**Internal**) - installed Python modules in the OSC process
* ``network``: (**Compute**, **Network**) - a virtual network for connecting servers and other resources
+* ``network segment``: (**Network**) - a segment of a virtual network
* ``object``: (**Object Storage**) a single file in the Object Storage
* ``object store account``: (**Object Storage**) owns a group of Object Storage resources
* ``policy``: (**Identity**) determines authorization
diff --git a/functional/tests/network/v2/test_network_segment.py b/functional/tests/network/v2/test_network_segment.py
new file mode 100644
index 00000000..a9980938
--- /dev/null
+++ b/functional/tests/network/v2/test_network_segment.py
@@ -0,0 +1,60 @@
+# 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.
+
+import testtools
+import uuid
+
+from functional.common import test
+
+
+# NOTE(rtheis): Routed networks is still a WIP and not enabled by default.
+@testtools.skip("bp/routed-networks")
+class NetworkSegmentTests(test.TestCase):
+ """Functional tests for network segment. """
+ NETWORK_NAME = uuid.uuid4().hex
+ PHYSICAL_NETWORK_NAME = uuid.uuid4().hex
+ NETWORK_SEGMENT_ID = None
+ NETWORK_ID = None
+
+ @classmethod
+ def setUpClass(cls):
+ # Create a network for the segment.
+ opts = cls.get_show_opts(['id'])
+ raw_output = cls.openstack('network create ' + cls.NETWORK_NAME + opts)
+ cls.NETWORK_ID = raw_output.strip('\n')
+
+ # Get the segment for the network.
+ opts = cls.get_show_opts(['ID', 'Network'])
+ raw_output = cls.openstack('--enable-beta-commands '
+ 'network segment list '
+ ' --network ' + cls.NETWORK_NAME +
+ ' ' + opts)
+ raw_output_row = raw_output.split('\n')[0]
+ cls.NETWORK_SEGMENT_ID = raw_output_row.split(' ')[0]
+
+ @classmethod
+ def tearDownClass(cls):
+ raw_output = cls.openstack('network delete ' + cls.NETWORK_NAME)
+ cls.assertOutput('', raw_output)
+
+ def test_network_segment_list(self):
+ opts = self.get_list_opts(['ID'])
+ raw_output = self.openstack('--enable-beta-commands '
+ 'network segment list' + opts)
+ self.assertIn(self.NETWORK_SEGMENT_ID, raw_output)
+
+ def test_network_segment_show(self):
+ opts = self.get_show_opts(['network_id'])
+ raw_output = self.openstack('--enable-beta-commands '
+ 'network segment show ' +
+ self.NETWORK_SEGMENT_ID + opts)
+ self.assertEqual(self.NETWORK_ID + "\n", raw_output)
diff --git a/openstackclient/network/v2/network_segment.py b/openstackclient/network/v2/network_segment.py
new file mode 100644
index 00000000..d8a91fd2
--- /dev/null
+++ b/openstackclient/network/v2/network_segment.py
@@ -0,0 +1,124 @@
+# 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.
+#
+
+"""Network segment action implementations"""
+
+# TODO(rtheis): Add description and name properties when support is available.
+
+from openstackclient.common import command
+from openstackclient.common import exceptions
+from openstackclient.common import utils
+from openstackclient.i18n import _
+
+
+class ListNetworkSegment(command.Lister):
+ """List network segments
+
+ (Caution: This is a beta command and subject to change.
+ Use global option --enable-beta-commands to enable
+ this command)
+ """
+
+ def get_parser(self, prog_name):
+ parser = super(ListNetworkSegment, self).get_parser(prog_name)
+ parser.add_argument(
+ '--long',
+ action='store_true',
+ default=False,
+ help=_('List additional fields in output'),
+ )
+ parser.add_argument(
+ '--network',
+ metavar='<network>',
+ help=_('List network segments that belong to this '
+ 'network (name or ID)'),
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ if not self.app.options.enable_beta_commands:
+ msg = _('Caution: This is a beta command and subject to '
+ 'change. Use global option --enable-beta-commands '
+ 'to enable this command.')
+ raise exceptions.CommandError(msg)
+
+ network_client = self.app.client_manager.network
+
+ filters = {}
+ if parsed_args.network:
+ _network = network_client.find_network(
+ parsed_args.network,
+ ignore_missing=False
+ )
+ filters = {'network_id': _network.id}
+ data = network_client.segments(**filters)
+
+ headers = (
+ 'ID',
+ 'Network',
+ 'Network Type',
+ 'Segment',
+ )
+ columns = (
+ 'id',
+ 'network_id',
+ 'network_type',
+ 'segmentation_id',
+ )
+ if parsed_args.long:
+ headers = headers + (
+ 'Physical Network',
+ )
+ columns = columns + (
+ 'physical_network',
+ )
+
+ return (headers,
+ (utils.get_item_properties(
+ s, columns,
+ formatters={},
+ ) for s in data))
+
+
+class ShowNetworkSegment(command.ShowOne):
+ """Display network segment details
+
+ (Caution: This is a beta command and subject to change.
+ Use global option --enable-beta-commands to enable
+ this command)
+ """
+
+ def get_parser(self, prog_name):
+ parser = super(ShowNetworkSegment, self).get_parser(prog_name)
+ parser.add_argument(
+ 'network_segment',
+ metavar='<network-segment>',
+ help=_('Network segment to display (ID only)'),
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ if not self.app.options.enable_beta_commands:
+ msg = _('Caution: This is a beta command and subject to '
+ 'change. Use global option --enable-beta-commands '
+ 'to enable this command.')
+ raise exceptions.CommandError(msg)
+
+ client = self.app.client_manager.network
+ obj = client.find_segment(
+ parsed_args.network_segment,
+ ignore_missing=False
+ )
+ columns = tuple(sorted(obj.keys()))
+ data = utils.get_item_properties(obj, columns)
+ return (columns, data)
diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py
index fb7a957a..7fb1daa9 100644
--- a/openstackclient/tests/fakes.py
+++ b/openstackclient/tests/fakes.py
@@ -97,6 +97,11 @@ class FakeApp(object):
self.log = _log
+class FakeOptions(object):
+ def __init__(self, **kwargs):
+ self.enable_beta_commands = False
+
+
class FakeClient(object):
def __init__(self, **kwargs):
diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py
index ce6f63e8..587fdc1a 100644
--- a/openstackclient/tests/network/v2/fakes.py
+++ b/openstackclient/tests/network/v2/fakes.py
@@ -275,6 +275,58 @@ class FakeNetwork(object):
return mock.MagicMock(side_effect=networks)
+class FakeNetworkSegment(object):
+ """Fake one or more network segments."""
+
+ @staticmethod
+ def create_one_network_segment(attrs=None):
+ """Create a fake network segment.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object faking the network segment
+ """
+ attrs = attrs or {}
+
+ # Set default attributes.
+ network_segment_attrs = {
+ 'id': 'segment-id-' + uuid.uuid4().hex,
+ 'network_id': 'network-id-' + uuid.uuid4().hex,
+ 'network_type': 'vlan',
+ 'physical_network': 'physical-network-name-' + uuid.uuid4().hex,
+ 'segmentation_id': 1024,
+ }
+
+ # Overwrite default attributes.
+ network_segment_attrs.update(attrs)
+
+ network_segment = fakes.FakeResource(
+ info=copy.deepcopy(network_segment_attrs),
+ loaded=True
+ )
+
+ return network_segment
+
+ @staticmethod
+ def create_network_segments(attrs=None, count=2):
+ """Create multiple fake network segments.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param int count:
+ The number of network segments to fake
+ :return:
+ A list of FakeResource objects faking the network segments
+ """
+ network_segments = []
+ for i in range(0, count):
+ network_segments.append(
+ FakeNetworkSegment.create_one_network_segment(attrs)
+ )
+ return network_segments
+
+
class FakePort(object):
"""Fake one or more ports."""
diff --git a/openstackclient/tests/network/v2/test_network_segment.py b/openstackclient/tests/network/v2/test_network_segment.py
new file mode 100644
index 00000000..2822581c
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_network_segment.py
@@ -0,0 +1,199 @@
+# 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.
+#
+
+import mock
+
+from openstackclient.common import exceptions
+from openstackclient.network.v2 import network_segment
+from openstackclient.tests.network.v2 import fakes as network_fakes
+from openstackclient.tests import utils as tests_utils
+
+
+class TestNetworkSegment(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestNetworkSegment, self).setUp()
+
+ # Enable beta commands.
+ self.app.options.enable_beta_commands = True
+
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+
+class TestListNetworkSegment(TestNetworkSegment):
+ _network = network_fakes.FakeNetwork.create_one_network()
+ _network_segments = \
+ network_fakes.FakeNetworkSegment.create_network_segments(count=3)
+
+ columns = (
+ 'ID',
+ 'Network',
+ 'Network Type',
+ 'Segment',
+ )
+ columns_long = columns + (
+ 'Physical Network',
+ )
+
+ data = []
+ for _network_segment in _network_segments:
+ data.append((
+ _network_segment.id,
+ _network_segment.network_id,
+ _network_segment.network_type,
+ _network_segment.segmentation_id,
+ ))
+
+ data_long = []
+ for _network_segment in _network_segments:
+ data_long.append((
+ _network_segment.id,
+ _network_segment.network_id,
+ _network_segment.network_type,
+ _network_segment.segmentation_id,
+ _network_segment.physical_network,
+ ))
+
+ def setUp(self):
+ super(TestListNetworkSegment, self).setUp()
+
+ # Get the command object to test
+ self.cmd = network_segment.ListNetworkSegment(self.app, self.namespace)
+
+ self.network.find_network = mock.Mock(return_value=self._network)
+ self.network.segments = mock.Mock(return_value=self._network_segments)
+
+ def test_list_no_option(self):
+ arglist = []
+ verifylist = [
+ ('long', False),
+ ('network', None),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.segments.assert_called_once_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_list_no_beta_commands(self):
+ self.app.options.enable_beta_commands = False
+ parsed_args = self.check_parser(self.cmd, [], [])
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+ def test_list_long(self):
+ arglist = [
+ '--long',
+ ]
+ verifylist = [
+ ('long', True),
+ ('network', None),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.segments.assert_called_once_with()
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(self.data_long, list(data))
+
+ def test_list_network(self):
+ arglist = [
+ '--network',
+ self._network.id,
+ ]
+ verifylist = [
+ ('long', False),
+ ('network', self._network.id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.segments.assert_called_once_with(
+ **{'network_id': self._network.id}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+
+class TestShowNetworkSegment(TestNetworkSegment):
+
+ # The network segment to show.
+ _network_segment = \
+ network_fakes.FakeNetworkSegment.create_one_network_segment()
+
+ columns = (
+ 'id',
+ 'network_id',
+ 'network_type',
+ 'physical_network',
+ 'segmentation_id',
+ )
+
+ data = (
+ _network_segment.id,
+ _network_segment.network_id,
+ _network_segment.network_type,
+ _network_segment.physical_network,
+ _network_segment.segmentation_id,
+ )
+
+ def setUp(self):
+ super(TestShowNetworkSegment, self).setUp()
+
+ self.network.find_segment = mock.Mock(
+ return_value=self._network_segment
+ )
+
+ # Get the command object to test
+ self.cmd = network_segment.ShowNetworkSegment(self.app, self.namespace)
+
+ def test_show_no_options(self):
+ # Missing required args should bail here
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, [], [])
+
+ def test_show_no_beta_commands(self):
+ arglist = [
+ self._network_segment.id,
+ ]
+ verifylist = [
+ ('network_segment', self._network_segment.id),
+ ]
+ self.app.options.enable_beta_commands = False
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+ def test_show_all_options(self):
+ arglist = [
+ self._network_segment.id,
+ ]
+ verifylist = [
+ ('network_segment', self._network_segment.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.find_segment.assert_called_once_with(
+ self._network_segment.id,
+ ignore_missing=False
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/utils.py b/openstackclient/tests/utils.py
index 319c1c11..8dead718 100644
--- a/openstackclient/tests/utils.py
+++ b/openstackclient/tests/utils.py
@@ -60,6 +60,7 @@ class TestCommand(TestCase):
self.fake_log = fakes.FakeLog()
self.app = fakes.FakeApp(self.fake_stdout, self.fake_log)
self.app.client_manager = fakes.FakeClientManager()
+ self.app.options = fakes.FakeOptions()
def check_parser(self, cmd, args, verify_args):
cmd_parser = cmd.get_parser('check_parser')
diff --git a/releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml b/releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml
new file mode 100644
index 00000000..82080f7e
--- /dev/null
+++ b/releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - Add support for the ``network segment`` command object via the
+ ``network segment list`` and ``network segment show`` commands.
+ These are beta commands and subject to change. Use global option
+ ``--enable-beta-commands`` to enable these commands.
+ [Blueprint `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]
diff --git a/setup.cfg b/setup.cfg
index f52e8bc6..78450c00 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -344,6 +344,9 @@ openstack.network.v2 =
network_set = openstackclient.network.v2.network:SetNetwork
network_show = openstackclient.network.v2.network:ShowNetwork
+ network_segment_list = openstackclient.network.v2.network_segment:ListNetworkSegment
+ network_segment_show = openstackclient.network.v2.network_segment:ShowNetworkSegment
+
port_create = openstackclient.network.v2.port:CreatePort
port_delete = openstackclient.network.v2.port:DeletePort
port_list = openstackclient.network.v2.port:ListPort