diff --git a/doc/source/command-objects/router.rst b/doc/source/command-objects/router.rst index c3a952e9dd..952415a8ac 100644 --- a/doc/source/command-objects/router.rst +++ b/doc/source/command-objects/router.rst @@ -74,3 +74,42 @@ List routers .. option:: --long List additional fields in output + +router set +---------- + +Set router properties + +.. program:: router set +.. code:: bash + + os router set + [--name ] + [--enable | --disable] + [--distributed | --centralized] + + +.. option:: --name + + Set router name + +.. option:: --enable + + Enable router + +.. option:: --disable + + Disable router + +.. option:: --distributed + + Set router to distributed mode (disabled router only) + +.. option:: --centralized + + Set router to centralized mode (disabled router only) + +.. _router_set-router: +.. describe:: + + Router to modify (name or ID) diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py index 0042e93f73..d084db1f75 100644 --- a/openstackclient/network/v2/router.py +++ b/openstackclient/network/v2/router.py @@ -20,6 +20,7 @@ from cliff import command from cliff import lister from cliff import show +from openstackclient.common import exceptions from openstackclient.common import utils from openstackclient.identity import common as identity_common @@ -49,6 +50,7 @@ def _get_attrs(client_manager, parsed_args): attrs['admin_state_up'] = parsed_args.admin_state_up if parsed_args.distributed is not None: attrs['distributed'] = parsed_args.distributed + # "router set" command doesn't support setting project. if 'project' in parsed_args and parsed_args.project is not None: identity_client = client_manager.identity project_id = identity_common.find_project( @@ -57,6 +59,11 @@ def _get_attrs(client_manager, parsed_args): parsed_args.project_domain, ).id attrs['tenant_id'] = project_id + + # TODO(tangchen): Support getting 'ha' property. + # TODO(tangchen): Support getting 'external_gateway_info' property. + # TODO(tangchen): Support getting 'routes' property. + return attrs @@ -195,3 +202,74 @@ class ListRouter(lister.Lister): s, columns, formatters=_formatters, ) for s in data)) + + +class SetRouter(command.Command): + """Set router properties""" + + log = logging.getLogger(__name__ + '.SetRouter') + + def get_parser(self, prog_name): + parser = super(SetRouter, self).get_parser(prog_name) + parser.add_argument( + 'router', + metavar="", + help=("Router to modify (name or ID)") + ) + parser.add_argument( + '--name', + metavar='', + help='Set router name', + ) + admin_group = parser.add_mutually_exclusive_group() + admin_group.add_argument( + '--enable', + dest='admin_state_up', + action='store_true', + default=None, + help='Enable router', + ) + admin_group.add_argument( + '--disable', + dest='admin_state_up', + action='store_false', + help='Disable router', + ) + distribute_group = parser.add_mutually_exclusive_group() + distribute_group.add_argument( + '--distributed', + dest='distributed', + action='store_true', + default=None, + help="Set router to distributed mode (disabled router only)", + ) + distribute_group.add_argument( + '--centralized', + dest='distributed', + action='store_false', + help="Set router to centralized mode (disabled router only)", + ) + + # TODO(tangchen): Support setting 'ha' property in 'router set' + # command. It appears that changing the ha state is supported by + # neutron under certain conditions. + + # TODO(tangchen): Support setting 'external_gateway_info' property in + # 'router set' command. + + # TODO(tangchen): Support setting 'routes' property in 'router set' + # command. + + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + client = self.app.client_manager.network + obj = client.find_router(parsed_args.router, ignore_missing=False) + + attrs = _get_attrs(self.app.client_manager, parsed_args) + if attrs == {}: + msg = "Nothing specified to be set" + raise exceptions.CommandError(msg) + + client.update_router(obj, **attrs) diff --git a/openstackclient/tests/network/v2/test_router.py b/openstackclient/tests/network/v2/test_router.py index ccda9d2dc2..e40d2d7105 100644 --- a/openstackclient/tests/network/v2/test_router.py +++ b/openstackclient/tests/network/v2/test_router.py @@ -13,6 +13,7 @@ import mock +from openstackclient.common import exceptions from openstackclient.network.v2 import router from openstackclient.tests.network.v2 import fakes as network_fakes from openstackclient.tests import utils as tests_utils @@ -194,3 +195,92 @@ class TestListRouter(TestRouter): self.network.routers.assert_called_with() self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) + + +class TestSetRouter(TestRouter): + + # The router to set. + _router = network_fakes.FakeRouter.create_one_router() + + def setUp(self): + super(TestSetRouter, self).setUp() + + self.network.update_router = mock.Mock(return_value=None) + + self.network.find_router = mock.Mock(return_value=self._router) + + # Get the command object to test + self.cmd = router.SetRouter(self.app, self.namespace) + + def test_set_this(self): + arglist = [ + self._router.name, + '--enable', + '--distributed', + '--name', 'noob', + ] + verifylist = [ + ('router', self._router.name), + ('admin_state_up', True), + ('distributed', True), + ('name', 'noob'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + attrs = { + 'admin_state_up': True, + 'distributed': True, + 'name': 'noob', + } + self.network.update_router.assert_called_with(self._router, **attrs) + self.assertEqual(None, result) + + def test_set_that(self): + arglist = [ + self._router.name, + '--disable', + '--centralized', + ] + verifylist = [ + ('router', self._router.name), + ('admin_state_up', False), + ('distributed', False), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + attrs = { + 'admin_state_up': False, + 'distributed': False, + } + self.network.update_router.assert_called_with(self._router, **attrs) + self.assertEqual(None, result) + + def test_set_distributed_centralized(self): + arglist = [ + self._router.name, + '--distributed', + '--centralized', + ] + verifylist = [ + ('router', self._router.name), + ('distributed', True), + ('distributed', False), + ] + + try: + # Argument parse failing should bail here + self.check_parser(self.cmd, arglist, verifylist) + except tests_utils.ParserException: + pass + + def test_set_nothing(self): + arglist = [self._router.name, ] + verifylist = [('router', self._router.name), ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) diff --git a/setup.cfg b/setup.cfg index ee6192a72b..d55dd1c989 100644 --- a/setup.cfg +++ b/setup.cfg @@ -335,6 +335,7 @@ openstack.network.v2 = router_create = openstackclient.network.v2.router:CreateRouter router_delete = openstackclient.network.v2.router:DeleteRouter router_list = openstackclient.network.v2.router:ListRouter + router_set = openstackclient.network.v2.router:SetRouter openstack.object_store.v1 = object_store_account_set = openstackclient.object.v1.account:SetAccount