Subnet List
Subnet list command Partially implements: blueprint neutron-client Partial-Bug: #1523258 Change-Id: I3c0748074a6511ff92500516b3129886d2476eed
This commit is contained in:
		 Terry Howe
					Terry Howe
				
			
				
					committed by
					
						 Lingxian Kong
						Lingxian Kong
					
				
			
			
				
	
			
			
			 Lingxian Kong
						Lingxian Kong
					
				
			
						parent
						
							eb36df1f82
						
					
				
				
					commit
					ffcfff6f3e
				
			
							
								
								
									
										20
									
								
								doc/source/command-objects/subnet.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								doc/source/command-objects/subnet.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| ====== | ||||
| subnet | ||||
| ====== | ||||
|  | ||||
| Network v2 | ||||
|  | ||||
| subnet list | ||||
| ----------- | ||||
|  | ||||
| List subnets | ||||
|  | ||||
| .. program:: subnet list | ||||
| .. code:: bash | ||||
|  | ||||
|     os subnet list | ||||
|         [--long] | ||||
|  | ||||
| .. option:: --long | ||||
|  | ||||
|     List additional fields in output | ||||
| @@ -116,6 +116,7 @@ referring to both Compute and Volume quotas. | ||||
| * ``service``: (**Identity**) a cloud service | ||||
| * ``service provider``: (**Identity**) a resource that consumes assertions from an ``identity provider`` | ||||
| * ``snapshot``: (**Volume**) a point-in-time copy of a volume | ||||
| * ``subnet``: (**Network**) - a pool of private IP addresses that can be assigned to instances or other resources | ||||
| * ``token``: (**Identity**) a bearer token managed by Identity service | ||||
| * ``usage``: (**Compute**) display host resources being consumed | ||||
| * ``user``: (**Identity**) individual cloud resources users | ||||
|   | ||||
							
								
								
									
										70
									
								
								openstackclient/network/v2/subnet.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								openstackclient/network/v2/subnet.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| #   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. | ||||
| # | ||||
|  | ||||
| """Subnet action implementations""" | ||||
|  | ||||
| import logging | ||||
|  | ||||
| from cliff import lister | ||||
|  | ||||
| from openstackclient.common import utils | ||||
|  | ||||
|  | ||||
| def _format_allocation_pools(data): | ||||
|     pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', '')) | ||||
|                       for pool in data] | ||||
|     return ','.join(pool_formatted) | ||||
|  | ||||
|  | ||||
| _formatters = { | ||||
|     'allocation_pools': _format_allocation_pools, | ||||
|     'dns_nameservers': utils.format_list, | ||||
|     'host_routes': utils.format_list, | ||||
| } | ||||
|  | ||||
|  | ||||
| class ListSubnet(lister.Lister): | ||||
|     """List subnets""" | ||||
|  | ||||
|     log = logging.getLogger(__name__ + '.ListSubnet') | ||||
|  | ||||
|     def get_parser(self, prog_name): | ||||
|         parser = super(ListSubnet, 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) | ||||
|  | ||||
|         data = self.app.client_manager.network.subnets() | ||||
|  | ||||
|         headers = ('ID', 'Name', 'Network', 'CIDR') | ||||
|         columns = ('id', 'name', 'network_id', 'cidr') | ||||
|         if parsed_args.long: | ||||
|             headers += ('Project', 'DHCP', 'DNS Nameservers', | ||||
|                         'Allocation Pools', 'Host Routes', 'IP Version', | ||||
|                         'Gateway') | ||||
|             columns += ('tenant_id', 'enable_dhcp', 'dns_nameservers', | ||||
|                         'allocation_pools', 'host_routes', 'ip_version', | ||||
|                         'gateway_ip') | ||||
|  | ||||
|         return (headers, | ||||
|                 (utils.get_item_properties( | ||||
|                     s, columns, | ||||
|                     formatters=_formatters, | ||||
|                 ) for s in data)) | ||||
| @@ -304,3 +304,71 @@ class FakeRouter(object): | ||||
|         if routers is None: | ||||
|             routers = FakeRouter.create_routers(count) | ||||
|         return mock.MagicMock(side_effect=routers) | ||||
|  | ||||
|  | ||||
| class FakeSubnet(object): | ||||
|     """Fake one or more subnets.""" | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_one_subnet(attrs={}, methods={}): | ||||
|         """Create a fake subnet. | ||||
|  | ||||
|         :param Dictionary attrs: | ||||
|             A dictionary with all attributes | ||||
|         :param Dictionary methods: | ||||
|             A dictionary with all methods | ||||
|         :return: | ||||
|             A FakeResource object faking the subnet | ||||
|         """ | ||||
|         # Set default attributes. | ||||
|         subnet_attrs = { | ||||
|             'id': 'subnet-id-' + uuid.uuid4().hex, | ||||
|             'name': 'subnet-name-' + uuid.uuid4().hex, | ||||
|             'network_id': 'network-id-' + uuid.uuid4().hex, | ||||
|             'cidr': '10.10.10.0/24', | ||||
|             'tenant_id': 'project-id-' + uuid.uuid4().hex, | ||||
|             'enable_dhcp': True, | ||||
|             'dns_nameservers': [], | ||||
|             'allocation_pools': [], | ||||
|             'host_routes': [], | ||||
|             'ip_version': '4', | ||||
|             'gateway_ip': '10.10.10.1', | ||||
|         } | ||||
|  | ||||
|         # Overwrite default attributes. | ||||
|         subnet_attrs.update(attrs) | ||||
|  | ||||
|         # Set default methods. | ||||
|         subnet_methods = { | ||||
|             'keys': ['id', 'name', 'network_id', 'cidr', 'enable_dhcp', | ||||
|                      'allocation_pools', 'dns_nameservers', 'gateway_ip', | ||||
|                      'host_routes', 'ip_version', 'tenant_id'] | ||||
|         } | ||||
|  | ||||
|         # Overwrite default methods. | ||||
|         subnet_methods.update(methods) | ||||
|  | ||||
|         subnet = fakes.FakeResource(info=copy.deepcopy(subnet_attrs), | ||||
|                                     methods=copy.deepcopy(subnet_methods), | ||||
|                                     loaded=True) | ||||
|  | ||||
|         return subnet | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_subnets(attrs={}, methods={}, count=2): | ||||
|         """Create multiple fake subnets. | ||||
|  | ||||
|         :param Dictionary attrs: | ||||
|             A dictionary with all attributes | ||||
|         :param Dictionary methods: | ||||
|             A dictionary with all methods | ||||
|         :param int count: | ||||
|             The number of subnets to fake | ||||
|         :return: | ||||
|             A list of FakeResource objects faking the subnets | ||||
|         """ | ||||
|         subnets = [] | ||||
|         for i in range(0, count): | ||||
|             subnets.append(FakeSubnet.create_one_subnet(attrs, methods)) | ||||
|  | ||||
|         return subnets | ||||
|   | ||||
							
								
								
									
										108
									
								
								openstackclient/tests/network/v2/test_subnet.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								openstackclient/tests/network/v2/test_subnet.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| #   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.common import utils | ||||
| from openstackclient.network.v2 import subnet as subnet_v2 | ||||
| from openstackclient.tests.network.v2 import fakes as network_fakes | ||||
|  | ||||
|  | ||||
| class TestSubnet(network_fakes.TestNetworkV2): | ||||
|     def setUp(self): | ||||
|         super(TestSubnet, self).setUp() | ||||
|  | ||||
|         # Get a shortcut to the network client | ||||
|         self.network = self.app.client_manager.network | ||||
|  | ||||
|  | ||||
| class TestListSubnet(TestSubnet): | ||||
|     # The subnets going to be listed up. | ||||
|     _subnet = network_fakes.FakeSubnet.create_subnets(count=3) | ||||
|  | ||||
|     columns = ( | ||||
|         'ID', | ||||
|         'Name', | ||||
|         'Network', | ||||
|         'CIDR' | ||||
|     ) | ||||
|     columns_long = columns + ( | ||||
|         'Project', | ||||
|         'DHCP', | ||||
|         'DNS Nameservers', | ||||
|         'Allocation Pools', | ||||
|         'Host Routes', | ||||
|         'IP Version', | ||||
|         'Gateway' | ||||
|     ) | ||||
|  | ||||
|     data = [] | ||||
|     for subnet in _subnet: | ||||
|         data.append(( | ||||
|             subnet.id, | ||||
|             subnet.name, | ||||
|             subnet.network_id, | ||||
|             subnet.cidr, | ||||
|         )) | ||||
|  | ||||
|     data_long = [] | ||||
|     for subnet in _subnet: | ||||
|         data_long.append(( | ||||
|             subnet.id, | ||||
|             subnet.name, | ||||
|             subnet.network_id, | ||||
|             subnet.cidr, | ||||
|             subnet.tenant_id, | ||||
|             subnet.enable_dhcp, | ||||
|             utils.format_list(subnet.dns_nameservers), | ||||
|             subnet_v2._format_allocation_pools(subnet.allocation_pools), | ||||
|             utils.format_list(subnet.host_routes), | ||||
|             subnet.ip_version, | ||||
|             subnet.gateway_ip | ||||
|         )) | ||||
|  | ||||
|     def setUp(self): | ||||
|         super(TestListSubnet, self).setUp() | ||||
|  | ||||
|         # Get the command object to test | ||||
|         self.cmd = subnet_v2.ListSubnet(self.app, self.namespace) | ||||
|  | ||||
|         self.network.subnets = mock.Mock(return_value=self._subnet) | ||||
|  | ||||
|     def test_subnet_list_no_options(self): | ||||
|         arglist = [] | ||||
|         verifylist = [ | ||||
|             ('long', False), | ||||
|         ] | ||||
|         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||
|  | ||||
|         columns, data = self.cmd.take_action(parsed_args) | ||||
|  | ||||
|         self.network.subnets.assert_called_with() | ||||
|         self.assertEqual(self.columns, columns) | ||||
|         self.assertEqual(self.data, list(data)) | ||||
|  | ||||
|     def test_subnet_list_long(self): | ||||
|         arglist = [ | ||||
|             '--long', | ||||
|         ] | ||||
|         verifylist = [ | ||||
|             ('long', True), | ||||
|         ] | ||||
|         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||
|  | ||||
|         columns, data = self.cmd.take_action(parsed_args) | ||||
|  | ||||
|         self.network.subnets.assert_called_with() | ||||
|         self.assertEqual(self.columns_long, columns) | ||||
|         self.assertEqual(self.data_long, list(data)) | ||||
| @@ -339,6 +339,7 @@ openstack.network.v2 = | ||||
|     router_list = openstackclient.network.v2.router:ListRouter | ||||
|     router_set = openstackclient.network.v2.router:SetRouter | ||||
|     router_show = openstackclient.network.v2.router:ShowRouter | ||||
|     subnet_list = openstackclient.network.v2.subnet:ListSubnet | ||||
|  | ||||
| openstack.object_store.v1 = | ||||
|     object_store_account_set = openstackclient.object.v1.account:SetAccount | ||||
|   | ||||
		Reference in New Issue
	
	Block a user