From e2d869d1daaca1047665fc47afe5f162e884035b Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Fri, 3 Feb 2012 16:03:07 -0600 Subject: [PATCH] Fixes bug 924588: Remove proto-keystone client from novaclient Change-Id: Ib3f3b8bfdefe56a13889796948a0186309c9a313 --- README.rst | 8 --- novaclient/keystone/__init__.py | 1 - novaclient/keystone/client.py | 67 -------------------- novaclient/keystone/shell.py | 99 ----------------------------- novaclient/keystone/tenants.py | 93 ---------------------------- novaclient/keystone/users.py | 106 -------------------------------- novaclient/shell.py | 2 - setup.py | 3 +- 8 files changed, 1 insertion(+), 378 deletions(-) delete mode 100644 novaclient/keystone/__init__.py delete mode 100644 novaclient/keystone/client.py delete mode 100644 novaclient/keystone/shell.py delete mode 100644 novaclient/keystone/tenants.py delete mode 100644 novaclient/keystone/users.py diff --git a/README.rst b/README.rst index d80497933..944edc85e 100644 --- a/README.rst +++ b/README.rst @@ -225,14 +225,6 @@ Quick-start using keystone:: >>> nt.keypairs.list() [...] - # if you want to use the keystone api to modify users/tenants: - >>> from novaclient import client - >>> conn = client.HTTPClient(USER, PASS, TENANT, KEYSTONE_URL) - >>> from novaclient import keystone - >>> kc = keystone.Client(conn.client) - >>> kc.tenants.list() - [...] - What's new? ----------- diff --git a/novaclient/keystone/__init__.py b/novaclient/keystone/__init__.py deleted file mode 100644 index c87b3f1b6..000000000 --- a/novaclient/keystone/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from novaclient.keystone.client import Client diff --git a/novaclient/keystone/client.py b/novaclient/keystone/client.py deleted file mode 100644 index 5cf87d357..000000000 --- a/novaclient/keystone/client.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2011 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy - -from novaclient.keystone import tenants -from novaclient.keystone import users - - -class Client(object): - """ - Top-level object to access the OpenStack Keystone API. - - Create an instance with your creds:: - - >>> from novaclient import client - >>> conn = client.HTTPClient(USER, PASS, TENANT, KEYSTONE_URL) - >>> from novaclient import keystone - >>> kc = keystone.Client(conn) - - Then call methods on its managers:: - - >>> kc.tenants.list() - ... - >>> kc.users.list() - ... - - """ - - def __init__(self, client): - # FIXME(ja): managers work by making calls against self.client - # which assumes management_url is set for the service. - # with keystone you get a token/endpoints for multiple - # services - so we have to clone and override the endpoint - # NOTE(ja): need endpoint from service catalog... no lazy auth - client.authenticate() - self.client = copy.copy(client) - endpoint = client.service_catalog.url_for(service_type='identity', - endpoint_type='adminURL') - self.client.management_url = endpoint - - self.tenants = tenants.TenantManager(self) - self.users = users.UserManager(self) - - def authenticate(self): - """ - Authenticate against the server. - - Normally this is called automatically when you first access the API, - but you can call this method to force authentication right now. - - Returns on success; raises :exc:`exceptions.Unauthorized` if the - credentials are wrong. - """ - self.client.authenticate() diff --git a/novaclient/keystone/shell.py b/novaclient/keystone/shell.py deleted file mode 100644 index 18299cd61..000000000 --- a/novaclient/keystone/shell.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright 2010 Jacob Kaplan-Moss - -# Copyright 2011 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import httplib2 -import urllib -import urlparse - -try: - import json -except ImportError: - import simplejson as json - -# Python 2.5 compat fix -if not hasattr(urlparse, 'parse_qsl'): - import cgi - urlparse.parse_qsl = cgi.parse_qsl - - -from novaclient import exceptions -from novaclient import utils -from novaclient import client - - -@utils.unauthenticated -def do_discover(cs, args): - """ - Discover Keystone servers and show authentication protocols supported. - - Usage: - $ nova discover - Keystone found at http://localhost:35357 - - supports version v2.0 (beta) here http://localhost:35357/v2.0 - Keystone found at https://openstack.org/ - - supports version v1.0 (DEPRECATED) here https://openstack.org/v1.0 - - supports version v1.1 (CURRENT) here https://openstack.org/v1.1 - - supports version v2.0 (BETA) here https://openstack.org/v2.0 - """ - _local_keystone_exists() - _check_keystone_versions(cs.client.auth_url) - - -def _local_keystone_exists(): - return _check_keystone_versions("http://localhost:35357") - - -def _check_keystone_versions(url): - try: - httpclient = client.HTTPClient(user=None, password=None, - projectid=None, auth_url=None) - resp, body = httpclient.request(url, "GET", - headers={'Accept': 'application/json'}) - if resp.status in (200, 204): # in some cases we get No Content - try: - print "Keystone found at %s" % url - if 'version' in body: - version = body['version'] - # Stable/diablo incorrect format - _display_version_info(version, url) - return True - if 'versions' in body: - # Correct format - for version in body['versions']['values']: - _display_version_info(version, url) - return True - print "Unrecognized response from %s" % url - except KeyError: - raise exceptions.AuthorizationFailure() - elif resp.status == 305: - return _check_keystone_versions(resp['location']) - else: - raise exceptions.from_response(resp, body) - except: - return False - - -def _display_version_info(version, url): - id = version['id'] - status = version['status'] - ref = urlparse.urljoin(url, id) - if 'links' in version: - for link in version['links']: - if link['rel'] == 'self': - ref = link['href'] - break - print " - supports version %s (%s) here %s" % (id, status, ref) diff --git a/novaclient/keystone/tenants.py b/novaclient/keystone/tenants.py deleted file mode 100644 index 68552c9b5..000000000 --- a/novaclient/keystone/tenants.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2011 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from novaclient import base - - -class RoleRefs(base.Resource): - def __repr__(self): - return "" % self._info - - -class Tenant(base.Resource): - def __repr__(self): - return "" % self._info - - def delete(self): - self.manager.delete(self) - - def update(self, description=None, enabled=None): - # FIXME(ja): set the attributes in this object if successful - self.manager.update(self.id, description, enabled) - - def add_user(self, user): - self.manager.add_user_to_tenant(self.id, base.getid(user)) - - -class TenantManager(base.ManagerWithFind): - resource_class = Tenant - - def get(self, tenant_id): - return self._get("/tenants/%s" % tenant_id, "tenant") - - # FIXME(ja): finialize roles once finalized in keystone - # right now the only way to add/remove a tenant is to - # give them a role within a project - def get_user_role_refs(self, user_id): - return self._get("/users/%s/roleRefs" % user_id, "roleRefs") - - def add_user_to_tenant(self, tenant_id, user_id): - params = {"roleRef": {"tenantId": tenant_id, "roleId": "Member"}} - return self._create("/users/%s/roleRefs" % user_id, params, "roleRef") - - def remove_user_from_tenant(self, tenant_id, user_id): - params = {"roleRef": {"tenantId": tenant_id, "roleId": "Member"}} - # FIXME(ja): we have to get the roleref? what is 5? - return self._delete("/users/%s/roleRefs/5" % user_id) - - def create(self, tenant_id, description=None, enabled=True): - """ - Create a new tenant. - """ - params = {"tenant": {"id": tenant_id, - "description": description, - "enabled": enabled}} - - return self._create('/tenants', params, "tenant") - - def list(self): - """ - Get a list of tenants. - :rtype: list of :class:`Tenant` - """ - return self._list("/tenants", "tenants") - - def update(self, tenant_id, description=None, enabled=None): - """ - update a tenant with a new name and description - """ - body = {"tenant": {'id': tenant_id}} - if enabled is not None: - body['tenant']['enabled'] = enabled - if description: - body['tenant']['description'] = description - - self._update("/tenants/%s" % tenant_id, body) - - def delete(self, tenant): - """ - Delete a tenant. - """ - self._delete("/tenants/%s" % (base.getid(tenant))) diff --git a/novaclient/keystone/users.py b/novaclient/keystone/users.py deleted file mode 100644 index 3a131dc08..000000000 --- a/novaclient/keystone/users.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2011 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from novaclient import base - - -class User(base.Resource): - def __repr__(self): - return "" % self._info - - def delete(self): - self.manager.delete(self) - - -class UserManager(base.ManagerWithFind): - resource_class = User - - def get(self, user): - return self._get("/users/%s" % base.getid(user), "user") - - def update_email(self, user, email): - """ - Update email - """ - # FIXME(ja): why do we have to send id in params and url? - params = {"user": {"id": base.getid(user), - "email": email}} - - self._update("/users/%s" % base.getid(user), params) - - def update_enabled(self, user, enabled): - """ - Update enabled-ness - """ - params = {"user": {"id": base.getid(user), - "enabled": enabled}} - - self._update("/users/%s/enabled" % base.getid(user), params) - - def update_password(self, user, password): - """ - Update password - """ - params = {"user": {"id": base.getid(user), - "password": password}} - - self._update("/users/%s/password" % base.getid(user), params) - - def update_tenant(self, user, tenant): - """ - Update default tenant. - """ - params = {"user": {"id": base.getid(user), - "tenantId": base.getid(tenant)}} - - # FIXME(ja): seems like a bad url - default tenant is an attribute - # not a subresource!??? - self._update("/users/%s/tenant" % base.getid(user), params) - - def create(self, user_id, password, email, tenant_id=None, enabled=True): - """ - Create a user. - """ - # FIXME(ja): email should be optional but keystone currently - # requires it - params = {"user": {"id": user_id, - "password": password, - "tenantId": tenant_id, - "email": email, - "enabled": enabled}} - return self._create('/users', params, "user") - - def _create(self, url, body, response_key): - # NOTE(ja): since we post the id, we have to use a PUT instead of POST - resp, body = self.api.client.put(url, body=body) - return self.resource_class(self, body[response_key]) - - def delete(self, user): - """ - Delete a user. - """ - self._delete("/users/%s" % base.getid(user)) - - def list(self, tenant_id=None): - """ - Get a list of users (optionally limited to a tenant) - - :rtype: list of :class:`User` - """ - - if not tenant_id: - return self._list("/users", "users") - else: - return self._list("/tenants/%s/users" % tenant_id, "users") diff --git a/novaclient/shell.py b/novaclient/shell.py index 71add1fe0..f56592d55 100644 --- a/novaclient/shell.py +++ b/novaclient/shell.py @@ -30,7 +30,6 @@ import sys from novaclient import client from novaclient import exceptions as exc import novaclient.extension -from novaclient.keystone import shell as shell_keystone from novaclient import utils from novaclient.v1_1 import shell as shell_v1_1 @@ -163,7 +162,6 @@ class OpenStackComputeShell(object): actions_module = shell_v1_1 self._find_actions(subparsers, actions_module) - self._find_actions(subparsers, shell_keystone) self._find_actions(subparsers, self) for extension in self.extensions: diff --git a/setup.py b/setup.py index 701295c33..c209667d4 100644 --- a/setup.py +++ b/setup.py @@ -37,8 +37,7 @@ setuptools.setup( long_description=read_file("README.rst"), license="Apache License, Version 2.0", url="https://github.com/openstack/python-novaclient", - packages=["novaclient", "novaclient.v1_1", "novaclient.v1_1.contrib", - "novaclient.keystone"], + packages=["novaclient", "novaclient.v1_1", "novaclient.v1_1.contrib"], install_requires=requirements, tests_require=["nose", "mock"], test_suite="nose.collector",