From 3268a4b96449647faa76e5521660516fbc9e8a84 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Fri, 19 Jul 2013 17:11:43 -0500 Subject: [PATCH] Use dependency injection for assignment and identity The assignment and identity backends don't use normal dependency injection because of a circular reference. Support for circular references was added, so these backends can now use normal dependency injection. Fixes: bug 1200769 Fixes: bug 1204605 Change-Id: I8716a65b984c26fcaaf2595463db09e1f02cb475 --- keystone/assignment/backends/kvs.py | 2 ++ keystone/assignment/backends/ldap.py | 2 ++ keystone/assignment/backends/sql.py | 5 ++--- keystone/assignment/core.py | 15 ++++++--------- keystone/identity/backends/ldap.py | 2 ++ keystone/identity/backends/sql.py | 2 ++ keystone/identity/core.py | 8 ++------ keystone/service.py | 10 +++++++++- keystone/test.py | 6 +++++- 9 files changed, 32 insertions(+), 20 deletions(-) diff --git a/keystone/assignment/backends/kvs.py b/keystone/assignment/backends/kvs.py index 4dfd908fe5..30d7b2eb6c 100644 --- a/keystone/assignment/backends/kvs.py +++ b/keystone/assignment/backends/kvs.py @@ -16,11 +16,13 @@ from keystone import assignment from keystone import clean +from keystone.common import dependency from keystone.common import kvs from keystone import exception from keystone import identity +@dependency.requires('identity_api') class Assignment(kvs.Base, assignment.Driver): def __init__(self): super(Assignment, self).__init__() diff --git a/keystone/assignment/backends/ldap.py b/keystone/assignment/backends/ldap.py index f8c81eae1a..9b273e4014 100644 --- a/keystone/assignment/backends/ldap.py +++ b/keystone/assignment/backends/ldap.py @@ -21,6 +21,7 @@ from keystone import assignment from keystone import clean +from keystone.common import dependency from keystone.common import ldap as common_ldap from keystone.common import logging from keystone.common import models @@ -39,6 +40,7 @@ } +@dependency.requires('identity_api') class Assignment(assignment.Driver): def __init__(self): super(Assignment, self).__init__() diff --git a/keystone/assignment/backends/sql.py b/keystone/assignment/backends/sql.py index 5ec435ff04..024a291a7a 100644 --- a/keystone/assignment/backends/sql.py +++ b/keystone/assignment/backends/sql.py @@ -16,15 +16,14 @@ from keystone import assignment from keystone import clean +from keystone.common import dependency from keystone.common import sql from keystone.common.sql import migration from keystone import exception +@dependency.requires('identity_api') class Assignment(sql.Base, assignment.Driver): - def __init__(self): - super(Assignment, self).__init__() - self.identity_api = None # Internal interface to manage the database def db_sync(self, version=None): diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py index b71e2a1888..64edb3fae9 100644 --- a/keystone/assignment/core.py +++ b/keystone/assignment/core.py @@ -35,6 +35,7 @@ @dependency.provider('assignment_api') +@dependency.requires('identity_api') class Manager(manager.Manager): """Default pivot point for the Assignment backend. @@ -45,18 +46,14 @@ class Manager(manager.Manager): api object by both managers. """ - def __init__(self, identity_api=None): - if identity_api is None: - from keystone import identity - identity_api = identity.Manager(self) - + def __init__(self): assignment_driver = CONF.assignment.driver + if assignment_driver is None: - assignment_driver = identity_api.default_assignment_driver() + identity_driver = dependency.REGISTRY['identity_api'].driver + assignment_driver = identity_driver.default_assignment_driver() + super(Manager, self).__init__(assignment_driver) - self.driver.identity_api = identity_api - self.identity_api = identity_api - self.identity_api.assignment_api = self def get_roles_for_user_and_project(self, user_id, tenant_id): """Get the roles associated with a user within given project. diff --git a/keystone/identity/backends/ldap.py b/keystone/identity/backends/ldap.py index f9e546a920..09de0baf4f 100644 --- a/keystone/identity/backends/ldap.py +++ b/keystone/identity/backends/ldap.py @@ -19,6 +19,7 @@ import ldap from keystone import clean +from keystone.common import dependency from keystone.common import ldap as common_ldap from keystone.common import logging from keystone.common import models @@ -38,6 +39,7 @@ } +@dependency.requires('assignment_api') class Identity(identity.Driver): def __init__(self): super(Identity, self).__init__() diff --git a/keystone/identity/backends/sql.py b/keystone/identity/backends/sql.py index ba97758c02..bff4110615 100644 --- a/keystone/identity/backends/sql.py +++ b/keystone/identity/backends/sql.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. +from keystone.common import dependency from keystone.common import sql from keystone.common.sql import migration from keystone.common import utils @@ -61,6 +62,7 @@ class UserGroupMembership(sql.ModelBase, sql.DictBase): primary_key=True) +@dependency.requires('assignment_api') class Identity(sql.Base, identity.Driver): def default_assignment_driver(self): return "keystone.assignment.backends.sql.Assignment" diff --git a/keystone/identity/core.py b/keystone/identity/core.py index 3d9bcf6218..b2b3eaf06f 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -16,7 +16,6 @@ """Main entry point into the Identity service.""" -from keystone import assignment from keystone import clean from keystone.common import dependency from keystone.common import logging @@ -53,6 +52,7 @@ def filter_user(user_ref): @dependency.provider('identity_api') +@dependency.requires('assignment_api') class Manager(manager.Manager): """Default pivot point for the Identity backend. @@ -61,12 +61,8 @@ class Manager(manager.Manager): """ - def __init__(self, assignment_api=None): + def __init__(self): super(Manager, self).__init__(CONF.identity.driver) - if assignment_api is None: - assignment_api = assignment.Manager(self) - self.assignment_api = assignment_api - self.driver.assignment_api = assignment_api def create_user(self, user_id, user_ref): user = user_ref.copy() diff --git a/keystone/service.py b/keystone/service.py index 775dfe5de4..ce64aba84d 100644 --- a/keystone/service.py +++ b/keystone/service.py @@ -16,6 +16,7 @@ import routes +from keystone import assignment from keystone import auth from keystone import catalog from keystone.common import dependency @@ -35,11 +36,18 @@ CONF = config.CONF LOG = logging.getLogger(__name__) + +# Ensure that the identity driver is created before the assignment manager. +# The default assignment driver is determined by the identity driver, so the +# identity driver must be available to the assignment manager. +_IDENTITY_API = identity.Manager() + DRIVERS = dict( + assignment_api=assignment.Manager(), catalog_api=catalog.Manager(), credentials_api=credential.Manager(), ec2_api=ec2.Manager(), - identity_api=identity.Manager(), + identity_api=_IDENTITY_API, policy_api=policy.Manager(), token_api=token.Manager(), trust_api=trust.Manager(), diff --git a/keystone/test.py b/keystone/test.py index 55aca3c614..5d1ad50502 100644 --- a/keystone/test.py +++ b/keystone/test.py @@ -266,7 +266,11 @@ def load_backends(self): # only call load_backends once. dependency.reset() - for manager in [assignment, catalog, credential, ec2, identity, policy, + # NOTE(blk-u): identity must be before assignment to ensure that the + # identity driver is available to the assignment manager because the + # assignment manager gets the default assignment driver from the + # identity driver. + for manager in [identity, assignment, catalog, credential, ec2, policy, token, token_provider, trust]: manager_name = '%s_api' % manager.__name__.split('.')[-1] setattr(self, manager_name, manager.Manager())