Merge "Add support for setting router gateway"
This commit is contained in:
commit
e51a2b3b17
@ -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>
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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>`_]
|
Loading…
Reference in New Issue
Block a user