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

View File

@ -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=<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'
# 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):

View File

@ -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), ]