Stable Keystone Driver Interfaces

Extended support for versioned driver classes to the rest of the
backends based on the design of the initial support for catalog backend @
https://review.openstack.org/#/c/218481/

partially Implements bp stable-driver-interfaces

Change-Id: I0078f6dc32932beb6db534ecf22b160097c5a090
This commit is contained in:
Vivek Dhayaal 2015-08-30 22:19:09 +00:00
parent c8e2364240
commit ba317dedd8
32 changed files with 90 additions and 43 deletions

View File

@ -156,17 +156,19 @@ variety of environments and needs. The backend for each service is defined in
the keystone.conf file with the key ``driver`` under a group associated with the keystone.conf file with the key ``driver`` under a group associated with
each service. each service.
A general class under each backend named ``Driver`` exists to provide an A general class exists under each backend to provide an
abstract base class for any implementations, identifying the expected service abstract base class for any implementations, identifying the expected service
implementations. The drivers for the services are: implementations. The classes are named after the keystone release in which
they were introduced. For eg. ``DriverV8`` for keystone release version 8.
The corresponding drivers for the services are:
* :mod:`keystone.assignment.core.Driver` * :mod:`keystone.assignment.core.AssignmentDriverV8`
* :mod:`keystone.assignment.core.RoleDriver` * :mod:`keystone.assignment.core.RoleDriverV8`
* :mod:`keystone.catalog.core.Driver` * :mod:`keystone.catalog.core.CatalogDriverV8`
* :mod:`keystone.identity.core.Driver` * :mod:`keystone.identity.core.IdentityDriverV8`
* :mod:`keystone.policy.core.Driver` * :mod:`keystone.policy.core.PolicyDriverV8`
* :mod:`keystone.resource.core.Driver` * :mod:`keystone.resource.core.ResourceDriverV8`
* :mod:`keystone.token.core.Driver` * :mod:`keystone.token.core.TokenDriverV8`
If you implement a backend driver for one of the Keystone services, you're If you implement a backend driver for one of the Keystone services, you're
expected to subclass from these classes. expected to subclass from these classes.

View File

@ -31,7 +31,7 @@ CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class Assignment(assignment.Driver): class Assignment(assignment.AssignmentDriverV8):
@versionutils.deprecated( @versionutils.deprecated(
versionutils.deprecated.KILO, versionutils.deprecated.KILO,
remove_in=+2, remove_in=+2,

View File

@ -49,7 +49,7 @@ class AssignmentType(object):
raise exception.AssignmentTypeCalculationError(**locals()) raise exception.AssignmentTypeCalculationError(**locals())
class Assignment(keystone_assignment.Driver): class Assignment(keystone_assignment.AssignmentDriverV8):
def default_role_driver(self): def default_role_driver(self):
return 'sql' return 'sql'

View File

@ -911,7 +911,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class AssignmentDriverV8(object):
def _role_to_dict(self, role_id, inherited): def _role_to_dict(self, role_id, inherited):
role_dict = {'id': role_id} role_dict = {'id': role_id}
@ -1158,6 +1158,9 @@ class Driver(object):
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(AssignmentDriverV8)
@dependency.provider('role_api') @dependency.provider('role_api')
@dependency.requires('assignment_api') @dependency.requires('assignment_api')
class RoleManager(manager.Manager): class RoleManager(manager.Manager):
@ -1219,7 +1222,7 @@ class RoleManager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class RoleDriver(object): class RoleDriverV8(object):
def _get_list_limit(self): def _get_list_limit(self):
return CONF.role.list_limit or CONF.list_limit return CONF.role.list_limit or CONF.list_limit
@ -1287,3 +1290,6 @@ class RoleDriver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
RoleDriver = manager.create_legacy_driver(RoleDriverV8)

View File

@ -27,7 +27,7 @@ CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class Role(assignment.RoleDriver): class Role(assignment.RoleDriverV8):
def __init__(self): def __init__(self):
super(Role, self).__init__() super(Role, self).__init__()

View File

@ -15,7 +15,7 @@ from keystone.common import sql
from keystone import exception from keystone import exception
class Role(assignment.RoleDriver): class Role(assignment.RoleDriverV8):
@sql.handle_conflicts(conflict_type='role') @sql.handle_conflicts(conflict_type='role')
def create_role(self, role_id, role): def create_role(self, role_id, role):

View File

@ -53,7 +53,7 @@ class ProjectEndpointGroupMembership(sql.ModelBase, sql.ModelDictMixin):
'project_id'), {}) 'project_id'), {})
class EndpointFilter(endpoint_filter.Driver): class EndpointFilter(endpoint_filter.EndpointFilterDriverV8):
@sql.handle_conflicts(conflict_type='project_endpoint') @sql.handle_conflicts(conflict_type='project_endpoint')
def add_endpoint_to_project(self, endpoint_id, project_id): def add_endpoint_to_project(self, endpoint_id, project_id):

View File

@ -65,7 +65,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class EndpointFilterDriverV8(object):
"""Interface description for an Endpoint Filter driver.""" """Interface description for an Endpoint Filter driver."""
@abc.abstractmethod @abc.abstractmethod
@ -291,3 +291,6 @@ class Driver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(EndpointFilterDriverV8)

View File

@ -155,7 +155,7 @@ class ServiceProviderModel(sql.ModelBase, sql.DictBase):
return d return d
class Federation(core.Driver): class Federation(core.FederationDriverV8):
# Identity Provider CRUD # Identity Provider CRUD
@sql.handle_conflicts(conflict_type='identity_provider') @sql.handle_conflicts(conflict_type='identity_provider')

View File

@ -92,7 +92,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class FederationDriverV8(object):
@abc.abstractmethod @abc.abstractmethod
def create_idp(self, idp_id, idp): def create_idp(self, idp_id, idp):
@ -350,3 +350,6 @@ class Driver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(FederationDriverV8)

View File

@ -199,7 +199,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class Oauth1DriverV8(object):
"""Interface description for an OAuth1 driver.""" """Interface description for an OAuth1 driver."""
@abc.abstractmethod @abc.abstractmethod
@ -362,3 +362,6 @@ class Driver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(Oauth1DriverV8)

View File

@ -27,7 +27,7 @@ _EVENT_KEY = 'os-revoke-events'
_KVS_BACKEND = 'openstack.kvs.Memory' _KVS_BACKEND = 'openstack.kvs.Memory'
class Revoke(revoke.Driver): class Revoke(revoke.RevokeDriverV8):
@versionutils.deprecated( @versionutils.deprecated(
versionutils.deprecated.JUNO, versionutils.deprecated.JUNO,

View File

@ -38,7 +38,7 @@ class RevocationEvent(sql.ModelBase, sql.ModelDictMixin):
audit_chain_id = sql.Column(sql.String(32)) audit_chain_id = sql.Column(sql.String(32))
class Revoke(revoke.Driver): class Revoke(revoke.RevokeDriverV8):
def _flush_batch_size(self, dialect): def _flush_batch_size(self, dialect):
batch_size = 0 batch_size = 0
if dialect == 'ibm_db_sa': if dialect == 'ibm_db_sa':

View File

@ -232,7 +232,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class RevokeDriverV8(object):
"""Interface for recording and reporting revocation events.""" """Interface for recording and reporting revocation events."""
@abc.abstractmethod @abc.abstractmethod
@ -257,3 +257,6 @@ class Driver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(RevokeDriverV8)

View File

@ -29,7 +29,7 @@ class CredentialModel(sql.ModelBase, sql.DictBase):
extra = sql.Column(sql.JsonBlob()) extra = sql.Column(sql.JsonBlob())
class Credential(credential.Driver): class Credential(credential.CredentialDriverV8):
# credential crud # credential crud

View File

@ -51,7 +51,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class CredentialDriverV8(object):
# credential crud # credential crud
@abc.abstractmethod @abc.abstractmethod
@ -140,3 +140,6 @@ class Driver(object):
except exception.CredentialNotFound: except exception.CredentialNotFound:
LOG.debug('Deletion of credential is not required: %s', LOG.debug('Deletion of credential is not required: %s',
cr['id']) cr['id'])
Driver = manager.create_legacy_driver(CredentialDriverV8)

View File

@ -264,7 +264,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class EndpointPolicyDriverV8(object):
"""Interface description for an Endpoint Policy driver.""" """Interface description for an Endpoint Policy driver."""
@abc.abstractmethod @abc.abstractmethod
@ -431,3 +431,6 @@ class Driver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(EndpointPolicyDriverV8)

View File

@ -32,7 +32,7 @@ CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class Identity(identity.Driver): class Identity(identity.IdentityDriverV8):
def __init__(self, conf=None): def __init__(self, conf=None):
super(Identity, self).__init__() super(Identity, self).__init__()
if conf is None: if conf is None:

View File

@ -70,7 +70,7 @@ class UserGroupMembership(sql.ModelBase, sql.DictBase):
primary_key=True) primary_key=True)
class Identity(identity.Driver): class Identity(identity.IdentityDriverV8):
# NOTE(henry-nash): Override the __init__() method so as to take a # NOTE(henry-nash): Override the __init__() method so as to take a
# config parameter to enable sql to be used as a domain-specific driver. # config parameter to enable sql to be used as a domain-specific driver.
def __init__(self, conf=None): def __init__(self, conf=None):

View File

@ -1066,7 +1066,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class IdentityDriverV8(object):
"""Interface description for an Identity driver.""" """Interface description for an Identity driver."""
def _get_list_limit(self): def _get_list_limit(self):
@ -1280,6 +1280,9 @@ class Driver(object):
# end of identity # end of identity
Driver = manager.create_legacy_driver(IdentityDriverV8)
@dependency.provider('id_mapping_api') @dependency.provider('id_mapping_api')
class MappingManager(manager.Manager): class MappingManager(manager.Manager):
"""Default pivot point for the ID Mapping backend.""" """Default pivot point for the ID Mapping backend."""
@ -1291,7 +1294,7 @@ class MappingManager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class MappingDriver(object): class MappingDriverV8(object):
"""Interface description for an ID Mapping driver.""" """Interface description for an ID Mapping driver."""
@abc.abstractmethod @abc.abstractmethod
@ -1350,3 +1353,6 @@ class MappingDriver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
MappingDriver = manager.create_legacy_driver(MappingDriverV8)

View File

@ -36,7 +36,7 @@ class IDMapping(sql.ModelBase, sql.ModelDictMixin):
@dependency.requires('id_generator_api') @dependency.requires('id_generator_api')
class Mapping(identity.MappingDriver): class Mapping(identity.MappingDriverV8):
def get_public_id(self, local_entity): def get_public_id(self, local_entity):
# NOTE(henry-nash): Since the Public ID is regeneratable, rather # NOTE(henry-nash): Since the Public ID is regeneratable, rather

View File

@ -69,7 +69,7 @@ def enforce(credentials, action, target, do_raise=True):
return _ENFORCER.enforce(action, target, credentials, **extra) return _ENFORCER.enforce(action, target, credentials, **extra)
class Policy(policy.Driver): class Policy(policy.PolicyDriverV8):
def enforce(self, credentials, action, target): def enforce(self, credentials, action, target):
LOG.debug('enforce %(action)s: %(credentials)s', { LOG.debug('enforce %(action)s: %(credentials)s', {
'action': action, 'action': action,

View File

@ -82,7 +82,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class PolicyDriverV8(object):
def _get_list_limit(self): def _get_list_limit(self):
return CONF.policy.list_limit or CONF.list_limit return CONF.policy.list_limit or CONF.list_limit
@ -136,3 +136,6 @@ class Driver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(PolicyDriverV8)

View File

@ -31,7 +31,7 @@ CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class Resource(resource.Driver): class Resource(resource.ResourceDriverV8):
def __init__(self): def __init__(self):
super(Resource, self).__init__() super(Resource, self).__init__()
self.LDAP_URL = CONF.ldap.url self.LDAP_URL = CONF.ldap.url

View File

@ -24,7 +24,7 @@ CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class Resource(keystone_resource.Driver): class Resource(keystone_resource.ResourceDriverV8):
def default_assignment_driver(self): def default_assignment_driver(self):
return 'sql' return 'sql'

View File

@ -42,7 +42,7 @@ class SensitiveConfig(sql.ModelBase, sql.ModelDictMixin):
return d return d
class DomainConfig(resource.DomainConfigDriver): class DomainConfig(resource.DomainConfigDriverV8):
def choose_table(self, sensitive): def choose_table(self, sensitive):
if sensitive: if sensitive:

View File

@ -541,7 +541,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class ResourceDriverV8(object):
def _get_list_limit(self): def _get_list_limit(self):
return CONF.resource.list_limit or CONF.list_limit return CONF.resource.list_limit or CONF.list_limit
@ -796,6 +796,9 @@ class Driver(object):
raise exception.DomainNotFound(domain_id=domain_id) raise exception.DomainNotFound(domain_id=domain_id)
Driver = manager.create_legacy_driver(ResourceDriverV8)
MEMOIZE_CONFIG = cache.get_memoization_decorator(section='domain_config') MEMOIZE_CONFIG = cache.get_memoization_decorator(section='domain_config')
@ -1272,7 +1275,7 @@ class DomainConfigManager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class DomainConfigDriver(object): class DomainConfigDriverV8(object):
"""Interface description for a Domain Config driver.""" """Interface description for a Domain Config driver."""
@abc.abstractmethod @abc.abstractmethod
@ -1359,3 +1362,6 @@ class DomainConfigDriver(object):
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
DomainConfigDriver = manager.create_legacy_driver(DomainConfigDriverV8)

View File

@ -33,7 +33,7 @@ CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class Token(token.persistence.Driver): class Token(token.persistence.TokenDriverV8):
"""KeyValueStore backend for tokens. """KeyValueStore backend for tokens.
This is the base implementation for any/all key-value-stores (e.g. This is the base implementation for any/all key-value-stores (e.g.

View File

@ -83,7 +83,7 @@ def _expiry_range_all(session, upper_bound_func):
yield upper_bound_func() yield upper_bound_func()
class Token(token.persistence.Driver): class Token(token.persistence.TokenDriverV8):
# Public interface # Public interface
def get_token(self, token_id): def get_token(self, token_id):
if token_id is None: if token_id is None:

View File

@ -230,7 +230,7 @@ class Manager(object):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class TokenDriverV8(object):
"""Interface description for a Token driver.""" """Interface description for a Token driver."""
@abc.abstractmethod @abc.abstractmethod
@ -357,3 +357,6 @@ class Driver(object):
"""Archive or delete tokens that have expired. """Archive or delete tokens that have expired.
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(TokenDriverV8)

View File

@ -54,7 +54,7 @@ class TrustRole(sql.ModelBase):
role_id = sql.Column(sql.String(64), primary_key=True, nullable=False) role_id = sql.Column(sql.String(64), primary_key=True, nullable=False)
class Trust(trust.Driver): class Trust(trust.TrustDriverV8):
@sql.handle_conflicts(conflict_type='trust') @sql.handle_conflicts(conflict_type='trust')
def create_trust(self, trust_id, trust, roles): def create_trust(self, trust_id, trust, roles):
with sql.transaction() as session: with sql.transaction() as session:

View File

@ -204,7 +204,7 @@ class Manager(manager.Manager):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Driver(object): class TrustDriverV8(object):
@abc.abstractmethod @abc.abstractmethod
def create_trust(self, trust_id, trust, roles): def create_trust(self, trust_id, trust, roles):
@ -251,3 +251,6 @@ class Driver(object):
keystone.exception.TrustNotFound keystone.exception.TrustNotFound
""" """
raise exception.NotImplemented() # pragma: no cover raise exception.NotImplemented() # pragma: no cover
Driver = manager.create_legacy_driver(TrustDriverV8)