summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColleen Murphy <colleen@gazlene.net>2018-01-30 23:23:15 +0100
committerColleen Murphy <colleen.murphy@suse.de>2018-02-12 14:22:52 +0100
commitb6a009254f7975bf806c499874ad87746bb8cbd8 (patch)
tree1d5c4d16de9a014372b983814f4bb05961b5eb61
parent5c34cb43d373330534bdcf5feff64fb0abbb8cda (diff)
downloadkeystone-b6a009254f7975bf806c499874ad87746bb8cbd8.tar.gz
Delete SQL users before deleting domain
Since the users table has a foreign key to the projects table[1], users must be deleted before the domain can be deleted. However, the notification emitted from the domain deletion comes too late, and keystone runs into a foreign key reference error before it can delete the users. This patch addresses the problem by adding a new internal notification to alert the identity manager that users should be deleted. This uses a new notification rather than the existing notification because the existing one is used to alert listeners that the domain deletion has been fully completed, whereas this one must happen in the middle of the domain delete process. The callback must also only try to delete SQL users. The LDAP driver doesn't support deleting users, and we can't assume other drivers support it either. Moreover, the foreign key reference is only a problem for SQL users anyway. Because our backend unit tests run with SQLite and foreign keys do not work properly, we can't properly expose this bug in our unit tests, but there is an accompanying tempest test[2][3] to validate this fix. [1] https://github.com/openstack/keystone/blob/2bd88d3/keystone/common/sql/expand_repo/versions/014_expand_add_domain_id_to_user_table.py#L140-L141 [2] https://review.openstack.org/#/c/509610 [3] https://review.openstack.org/#/c/509947 Change-Id: If5bdb6f5eef80b50b000aed5188ce7da4dfd1083 Closes-bug: #1718747 (cherry picked from commit 62ee18b359cbb2e6a9469bdaac9057ef19de1bdf)
-rw-r--r--keystone/identity/core.py21
-rw-r--r--keystone/notifications.py1
-rw-r--r--keystone/resource/core.py3
-rw-r--r--releasenotes/notes/bug-1718747-50d39fa87bdbb12b.yaml17
4 files changed, 36 insertions, 6 deletions
diff --git a/keystone/identity/core.py b/keystone/identity/core.py
index c97b6a79b..5168bf01f 100644
--- a/keystone/identity/core.py
+++ b/keystone/identity/core.py
@@ -487,17 +487,26 @@ class Manager(manager.Manager):
def __init__(self):
super(Manager, self).__init__(CONF.identity.driver)
self.domain_configs = DomainConfigs()
-
- self.event_callbacks = {
- notifications.ACTIONS.deleted: {
- 'domain': [self._domain_deleted],
- },
- }
+ notifications.register_event_callback(
+ notifications.ACTIONS.internal, notifications.DOMAIN_DELETED,
+ self._domain_deleted
+ )
+ self.event_callbacks = {}
def _domain_deleted(self, service, resource_type, operation,
payload):
domain_id = payload['resource_info']
+ driver = self._select_identity_driver(domain_id)
+
+ if not driver.is_sql:
+ # The LDAP driver does not support deleting users or groups.
+ # Moreover, we shouldn't destroy users and groups in an unknown
+ # driver. The only time when we should delete users and groups is
+ # when the backend is SQL because the foreign key in the SQL table
+ # forces us to.
+ return
+
user_refs = self.list_users(domain_scope=domain_id)
group_refs = self.list_groups(domain_scope=domain_id)
diff --git a/keystone/notifications.py b/keystone/notifications.py
index 9354e66d4..8488ae0e4 100644
--- a/keystone/notifications.py
+++ b/keystone/notifications.py
@@ -78,6 +78,7 @@ CONF = keystone.conf.CONF
INVALIDATE_USER_TOKEN_PERSISTENCE = 'invalidate_user_tokens'
INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE = 'invalidate_user_project_tokens'
INVALIDATE_USER_OAUTH_CONSUMER_TOKENS = 'invalidate_user_consumer_tokens'
+DOMAIN_DELETED = 'domain_deleted'
class Audit(object):
diff --git a/keystone/resource/core.py b/keystone/resource/core.py
index 175ec6b93..3c5c26cde 100644
--- a/keystone/resource/core.py
+++ b/keystone/resource/core.py
@@ -757,6 +757,9 @@ class Manager(manager.Manager):
'first.'))
self._delete_domain_contents(domain_id)
+ notifications.Audit.internal(
+ notifications.DOMAIN_DELETED, domain_id
+ )
self._delete_project(domain_id, initiator)
try:
self.get_domain.invalidate(self, domain_id)
diff --git a/releasenotes/notes/bug-1718747-50d39fa87bdbb12b.yaml b/releasenotes/notes/bug-1718747-50d39fa87bdbb12b.yaml
new file mode 100644
index 000000000..2ee2f44bf
--- /dev/null
+++ b/releasenotes/notes/bug-1718747-50d39fa87bdbb12b.yaml
@@ -0,0 +1,17 @@
+---
+fixes:
+ - |
+ [`bug 1718747 <https://bugs.launchpad.net/keystone/+bug/1718747>`_]
+ Fixes a regression where deleting a domain with users in it caues a server
+ error. This bugfix restores the previous behavior of deleting the users
+ namespaced in the domain. This only applies when using the SQL identity
+ backend.
+other:
+ - |
+ [`bug 1718747 <https://bugs.launchpad.net/keystone/+bug/1718747>`_]
+ As part of solving a regression in the identity SQL backend that prevented
+ domains containing users from being deleted, a notification callback was
+ altered so that users would only be deleted if the identity backend is SQL.
+ If you have a custom identity backend that is not read-only, deleting a
+ domain in keystone will not delete the users in your backend unless your
+ driver has an is_sql property that evaluates to true.