diff options
Diffstat (limited to 'openstackclient/volume')
| -rw-r--r-- | openstackclient/volume/v2/volume.py | 109 | ||||
| -rw-r--r-- | openstackclient/volume/v2/volume_type.py | 94 |
2 files changed, 203 insertions, 0 deletions
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py index d4536f51..fe4a3ff6 100644 --- a/openstackclient/volume/v2/volume.py +++ b/openstackclient/volume/v2/volume.py @@ -14,9 +14,12 @@ """Volume V2 Volume action implementations""" +import copy import logging +import os from cliff import command +from cliff import lister from cliff import show import six @@ -189,6 +192,112 @@ class DeleteVolume(command.Command): return +class ListVolume(lister.Lister): + """List volumes""" + + log = logging.getLogger(__name__ + '.ListVolume') + + def get_parser(self, prog_name): + parser = super(ListVolume, self).get_parser(prog_name) + parser.add_argument( + '--all-projects', + action='store_true', + default=bool(int(os.environ.get("ALL_PROJECTS", 0))), + help='Include all projects (admin only)', + ) + parser.add_argument( + '--long', + action='store_true', + default=False, + help='List additional fields in output', + ) + parser.add_argument( + '--name', + metavar='<name>', + help='Filter results by name', + ) + parser.add_argument( + '--status', + metavar='<status>', + help='Filter results by status', + ) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)', parsed_args) + + volume_client = self.app.client_manager.volume + compute_client = self.app.client_manager.compute + + def _format_attach(attachments): + """Return a formatted string of a volume's attached instances + + :param volume: a volume.attachments field + :rtype: a string of formatted instances + """ + + msg = '' + for attachment in attachments: + server = attachment['id'] + if server in server_cache: + server = server_cache[server].name + device = attachment['device'] + msg += 'Attached to %s on %s ' % (server, device) + return msg + + if parsed_args.long: + columns = [ + 'ID', + 'Name', + 'Status', + 'Size', + 'Volume Type', + 'Bootable', + 'Attachments', + 'Metadata', + ] + column_headers = copy.deepcopy(columns) + column_headers[1] = 'Display Name' + column_headers[4] = 'Type' + column_headers[6] = 'Attached to' + column_headers[7] = 'Properties' + else: + columns = [ + 'ID', + 'Name', + 'Status', + 'Size', + 'Attachments', + ] + column_headers = copy.deepcopy(columns) + column_headers[1] = 'Display Name' + column_headers[4] = 'Attached to' + + # Cache the server list + server_cache = {} + try: + for s in compute_client.servers.list(): + server_cache[s.id] = s + except Exception: + # Just forget it if there's any trouble + pass + + search_opts = { + 'all_projects': parsed_args.all_projects, + 'display_name': parsed_args.name, + 'status': parsed_args.status, + } + + data = volume_client.volumes.list(search_opts=search_opts) + + return (column_headers, + (utils.get_item_properties( + s, columns, + formatters={'Metadata': utils.format_dict, + 'Attachments': _format_attach}, + ) for s in data)) + + class SetVolume(show.ShowOne): """Set volume properties""" diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py index 7f9a1c4b..fb0342c5 100644 --- a/openstackclient/volume/v2/volume_type.py +++ b/openstackclient/volume/v2/volume_type.py @@ -143,6 +143,67 @@ class ListVolumeType(lister.Lister): ) for s in data)) +class SetVolumeType(command.Command): + """Set volume type properties""" + + log = logging.getLogger(__name__ + '.SetVolumeType') + + def get_parser(self, prog_name): + parser = super(SetVolumeType, self).get_parser(prog_name) + parser.add_argument( + 'volume_type', + metavar='<volume-type>', + help='Volume type to modify (name or ID)', + ) + parser.add_argument( + '--name', + metavar='<name>', + help='Set volume type name', + ) + parser.add_argument( + '--description', + metavar='<name>', + help='Set volume type description', + ) + parser.add_argument( + '--property', + metavar='<key=value>', + action=parseractions.KeyValueAction, + help='Property to add or modify for this volume type ' + '(repeat option to set multiple properties)', + ) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)', parsed_args) + volume_client = self.app.client_manager.volume + volume_type = utils.find_resource( + volume_client.volume_types, parsed_args.volume_type) + + if (not parsed_args.name + and not parsed_args.description + and not parsed_args.property): + self.app.log.error("No changes requested\n") + return + + kwargs = {} + if parsed_args.name: + kwargs['name'] = parsed_args.name + if parsed_args.description: + kwargs['description'] = parsed_args.description + + if kwargs: + volume_client.volume_types.update( + volume_type.id, + **kwargs + ) + + if parsed_args.property: + volume_type.set_keys(parsed_args.property) + + return + + class ShowVolumeType(show.ShowOne): """Display volume type details""" @@ -165,3 +226,36 @@ class ShowVolumeType(show.ShowOne): properties = utils.format_dict(volume_type._info.pop('extra_specs')) volume_type._info.update({'properties': properties}) return zip(*sorted(six.iteritems(volume_type._info))) + + +class UnsetVolumeType(command.Command): + """Unset volume type properties""" + + log = logging.getLogger(__name__ + '.UnsetVolumeType') + + def get_parser(self, prog_name): + parser = super(UnsetVolumeType, self).get_parser(prog_name) + parser.add_argument( + 'volume_type', + metavar='<volume-type>', + help='Volume type to modify (name or ID)', + ) + parser.add_argument( + '--property', + metavar='<key>', + default=[], + required=True, + help='Property to remove from volume type ' + '(repeat option to remove multiple properties)', + ) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)', parsed_args) + volume_client = self.app.client_manager.volume + volume_type = utils.find_resource( + volume_client.volume_types, + parsed_args.volume_type, + ) + volume_type.unset_keys(parsed_args.property) + return |
