diff --git a/novaclient/shell.py b/novaclient/shell.py index 9642645d3..c2f94164e 100644 --- a/novaclient/shell.py +++ b/novaclient/shell.py @@ -25,7 +25,7 @@ import os import prettytable import sys -from novaclient import exceptions +from novaclient import exceptions as exc from novaclient import utils from novaclient.v1_0 import shell as shell_v1_0 from novaclient.v1_1 import shell as shell_v1_1 @@ -151,18 +151,21 @@ class OpenStackComputeShell(object): # for username or apikey but for compatibility it is not. if not user: - raise exceptions.CommandError("You must provide a username, either via " - "--username or via env[NOVA_USERNAME]") + raise exc.CommandError("You must provide a username, either" + "via --username or via " + "env[NOVA_USERNAME]") if not apikey: - raise exceptions.CommandError("You must provide an API key, either via " - "--apikey or via env[NOVA_API_KEY]") + raise exc.CommandError("You must provide an API key, either" + "via --apikey or via" + "env[NOVA_API_KEY]") - self.cs = self.get_api_class(options.version)(user, apikey, projectid, url) + self.cs = self.get_api_class(options.version)(user, apikey, projectid, + url) try: self.cs.authenticate() - except exceptions.Unauthorized: - raise exceptions.CommandError("Invalid OpenStack Nova credentials.") + except exc.Unauthorized: + raise exc.CommandError("Invalid OpenStack Nova credentials.") args.func(self.cs, args) @@ -185,8 +188,8 @@ class OpenStackComputeShell(object): if args.command in self.subcommands: self.subcommands[args.command].print_help() else: - raise exceptions.CommandError("'%s' is not a valid subcommand." % - args.command) + raise exc.CommandError("'%s' is not a valid subcommand" % + args.command) else: self.parser.print_help() diff --git a/novaclient/v1_0/accounts.py b/novaclient/v1_0/accounts.py index 966afa54b..be162d9bf 100644 --- a/novaclient/v1_0/accounts.py +++ b/novaclient/v1_0/accounts.py @@ -3,7 +3,6 @@ from novaclient import base from novaclient.v1_0 import base as local_base - class Account(base.Resource): pass diff --git a/novaclient/v1_0/client.py b/novaclient/v1_0/client.py index f7e203fae..37bb50a4c 100644 --- a/novaclient/v1_0/client.py +++ b/novaclient/v1_0/client.py @@ -1,5 +1,3 @@ - - from novaclient import client from novaclient.v1_0 import accounts from novaclient.v1_0 import backup_schedules @@ -10,7 +8,6 @@ from novaclient.v1_0 import servers from novaclient.v1_0 import zones - class Client(object): """ Top-level object to access the OpenStack Compute API. diff --git a/novaclient/v1_0/shell.py b/novaclient/v1_0/shell.py index 748a6a338..196ec26bc 100644 --- a/novaclient/v1_0/shell.py +++ b/novaclient/v1_0/shell.py @@ -76,6 +76,7 @@ def do_backup_schedule(cs, args): else: utils.print_dict(server.backup_schedule._info) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_backup_schedule_delete(cs, args): """ @@ -84,6 +85,7 @@ def do_backup_schedule_delete(cs, args): server = _find_server(cs, args.server) server.backup_schedule.delete() + def _boot(cs, args, reservation_id=None, min_count=None, max_count=None): """Boot a new server.""" if min_count is None: @@ -91,9 +93,11 @@ def _boot(cs, args, reservation_id=None, min_count=None, max_count=None): if max_count is None: max_count = min_count if min_count > max_count: - raise exceptions.CommandError("min_instances should be <= max_instances") + raise exceptions.CommandError("min_instances should be" + "<= max_instances") if not min_count or not max_count: - raise exceptions.CommandError("min_instances nor max_instances should be 0") + raise exceptions.CommandError("min_instances nor max_instances" + "should be 0") flavor = args.flavor or cs.flavors.find(ram=256) image = args.image or cs.images.find(name="Ubuntu 10.04 LTS "\ @@ -140,6 +144,7 @@ def _boot(cs, args, reservation_id=None, min_count=None, max_count=None): return (args.name, image, flavor, ipgroup, metadata, files, reservation_id, min_count, max_count) + @utils.arg('--flavor', default=None, metavar='<flavor>', @@ -188,6 +193,7 @@ def do_boot(cs, args): max_count=max_count) utils.print_dict(server._info) + @utils.arg('--flavor', default=None, metavar='<flavor>', @@ -237,6 +243,7 @@ def do_boot_for_account(cs, args): files=files) utils.print_dict(server._info) + @utils.arg('--flavor', default=None, metavar='<flavor>', @@ -310,6 +317,7 @@ def do_zone_boot(cs, args): max_count=max_count) print "Reservation ID=", reservation_id + def _translate_flavor_keys(collection): convert = [('ram', 'memory_mb'), ('disk', 'local_gb')] for item in collection: @@ -318,6 +326,7 @@ def _translate_flavor_keys(collection): if from_key in keys and to_key not in keys: setattr(item, to_key, item._info[from_key]) + def do_flavor_list(cs, args): """Print a list of available 'flavors' (sizes of servers).""" flavors = cs.flavors.list() @@ -332,10 +341,12 @@ def do_flavor_list(cs, args): 'RXTX_Quota', 'RXTX_Cap']) + def do_image_list(cs, args): """Print a list of available images to boot from.""" utils.print_list(cs.images.list(), ['ID', 'Name', 'Status']) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('name', metavar='<name>', help='Name of snapshot.') def do_image_create(cs, args): @@ -344,6 +355,7 @@ def do_image_create(cs, args): image = cs.images.create(server, args.name) utils.print_dict(image._info) + @utils.arg('image', metavar='<image>', help='Name or ID of image.') def do_image_delete(cs, args): """ @@ -355,6 +367,7 @@ def do_image_delete(cs, args): image = _find_image(cs, args.image) image.delete() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('group', metavar='<group>', help='Name or ID of group.') @utils.arg('address', metavar='<address>', help='IP address to share.') @@ -364,6 +377,7 @@ def do_ip_share(cs, args): group = _find_ipgroup(cs, args.group) server.share_ip(group, args.address) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('address', metavar='<address>', help='Shared IP address to remove from the server.') @@ -372,6 +386,7 @@ def do_ip_unshare(cs, args): server = _find_server(cs, args.server) server.unshare_ip(args.address) + def do_ipgroup_list(cs, args): """Show IP groups.""" def pretty_server_list(ipgroup): @@ -382,12 +397,14 @@ def do_ipgroup_list(cs, args): fields=['ID', 'Name', 'Server List'], formatters={'Server List': pretty_server_list}) + @utils.arg('group', metavar='<group>', help='Name or ID of group.') def do_ipgroup_show(cs, args): """Show details about a particular IP group.""" group = _find_ipgroup(cs, args.group) utils.print_dict(group._info) + @utils.arg('name', metavar='<name>', help='What to name this new group.') @utils.arg('server', metavar='<server>', nargs='?', help='Server (name or ID) to make a member of this new group.') @@ -400,11 +417,13 @@ def do_ipgroup_create(cs, args): group = cs.ipgroups.create(args.name, server) utils.print_dict(group._info) + @utils.arg('group', metavar='<group>', help='Name or ID of group.') def do_ipgroup_delete(cs, args): """Delete an IP group.""" _find_ipgroup(cs, args.group).delete() + @utils.arg('--fixed_ip', dest='fixed_ip', metavar='<fixed_ip>', @@ -467,6 +486,7 @@ def do_list(cs, args): utils.print_list(cs.servers.list(search_opts=search_opts), to_print) + @utils.arg('--hard', dest='reboot_type', action='store_const', @@ -478,6 +498,7 @@ def do_reboot(cs, args): """Reboot a server.""" _find_server(cs, args.server).reboot(args.reboot_type) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('image', metavar='<image>', help="Name or ID of new image.") def do_rebuild(cs, args): @@ -486,12 +507,15 @@ def do_rebuild(cs, args): image = _find_image(cs, args.image) server.rebuild(image) -@utils.arg('server', metavar='<server>', help='Name (old name) or ID of server.') + +@utils.arg('server', metavar='<server>', + help='Name (old name) or ID of server.') @utils.arg('name', metavar='<name>', help='New name for the server.') def do_rename(cs, args): """Rename a server.""" _find_server(cs, args.server).update(name=args.name) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('flavor', metavar='<flavor>', help="Name or ID of new flavor.") def do_resize(cs, args): @@ -500,6 +524,7 @@ def do_resize(cs, args): flavor = _find_flavor(cs, args.flavor) server.resize(flavor) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('name', metavar='<name>', help='Name of snapshot.') @utils.arg('backup_type', metavar='<daily|weekly>', help='type of backup') @@ -510,46 +535,55 @@ def do_backup(cs, args): server = _find_server(cs, args.server) server.backup(args.name, args.backup_type, args.rotation) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_migrate(cs, args): """Migrate a server.""" _find_server(cs, args.server).migrate() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_pause(cs, args): """Pause a server.""" _find_server(cs, args.server).pause() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_unpause(cs, args): """Unpause a server.""" _find_server(cs, args.server).unpause() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_suspend(cs, args): """Suspend a server.""" _find_server(cs, args.server).suspend() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_resume(cs, args): """Resume a server.""" _find_server(cs, args.server).resume() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_rescue(cs, args): """Rescue a server.""" _find_server(cs, args.server).rescue() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_unrescue(cs, args): """Unrescue a server.""" _find_server(cs, args.server).unrescue() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_diagnostics(cs, args): """Retrieve server diagnostics.""" utils.print_dict(cs.servers.diagnostics(args.server)[1]) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_actions(cs, args): """Retrieve server actions.""" @@ -557,16 +591,19 @@ def do_actions(cs, args): cs.servers.actions(args.server), ["Created_At", "Action", "Error"]) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_resize_confirm(cs, args): """Confirm a previous resize.""" _find_server(cs, args.server).confirm_resize() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_resize_revert(cs, args): """Revert a previous resize (and return to the previous VM).""" _find_server(cs, args.server).revert_resize() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_root_password(cs, args): """ @@ -579,6 +616,7 @@ def do_root_password(cs, args): raise exceptions.CommandError("Passwords do not match.") server.update(password=p1) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_show(cs, args): """Show details about the given server.""" @@ -598,11 +636,13 @@ def do_show(cs, args): utils.print_dict(info) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_delete(cs, args): """Immediately shut down and delete a server.""" _find_server(cs, args.server).delete() + # --zone_username is required since --username is already used. @utils.arg('zone', metavar='<zone_id>', help='ID of the zone', default=None) @utils.arg('--api_url', dest='api_url', default=None, help='New URL.') @@ -634,11 +674,13 @@ def do_zone(cs, args): else: utils.print_dict(zone._info) + def do_zone_info(cs, args): """Get this zones name and capabilities.""" zone = cs.zones.info() utils.print_dict(zone._info) + @utils.arg('api_url', metavar='<api_url>', help="URL for the Zone's API") @utils.arg('zone_username', metavar='<zone_username>', help='Authentication username.') @@ -654,16 +696,19 @@ def do_zone_add(cs, args): args.weight_scale) utils.print_dict(zone._info) + @utils.arg('zone', metavar='<zone>', help='Name or ID of the zone') def do_zone_delete(cs, args): """Delete a zone.""" cs.zones.delete(args.zone) + def do_zone_list(cs, args): """List the children of a zone.""" utils.print_list(cs.zones.list(), ['ID', 'Name', 'Is Active', \ 'API URL', 'Weight Offset', 'Weight Scale']) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('network_id', metavar='<network_id>', help='Network ID.') def do_add_fixed_ip(cs, args): @@ -671,6 +716,7 @@ def do_add_fixed_ip(cs, args): server = _find_server(cs, args.server) server.add_fixed_ip(args.network_id) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('address', metavar='<address>', help='IP Address.') def do_remove_fixed_ip(cs, args): @@ -678,18 +724,22 @@ def do_remove_fixed_ip(cs, args): server = _find_server(cs, args.server) server.remove_fixed_ip(args.address) + def _find_server(cs, server): """Get a server by name or ID.""" return _find_resource(cs.servers, server) + def _find_ipgroup(cs, group): """Get an IP group by name or ID.""" return _find_resource(cs.ipgroups, group) + def _find_image(cs, image): """Get an image by name or ID.""" return _find_resource(cs.images, image) + def _find_flavor(cs, flavor): """Get a flavor by name, ID, or RAM size.""" try: @@ -697,6 +747,7 @@ def _find_flavor(cs, flavor): except exceptions.NotFound: return cs.flavors.find(ram=flavor) + def _find_resource(manager, name_or_id): """Helper for the _find_* methods.""" try: @@ -709,6 +760,6 @@ def _find_resource(manager, name_or_id): except ValueError: return manager.find(name=name_or_id) except exceptions.NotFound: - raise exceptions.CommandError("No %s with a name or ID of '%s' exists." % + raise exceptions.CommandError( + "No %s with a name or ID of '%s' exists." % (manager.resource_class.__name__.lower(), name_or_id)) - diff --git a/novaclient/v1_1/client.py b/novaclient/v1_1/client.py index d2b7b3caa..aca860c0f 100644 --- a/novaclient/v1_1/client.py +++ b/novaclient/v1_1/client.py @@ -1,5 +1,3 @@ - - from novaclient import client from novaclient.v1_1 import flavors from novaclient.v1_1 import images @@ -7,7 +5,6 @@ from novaclient.v1_1 import servers from novaclient.v1_1 import zones - class Client(object): """ Top-level object to access the OpenStack Compute API. diff --git a/novaclient/v1_1/shell.py b/novaclient/v1_1/shell.py index dfa26a14e..d9fdf5ae3 100644 --- a/novaclient/v1_1/shell.py +++ b/novaclient/v1_1/shell.py @@ -38,9 +38,11 @@ def _boot(cs, args, reservation_id=None, min_count=None, max_count=None): if max_count is None: max_count = min_count if min_count > max_count: - raise exceptions.CommandError("min_instances should be <= max_instances") + raise exceptions.CommandError("min_instances should be <= " + "max_instances") if not min_count or not max_count: - raise exceptions.CommandError("min_instances nor max_instances should be 0") + raise exceptions.CommandError("min_instances nor max_instances should" + "be 0") flavor = args.flavor or cs.flavors.find(ram=256) image = args.image or cs.images.find(name="Ubuntu 10.04 LTS "\ @@ -80,6 +82,7 @@ def _boot(cs, args, reservation_id=None, min_count=None, max_count=None): return (args.name, image, flavor, metadata, files, reservation_id, min_count, max_count) + @utils.arg('--flavor', default=None, metavar='<flavor>', @@ -216,10 +219,12 @@ def do_flavor_list(cs, args): 'RXTX_Quota', 'RXTX_Cap']) + def do_image_list(cs, args): """Print a list of available images to boot from.""" utils.print_list(cs.images.list(), ['ID', 'Name', 'Status']) + @utils.arg('image', metavar='<image>', help='Name or ID of image.') def do_image_delete(cs, args): """ @@ -231,6 +236,7 @@ def do_image_delete(cs, args): image = _find_image(cs, args.image) image.delete() + @utils.arg('--fixed_ip', dest='fixed_ip', metavar='<fixed_ip>', @@ -294,7 +300,8 @@ def do_list(cs, args): columns = [id_col, 'Name', 'Status', 'Networks'] formatters = {'Networks': _format_servers_list_networks} - utils.print_list(cs.servers.list(search_opts=search_opts), columns, formatters) + utils.print_list(cs.servers.list(search_opts=search_opts), columns, + formatters) def _format_servers_list_networks(server): @@ -320,6 +327,7 @@ def do_reboot(cs, args): """Reboot a server.""" _find_server(cs, args.server).reboot(args.reboot_type) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('image', metavar='<image>', help="Name or ID of new image.") def do_rebuild(cs, args): @@ -328,12 +336,15 @@ def do_rebuild(cs, args): image = _find_image(cs, args.image) server.rebuild(image) -@utils.arg('server', metavar='<server>', help='Name (old name) or ID of server.') + +@utils.arg('server', metavar='<server>', + help='Name (old name) or ID of server.') @utils.arg('name', metavar='<name>', help='New name for the server.') def do_rename(cs, args): """Rename a server.""" _find_server(cs, args.server).update(name=args.name) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('flavor', metavar='<flavor>', help="Name or ID of new flavor.") def do_resize(cs, args): @@ -342,56 +353,67 @@ def do_resize(cs, args): flavor = _find_flavor(cs, args.flavor) server.resize(flavor) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_resize_confirm(cs, args): """Confirm a previous resize.""" _find_server(cs, args.server).confirm_resize() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_resize_revert(cs, args): """Revert a previous resize (and return to the previous VM).""" _find_server(cs, args.server).revert_resize() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_migrate(cs, args): """Migrate a server.""" _find_server(cs, args.server).migrate() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_pause(cs, args): """Pause a server.""" _find_server(cs, args.server).pause() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_unpause(cs, args): """Unpause a server.""" _find_server(cs, args.server).unpause() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_suspend(cs, args): """Suspend a server.""" _find_server(cs, args.server).suspend() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_resume(cs, args): """Resume a server.""" _find_server(cs, args.server).resume() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_rescue(cs, args): """Rescue a server.""" _find_server(cs, args.server).rescue() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_unrescue(cs, args): """Unrescue a server.""" _find_server(cs, args.server).unrescue() + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_diagnostics(cs, args): """Retrieve server diagnostics.""" utils.print_dict(cs.servers.diagnostics(args.server)[1]) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_actions(cs, args): """Retrieve server actions.""" @@ -400,7 +422,6 @@ def do_actions(cs, args): ["Created_At", "Action", "Error"]) - @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_root_password(cs, args): """ @@ -413,6 +434,7 @@ def do_root_password(cs, args): raise exceptions.CommandError("Passwords do not match.") server.change_password(p1) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('name', metavar='<name>', help='Name of snapshot.') def do_image_create(cs, args): @@ -420,6 +442,7 @@ def do_image_create(cs, args): server = _find_server(cs, args.server) cs.servers.create_image(server, args.name) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_show(cs, args): """Show details about the given server.""" @@ -444,19 +467,23 @@ def do_show(cs, args): utils.print_dict(info) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') def do_delete(cs, args): """Immediately shut down and delete a server.""" _find_server(cs, args.server).delete() + def _find_server(cs, server): """Get a server by name or ID.""" return _find_resource(cs.servers, server) + def _find_image(cs, image): """Get an image by name or ID.""" return _find_resource(cs.images, image) + def _find_flavor(cs, flavor): """Get a flavor by name, ID, or RAM size.""" try: @@ -464,6 +491,7 @@ def _find_flavor(cs, flavor): except exceptions.NotFound: return cs.flavors.find(ram=flavor) + def _find_resource(manager, name_or_id): """Helper for the _find_* methods.""" try: @@ -476,8 +504,10 @@ def _find_resource(manager, name_or_id): except ValueError: return manager.find(name=name_or_id) except exceptions.NotFound: - raise exceptions.CommandError("No %s with a name or ID of '%s' exists." % - (manager.resource_class.__name__.lower(), name_or_id)) + raise exceptions.CommandError( + "No %s with a name or ID of '%s' exists." % + (manager.resource_class.__name__.lower(), name_or_id)) + # --zone_username is required since --username is already used. @utils.arg('zone', metavar='<zone_id>', help='ID of the zone', default=None) @@ -510,11 +540,13 @@ def do_zone(cs, args): else: utils.print_dict(zone._info) + def do_zone_info(cs, args): """Get this zones name and capabilities.""" zone = cs.zones.info() utils.print_dict(zone._info) + @utils.arg('api_url', metavar='<api_url>', help="URL for the Zone's API") @utils.arg('zone_username', metavar='<zone_username>', help='Authentication username.') @@ -530,16 +562,19 @@ def do_zone_add(cs, args): args.weight_scale) utils.print_dict(zone._info) + @utils.arg('zone', metavar='<zone>', help='Name or ID of the zone') def do_zone_delete(cs, args): """Delete a zone.""" cs.zones.delete(args.zone) + def do_zone_list(cs, args): """List the children of a zone.""" utils.print_list(cs.zones.list(), ['ID', 'Name', 'Is Active', \ 'API URL', 'Weight Offset', 'Weight Scale']) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('network_id', metavar='<network_id>', help='Network ID.') def do_add_fixed_ip(cs, args): @@ -547,6 +582,7 @@ def do_add_fixed_ip(cs, args): server = _find_server(cs, args.server) server.add_fixed_ip(args.network_id) + @utils.arg('server', metavar='<server>', help='Name or ID of server.') @utils.arg('address', metavar='<address>', help='IP Address.') def do_remove_fixed_ip(cs, args):