From: Nizamudeen A Date: Thu, 24 Aug 2023 11:47:29 +0000 (+0530) Subject: mgr/dashboard: fix rgw page issues when hostname not resolvable X-Git-Tag: v16.2.15~200^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ec3151dbdadcd016fa3a8e1de1f8de54667cd540;p=ceph.git mgr/dashboard: fix rgw page issues when hostname not resolvable Part of the fix is copied from https://github.com/ceph/ceph/pull/47495/files#diff-ba538532bb5450d415ab80916916bd68fe51d195e57c9aa34effaa8789d7a392R705 Fixes: https://tracker.ceph.com/issues/62396 Signed-off-by: Nizamudeen A (cherry picked from commit 78cfeb6372707ec3f997d28ad617367feb3a983e) Conflicts: src/pybind/mgr/dashboard/services/rgw_client.py - only keep the CephService import --- diff --git a/src/pybind/mgr/dashboard/services/rgw_client.py b/src/pybind/mgr/dashboard/services/rgw_client.py index 4c401f2a42ae..f6ee0df57611 100644 --- a/src/pybind/mgr/dashboard/services/rgw_client.py +++ b/src/pybind/mgr/dashboard/services/rgw_client.py @@ -9,7 +9,7 @@ import xml.etree.ElementTree as ET # noqa: N814 from distutils.util import strtobool from subprocess import SubprocessError -from mgr_util import build_url +from mgr_util import build_url, name_to_config_section from .. import mgr from ..awsauth import S3Auth @@ -17,6 +17,7 @@ from ..exceptions import DashboardException from ..rest_client import RequestException, RestClient from ..settings import Settings from ..tools import dict_contains_path, dict_get, json_str_to_object +from .ceph_service import CephService try: from typing import Any, Dict, List, Optional, Tuple, Union @@ -85,9 +86,19 @@ def _determine_rgw_addr(daemon_info: Dict[str, Any]) -> RgwDaemon: Parse RGW daemon info to determine the configured host (IP address) and port. """ daemon = RgwDaemon() - daemon.host = daemon_info['metadata']['hostname'] + rgw_dns_name = CephService.send_command('mon', 'config get', + who=name_to_config_section('rgw.' + daemon_info['metadata']['id']), # noqa E501 #pylint: disable=line-too-long + key='rgw_dns_name').rstrip() + daemon.port, daemon.ssl = _parse_frontend_config(daemon_info['metadata']['frontend_config#0']) + if rgw_dns_name: + daemon.host = rgw_dns_name + elif daemon.ssl: + daemon.host = daemon_info['metadata']['hostname'] + else: + daemon.host = _parse_addr(daemon_info['addr']) + return daemon diff --git a/src/pybind/mgr/dashboard/tests/test_rgw.py b/src/pybind/mgr/dashboard/tests/test_rgw.py index ce1b5fd928fd..cea12ba4fb74 100644 --- a/src/pybind/mgr/dashboard/tests/test_rgw.py +++ b/src/pybind/mgr/dashboard/tests/test_rgw.py @@ -19,7 +19,9 @@ class RgwControllerTestCase(ControllerTestCase): @patch.object(RgwClient, '_get_user_id', Mock(return_value='fake-user')) @patch.object(RgwClient, 'is_service_online', Mock(return_value=True)) @patch.object(RgwClient, '_is_system_user', Mock(return_value=True)) - def test_status_available(self): + @patch('dashboard.services.ceph_service.CephService.send_command') + def test_status_available(self, send_command): + send_command.return_value = '' self._get('/test/ui-api/rgw/status') self.assertStatus(200) self.assertJsonBody({'available': True, 'message': None}) @@ -27,7 +29,9 @@ class RgwControllerTestCase(ControllerTestCase): @patch.object(RgwClient, '_get_user_id', Mock(return_value='fake-user')) @patch.object(RgwClient, 'is_service_online', Mock( side_effect=RequestException('My test error'))) - def test_status_online_check_error(self): + @patch('dashboard.services.ceph_service.CephService.send_command') + def test_status_online_check_error(self, send_command): + send_command.return_value = '' self._get('/test/ui-api/rgw/status') self.assertStatus(200) self.assertJsonBody({'available': False, @@ -35,7 +39,9 @@ class RgwControllerTestCase(ControllerTestCase): @patch.object(RgwClient, '_get_user_id', Mock(return_value='fake-user')) @patch.object(RgwClient, 'is_service_online', Mock(return_value=False)) - def test_status_not_online(self): + @patch('dashboard.services.ceph_service.CephService.send_command') + def test_status_not_online(self, send_command): + send_command.return_value = '' self._get('/test/ui-api/rgw/status') self.assertStatus(200) self.assertJsonBody({'available': False, @@ -44,7 +50,9 @@ class RgwControllerTestCase(ControllerTestCase): @patch.object(RgwClient, '_get_user_id', Mock(return_value='fake-user')) @patch.object(RgwClient, 'is_service_online', Mock(return_value=True)) @patch.object(RgwClient, '_is_system_user', Mock(return_value=False)) - def test_status_not_system_user(self): + @patch('dashboard.services.ceph_service.CephService.send_command') + def test_status_not_system_user(self, send_command): + send_command.return_value = '' self._get('/test/ui-api/rgw/status') self.assertStatus(200) self.assertJsonBody({'available': False, @@ -64,7 +72,9 @@ class RgwDaemonControllerTestCase(ControllerTestCase): @patch('dashboard.services.rgw_client.RgwClient._get_user_id', Mock( return_value='dummy_admin')) - def test_list(self): + @patch('dashboard.services.ceph_service.CephService.send_command') + def test_list(self, send_command): + send_command.return_value = '' RgwStub.get_daemons() RgwStub.get_settings() mgr.list_servers.return_value = [{ @@ -155,7 +165,9 @@ class RgwUserControllerTestCase(ControllerTestCase): self.assertJsonBody(['test1', 'test2', 'test3', 'admin']) @patch('dashboard.controllers.rgw.RgwRESTController.proxy') - def test_user_list_duplicate_marker(self, mock_proxy): + @patch('dashboard.services.ceph_service.CephService.send_command') + def test_user_list_duplicate_marker(self, mock_proxy, send_command): + send_command.return_value = '' mock_proxy.side_effect = [{ 'count': 3, 'keys': ['test1', 'test2', 'test3'], diff --git a/src/pybind/mgr/dashboard/tests/test_rgw_client.py b/src/pybind/mgr/dashboard/tests/test_rgw_client.py index d23bdec2ca51..4949ba36bf21 100644 --- a/src/pybind/mgr/dashboard/tests/test_rgw_client.py +++ b/src/pybind/mgr/dashboard/tests/test_rgw_client.py @@ -14,6 +14,8 @@ from ..tests import CLICommandTestMixin, RgwStub @patch('dashboard.services.rgw_client.RgwClient._get_user_id', Mock( return_value='dummy_admin')) +@patch('dashboard.services.ceph_service.CephService.send_command', Mock( + return_value='')) class RgwClientTest(TestCase, CLICommandTestMixin): _dashboard_user_realm1_access_key = 'VUOFXZFK24H81ISTVBTR' _dashboard_user_realm1_secret_key = '0PGsCvXPGWS3AGgibUZEcd9efLrbbshlUkY3jruR' diff --git a/src/pybind/mgr/mgr_util.py b/src/pybind/mgr/mgr_util.py index 6500611a8136..43666de363a5 100644 --- a/src/pybind/mgr/mgr_util.py +++ b/src/pybind/mgr/mgr_util.py @@ -12,7 +12,7 @@ import time import logging import sys from threading import Lock, Condition, Event -from typing import no_type_check +from typing import no_type_check, NewType import urllib from functools import wraps if sys.version_info >= (3, 3): @@ -29,6 +29,8 @@ T = TypeVar('T') if TYPE_CHECKING: from mgr_module import MgrModule +ConfEntity = NewType('ConfEntity', str) + Module_T = TypeVar('Module_T', bound="MgrModule") ( @@ -801,3 +803,15 @@ def profile_method(skip_attribute: bool = False) -> Callable[[Callable[..., T]], return result return wrapper return outer + +def name_to_config_section(name: str) -> ConfEntity: + """ + Map from daemon names to ceph entity names (as seen in config) + """ + daemon_type = name.split('.', 1)[0] + if daemon_type in ['rgw', 'rbd-mirror', 'nfs', 'crash', 'iscsi']: + return ConfEntity('client.' + name) + elif daemon_type in ['mon', 'osd', 'mds', 'mgr', 'client']: + return ConfEntity(name) + else: + return ConfEntity('mon')