]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Stale RGW user/account metadata cache in mgr after delete and recreate 69968/head
authorNaman Munet <naman.munet@ibm.com>
Mon, 6 Jul 2026 17:15:22 +0000 (22:45 +0530)
committerNaman Munet <naman.munet@ibm.com>
Tue, 7 Jul 2026 05:55:18 +0000 (11:25 +0530)
fixes: https://tracker.ceph.com/issues/77544

Signed-off-by: Naman Munet <naman.munet@ibm.com>
src/pybind/mgr/dashboard/controllers/rgw.py
src/pybind/mgr/dashboard/services/rgw_client.py

index a0ef6965771f394b3da2fe16436608fecba28890..61b26c2e73405f3563031ab90191b31d17e207d2 100755 (executable)
@@ -1099,8 +1099,15 @@ class RgwUser(RgwRESTController):
                 raise DashboardException(msg='Unable to delete "{}" - this user '
                                              'account is required for managing the '
                                              'Object Gateway'.format(uid))
-            # Finally redirect request to the RGW proxy.
-            return self.proxy(daemon_name, 'DELETE', 'user', {'uid': uid}, json_response=False)
+            daemon_name_to_use = daemon_name if daemon_name else instance.daemon.name
+            user_instance = RgwClient.get_cached_user_instance(daemon_name_to_use, uid)
+            result = self.proxy(daemon_name, 'DELETE', 'user', {'uid': uid}, json_response=False)
+            # Only invalidate cache after successful deletion to prevent negative cache hits
+            # when the user is recreated with the same UID. This fixes the issue where
+            # Dashboard fails to authenticate after deleting and recreating a user.
+            if user_instance:
+                RgwClient.drop_instance(user_instance)
+            return result
         except (DashboardException, RequestException) as e:  # pragma: no cover
             raise DashboardException(e, component='rgw')
 
index a36eded72dd873fda8ce11e89cdee4d3fc0eaa53..f060efd4fc3a7d1a1499c9e913280004cdacde49 100755 (executable)
@@ -370,6 +370,20 @@ class RgwClient(RestClient):
     def admin_instance(daemon_name: Optional[str] = None) -> 'RgwClient':
         return RgwClient.instance(daemon_name=daemon_name)
 
+    @staticmethod
+    def get_cached_user_instance(daemon_name: str, userid: str) -> Optional['RgwClient']:
+        """
+        Get a cached user instance if it exists.
+
+        :param daemon_name: The daemon name
+        :param userid: The user ID
+        :return: The cached RgwClient instance or None if not found
+        """
+        if daemon_name in RgwClient._user_instances and \
+           userid in RgwClient._user_instances[daemon_name]:
+            return RgwClient._user_instances[daemon_name][userid]
+        return None
+
     @staticmethod
     def drop_instance(instance: Optional['RgwClient'] = None):
         """