summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorReedip <reedip.banerjee@nectechnologies.in>2016-08-19 21:02:35 +0530
committerReedip <reedip.banerjee@gmail.com>2016-12-17 18:22:45 +0000
commit841d9d8dbd313b3dcf604466786d6b9a5c918156 (patch)
tree132940b348a75560de216bea007e421637925029 /openstackclient
parentd6e058fa1f6323ef73354f0aea0e09efb647bc7e (diff)
downloadpython-openstackclient-841d9d8dbd313b3dcf604466786d6b9a5c918156.tar.gz
Add support for setting router gateway
This patch adds the support to set the gateway information for a router. Implements: blueprint neutron-client-advanced-router Partially-Implements: blueprint network-commands-options Change-Id: Ifb5a4d1965cd7e75c0c8cf2cfb677e0628b699dc Depends-On: I2bda0dd40afd64b6cecca5f64ef2326bda4fac92
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/network/v2/router.py58
-rw-r--r--openstackclient/tests/unit/network/v2/test_router.py112
2 files changed, 163 insertions, 7 deletions
diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py
index cbd412b5..bf60cf6f 100644
--- a/openstackclient/network/v2/router.py
+++ b/openstackclient/network/v2/router.py
@@ -473,9 +473,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):
@@ -504,7 +527,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)
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index 24984e47..f5f2c325 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -561,17 +561,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)
@@ -758,6 +760,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):