diff --git a/doc/source/architecture.rst b/doc/source/architecture.rst index 97a68f4c03..cbd2f40ac7 100644 --- a/doc/source/architecture.rst +++ b/doc/source/architecture.rst @@ -207,7 +207,7 @@ variety of CRUD operations are provided for the sake of development and testing. CRUD is treated as an extension or additional feature to the core feature set in that it is not required that a backend support it. It is expected that backends for services that don't support the CRUD operations will raise a -:mod:`NotImplementedError`. +:mod:`keystone.exception.NotImplemented`. ---------------------------------- diff --git a/keystone/catalog/backends/kvs.py b/keystone/catalog/backends/kvs.py index ed5165f351..58025ca10d 100644 --- a/keystone/catalog/backends/kvs.py +++ b/keystone/catalog/backends/kvs.py @@ -15,10 +15,11 @@ # under the License. +from keystone import catalog from keystone.common import kvs -class Catalog(kvs.Base): +class Catalog(kvs.Base, catalog.Driver): # Public interface def get_catalog(self, user_id, tenant_id, metadata=None): return self.db.get('catalog-%s-%s' % (tenant_id, user_id)) diff --git a/keystone/catalog/backends/sql.py b/keystone/catalog/backends/sql.py index 3fb5316797..b2a12dde59 100644 --- a/keystone/catalog/backends/sql.py +++ b/keystone/catalog/backends/sql.py @@ -77,7 +77,7 @@ class Endpoint(sql.ModelBase, sql.DictBase): return extra_copy -class Catalog(sql.Base): +class Catalog(sql.Base, catalog.Driver): def db_sync(self): migration.db_sync() @@ -99,7 +99,7 @@ class Catalog(sql.Base): session.delete(service_ref) session.flush() - def create_service(self, context, service_ref): + def create_service(self, service_id, service_ref): session = self.get_session() with session.begin(): service = Service.from_dict(service_ref) @@ -114,7 +114,7 @@ class Catalog(sql.Base): return True # Endpoints - def create_endpoint(self, context, endpoint_ref): + def create_endpoint(self, endpoint_id, endpoint_ref): session = self.get_session() new_endpoint = Endpoint.from_dict(endpoint_ref) with session.begin(): diff --git a/keystone/catalog/core.py b/keystone/catalog/core.py index 44bb0c706c..f6e7123230 100644 --- a/keystone/catalog/core.py +++ b/keystone/catalog/core.py @@ -22,6 +22,7 @@ import uuid import webob.exc from keystone import config +from keystone import exception from keystone import identity from keystone import policy from keystone import token @@ -44,6 +45,84 @@ class Manager(manager.Manager): super(Manager, self).__init__(CONF.catalog.driver) +class Driver(object): + """Interface description for an Catalog driver.""" + def list_services(self): + """List all service ids in catalog. + + Returns: list of service_ids or an empty list. + + """ + raise exception.NotImplemented() + + def get_service(self, service_id): + """Get service by id. + + Returns: service_ref dict or None. + + """ + raise exception.NotImplemented() + + def delete_service(self, service_id): + raise exception.NotImplemented() + + def create_service(self, service_id, service_ref): + raise exception.NotImplemented() + + def service_exists(self, service_id): + """Query existence of a service by id. + + Returns: True if the service exists or False. + + """ + raise exception.NotImplemented() + + def create_endpoint(self, endpoint_id, endpoint_ref): + raise exception.NotImplemented() + + def delete_endpoint(self, endpoint_id): + raise exception.NotImplemented() + + def get_endpoint(self, endpoint_id): + """Get endpoint by id. + + Returns: endpoint_ref dict or None. + + """ + raise exception.NotImplemented() + + def list_endpoints(self): + """List all endpoint ids in catalog. + + Returns: list of endpoint_ids or an empty list. + + """ + raise exception.NotImplemented() + + def get_catalog(self, user_id, tenant_id, metadata=None): + """Retreive and format the current service catalog. + + Returns: A nested dict representing the service catalog or an + empty dict. + + Example: + + { 'RegionOne': + {'compute': { + 'adminURL': u'http://host:8774/v1.1/tenantid', + 'internalURL': u'http://host:8774/v1.1/tenant_id', + 'name': 'Compute Service', + 'publicURL': u'http://host:8774/v1.1/tenantid'}, + 'ec2': { + 'adminURL': 'http://host:8773/services/Admin', + 'internalURL': 'http://host:8773/services/Cloud', + 'name': 'EC2 Service', + 'publicURL': 'http://host:8773/services/Cloud'}} + + """ + raise exception.NotImplemented() + + class ServiceController(wsgi.Application): def __init__(self): self.catalog_api = Manager() diff --git a/keystone/exception.py b/keystone/exception.py index 115006e3d9..d95a75e01a 100644 --- a/keystone/exception.py +++ b/keystone/exception.py @@ -69,5 +69,11 @@ class NotFound(Error): title = 'Not Found' +class NotImplemented(Error): + """The action you have requested has not been implemented.""" + code = 501 + action = 'Not Implemented' + + class TokenNotFound(NotFound): """Could not find token: %(token_id)s""" diff --git a/keystone/identity/core.py b/keystone/identity/core.py index 3e141766d4..a89f6f4d46 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -54,7 +54,7 @@ class Driver(object): Returns: (user, tenant, metadata). """ - raise NotImplementedError() + raise exception.NotImplemented() def get_tenant(self, tenant_id): """Get a tenant by id. @@ -62,7 +62,7 @@ class Driver(object): Returns: tenant_ref or None. """ - raise NotImplementedError() + raise exception.NotImplemented() def get_tenant_by_name(self, tenant_name): """Get a tenant by name. @@ -70,7 +70,7 @@ class Driver(object): Returns: tenant_ref or None. """ - raise NotImplementedError() + raise exception.NotImplemented() def get_user(self, user_id): """Get a user by id. @@ -78,7 +78,7 @@ class Driver(object): Returns: user_ref or None. """ - raise NotImplementedError() + raise exception.NotImplemented() def get_user_by_name(self, user_name): """Get a user by name. @@ -86,7 +86,7 @@ class Driver(object): Returns: user_ref or None. """ - raise NotImplementedError() + raise exception.NotImplemented() def get_role(self, role_id): """Get a role by id. @@ -94,7 +94,7 @@ class Driver(object): Returns: role_ref or None. """ - raise NotImplementedError() + raise exception.NotImplemented() def list_users(self): """List all users in the system. @@ -105,7 +105,7 @@ class Driver(object): Returns: a list of user_refs or an empty list. """ - raise NotImplementedError() + raise exception.NotImplemented() def list_roles(self): """List all roles in the system. @@ -113,18 +113,18 @@ class Driver(object): Returns: a list of role_refs or an empty list. """ - raise NotImplementedError() + raise exception.NotImplemented() # NOTE(termie): seven calls below should probably be exposed by the api # more clearly when the api redesign happens def add_user_to_tenant(self, tenant_id, user_id): - raise NotImplementedError() + raise exception.NotImplemented() def remove_user_from_tenant(self, tenant_id, user_id): - raise NotImplementedError() + raise exception.NotImplemented() def get_all_tenants(self): - raise NotImplementedError() + raise exception.NotImplemented() def get_tenants_for_user(self, user_id): """Get the tenants associated with a given user. @@ -132,7 +132,7 @@ class Driver(object): Returns: a list of tenant ids. """ - raise NotImplementedError() + raise exception.NotImplemented() def get_roles_for_user_and_tenant(self, user_id, tenant_id): """Get the roles associated with a user within given tenant. @@ -140,59 +140,59 @@ class Driver(object): Returns: a list of role ids. """ - raise NotImplementedError() + raise exception.NotImplemented() def add_role_to_user_and_tenant(self, user_id, tenant_id, role_id): """Add a role to a user within given tenant.""" - raise NotImplementedError() + raise exception.NotImplemented() def remove_role_from_user_and_tenant(self, user_id, tenant_id, role_id): """Remove a role from a user within given tenant.""" - raise NotImplementedError() + raise exception.NotImplemented() # user crud def create_user(self, user_id, user): - raise NotImplementedError() + raise exception.NotImplemented() def update_user(self, user_id, user): - raise NotImplementedError() + raise exception.NotImplemented() def delete_user(self, user_id): - raise NotImplementedError() + raise exception.NotImplemented() # tenant crud def create_tenant(self, tenant_id, tenant): - raise NotImplementedError() + raise exception.NotImplemented() def update_tenant(self, tenant_id, tenant): - raise NotImplementedError() + raise exception.NotImplemented() def delete_tenant(self, tenant_id, tenant): - raise NotImplementedError() + raise exception.NotImplemented() # metadata crud def get_metadata(self, user_id, tenant_id): - raise NotImplementedError() + raise exception.NotImplemented() def create_metadata(self, user_id, tenant_id, metadata): - raise NotImplementedError() + raise exception.NotImplemented() def update_metadata(self, user_id, tenant_id, metadata): - raise NotImplementedError() + raise exception.NotImplemented() def delete_metadata(self, user_id, tenant_id, metadata): - raise NotImplementedError() + raise exception.NotImplemented() # role crud def create_role(self, role_id, role): - raise NotImplementedError() + raise exception.NotImplemented() def update_role(self, role_id, role): - raise NotImplementedError() + raise exception.NotImplemented() def delete_role(self, role_id): - raise NotImplementedError() + raise exception.NotImplemented() class PublicRouter(wsgi.ComposableRouter): diff --git a/keystone/policy/core.py b/keystone/policy/core.py index a89c60835d..a6dd00a16f 100644 --- a/keystone/policy/core.py +++ b/keystone/policy/core.py @@ -17,6 +17,7 @@ """Main entry point into the Policy service.""" from keystone import config +from keystone import exception from keystone.common import manager @@ -42,4 +43,4 @@ class Driver(object): For more information on a full implementation of this see: `keystone.common.policy.enforce`. """ - raise NotImplementedError() + raise exception.NotImplemented() diff --git a/keystone/service.py b/keystone/service.py index bec771234f..a26cb0bfaa 100644 --- a/keystone/service.py +++ b/keystone/service.py @@ -149,7 +149,7 @@ class VersionController(wsgi.Application): if service == 'identity': return service_ref[self.url_key] - raise NotImplementedError() + raise exception.NotImplemented() def _get_versions_list(self, context): """The list of versions is dependent on the context.""" @@ -421,7 +421,7 @@ class TokenController(wsgi.Application): def endpoints(self, context, token_id): """Return a list of endpoints available to the token.""" - raise NotImplementedError() + raise exception.NotImplemented() def _format_authenticate(self, token_ref, roles_ref, catalog_ref): o = self._format_token(token_ref, roles_ref) diff --git a/keystone/token/core.py b/keystone/token/core.py index 102d187588..0a28e38208 100644 --- a/keystone/token/core.py +++ b/keystone/token/core.py @@ -19,6 +19,7 @@ import datetime from keystone import config +from keystone import exception from keystone.common import manager @@ -50,7 +51,7 @@ class Driver(object): :raises: keystone.exception.TokenNotFound """ - raise NotImplementedError() + raise exception.NotImplemented() def create_token(self, token_id, data): """Create a token by id and data. @@ -73,7 +74,7 @@ class Driver(object): :returns: token_ref or None. """ - raise NotImplementedError() + raise exception.NotImplemented() def delete_token(self, token_id): """Deletes a token by id. @@ -84,7 +85,7 @@ class Driver(object): :raises: keystone.exception.TokenNotFound """ - raise NotImplementedError() + raise exception.NotImplemented() def _get_default_expire_time(self): """Determine when a token should expire based on the config.