Browse Source

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 62ee18b359)
Colleen Murphy 1 year ago
parent
commit
b6a009254f

+ 15
- 6
keystone/identity/core.py View File

@@ -487,17 +487,26 @@ class Manager(manager.Manager):
487 487
     def __init__(self):
488 488
         super(Manager, self).__init__(CONF.identity.driver)
489 489
         self.domain_configs = DomainConfigs()
490
-
491
-        self.event_callbacks = {
492
-            notifications.ACTIONS.deleted: {
493
-                'domain': [self._domain_deleted],
494
-            },
495
-        }
490
+        notifications.register_event_callback(
491
+            notifications.ACTIONS.internal, notifications.DOMAIN_DELETED,
492
+            self._domain_deleted
493
+        )
494
+        self.event_callbacks = {}
496 495
 
497 496
     def _domain_deleted(self, service, resource_type, operation,
498 497
                         payload):
499 498
         domain_id = payload['resource_info']
500 499
 
500
+        driver = self._select_identity_driver(domain_id)
501
+
502
+        if not driver.is_sql:
503
+            # The LDAP driver does not support deleting users or groups.
504
+            # Moreover, we shouldn't destroy users and groups in an unknown
505
+            # driver. The only time when we should delete users and groups is
506
+            # when the backend is SQL because the foreign key in the SQL table
507
+            # forces us to.
508
+            return
509
+
501 510
         user_refs = self.list_users(domain_scope=domain_id)
502 511
         group_refs = self.list_groups(domain_scope=domain_id)
503 512
 

+ 1
- 0
keystone/notifications.py View File

@@ -78,6 +78,7 @@ CONF = keystone.conf.CONF
78 78
 INVALIDATE_USER_TOKEN_PERSISTENCE = 'invalidate_user_tokens'
79 79
 INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE = 'invalidate_user_project_tokens'
80 80
 INVALIDATE_USER_OAUTH_CONSUMER_TOKENS = 'invalidate_user_consumer_tokens'
81
+DOMAIN_DELETED = 'domain_deleted'
81 82
 
82 83
 
83 84
 class Audit(object):

+ 3
- 0
keystone/resource/core.py View File

@@ -757,6 +757,9 @@ class Manager(manager.Manager):
757 757
                   'first.'))
758 758
 
759 759
         self._delete_domain_contents(domain_id)
760
+        notifications.Audit.internal(
761
+            notifications.DOMAIN_DELETED, domain_id
762
+        )
760 763
         self._delete_project(domain_id, initiator)
761 764
         try:
762 765
             self.get_domain.invalidate(self, domain_id)

+ 17
- 0
releasenotes/notes/bug-1718747-50d39fa87bdbb12b.yaml View File

@@ -0,0 +1,17 @@
1
+---
2
+fixes:
3
+  - |
4
+    [`bug 1718747 <https://bugs.launchpad.net/keystone/+bug/1718747>`_]
5
+    Fixes a regression where deleting a domain with users in it caues a server
6
+    error. This bugfix restores the previous behavior of deleting the users
7
+    namespaced in the domain. This only applies when using the SQL identity
8
+    backend.
9
+other:
10
+  - |
11
+    [`bug 1718747 <https://bugs.launchpad.net/keystone/+bug/1718747>`_]
12
+    As part of solving a regression in the identity SQL backend that prevented
13
+    domains containing users from being deleted, a notification callback was
14
+    altered so that users would only be deleted if the identity backend is SQL.
15
+    If you have a custom identity backend that is not read-only, deleting a
16
+    domain in keystone will not delete the users in your backend unless your
17
+    driver has an is_sql property that evaluates to true.

Loading…
Cancel
Save