From 10c7a00a64a6f0162cb18d52ead54f8fe7de94b0 Mon Sep 17 00:00:00 2001 From: Morgan Fainberg Date: Sun, 7 Feb 2016 12:06:11 -0800 Subject: [PATCH] Followup for LDAP removal Add back in support for ASSIGNMENT driver to be selected based upon the IDENTITY driver and revert the changes to assert_backend in test_backend_ldap based upon comments on commit e6efbe62b8b7f226aab22e01edecee0e60745897 Change-Id: Id6b753cb846204cf778971d60c2155f3416f8806 --- keystone/assignment/core.py | 22 ++++++++++++++++++++++ keystone/common/config.py | 8 +++++--- keystone/exception.py | 6 ++++++ keystone/identity/backends/ldap.py | 3 --- keystone/identity/backends/sql.py | 3 --- keystone/identity/core.py | 5 +++++ keystone/server/backends.py | 12 +++++++++--- keystone/tests/unit/test_backend_ldap.py | 11 ++++++++--- 8 files changed, 55 insertions(+), 15 deletions(-) diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py index a64c5d3738..4ea1d1e27a 100644 --- a/keystone/assignment/core.py +++ b/keystone/assignment/core.py @@ -68,6 +68,28 @@ class Manager(manager.Manager): def __init__(self): assignment_driver = CONF.assignment.driver + # If there is no explicit assignment driver specified, we let the + # identity driver tell us what to use. This is for backward + # compatibility reasons from the time when identity, resource and + # assignment were all part of identity. + if assignment_driver is None: + msg = _('Use of the identity driver config to automatically ' + 'configure the same assignment driver has been ' + 'deprecated, in the "O" release, the assignment driver ' + 'will need to be expicitly configured if different ' + 'than the default (SQL).') + versionutils.report_deprecated_feature(LOG, msg) + try: + identity_driver = dependency.get_provider( + 'identity_api').driver + assignment_driver = identity_driver.default_assignment_driver() + except ValueError: + msg = _('Attempted automatic driver selection for assignment ' + 'based upon [identity]\driver option failed since ' + 'driver %s is not found. Set [assignment]/driver to ' + 'a valid driver in keystone config.') + LOG.critical(msg) + raise exception.KeystoneConfigurationError(msg) super(Manager, self).__init__(assignment_driver) # Make sure it is a driver version we support, and if it is a legacy diff --git a/keystone/common/config.py b/keystone/common/config.py index 356807d70f..72e1b58324 100644 --- a/keystone/common/config.py +++ b/keystone/common/config.py @@ -408,12 +408,14 @@ FILE_OPTIONS = { cfg.StrOpt('driver', help='Entrypoint for the assignment backend driver in the ' 'keystone.assignment namespace. Only an SQL driver is ' - 'supplied.', - default='sql'), + 'supplied. If an assignment driver is not ' + 'specified, the identity driver will choose the ' + 'assignment driver (driver selection based on ' + '`[identity]/driver` option is deprecated and will be ' + 'removed in the "O" release).'), cfg.ListOpt('prohibited_implied_role', default=['admin'], help='A list of role names which are prohibited from ' 'being an implied role.'), - ], 'resource': [ cfg.StrOpt('driver', diff --git a/keystone/exception.py b/keystone/exception.py index 4a822e2d99..e347d3451a 100644 --- a/keystone/exception.py +++ b/keystone/exception.py @@ -393,6 +393,12 @@ class ConfigRegistrationNotFound(Exception): pass +class KeystoneConfigurationError(Exception): + # This is an exception to be used in the case that Keystone config is + # invalid and Keystone should not start. + pass + + class Conflict(Error): message_format = _("Conflict occurred attempting to store %(type)s -" " %(details)s") diff --git a/keystone/identity/backends/ldap.py b/keystone/identity/backends/ldap.py index 1e5ea13679..9a923ef44c 100644 --- a/keystone/identity/backends/ldap.py +++ b/keystone/identity/backends/ldap.py @@ -47,9 +47,6 @@ class Identity(identity.IdentityDriverV8): self.user = UserApi(self.conf) self.group = GroupApi(self.conf) - def default_assignment_driver(self): - return 'ldap' - def is_domain_aware(self): return False diff --git a/keystone/identity/backends/sql.py b/keystone/identity/backends/sql.py index 7273629b91..43e69463cd 100644 --- a/keystone/identity/backends/sql.py +++ b/keystone/identity/backends/sql.py @@ -158,9 +158,6 @@ class Identity(identity.IdentityDriverV8): self.conf = conf super(Identity, self).__init__() - def default_assignment_driver(self): - return 'sql' - @property def is_sql(self): return True diff --git a/keystone/identity/core.py b/keystone/identity/core.py index 878936c840..9dddb2122c 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -1231,6 +1231,11 @@ class IdentityDriverV8(object): """Indicates if Driver supports domains.""" return True + def default_assignment_driver(self): + # TODO(morganfainberg): To be removed when assignment driver based + # upon [identity]/driver option is removed in the "O" release. + return 'sql' + @property def is_sql(self): """Indicates if this Driver uses SQL.""" diff --git a/keystone/server/backends.py b/keystone/server/backends.py index 12ec0d22a7..af888a699d 100644 --- a/keystone/server/backends.py +++ b/keystone/server/backends.py @@ -39,8 +39,14 @@ def load_backends(): region=assignment.COMPUTED_ASSIGNMENTS_REGION, region_name=assignment.COMPUTED_ASSIGNMENTS_REGION.name) - # Ensure that the assignment driver is created before the resource manager. - # The default resource driver depends on assignment. + # Ensure that the identity driver is created before the assignment manager + # and that the assignment driver is created before the resource manager. + # The default resource driver depends on assignment, which in turn + # depends on identity - hence we need to ensure the chain is available. + # TODO(morganfainberg): In "O" release move _IDENTITY_API to be directly + # instantiated in the DRIVERS dict once assignment driver being selected + # based upon [identity]/driver is removed. + _IDENTITY_API = identity.Manager() _ASSIGNMENT_API = assignment.Manager() DRIVERS = dict( @@ -52,7 +58,7 @@ def load_backends(): federation_api=federation.Manager(), id_generator_api=identity.generator.Manager(), id_mapping_api=identity.MappingManager(), - identity_api=identity.Manager(), + identity_api=_IDENTITY_API, oauth_api=oauth1.Manager(), policy_api=policy.Manager(), resource_api=resource.Manager(), diff --git a/keystone/tests/unit/test_backend_ldap.py b/keystone/tests/unit/test_backend_ldap.py index f5e1132dc6..7e63fb74a4 100644 --- a/keystone/tests/unit/test_backend_ldap.py +++ b/keystone/tests/unit/test_backend_ldap.py @@ -998,7 +998,10 @@ class LDAPIdentity(BaseLDAPIdentity, unit.TestCase): # credentials) that require a database. self.useFixture(database.Database()) super(LDAPIdentity, self).setUp() - _assert_backends(self, identity='ldap') + _assert_backends(self, + assignment='sql', + identity='ldap', + resource='sql') def load_fixtures(self, fixtures): # Override super impl since need to create group container. @@ -1875,12 +1878,14 @@ class LDAPLimitTests(unit.TestCase, test_backend.LimitTests): super(LDAPLimitTests, self).setUp() self.useFixture(ldapdb.LDAPDatabase()) - self.useFixture(database.Database()) self.useFixture(database.Database(self.sql_driver_version_overrides)) self.load_backends() self.load_fixtures(default_fixtures) test_backend.LimitTests.setUp(self) - _assert_backends(self, identity='ldap') + _assert_backends(self, + assignment='sql', + identity='ldap', + resource='sql') def config_overrides(self): super(LDAPLimitTests, self).config_overrides()