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:
parent
ada06f4dc3
commit
01c19ef0bc
@ -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>
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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), ]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user