]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: fix bind address regression from CherryPy isolation 69715/head
authorAfreen Misbah <afreen@ibm.com>
Tue, 23 Jun 2026 13:30:22 +0000 (19:00 +0530)
committerAfreen Misbah <afreen@ibm.com>
Thu, 9 Jul 2026 20:20:07 +0000 (01:50 +0530)
The CherryPy isolation refactor (PR #67227) accidentally changed the
dashboard bind address from wildcard (*:8443) to mon_ip:8443. The
get_mgr_ip() replacement was originally only for URI generation, but
the refactor passed the mutated address to CherryPyMgr.mount() as the
actual socket bind address.

This breaks the management gateway when its VIP is not on the same
interface as mon_ip, as the dashboard becomes unreachable on other
interfaces.

Preserve the original wildcard address for binding and only use
get_mgr_ip() for the advertised URI. Add regression test to prevent
future confusion between bind_addr and server_addr.

Fixes: https://tracker.ceph.com/issues/77491
Signed-off-by: Afreen Misbah <afreen@ibm.com>
(cherry picked from commit f45a1bfc93596f17370ee38ce241ae8123d81e8e)

src/pybind/mgr/dashboard/module.py
src/pybind/mgr/dashboard/tests/test_settings.py

index 1f5798b41f2a77e1b8bd4d80e1a71f452664ab1e..890de34eadd83faa275b0c607fba3e35ad493ede 100644 (file)
@@ -210,6 +210,7 @@ class CherryPyConfig(object):
         self._url_prefix = prepare_url_prefix(self.get_module_option(  # type: ignore
             'url_prefix', default=''))
 
+        bind_addr = server_addr
         if server_addr in ['::', '0.0.0.0']:
             server_addr = self.get_mgr_ip()  # type: ignore
         base_url = build_url(
@@ -218,7 +219,7 @@ class CherryPyConfig(object):
             port=server_port,
         )
         uri = f'{base_url}{self.url_prefix}/'
-        return uri, (server_addr, server_port), ssl_info, config
+        return uri, (bind_addr, server_port), ssl_info, config
 
     def await_configuration(self):
         """
index d6c94b6b0b8ba9956018aa3e44f405ce615c838c..17dad55040095a2a52decab504dff28c596606a8 100644 (file)
@@ -2,11 +2,13 @@
 
 import errno
 import unittest
+from unittest.mock import MagicMock
 
 from mgr_module import ERROR_MSG_EMPTY_INPUT_FILE
 
 from .. import settings
 from ..controllers.settings import Settings as SettingsController
+from ..module import CherryPyConfig
 from ..settings import Settings, handle_option_command
 from ..tests import ControllerTestCase, KVStoreMockMixin
 
@@ -125,6 +127,33 @@ class SettingsTest(unittest.TestCase, KVStoreMockMixin):
         self.assertEqual(str(ctx.exception),
                          "type object 'Options' has no attribute 'NON_EXISTENT_OPTION'")
 
+    def _setup_cherrypy_config(self, server_addr, server_port):
+        obj = CherryPyConfig()
+        config_map = {
+            'server_addr': server_addr,
+            'ssl': False,
+            'server_port': server_port
+        }
+        obj.get_localized_module_option = MagicMock(
+            side_effect=lambda key, default=None: config_map.get(key, default))
+        obj.get_mgr_ip = MagicMock(return_value='192.168.1.10')
+        obj.get_module_option = MagicMock(return_value='')
+        obj.get_mgr_id = MagicMock(return_value='test')
+        obj.module_name = 'dashboard'
+        obj.log = MagicMock()
+        obj.update_cherrypy_config = MagicMock()
+        return obj
+
+    def test_wildcard_bind_addr_preserved(self):
+        obj = self._setup_cherrypy_config('::', 8080)
+        _, bind_addr, _, _ = obj._configure()  # pylint: disable=protected-access
+        self.assertEqual(bind_addr, ('::', 8080))
+
+    def test_wildcard_bind_addr_preserved_ipv4(self):
+        obj = self._setup_cherrypy_config('0.0.0.0', 8443)
+        _, bind_addr, _, _ = obj._configure()  # pylint: disable=protected-access
+        self.assertEqual(bind_addr, ('0.0.0.0', 8443))
+
 
 class SettingsControllerTest(ControllerTestCase, KVStoreMockMixin):
     @classmethod