]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Drop invalid RGW client instances, improve logging 38406/head
authorVolker Theile <vtheile@suse.com>
Wed, 2 Dec 2020 16:14:45 +0000 (17:14 +0100)
committerVolker Theile <vtheile@suse.com>
Mon, 14 Dec 2020 11:57:14 +0000 (12:57 +0100)
* Log RGW settings for easier problem tracking.
* Drop RGW client instances that do not exist anymore. This happens when a RGW service is removed via the orchestrator. The Dashboard tries to access the RGW client using the previous settings which leads to an error which might be confusing. Without dropping the error message 'RGW REST API failed request ...' is displayed instead of the correct one 'No RGW found'. Dropping the RGW client instance will produce correct error messages the next time the backend tries to establish a new connection.

Fixes: https://tracker.ceph.com/issues/48586
Signed-off-by: Volker Theile <vtheile@suse.com>
src/pybind/mgr/dashboard/controllers/rgw.py
src/pybind/mgr/dashboard/services/rgw_client.py

index 984c8622d9bd1db0fc38f70587d818ee8e0df85f..59ed06aa24ba5c5956f4c9f8c9b50bf268608ec9 100644 (file)
@@ -51,7 +51,19 @@ class Rgw(BaseController):
         try:
             instance = RgwClient.admin_instance()
             # Check if the service is online.
-            if not instance.is_service_online():  # pragma: no cover - no complexity there
+            try:
+                is_online = instance.is_service_online()
+            except RequestException as e:
+                # Drop this instance because the RGW client seems not to
+                # exist anymore (maybe removed via orchestrator). Removing
+                # the instance from the cache will result in the correct
+                # error message next time when the backend tries to
+                # establish a new connection (-> 'No RGW found' instead
+                # of 'RGW REST API failed request ...').
+                # Note, this only applies to auto-detected RGW clients.
+                RgwClient.drop_instance(instance.userid)
+                raise e
+            if not is_online:
                 msg = 'Failed to connect to the Object Gateway\'s Admin Ops API.'
                 raise RequestException(msg)
             # Ensure the API user ID is known by the RGW.
index 2355bbbc1ffe8e0480cefd53dfd5aea1347c4330..54b26a7a3a1a3a9106464a0302794593f6d9f9f5 100644 (file)
@@ -15,7 +15,7 @@ from ..settings import Options, Settings
 from ..tools import build_url, dict_contains_path, dict_get, json_str_to_object
 
 try:
-    from typing import Any, Dict, List, Optional
+    from typing import Any, Dict, List, Optional, Tuple
 except ImportError:
     pass  # For typing only
 
@@ -88,19 +88,21 @@ def _get_daemon_info() -> Dict[str, Any]:
     return daemon
 
 
-def _determine_rgw_addr():
+def _determine_rgw_addr() -> Tuple[str, int, bool]:
     """
     Parse RGW daemon info to determine the configured host (IP address) and port.
     """
     daemon = _get_daemon_info()
-
     addr = _parse_addr(daemon['addr'])
     port, ssl = _parse_frontend_config(daemon['metadata']['frontend_config#0'])
 
+    logger.info('Auto-detected RGW configuration: addr=%s, port=%d, ssl=%s',
+                addr, port, str(ssl))
+
     return addr, port, ssl
 
 
-def _parse_addr(value):
+def _parse_addr(value) -> str:
     """
     Get the IP address the RGW is running on.
 
@@ -154,7 +156,7 @@ def _parse_addr(value):
     raise LookupError('Failed to determine RGW address')
 
 
-def _parse_frontend_config(config):
+def _parse_frontend_config(config) -> Tuple[int, bool]:
     """
     Get the port the RGW is running on. Due the complexity of the
     syntax not all variations are supported.
@@ -270,7 +272,7 @@ class RgwClient(RestClient):
         # Discard all cached instances if any rgw setting has changed
         if RgwClient._rgw_settings_snapshot != RgwClient._rgw_settings():
             RgwClient._rgw_settings_snapshot = RgwClient._rgw_settings()
-            RgwClient._user_instances.clear()
+            RgwClient.drop_instance()
 
         if not RgwClient._user_instances:
             RgwClient._load_settings()
@@ -297,6 +299,16 @@ class RgwClient(RestClient):
     def admin_instance():
         return RgwClient.instance(RgwClient._SYSTEM_USERID)
 
+    @staticmethod
+    def drop_instance(userid: Optional[str] = None):
+        """
+        Drop a cached instance by name or all.
+        """
+        if userid:
+            RgwClient._user_instances.pop(userid, None)
+        else:
+            RgwClient._user_instances.clear()
+
     def _reset_login(self):
         if self.userid != RgwClient._SYSTEM_USERID:
             logger.info("Fetching new keys for user: %s", self.userid)