Change '_' to '-' in options

This changes every command-line option with a '_' in its name
and changes them to '-'.  The old option names are maintained
for backward compatibility but are no longer in the help text.

BP command-options

Note: there is a dodgy hack in novaclient/shell.py to handle
usage-list's --end option that conflicts with --endpoint-type
if --endpoint_type is also present for backward compatibility.
If --endpoint_type is not added to the parser it works.  Go figure.
Better solutions that do not break backward compatibility are welcome.

Rebased due to https://review.openstack.org/11072 merging.
Note: --availability_zone changed to --availability-zone with no
backward compatability since this s a new option.

Change-Id: I09ab546659be0a0d3f0eadb22ab5e13fac2f059d
This commit is contained in:
Dean Troyer 2012-08-22 13:01:17 -05:00
parent 8ccd9059d6
commit 9101741960
5 changed files with 398 additions and 215 deletions

View File

@ -40,14 +40,14 @@ Installing this package gets you a shell command, ``nova``, that you
can use to interact with any Rackspace compatible API (including OpenStack).
You'll need to provide your OpenStack username and password. You can do this
with the ``--os_username``, ``--os_password`` and ``--os_tenant_name``
with the ``--os-username``, ``--os-password`` and ``--os-tenant-name``
params, but it's easier to just set them as environment variables::
export OS_USERNAME=openstack
export OS_PASSWORD=yadayada
export OS_TENANT_NAME=myproject
You will also need to define the authentication url with ``--os_auth_url``
You will also need to define the authentication url with ``--os-auth-url``
and the version of the API with ``--version``. Or set them as an environment
variables as well::
@ -60,19 +60,21 @@ endpoint::
export OS_AUTH_URL=http://example.com:5000/v2.0/
Since Keystone can return multiple regions in the Service Catalog, you
can specify the one you want with ``--os_region_name`` (or
can specify the one you want with ``--os-region-name`` (or
``export OS_REGION_NAME``). It defaults to the first in the list returned.
You'll find complete documentation on the shell by running
``nova help``::
usage: nova [--debug] [--os_username OS_USERNAME] [--os_password OS_PASSWORD]
[--os_tenant_name OS_TENANT_NAME] [--os_auth_url OS_AUTH_URL]
[--os_region_name OS_REGION_NAME] [--service_type SERVICE_TYPE]
[--service_name SERVICE_NAME] [--endpoint_type ENDPOINT_TYPE]
[--version VERSION] [--username USERNAME]
[--region_name REGION_NAME] [--apikey APIKEY]
[--projectid PROJECTID] [--url URL]
usage: nova [--debug] [--no-cache] [--timings]
[--os-username <auth-user-name>] [--os-password <auth-password>]
[--os-tenant-name <auth-tenant-name>] [--os-auth-url <auth-url>]
[--os-region-name <region-name>] [--os-auth-system <auth-system>]
[--service-type <service-type>] [--service-name <service-name>]
[--volume-service-name <volume-service-type>]
[--endpoint-type <endpoint-type>]
[--os-compute-api-version <compute-api-ver>] [--insecure]
[--bypass-url <bypass-url>]
<subcommand> ...
Command-line interface to the OpenStack Nova API.
@ -199,33 +201,36 @@ You'll find complete documentation on the shell by running
Optional arguments:
--debug Print debugging output
--os_username OS_USERNAME
--no-cache Don't use the auth token cache.
--timings Print call timing info
--os-username <auth-user-name>
Defaults to env[OS_USERNAME].
--os_password OS_PASSWORD
--os-password <auth-password>
Defaults to env[OS_PASSWORD].
--os_tenant_name OS_TENANT_NAME
--os-tenant-name <auth-tenant-name>
Defaults to env[OS_TENANT_NAME].
--os_auth_url OS_AUTH_URL
--os-auth-url <auth-url>
Defaults to env[OS_AUTH_URL].
--os_region_name OS_REGION_NAME
--os-region-name <region-name>
Defaults to env[OS_REGION_NAME].
--service_type SERVICE_TYPE
--os-auth-system <auth-system>
Defaults to env[OS_AUTH_SYSTEM].
--service-type <service-type>
Defaults to compute for most actions
--service_name SERVICE_NAME
--service-name <service-name>
Defaults to env[NOVA_SERVICE_NAME]
--endpoint_type ENDPOINT_TYPE
--volume-service-name <volume-service-type>
Defaults to env[NOVA_VOLUME_SERVICE_NAME]
--endpoint-type <endpoint-type>
Defaults to env[NOVA_ENDPOINT_TYPE] or publicURL.
--os_compute_api_version VERSION
Accepts 1.1, defaults to env[OS_COMPUTE_API_VERSION].
--username USERNAME Deprecated
--region_name REGION_NAME
Deprecated
--apikey APIKEY, --password APIKEY
Deprecated
--projectid PROJECTID, --tenant_name PROJECTID
Deprecated
--url URL, --auth_url URL
Deprecated
--os-compute-api-version <compute-api-ver>
Accepts 1.1, defaults to env[OS_COMPUTE_API_VERSION]. --username USERNAME Deprecated
--insecure Explicitly allow novaclient to perform "insecure" SSL
(https) requests. The server's certificate will not be
verified against any certificate authorities. This
option should be used with caution.
--bypass-url <bypass-url>
Use this API endpoint instead of the Service Catalog
See "nova help COMMAND" for help on a specific command.

View File

@ -11,8 +11,8 @@ First, you'll need an OpenStack Nova account and an API key. You get this
by using the `nova-manage` command in OpenStack Nova.
You'll need to provide :program:`nova` with your OpenStack username and
API key. You can do this with the :option:`--os_username`, :option:`--os_password`
and :option:`--os_tenant_id` options, but it's easier to just set them as
API key. You can do this with the :option:`--os-username`, :option:`--os-password`
and :option:`--os-tenant-id` options, but it's easier to just set them as
environment variables by setting two environment variables:
.. envvar:: OS_USERNAME

View File

@ -86,61 +86,100 @@ class OpenStackComputeShell(object):
action='store_true',
help="Print debugging output")
parser.add_argument('--no_cache',
parser.add_argument('--no-cache',
default=utils.env('OS_NO_CACHE', default=False),
action='store_true',
help="Don't use the auth token cache.")
parser.add_argument('--no_cache',
help=argparse.SUPPRESS)
parser.add_argument('--timings',
default=False,
action='store_true',
help="Print call timing info")
parser.add_argument('--os_username',
parser.add_argument('--os-username',
metavar='<auth-user-name>',
default=utils.env('OS_USERNAME', 'NOVA_USERNAME'),
help='Defaults to env[OS_USERNAME].')
parser.add_argument('--os_username',
help=argparse.SUPPRESS)
parser.add_argument('--os_password',
parser.add_argument('--os-password',
metavar='<auth-password>',
default=utils.env('OS_PASSWORD', 'NOVA_PASSWORD'),
help='Defaults to env[OS_PASSWORD].')
parser.add_argument('--os_password',
help=argparse.SUPPRESS)
parser.add_argument('--os_tenant_name',
parser.add_argument('--os-tenant-name',
metavar='<auth-tenant-name>',
default=utils.env('OS_TENANT_NAME', 'NOVA_PROJECT_ID'),
help='Defaults to env[OS_TENANT_NAME].')
parser.add_argument('--os_tenant_name',
help=argparse.SUPPRESS)
parser.add_argument('--os_auth_url',
parser.add_argument('--os-auth-url',
metavar='<auth-url>',
default=utils.env('OS_AUTH_URL', 'NOVA_URL'),
help='Defaults to env[OS_AUTH_URL].')
parser.add_argument('--os_auth_url',
help=argparse.SUPPRESS)
parser.add_argument('--os_region_name',
parser.add_argument('--os-region-name',
metavar='<region-name>',
default=utils.env('OS_REGION_NAME', 'NOVA_REGION_NAME'),
help='Defaults to env[OS_REGION_NAME].')
parser.add_argument('--os_region_name',
help=argparse.SUPPRESS)
parser.add_argument('--os_auth_system',
parser.add_argument('--os-auth-system',
metavar='<auth-system>',
default=utils.env('OS_AUTH_SYSTEM'),
help='Defaults to env[OS_AUTH_SYSTEM].')
parser.add_argument('--os_auth_system',
help=argparse.SUPPRESS)
parser.add_argument('--service_type',
parser.add_argument('--service-type',
metavar='<service-type>',
help='Defaults to compute for most actions')
parser.add_argument('--service_type',
help=argparse.SUPPRESS)
parser.add_argument('--service_name',
parser.add_argument('--service-name',
metavar='<service-name>',
default=utils.env('NOVA_SERVICE_NAME'),
help='Defaults to env[NOVA_SERVICE_NAME]')
parser.add_argument('--service_name',
help=argparse.SUPPRESS)
parser.add_argument('--volume_service_name',
parser.add_argument('--volume-service-name',
metavar='<volume-service-name>',
default=utils.env('NOVA_VOLUME_SERVICE_NAME'),
help='Defaults to env[NOVA_VOLUME_SERVICE_NAME]')
parser.add_argument('--volume_service_name',
help=argparse.SUPPRESS)
parser.add_argument('--endpoint_type',
parser.add_argument('--endpoint-type',
metavar='<endpoint-type>',
default=utils.env('NOVA_ENDPOINT_TYPE',
default=DEFAULT_NOVA_ENDPOINT_TYPE),
help='Defaults to env[NOVA_ENDPOINT_TYPE] or '
+ DEFAULT_NOVA_ENDPOINT_TYPE + '.')
# NOTE(dtroyer): We can't add --endpoint_type here due to argparse
# thinking usage-list --end is ambiguous; but it
# works fine with only --endpoint-type present
# Go figure. I'm leaving this here for doc purposes.
#parser.add_argument('--endpoint_type',
# help=argparse.SUPPRESS)
parser.add_argument('--os_compute_api_version',
parser.add_argument('--os-compute-api-version',
metavar='<compute-api-ver>',
default=utils.env('OS_COMPUTE_API_VERSION',
default=DEFAULT_OS_COMPUTE_API_VERSION),
default=DEFAULT_OS_COMPUTE_API_VERSION),
help='Accepts 1.1, defaults to env[OS_COMPUTE_API_VERSION].')
parser.add_argument('--os_compute_api_version',
help=argparse.SUPPRESS)
parser.add_argument('--insecure',
default=utils.env('NOVACLIENT_INSECURE', default=False),
@ -153,31 +192,35 @@ class OpenStackComputeShell(object):
# FIXME(dtroyer): The args below are here for diablo compatibility,
# remove them in folsum cycle
# alias for --os_username, left in for backwards compatibility
# alias for --os-username, left in for backwards compatibility
parser.add_argument('--username',
help='Deprecated')
help=argparse.SUPPRESS)
# alias for --os_region_name, left in for backwards compatibility
# alias for --os-region-name, left in for backwards compatibility
parser.add_argument('--region_name',
help='Deprecated')
help=argparse.SUPPRESS)
# alias for --os_password, left in for backwards compatibility
# alias for --os-password, left in for backwards compatibility
parser.add_argument('--apikey', '--password', dest='apikey',
default=utils.env('NOVA_API_KEY'),
help='Deprecated')
help=argparse.SUPPRESS)
# alias for --os_tenant_name, left in for backward compatibility
# alias for --os-tenant-name, left in for backward compatibility
parser.add_argument('--projectid', '--tenant_name', dest='projectid',
default=utils.env('NOVA_PROJECT_ID'),
help='Deprecated')
help=argparse.SUPPRESS)
# alias for --os_auth_url, left in for backward compatibility
# alias for --os-auth-url, left in for backward compatibility
parser.add_argument('--url', '--auth_url', dest='url',
default=utils.env('NOVA_URL'),
help='Deprecated')
help=argparse.SUPPRESS)
parser.add_argument('--bypass_url', dest='bypass_url',
parser.add_argument('--bypass-url',
metavar='<bypass-url>',
dest='bypass_url',
help="Use this API endpoint instead of the Service Catalog")
parser.add_argument('--bypass_url',
help=argparse.SUPPRESS)
return parser
@ -286,7 +329,7 @@ class OpenStackComputeShell(object):
httplib2.debuglevel = 1
def main(self, argv):
# Parse args once to find version
# Parse args once to find version and debug settings
parser = self.get_base_parser()
(options, args) = parser.parse_known_args(argv)
self.setup_debugging(options.debug)
@ -296,6 +339,14 @@ class OpenStackComputeShell(object):
options.os_compute_api_version)
self._run_extension_hooks('__pre_parse_args__')
# NOTE(dtroyer): Hackery to handle --endpoint_type due to argparse
# thinking usage-list --end is ambiguous; but it
# works fine with only --endpoint-type present
# Go figure.
if '--endpoint_type' in argv:
spot = argv.index('--endpoint_type')
argv[spot] = '--endpoint-type'
subcommand_parser = self.get_subcommand_parser(
options.os_compute_api_version)
self.parser = subcommand_parser
@ -343,14 +394,14 @@ class OpenStackComputeShell(object):
if not os_username:
if not username:
raise exc.CommandError("You must provide a username "
"via either --os_username or env[OS_USERNAME]")
"via either --os-username or env[OS_USERNAME]")
else:
os_username = username
if not os_password:
if not apikey:
raise exc.CommandError("You must provide a password "
"via either --os_password or via "
"via either --os-password or via "
"env[OS_PASSWORD]")
else:
os_password = apikey
@ -358,7 +409,7 @@ class OpenStackComputeShell(object):
if not os_tenant_name:
if not projectid:
raise exc.CommandError("You must provide a tenant name "
"via either --os_tenant_name or "
"via either --os-tenant-name or "
"env[OS_TENANT_NAME]")
else:
os_tenant_name = projectid
@ -373,9 +424,9 @@ class OpenStackComputeShell(object):
if not os_auth_url:
raise exc.CommandError("You must provide an auth url "
"via either --os_auth_url or env[OS_AUTH_URL] "
"via either --os-auth-url or env[OS_AUTH_URL] "
"or specify an auth_system which defines a "
"default url with --os_auth_system "
"default url with --os-auth-system "
"or env[OS_AUTH_SYSTEM")
if not os_region_name and region_name:
@ -385,11 +436,11 @@ class OpenStackComputeShell(object):
options.os_compute_api_version != '1.0'):
if not os_tenant_name:
raise exc.CommandError("You must provide a tenant name "
"via either --os_tenant_name or env[OS_TENANT_NAME]")
"via either --os-tenant-name or env[OS_TENANT_NAME]")
if not os_auth_url:
raise exc.CommandError("You must provide an auth url "
"via either --os_auth_url or env[OS_AUTH_URL]")
"via either --os-auth-url or env[OS_AUTH_URL]")
self.cs = client.Client(options.os_compute_api_version, os_username,
os_password, os_tenant_name, os_auth_url, insecure,

View File

@ -15,6 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import datetime
import getpass
import os
@ -155,29 +156,40 @@ def _boot(cs, args, reservation_id=None, min_count=None, max_count=None):
default=[],
help="Store arbitrary files from <src-path> locally to <dst-path> "\
"on the new server. You may store up to 5 files.")
@utils.arg('--key-name',
metavar='<key-name>',
help="Key name of keypair that should be created earlier with \
the command keypair-add")
@utils.arg('--key_name',
metavar='<key_name>',
help="Key name of keypair that should be created earlier with \
the command keypair-add")
help=argparse.SUPPRESS)
@utils.arg('name', metavar='<name>', help='Name for the new server')
@utils.arg('--user-data',
default=None,
metavar='<user-data>',
help="user data file to pass to be exposed by the metadata server.")
@utils.arg('--user_data',
default=None,
metavar='<user-data>',
help="user data file to pass to be exposed by the metadata server.")
help=argparse.SUPPRESS)
@utils.arg('--availability-zone',
default=None,
metavar='<availability-zone>',
help="The availability zone for instance placement.")
@utils.arg('--availability_zone',
default=None,
metavar='<availability-zone>',
help="The availability zone for instance placement.")
help=argparse.SUPPRESS)
@utils.arg('--security-groups',
default=None,
metavar='<security-groups>',
help="Comma separated list of security group names.")
@utils.arg('--security_groups',
default=None,
metavar='<security_groups>',
help="comma separated list of security group names.")
help=argparse.SUPPRESS)
@utils.arg('--block-device-mapping',
metavar="<dev-name=mapping>",
action='append',
default=[],
help="Block device mapping in the format "
"<dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate>.")
@utils.arg('--block_device_mapping',
metavar="<dev_name=mapping>",
action='append',
default=[],
help="Block device mapping in the format "
"<dev_name=<id>:<type>:<size(GB)>:<delete_on_terminate>.")
action='append',
help=argparse.SUPPRESS)
@utils.arg('--hint',
action='append',
dest='scheduler_hints',
@ -480,31 +492,35 @@ def do_image_delete(cs, args):
image.delete()
@utils.arg('--reservation_id',
@utils.arg('--reservation-id',
dest='reservation_id',
metavar='<reservation_id>',
metavar='<reservation-id>',
default=None,
help='Only return instances that match reservation_id.')
help='Only return instances that match reservation-id.')
@utils.arg('--reservation_id',
help=argparse.SUPPRESS)
@utils.arg('--ip',
dest='ip',
metavar='<ip_regexp>',
metavar='<ip-regexp>',
default=None,
help='Search with regular expression match by IP address')
@utils.arg('--ip6',
dest='ip6',
metavar='<ip6_regexp>',
metavar='<ip6-regexp>',
default=None,
help='Search with regular expression match by IPv6 address')
@utils.arg('--name',
dest='name',
metavar='<name_regexp>',
metavar='<name-regexp>',
default=None,
help='Search with regular expression match by name')
@utils.arg('--instance_name',
@utils.arg('--instance-name',
dest='instance_name',
metavar='<name_regexp>',
metavar='<name-regexp>',
default=None,
help='Search with regular expression match by instance name')
@utils.arg('--instance_name',
help=argparse.SUPPRESS)
@utils.arg('--status',
dest='status',
metavar='<status>',
@ -526,7 +542,7 @@ def do_image_delete(cs, args):
metavar='<hostname>',
default=None,
help='Search instances by hostname to which they are assigned')
@utils.arg('--all_tenants',
@utils.arg('--all-tenants',
dest='all_tenants',
metavar='<0|1>',
nargs='?',
@ -534,6 +550,11 @@ def do_image_delete(cs, args):
const=1,
default=0,
help='Display information from all tenants (Admin only).')
@utils.arg('--all_tenants',
nargs='?',
type=int,
const=1,
help=argparse.SUPPRESS)
def do_list(cs, args):
"""List active servers."""
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
@ -581,9 +602,13 @@ def do_reboot(cs, args):
@utils.arg('server', metavar='<server>', help='Name or ID of server.')
@utils.arg('image', metavar='<image>', help="Name or ID of new image.")
@utils.arg('--rebuild_password', dest='rebuild_password',
metavar='<rebuild_password>', default=False,
help="Set the provided password on the rebuild instance.")
@utils.arg('--rebuild-password',
dest='rebuild_password',
metavar='<rebuild-password>',
default=False,
help="Set the provided password on the rebuild instance.")
@utils.arg('--rebuild_password',
help=argparse.SUPPRESS)
@utils.arg('--poll',
dest='poll',
action="store_true",
@ -866,7 +891,9 @@ def _find_flavor(cs, flavor):
@utils.arg('server', metavar='<server>', help='Name or ID of server.')
@utils.arg('network_id', metavar='<network_id>', help='Network ID.')
@utils.arg('network_id',
metavar='<network-id>',
help='Network ID.')
def do_add_fixed_ip(cs, args):
"""Add new IP address to network."""
server = _find_server(cs, args.server)
@ -943,23 +970,33 @@ def do_volume_show(cs, args):
metavar='<size>',
type=int,
help='Size of volume in GB')
@utils.arg('--snapshot-id',
metavar='<snapshot-id>',
default=None,
help='Optional snapshot id to create the volume from. (Default=None)')
@utils.arg('--snapshot_id',
metavar='<snapshot_id>',
help='Optional snapshot id to create the volume from. (Default=None)',
default=None)
@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)
help=argparse.SUPPRESS)
@utils.arg('--display-name',
metavar='<display-name>',
default=None,
help='Optional volume name. (Default=None)')
@utils.arg('--display_name',
help=argparse.SUPPRESS)
@utils.arg('--display-description',
metavar='<display-description>',
default=None,
help='Optional volume description. (Default=None)')
@utils.arg('--display_description',
help=argparse.SUPPRESS)
@utils.arg('--volume-type',
metavar='<volume-type>',
default=None,
help='Optional volume type. (Default=None)')
@utils.arg('--volume_type',
metavar='<volume_type>',
help='Optional volume type. (Default=None)',
help=argparse.SUPPRESS)
@utils.arg('--availability-zone', metavar='<availability-zone>',
help='Optional Availability Zone for volume. (Default=None)',
default=None)
@utils.arg('--availability_zone', metavar='<availability_zone>',
help='Optional Availability Zone for volume. (Default=None)',
default=None)
@utils.service_type('volume')
def do_volume_create(cs, args):
"""Add a new volume."""
@ -1029,19 +1066,25 @@ def do_volume_snapshot_show(cs, args):
@utils.arg('volume_id',
metavar='<volume_id>',
metavar='<volume-id>',
help='ID of the volume to snapshot')
@utils.arg('--force',
metavar='<True|False>',
help='Optional flag to indicate whether to snapshot a volume even if its '
'attached to an instance. (Default=False)',
default=False)
@utils.arg('--display_name', metavar='<display_name>',
help='Optional snapshot name. (Default=None)',
default=None)
@utils.arg('--display_description', metavar='<display_description>',
help='Optional snapshot description. (Default=None)',
default=None)
@utils.arg('--display-name',
metavar='<display-name>',
default=None,
help='Optional snapshot name. (Default=None)')
@utils.arg('--display_name',
help=argparse.SUPPRESS)
@utils.arg('--display-description',
metavar='<display-description>',
default=None,
help='Optional snapshot description. (Default=None)')
@utils.arg('--display_description',
help=argparse.SUPPRESS)
@utils.service_type('volume')
def do_volume_snapshot_create(cs, args):
"""Add a new snapshot."""
@ -1052,7 +1095,7 @@ def do_volume_snapshot_create(cs, args):
@utils.arg('snapshot_id',
metavar='<snapshot_id>',
metavar='<snapshot-id>',
help='ID of the snapshot to delete.')
@utils.service_type('volume')
def do_volume_snapshot_delete(cs, args):
@ -1093,7 +1136,7 @@ def do_volume_type_delete(cs, args):
@utils.arg('server', metavar='<server>', help='Name or ID of server.')
@utils.arg('console_type',
metavar='<console_type>',
metavar='<console-type>',
help='Type of vnc console ("novnc" or "xvpvnc").')
def do_get_vnc_console(cs, args):
"""Get a vnc console to a server."""
@ -1157,7 +1200,7 @@ def do_remove_secgroup(cs, args):
@utils.arg('pool',
metavar='<floating_ip_pool>',
metavar='<floating-ip-pool>',
help='Name of Floating IP Pool. (Optional)',
nargs='?',
default=None)
@ -1241,10 +1284,13 @@ def do_dns_delete_domain(cs, args):
@utils.arg('domain', metavar='<domain>', help='DNS domain')
@utils.arg('--availability_zone', metavar='<availability_zone>',
help='Limit access to this domain to instances '
'in the specified availability zone.',
default=None)
@utils.arg('--availability-zone',
metavar='<availability-zone>',
default=None,
help='Limit access to this domain to instances '
'in the specified availability zone.')
@utils.arg('--availability_zone',
help=argparse.SUPPRESS)
def do_dns_create_private_domain(cs, args):
"""Create the specified DNS domain."""
cs.dns_domains.create_private(args.domain,
@ -1294,9 +1340,15 @@ def _get_secgroup(cs, secgroup):
@utils.arg('secgroup', metavar='<secgroup>', help='ID of security group.')
@utils.arg('ip_proto', metavar='<ip_proto>', help='ip_proto (icmp, tcp, udp).')
@utils.arg('from_port', metavar='<from_port>', help='Port at start of range.')
@utils.arg('to_port', metavar='<to_port>', help='Port at end of range.')
@utils.arg('ip_proto',
metavar='<ip-proto>',
help='IP protocol (icmp, tcp, udp).')
@utils.arg('from_port',
metavar='<from-port>',
help='Port at start of range.')
@utils.arg('to_port',
metavar='<to-port>',
help='Port at end of range.')
@utils.arg('cidr', metavar='<cidr>', help='CIDR for address range.')
def do_secgroup_add_rule(cs, args):
"""Add a rule to a security group."""
@ -1310,9 +1362,15 @@ def do_secgroup_add_rule(cs, args):
@utils.arg('secgroup', metavar='<secgroup>', help='ID of security group.')
@utils.arg('ip_proto', metavar='<ip_proto>', help='ip_proto (icmp, tcp, udp).')
@utils.arg('from_port', metavar='<from_port>', help='Port at start of range.')
@utils.arg('to_port', metavar='<to_port>', help='Port at end of range.')
@utils.arg('ip_proto',
metavar='<ip-proto>',
help='IP protocol (icmp, tcp, udp).')
@utils.arg('from_port',
metavar='<from-port>',
help='Port at start of range.')
@utils.arg('to_port',
metavar='<to-port>',
help='Port at end of range.')
@utils.arg('cidr', metavar='<cidr>', help='CIDR for address range.')
def do_secgroup_delete_rule(cs, args):
"""Delete a rule from a security group."""
@ -1355,13 +1413,18 @@ def do_secgroup_list_rules(cs, args):
@utils.arg('secgroup', metavar='<secgroup>', help='ID of security group.')
@utils.arg('source_group', metavar='<source_group>',
help='ID of source group.')
@utils.arg('--ip_proto', metavar='<ip_proto>',
help='ip_proto (icmp, tcp, udp).')
@utils.arg('--from_port', metavar='<from_port>',
help='Port at start of range.')
@utils.arg('--to_port', metavar='<to_port>', help='Port at end of range.')
@utils.arg('source_group',
metavar='<source-group>',
help='ID of source group.')
@utils.arg('ip_proto',
metavar='<ip-proto>',
help='IP protocol (icmp, tcp, udp).')
@utils.arg('from_port',
metavar='<from-port>',
help='Port at start of range.')
@utils.arg('to_port',
metavar='<to-port>',
help='Port at end of range.')
def do_secgroup_add_group_rule(cs, args):
"""Add a source group rule to a security group."""
secgroup = _get_secgroup(cs, args.secgroup)
@ -1382,13 +1445,18 @@ def do_secgroup_add_group_rule(cs, args):
@utils.arg('secgroup', metavar='<secgroup>', help='ID of security group.')
@utils.arg('source_group', metavar='<source_group>',
help='ID of source group.')
@utils.arg('--ip_proto', metavar='<ip_proto>',
help='ip_proto (icmp, tcp, udp).')
@utils.arg('--from_port', metavar='<from_port>',
help='Port at start of range.')
@utils.arg('--to_port', metavar='<to_port>', help='Port at end of range.')
@utils.arg('source_group',
metavar='<source-group>',
help='ID of source group.')
@utils.arg('ip_proto',
metavar='<ip-proto>',
help='IP protocol (icmp, tcp, udp).')
@utils.arg('from_port',
metavar='<from-port>',
help='Port at start of range.')
@utils.arg('to_port',
metavar='<to-port>',
help='Port at end of range.')
def do_secgroup_delete_group_rule(cs, args):
"""Delete a source group rule from a security group."""
secgroup = _get_secgroup(cs, args.secgroup)
@ -1416,8 +1484,12 @@ def do_secgroup_delete_group_rule(cs, args):
@utils.arg('name', metavar='<name>', help='Name of key.')
@utils.arg('--pub_key', metavar='<pub_key>', help='Path to a public ssh key.',
default=None)
@utils.arg('--pub-key',
metavar='<pub-key>',
default=None,
help='Path to a public ssh key.')
@utils.arg('--pub_key',
help=argparse.SUPPRESS)
def do_keypair_add(cs, args):
"""Create a new key pair for use with instances"""
name = args.name
@ -1511,15 +1583,15 @@ def do_usage_list(cs, args):
@utils.arg('pk_filename',
metavar='<private_key_file>',
nargs='?',
default='pk.pem',
help='Filename to write the private key to.')
metavar='<private-key-filename>',
nargs='?',
default='pk.pem',
help='Filename for the private key [Default: pk.pem]')
@utils.arg('cert_filename',
metavar='<x509_cert>',
nargs='?',
default='cert.pem',
help='Filename to write the x509 cert.')
metavar='<x509-cert-filename>',
nargs='?',
default='cert.pem',
help='Filename for the X.509 certificate [Default: cert.pem]')
def do_x509_create_cert(cs, args):
"""Create x509 cert for a user in tenant"""
@ -1566,8 +1638,9 @@ def do_aggregate_list(cs, args):
@utils.arg('name', metavar='<name>', help='Name of aggregate.')
@utils.arg('availability_zone', metavar='<availability_zone>',
help='The availability zone of the aggregate.')
@utils.arg('availability_zone',
metavar='<availability-zone>',
help='The availability zone of the aggregate.')
def do_aggregate_create(cs, args):
"""Create a new aggregate with the specified details."""
aggregate = cs.aggregates.create(args.name, args.availability_zone)
@ -1583,8 +1656,11 @@ def do_aggregate_delete(cs, args):
@utils.arg('id', metavar='<id>', help='Aggregate id to update.')
@utils.arg('name', metavar='<name>', help='Name of aggregate.')
@utils.arg('availability_zone', metavar='<availability_zone>',
help='The availability zone of the aggregate.', nargs='?')
@utils.arg('availability_zone',
metavar='<availability-zone>',
nargs='?',
default=None,
help='The availability zone of the aggregate.')
def do_aggregate_update(cs, args):
"""Update the aggregate's name and optionally availability zone."""
updates = {"name": args.name}
@ -1642,13 +1718,23 @@ def _print_aggregate_details(aggregate):
@utils.arg('server', metavar='<server>', help='Name or ID of server.')
@utils.arg('host', metavar='<host>', help='destination host name.')
@utils.arg('--block_migrate', action='store_true', dest='block_migrate',
default=False,
help='True in case of block_migration.\
(Default=False:live_migration)')
@utils.arg('--disk_over_commit', action='store_true', dest='disk_over_commit',
default=False,
help='Allow overcommit.(Default=Flase)')
@utils.arg('--block-migrate',
action='store_true',
dest='block_migrate',
default=False,
help='True in case of block_migration.\
(Default=False:live_migration)')
@utils.arg('--block_migrate',
action='store_true',
help=argparse.SUPPRESS)
@utils.arg('--disk-over-commit',
action='store_true',
dest='disk_over_commit',
default=False,
help='Allow overcommit.(Default=Flase)')
@utils.arg('--disk_over_commit',
action='store_true',
help=argparse.SUPPRESS)
def do_live_migration(cs, args):
"""Migrates a running instance to a new machine."""
_find_server(cs, args.server).live_migrate(args.host,
@ -1684,9 +1770,11 @@ def do_host_list(cs, args):
@utils.arg('host', metavar='<hostname>', help='Name of host.')
@utils.arg('--status', metavar='<status>', default=None, dest='status',
help='Either enable or disable a host.')
@utils.arg('--maintenance', metavar='<maintenance_mode>', default=None,
dest='maintenance',
help='Either put or resume host to/from maintenance.')
@utils.arg('--maintenance',
metavar='<maintenance-mode>',
default=None,
dest='maintenance',
help='Either put or resume host to/from maintenance.')
def do_host_update(cs, args):
"""Update host settings."""
updates = {}
@ -1750,8 +1838,9 @@ def do_hypervisor_servers(cs, args):
'Hypervisor Hostname'])
@utils.arg('hypervisor_id', metavar='<hypervisor_id>',
help='The ID of the hypervisor to show the details of.')
@utils.arg('hypervisor_id',
metavar='<hypervisor-id>',
help='The ID of the hypervisor to show the details of.')
def do_hypervisor_show(cs, args):
"""Display the details of the specified hypervisor."""
hyper = utils.find_resource(cs.hypervisors, args.hypervisor_id)
@ -1765,8 +1854,9 @@ def do_hypervisor_show(cs, args):
utils.print_dict(info)
@utils.arg('hypervisor_id', metavar='<hypervisor_id>',
help='The ID of the hypervisor to show the uptime of.')
@utils.arg('hypervisor_id',
metavar='<hypervisor-id>',
help='The ID of the hypervisor to show the uptime of.')
def do_hypervisor_uptime(cs, args):
"""Display the uptime of the specified hypervisor."""
hyper = cs.hypervisors.uptime(args.hypervisor_id)
@ -1882,24 +1972,27 @@ def _quota_update(manager, identifier, args):
manager.update(identifier, **updates)
@utils.arg('tenant', metavar='<tenant_id>',
help='UUID of tenant to list the quotas for.')
@utils.arg('tenant',
metavar='<tenant-id>',
help='UUID of tenant to list the quotas for.')
def do_quota_show(cs, args):
"""List the quotas for a tenant."""
_quota_show(cs.quotas.get(args.tenant))
@utils.arg('tenant', metavar='<tenant_id>',
help='UUID of tenant to list the default quotas for.')
@utils.arg('tenant',
metavar='<tenant-id>',
help='UUID of tenant to list the default quotas for.')
def do_quota_defaults(cs, args):
"""List the default quotas for a tenant."""
_quota_show(cs.quotas.defaults(args.tenant))
@utils.arg('tenant', metavar='<tenant_id>',
help='UUID of tenant to set the quotas for.')
@utils.arg('tenant',
metavar='<tenant-id>',
help='UUID of tenant to set the quotas for.')
@utils.arg('--instances',
metavar='<instances>',
type=int, default=None,
@ -1920,38 +2013,56 @@ def do_quota_defaults(cs, args):
metavar='<gigabytes>',
type=int, default=None,
help='New value for the "gigabytes" quota.')
@utils.arg('--floating-ips', '--floating_ips',
metavar='<floating_ips>',
type=int, default=None,
help='New value for the "floating_ips" quota.')
@utils.arg('--metadata-items', '--metadata_items',
metavar='<metadata_items>',
type=int, default=None,
help='New value for the "metadata_items" quota.')
@utils.arg('--injected-files', '--injected_files',
metavar='<injected_files>',
type=int, default=None,
help='New value for the "injected_files" quota.')
@utils.arg('--injected-file-content-bytes', '--injected_file_content_bytes',
metavar='<injected_file_content_bytes>',
type=int, default=None,
help='New value for the "injected_file_content_bytes" quota.')
@utils.arg('--floating-ips',
metavar='<floating-ips>',
type=int,
default=None,
help='New value for the "floating-ips" quota.')
@utils.arg('--floating_ips',
type=int,
help=argparse.SUPPRESS)
@utils.arg('--metadata-items',
metavar='<metadata-items>',
type=int,
default=None,
help='New value for the "metadata-items" quota.')
@utils.arg('--metadata_items',
type=int,
help=argparse.SUPPRESS)
@utils.arg('--injected-files',
metavar='<injected-files>',
type=int,
default=None,
help='New value for the "injected-files" quota.')
@utils.arg('--injected_files',
type=int,
help=argparse.SUPPRESS)
@utils.arg('--injected-file-content-bytes',
metavar='<injected-file-content-bytes>',
type=int,
default=None,
help='New value for the "injected-file-content-bytes" quota.')
@utils.arg('--injected_file_content_bytes',
type=int,
help=argparse.SUPPRESS)
def do_quota_update(cs, args):
"""Update the quotas for a tenant."""
_quota_update(cs.quotas, args.tenant, args)
@utils.arg('class_name', metavar='<class>',
help='Name of quota class to list the quotas for.')
@utils.arg('class_name',
metavar='<class>',
help='Name of quota class to list the quotas for.')
def do_quota_class_show(cs, args):
"""List the quotas for a quota class."""
_quota_show(cs.quota_classes.get(args.class_name))
@utils.arg('class_name', metavar='<class>',
help='Name of quota class to set the quotas for.')
@utils.arg('class_name',
metavar='<class>',
help='Name of quota class to set the quotas for.')
@utils.arg('--instances',
metavar='<instances>',
type=int, default=None,
@ -1972,22 +2083,38 @@ def do_quota_class_show(cs, args):
metavar='<gigabytes>',
type=int, default=None,
help='New value for the "gigabytes" quota.')
@utils.arg('--floating-ips', '--floating_ips',
metavar='<floating_ips>',
type=int, default=None,
help='New value for the "floating_ips" quota.')
@utils.arg('--metadata-items', '--metadata_items',
metavar='<metadata_items>',
type=int, default=None,
help='New value for the "metadata_items" quota.')
@utils.arg('--injected-files', '--injected_files',
metavar='<injected_files>',
type=int, default=None,
help='New value for the "injected_files" quota.')
@utils.arg('--injected-file-content-bytes', '--injected_file_content_bytes',
metavar='<injected_file_content_bytes>',
type=int, default=None,
help='New value for the "injected_file_content_bytes" quota.')
@utils.arg('--floating-ips',
metavar='<floating-ips>',
type=int,
default=None,
help='New value for the "floating-ips" quota.')
@utils.arg('--floating_ips',
type=int,
help=argparse.SUPPRESS)
@utils.arg('--metadata-items',
metavar='<metadata-items>',
type=int,
default=None,
help='New value for the "metadata-items" quota.')
@utils.arg('--metadata_items',
type=int,
help=argparse.SUPPRESS)
@utils.arg('--injected-files',
metavar='<injected-files>',
type=int,
default=None,
help='New value for the "injected-files" quota.')
@utils.arg('--injected_files',
type=int,
help=argparse.SUPPRESS)
@utils.arg('--injected-file-content-bytes',
metavar='<injected-file-content-bytes>',
type=int,
default=None,
help='New value for the "injected-file-content-bytes" quota.')
@utils.arg('--injected_file_content_bytes',
type=int,
help=argparse.SUPPRESS)
def do_quota_class_update(cs, args):
"""Update the quotas for a quota class."""

View File

@ -229,7 +229,7 @@ class ShellTest(utils.TestCase):
# {'rebuild': {'imageRef': 1}})
self.assert_called('GET', '/images/2')
self.run_command('rebuild sample-server 1 --rebuild_password asdf')
self.run_command('rebuild sample-server 1 --rebuild-password asdf')
# XXX need a way to test multiple calls
#self.assert_called('POST', '/servers/1234/action',
# {'rebuild': {'imageRef': 1, 'adminPass': 'asdf'}})
@ -320,7 +320,7 @@ class ShellTest(utils.TestCase):
def test_dns_create_private_domain(self):
self.run_command('dns-create-private-domain testdomain '
'--availability_zone av_zone')
'--availability-zone av_zone')
self.assert_called('PUT', '/os-floating-ip-dns/testdomain')
def test_dns_delete(self):
@ -428,13 +428,13 @@ class ShellTest(utils.TestCase):
'block_migration': False,
'disk_over_commit': False}})
self.run_command('live-migration sample-server hostname \
--block_migrate')
--block-migrate')
self.assert_called('POST', '/servers/1234/action',
{'os-migrateLive': {'host': 'hostname',
'block_migration': True,
'disk_over_commit': False}})
self.run_command('live-migration sample-server hostname \
--block_migrate --disk_over_commit')
--block-migrate --disk-over-commit')
self.assert_called('POST', '/servers/1234/action',
{'os-migrateLive': {'host': 'hostname',
'block_migration': True,