Merge "Add support for setting router gateway"

This commit is contained in:
Jenkins 2016-12-19 14:31:10 +00:00 committed by Gerrit Code Review
commit e51a2b3b17
4 changed files with 189 additions and 7 deletions

View File

@ -223,6 +223,7 @@ Set router properties
[--description <description>]
[--route destination=<subnet>,gateway=<ip-address> | --no-route]
[--ha | --no-ha]
[--external-gateway <network> [--enable-snat|--disable-snat] [--fixed-ip subnet=<subnet>,ip-address=<ip-address>]]
<router>
.. option:: --name <name>
@ -268,6 +269,24 @@ Set router properties
Clear high availablability attribute of the router (disabled router only)
.. option:: --external-gateway <network>
External Network used as router's gateway (name or ID)
.. option:: --enable-snat
Enable Source NAT on external gateway
.. option:: --disable-snat
Disable Source NAT on external gateway
.. option:: --fixed-ip subnet=<subnet>,ip-address=<ip-address>
Desired IP and/or subnet (name or ID) on external gateway:
subnet=<subnet>,ip-address=<ip-address>
(repeat option to set multiple fixed IP addresses)
.. _router_set-router:
.. describe:: <router>

View File

@ -499,9 +499,32 @@ class SetRouter(command.Command):
help=_("Clear high availablability attribute of the router "
"(disabled router only)")
)
# TODO(tangchen): Support setting 'external_gateway_info' property in
# 'router set' command.
parser.add_argument(
'--external-gateway',
metavar="<network>",
help=_("External Network used as router's gateway (name or ID)")
)
parser.add_argument(
'--fixed-ip',
metavar='subnet=<subnet>,ip-address=<ip-address>',
action=parseractions.MultiKeyValueAction,
optional_keys=['subnet', 'ip-address'],
help=_("Desired IP and/or subnet (name or ID)"
"on external gateway: "
"subnet=<subnet>,ip-address=<ip-address> "
"(repeat option to set multiple fixed IP addresses)")
)
snat_group = parser.add_mutually_exclusive_group()
snat_group.add_argument(
'--enable-snat',
action='store_true',
help=_("Enable Source NAT on external gateway")
)
snat_group.add_argument(
'--disable-snat',
action='store_true',
help=_("Disable Source NAT on external gateway")
)
return parser
def take_action(self, parsed_args):
@ -530,7 +553,34 @@ class SetRouter(command.Command):
for route in parsed_args.routes:
route['nexthop'] = route.pop('gateway')
attrs['routes'] = obj.routes + parsed_args.routes
if (parsed_args.disable_snat or parsed_args.enable_snat or
parsed_args.fixed_ip) and not parsed_args.external_gateway:
msg = (_("You must specify '--external-gateway' in order"
"to update the SNAT or fixed-ip values"))
raise exceptions.CommandError(msg)
if parsed_args.external_gateway:
gateway_info = {}
network = client.find_network(
parsed_args.external_gateway, ignore_missing=False)
gateway_info['network_id'] = network.id
if parsed_args.disable_snat:
gateway_info['enable_snat'] = False
if parsed_args.enable_snat:
gateway_info['enable_snat'] = True
if parsed_args.fixed_ip:
ips = []
for ip_spec in parsed_args.fixed_ip:
if ip_spec.get('subnet', False):
subnet_name_id = ip_spec.pop('subnet')
if subnet_name_id:
subnet = client.find_subnet(subnet_name_id,
ignore_missing=False)
ip_spec['subnet_id'] = subnet.id
if ip_spec.get('ip-address', False):
ip_spec['ip_address'] = ip_spec.pop('ip-address')
ips.append(ip_spec)
gateway_info['external_fixed_ips'] = ips
attrs['external_gateway_info'] = gateway_info
client.update_router(obj, **attrs)

View File

@ -602,17 +602,19 @@ class TestSetRouter(TestRouter):
# The router to set.
_default_route = {'destination': '10.20.20.0/24', 'nexthop': '10.20.30.1'}
_network = network_fakes.FakeNetwork.create_one_network()
_subnet = network_fakes.FakeSubnet.create_one_subnet()
_router = network_fakes.FakeRouter.create_one_router(
attrs={'routes': [_default_route]}
)
def setUp(self):
super(TestSetRouter, self).setUp()
self.network.router_add_gateway = mock.Mock()
self.network.update_router = mock.Mock(return_value=None)
self.network.find_router = mock.Mock(return_value=self._router)
self.network.find_network = mock.Mock(return_value=self._network)
self.network.find_subnet = mock.Mock(return_value=self._subnet)
# Get the command object to test
self.cmd = router.SetRouter(self.app, self.namespace)
@ -799,6 +801,110 @@ class TestSetRouter(TestRouter):
self._router, **attrs)
self.assertIsNone(result)
def test_wrong_gateway_params(self):
arglist = [
"--fixed-ip", "subnet='abc'",
self._router.id,
]
verifylist = [
('fixed_ip', [{'subnet': "'abc'"}]),
('router', self._router.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError,
self.cmd.take_action, parsed_args)
def test_set_gateway_network_only(self):
arglist = [
"--external-gateway", self._network.id,
self._router.id,
]
verifylist = [
('external_gateway', self._network.id),
('router', self._router.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.network.update_router.assert_called_with(
self._router, **{'external_gateway_info': {
'network_id': self._network.id}})
self.assertIsNone(result)
def test_set_gateway_options_subnet_only(self):
arglist = [
"--external-gateway", self._network.id,
"--fixed-ip", "subnet='abc'",
self._router.id,
'--enable-snat',
]
verifylist = [
('router', self._router.id),
('external_gateway', self._network.id),
('fixed_ip', [{'subnet': "'abc'"}]),
('enable_snat', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.network.update_router.assert_called_with(
self._router, **{'external_gateway_info': {
'network_id': self._network.id,
'external_fixed_ips': [{
'subnet_id': self._subnet.id, }],
'enable_snat': True, }})
self.assertIsNone(result)
def test_set_gateway_option_ipaddress_only(self):
arglist = [
"--external-gateway", self._network.id,
"--fixed-ip", "ip-address=10.0.1.1",
self._router.id,
'--enable-snat',
]
verifylist = [
('router', self._router.id),
('external_gateway', self._network.id),
('fixed_ip', [{'ip-address': "10.0.1.1"}]),
('enable_snat', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.network.update_router.assert_called_with(
self._router, **{'external_gateway_info': {
'network_id': self._network.id,
'external_fixed_ips': [{
'ip_address': "10.0.1.1", }],
'enable_snat': True, }})
self.assertIsNone(result)
def test_set_gateway_options_subnet_ipaddress(self):
arglist = [
"--external-gateway", self._network.id,
"--fixed-ip", "subnet='abc',ip-address=10.0.1.1",
self._router.id,
'--enable-snat',
]
verifylist = [
('router', self._router.id),
('external_gateway', self._network.id),
('fixed_ip', [{'subnet': "'abc'",
'ip-address': "10.0.1.1"}]),
('enable_snat', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.network.update_router.assert_called_with(
self._router, **{'external_gateway_info': {
'network_id': self._network.id,
'external_fixed_ips': [{
'subnet_id': self._subnet.id,
'ip_address': "10.0.1.1", }],
'enable_snat': True, }})
self.assertIsNone(result)
class TestShowRouter(TestRouter):

View File

@ -0,0 +1,7 @@
---
features:
- |
Add support for setting the gateway information in a router,
by introducing the new option ``--external-gateway`` in
``router set`` CLI.
[ Blueprint `neutron-client-advanced-router <https://blueprints.launchpad.net/python-openstackclient/+spec/neutron-client-advanced-router>`_]