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
This commit is contained in:
Tang Chen 2016-02-04 13:19:01 +08:00
parent ada06f4dc3
commit 01c19ef0bc
3 changed files with 95 additions and 4 deletions

View File

@ -93,6 +93,7 @@ Set router properties
[--name <name>] [--name <name>]
[--enable | --disable] [--enable | --disable]
[--distributed | --centralized] [--distributed | --centralized]
[--route destination=<subnet>,gateway=<ip-address> | --clear-routes]
<router> <router>
.. option:: --name <name> .. option:: --name <name>
@ -115,6 +116,17 @@ Set router properties
Set router to centralized mode (disabled router only) Set router to centralized mode (disabled router only)
.. option:: --route destination=<subnet>,gateway=<ip-address>
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: .. _router_set-router:
.. describe:: <router> .. describe:: <router>

View File

@ -17,6 +17,7 @@ import json
from openstackclient.common import command from openstackclient.common import command
from openstackclient.common import exceptions from openstackclient.common import exceptions
from openstackclient.common import parseractions
from openstackclient.common import utils from openstackclient.common import utils
from openstackclient.identity import common as identity_common 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 if ('availability_zone_hints' in parsed_args
and parsed_args.availability_zone_hints is not None): and parsed_args.availability_zone_hints is not None):
attrs['availability_zone_hints'] = parsed_args.availability_zone_hints 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. # "router set" command doesn't support setting project.
if 'project' in parsed_args and parsed_args.project is not None: if 'project' in parsed_args and parsed_args.project is not None:
identity_client = client_manager.identity 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 'ha' property.
# TODO(tangchen): Support getting 'external_gateway_info' property. # TODO(tangchen): Support getting 'external_gateway_info' property.
# TODO(tangchen): Support getting 'routes' property.
return attrs return attrs
@ -250,6 +256,25 @@ class SetRouter(command.Command):
action='store_false', action='store_false',
help="Set router to centralized mode (disabled router only)", help="Set router to centralized mode (disabled router only)",
) )
routes_group = parser.add_mutually_exclusive_group()
routes_group.add_argument(
'--route',
metavar='destination=<subnet>,gateway=<ip-address>',
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' # TODO(tangchen): Support setting 'ha' property in 'router set'
# command. It appears that changing the ha state is supported by # 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 # TODO(tangchen): Support setting 'external_gateway_info' property in
# 'router set' command. # 'router set' command.
# TODO(tangchen): Support setting 'routes' property in 'router set'
# command.
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):

View File

@ -306,6 +306,63 @@ class TestSetRouter(TestRouter):
self.assertRaises(tests_utils.ParserException, self.check_parser, self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist) 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): def test_set_nothing(self):
arglist = [self._router.name, ] arglist = [self._router.name, ]
verifylist = [('router', self._router.name), ] verifylist = [('router', self._router.name), ]