From cfbebeeae036f0c7db6c99f5e0c328469967da0d Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sat, 17 Dec 2011 22:07:13 -0800 Subject: [PATCH 01/16] initial pass to cliauth blueprint --- README.rst | 26 ++++++------ keystoneclient/client.py | 16 ++++---- keystoneclient/shell.py | 74 +++++++++++++++++------------------ keystoneclient/v2_0/client.py | 40 +++++++++---------- keystoneclient/v2_0/tokens.py | 17 +++++--- 5 files changed, 90 insertions(+), 83 deletions(-) diff --git a/README.rst b/README.rst index 5b009a7ea..5cb0f2ea8 100644 --- a/README.rst +++ b/README.rst @@ -27,7 +27,7 @@ By way of a quick-start:: # use v2.0 auth with http://example.com:5000/v2.0") >>> from keystoneclient.v2_0 import client - >>> keystone = client.Client(username=USERNAME, password=API_KEY, project_id=TENANT, auth_url=KEYSTONE_URL) + >>> keystone = client.Client(user_name=USERNAME, password=PASSWORD, tenant_name=TENANT, auth_url=KEYSTONE_URL) >>> keystone.tenants.list() >>> tenant = keystone.tenants.create(name="test", descrption="My new tenant!", enabled=True) >>> tenant.delete() @@ -48,17 +48,16 @@ You'll need to provide your OpenStack username and API key. You can do this with the ``--username``, ``--apikey`` and ``--projectid`` params, but it's easier to just set them as environment variables:: - export KEYSTONE_USERNAME=openstack - export KEYSTONE_API_KEY=yadayada - export KEYSTONE_PROJECTID=yadayada + export OS_TENANT_NAME=project + export OS_USER_NAME=user + export OS_PASSWORD=pass You will also need to define the authentication url with ``--url`` and the version of the API with ``--version``. Or set them as an environment variables as well:: - export KEYSTONE_URL=http://example.com:5000/v2.0 + export OS_AUTH_URL=http://example.com:5000/v2.0 export KEYSTONE_ADMIN_URL=http://example.com:35357/v2.0 - export KEYSTONE_VERSION=2.0 Since Keystone can return multiple regions in the Service Catalog, you can specify the one you want with ``--region_name`` (or @@ -67,8 +66,8 @@ can specify the one you want with ``--region_name`` (or You'll find complete documentation on the shell by running ``keystone help``:: - usage: keystone [--username USERNAME] [--apikey APIKEY] [--projectid PROJECTID] - [--url URL] [--version VERSION] [--region_name NAME] + usage: keystone [--user_name user] [--password password] + [--tenant_name tenant] [--auth_url URL] ... Command-line interface to the OpenStack Keystone API. @@ -79,11 +78,12 @@ You'll find complete documentation on the shell by running Optional arguments: - --username USERNAME Defaults to env[KEYSTONE_USERNAME]. - --apikey APIKEY Defaults to env[KEYSTONE_API_KEY]. - --apikey PROJECTID Defaults to env[KEYSTONE_PROJECT_ID]. - --url AUTH_URL Defaults to env[KEYSTONE_URL] or - --url ADMIN_URL Defaults to env[KEYSTONE_ADMIN_URL] + --user_name USER Defaults to env[OS_USER_NAME]. + --user_id USERID Defaults to env[OS_USER_ID]. + --password PASSWORD Defaults to env[OS_PASSWORD]. + --tenant_name TENANT Defaults to env[OS_TENANT_NAME]. + --tenant_id TENANTID Defaults to env[OS_TENANT_]. + --url AUTH_URL Defaults to env[OS_AUTH_URL] or --version VERSION Defaults to env[KEYSTONE_VERSION] or 2.0. --region_name NAME The region name in the Keystone Service Catalog to use after authentication. Defaults to diff --git a/keystoneclient/client.py b/keystoneclient/client.py index afdb5c281..94d9c9463 100644 --- a/keystoneclient/client.py +++ b/keystoneclient/client.py @@ -38,19 +38,22 @@ class HTTPClient(httplib2.Http): USER_AGENT = 'python-keystoneclient' - def __init__(self, username=None, password=None, token=None, + def __init__(self, user_name=None, user_id=None, + tenant_id=None, tenant_name=None, password=None, project_id=None, auth_url=None, region_name=None, - timeout=None, endpoint=None): + timeout=None, endpoint=None, token=None): super(HTTPClient, self).__init__(timeout=timeout) - self.user = username + self.user_id = user_id + self.user_name = user_name + self.tenant_id = tenant_id + self.tenant_name = tenant_name self.password = password - self.project_id = unicode(project_id) self.auth_url = auth_url self.version = 'v2.0' self.region_name = region_name + self.auth_token = token self.management_url = endpoint - self.auth_token = token or password # httplib2 overrides self.force_exception_to_status_code = True @@ -140,12 +143,11 @@ class HTTPClient(httplib2.Http): kwargs.setdefault('headers', {}) if self.auth_token and self.auth_token != self.password: kwargs['headers']['X-Auth-Token'] = self.auth_token - if self.project_id: - kwargs['headers']['X-Auth-Project-Id'] = self.project_id # Perform the request once. If we get a 401 back then it # might be because the auth token expired, so try to # re-authenticate and try again. If it still fails, bail. + print 'SENDING: %s' % kwargs try: resp, body = self.request(self.management_url + url, method, **kwargs) diff --git a/keystoneclient/shell.py b/keystoneclient/shell.py index 7d145fa75..0fb984090 100644 --- a/keystoneclient/shell.py +++ b/keystoneclient/shell.py @@ -55,21 +55,29 @@ class OpenStackIdentityShell(object): action='store_true', help=argparse.SUPPRESS) - parser.add_argument('--username', - default=env('KEYSTONE_USERNAME'), - help='Defaults to env[KEYSTONE_USERNAME].') + parser.add_argument('--user_name', + default=env('OS_USER_NAME'), + help='Defaults to env[OS_USER_NAME].') - parser.add_argument('--apikey', - default=env('KEYSTONE_API_KEY'), - help='Defaults to env[KEYSTONE_API_KEY].') + parser.add_argument('--user_id', + default=env('OS_USER_ID'), + help='Defaults to env[OS_USER_ID].') - parser.add_argument('--projectid', - default=env('KEYSTONE_PROJECT_ID'), - help='Defaults to env[KEYSTONE_PROJECT_ID].') + parser.add_argument('--password', + default=env('OS_PASSWORD'), + help='Defaults to env[OS_PASSWORD].') + + parser.add_argument('--tenant_name', + default=env('OS_TENANT_NAME'), + help='Defaults to env[OS_TENANT_NAME].') + + parser.add_argument('--tenant_id', + default=env('OS_TENANT_ID'), + help='Defaults to env[OS_TENANT_ID].') parser.add_argument('--url', - default=env('KEYSTONE_URL'), - help='Defaults to env[KEYSTONE_URL].') + default=env('OS_AUTH_URL'), + help='Defaults to env[OS_AUTH_URL].') parser.add_argument('--region_name', default=env('KEYSTONE_REGION_NAME'), @@ -144,37 +152,29 @@ class OpenStackIdentityShell(object): self.do_help(args) return 0 - user, apikey, projectid, url, region_name = \ - args.username, args.apikey, args.projectid, args.url, \ - args.region_name - #FIXME(usrleon): Here should be restrict for project id same as # for username or apikey but for compatibility it is not. - if not user: - raise exc.CommandError("You must provide a username, either" - "via --username or via " - "env[KEYSTONE_USERNAME]") - if not apikey: - raise exc.CommandError("You must provide an API key, either" - "via --apikey or via" - "env[KEYSTONE_API_KEY]") - if options.version and options.version != '1.0': - if not projectid: - raise exc.CommandError("You must provide an projectid, either" - "via --projectid or via" - "env[KEYSTONE_PROJECT_ID") + if not args.user_id and not args.user_name: + raise exc.CommandError("You must provide a user name or id:" + "via --user_name or env[OS_USER_NAME]" + "via --user_id or env[OS_USER_ID])") + if not args.password: + raise exc.CommandError("You must provide a password, either" + "via --password or env[OS_PASSWORD]") - if not url: - raise exc.CommandError("You must provide a auth url, either" - "via --url or via" - "env[KEYSTONE_URL") + if not args.url: + raise exc.CommandError("You must provide a auth url, either" + "via --auth_url or via" + "env[OS_AUTH_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_name=args.user_name, + user_id=args.user_id, + tenant_name=args.tenant_name, + tenant_id=args.tenant_id, + password=args.password, + auth_url=args.auth_url, + region_name=args.region_name) try: self.cs.authenticate() diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 21bc4c70a..c9dc6d565 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -12,7 +12,6 @@ # 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 urlparse import logging from keystoneclient import client @@ -86,20 +85,22 @@ class Client(client.HTTPClient): Returns ``True`` if authentication was successful. """ self.management_url = self.auth_url - try: - raw_token = self.tokens.authenticate(username=self.user, - password=self.password, - tenant=self.project_id, - token=self.auth_token, - return_raw=True) - self._extract_service_catalog(self.auth_url, raw_token) - return True - except (exceptions.AuthorizationFailure, exceptions.Unauthorized): - raise - except Exception, e: - _logger.exception("Authorization Failed.") - raise exceptions.AuthorizationFailure("Authorization Failed: " - "%s" % e) + # try: + raw_token = self.tokens.authenticate(user_name=self.user_name, + user_id=self.user_id, + tenant_id=self.tenant_id, + tenant_name=self.tenant_name, + password=self.password, + return_raw=True) + print 'got token %s' % raw_token + self._extract_service_catalog(self.auth_url, raw_token) + return True + # except (exceptions.AuthorizationFailure, exceptions.Unauthorized): + # raise + # except Exception, e: + # _logger.exception("Authorization Failed.") + # raise exceptions.AuthorizationFailure("Authorization Failed: " + # "%s" % e) def _extract_service_catalog(self, url, body): """ Set the client's service catalog from the response data. """ @@ -108,9 +109,8 @@ class Client(client.HTTPClient): self.auth_token = self.service_catalog.get_token() except KeyError: raise exceptions.AuthorizationFailure() - if self.project_id: - # Unscoped tokens don't return a service catalog - self.management_url = self.service_catalog.url_for( - attr='region', - filter_value=self.region_name) + + # Unscoped tokens don't return a service catalog + self.management_url = self.service_catalog.url_for(attr='region', + filter_value=self.region_name) return self.service_catalog diff --git a/keystoneclient/v2_0/tokens.py b/keystoneclient/v2_0/tokens.py index 581a71a28..a36980169 100644 --- a/keystoneclient/v2_0/tokens.py +++ b/keystoneclient/v2_0/tokens.py @@ -21,17 +21,22 @@ class Token(base.Resource): class TokenManager(base.ManagerWithFind): resource_class = Token - def authenticate(self, username=None, password=None, tenant=None, - token=None, return_raw=False): + def authenticate(self, user_name=None, user_id=None, tenant_id=None, + tenant_name=None, password=None, token=None, return_raw=False): if token and token != password: params = {"auth": {"token": {"id": token}}} - elif username and password: - params = {"auth": {"passwordCredentials": {"username": username, + elif user_name and password: + params = {"auth": {"passwordCredentials": {"username": user_name, + "password": password}}} + elif user_id and password: + params = {"auth": {"passwordCredentials": {"userId": user_id, "password": password}}} else: raise ValueError('A username and password or token is required.') - if tenant: - params['auth']['tenantId'] = tenant + if tenant_id: + params['auth']['tenantId'] = tenant_id + elif tenant_name: + params['auth']['tenantName'] = tenant_name return self._create('/tokens', params, "access", return_raw=return_raw) def endpoints(self, token): From 0f392a58c33aba4b7e6a6801a2a1e2f38066b57f Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sat, 17 Dec 2011 22:28:31 -0800 Subject: [PATCH 02/16] remove user_id as you shouldn't auth using it --- keystoneclient/client.py | 8 +++----- keystoneclient/shell.py | 12 +++--------- keystoneclient/v2_0/client.py | 1 - keystoneclient/v2_0/tokens.py | 7 ++----- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/keystoneclient/client.py b/keystoneclient/client.py index 94d9c9463..aad24467d 100644 --- a/keystoneclient/client.py +++ b/keystoneclient/client.py @@ -38,12 +38,10 @@ class HTTPClient(httplib2.Http): USER_AGENT = 'python-keystoneclient' - def __init__(self, user_name=None, user_id=None, - tenant_id=None, tenant_name=None, password=None, - project_id=None, auth_url=None, region_name=None, - timeout=None, endpoint=None, token=None): + def __init__(self, user_name=None, tenant_id=None, tenant_name=None, + password=None, project_id=None, auth_url=None, + region_name=None, timeout=None, endpoint=None, token=None): super(HTTPClient, self).__init__(timeout=timeout) - self.user_id = user_id self.user_name = user_name self.tenant_id = tenant_id self.tenant_name = tenant_name diff --git a/keystoneclient/shell.py b/keystoneclient/shell.py index 0fb984090..01f53c413 100644 --- a/keystoneclient/shell.py +++ b/keystoneclient/shell.py @@ -59,10 +59,6 @@ class OpenStackIdentityShell(object): default=env('OS_USER_NAME'), help='Defaults to env[OS_USER_NAME].') - parser.add_argument('--user_id', - default=env('OS_USER_ID'), - help='Defaults to env[OS_USER_ID].') - parser.add_argument('--password', default=env('OS_PASSWORD'), help='Defaults to env[OS_PASSWORD].') @@ -155,10 +151,9 @@ class OpenStackIdentityShell(object): #FIXME(usrleon): Here should be restrict for project id same as # for username or apikey but for compatibility it is not. - if not args.user_id and not args.user_name: - raise exc.CommandError("You must provide a user name or id:" - "via --user_name or env[OS_USER_NAME]" - "via --user_id or env[OS_USER_ID])") + if not args.user_name: + raise exc.CommandError("You must provide a user name:" + "via --user_name or env[OS_USER_NAME]") if not args.password: raise exc.CommandError("You must provide a password, either" "via --password or env[OS_PASSWORD]") @@ -169,7 +164,6 @@ class OpenStackIdentityShell(object): "env[OS_AUTH_URL") self.cs = self.get_api_class(options.version)(user_name=args.user_name, - user_id=args.user_id, tenant_name=args.tenant_name, tenant_id=args.tenant_id, password=args.password, diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index c9dc6d565..1dee548f9 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -87,7 +87,6 @@ class Client(client.HTTPClient): self.management_url = self.auth_url # try: raw_token = self.tokens.authenticate(user_name=self.user_name, - user_id=self.user_id, tenant_id=self.tenant_id, tenant_name=self.tenant_name, password=self.password, diff --git a/keystoneclient/v2_0/tokens.py b/keystoneclient/v2_0/tokens.py index a36980169..a79c1a50a 100644 --- a/keystoneclient/v2_0/tokens.py +++ b/keystoneclient/v2_0/tokens.py @@ -21,16 +21,13 @@ class Token(base.Resource): class TokenManager(base.ManagerWithFind): resource_class = Token - def authenticate(self, user_name=None, user_id=None, tenant_id=None, - tenant_name=None, password=None, token=None, return_raw=False): + def authenticate(self, user_name=None, tenant_id=None, tenant_name=None, + password=None, token=None, return_raw=False): if token and token != password: params = {"auth": {"token": {"id": token}}} elif user_name and password: params = {"auth": {"passwordCredentials": {"username": user_name, "password": password}}} - elif user_id and password: - params = {"auth": {"passwordCredentials": {"userId": user_id, - "password": password}}} else: raise ValueError('A username and password or token is required.') if tenant_id: From a8001d3e6c12fd5c09be8c90dc7ada145907dca6 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sat, 17 Dec 2011 22:36:59 -0800 Subject: [PATCH 03/16] more work on standardization of cliauth --- README.rst | 9 ++++----- keystoneclient/client.py | 4 ++-- keystoneclient/shell.py | 14 +++++++------- keystoneclient/v2_0/client.py | 2 +- keystoneclient/v2_0/tokens.py | 6 +++--- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/README.rst b/README.rst index 5cb0f2ea8..eff5f3043 100644 --- a/README.rst +++ b/README.rst @@ -27,7 +27,7 @@ By way of a quick-start:: # use v2.0 auth with http://example.com:5000/v2.0") >>> from keystoneclient.v2_0 import client - >>> keystone = client.Client(user_name=USERNAME, password=PASSWORD, tenant_name=TENANT, auth_url=KEYSTONE_URL) + >>> keystone = client.Client(username=USERNAME, password=PASSWORD, tenant_name=TENANT, auth_url=KEYSTONE_URL) >>> keystone.tenants.list() >>> tenant = keystone.tenants.create(name="test", descrption="My new tenant!", enabled=True) >>> tenant.delete() @@ -49,7 +49,7 @@ with the ``--username``, ``--apikey`` and ``--projectid`` params, but it's easier to just set them as environment variables:: export OS_TENANT_NAME=project - export OS_USER_NAME=user + export OS_USERNAME=user export OS_PASSWORD=pass You will also need to define the authentication url with ``--url`` and the @@ -66,7 +66,7 @@ can specify the one you want with ``--region_name`` (or You'll find complete documentation on the shell by running ``keystone help``:: - usage: keystone [--user_name user] [--password password] + usage: keystone [--username user] [--password password] [--tenant_name tenant] [--auth_url URL] ... @@ -78,8 +78,7 @@ You'll find complete documentation on the shell by running Optional arguments: - --user_name USER Defaults to env[OS_USER_NAME]. - --user_id USERID Defaults to env[OS_USER_ID]. + --username USER Defaults to env[OS_USERNAME]. --password PASSWORD Defaults to env[OS_PASSWORD]. --tenant_name TENANT Defaults to env[OS_TENANT_NAME]. --tenant_id TENANTID Defaults to env[OS_TENANT_]. diff --git a/keystoneclient/client.py b/keystoneclient/client.py index aad24467d..a29e34afa 100644 --- a/keystoneclient/client.py +++ b/keystoneclient/client.py @@ -38,11 +38,11 @@ class HTTPClient(httplib2.Http): USER_AGENT = 'python-keystoneclient' - def __init__(self, user_name=None, tenant_id=None, tenant_name=None, + def __init__(self, username=None, tenant_id=None, tenant_name=None, password=None, project_id=None, auth_url=None, region_name=None, timeout=None, endpoint=None, token=None): super(HTTPClient, self).__init__(timeout=timeout) - self.user_name = user_name + self.username = username self.tenant_id = tenant_id self.tenant_name = tenant_name self.password = password diff --git a/keystoneclient/shell.py b/keystoneclient/shell.py index 01f53c413..9232d14a1 100644 --- a/keystoneclient/shell.py +++ b/keystoneclient/shell.py @@ -55,9 +55,9 @@ class OpenStackIdentityShell(object): action='store_true', help=argparse.SUPPRESS) - parser.add_argument('--user_name', - default=env('OS_USER_NAME'), - help='Defaults to env[OS_USER_NAME].') + parser.add_argument('--username', + default=env('OS_USERNAME'), + help='Defaults to env[OS_USERNAME].') parser.add_argument('--password', default=env('OS_PASSWORD'), @@ -151,9 +151,9 @@ class OpenStackIdentityShell(object): #FIXME(usrleon): Here should be restrict for project id same as # for username or apikey but for compatibility it is not. - if not args.user_name: - raise exc.CommandError("You must provide a user name:" - "via --user_name or env[OS_USER_NAME]") + if not args.username: + raise exc.CommandError("You must provide a username:" + "via --username or env[OS_USERNAME]") if not args.password: raise exc.CommandError("You must provide a password, either" "via --password or env[OS_PASSWORD]") @@ -163,7 +163,7 @@ class OpenStackIdentityShell(object): "via --auth_url or via" "env[OS_AUTH_URL") - self.cs = self.get_api_class(options.version)(user_name=args.user_name, + self.cs = self.get_api_class(options.version)(username=args.username, tenant_name=args.tenant_name, tenant_id=args.tenant_id, password=args.password, diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 1dee548f9..627634c38 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -86,7 +86,7 @@ class Client(client.HTTPClient): """ self.management_url = self.auth_url # try: - raw_token = self.tokens.authenticate(user_name=self.user_name, + raw_token = self.tokens.authenticate(username=self.username, tenant_id=self.tenant_id, tenant_name=self.tenant_name, password=self.password, diff --git a/keystoneclient/v2_0/tokens.py b/keystoneclient/v2_0/tokens.py index a79c1a50a..0b3c57901 100644 --- a/keystoneclient/v2_0/tokens.py +++ b/keystoneclient/v2_0/tokens.py @@ -21,12 +21,12 @@ class Token(base.Resource): class TokenManager(base.ManagerWithFind): resource_class = Token - def authenticate(self, user_name=None, tenant_id=None, tenant_name=None, + def authenticate(self, username=None, tenant_id=None, tenant_name=None, password=None, token=None, return_raw=False): if token and token != password: params = {"auth": {"token": {"id": token}}} - elif user_name and password: - params = {"auth": {"passwordCredentials": {"username": user_name, + elif username and password: + params = {"auth": {"passwordCredentials": {"username": username, "password": password}}} else: raise ValueError('A username and password or token is required.') From 55c01652b2d4b42572ec4615bffdc2ee8970cd48 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sat, 17 Dec 2011 22:48:37 -0800 Subject: [PATCH 04/16] remove print statements and uncomment exceptions --- keystoneclient/client.py | 1 - keystoneclient/v2_0/client.py | 29 ++++++++++++++--------------- tests/v2_0/test_tenants.py | 1 - 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/keystoneclient/client.py b/keystoneclient/client.py index a29e34afa..0c2b9cd21 100644 --- a/keystoneclient/client.py +++ b/keystoneclient/client.py @@ -145,7 +145,6 @@ class HTTPClient(httplib2.Http): # Perform the request once. If we get a 401 back then it # might be because the auth token expired, so try to # re-authenticate and try again. If it still fails, bail. - print 'SENDING: %s' % kwargs try: resp, body = self.request(self.management_url + url, method, **kwargs) diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 627634c38..c5e5545b9 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -85,21 +85,20 @@ class Client(client.HTTPClient): Returns ``True`` if authentication was successful. """ self.management_url = self.auth_url - # try: - raw_token = self.tokens.authenticate(username=self.username, - tenant_id=self.tenant_id, - tenant_name=self.tenant_name, - password=self.password, - return_raw=True) - print 'got token %s' % raw_token - self._extract_service_catalog(self.auth_url, raw_token) - return True - # except (exceptions.AuthorizationFailure, exceptions.Unauthorized): - # raise - # except Exception, e: - # _logger.exception("Authorization Failed.") - # raise exceptions.AuthorizationFailure("Authorization Failed: " - # "%s" % e) + try: + raw_token = self.tokens.authenticate(username=self.username, + tenant_id=self.tenant_id, + tenant_name=self.tenant_name, + password=self.password, + return_raw=True) + self._extract_service_catalog(self.auth_url, raw_token) + return True + except (exceptions.AuthorizationFailure, exceptions.Unauthorized): + raise + except Exception, e: + _logger.exception("Authorization Failed.") + raise exceptions.AuthorizationFailure("Authorization Failed: " + "%s" % e) def _extract_service_catalog(self, url, body): """ Set the client's service catalog from the response data. """ diff --git a/tests/v2_0/test_tenants.py b/tests/v2_0/test_tenants.py index 2b8751c5c..77aa94ce7 100644 --- a/tests/v2_0/test_tenants.py +++ b/tests/v2_0/test_tenants.py @@ -144,7 +144,6 @@ class TenantTests(utils.TestCase): req_body['tenant']['name'], req_body['tenant']['description'], req_body['tenant']['enabled']) - print tenant self.assertTrue(isinstance(tenant, tenants.Tenant)) self.assertEqual(tenant.id, 4) self.assertEqual(tenant.name, "tenantX") From 70f83389a93b364fa9486bcc8be47f793f2f60cb Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sat, 17 Dec 2011 22:50:49 -0800 Subject: [PATCH 05/16] typo in comments --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index eff5f3043..8134152af 100644 --- a/README.rst +++ b/README.rst @@ -81,7 +81,7 @@ You'll find complete documentation on the shell by running --username USER Defaults to env[OS_USERNAME]. --password PASSWORD Defaults to env[OS_PASSWORD]. --tenant_name TENANT Defaults to env[OS_TENANT_NAME]. - --tenant_id TENANTID Defaults to env[OS_TENANT_]. + --tenant_id TENANTID Defaults to env[OS_TENANT_ID]. --url AUTH_URL Defaults to env[OS_AUTH_URL] or --version VERSION Defaults to env[KEYSTONE_VERSION] or 2.0. --region_name NAME The region name in the Keystone Service Catalog From caad71d1b74c17148e29e94a99d0879d77fe1ad0 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sat, 17 Dec 2011 23:02:27 -0800 Subject: [PATCH 06/16] more work on standardizing project_id --- docs/shell.rst | 36 ++++++++++++++++++++--------------- keystoneclient/v2_0/client.py | 6 ++++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/docs/shell.rst b/docs/shell.rst index fb1ea7413..d19a75577 100644 --- a/docs/shell.rst +++ b/docs/shell.rst @@ -12,27 +12,33 @@ The :program:`keystone` shell utility The :program:`keystone` shell utility interacts with OpenStack Keystone API from the command line. It supports the entirety of the OpenStack Keystone API. -First, you'll need an OpenStack Keystone account and an API key. You get this -by using the `keystone-manage` command in OpenStack Keystone. +First, you'll need an OpenStack Keystone account. You get this by using the +`keystone-manage` command in OpenStack Keystone. You'll need to provide :program:`keystone` with your OpenStack username and -API key. You can do this with the :option:`--username`, :option:`--apikey` -and :option:`--projectid` options, but it's easier to just set them as -environment variables by setting two environment variables: +password. You can do this with the :option:`--username`, :option:`--password`. +You can optionally specify a :option:`--tenant_id` or :option:`--tenant_name`, +to scope your token to a specific tenant. If you don't specify a tenant, you +will be scoped to your default tenant if you have one. Instead of using +options, it is easier to just set them as environment variables: -.. envvar:: KEYSTONE_USERNAME +.. envvar:: OS_USERNAME Your Keystone username. -.. envvar:: KEYSTONE_API_KEY +.. envvar:: OS_PASSWORD - Your API key. + Your Keystone password. -.. envvar:: KEYSTONE_PROJECT_ID +.. envvar:: OS_TENANT_NAME - Project for work. + Name of Keystone Tenant. -.. envvar:: KEYSTONE_URL +.. envvar:: OS_TENANT_ID + + ID of Keystone Tenant. + +.. envvar:: OS_AUTH_URL The OpenStack API server URL. @@ -42,10 +48,10 @@ environment variables by setting two environment variables: For example, in Bash you'd use:: - export KEYSTONE_USERNAME=yourname - export KEYSTONE_API_KEY=yadayadayada - export KEYSTONE_PROJECT_ID=myproject - export KEYSTONE_URL=http://... + export OS_USERNAME=yourname + export OS_PASSWORD=yadayadayada + export OS_TENANT_NAME=myproject + export OS_AUTH_URL=http://example.com:5000/v2.0/ export KEYSTONE_VERSION=2.0 From there, all shell commands take the form:: diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index c5e5545b9..403d57109 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -33,7 +33,9 @@ class Client(client.HTTPClient): :param string username: Username for authentication. (optional) :param string password: Password for authentication. (optional) :param string token: Token for authentication. (optional) - :param string project_id: Tenant/Project id. (optional) + :param string tenant_name: Tenant id. (optional) + :param string tenant_id: Tenant name. (optional) + :param string project_id: Converted to tenant name. (deprecated - to be removed in essex) :param string auth_url: Keystone service endpoint for authorization. :param string region_name: Name of a region to select when choosing an endpoint from the service catalog. @@ -49,7 +51,7 @@ class Client(client.HTTPClient): >>> from keystoneclient.v2_0 import client >>> keystone = client.Client(username=USER, password=PASS, - project_id=TENANT, + tenant_name=TENANT, auth_url=KEYSTONE_URL) >>> keystone.tenants.list() ... From 74bdba290b7b7c61909d0c7ab48161cff3a3f5c7 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sun, 18 Dec 2011 21:26:38 -0800 Subject: [PATCH 07/16] set the management_url from the service_catalog --- keystoneclient/v2_0/client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 403d57109..23e50eb10 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -72,6 +72,7 @@ class Client(client.HTTPClient): # get away with lazy auth. Otherwise auth immediately. if endpoint is None: self.authenticate() + self.management_url = self.service_catalog.url_for(endpoint_type='adminURL') else: self.management_url = endpoint From 604b748b517f61da29fa3b9e572fdade3bbaa803 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sun, 18 Dec 2011 21:31:23 -0800 Subject: [PATCH 08/16] pep8 --- keystoneclient/shell.py | 10 +++++----- keystoneclient/v2_0/client.py | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/keystoneclient/shell.py b/keystoneclient/shell.py index 9232d14a1..7de3edc6f 100644 --- a/keystoneclient/shell.py +++ b/keystoneclient/shell.py @@ -164,11 +164,11 @@ class OpenStackIdentityShell(object): "env[OS_AUTH_URL") self.cs = self.get_api_class(options.version)(username=args.username, - tenant_name=args.tenant_name, - tenant_id=args.tenant_id, - password=args.password, - auth_url=args.auth_url, - region_name=args.region_name) + tenant_name=args.tenant_name, + tenant_id=args.tenant_id, + password=args.password, + auth_url=args.auth_url, + region_name=args.region_name) try: self.cs.authenticate() diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 23e50eb10..b2d4e2251 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -35,7 +35,8 @@ class Client(client.HTTPClient): :param string token: Token for authentication. (optional) :param string tenant_name: Tenant id. (optional) :param string tenant_id: Tenant name. (optional) - :param string project_id: Converted to tenant name. (deprecated - to be removed in essex) + :param string project_id: Converted to tenant name. (deprecated - + to be removed in essex) :param string auth_url: Keystone service endpoint for authorization. :param string region_name: Name of a region to select when choosing an endpoint from the service catalog. @@ -72,7 +73,9 @@ class Client(client.HTTPClient): # get away with lazy auth. Otherwise auth immediately. if endpoint is None: self.authenticate() - self.management_url = self.service_catalog.url_for(endpoint_type='adminURL') + self.management_url = self.service_catalog.url_for( + service_type='identity', + endpoint_type='adminURL') else: self.management_url = endpoint From d37c20ca72fbcdb929601b8af1ef8fedd76e1afd Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sun, 18 Dec 2011 22:08:26 -0800 Subject: [PATCH 09/16] remove X-Auth-Project-Id, re-add auth by token support (most tests pass) --- keystoneclient/v2_0/client.py | 1 + tests/test_http.py | 2 -- tests/utils.py | 4 ++-- tests/v2_0/test_auth.py | 20 ++++++++------------ tests/v2_0/test_roles.py | 6 ++---- tests/v2_0/test_services.py | 6 ++---- tests/v2_0/test_tenants.py | 6 ++---- tests/v2_0/test_tokens.py | 6 ++---- tests/v2_0/test_users.py | 6 ++---- 9 files changed, 21 insertions(+), 36 deletions(-) diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index b2d4e2251..66ee58462 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -96,6 +96,7 @@ class Client(client.HTTPClient): tenant_id=self.tenant_id, tenant_name=self.tenant_name, password=self.password, + token=self.auth_token, return_raw=True) self._extract_service_catalog(self.auth_url, raw_token) return True diff --git a/tests/test_http.py b/tests/test_http.py index e91d58fc0..96a38ee9c 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -33,7 +33,6 @@ class ClientTest(utils.TestCase): def test_get_call(): resp, body = cl.get("/hi") headers = {"X-Auth-Token": "token", - "X-Auth-Project-Id": "project_id", "User-Agent": cl.USER_AGENT, } mock_request.assert_called_with("http://127.0.0.1:5000/" @@ -52,7 +51,6 @@ class ClientTest(utils.TestCase): cl.post("/hi", body=[1, 2, 3]) headers = { "X-Auth-Token": "token", - "X-Auth-Project-Id": "project_id", "Content-Type": "application/json", "User-Agent": cl.USER_AGENT } diff --git a/tests/utils.py b/tests/utils.py index bf20e2155..6bdbb2d8c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -8,7 +8,7 @@ from keystoneclient.v2_0 import client class TestCase(unittest.TestCase): - TEST_TENANT = '1' + TEST_TENANT_ID = '1' TEST_TENANT_NAME = 'aTenant' TEST_TOKEN = 'aToken' TEST_USER = 'test' @@ -70,7 +70,7 @@ class TestCase(unittest.TestCase): httplib2.Http.request = self.mox.CreateMockAnything() self.client = client.Client(username=self.TEST_USER, token=self.TEST_TOKEN, - project_id=self.TEST_TENANT, + tenant_name=self.TEST_TENANT_ID, auth_url=self.TEST_URL, endpoint=self.TEST_URL) diff --git a/tests/v2_0/test_auth.py b/tests/v2_0/test_auth.py index 00c3d8586..1b8f22ea2 100644 --- a/tests/v2_0/test_auth.py +++ b/tests/v2_0/test_auth.py @@ -36,7 +36,7 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): "username": self.TEST_USER, "password": self.TEST_TOKEN, }, - "tenantId": self.TEST_TENANT + "tenantId": self.TEST_TENANT_ID } } self.TEST_REQUEST_HEADERS = { @@ -47,7 +47,6 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): def test_authenticate_failure(self): self.TEST_REQUEST_BODY['auth']['passwordCredentials']['password'] = \ 'bad_key' - self.TEST_REQUEST_HEADERS['X-Auth-Project-Id'] = '1' resp = httplib2.Response({ "status": 401, "body": json.dumps({"unauthorized": { @@ -70,11 +69,10 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): with self.assertRaises(exceptions.Unauthorized): client.Client(username=self.TEST_USER, password="bad_key", - project_id=self.TEST_TENANT, + tenant_id=self.TEST_TENANT_ID, auth_url=self.TEST_URL) def test_auth_redirect(self): - self.TEST_REQUEST_HEADERS['X-Auth-Project-Id'] = '1' correct_response = json.dumps(self.TEST_RESPONSE_DICT) dict_responses = [ {"headers": {'location': self.TEST_ADMIN_URL + "/tokens"}, @@ -101,17 +99,16 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): cs = client.Client(username=self.TEST_USER, password=self.TEST_TOKEN, - project_id=self.TEST_TENANT, + tenant_id=self.TEST_TENANT_ID, auth_url=self.TEST_URL) self.assertEqual(cs.management_url, self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3] - ['endpoints'][0]["publicURL"]) + ['endpoints'][0]["adminURL"]) self.assertEqual(cs.auth_token, self.TEST_RESPONSE_DICT["access"]["token"]["id"]) def test_authenticate_success_password_scoped(self): - self.TEST_REQUEST_HEADERS['X-Auth-Project-Id'] = '1' resp = httplib2.Response({ "status": 200, "body": json.dumps(self.TEST_RESPONSE_DICT), @@ -126,11 +123,11 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): cs = client.Client(username=self.TEST_USER, password=self.TEST_TOKEN, - project_id=self.TEST_TENANT, + tenant_id=self.TEST_TENANT_ID, auth_url=self.TEST_URL) self.assertEqual(cs.management_url, self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3] - ['endpoints'][0]["publicURL"]) + ['endpoints'][0]["adminURL"]) self.assertEqual(cs.auth_token, self.TEST_RESPONSE_DICT["access"]["token"]["id"]) @@ -159,7 +156,6 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): def test_authenticate_success_token_scoped(self): del self.TEST_REQUEST_BODY['auth']['passwordCredentials'] self.TEST_REQUEST_BODY['auth']['token'] = {'id': self.TEST_TOKEN} - self.TEST_REQUEST_HEADERS['X-Auth-Project-Id'] = '1' self.TEST_REQUEST_HEADERS['X-Auth-Token'] = self.TEST_TOKEN resp = httplib2.Response({ "status": 200, @@ -174,11 +170,11 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): self.mox.ReplayAll() cs = client.Client(token=self.TEST_TOKEN, - project_id=self.TEST_TENANT, + tenant_id=self.TEST_TENANT_ID, auth_url=self.TEST_URL) self.assertEqual(cs.management_url, self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3] - ['endpoints'][0]["publicURL"]) + ['endpoints'][0]["adminURL"]) self.assertEqual(cs.auth_token, self.TEST_RESPONSE_DICT["access"]["token"]["id"]) diff --git a/tests/v2_0/test_roles.py b/tests/v2_0/test_roles.py index fe12658ff..f051243f6 100644 --- a/tests/v2_0/test_roles.py +++ b/tests/v2_0/test_roles.py @@ -10,11 +10,9 @@ from tests import utils class RoleTests(utils.TestCase): def setUp(self): super(RoleTests, self).setUp() - self.TEST_REQUEST_HEADERS = {'X-Auth-Project-Id': '1', - 'X-Auth-Token': 'aToken', + self.TEST_REQUEST_HEADERS = {'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} - self.TEST_POST_HEADERS = {'X-Auth-Project-Id': '1', - 'Content-Type': 'application/json', + self.TEST_POST_HEADERS = {'Content-Type': 'application/json', 'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} self.TEST_ROLES = { diff --git a/tests/v2_0/test_services.py b/tests/v2_0/test_services.py index 93f3d4569..1d3118ed7 100644 --- a/tests/v2_0/test_services.py +++ b/tests/v2_0/test_services.py @@ -10,11 +10,9 @@ from tests import utils class ServiceTests(utils.TestCase): def setUp(self): super(ServiceTests, self).setUp() - self.TEST_REQUEST_HEADERS = {'X-Auth-Project-Id': '1', - 'X-Auth-Token': 'aToken', + self.TEST_REQUEST_HEADERS = {'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} - self.TEST_POST_HEADERS = {'X-Auth-Project-Id': '1', - 'Content-Type': 'application/json', + self.TEST_POST_HEADERS = {'Content-Type': 'application/json', 'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} self.TEST_SERVICES = {"OS-KSADM:services": { diff --git a/tests/v2_0/test_tenants.py b/tests/v2_0/test_tenants.py index 77aa94ce7..ea4f78b54 100644 --- a/tests/v2_0/test_tenants.py +++ b/tests/v2_0/test_tenants.py @@ -10,11 +10,9 @@ from tests import utils class TenantTests(utils.TestCase): def setUp(self): super(TenantTests, self).setUp() - self.TEST_REQUEST_HEADERS = {'X-Auth-Project-Id': '1', - 'X-Auth-Token': 'aToken', + self.TEST_REQUEST_HEADERS = {'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} - self.TEST_POST_HEADERS = {'X-Auth-Project-Id': '1', - 'Content-Type': 'application/json', + self.TEST_POST_HEADERS = {'Content-Type': 'application/json', 'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} self.TEST_TENANTS = {"tenants": { diff --git a/tests/v2_0/test_tokens.py b/tests/v2_0/test_tokens.py index 49655595b..1edcba62a 100644 --- a/tests/v2_0/test_tokens.py +++ b/tests/v2_0/test_tokens.py @@ -10,11 +10,9 @@ from tests import utils class TokenTests(utils.TestCase): def setUp(self): #super(ServiceTests, self).setUp() - self.TEST_REQUEST_HEADERS = {'X-Auth-Project-Id': '1', - 'X-Auth-Token': 'aToken', + self.TEST_REQUEST_HEADERS = {'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} - self.TEST_POST_HEADERS = {'X-Auth-Project-Id': '1', - 'Content-Type': 'application/json', + self.TEST_POST_HEADERS = {'Content-Type': 'application/json', 'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} ''' diff --git a/tests/v2_0/test_users.py b/tests/v2_0/test_users.py index fb6955903..dbff00870 100644 --- a/tests/v2_0/test_users.py +++ b/tests/v2_0/test_users.py @@ -10,11 +10,9 @@ from tests import utils class UserTests(utils.TestCase): def setUp(self): super(UserTests, self).setUp() - self.TEST_REQUEST_HEADERS = {'X-Auth-Project-Id': '1', - 'X-Auth-Token': 'aToken', + self.TEST_REQUEST_HEADERS = {'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} - self.TEST_POST_HEADERS = {'X-Auth-Project-Id': '1', - 'Content-Type': 'application/json', + self.TEST_POST_HEADERS = {'Content-Type': 'application/json', 'X-Auth-Token': 'aToken', 'User-Agent': 'python-keystoneclient'} self.TEST_USERS = { From 12969bb677844dc09d86b045b1c04f09f83a5c44 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sun, 18 Dec 2011 23:19:26 -0800 Subject: [PATCH 10/16] Fix the tests --- keystoneclient/v2_0/client.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 66ee58462..dda1a239d 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -73,9 +73,6 @@ class Client(client.HTTPClient): # get away with lazy auth. Otherwise auth immediately. if endpoint is None: self.authenticate() - self.management_url = self.service_catalog.url_for( - service_type='identity', - endpoint_type='adminURL') else: self.management_url = endpoint @@ -115,7 +112,12 @@ class Client(client.HTTPClient): except KeyError: raise exceptions.AuthorizationFailure() - # Unscoped tokens don't return a service catalog - self.management_url = self.service_catalog.url_for(attr='region', - filter_value=self.region_name) - return self.service_catalog + # FIXME(ja): we should be lazy about setting managment_url. + # in fact we should rewrite the client to support the service + # catalog (api calls should be directable to any endpoints) + try: + self.management_url = self.service_catalog.url_for(attr='region', + filter_value=self.region_name, endpoint_type='adminURL') + except: + # Unscoped tokens don't return a service catalog + pass From 977227ce3e6b93d2f8408858f472b3c0e02caf21 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Sun, 18 Dec 2011 23:29:00 -0800 Subject: [PATCH 11/16] update test env shell --- tests/test_shell.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_shell.py b/tests/test_shell.py index 227b120c1..9c99bc298 100644 --- a/tests/test_shell.py +++ b/tests/test_shell.py @@ -13,10 +13,10 @@ class ShellTest(utils.TestCase): def setUp(self): global _old_env fake_env = { - 'KEYSTONE_USERNAME': 'username', - 'KEYSTONE_API_KEY': 'password', - 'KEYSTONE_PROJECT_ID': 'project_id', - 'KEYSTONE_URL': 'http://127.0.0.1:5000', + 'OS_USERNAME': 'username', + 'OS_PASSWORD': 'password', + 'OS_TENANT_ID': 'tenant_id', + 'OS_AUTH_URL': 'http://127.0.0.1:5000/v2.0', } _old_env, os.environ = os.environ, fake_env.copy() From f765daf3360727c2baee0cfc9114d8728c1c4336 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Mon, 19 Dec 2011 10:00:39 -0800 Subject: [PATCH 12/16] finish removing project_id --- keystoneclient/client.py | 4 ++-- keystoneclient/v2_0/client.py | 2 -- tests/test_http.py | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/keystoneclient/client.py b/keystoneclient/client.py index 0c2b9cd21..bd5d30924 100644 --- a/keystoneclient/client.py +++ b/keystoneclient/client.py @@ -39,8 +39,8 @@ class HTTPClient(httplib2.Http): USER_AGENT = 'python-keystoneclient' def __init__(self, username=None, tenant_id=None, tenant_name=None, - password=None, project_id=None, auth_url=None, - region_name=None, timeout=None, endpoint=None, token=None): + password=None, auth_url=None, region_name=None, timeout=None, + endpoint=None, token=None): super(HTTPClient, self).__init__(timeout=timeout) self.username = username self.tenant_id = tenant_id diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index dda1a239d..02e936a7d 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -35,8 +35,6 @@ class Client(client.HTTPClient): :param string token: Token for authentication. (optional) :param string tenant_name: Tenant id. (optional) :param string tenant_id: Tenant name. (optional) - :param string project_id: Converted to tenant name. (deprecated - - to be removed in essex) :param string auth_url: Keystone service endpoint for authorization. :param string region_name: Name of a region to select when choosing an endpoint from the service catalog. diff --git a/tests/test_http.py b/tests/test_http.py index 96a38ee9c..4da7b5516 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -11,8 +11,8 @@ mock_request = mock.Mock(return_value=(fake_response, fake_body)) def get_client(): - cl = client.HTTPClient(username="username", password="apikey", - project_id="project_id", auth_url="auth_test") + cl = client.HTTPClient(username="username", password="password", + tenant_id="tenant", auth_url="auth_test") return cl From 11a49bbe7d00b75f7ac294b10352d0e3e4169c49 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Mon, 19 Dec 2011 10:03:08 -0800 Subject: [PATCH 13/16] use full name for args in readme --- README.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.rst b/README.rst index 8134152af..e47c657af 100644 --- a/README.rst +++ b/README.rst @@ -78,15 +78,15 @@ You'll find complete documentation on the shell by running Optional arguments: - --username USER Defaults to env[OS_USERNAME]. - --password PASSWORD Defaults to env[OS_PASSWORD]. - --tenant_name TENANT Defaults to env[OS_TENANT_NAME]. - --tenant_id TENANTID Defaults to env[OS_TENANT_ID]. - --url AUTH_URL Defaults to env[OS_AUTH_URL] or - --version VERSION Defaults to env[KEYSTONE_VERSION] or 2.0. - --region_name NAME The region name in the Keystone Service Catalog - to use after authentication. Defaults to - env[KEYSTONE_REGION_NAME] or the first item - in the list returned. + --username USER Defaults to env[OS_USERNAME]. + --password PASSWORD Defaults to env[OS_PASSWORD]. + --tenant_name TENANT_NAME Defaults to env[OS_TENANT_NAME]. + --tenant_id TENANT_ID Defaults to env[OS_TENANT_ID]. + --url AUTH_URL Defaults to env[OS_AUTH_URL] or + --version VERSION Defaults to env[KEYSTONE_VERSION] or 2.0. + --region_name NAME The region name in the Keystone Service + Catalog to use after authentication. + Defaults to env[KEYSTONE_REGION_NAME] or the + first item in the list returned. See "keystone help COMMAND" for help on a specific command. From 8ab0bb9d2260f66f7e85805e997df686ee9d2e74 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Mon, 19 Dec 2011 11:35:27 -0800 Subject: [PATCH 14/16] should have had tenant_name --- tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index 6bdbb2d8c..c4530e8d0 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -70,7 +70,7 @@ class TestCase(unittest.TestCase): httplib2.Http.request = self.mox.CreateMockAnything() self.client = client.Client(username=self.TEST_USER, token=self.TEST_TOKEN, - tenant_name=self.TEST_TENANT_ID, + tenant_name=self.TEST_TENANT_NAME, auth_url=self.TEST_URL, endpoint=self.TEST_URL) From 1805097c8b20c65197d59340c38b74f7754167ac Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Mon, 19 Dec 2011 11:36:31 -0800 Subject: [PATCH 15/16] update comment to be tenant_name --- keystoneclient/v2_0/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 02e936a7d..46a6afed5 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -50,7 +50,7 @@ class Client(client.HTTPClient): >>> from keystoneclient.v2_0 import client >>> keystone = client.Client(username=USER, password=PASS, - tenant_name=TENANT, + tenant_name=TENANT_NAME, auth_url=KEYSTONE_URL) >>> keystone.tenants.list() ... From 6e970244a0a6f2a4c4719cca75b95d3248286b82 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Wed, 21 Dec 2011 13:00:10 -0800 Subject: [PATCH 16/16] log when no service catalog --- keystoneclient/v2_0/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 46a6afed5..a7fc3b252 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -118,4 +118,4 @@ class Client(client.HTTPClient): filter_value=self.region_name, endpoint_type='adminURL') except: # Unscoped tokens don't return a service catalog - pass + _logger.exception("unable to retrieve service catalog with token")