diff --git a/README.rst b/README.rst index 5c167b76a..663864bb1 100644 --- a/README.rst +++ b/README.rst @@ -122,6 +122,12 @@ You'll find complete documentation on the shell by running secgroup-list-rules List rules for a security group. show Show details about the given server. unrescue Unrescue a server. + volume-attach Attach a volume to a server. + volume-create Add a new volume. + volume-delete Remove a volume. + volume-detach Detach a volume from a server. + volume-list List all the volumes. + volume-show Show details about a volume. zone Show or edit a Child Zone zone-add Add a Child Zone. zone-boot Boot a server, considering Zones. diff --git a/novaclient/v1_1/client.py b/novaclient/v1_1/client.py index 81118c6c6..a46d6bbb8 100644 --- a/novaclient/v1_1/client.py +++ b/novaclient/v1_1/client.py @@ -7,6 +7,7 @@ from novaclient.v1_1 import security_group_rules from novaclient.v1_1 import security_groups from novaclient.v1_1 import servers from novaclient.v1_1 import quotas +from novaclient.v1_1 import volumes from novaclient.v1_1 import zones @@ -36,6 +37,7 @@ class Client(object): self.servers = servers.ServerManager(self) # extensions + self.volumes = volumes.VolumeManager(self) self.keypairs = keypairs.KeypairManager(self) self.zones = zones.ZoneManager(self) self.quotas = quotas.QuotaSetManager(self) diff --git a/novaclient/v1_1/shell.py b/novaclient/v1_1/shell.py index 2dbd2030a..ef9d3d3bd 100644 --- a/novaclient/v1_1/shell.py +++ b/novaclient/v1_1/shell.py @@ -705,6 +705,94 @@ def do_remove_fixed_ip(cs, args): server.remove_fixed_ip(args.address) +def _find_volume(cs, volume): + """Get a volume by ID.""" + return utils.find_resource(cs.volumes, volume) + + +def _print_volume(cs, volume): + utils.print_dict(volume._info) + + +def _translate_volume_keys(collection): + convert = [('displayName', 'display_name')] + for item in collection: + keys = item.__dict__.keys() + for from_key, to_key in convert: + if from_key in keys and to_key not in keys: + setattr(item, to_key, item._info[from_key]) + + +def do_volume_list(cs, args): + """List all the volumes.""" + volumes = cs.volumes.list() + _translate_volume_keys(volumes) + + # Create a list of servers to which the volume is attached + for vol in volumes: + servers = [server.get('serverId') for server in vol.attachments] + setattr(vol, 'attached_to', ','.join(map(str, servers))) + utils.print_list(volumes, ['ID', 'Status', 'Display Name', + 'Size', 'Attached to']) + + +@utils.arg('volume', metavar='<volume>', help='ID of the volume.') +def do_volume_show(cs, args): + """Show details about a volume.""" + volume = _find_volume(cs, args.volume) + _print_volume(cs, volume) + + +@utils.arg('size', + metavar='<size>', + type=int, + help='Size of volume in GB') +@utils.arg('--display_name', metavar='<display_name>', + help='Optional volume name. (Default=None)', + default=None) +@utils.arg('--display_description', metavar='<display_description>', + help='Optional volume description. (Default=None)', + default=None) +def do_volume_create(cs, args): + """Add a new volume.""" + cs.volumes.create(args.size, args.display_name, args.display_description) + + +@utils.arg('volume', metavar='<volume>', help='ID of the volume to delete.') +def do_volume_delete(cs, args): + """Remove a volume.""" + volume = _find_volume(cs, args.volume) + volume.delete() + + +@utils.arg('server', + metavar='<server>', + help='Name or ID of server.') +@utils.arg('volume', + metavar='<volume>', + type=int, + help='ID of the volume to attach.') +@utils.arg('device', metavar='<device>', + help='Name of the device e.g. /dev/vdb.') +def do_volume_attach(cs, args): + """Attach a volume to a server.""" + cs.volumes.create_server_volume(_find_server(cs, args.server).id, + args.volume, + args.device) + + +@utils.arg('server', + metavar='<server>', + help='Name or ID of server.') +@utils.arg('attachment_id', + metavar='<volume>', + type=int, + help='Attachment ID of the volume.') +def do_volume_detach(cs, args): + """Detach a volume from a server.""" + cs.volumes.delete_server_volume(_find_server(cs, args.server).id, + args.attachment_id) + def _print_floating_ip_list(floating_ips): utils.print_list(floating_ips, ['Ip', 'Instance Id', 'Fixed Ip'])