summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorRichard Theis <rtheis@us.ibm.com>2016-03-08 15:18:16 -0600
committerRichard Theis <rtheis@us.ibm.com>2016-05-27 12:58:25 -0500
commit6a55e05cbf72509898ccc490ca894d766f34d9dc (patch)
tree72924bf2e12354ad2de51db1b33e3cc9a3e09a93 /openstackclient
parent9da02d14eadc39da6f97b3df095af8b0c452a5b4 (diff)
downloadpython-openstackclient-6a55e05cbf72509898ccc490ca894d766f34d9dc.tar.gz
Add network segment command object
Add network segment command object in support of routed networks. This patch set includes documentation, unit tests and functional tests (currently skipped until segments enabled in neutron by default) for the following new commands: - "os network segment list" - "os network segment show" These new commands are currently marked as beta commands. Change-Id: I1a79b48dc6820fe2a39fcceb11c8cae3bda413a0 Partially-Implements: blueprint routed-networks
Diffstat (limited to 'openstackclient')
-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
5 files changed, 381 insertions, 0 deletions
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 229b4652..ac91257e 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 417cf26e..8507e278 100644
--- a/openstackclient/tests/network/v2/fakes.py
+++ b/openstackclient/tests/network/v2/fakes.py
@@ -256,6 +256,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')