Skip to content

Commit

Permalink
Use dependency injection for assignment and identity
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Brant Knudson committed Jul 31, 2013
1 parent 3c6cc9e commit 3268a4b
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 20 deletions.
2 changes: 2 additions & 0 deletions keystone/assignment/backends/kvs.py
Expand Up @@ -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__()
Expand Down
2 changes: 2 additions & 0 deletions keystone/assignment/backends/ldap.py
Expand Up @@ -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
Expand All @@ -39,6 +40,7 @@
}


@dependency.requires('identity_api')
class Assignment(assignment.Driver):
def __init__(self):
super(Assignment, self).__init__()
Expand Down
5 changes: 2 additions & 3 deletions keystone/assignment/backends/sql.py
Expand Up @@ -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):
Expand Down
15 changes: 6 additions & 9 deletions keystone/assignment/core.py
Expand Up @@ -35,6 +35,7 @@


@dependency.provider('assignment_api')
@dependency.requires('identity_api')
class Manager(manager.Manager):
"""Default pivot point for the Assignment backend.
Expand All @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions keystone/identity/backends/ldap.py
Expand Up @@ -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
Expand All @@ -38,6 +39,7 @@
}


@dependency.requires('assignment_api')
class Identity(identity.Driver):
def __init__(self):
super(Identity, self).__init__()
Expand Down
2 changes: 2 additions & 0 deletions keystone/identity/backends/sql.py
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down
8 changes: 2 additions & 6 deletions keystone/identity/core.py
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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()
Expand Down
10 changes: 9 additions & 1 deletion keystone/service.py
Expand Up @@ -16,6 +16,7 @@

import routes

from keystone import assignment
from keystone import auth
from keystone import catalog
from keystone.common import dependency
Expand All @@ -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(),
Expand Down
6 changes: 5 additions & 1 deletion keystone/test.py
Expand Up @@ -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())
Expand Down

0 comments on commit 3268a4b

Please sign in to comment.