From 6158ebb0e02ca2b796df973e71c6a7d5e829c959 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Mon, 14 Dec 2015 16:33:49 +0800 Subject: [PATCH] Router: Add "router create" command using SDK This patch adds "router create" command to osc using sdk. NOTE: Test for --project needs support for fake identity client v2 and v3. These tests will be added in other patches. NOTE: external_gateway_info and routes are not supported to be passed to create command now. They will be supported in another tow patches. NOTE: Creating a ha router is not supported for now. Will support it in another patch. Change-Id: I7642295d27c27dd498331ae1da1c293706d8f6af Implements: blueprint neutron-client Partial-bug: #1519503 --- doc/source/command-objects/router.rst | 40 ++++++++++ openstackclient/network/v2/router.py | 79 +++++++++++++++++++ openstackclient/tests/network/v2/fakes.py | 5 +- .../tests/network/v2/test_router.py | 62 +++++++++++++++ setup.cfg | 1 + 5 files changed, 186 insertions(+), 1 deletion(-) diff --git a/doc/source/command-objects/router.rst b/doc/source/command-objects/router.rst index f7b5a67e07..9e1e72911a 100644 --- a/doc/source/command-objects/router.rst +++ b/doc/source/command-objects/router.rst @@ -4,6 +4,46 @@ router Network v2 +router create +-------------- + +Create new router + +.. program:: router create +.. code:: bash + + os router create + [--project [--project-domain ]] + [--enable | --disable] + [--distributed] + + +.. option:: --project + + Owner's project (name or ID) + +.. option:: --project-domain + + Domain the project belongs to (name or ID). + This can be used in case collisions between project names exist. + +.. option:: --enable + + Enable router (default) + +.. option:: --disable + + Disable router + +.. option:: --distributed + + Create a distributed router + +.. _router_create-name: +.. describe:: + + New router name + router list ----------- diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py index cf5dae59f1..755bf10059 100644 --- a/openstackclient/network/v2/router.py +++ b/openstackclient/network/v2/router.py @@ -17,8 +17,10 @@ import json import logging from cliff import lister +from cliff import show from openstackclient.common import utils +from openstackclient.identity import common as identity_common def _format_admin_state(state): @@ -38,6 +40,83 @@ _formatters = { } +def _get_attrs(client_manager, parsed_args): + attrs = {} + if parsed_args.name is not None: + attrs['name'] = str(parsed_args.name) + if parsed_args.admin_state_up is not None: + attrs['admin_state_up'] = parsed_args.admin_state_up + if parsed_args.distributed is not None: + attrs['distributed'] = parsed_args.distributed + if 'project' in parsed_args and parsed_args.project is not None: + identity_client = client_manager.identity + project_id = identity_common.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain, + ).id + attrs['tenant_id'] = project_id + return attrs + + +class CreateRouter(show.ShowOne): + """Create a new router""" + + log = logging.getLogger(__name__ + '.CreateRouter') + + def get_parser(self, prog_name): + parser = super(CreateRouter, self).get_parser(prog_name) + parser.add_argument( + 'name', + metavar='', + help="New router name", + ) + admin_group = parser.add_mutually_exclusive_group() + admin_group.add_argument( + '--enable', + dest='admin_state_up', + action='store_true', + default=True, + help="Enable router (default)", + ) + admin_group.add_argument( + '--disable', + dest='admin_state_up', + action='store_false', + help="Disable router", + ) + parser.add_argument( + '--distributed', + dest='distributed', + action='store_true', + default=False, + help="Create a distributed router", + ) + parser.add_argument( + '--project', + metavar='', + help="Owner's project (name or ID)", + ) + identity_common.add_project_domain_option_to_parser(parser) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + client = self.app.client_manager.network + + attrs = _get_attrs(self.app.client_manager, parsed_args) + obj = client.create_router(**attrs) + + columns = sorted(obj.keys()) + data = utils.get_item_properties(obj, columns, formatters=_formatters) + + if 'tenant_id' in columns: + # Rename "tenant_id" to "project_id". + index = columns.index('tenant_id') + columns[index] = 'project_id' + return (tuple(columns), data) + + class ListRouter(lister.Lister): """List routers""" diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py index 284a40b7a2..b45c5412f9 100644 --- a/openstackclient/tests/network/v2/fakes.py +++ b/openstackclient/tests/network/v2/fakes.py @@ -174,7 +174,10 @@ class FakeRouter(object): router_attrs.update(attrs) # Set default methods. - router_methods = {} + router_methods = { + 'keys': ['id', 'name', 'admin_state_up', 'distributed', 'ha', + 'tenant_id'], + } # Overwrite default methods. router_methods.update(methods) diff --git a/openstackclient/tests/network/v2/test_router.py b/openstackclient/tests/network/v2/test_router.py index d91daceb8a..5170826cbd 100644 --- a/openstackclient/tests/network/v2/test_router.py +++ b/openstackclient/tests/network/v2/test_router.py @@ -15,6 +15,7 @@ import mock from openstackclient.network.v2 import router from openstackclient.tests.network.v2 import fakes as network_fakes +from openstackclient.tests import utils as tests_utils class TestRouter(network_fakes.TestNetworkV2): @@ -26,6 +27,67 @@ class TestRouter(network_fakes.TestNetworkV2): self.network = self.app.client_manager.network +class TestCreateRouter(TestRouter): + + # The new router created. + new_router = network_fakes.FakeRouter.create_one_router() + + columns = ( + 'admin_state_up', + 'distributed', + 'ha', + 'id', + 'name', + 'project_id', + ) + data = ( + router._format_admin_state(new_router.admin_state_up), + new_router.distributed, + new_router.ha, + new_router.id, + new_router.name, + new_router.tenant_id, + ) + + def setUp(self): + super(TestCreateRouter, self).setUp() + + self.network.create_router = mock.Mock(return_value=self.new_router) + + # Get the command object to test + self.cmd = router.CreateRouter(self.app, self.namespace) + + def test_create_no_options(self): + arglist = [] + verifylist = [] + + try: + self.check_parser(self.cmd, arglist, verifylist) + except tests_utils.ParserException: + pass + + def test_create_default_options(self): + arglist = [ + self.new_router.name, + ] + verifylist = [ + ('name', self.new_router.name), + ('admin_state_up', True), + ('distributed', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_router.assert_called_with(**{ + 'admin_state_up': True, + 'name': self.new_router.name, + 'distributed': False, + }) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + class TestListRouter(TestRouter): # The routers going to be listed up. diff --git a/setup.cfg b/setup.cfg index 01615a3380..535e4fdf95 100644 --- a/setup.cfg +++ b/setup.cfg @@ -332,6 +332,7 @@ openstack.network.v2 = network_list = openstackclient.network.v2.network:ListNetwork network_set = openstackclient.network.v2.network:SetNetwork network_show = openstackclient.network.v2.network:ShowNetwork + router_create = openstackclient.network.v2.router:CreateRouter router_list = openstackclient.network.v2.router:ListRouter openstack.object_store.v1 =