Import access module from keystoneclient to handle V3 endpoints

* service_catalog.py will be used only by nova(cinder.py), it will be removed if nova
uses access instead of service_catalog. Then service_catalog.py and
test_service_catalog.py will be removed from cinderclient if necessary.

* Some unit tests are modified.

* Because of JSON format's modification, functions that process cinder
credentials and cinder endpoints are changed.

* Add dependency for keystoneclient in requirements.txt.

Change-Id: Icf7badfdddcf5f55536d95db7242aff58aa34b6e
Closes-Bug: #1263876
bp: service-catalog
This commit is contained in:
Shao Kai Li 2014-02-19 00:34:30 -05:00
parent 3ec28c3309
commit 1b0ea8768c
7 changed files with 34 additions and 115 deletions

View File

@ -45,8 +45,9 @@ if not hasattr(urlparse, 'parse_qsl'):
import requests
from keystoneclient import access
from cinderclient import exceptions
from cinderclient import service_catalog
from cinderclient import utils
@ -223,19 +224,17 @@ class HTTPClient(object):
if resp.status_code == 200: # content must always present
try:
self.auth_url = url
self.service_catalog = \
service_catalog.ServiceCatalog(body)
self.auth_ref = access.AccessInfo.factory(resp, body)
self.service_catalog = self.auth_ref.service_catalog
if extract_token:
self.auth_token = self.service_catalog.get_token()
self.auth_token = self.auth_ref.auth_token
management_url = self.service_catalog.url_for(
attr='region',
filter_value=self.region_name,
endpoint_type=self.endpoint_type,
service_type=self.service_type,
service_name=self.service_name,
volume_service_name=self.volume_service_name)
service_type=self.service_type)
self.management_url = management_url.rstrip('/')
return None
except exceptions.AmbiguousEndpoints:

View File

@ -24,7 +24,14 @@ fake_response = utils.TestResponse({
"status_code": 200,
"text": '{"hi": "there"}',
})
fake_response_empty = utils.TestResponse({
"status_code": 200,
"text": '{"access": {}}'
})
mock_request = mock.Mock(return_value=(fake_response))
mock_request_empty = mock.Mock(return_value=(fake_response_empty))
bad_400_response = utils.TestResponse({
"status_code": 400,
@ -197,8 +204,20 @@ class ClientTest(utils.TestCase):
cl = get_client()
# response must not have x-server-management-url header
@mock.patch.object(requests, "request", mock_request)
@mock.patch.object(requests, "request", mock_request_empty)
def test_auth_call():
self.assertRaises(exceptions.AuthorizationFailure, cl.authenticate)
self.assertRaises(exceptions.AuthorizationFailure,
cl.authenticate)
test_auth_call()
def test_auth_not_implemented(self):
cl = get_client()
# response must not have x-server-management-url header
# {'hi': 'there'} is neither V2 or V3
@mock.patch.object(requests, "request", mock_request)
def test_auth_call():
self.assertRaises(NotImplementedError, cl.authenticate)
test_auth_call()

View File

@ -264,56 +264,6 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
test_auth_call()
def test_ambiguous_endpoints(self):
cs = client.Client("username", "password", "project_id",
"http://localhost:8776/v1", service_type='volume')
resp = {
"access": {
"token": {
"expires": "12345",
"id": "FAKE_ID",
},
"serviceCatalog": [
{
"adminURL": "http://localhost:8776/v1",
"type": "volume",
"name": "Cinder Volume Service",
"endpoints": [
{
"region": "RegionOne",
"internalURL": "http://localhost:8776/v1",
"publicURL": "http://localhost:8776/v1",
},
],
},
{
"adminURL": "http://localhost:8776/v1",
"type": "volume",
"name": "Cinder Volume Cloud Service",
"endpoints": [
{
"internalURL": "http://localhost:8776/v1",
"publicURL": "http://localhost:8776/v1",
},
],
},
],
},
}
auth_response = utils.TestResponse({
"status_code": 200,
"text": json.dumps(resp),
})
mock_request = mock.Mock(return_value=(auth_response))
@mock.patch.object(requests, "request", mock_request)
def test_auth_call():
self.assertRaises(exceptions.AmbiguousEndpoints,
cs.client.authenticate)
test_auth_call()
class AuthenticationTests(utils.TestCase):
def test_authenticate_success(self):

View File

@ -267,56 +267,6 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
test_auth_call()
def test_ambiguous_endpoints(self):
cs = client.Client("username", "password", "project_id",
"http://localhost:8776/v2", service_type='volumev2')
resp = {
"access": {
"token": {
"expires": "12345",
"id": "FAKE_ID",
},
"serviceCatalog": [
{
"adminURL": "http://localhost:8776/v1",
"type": "volumev2",
"name": "Cinder Volume Service",
"endpoints": [
{
"region": "RegionOne",
"internalURL": "http://localhost:8776/v1",
"publicURL": "http://localhost:8776/v1",
},
],
},
{
"adminURL": "http://localhost:8776/v2",
"type": "volumev2",
"name": "Cinder Volume V2",
"endpoints": [
{
"internalURL": "http://localhost:8776/v2",
"publicURL": "http://localhost:8776/v2",
},
],
},
],
},
}
auth_response = utils.TestResponse({
"status_code": 200,
"text": json.dumps(resp),
})
mock_request = mock.Mock(return_value=(auth_response))
@mock.patch.object(requests, "request", mock_request)
def test_auth_call():
self.assertRaises(exceptions.AmbiguousEndpoints,
cs.client.authenticate)
test_auth_call()
class AuthenticationTests(utils.TestCase):
def test_authenticate_success(self):

View File

@ -616,15 +616,15 @@ def do_type_key(cs, args):
def do_endpoints(cs, args):
"""Discover endpoints that get returned from the authenticate services."""
catalog = cs.client.service_catalog.catalog
for e in catalog['access']['serviceCatalog']:
for e in catalog['serviceCatalog']:
utils.print_dict(e['endpoints'][0], e['name'])
def do_credentials(cs, args):
"""Show user credentials returned from auth."""
catalog = cs.client.service_catalog.catalog
utils.print_dict(catalog['access']['user'], "User Credentials")
utils.print_dict(catalog['access']['token'], "Token")
utils.print_dict(catalog['user'], "User Credentials")
utils.print_dict(catalog['token'], "Token")
_quota_resources = ['volumes', 'snapshots', 'gigabytes']

View File

@ -673,7 +673,7 @@ def do_type_key(cs, args):
def do_endpoints(cs, args):
"""Discover endpoints that get returned from the authenticate services."""
catalog = cs.client.service_catalog.catalog
for e in catalog['access']['serviceCatalog']:
for e in catalog['serviceCatalog']:
utils.print_dict(e['endpoints'][0], e['name'])
@ -681,8 +681,8 @@ def do_endpoints(cs, args):
def do_credentials(cs, args):
"""Show user credentials returned from auth."""
catalog = cs.client.service_catalog.catalog
utils.print_dict(catalog['access']['user'], "User Credentials")
utils.print_dict(catalog['access']['token'], "Token")
utils.print_dict(catalog['user'], "User Credentials")
utils.print_dict(catalog['token'], "Token")
_quota_resources = ['volumes', 'snapshots', 'gigabytes']

View File

@ -1,6 +1,7 @@
pbr>=0.6,<1.0
argparse
PrettyTable>=0.7,<0.8
python-keystoneclient>=0.6.0
requests>=1.1
simplejson>=2.0.9
Babel>=1.3