From 01c19ef0bc6abc0dbbd76666bdc0c5dda7ba0196 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Thu, 4 Feb 2016 13:19:01 +0800 Subject: [PATCH] Router: Add --route and --clear-routes options to "router set" command --route option is used to set routes to the router. It is used like this: --route destination=subnet,gateway=ip-address destination: destination subnet CIDR gateway: nexthop IP address --clear-routes is used to clear all routes on the router. Change-Id: I97ce4871113c684b29c98cdad4dec9cc80ed20f7 Implements: blueprint neutron-client Partial-bug: #1519503 --- doc/source/command-objects/router.rst | 12 ++++ openstackclient/network/v2/router.py | 30 ++++++++-- .../tests/network/v2/test_router.py | 57 +++++++++++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/doc/source/command-objects/router.rst b/doc/source/command-objects/router.rst index 2a5bf0539c..6b8b357b1c 100644 --- a/doc/source/command-objects/router.rst +++ b/doc/source/command-objects/router.rst @@ -93,6 +93,7 @@ Set router properties [--name ] [--enable | --disable] [--distributed | --centralized] + [--route destination=,gateway= | --clear-routes] .. option:: --name @@ -115,6 +116,17 @@ Set router properties Set router to centralized mode (disabled router only) +.. option:: --route destination=,gateway= + + Routes associated with the router. + Repeat this option to set multiple routes. + destination: destination subnet (in CIDR notation). + gateway: nexthop IP address. + +.. option:: --clear-routes + + Clear routes associated with the router + .. _router_set-router: .. describe:: diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py index 60db816ac6..e4eea3f8ab 100644 --- a/openstackclient/network/v2/router.py +++ b/openstackclient/network/v2/router.py @@ -17,6 +17,7 @@ import json from openstackclient.common import command from openstackclient.common import exceptions +from openstackclient.common import parseractions from openstackclient.common import utils from openstackclient.identity import common as identity_common @@ -51,6 +52,12 @@ def _get_attrs(client_manager, parsed_args): if ('availability_zone_hints' in parsed_args and parsed_args.availability_zone_hints is not None): attrs['availability_zone_hints'] = parsed_args.availability_zone_hints + + if 'clear_routes' in parsed_args and parsed_args.clear_routes: + attrs['routes'] = [] + elif 'routes' in parsed_args and parsed_args.routes is not None: + attrs['routes'] = parsed_args.routes + # "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 @@ -63,7 +70,6 @@ def _get_attrs(client_manager, parsed_args): # TODO(tangchen): Support getting 'ha' property. # TODO(tangchen): Support getting 'external_gateway_info' property. - # TODO(tangchen): Support getting 'routes' property. return attrs @@ -250,6 +256,25 @@ class SetRouter(command.Command): action='store_false', help="Set router to centralized mode (disabled router only)", ) + routes_group = parser.add_mutually_exclusive_group() + routes_group.add_argument( + '--route', + metavar='destination=,gateway=', + action=parseractions.MultiKeyValueAction, + dest='routes', + default=None, + required_keys=['destination', 'gateway'], + help="Routes associated with the router. " + "Repeat this option to set multiple routes. " + "destination: destination subnet (in CIDR notation). " + "gateway: nexthop IP address.", + ) + routes_group.add_argument( + '--clear-routes', + dest='clear_routes', + action='store_true', + help="Clear routes associated with the router", + ) # TODO(tangchen): Support setting 'ha' property in 'router set' # command. It appears that changing the ha state is supported by @@ -258,9 +283,6 @@ class SetRouter(command.Command): # 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): diff --git a/openstackclient/tests/network/v2/test_router.py b/openstackclient/tests/network/v2/test_router.py index 05bb7857e2..794f8ab5c6 100644 --- a/openstackclient/tests/network/v2/test_router.py +++ b/openstackclient/tests/network/v2/test_router.py @@ -306,6 +306,63 @@ class TestSetRouter(TestRouter): self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) + def test_set_route(self): + arglist = [ + self._router.name, + '--route', 'destination=10.20.30.0/24,gateway=10.20.30.1', + ] + verifylist = [ + ('router', self._router.name), + ('routes', [{'destination': '10.20.30.0/24', + 'gateway': '10.20.30.1'}]), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + attrs = { + 'routes': [{'destination': '10.20.30.0/24', + 'gateway': '10.20.30.1'}], + } + self.network.update_router.assert_called_with(self._router, **attrs) + self.assertIsNone(result) + + def test_set_clear_routes(self): + arglist = [ + self._router.name, + '--clear-routes', + ] + verifylist = [ + ('router', self._router.name), + ('clear_routes', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + attrs = { + 'routes': [], + } + self.network.update_router.assert_called_with(self._router, **attrs) + self.assertIsNone(result) + + def test_set_route_clear_routes(self): + arglist = [ + self._router.name, + '--route', 'destination=10.20.30.0/24,gateway=10.20.30.1', + '--clear-routes', + ] + verifylist = [ + ('router', self._router.name), + ('routes', [{'destination': '10.20.30.0/24', + 'gateway': '10.20.30.1'}]), + ('clear_routes', True), + ] + + # Argument parse failing should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + def test_set_nothing(self): arglist = [self._router.name, ] verifylist = [('router', self._router.name), ]