Merge branch 'master' of git://github.com/rackspace/python-novaclient

Conflicts:
	novaclient/v1_1/shell.py
This commit is contained in:
Gaurav Gupta 2011-11-09 10:49:51 -08:00
commit ff48a3e1ec
13 changed files with 65 additions and 35 deletions

View File

@ -47,7 +47,7 @@ copyright = u'Rackspace, based on work by Jacob Kaplan-Moss'
# The short X.Y version.
version = '2.6'
# The full version, including alpha/beta/rc tags.
release = '2.6.6'
release = '2.6.7'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -37,8 +37,8 @@ class HTTPClient(httplib2.Http):
USER_AGENT = 'python-novaclient'
def __init__(self, user, apikey, projectid, auth_url, timeout=None,
token=None, region_name=None):
def __init__(self, user, apikey, projectid, auth_url, insecure=False,
timeout=None, token=None, region_name=None):
super(HTTPClient, self).__init__(timeout=timeout)
self.user = user
self.apikey = apikey
@ -53,6 +53,7 @@ class HTTPClient(httplib2.Http):
# httplib2 overrides
self.force_exception_to_status_code = True
self.disable_ssl_certificate_validation = insecure
def http_log(self, args, kwargs, resp, body):
if 'NOVACLIENT_DEBUG' in os.environ and os.environ['NOVACLIENT_DEBUG']:
@ -139,7 +140,7 @@ class HTTPClient(httplib2.Http):
def delete(self, url, **kwargs):
return self._cs_request(url, 'DELETE', **kwargs)
def _extract_service_catalog(self, url, resp, body):
def _extract_service_catalog(self, url, resp, body, extract_token=True):
"""See what the auth service told us and process the response.
We may get redirected to another site, fail or actually get
back a service catalog with a token and our endpoints."""
@ -149,8 +150,9 @@ class HTTPClient(httplib2.Http):
self.auth_url = url
self.service_catalog = \
service_catalog.ServiceCatalog(body)
self.auth_token = self.service_catalog.get_token()
if extract_token:
self.auth_token = self.service_catalog.get_token()
self.management_url = self.service_catalog.url_for(
attr='region',
filter_value=self.region_name)
@ -184,7 +186,8 @@ class HTTPClient(httplib2.Http):
_logger.debug("Using Endpoint URL: %s" % url)
resp, body = self.request(url, "GET",
headers={'X-Auth_Token': self.auth_token})
return self._extract_service_catalog(url, resp, body)
return self._extract_service_catalog(url, resp, body,
extract_token=False)
def authenticate(self):
magic_tuple = urlparse.urlsplit(self.auth_url)
@ -198,9 +201,9 @@ class HTTPClient(httplib2.Http):
self.version = part
break
# TODO(sandy): Assume admin endpoint is service endpoint+1 for now.
# Ideally this is going to have to be provided by the admin.
new_netloc = netloc.replace(':%d' % port, ':%d' % (port + 1))
# TODO(sandy): Assume admin endpoint is 35357 for now.
# Ideally this is going to have to be provided by the service catalog.
new_netloc = netloc.replace(':%d' % port, ':%d' % (35357,))
admin_url = urlparse.urlunsplit(
(scheme, new_netloc, path, query, frag))
@ -213,7 +216,11 @@ class HTTPClient(httplib2.Http):
# existing token? If so, our actual endpoints may
# be different than that of the admin token.
if self.proxy_token:
return self._fetch_endpoints_from_auth(admin_url)
self._fetch_endpoints_from_auth(admin_url)
# Since keystone no longer returns the user token
# with the endpoints any more, we need to replace
# our service account token with the user token.
self.auth_token = self.proxy_token
else:
try:

View File

@ -1,2 +1 @@
from novaclient.keystone.client import Client

View File

@ -78,7 +78,7 @@ class TenantManager(base.ManagerWithFind):
"""
update a tenant with a new name and description
"""
body = {"tenant": {'id': tenant_id }}
body = {"tenant": {'id': tenant_id}}
if enabled is not None:
body['tenant']['enabled'] = enabled
if description:

View File

@ -36,7 +36,7 @@ class UserManager(base.ManagerWithFind):
"""
# FIXME(ja): why do we have to send id in params and url?
params = {"user": {"id": base.getid(user),
"email": email }}
"email": email}}
self._update("/users/%s" % base.getid(user), params)
@ -45,7 +45,7 @@ class UserManager(base.ManagerWithFind):
Update enabled-ness
"""
params = {"user": {"id": base.getid(user),
"enabled": enabled }}
"enabled": enabled}}
self._update("/users/%s/enabled" % base.getid(user), params)
@ -54,7 +54,7 @@ class UserManager(base.ManagerWithFind):
Update password
"""
params = {"user": {"id": base.getid(user),
"password": password }}
"password": password}}
self._update("/users/%s/password" % base.getid(user), params)
@ -63,7 +63,7 @@ class UserManager(base.ManagerWithFind):
Update default tenant.
"""
params = {"user": {"id": base.getid(user),
"tenantId": base.getid(tenant) }}
"tenantId": base.getid(tenant)}}
# FIXME(ja): seems like a bad url - default tenant is an attribute
# not a subresource!???
@ -73,7 +73,8 @@ class UserManager(base.ManagerWithFind):
"""
Create a user.
"""
# FIXME(ja): email should be optional but keystone currently requires it
# FIXME(ja): email should be optional but keystone currently
# requires it
params = {"user": {"id": user_id,
"password": password,
"tenantId": tenant_id,

View File

@ -33,6 +33,18 @@ class ServiceCatalog(object):
"""Fetch the public URL from the Compute service for
a particular endpoint attribute. If none given, return
the first. See tests for sample service catalog."""
if 'endpoints' in self.catalog:
# We have a bastardized service catalog. Treat it special. :/
for endpoint in self.catalog['endpoints']:
if not filter_value or endpoint[attr] == filter_value:
return endpoint[endpoint_type]
raise novaclient.exceptions.EndpointNotFound()
# We don't always get a service catalog back ...
if not 'serviceCatalog' in self.catalog['access']:
return None
# Full catalog ...
catalog = self.catalog['access']['serviceCatalog']
for service in catalog:

View File

@ -82,6 +82,11 @@ class OpenStackComputeShell(object):
default=env('NOVA_VERSION'),
help='Accepts 1.0 or 1.1, defaults to env[NOVA_VERSION].')
parser.add_argument('--insecure',
default=False,
action='store_true',
help=argparse.SUPPRESS)
return parser
def get_subcommand_parser(self, version):
@ -148,9 +153,9 @@ class OpenStackComputeShell(object):
self.do_help(args)
return 0
user, apikey, projectid, url, region_name = \
user, apikey, projectid, url, region_name, insecure = \
args.username, args.apikey, args.projectid, args.url, \
args.region_name
args.region_name, args.insecure
#FIXME(usrleon): Here should be restrict for project id same as
# for username or apikey but for compatibility it is not.
@ -174,9 +179,8 @@ class OpenStackComputeShell(object):
"via --url or via"
"env[NOVA_URL")
self.cs = self.get_api_class(options.version) \
(user, apikey, projectid, url,
region_name=region_name)
self.cs = self.get_api_class(options.version)(user, apikey, projectid,
url, insecure, region_name=region_name)
try:
self.cs.authenticate()

View File

@ -26,7 +26,7 @@ class Client(object):
"""
def __init__(self, username, api_key, project_id, auth_url=None,
timeout=None, token=None, region_name=None):
insecure=False, timeout=None, token=None, region_name=None):
self.accounts = accounts.AccountManager(self)
self.backup_schedules = backup_schedules.BackupScheduleManager(self)
@ -42,6 +42,7 @@ class Client(object):
api_key,
project_id,
_auth_url,
insecure=insecure,
timeout=timeout,
token=token,
region_name=region_name)

View File

@ -30,8 +30,8 @@ class Client(object):
"""
# FIXME(jesse): project_id isn't required to autenticate
def __init__(self, username, api_key, project_id, auth_url, timeout=None,
token=None, region_name=None):
def __init__(self, username, api_key, project_id, auth_url,
insecure=False, timeout=None, token=None, region_name=None):
self.flavors = flavors.FlavorManager(self)
self.floating_ips = floating_ips.FloatingIPManager(self)
self.images = images.ImageManager(self)
@ -51,6 +51,7 @@ class Client(object):
api_key,
project_id,
auth_url,
insecure=insecure,
timeout=timeout,
token=token,
region_name=region_name)

View File

@ -58,9 +58,9 @@ class ImageManager(base.ManagerWithFind):
self._delete("/images/%s" % base.getid(image))
def set_meta(self, image, metadata):
"""
"""
Set an images metadata
:param image: The :class:`Image` to add metadata to
:param metadata: A dict of metadata to add to the image
"""
@ -69,9 +69,9 @@ class ImageManager(base.ManagerWithFind):
"metadata")
def delete_meta(self, image, keys):
"""
"""
Delete metadata from an image
:param image: The :class:`Image` to add metadata to
:param keys: A list of metadata keys to delete from the image
"""

View File

@ -184,7 +184,11 @@ def do_boot(cs, args):
security_groups=security_groups,
key_name=key_name,
block_device_mapping=block_device_mapping)
# Keep any information (like adminPass) returned by create
info = server._info
server = cs.servers.get(info['id'])
info.update(server._info)
flavor = info.get('flavor', {})
flavor_id = flavor.get('id', '')
@ -1123,7 +1127,8 @@ 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>', help='Path to a public ssh key.',
default=None)
def do_keypair_add(cs, args):
"""Create a new key pair for use with instances"""
name = args.name
@ -1134,7 +1139,8 @@ def do_keypair_add(cs, args):
with open(pub_key) as f:
pub_key = f.read()
except IOError, e:
raise exceptions.CommandError("Can't open or read '%s': %s" % (pub_key, e))
raise exceptions.CommandError("Can't open or read '%s': %s" % \
(pub_key, e))
keypair = cs.keypairs.create(name, pub_key)
@ -1155,4 +1161,3 @@ def do_keypair_list(cs, args):
keypairs = cs.keypairs.list()
columns = ['Name', 'Fingerprint']
utils.print_list(keypairs, columns)

View File

@ -128,5 +128,5 @@ class VolumeManager(base.ManagerWithFind):
:param server_id: The ID of the server
:param attachment_id: The ID of the attachment
"""
return self._delete("/servers/%s/os-volume_attachments/%s" % (server_id,
attachment_id,))
return self._delete("/servers/%s/os-volume_attachments/%s" %
(server_id, attachment_id,))

View File

@ -12,7 +12,7 @@ if sys.version_info < (2, 6):
setup(
name = "python-novaclient",
version = "2.6.6",
version = "2.6.7",
description = "Client library for OpenStack Nova API",
long_description = read('README.rst'),
url = 'https://github.com/rackspace/python-novaclient',