Introduce overwrite functionality in `osc router set
`
The overwrite functionality allows user to overwrite the routes of a specific router. Change-Id: I8d3cfe5cab2ffbfa046371c3adcd2cf446c91cbc partially-implements: blueprint allow-overwrite-set-options
This commit is contained in:
parent
e51a2b3b17
commit
25104c7d4a
@ -259,7 +259,9 @@ Set router properties
|
|||||||
|
|
||||||
.. option:: --no-route
|
.. option:: --no-route
|
||||||
|
|
||||||
Clear routes associated with the router
|
Clear routes associated with the router.
|
||||||
|
Specify both --route and --no-route to overwrite
|
||||||
|
current value of route.
|
||||||
|
|
||||||
.. option:: --ha
|
.. option:: --ha
|
||||||
|
|
||||||
|
@ -98,8 +98,6 @@ def _get_attrs(client_manager, parsed_args):
|
|||||||
).id
|
).id
|
||||||
attrs['tenant_id'] = project_id
|
attrs['tenant_id'] = project_id
|
||||||
|
|
||||||
# TODO(tangchen): Support getting 'external_gateway_info' property.
|
|
||||||
|
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
@ -464,7 +462,8 @@ class SetRouter(command.Command):
|
|||||||
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 = parser.add_mutually_exclusive_group()
|
||||||
routes_group.add_argument(
|
# ToDo(Reedip):Remove mutual exclusiveness once clear-routes is removed
|
||||||
|
parser.add_argument(
|
||||||
'--route',
|
'--route',
|
||||||
metavar='destination=<subnet>,gateway=<ip-address>',
|
metavar='destination=<subnet>,gateway=<ip-address>',
|
||||||
action=parseractions.MultiKeyValueAction,
|
action=parseractions.MultiKeyValueAction,
|
||||||
@ -479,7 +478,9 @@ class SetRouter(command.Command):
|
|||||||
routes_group.add_argument(
|
routes_group.add_argument(
|
||||||
'--no-route',
|
'--no-route',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help=_("Clear routes associated with the router")
|
help=_("Clear routes associated with the router. "
|
||||||
|
"Specify both --route and --no-route to overwrite "
|
||||||
|
"current value of route.")
|
||||||
)
|
)
|
||||||
routes_group.add_argument(
|
routes_group.add_argument(
|
||||||
'--clear-routes',
|
'--clear-routes',
|
||||||
@ -539,20 +540,22 @@ class SetRouter(command.Command):
|
|||||||
attrs['ha'] = True
|
attrs['ha'] = True
|
||||||
elif parsed_args.no_ha:
|
elif parsed_args.no_ha:
|
||||||
attrs['ha'] = False
|
attrs['ha'] = False
|
||||||
if parsed_args.no_route:
|
if parsed_args.clear_routes:
|
||||||
attrs['routes'] = []
|
|
||||||
elif parsed_args.clear_routes:
|
|
||||||
attrs['routes'] = []
|
|
||||||
LOG.warning(_(
|
LOG.warning(_(
|
||||||
'The --clear-routes option is deprecated, '
|
'The --clear-routes option is deprecated, '
|
||||||
'please use --no-route instead.'
|
'please use --no-route instead.'
|
||||||
))
|
))
|
||||||
elif parsed_args.routes is not None:
|
|
||||||
# Map the route keys and append to the current routes.
|
if parsed_args.routes is not None:
|
||||||
# The REST API will handle route validation and duplicates.
|
|
||||||
for route in parsed_args.routes:
|
for route in parsed_args.routes:
|
||||||
route['nexthop'] = route.pop('gateway')
|
route['nexthop'] = route.pop('gateway')
|
||||||
attrs['routes'] = obj.routes + parsed_args.routes
|
attrs['routes'] = parsed_args.routes
|
||||||
|
if not (parsed_args.no_route or parsed_args.clear_routes):
|
||||||
|
# Map the route keys and append to the current routes.
|
||||||
|
# The REST API will handle route validation and duplicates.
|
||||||
|
attrs['routes'] += obj.routes
|
||||||
|
elif parsed_args.no_route or parsed_args.clear_routes:
|
||||||
|
attrs['routes'] = []
|
||||||
if (parsed_args.disable_snat or parsed_args.enable_snat or
|
if (parsed_args.disable_snat or parsed_args.enable_snat or
|
||||||
parsed_args.fixed_ip) and not parsed_args.external_gateway:
|
parsed_args.fixed_ip) and not parsed_args.external_gateway:
|
||||||
msg = (_("You must specify '--external-gateway' in order"
|
msg = (_("You must specify '--external-gateway' in order"
|
||||||
|
@ -704,10 +704,10 @@ class TestSetRouter(TestRouter):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
routes = [{'destination': '10.20.30.0/24',
|
||||||
|
'nexthop': '10.20.30.1'}]
|
||||||
attrs = {
|
attrs = {
|
||||||
'routes': self._router.routes + [{'destination': '10.20.30.0/24',
|
'routes': routes + self._router.routes
|
||||||
'nexthop': '10.20.30.1'}],
|
|
||||||
}
|
}
|
||||||
self.network.update_router.assert_called_once_with(
|
self.network.update_router.assert_called_once_with(
|
||||||
self._router, **attrs)
|
self._router, **attrs)
|
||||||
@ -733,21 +733,31 @@ class TestSetRouter(TestRouter):
|
|||||||
self._router, **attrs)
|
self._router, **attrs)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_set_route_no_route(self):
|
def test_set_route_overwrite_route(self):
|
||||||
|
_testrouter = network_fakes.FakeRouter.create_one_router(
|
||||||
|
{'routes': [{"destination": "10.0.0.2",
|
||||||
|
"nexthop": "1.1.1.1"}]})
|
||||||
|
self.network.find_router = mock.Mock(return_value=_testrouter)
|
||||||
arglist = [
|
arglist = [
|
||||||
self._router.name,
|
_testrouter.name,
|
||||||
'--route', 'destination=10.20.30.0/24,gateway=10.20.30.1',
|
'--route', 'destination=10.20.30.0/24,gateway=10.20.30.1',
|
||||||
'--no-route',
|
'--no-route',
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('router', self._router.name),
|
('router', _testrouter.name),
|
||||||
('routes', [{'destination': '10.20.30.0/24',
|
('routes', [{'destination': '10.20.30.0/24',
|
||||||
'gateway': '10.20.30.1'}]),
|
'gateway': '10.20.30.1'}]),
|
||||||
('no_route', True),
|
('no_route', True),
|
||||||
]
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.cmd, arglist, verifylist)
|
attrs = {
|
||||||
|
'routes': [{'destination': '10.20.30.0/24',
|
||||||
|
'nexthop': '10.20.30.1'}]
|
||||||
|
}
|
||||||
|
self.network.update_router.assert_called_once_with(
|
||||||
|
_testrouter, **attrs)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_set_clear_routes(self):
|
def test_set_clear_routes(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -769,21 +779,31 @@ class TestSetRouter(TestRouter):
|
|||||||
self._router, **attrs)
|
self._router, **attrs)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_set_route_clear_routes(self):
|
def test_overwrite_route_clear_routes(self):
|
||||||
|
_testrouter = network_fakes.FakeRouter.create_one_router(
|
||||||
|
{'routes': [{"destination": "10.0.0.2",
|
||||||
|
"nexthop": "1.1.1.1"}]})
|
||||||
|
self.network.find_router = mock.Mock(return_value=_testrouter)
|
||||||
arglist = [
|
arglist = [
|
||||||
self._router.name,
|
_testrouter.name,
|
||||||
'--route', 'destination=10.20.30.0/24,gateway=10.20.30.1',
|
'--route', 'destination=10.20.30.0/24,gateway=10.20.30.1',
|
||||||
'--clear-routes',
|
'--clear-routes',
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('router', self._router.name),
|
('router', _testrouter.name),
|
||||||
('routes', [{'destination': '10.20.30.0/24',
|
('routes', [{'destination': '10.20.30.0/24',
|
||||||
'gateway': '10.20.30.1'}]),
|
'gateway': '10.20.30.1'}]),
|
||||||
('clear_routes', True),
|
('clear_routes', True),
|
||||||
]
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.cmd, arglist, verifylist)
|
attrs = {
|
||||||
|
'routes': [{'destination': '10.20.30.0/24',
|
||||||
|
'nexthop': '10.20.30.1'}]
|
||||||
|
}
|
||||||
|
self.network.update_router.assert_called_once_with(
|
||||||
|
_testrouter, **attrs)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_set_nothing(self):
|
def test_set_nothing(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add support to overwrite routes in a router instance, using ``--router``
|
||||||
|
and ``--no-router`` option in ``osc router set``.
|
||||||
|
[ Blueprint `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user