Router: Add "router list" command using SDK
Add "router list" command. It takes one "--long" option. By default, the command will print router id, name, status, admin state up, distributed, ha and project id. With "--long" option, it will also print routes and external gateway info. Change-Id: I9d21904c41c11ee1fa107f985744878a1dc2f970 Implements: blueprint neutron-client Partial-bug: #1519503
This commit is contained in:
		
							
								
								
									
										20
									
								
								doc/source/command-objects/router.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								doc/source/command-objects/router.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | ====== | ||||||
|  | router | ||||||
|  | ====== | ||||||
|  |  | ||||||
|  | Network v2 | ||||||
|  |  | ||||||
|  | router list | ||||||
|  | ----------- | ||||||
|  |  | ||||||
|  | List routers | ||||||
|  |  | ||||||
|  | .. program:: router list | ||||||
|  | .. code:: bash | ||||||
|  |  | ||||||
|  |     os router list | ||||||
|  |         [--long] | ||||||
|  |  | ||||||
|  | .. option:: --long | ||||||
|  |  | ||||||
|  |     List additional fields in output | ||||||
| @@ -107,6 +107,7 @@ referring to both Compute and Volume quotas. | |||||||
| * ``request token``: (**Identity**) temporary OAuth-based token | * ``request token``: (**Identity**) temporary OAuth-based token | ||||||
| * ``role``: (**Identity**) a policy object used to determine authorization | * ``role``: (**Identity**) a policy object used to determine authorization | ||||||
| * ``role assignment``: (**Identity**) a relationship between roles, users or groups, and domains or projects | * ``role assignment``: (**Identity**) a relationship between roles, users or groups, and domains or projects | ||||||
|  | * ``router``: (**Network**) - a virtual router | ||||||
| * ``security group``: (**Compute**, **Network**) - groups of network access rules | * ``security group``: (**Compute**, **Network**) - groups of network access rules | ||||||
| * ``security group rule``: (**Compute**, **Network**) - the individual rules that define protocol/IP/port access | * ``security group rule``: (**Compute**, **Network**) - the individual rules that define protocol/IP/port access | ||||||
| * ``server``: (**Compute**) virtual machine instance | * ``server``: (**Compute**) virtual machine instance | ||||||
|   | |||||||
							
								
								
									
										93
									
								
								openstackclient/network/v2/router.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								openstackclient/network/v2/router.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | #   Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||||
|  | #   not use this file except in compliance with the License. You may obtain | ||||||
|  | #   a copy of the License at | ||||||
|  | # | ||||||
|  | #        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | #   Unless required by applicable law or agreed to in writing, software | ||||||
|  | #   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
|  | #   License for the specific language governing permissions and limitations | ||||||
|  | #   under the License. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | """Router action implementations""" | ||||||
|  |  | ||||||
|  | import json | ||||||
|  | import logging | ||||||
|  |  | ||||||
|  | from cliff import lister | ||||||
|  |  | ||||||
|  | from openstackclient.common import utils | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _format_admin_state(state): | ||||||
|  |     return 'UP' if state else 'DOWN' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _format_external_gateway_info(info): | ||||||
|  |     try: | ||||||
|  |         return json.dumps(info) | ||||||
|  |     except (TypeError, KeyError): | ||||||
|  |         return '' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | _formatters = { | ||||||
|  |     'admin_state_up': _format_admin_state, | ||||||
|  |     'external_gateway_info': _format_external_gateway_info, | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ListRouter(lister.Lister): | ||||||
|  |     """List routers""" | ||||||
|  |  | ||||||
|  |     log = logging.getLogger(__name__ + '.ListRouter') | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(ListRouter, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--long', | ||||||
|  |             action='store_true', | ||||||
|  |             default=False, | ||||||
|  |             help='List additional fields in output', | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         self.log.debug('take_action(%s)' % parsed_args) | ||||||
|  |         client = self.app.client_manager.network | ||||||
|  |  | ||||||
|  |         columns = ( | ||||||
|  |             'id', | ||||||
|  |             'name', | ||||||
|  |             'status', | ||||||
|  |             'admin_state_up', | ||||||
|  |             'distributed', | ||||||
|  |             'ha', | ||||||
|  |             'tenant_id', | ||||||
|  |         ) | ||||||
|  |         column_headers = ( | ||||||
|  |             'ID', | ||||||
|  |             'Name', | ||||||
|  |             'Status', | ||||||
|  |             'State', | ||||||
|  |             'Distributed', | ||||||
|  |             'HA', | ||||||
|  |             'Project', | ||||||
|  |         ) | ||||||
|  |         if parsed_args.long: | ||||||
|  |             columns = columns + ( | ||||||
|  |                 'routes', | ||||||
|  |                 'external_gateway_info', | ||||||
|  |             ) | ||||||
|  |             column_headers = column_headers + ( | ||||||
|  |                 'Routes', | ||||||
|  |                 'External gateway info', | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |         data = client.routers() | ||||||
|  |         return (column_headers, | ||||||
|  |                 (utils.get_item_properties( | ||||||
|  |                     s, columns, | ||||||
|  |                     formatters=_formatters, | ||||||
|  |                 ) for s in data)) | ||||||
							
								
								
									
										105
									
								
								openstackclient/tests/network/v2/test_router.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								openstackclient/tests/network/v2/test_router.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | |||||||
|  | #   Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||||
|  | #   not use this file except in compliance with the License. You may obtain | ||||||
|  | #   a copy of the License at | ||||||
|  | # | ||||||
|  | #        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | #   Unless required by applicable law or agreed to in writing, software | ||||||
|  | #   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
|  | #   License for the specific language governing permissions and limitations | ||||||
|  | #   under the License. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | import mock | ||||||
|  |  | ||||||
|  | from openstackclient.network.v2 import router | ||||||
|  | from openstackclient.tests.network.v2 import fakes as network_fakes | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestRouter(network_fakes.TestNetworkV2): | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestRouter, self).setUp() | ||||||
|  |  | ||||||
|  |         # Get a shortcut to the network client | ||||||
|  |         self.network = self.app.client_manager.network | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestListRouter(TestRouter): | ||||||
|  |  | ||||||
|  |     # The routers going to be listed up. | ||||||
|  |     routers = network_fakes.FakeRouter.create_routers(count=3) | ||||||
|  |  | ||||||
|  |     columns = ( | ||||||
|  |         'ID', | ||||||
|  |         'Name', | ||||||
|  |         'Status', | ||||||
|  |         'State', | ||||||
|  |         'Distributed', | ||||||
|  |         'HA', | ||||||
|  |         'Project', | ||||||
|  |     ) | ||||||
|  |     columns_long = columns + ( | ||||||
|  |         'Routes', | ||||||
|  |         'External gateway info', | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     data = [] | ||||||
|  |     for r in routers: | ||||||
|  |         data.append(( | ||||||
|  |             r.id, | ||||||
|  |             r.name, | ||||||
|  |             r.status, | ||||||
|  |             router._format_admin_state(r.admin_state_up), | ||||||
|  |             r.distributed, | ||||||
|  |             r.ha, | ||||||
|  |             r.tenant_id, | ||||||
|  |         )) | ||||||
|  |     data_long = [] | ||||||
|  |     for i in range(0, len(routers)): | ||||||
|  |         r = routers[i] | ||||||
|  |         data_long.append( | ||||||
|  |             data[i] + ( | ||||||
|  |                 r.routes, | ||||||
|  |                 router._format_external_gateway_info(r.external_gateway_info), | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestListRouter, self).setUp() | ||||||
|  |  | ||||||
|  |         # Get the command object to test | ||||||
|  |         self.cmd = router.ListRouter(self.app, self.namespace) | ||||||
|  |  | ||||||
|  |         self.network.routers = mock.Mock(return_value=self.routers) | ||||||
|  |  | ||||||
|  |     def test_router_list_no_options(self): | ||||||
|  |         arglist = [] | ||||||
|  |         verifylist = [ | ||||||
|  |             ('long', False), | ||||||
|  |         ] | ||||||
|  |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
|  |         # DisplayCommandBase.take_action() returns two tuples | ||||||
|  |         columns, data = self.cmd.take_action(parsed_args) | ||||||
|  |  | ||||||
|  |         self.network.routers.assert_called_with() | ||||||
|  |         self.assertEqual(self.columns, columns) | ||||||
|  |         self.assertEqual(self.data, list(data)) | ||||||
|  |  | ||||||
|  |     def test_router_list_long(self): | ||||||
|  |         arglist = [ | ||||||
|  |             '--long', | ||||||
|  |         ] | ||||||
|  |         verifylist = [ | ||||||
|  |             ('long', True), | ||||||
|  |         ] | ||||||
|  |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
|  |         # DisplayCommandBase.take_action() returns two tuples | ||||||
|  |         columns, data = self.cmd.take_action(parsed_args) | ||||||
|  |  | ||||||
|  |         self.network.routers.assert_called_with() | ||||||
|  |         self.assertEqual(self.columns_long, columns) | ||||||
|  |         self.assertEqual(self.data_long, list(data)) | ||||||
| @@ -332,6 +332,7 @@ openstack.network.v2 = | |||||||
|     network_list = openstackclient.network.v2.network:ListNetwork |     network_list = openstackclient.network.v2.network:ListNetwork | ||||||
|     network_set = openstackclient.network.v2.network:SetNetwork |     network_set = openstackclient.network.v2.network:SetNetwork | ||||||
|     network_show = openstackclient.network.v2.network:ShowNetwork |     network_show = openstackclient.network.v2.network:ShowNetwork | ||||||
|  |     router_list = openstackclient.network.v2.router:ListRouter | ||||||
|  |  | ||||||
| openstack.object_store.v1 = | openstack.object_store.v1 = | ||||||
|     object_store_account_set = openstackclient.object.v1.account:SetAccount |     object_store_account_set = openstackclient.object.v1.account:SetAccount | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Tang Chen
					Tang Chen