diff options
Diffstat (limited to 'openstackclient/volume')
| -rw-r--r-- | openstackclient/volume/v1/backup.py | 63 | ||||
| -rw-r--r-- | openstackclient/volume/v1/qos_specs.py | 16 | ||||
| -rw-r--r-- | openstackclient/volume/v1/service.py | 4 | ||||
| -rw-r--r-- | openstackclient/volume/v1/snapshot.py | 12 | ||||
| -rw-r--r-- | openstackclient/volume/v1/volume.py | 107 | ||||
| -rw-r--r-- | openstackclient/volume/v1/volume_transfer_request.py | 10 | ||||
| -rw-r--r-- | openstackclient/volume/v1/volume_type.py | 18 | ||||
| -rw-r--r-- | openstackclient/volume/v2/backup.py | 84 | ||||
| -rw-r--r-- | openstackclient/volume/v2/consistency_group.py | 145 | ||||
| -rw-r--r-- | openstackclient/volume/v2/consistency_group_snapshot.py | 190 | ||||
| -rw-r--r-- | openstackclient/volume/v2/qos_specs.py | 16 | ||||
| -rw-r--r-- | openstackclient/volume/v2/service.py | 4 | ||||
| -rw-r--r-- | openstackclient/volume/v2/snapshot.py | 12 | ||||
| -rw-r--r-- | openstackclient/volume/v2/volume.py | 114 | ||||
| -rw-r--r-- | openstackclient/volume/v2/volume_transfer_request.py | 10 | ||||
| -rw-r--r-- | openstackclient/volume/v2/volume_type.py | 21 |
16 files changed, 715 insertions, 111 deletions
diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/backup.py index c9d0ca0d..9ac1302a 100644 --- a/openstackclient/volume/v1/backup.py +++ b/openstackclient/volume/v1/backup.py @@ -30,7 +30,7 @@ LOG = logging.getLogger(__name__) class CreateVolumeBackup(command.ShowOne): - """Create new volume backup""" + _description = _("Create new volume backup") def get_parser(self, prog_name): parser = super(CreateVolumeBackup, self).get_parser(prog_name) @@ -73,7 +73,7 @@ class CreateVolumeBackup(command.ShowOne): class CreateBackup(CreateVolumeBackup): - """Create new backup""" + _description = _("Create new backup") # TODO(Huanxuan Ao): Remove this class and ``backup create`` command # two cycles after Newton. @@ -90,7 +90,7 @@ class CreateBackup(CreateVolumeBackup): class DeleteVolumeBackup(command.Command): - """Delete volume backup(s)""" + _description = _("Delete volume backup(s)") def get_parser(self, prog_name): parser = super(DeleteVolumeBackup, self).get_parser(prog_name) @@ -125,7 +125,7 @@ class DeleteVolumeBackup(command.Command): class DeleteBackup(DeleteVolumeBackup): - """Delete backup(s)""" + _description = _("Delete backup(s)") # TODO(Huanxuan Ao): Remove this class and ``backup delete`` command # two cycles after Newton. @@ -142,7 +142,7 @@ class DeleteBackup(DeleteVolumeBackup): class ListVolumeBackup(command.Lister): - """List volume backups""" + _description = _("List volume backups") def get_parser(self, prog_name): parser = super(ListVolumeBackup, self).get_parser(prog_name) @@ -152,9 +152,36 @@ class ListVolumeBackup(command.Lister): default=False, help=_('List additional fields in output'), ) + parser.add_argument( + "--name", + metavar="<name>", + help=_("Filters results by the backup name") + ) + parser.add_argument( + "--status", + metavar="<status>", + choices=['creating', 'available', 'deleting', + 'error', 'restoring', 'error_restoring'], + help=_("Filters results by the backup status " + "('creating', 'available', 'deleting', " + "'error', 'restoring' or 'error_restoring')") + ) + parser.add_argument( + "--volume", + metavar="<volume>", + help=_("Filters results by the volume which they " + "backup (name or ID)") + ) + 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 def _format_volume_id(volume_id): """Return a volume name if available @@ -180,13 +207,25 @@ class ListVolumeBackup(command.Lister): # Cache the volume list volume_cache = {} try: - for s in self.app.client_manager.volume.volumes.list(): + for s in volume_client.volumes.list(): volume_cache[s.id] = s except Exception: # Just forget it if there's any trouble pass - data = self.app.client_manager.volume.backups.list() + filter_volume_id = None + if parsed_args.volume: + filter_volume_id = utils.find_resource(volume_client.volumes, + parsed_args.volume).id + search_opts = { + 'name': parsed_args.name, + 'status': parsed_args.status, + 'volume_id': filter_volume_id, + 'all_tenants': parsed_args.all_projects, + } + data = volume_client.backups.list( + search_opts=search_opts, + ) return (column_headers, (utils.get_item_properties( @@ -196,7 +235,7 @@ class ListVolumeBackup(command.Lister): class ListBackup(ListVolumeBackup): - """List backups""" + _description = _("List backups") # TODO(Huanxuan Ao): Remove this class and ``backup list`` command # two cycles after Newton. @@ -213,7 +252,7 @@ class ListBackup(ListVolumeBackup): class RestoreVolumeBackup(command.Command): - """Restore volume backup""" + _description = _("Restore volume backup") def get_parser(self, prog_name): parser = super(RestoreVolumeBackup, self).get_parser(prog_name) @@ -240,7 +279,7 @@ class RestoreVolumeBackup(command.Command): class RestoreBackup(RestoreVolumeBackup): - """Restore backup""" + _description = _("Restore backup") # TODO(Huanxuan Ao): Remove this class and ``backup restore`` command # two cycles after Newton. @@ -257,7 +296,7 @@ class RestoreBackup(RestoreVolumeBackup): class ShowVolumeBackup(command.ShowOne): - """Display volume backup details""" + _description = _("Display volume backup details") def get_parser(self, prog_name): parser = super(ShowVolumeBackup, self).get_parser(prog_name) @@ -277,7 +316,7 @@ class ShowVolumeBackup(command.ShowOne): class ShowBackup(ShowVolumeBackup): - """Display backup details""" + _description = _("Display backup details") # TODO(Huanxuan Ao): Remove this class and ``backup show`` command # two cycles after Newton. diff --git a/openstackclient/volume/v1/qos_specs.py b/openstackclient/volume/v1/qos_specs.py index 93c24a21..b824b351 100644 --- a/openstackclient/volume/v1/qos_specs.py +++ b/openstackclient/volume/v1/qos_specs.py @@ -30,7 +30,7 @@ LOG = logging.getLogger(__name__) class AssociateQos(command.Command): - """Associate a QoS specification to a volume type""" + _description = _("Associate a QoS specification to a volume type") def get_parser(self, prog_name): parser = super(AssociateQos, self).get_parser(prog_name) @@ -57,7 +57,7 @@ class AssociateQos(command.Command): class CreateQos(command.ShowOne): - """Create new QoS specification""" + _description = _("Create new QoS specification") def get_parser(self, prog_name): parser = super(CreateQos, self).get_parser(prog_name) @@ -99,7 +99,7 @@ class CreateQos(command.ShowOne): class DeleteQos(command.Command): - """Delete QoS specification""" + _description = _("Delete QoS specification") def get_parser(self, prog_name): parser = super(DeleteQos, self).get_parser(prog_name) @@ -139,7 +139,7 @@ class DeleteQos(command.Command): class DisassociateQos(command.Command): - """Disassociate a QoS specification from a volume type""" + _description = _("Disassociate a QoS specification from a volume type") def get_parser(self, prog_name): parser = super(DisassociateQos, self).get_parser(prog_name) @@ -177,7 +177,7 @@ class DisassociateQos(command.Command): class ListQos(command.Lister): - """List QoS specifications""" + _description = _("List QoS specifications") def take_action(self, parsed_args): volume_client = self.app.client_manager.volume @@ -202,7 +202,7 @@ class ListQos(command.Lister): class SetQos(command.Command): - """Set QoS specification properties""" + _description = _("Set QoS specification properties") def get_parser(self, prog_name): parser = super(SetQos, self).get_parser(prog_name) @@ -231,7 +231,7 @@ class SetQos(command.Command): class ShowQos(command.ShowOne): - """Display QoS specification details""" + _description = _("Display QoS specification details") def get_parser(self, prog_name): parser = super(ShowQos, self).get_parser(prog_name) @@ -260,7 +260,7 @@ class ShowQos(command.ShowOne): class UnsetQos(command.Command): - """Unset QoS specification properties""" + _description = _("Unset QoS specification properties") def get_parser(self, prog_name): parser = super(UnsetQos, self).get_parser(prog_name) diff --git a/openstackclient/volume/v1/service.py b/openstackclient/volume/v1/service.py index 867c4b9c..d468c6ff 100644 --- a/openstackclient/volume/v1/service.py +++ b/openstackclient/volume/v1/service.py @@ -22,7 +22,7 @@ from openstackclient.i18n import _ class ListService(command.Lister): - """List service command""" + _description = _("List service command") def get_parser(self, prog_name): parser = super(ListService, self).get_parser(prog_name) @@ -76,7 +76,7 @@ class ListService(command.Lister): class SetService(command.Command): - """Set volume service properties""" + _description = _("Set volume service properties") def get_parser(self, prog_name): parser = super(SetService, self).get_parser(prog_name) diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py index 1c0c0bc7..e9e3894b 100644 --- a/openstackclient/volume/v1/snapshot.py +++ b/openstackclient/volume/v1/snapshot.py @@ -37,7 +37,7 @@ LOG = logging.getLogger(__name__) class CreateSnapshot(command.ShowOne): - """Create new snapshot""" + _description = _("Create new snapshot") def get_parser(self, prog_name): parser = super(CreateSnapshot, self).get_parser(prog_name) @@ -87,7 +87,7 @@ class CreateSnapshot(command.ShowOne): class DeleteSnapshot(command.Command): - """Delete snapshot(s)""" + _description = _("Delete snapshot(s)") def get_parser(self, prog_name): parser = super(DeleteSnapshot, self).get_parser(prog_name) @@ -124,7 +124,7 @@ class DeleteSnapshot(command.Command): class ListSnapshot(command.Lister): - """List snapshots""" + _description = _("List snapshots") def get_parser(self, prog_name): parser = super(ListSnapshot, self).get_parser(prog_name) @@ -197,7 +197,7 @@ class ListSnapshot(command.Lister): class SetSnapshot(command.Command): - """Set snapshot properties""" + _description = _("Set snapshot properties") def get_parser(self, prog_name): parser = super(SetSnapshot, self).get_parser(prog_name) @@ -260,7 +260,7 @@ class SetSnapshot(command.Command): class ShowSnapshot(command.ShowOne): - """Display snapshot details""" + _description = _("Display snapshot details") def get_parser(self, prog_name): parser = super(ShowSnapshot, self).get_parser(prog_name) @@ -286,7 +286,7 @@ class ShowSnapshot(command.ShowOne): class UnsetSnapshot(command.Command): - """Unset snapshot properties""" + _description = _("Unset snapshot properties") def get_parser(self, prog_name): parser = super(UnsetSnapshot, self).get_parser(prog_name) diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py index cafe8ce6..0087bad4 100644 --- a/openstackclient/volume/v1/volume.py +++ b/openstackclient/volume/v1/volume.py @@ -45,7 +45,7 @@ def _check_size_arg(args): class CreateVolume(command.ShowOne): - """Create new volume""" + _description = _("Create new volume") def get_parser(self, prog_name): parser = super(CreateVolume, self).get_parser(prog_name) @@ -178,7 +178,7 @@ class CreateVolume(command.ShowOne): class DeleteVolume(command.Command): - """Delete volume(s)""" + _description = _("Delete volume(s)") def get_parser(self, prog_name): parser = super(DeleteVolume, self).get_parser(prog_name) @@ -223,7 +223,7 @@ class DeleteVolume(command.Command): class ListVolume(command.Lister): - """List volumes""" + _description = _("List volumes") def get_parser(self, prog_name): parser = super(ListVolume, self).get_parser(prog_name) @@ -344,8 +344,39 @@ class ListVolume(command.Lister): ) for s in data)) +class MigrateVolume(command.Command): + _description = _("Migrate volume to a new host") + + def get_parser(self, prog_name): + parser = super(MigrateVolume, self).get_parser(prog_name) + parser.add_argument( + 'volume', + metavar="<volume>", + help=_("Volume to migrate (name or ID)") + ) + parser.add_argument( + '--host', + metavar="<host>", + required=True, + help=_("Destination host (takes the form: host@backend-name#pool)") + ) + parser.add_argument( + '--force-host-copy', + action="store_true", + help=_("Enable generic host-based force-migration, " + "which bypasses driver optimizations") + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + volume = utils.find_resource(volume_client.volumes, parsed_args.volume) + volume_client.volumes.migrate_volume(volume.id, parsed_args.host, + parsed_args.force_host_copy,) + + class SetVolume(command.Command): - """Set volume properties""" + _description = _("Set volume properties") def get_parser(self, prog_name): parser = super(SetVolume, self).get_parser(prog_name) @@ -388,42 +419,82 @@ class SetVolume(command.Command): action="store_true", help=_("Mark volume as non-bootable") ) + readonly_group = parser.add_mutually_exclusive_group() + readonly_group.add_argument( + "--read-only", + action="store_true", + help=_("Set volume to read-only access mode") + ) + readonly_group.add_argument( + "--read-write", + action="store_true", + help=_("Set volume to read-write access mode") + ) return parser def take_action(self, parsed_args): volume_client = self.app.client_manager.volume volume = utils.find_resource(volume_client.volumes, parsed_args.volume) + result = 0 if parsed_args.size: - if volume.status != 'available': - LOG.error(_("Volume is in %s state, it must be available " - "before size can be extended"), volume.status) - return - if parsed_args.size <= volume.size: - LOG.error(_("New size must be greater than %s GB"), - volume.size) - return - volume_client.volumes.extend(volume.id, parsed_args.size) - + try: + if volume.status != 'available': + msg = (_("Volume is in %s state, it must be available " + "before size can be extended") % volume.status) + raise exceptions.CommandError(msg) + if parsed_args.size <= volume.size: + msg = (_("New size must be greater than %s GB") + % volume.size) + raise exceptions.CommandError(msg) + volume_client.volumes.extend(volume.id, parsed_args.size) + except Exception as e: + LOG.error(_("Failed to set volume size: %s"), e) + result += 1 if parsed_args.property: - volume_client.volumes.set_metadata(volume.id, parsed_args.property) + try: + volume_client.volumes.set_metadata( + volume.id, + parsed_args.property) + except Exception as e: + LOG.error(_("Failed to set volume property: %s"), e) + result += 1 if parsed_args.bootable or parsed_args.non_bootable: try: volume_client.volumes.set_bootable( volume.id, parsed_args.bootable) except Exception as e: LOG.error(_("Failed to set volume bootable property: %s"), e) + result += 1 + if parsed_args.read_only or parsed_args.read_write: + try: + volume_client.volumes.update_readonly_flag( + volume.id, + parsed_args.read_only) + except Exception as e: + LOG.error(_("Failed to set volume read-only access " + "mode flag: %s"), e) + result += 1 kwargs = {} if parsed_args.name: kwargs['display_name'] = parsed_args.name if parsed_args.description: kwargs['display_description'] = parsed_args.description if kwargs: - volume_client.volumes.update(volume.id, **kwargs) + try: + volume_client.volumes.update(volume.id, **kwargs) + except Exception as e: + LOG.error(_("Failed to update volume display name " + "or display description: %s"), e) + result += 1 + + if result > 0: + raise exceptions.CommandError(_("One or more of the " + "set operations failed")) class ShowVolume(command.ShowOne): - """Show volume details""" + _description = _("Show volume details") def get_parser(self, prog_name): parser = super(ShowVolume, self).get_parser(prog_name) @@ -453,7 +524,7 @@ class ShowVolume(command.ShowOne): class UnsetVolume(command.Command): - """Unset volume properties""" + _description = _("Unset volume properties") def get_parser(self, prog_name): parser = super(UnsetVolume, self).get_parser(prog_name) diff --git a/openstackclient/volume/v1/volume_transfer_request.py b/openstackclient/volume/v1/volume_transfer_request.py index 4d6f2161..f24d5a56 100644 --- a/openstackclient/volume/v1/volume_transfer_request.py +++ b/openstackclient/volume/v1/volume_transfer_request.py @@ -28,7 +28,7 @@ LOG = logging.getLogger(__name__) class AcceptTransferRequest(command.ShowOne): - """Accept volume transfer request.""" + _description = _("Accept volume transfer request.") def get_parser(self, prog_name): parser = super(AcceptTransferRequest, self).get_parser(prog_name) @@ -56,7 +56,7 @@ class AcceptTransferRequest(command.ShowOne): class CreateTransferRequest(command.ShowOne): - """Create volume transfer request.""" + _description = _("Create volume transfer request.") def get_parser(self, prog_name): parser = super(CreateTransferRequest, self).get_parser(prog_name) @@ -85,7 +85,7 @@ class CreateTransferRequest(command.ShowOne): class DeleteTransferRequest(command.Command): - """Delete volume transfer request(s).""" + _description = _("Delete volume transfer request(s).") def get_parser(self, prog_name): parser = super(DeleteTransferRequest, self).get_parser(prog_name) @@ -120,7 +120,7 @@ class DeleteTransferRequest(command.Command): class ListTransferRequest(command.Lister): - """Lists all volume transfer requests.""" + _description = _("Lists all volume transfer requests.") def get_parser(self, prog_name): parser = super(ListTransferRequest, self).get_parser(prog_name) @@ -151,7 +151,7 @@ class ListTransferRequest(command.Lister): class ShowTransferRequest(command.ShowOne): - """Show volume transfer request details.""" + _description = _("Show volume transfer request details.") def get_parser(self, prog_name): parser = super(ShowTransferRequest, self).get_parser(prog_name) diff --git a/openstackclient/volume/v1/volume_type.py b/openstackclient/volume/v1/volume_type.py index 61e9f7fc..8adce322 100644 --- a/openstackclient/volume/v1/volume_type.py +++ b/openstackclient/volume/v1/volume_type.py @@ -30,7 +30,7 @@ LOG = logging.getLogger(__name__) class CreateVolumeType(command.ShowOne): - """Create new volume type""" + _description = _("Create new volume type") def get_parser(self, prog_name): parser = super(CreateVolumeType, self).get_parser(prog_name) @@ -61,7 +61,7 @@ class CreateVolumeType(command.ShowOne): class DeleteVolumeType(command.Command): - """Delete volume type(s)""" + _description = _("Delete volume type(s)") def get_parser(self, prog_name): parser = super(DeleteVolumeType, self).get_parser(prog_name) @@ -97,7 +97,7 @@ class DeleteVolumeType(command.Command): class ListVolumeType(command.Lister): - """List volume types""" + _description = _("List volume types") def get_parser(self, prog_name): parser = super(ListVolumeType, self).get_parser(prog_name) @@ -111,10 +111,10 @@ class ListVolumeType(command.Lister): def take_action(self, parsed_args): if parsed_args.long: - columns = ('ID', 'Name', 'Extra Specs') - column_headers = ('ID', 'Name', 'Properties') + columns = ('ID', 'Name', 'Is Public', 'Extra Specs') + column_headers = ('ID', 'Name', 'Is Public', 'Properties') else: - columns = ('ID', 'Name') + columns = ('ID', 'Name', 'Is Public') column_headers = columns data = self.app.client_manager.volume.volume_types.list() return (column_headers, @@ -125,7 +125,7 @@ class ListVolumeType(command.Lister): class SetVolumeType(command.Command): - """Set volume type properties""" + _description = _("Set volume type properties") def get_parser(self, prog_name): parser = super(SetVolumeType, self).get_parser(prog_name) @@ -153,7 +153,7 @@ class SetVolumeType(command.Command): class ShowVolumeType(command.ShowOne): - """Display volume type details""" + _description = _("Display volume type details") def get_parser(self, prog_name): parser = super(ShowVolumeType, self).get_parser(prog_name) @@ -175,7 +175,7 @@ class ShowVolumeType(command.ShowOne): class UnsetVolumeType(command.Command): - """Unset volume type properties""" + _description = _("Unset volume type properties") def get_parser(self, prog_name): parser = super(UnsetVolumeType, self).get_parser(prog_name) diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/backup.py index 2ca35b24..00389fcb 100644 --- a/openstackclient/volume/v2/backup.py +++ b/openstackclient/volume/v2/backup.py @@ -17,6 +17,7 @@ import copy import logging +from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils @@ -29,7 +30,7 @@ LOG = logging.getLogger(__name__) class CreateVolumeBackup(command.ShowOne): - """Create new volume backup""" + _description = _("Create new volume backup") def get_parser(self, prog_name): parser = super(CreateVolumeBackup, self).get_parser(prog_name) @@ -94,7 +95,7 @@ class CreateVolumeBackup(command.ShowOne): class CreateBackup(CreateVolumeBackup): - """Create new backup""" + _description = _("Create new backup") # TODO(Huanxuan Ao): Remove this class and ``backup create`` command # two cycles after Newton. @@ -111,7 +112,7 @@ class CreateBackup(CreateVolumeBackup): class DeleteVolumeBackup(command.Command): - """Delete volume backup(s)""" + _description = _("Delete volume backup(s)") def get_parser(self, prog_name): parser = super(DeleteVolumeBackup, self).get_parser(prog_name) @@ -152,7 +153,7 @@ class DeleteVolumeBackup(command.Command): class DeleteBackup(DeleteVolumeBackup): - """Delete backup(s)""" + _description = _("Delete backup(s)") # TODO(Huanxuan Ao): Remove this class and ``backup delete`` command # two cycles after Newton. @@ -169,7 +170,7 @@ class DeleteBackup(DeleteVolumeBackup): class ListVolumeBackup(command.Lister): - """List volume backups""" + _description = _("List volume backups") def get_parser(self, prog_name): parser = super(ListVolumeBackup, self).get_parser(prog_name) @@ -179,9 +180,48 @@ class ListVolumeBackup(command.Lister): default=False, help=_("List additional fields in output") ) + parser.add_argument( + "--name", + metavar="<name>", + help=_("Filters results by the backup name") + ) + parser.add_argument( + "--status", + metavar="<status>", + choices=['creating', 'available', 'deleting', + 'error', 'restoring', 'error_restoring'], + help=_("Filters results by the backup status " + "('creating', 'available', 'deleting', " + "'error', 'restoring' or 'error_restoring')") + ) + parser.add_argument( + "--volume", + metavar="<volume>", + help=_("Filters results by the volume which they " + "backup (name or ID)") + ) + parser.add_argument( + '--marker', + metavar='<marker>', + help=_('The last backup of the previous page (name or ID)'), + ) + parser.add_argument( + '--limit', + type=int, + action=parseractions.NonNegativeAction, + metavar='<limit>', + help=_('Maximum number of backups to display'), + ) + 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 def _format_volume_id(volume_id): """Return a volume name if available @@ -207,13 +247,31 @@ class ListVolumeBackup(command.Lister): # Cache the volume list volume_cache = {} try: - for s in self.app.client_manager.volume.volumes.list(): + for s in volume_client.volumes.list(): volume_cache[s.id] = s except Exception: # Just forget it if there's any trouble pass - data = self.app.client_manager.volume.backups.list() + filter_volume_id = None + if parsed_args.volume: + filter_volume_id = utils.find_resource(volume_client.volumes, + parsed_args.volume).id + marker_backup_id = None + if parsed_args.marker: + marker_backup_id = utils.find_resource(volume_client.backups, + parsed_args.marker).id + search_opts = { + 'name': parsed_args.name, + 'status': parsed_args.status, + 'volume_id': filter_volume_id, + 'all_tenants': parsed_args.all_projects, + } + data = volume_client.backups.list( + search_opts=search_opts, + marker=marker_backup_id, + limit=parsed_args.limit, + ) return (column_headers, (utils.get_item_properties( @@ -223,7 +281,7 @@ class ListVolumeBackup(command.Lister): class ListBackup(ListVolumeBackup): - """List backups""" + _description = _("List backups") # TODO(Huanxuan Ao): Remove this class and ``backup list`` command # two cycles after Newton. @@ -240,7 +298,7 @@ class ListBackup(ListVolumeBackup): class RestoreVolumeBackup(command.ShowOne): - """Restore volume backup""" + _description = _("Restore volume backup") def get_parser(self, prog_name): parser = super(RestoreVolumeBackup, self).get_parser(prog_name) @@ -265,7 +323,7 @@ class RestoreVolumeBackup(command.ShowOne): class RestoreBackup(RestoreVolumeBackup): - """Restore backup""" + _description = _("Restore backup") # TODO(Huanxuan Ao): Remove this class and ``backup restore`` command # two cycles after Newton. @@ -282,7 +340,7 @@ class RestoreBackup(RestoreVolumeBackup): class SetVolumeBackup(command.Command): - """Set volume backup properties""" + _description = _("Set volume backup properties") def get_parser(self, prog_name): parser = super(SetVolumeBackup, self).get_parser(prog_name) @@ -344,7 +402,7 @@ class SetVolumeBackup(command.Command): class ShowVolumeBackup(command.ShowOne): - """Display volume backup details""" + _description = _("Display volume backup details") def get_parser(self, prog_name): parser = super(ShowVolumeBackup, self).get_parser(prog_name) @@ -364,7 +422,7 @@ class ShowVolumeBackup(command.ShowOne): class ShowBackup(ShowVolumeBackup): - """Display backup details""" + _description = _("Display backup details") # TODO(Huanxuan Ao): Remove this class and ``backup show`` command # two cycles after Newton. diff --git a/openstackclient/volume/v2/consistency_group.py b/openstackclient/volume/v2/consistency_group.py index 39f2d577..661bcbe5 100644 --- a/openstackclient/volume/v2/consistency_group.py +++ b/openstackclient/volume/v2/consistency_group.py @@ -14,14 +14,137 @@ """Volume v2 consistency group action implementations""" +import logging + from osc_lib.command import command +from osc_lib import exceptions from osc_lib import utils +import six from openstackclient.i18n import _ +LOG = logging.getLogger(__name__) + + +class DeleteConsistencyGroup(command.Command): + _description = _("Delete consistency group(s).") + + def get_parser(self, prog_name): + parser = super(DeleteConsistencyGroup, self).get_parser(prog_name) + parser.add_argument( + 'consistency_groups', + metavar='<consistency-group>', + nargs="+", + help=_('Consistency group(s) to delete (name or ID)'), + ) + parser.add_argument( + '--force', + action='store_true', + default=False, + help=_("Allow delete in state other than error or available"), + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + result = 0 + + for i in parsed_args.consistency_groups: + try: + consistency_group_id = utils.find_resource( + volume_client.consistencygroups, i).id + volume_client.consistencygroups.delete( + consistency_group_id, parsed_args.force) + except Exception as e: + result += 1 + LOG.error(_("Failed to delete consistency group with " + "name or ID '%(consistency_group)s':%(e)s") + % {'consistency_group': i, 'e': e}) + + if result > 0: + total = len(parsed_args.consistency_groups) + msg = (_("%(result)s of %(total)s consistency groups failed " + "to delete.") % {'result': result, 'total': total}) + raise exceptions.CommandError(msg) + + +LOG = logging.getLogger(__name__) + + +class CreateConsistencyGroup(command.ShowOne): + _description = _("Create new consistency group.") + + def get_parser(self, prog_name): + parser = super(CreateConsistencyGroup, self).get_parser(prog_name) + parser.add_argument( + "name", + metavar="<name>", + nargs="?", + help=_("Name of new consistency group (default to None)") + ) + exclusive_group = parser.add_mutually_exclusive_group(required=True) + exclusive_group.add_argument( + "--volume-type", + metavar="<volume-type>", + help=_("Volume type of this consistency group (name or ID)") + ) + exclusive_group.add_argument( + "--consistency-group-source", + metavar="<consistency-group>", + help=_("Existing consistency group (name or ID)") + ) + parser.add_argument( + "--description", + metavar="<description>", + help=_("Description of this consistency group") + ) + parser.add_argument( + "--availability-zone", + metavar="<availability-zone>", + help=_("Availability zone for this consistency group " + "(not available if creating consistency group " + "from source)"), + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + if parsed_args.volume_type: + volume_type_id = utils.find_resource( + volume_client.volume_types, + parsed_args.volume_type).id + consistency_group = volume_client.consistencygroups.create( + volume_type_id, + name=parsed_args.name, + description=parsed_args.description, + availability_zone=parsed_args.availability_zone + ) + elif parsed_args.consistency_group_source: + if parsed_args.availability_zone: + msg = _("'--availability-zone' option will not work " + "if creating consistency group from source") + LOG.warning(msg) + consistency_group_id = utils.find_resource( + volume_client.consistencygroups, + parsed_args.consistency_group_source).id + consistency_group_snapshot = None + # TODO(Huanxuan Ao): Support for creating from consistency group + # snapshot after adding "consistency_group_snapshot" resource + consistency_group = ( + volume_client.consistencygroups.create_from_src( + consistency_group_snapshot, + consistency_group_id, + name=parsed_args.name, + description=parsed_args.description + ) + ) + + return zip(*sorted(six.iteritems(consistency_group._info))) + + class ListConsistencyGroup(command.Lister): - """List consistency groups.""" + _description = _("List consistency groups.") def get_parser(self, prog_name): parser = super(ListConsistencyGroup, self).get_parser(prog_name) @@ -55,3 +178,23 @@ class ListConsistencyGroup(command.Lister): s, columns, formatters={'Volume Types': utils.format_list}) for s in consistency_groups)) + + +class ShowConsistencyGroup(command.ShowOne): + _description = _("Display consistency group details.") + + def get_parser(self, prog_name): + parser = super(ShowConsistencyGroup, self).get_parser(prog_name) + parser.add_argument( + "consistency_group", + metavar="<consistency-group>", + help=_("Consistency group to display (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + consistency_group = utils.find_resource( + volume_client.consistencygroups, + parsed_args.consistency_group) + return zip(*sorted(six.iteritems(consistency_group._info))) diff --git a/openstackclient/volume/v2/consistency_group_snapshot.py b/openstackclient/volume/v2/consistency_group_snapshot.py new file mode 100644 index 00000000..540deb01 --- /dev/null +++ b/openstackclient/volume/v2/consistency_group_snapshot.py @@ -0,0 +1,190 @@ +# +# 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 v2 consistency group snapshot action implementations""" + +import logging + +from osc_lib.command import command +from osc_lib import exceptions +from osc_lib import utils +import six + +from openstackclient.i18n import _ + + +LOG = logging.getLogger(__name__) + + +class CreateConsistencyGroupSnapshot(command.ShowOne): + _description = _("Create new consistency group snapshot.") + + def get_parser(self, prog_name): + parser = super( + CreateConsistencyGroupSnapshot, self).get_parser(prog_name) + parser.add_argument( + "snapshot_name", + metavar="<snapshot-name>", + nargs="?", + help=_("Name of new consistency group snapshot (default to None)") + ) + parser.add_argument( + "--consistency-group", + metavar="<consistency-group>", + help=_("Consistency group to snapshot (name or ID) " + "(default to be the same as <snapshot-name>)") + ) + parser.add_argument( + "--description", + metavar="<description>", + help=_("Description of this consistency group snapshot") + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + consistency_group = parsed_args.consistency_group + if not parsed_args.consistency_group: + # If "--consistency-group" not specified, then consistency_group + # will be the same as the new consistency group snapshot name + consistency_group = parsed_args.snapshot_name + consistency_group_id = utils.find_resource( + volume_client.consistencygroups, + consistency_group).id + consistency_group_snapshot = volume_client.cgsnapshots.create( + consistency_group_id, + name=parsed_args.snapshot_name, + description=parsed_args.description, + ) + + return zip(*sorted(six.iteritems(consistency_group_snapshot._info))) + + +class DeleteConsistencyGroupSnapshot(command.Command): + _description = _("Delete consistency group snapshot(s).") + + def get_parser(self, prog_name): + parser = super( + DeleteConsistencyGroupSnapshot, self).get_parser(prog_name) + parser.add_argument( + "consistency_group_snapshot", + metavar="<consistency-group-snapshot>", + nargs="+", + help=_("Consistency group snapshot(s) to delete (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + result = 0 + + for snapshot in parsed_args.consistency_group_snapshot: + try: + snapshot_id = utils.find_resource(volume_client.cgsnapshots, + snapshot).id + + volume_client.cgsnapshots.delete(snapshot_id) + except Exception as e: + result += 1 + LOG.error(_("Failed to delete consistency group snapshot " + "with name or ID '%(snapshot)s': %(e)s") + % {'snapshot': snapshot, 'e': e}) + + if result > 0: + total = len(parsed_args.consistency_group_snapshot) + msg = (_("%(result)s of %(total)s consistency group snapshots " + "failed to delete.") % {'result': result, 'total': total}) + raise exceptions.CommandError(msg) + + +class ListConsistencyGroupSnapshot(command.Lister): + _description = _("List consistency group snapshots.") + + def get_parser(self, prog_name): + parser = super( + ListConsistencyGroupSnapshot, self).get_parser(prog_name) + parser.add_argument( + '--all-projects', + action="store_true", + help=_('Show detail for all projects (admin only) ' + '(defaults to False)') + ) + parser.add_argument( + '--long', + action="store_true", + help=_('List additional fields in output') + ) + parser.add_argument( + '--status', + metavar="<status>", + choices=['available', 'error', 'creating', 'deleting', + 'error-deleting'], + help=_('Filters results by a status ("available", "error", ' + '"creating", "deleting" or "error_deleting")') + ) + parser.add_argument( + '--consistency-group', + metavar="<consistency-group>", + help=_('Filters results by a consistency group (name or ID)') + ) + return parser + + def take_action(self, parsed_args): + if parsed_args.long: + columns = ['ID', 'Status', 'ConsistencyGroup ID', + 'Name', 'Description', 'Created At'] + else: + columns = ['ID', 'Status', 'Name'] + volume_client = self.app.client_manager.volume + consistency_group_id = None + if parsed_args.consistency_group: + consistency_group_id = utils.find_resource( + volume_client.consistencygroups, + parsed_args.consistency_group, + ).id + search_opts = { + 'all_tenants': parsed_args.all_projects, + 'status': parsed_args.status, + 'consistencygroup_id': consistency_group_id, + } + consistency_group_snapshots = volume_client.cgsnapshots.list( + detailed=True, + search_opts=search_opts, + ) + + return (columns, ( + utils.get_item_properties( + s, columns) + for s in consistency_group_snapshots)) + + +class ShowConsistencyGroupSnapshot(command.ShowOne): + _description = _("Display consistency group snapshot details") + + def get_parser(self, prog_name): + parser = super( + ShowConsistencyGroupSnapshot, self).get_parser(prog_name) + parser.add_argument( + "consistency_group_snapshot", + metavar="<consistency-group-snapshot>", + help=_("Consistency group snapshot to display (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + consistency_group_snapshot = utils.find_resource( + volume_client.cgsnapshots, + parsed_args.consistency_group_snapshot) + return zip(*sorted(six.iteritems(consistency_group_snapshot._info))) diff --git a/openstackclient/volume/v2/qos_specs.py b/openstackclient/volume/v2/qos_specs.py index 9797f1a6..b7f49eca 100644 --- a/openstackclient/volume/v2/qos_specs.py +++ b/openstackclient/volume/v2/qos_specs.py @@ -30,7 +30,7 @@ LOG = logging.getLogger(__name__) class AssociateQos(command.Command): - """Associate a QoS specification to a volume type""" + _description = _("Associate a QoS specification to a volume type") def get_parser(self, prog_name): parser = super(AssociateQos, self).get_parser(prog_name) @@ -57,7 +57,7 @@ class AssociateQos(command.Command): class CreateQos(command.ShowOne): - """Create new QoS specification""" + _description = _("Create new QoS specification") def get_parser(self, prog_name): parser = super(CreateQos, self).get_parser(prog_name) @@ -99,7 +99,7 @@ class CreateQos(command.ShowOne): class DeleteQos(command.Command): - """Delete QoS specification""" + _description = _("Delete QoS specification") def get_parser(self, prog_name): parser = super(DeleteQos, self).get_parser(prog_name) @@ -139,7 +139,7 @@ class DeleteQos(command.Command): class DisassociateQos(command.Command): - """Disassociate a QoS specification from a volume type""" + _description = _("Disassociate a QoS specification from a volume type") def get_parser(self, prog_name): parser = super(DisassociateQos, self).get_parser(prog_name) @@ -177,7 +177,7 @@ class DisassociateQos(command.Command): class ListQos(command.Lister): - """List QoS specifications""" + _description = _("List QoS specifications") def take_action(self, parsed_args): volume_client = self.app.client_manager.volume @@ -202,7 +202,7 @@ class ListQos(command.Lister): class SetQos(command.Command): - """Set QoS specification properties""" + _description = _("Set QoS specification properties") def get_parser(self, prog_name): parser = super(SetQos, self).get_parser(prog_name) @@ -231,7 +231,7 @@ class SetQos(command.Command): class ShowQos(command.ShowOne): - """Display QoS specification details""" + _description = _("Display QoS specification details") def get_parser(self, prog_name): parser = super(ShowQos, self).get_parser(prog_name) @@ -260,7 +260,7 @@ class ShowQos(command.ShowOne): class UnsetQos(command.Command): - """Unset QoS specification properties""" + _description = _("Unset QoS specification properties") def get_parser(self, prog_name): parser = super(UnsetQos, self).get_parser(prog_name) diff --git a/openstackclient/volume/v2/service.py b/openstackclient/volume/v2/service.py index 867c4b9c..d468c6ff 100644 --- a/openstackclient/volume/v2/service.py +++ b/openstackclient/volume/v2/service.py @@ -22,7 +22,7 @@ from openstackclient.i18n import _ class ListService(command.Lister): - """List service command""" + _description = _("List service command") def get_parser(self, prog_name): parser = super(ListService, self).get_parser(prog_name) @@ -76,7 +76,7 @@ class ListService(command.Lister): class SetService(command.Command): - """Set volume service properties""" + _description = _("Set volume service properties") def get_parser(self, prog_name): parser = super(SetService, self).get_parser(prog_name) diff --git a/openstackclient/volume/v2/snapshot.py b/openstackclient/volume/v2/snapshot.py index 2f3de211..a18887e3 100644 --- a/openstackclient/volume/v2/snapshot.py +++ b/openstackclient/volume/v2/snapshot.py @@ -36,7 +36,7 @@ LOG = logging.getLogger(__name__) class CreateSnapshot(command.ShowOne): - """Create new snapshot""" + _description = _("Create new snapshot") def get_parser(self, prog_name): parser = super(CreateSnapshot, self).get_parser(prog_name) @@ -91,7 +91,7 @@ class CreateSnapshot(command.ShowOne): class DeleteSnapshot(command.Command): - """Delete volume snapshot(s)""" + _description = _("Delete volume snapshot(s)") def get_parser(self, prog_name): parser = super(DeleteSnapshot, self).get_parser(prog_name) @@ -128,7 +128,7 @@ class DeleteSnapshot(command.Command): class ListSnapshot(command.Lister): - """List snapshots""" + _description = _("List snapshots") def get_parser(self, prog_name): parser = super(ListSnapshot, self).get_parser(prog_name) @@ -211,7 +211,7 @@ class ListSnapshot(command.Lister): class SetSnapshot(command.Command): - """Set snapshot properties""" + _description = _("Set snapshot properties") def get_parser(self, prog_name): parser = super(SetSnapshot, self).get_parser(prog_name) @@ -294,7 +294,7 @@ class SetSnapshot(command.Command): class ShowSnapshot(command.ShowOne): - """Display snapshot details""" + _description = _("Display snapshot details") def get_parser(self, prog_name): parser = super(ShowSnapshot, self).get_parser(prog_name) @@ -318,7 +318,7 @@ class ShowSnapshot(command.ShowOne): class UnsetSnapshot(command.Command): - """Unset snapshot properties""" + _description = _("Unset snapshot properties") def get_parser(self, prog_name): parser = super(UnsetSnapshot, self).get_parser(prog_name) diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py index cb409711..80abfb55 100644 --- a/openstackclient/volume/v2/volume.py +++ b/openstackclient/volume/v2/volume.py @@ -45,7 +45,7 @@ def _check_size_arg(args): class CreateVolume(command.ShowOne): - """Create new volume""" + _description = _("Create new volume") def get_parser(self, prog_name): parser = super(CreateVolume, self).get_parser(prog_name) @@ -211,7 +211,7 @@ class CreateVolume(command.ShowOne): class DeleteVolume(command.Command): - """Delete volume(s)""" + _description = _("Delete volume(s)") def get_parser(self, prog_name): parser = super(DeleteVolume, self).get_parser(prog_name) @@ -263,7 +263,7 @@ class DeleteVolume(command.Command): class ListVolume(command.Lister): - """List volumes""" + _description = _("List volumes") def get_parser(self, prog_name): parser = super(ListVolume, self).get_parser(prog_name) @@ -409,8 +409,55 @@ class ListVolume(command.Lister): ) for s in data)) +class MigrateVolume(command.Command): + _description = _("Migrate volume to a new host") + + def get_parser(self, prog_name): + parser = super(MigrateVolume, self).get_parser(prog_name) + parser.add_argument( + 'volume', + metavar="<volume>", + help=_("Volume to migrate (name or ID)") + ) + parser.add_argument( + '--host', + metavar="<host>", + required=True, + help=_("Destination host (takes the form: host@backend-name#pool)") + ) + parser.add_argument( + '--force-host-copy', + action="store_true", + help=_("Enable generic host-based force-migration, " + "which bypasses driver optimizations") + ) + lock_group = parser.add_mutually_exclusive_group() + lock_group.add_argument( + '--lock-volume', + action="store_true", + help=_("If specified, the volume state will be locked " + "and will not allow a migration to be aborted " + "(possibly by another operation)") + ) + lock_group.add_argument( + '--unlock-volume', + action="store_true", + help=_("If specified, the volume state will not be " + "locked and the a migration can be aborted " + "(default) (possibly by another operation)") + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + volume = utils.find_resource(volume_client.volumes, parsed_args.volume) + volume_client.volumes.migrate_volume(volume.id, parsed_args.host, + parsed_args.force_host_copy, + parsed_args.lock_volume,) + + class SetVolume(command.Command): - """Set volume properties""" + _description = _("Set volume properties") def get_parser(self, prog_name): parser = super(SetVolume, self).get_parser(prog_name) @@ -462,6 +509,19 @@ class SetVolume(command.Command): 'in the database with no regard to actual status, ' 'exercise caution when using)'), ) + parser.add_argument( + '--type', + metavar='<volume-type>', + help=_('New volume type (name or ID)'), + ) + parser.add_argument( + '--retype-policy', + metavar='<retype-policy>', + choices=['never', 'on-demand'], + help=_('Migration policy while re-typing volume ' + '("never" or "on-demand", default is "never" ) ' + '(available only when "--type" option is specified)'), + ) bootable_group = parser.add_mutually_exclusive_group() bootable_group.add_argument( "--bootable", @@ -473,6 +533,17 @@ class SetVolume(command.Command): action="store_true", help=_("Mark volume as non-bootable") ) + readonly_group = parser.add_mutually_exclusive_group() + readonly_group.add_argument( + "--read-only", + action="store_true", + help=_("Set volume to read-only access mode") + ) + readonly_group.add_argument( + "--read-write", + action="store_true", + help=_("Set volume to read-write access mode") + ) return parser def take_action(self, parsed_args): @@ -523,6 +594,37 @@ class SetVolume(command.Command): except Exception as e: LOG.error(_("Failed to set volume bootable property: %s"), e) result += 1 + if parsed_args.read_only or parsed_args.read_write: + try: + volume_client.volumes.update_readonly_flag( + volume.id, + parsed_args.read_only) + except Exception as e: + LOG.error(_("Failed to set volume read-only access " + "mode flag: %s"), e) + result += 1 + if parsed_args.type: + # get the migration policy + migration_policy = 'never' + if parsed_args.retype_policy: + migration_policy = parsed_args.retype_policy + try: + # find the volume type + volume_type = utils.find_resource( + volume_client.volume_types, + parsed_args.type) + # reset to the new volume type + volume_client.volumes.retype( + volume.id, + volume_type.id, + migration_policy) + except Exception as e: + LOG.error(_("Failed to set volume type: %s"), e) + result += 1 + elif parsed_args.retype_policy: + # If the "--retype-policy" is specified without "--type" + LOG.warning(_("'--retype-policy' option will not work " + "without '--type' option")) kwargs = {} if parsed_args.name: @@ -543,7 +645,7 @@ class SetVolume(command.Command): class ShowVolume(command.ShowOne): - """Display volume details""" + _description = _("Display volume details") def get_parser(self, prog_name): parser = super(ShowVolume, self).get_parser(prog_name) @@ -574,7 +676,7 @@ class ShowVolume(command.ShowOne): class UnsetVolume(command.Command): - """Unset volume properties""" + _description = _("Unset volume properties") def get_parser(self, prog_name): parser = super(UnsetVolume, self).get_parser(prog_name) diff --git a/openstackclient/volume/v2/volume_transfer_request.py b/openstackclient/volume/v2/volume_transfer_request.py index 9008fe3c..aefe594a 100644 --- a/openstackclient/volume/v2/volume_transfer_request.py +++ b/openstackclient/volume/v2/volume_transfer_request.py @@ -28,7 +28,7 @@ LOG = logging.getLogger(__name__) class AcceptTransferRequest(command.ShowOne): - """Accept volume transfer request.""" + _description = _("Accept volume transfer request.") def get_parser(self, prog_name): parser = super(AcceptTransferRequest, self).get_parser(prog_name) @@ -56,7 +56,7 @@ class AcceptTransferRequest(command.ShowOne): class CreateTransferRequest(command.ShowOne): - """Create volume transfer request.""" + _description = _("Create volume transfer request.") def get_parser(self, prog_name): parser = super(CreateTransferRequest, self).get_parser(prog_name) @@ -85,7 +85,7 @@ class CreateTransferRequest(command.ShowOne): class DeleteTransferRequest(command.Command): - """Delete volume transfer request(s).""" + _description = _("Delete volume transfer request(s).") def get_parser(self, prog_name): parser = super(DeleteTransferRequest, self).get_parser(prog_name) @@ -120,7 +120,7 @@ class DeleteTransferRequest(command.Command): class ListTransferRequest(command.Lister): - """Lists all volume transfer requests.""" + _description = _("Lists all volume transfer requests.") def get_parser(self, prog_name): parser = super(ListTransferRequest, self).get_parser(prog_name) @@ -151,7 +151,7 @@ class ListTransferRequest(command.Lister): class ShowTransferRequest(command.ShowOne): - """Show volume transfer request details.""" + _description = _("Show volume transfer request details.") def get_parser(self, prog_name): parser = super(ShowTransferRequest, self).get_parser(prog_name) diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py index 80a1f21b..42ebb53e 100644 --- a/openstackclient/volume/v2/volume_type.py +++ b/openstackclient/volume/v2/volume_type.py @@ -30,7 +30,7 @@ LOG = logging.getLogger(__name__) class CreateVolumeType(command.ShowOne): - """Create new volume type""" + _description = _("Create new volume type") def get_parser(self, prog_name): parser = super(CreateVolumeType, self).get_parser(prog_name) @@ -116,7 +116,7 @@ class CreateVolumeType(command.ShowOne): class DeleteVolumeType(command.Command): - """Delete volume type(s)""" + _description = _("Delete volume type(s)") def get_parser(self, prog_name): parser = super(DeleteVolumeType, self).get_parser(prog_name) @@ -152,7 +152,7 @@ class DeleteVolumeType(command.Command): class ListVolumeType(command.Lister): - """List volume types""" + _description = _("List volume types") def get_parser(self, prog_name): parser = super(ListVolumeType, self).get_parser(prog_name) @@ -176,10 +176,11 @@ class ListVolumeType(command.Lister): def take_action(self, parsed_args): if parsed_args.long: - columns = ['ID', 'Name', 'Description', 'Extra Specs'] - column_headers = ['ID', 'Name', 'Description', 'Properties'] + columns = ['ID', 'Name', 'Is Public', 'Description', 'Extra Specs'] + column_headers = [ + 'ID', 'Name', 'Is Public', 'Description', 'Properties'] else: - columns = ['ID', 'Name'] + columns = ['ID', 'Name', 'Is Public'] column_headers = columns is_public = None @@ -197,7 +198,7 @@ class ListVolumeType(command.Lister): class SetVolumeType(command.Command): - """Set volume type properties""" + _description = _("Set volume type properties") def get_parser(self, prog_name): parser = super(SetVolumeType, self).get_parser(prog_name) @@ -213,7 +214,7 @@ class SetVolumeType(command.Command): ) parser.add_argument( '--description', - metavar='<name>', + metavar='<description>', help=_('Set volume type description'), ) parser.add_argument( @@ -286,7 +287,7 @@ class SetVolumeType(command.Command): class ShowVolumeType(command.ShowOne): - """Display volume type details""" + _description = _("Display volume type details") def get_parser(self, prog_name): parser = super(ShowVolumeType, self).get_parser(prog_name) @@ -324,7 +325,7 @@ class ShowVolumeType(command.ShowOne): class UnsetVolumeType(command.Command): - """Unset volume type properties""" + _description = _("Unset volume type properties") def get_parser(self, prog_name): parser = super(UnsetVolumeType, self).get_parser(prog_name) |
