summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--keystone/catalog/backends/sql.py1
-rw-r--r--keystone/service.py51
-rw-r--r--tests/default_catalog.templates2
-rw-r--r--tests/test_backend_templated.py6
-rw-r--r--tests/test_content_types.py24
5 files changed, 76 insertions, 8 deletions
diff --git a/keystone/catalog/backends/sql.py b/keystone/catalog/backends/sql.py
index c47d337a..bd0f687c 100644
--- a/keystone/catalog/backends/sql.py
+++ b/keystone/catalog/backends/sql.py
@@ -158,6 +158,7 @@ class Catalog(sql.Base, catalog.Driver):
internal_url = ep['internalurl'].replace('$(', '%(')
public_url = ep['publicurl'].replace('$(', '%(')
admin_url = ep['adminurl'].replace('$(', '%(')
+ catalog[region][srv_type]['id'] = ep['id']
catalog[region][srv_type]['name'] = srv_name
catalog[region][srv_type]['publicURL'] = public_url % d
catalog[region][srv_type]['adminURL'] = admin_url % d
diff --git a/keystone/service.py b/keystone/service.py
index 135e490f..dfd80714 100644
--- a/keystone/service.py
+++ b/keystone/service.py
@@ -544,7 +544,19 @@ class TokenController(wsgi.Application):
def endpoints(self, context, token_id):
"""Return a list of endpoints available to the token."""
- raise exception.NotImplemented()
+ self.assert_admin(context)
+
+ token_ref = self._get_token_ref(context, token_id)
+
+ catalog_ref = None
+ if token_ref.get('tenant'):
+ catalog_ref = self.catalog_api.get_catalog(
+ context=context,
+ user_id=token_ref['user']['id'],
+ tenant_id=token_ref['tenant']['id'],
+ metadata=token_ref['metadata'])
+
+ return self._format_endpoint_list(catalog_ref)
def _format_authenticate(self, token_ref, roles_ref, catalog_ref):
o = self._format_token(token_ref, roles_ref)
@@ -630,6 +642,43 @@ class TokenController(wsgi.Application):
return services.values()
+ def _format_endpoint_list(self, catalog_ref):
+ """Formats a list of endpoints according to Identity API v2.
+
+ The v2.0 API wants an endpoint list to look like::
+
+ {
+ 'endpoints': [
+ {
+ 'id': $endpoint_id,
+ 'name': $SERVICE[name],
+ 'type': $SERVICE,
+ 'tenantId': $tenant_id,
+ 'region': $REGION,
+ }
+ ],
+ 'endpoints_links': [],
+ }
+
+ """
+ if not catalog_ref:
+ return {}
+
+ endpoints = []
+ for region_name, region_ref in catalog_ref.iteritems():
+ for service_type, service_ref in region_ref.iteritems():
+ endpoints.append({
+ 'id': service_ref.get('id'),
+ 'name': service_ref.get('name'),
+ 'type': service_type,
+ 'region': region_name,
+ 'publicURL': service_ref.get('publicURL'),
+ 'internalURL': service_ref.get('internalURL'),
+ 'adminURL': service_ref.get('adminURL'),
+ })
+
+ return {'endpoints': endpoints, 'endpoints_links': []}
+
class ExtensionsController(wsgi.Application):
"""Base extensions controller to be extended by public and admin API's."""
diff --git a/tests/default_catalog.templates b/tests/default_catalog.templates
index c12b5c4c..f26c949a 100644
--- a/tests/default_catalog.templates
+++ b/tests/default_catalog.templates
@@ -4,9 +4,11 @@ catalog.RegionOne.identity.publicURL = http://localhost:$(public_port)s/v2.0
catalog.RegionOne.identity.adminURL = http://localhost:$(admin_port)s/v2.0
catalog.RegionOne.identity.internalURL = http://localhost:$(admin_port)s/v2.0
catalog.RegionOne.identity.name = 'Identity Service'
+catalog.RegionOne.identity.id = 1
# fake compute service for now to help novaclient tests work
catalog.RegionOne.compute.publicURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
catalog.RegionOne.compute.adminURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
catalog.RegionOne.compute.internalURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
catalog.RegionOne.compute.name = 'Compute Service'
+catalog.RegionOne.compute.id = 2
diff --git a/tests/test_backend_templated.py b/tests/test_backend_templated.py
index 0b9c1698..263d5c63 100644
--- a/tests/test_backend_templated.py
+++ b/tests/test_backend_templated.py
@@ -38,13 +38,15 @@ class TestTemplatedCatalog(test.TestCase, test_backend.CatalogTests):
'adminURL': 'http://localhost:8774/v1.1/bar',
'publicURL': 'http://localhost:8774/v1.1/bar',
'internalURL': 'http://localhost:8774/v1.1/bar',
- 'name': "'Compute Service'"
+ 'name': "'Compute Service'",
+ 'id': '2'
},
'identity': {
'adminURL': 'http://localhost:35357/v2.0',
'publicURL': 'http://localhost:5000/v2.0',
'internalURL': 'http://localhost:35357/v2.0',
- 'name': "'Identity Service'"
+ 'name': "'Identity Service'",
+ 'id': '1'
}
}
}
diff --git a/tests/test_content_types.py b/tests/test_content_types.py
index 0371c556..ea501c09 100644
--- a/tests/test_content_types.py
+++ b/tests/test_content_types.py
@@ -413,15 +413,13 @@ class CoreApiTests(object):
expected_status=204)
def test_endpoints(self):
- raise nose.exc.SkipTest('Blocked by bug 933555')
-
token = self.get_scoped_token()
r = self.admin_request(
path='/v2.0/tokens/%(token_id)s/endpoints' % {
'token_id': token,
},
token=token)
- self.assertValidTokenCatalogResponse(r)
+ self.assertValidEndpointListResponse(r)
def test_get_tenant(self):
token = self.get_scoped_token()
@@ -582,6 +580,17 @@ class JsonTestCase(RestfulTestCase, CoreApiTests):
def assertValidVersionResponse(self, r):
self.assertValidVersion(r.body.get('version'))
+ def assertValidEndpointListResponse(self, r):
+ self.assertIsNotNone(r.body.get('endpoints'))
+ self.assertTrue(len(r.body['endpoints']))
+ for endpoint in r.body['endpoints']:
+ self.assertIsNotNone(endpoint.get('id'))
+ self.assertIsNotNone(endpoint.get('name'))
+ self.assertIsNotNone(endpoint.get('type'))
+ self.assertIsNotNone(endpoint.get('publicURL'))
+ self.assertIsNotNone(endpoint.get('internalURL'))
+ self.assertIsNotNone(endpoint.get('adminURL'))
+
def test_service_crud_requires_auth(self):
"""Service CRUD should 401 without an X-Auth-Token (bug 1006822)."""
# values here don't matter because we should 401 before they're checked
@@ -715,13 +724,18 @@ class XmlTestCase(RestfulTestCase, CoreApiTests):
self.assertValidVersion(xml)
- def assertValidTokenCatalogResponse(self, r):
+ def assertValidEndpointListResponse(self, r):
xml = r.body
self.assertEqual(xml.tag, self._tag('endpoints'))
self.assertTrue(len(xml.findall(self._tag('endpoint'))))
for endpoint in xml.findall(self._tag('endpoint')):
- self.assertIsNotNone(endpoint.get('publicUrl'))
+ self.assertIsNotNone(endpoint.get('id'))
+ self.assertIsNotNone(endpoint.get('name'))
+ self.assertIsNotNone(endpoint.get('type'))
+ self.assertIsNotNone(endpoint.get('publicURL'))
+ self.assertIsNotNone(endpoint.get('internalURL'))
+ self.assertIsNotNone(endpoint.get('adminURL'))
def assertValidTenantResponse(self, r):
xml = r.body