Merge "Add volume summary command"
This commit is contained in:
		| @@ -388,3 +388,8 @@ Unset volume properties | |||||||
| .. describe:: <volume> | .. describe:: <volume> | ||||||
|  |  | ||||||
|     Volume to modify (name or ID) |     Volume to modify (name or ID) | ||||||
|  |  | ||||||
|  | Block Storage v3 | ||||||
|  |  | ||||||
|  |  .. autoprogram-cliff:: openstack.volume.v3 | ||||||
|  |      :command: volume summary | ||||||
|   | |||||||
| @@ -120,7 +120,7 @@ snapshot-rename,snapshot set --name,Renames a snapshot. | |||||||
| snapshot-reset-state,snapshot set --state,Explicitly updates the snapshot state. | snapshot-reset-state,snapshot set --state,Explicitly updates the snapshot state. | ||||||
| snapshot-show,snapshot show,Shows snapshot details. | snapshot-show,snapshot show,Shows snapshot details. | ||||||
| snapshot-unmanage,volume snapshot delete --remote,Stop managing a snapshot. | snapshot-unmanage,volume snapshot delete --remote,Stop managing a snapshot. | ||||||
| summary,,Get volumes summary. (Supported by API versions 3.12 - 3.latest) | summary,volume summary,Get volumes summary. (Supported by API versions 3.12 - 3.latest) | ||||||
| thaw-host,volume host set --enable,Thaw and enable the specified cinder-volume host. | thaw-host,volume host set --enable,Thaw and enable the specified cinder-volume host. | ||||||
| transfer-accept,volume transfer accept,Accepts a volume transfer. | transfer-accept,volume transfer accept,Accepts a volume transfer. | ||||||
| transfer-create,volume transfer create,Creates a volume transfer. | transfer-create,volume transfer create,Creates a volume transfer. | ||||||
|   | |||||||
| 
 | 
							
								
								
									
										121
									
								
								openstackclient/tests/unit/volume/v3/test_volume.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								openstackclient/tests/unit/volume/v3/test_volume.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | # | ||||||
|  | #   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 copy | ||||||
|  |  | ||||||
|  | from cinderclient import api_versions | ||||||
|  | from osc_lib.cli import format_columns | ||||||
|  | from osc_lib import exceptions | ||||||
|  |  | ||||||
|  | from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes | ||||||
|  | from openstackclient.volume.v3 import volume | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestVolumeSummary(volume_fakes.TestVolume): | ||||||
|  |  | ||||||
|  |     columns = [ | ||||||
|  |         'Total Count', | ||||||
|  |         'Total Size', | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super().setUp() | ||||||
|  |  | ||||||
|  |         self.volumes_mock = self.app.client_manager.volume.volumes | ||||||
|  |         self.volumes_mock.reset_mock() | ||||||
|  |         self.mock_vol_1 = volume_fakes.create_one_volume() | ||||||
|  |         self.mock_vol_2 = volume_fakes.create_one_volume() | ||||||
|  |         self.return_dict = { | ||||||
|  |             'volume-summary': { | ||||||
|  |                 'total_count': 2, | ||||||
|  |                 'total_size': self.mock_vol_1.size + self.mock_vol_2.size}} | ||||||
|  |         self.volumes_mock.summary.return_value = self.return_dict | ||||||
|  |  | ||||||
|  |         # Get the command object to test | ||||||
|  |         self.cmd = volume.VolumeSummary(self.app, None) | ||||||
|  |  | ||||||
|  |     def test_volume_summary(self): | ||||||
|  |         self.app.client_manager.volume.api_version = \ | ||||||
|  |             api_versions.APIVersion('3.12') | ||||||
|  |         arglist = [ | ||||||
|  |             '--all-projects', | ||||||
|  |         ] | ||||||
|  |         verifylist = [ | ||||||
|  |             ('all_projects', True), | ||||||
|  |         ] | ||||||
|  |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
|  |         columns, data = self.cmd.take_action(parsed_args) | ||||||
|  |  | ||||||
|  |         self.volumes_mock.summary.assert_called_once_with( | ||||||
|  |             all_tenants=True, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         self.assertEqual(self.columns, columns) | ||||||
|  |  | ||||||
|  |         datalist = ( | ||||||
|  |             2, | ||||||
|  |             self.mock_vol_1.size + self.mock_vol_2.size) | ||||||
|  |         self.assertCountEqual(datalist, tuple(data)) | ||||||
|  |  | ||||||
|  |     def test_volume_summary_pre_312(self): | ||||||
|  |         arglist = [ | ||||||
|  |             '--all-projects', | ||||||
|  |         ] | ||||||
|  |         verifylist = [ | ||||||
|  |             ('all_projects', True), | ||||||
|  |         ] | ||||||
|  |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
|  |         exc = self.assertRaises( | ||||||
|  |             exceptions.CommandError, | ||||||
|  |             self.cmd.take_action, | ||||||
|  |             parsed_args) | ||||||
|  |         self.assertIn( | ||||||
|  |             '--os-volume-api-version 3.12 or greater is required', | ||||||
|  |             str(exc)) | ||||||
|  |  | ||||||
|  |     def test_volume_summary_with_metadata(self): | ||||||
|  |         self.app.client_manager.volume.api_version = \ | ||||||
|  |             api_versions.APIVersion('3.36') | ||||||
|  |  | ||||||
|  |         combine_meta = {**self.mock_vol_1.metadata, **self.mock_vol_2.metadata} | ||||||
|  |         meta_dict = copy.deepcopy(self.return_dict) | ||||||
|  |         meta_dict['volume-summary']['metadata'] = combine_meta | ||||||
|  |         self.volumes_mock.summary.return_value = meta_dict | ||||||
|  |  | ||||||
|  |         new_cols = copy.deepcopy(self.columns) | ||||||
|  |         new_cols.extend(['Metadata']) | ||||||
|  |  | ||||||
|  |         arglist = [ | ||||||
|  |             '--all-projects', | ||||||
|  |         ] | ||||||
|  |         verifylist = [ | ||||||
|  |             ('all_projects', True), | ||||||
|  |         ] | ||||||
|  |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
|  |         columns, data = self.cmd.take_action(parsed_args) | ||||||
|  |  | ||||||
|  |         self.volumes_mock.summary.assert_called_once_with( | ||||||
|  |             all_tenants=True, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         self.assertEqual(new_cols, columns) | ||||||
|  |  | ||||||
|  |         datalist = ( | ||||||
|  |             2, | ||||||
|  |             self.mock_vol_1.size + self.mock_vol_2.size, | ||||||
|  |             format_columns.DictColumn(combine_meta)) | ||||||
|  |         self.assertCountEqual(datalist, tuple(data)) | ||||||
							
								
								
									
										81
									
								
								openstackclient/volume/v3/volume.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								openstackclient/volume/v3/volume.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | # | ||||||
|  | #   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. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | """Volume V3 Volume action implementations""" | ||||||
|  |  | ||||||
|  | import logging | ||||||
|  |  | ||||||
|  | from cinderclient import api_versions | ||||||
|  | from osc_lib.cli import format_columns | ||||||
|  | from osc_lib.command import command | ||||||
|  | from osc_lib import exceptions | ||||||
|  | from osc_lib import utils | ||||||
|  |  | ||||||
|  | from openstackclient.i18n import _ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | LOG = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class VolumeSummary(command.ShowOne): | ||||||
|  |     _description = _("Show a summary of all volumes in this deployment.") | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super().get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--all-projects', | ||||||
|  |             action='store_true', | ||||||
|  |             default=False, | ||||||
|  |             help=_('Include all projects (admin only)'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |  | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |  | ||||||
|  |         if volume_client.api_version < api_versions.APIVersion('3.12'): | ||||||
|  |             msg = _( | ||||||
|  |                 "--os-volume-api-version 3.12 or greater is required to " | ||||||
|  |                 "support the 'volume summary' command" | ||||||
|  |             ) | ||||||
|  |             raise exceptions.CommandError(msg) | ||||||
|  |  | ||||||
|  |         columns = [ | ||||||
|  |             'total_count', | ||||||
|  |             'total_size', | ||||||
|  |         ] | ||||||
|  |         column_headers = [ | ||||||
|  |             'Total Count', | ||||||
|  |             'Total Size', | ||||||
|  |         ] | ||||||
|  |         if volume_client.api_version.matches('3.36'): | ||||||
|  |             columns.append('metadata') | ||||||
|  |             column_headers.append('Metadata') | ||||||
|  |  | ||||||
|  |         # set value of 'all_tenants' when using project option | ||||||
|  |         all_projects = parsed_args.all_projects | ||||||
|  |  | ||||||
|  |         vol_summary = volume_client.volumes.summary( | ||||||
|  |             all_tenants=all_projects, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         return ( | ||||||
|  |             column_headers, | ||||||
|  |             utils.get_dict_properties( | ||||||
|  |                 vol_summary['volume-summary'], | ||||||
|  |                 columns, | ||||||
|  |                 formatters={'metadata': format_columns.DictColumn}, | ||||||
|  |             ), | ||||||
|  |         ) | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | --- | ||||||
|  | features: | ||||||
|  |   - | | ||||||
|  |     Added ``volume summary`` command to show the total size, | ||||||
|  |     total count and metadata of volumes. | ||||||
| @@ -819,3 +819,5 @@ openstack.volume.v3 = | |||||||
|     volume_transfer_request_delete = openstackclient.volume.v2.volume_transfer_request:DeleteTransferRequest |     volume_transfer_request_delete = openstackclient.volume.v2.volume_transfer_request:DeleteTransferRequest | ||||||
|     volume_transfer_request_list = openstackclient.volume.v2.volume_transfer_request:ListTransferRequest |     volume_transfer_request_list = openstackclient.volume.v2.volume_transfer_request:ListTransferRequest | ||||||
|     volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest |     volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest | ||||||
|  |  | ||||||
|  |     volume_summary = openstackclient.volume.v3.volume:VolumeSummary | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zuul
					Zuul