]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: RGW port autodetection does not support "Beast" RGW frontend 33060/head
authorVolker Theile <vtheile@suse.com>
Tue, 4 Feb 2020 14:04:08 +0000 (15:04 +0100)
committerVolker Theile <vtheile@suse.com>
Tue, 18 Feb 2020 16:06:02 +0000 (17:06 +0100)
* Improve regular expressions to support more configuration variations.
* Modify error message. It includes the config line to be parsed. This should help to debug errors much easier.
* If there are multiple (ssl_)ports/(ssl_)endpoints options, then the first found option will be returned.

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

index a3c7b6edc63ba520da09b8e8083d0490fa34b724..5ec4269ee1916895b64266c7045ee627bbf5e01f 100644 (file)
@@ -150,44 +150,13 @@ def _parse_frontend_config(config):
     Get the port the RGW is running on. Due the complexity of the
     syntax not all variations are supported.
 
+    If there are multiple (ssl_)ports/(ssl_)endpoints options, then
+    the first found option will be returned.
+
     Get more details about the configuration syntax here:
     http://docs.ceph.com/docs/master/radosgw/frontends/
     https://civetweb.github.io/civetweb/UserManual.html
 
-    >>> _parse_frontend_config('beast port=8000')
-    (8000, False)
-
-    >>> _parse_frontend_config('civetweb port=8000s')
-    (8000, True)
-
-    >>> _parse_frontend_config('beast port=192.0.2.3:80')
-    (80, False)
-
-    >>> _parse_frontend_config('civetweb port=172.5.2.51:8080s')
-    (8080, True)
-
-    >>> _parse_frontend_config('civetweb port=[::]:8080')
-    (8080, False)
-
-    >>> _parse_frontend_config('civetweb port=ip6-localhost:80s')
-    (80, True)
-
-    >>> _parse_frontend_config('civetweb port=[2001:0db8::1234]:80')
-    (80, False)
-
-    >>> _parse_frontend_config('civetweb port=[::1]:8443s')
-    (8443, True)
-
-    >>> _parse_frontend_config('civetweb port=xyz')
-    Traceback (most recent call last):
-    ...
-    LookupError: Failed to determine RGW port
-
-    >>> _parse_frontend_config('civetweb')
-    Traceback (most recent call last):
-    ...
-    LookupError: Failed to determine RGW port
-
     :param config: The configuration string to parse.
     :type config: str
     :raises LookupError if parsing fails to determine the port.
@@ -195,12 +164,36 @@ def _parse_frontend_config(config):
              whether SSL is used.
     :rtype: (int, boolean)
     """
-    match = re.search(r'port=(.*:)?(\d+)(s)?', config)
+    match = re.search(r'^(beast|civetweb)\s+.+$', config)
     if match:
-        port = int(match.group(2))
-        ssl = match.group(3) == 's'
-        return port, ssl
-    raise LookupError('Failed to determine RGW port')
+        if match.group(1) == 'beast':
+            match = re.search(r'(port|ssl_port|endpoint|ssl_endpoint)=(.+)',
+                              config)
+            if match:
+                option_name = match.group(1)
+                if option_name in ['port', 'ssl_port']:
+                    match = re.search(r'(\d+)', match.group(2))
+                    if match:
+                        port = int(match.group(1))
+                        ssl = option_name == 'ssl_port'
+                        return port, ssl
+                if option_name in ['endpoint', 'ssl_endpoint']:
+                    match = re.search(r'([\d.]+|\[.+\])(:(\d+))?',
+                                      match.group(2))
+                    if match:
+                        port = int(match.group(3)) if \
+                            match.group(2) is not None else 443 if \
+                            option_name == 'ssl_endpoint' else \
+                            80
+                        ssl = option_name == 'ssl_endpoint'
+                        return port, ssl
+        if match.group(1) == 'civetweb':
+            match = re.search(r'port=(.*:)?(\d+)(s)?', config)
+            if match:
+                port = int(match.group(2))
+                ssl = match.group(3) == 's'
+                return port, ssl
+    raise LookupError('Failed to determine RGW port from "{}"'.format(config))
 
 
 class RgwClient(RestClient):
@@ -256,7 +249,7 @@ class RgwClient(RestClient):
         return [partial_dict(
             zonegroup['val'],
             ['api_name', 'zones']
-            ) for zonegroup in zonegroups['zonegroups']]
+        ) for zonegroup in zonegroups['zonegroups']]
 
     @staticmethod
     def _rgw_settings():
index 8d5241cd4a253287dd1e3c8b99ebb1f6d72c1e73..7e153a2eefc6671639287888012b65fcbd8cda38 100644 (file)
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+# pylint: disable=too-many-public-methods
 import unittest
 
 try:
@@ -6,7 +7,7 @@ try:
 except ImportError:
     from unittest.mock import patch
 
-from ..services.rgw_client import RgwClient
+from ..services.rgw_client import RgwClient, _parse_frontend_config
 from ..settings import Settings
 from . import KVStoreMockMixin
 
@@ -122,3 +123,86 @@ class RgwClientTest(unittest.TestCase, KVStoreMockMixin):
             ]
         }
         self.assertEqual(expected_result, instance.get_placement_targets())
+
+
+class RgwClientHelperTest(unittest.TestCase):
+    def test_parse_frontend_config_1(self):
+        self.assertEqual(_parse_frontend_config('beast port=8000'), (8000, False))
+
+    def test_parse_frontend_config_2(self):
+        self.assertEqual(_parse_frontend_config('beast port=80 port=8000'), (80, False))
+
+    def test_parse_frontend_config_3(self):
+        self.assertEqual(_parse_frontend_config('beast ssl_port=443 port=8000'), (443, True))
+
+    def test_parse_frontend_config_4(self):
+        self.assertEqual(_parse_frontend_config('beast endpoint=192.168.0.100:8000'), (8000, False))
+
+    def test_parse_frontend_config_5(self):
+        self.assertEqual(_parse_frontend_config('beast endpoint=[::1]'), (80, False))
+
+    def test_parse_frontend_config_6(self):
+        self.assertEqual(_parse_frontend_config(
+            'beast ssl_endpoint=192.168.0.100:8443'), (8443, True))
+
+    def test_parse_frontend_config_7(self):
+        self.assertEqual(_parse_frontend_config('beast ssl_endpoint=192.168.0.100'), (443, True))
+
+    def test_parse_frontend_config_8(self):
+        self.assertEqual(_parse_frontend_config(
+            'beast ssl_endpoint=[::1]:8443 endpoint=192.0.2.3:80'), (8443, True))
+
+    def test_parse_frontend_config_9(self):
+        self.assertEqual(_parse_frontend_config(
+            'beast port=8080 endpoint=192.0.2.3:80'), (8080, False))
+
+    def test_parse_frontend_config_10(self):
+        self.assertEqual(_parse_frontend_config(
+            'beast ssl_endpoint=192.0.2.3:8443 port=8080'), (8443, True))
+
+    def test_parse_frontend_config_11(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=8000s'), (8000, True))
+
+    def test_parse_frontend_config_12(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=443s port=8000'), (443, True))
+
+    def test_parse_frontend_config_13(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=192.0.2.3:80'), (80, False))
+
+    def test_parse_frontend_config_14(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=172.5.2.51:8080s'), (8080, True))
+
+    def test_parse_frontend_config_15(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=[::]:8080'), (8080, False))
+
+    def test_parse_frontend_config_16(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=ip6-localhost:80s'), (80, True))
+
+    def test_parse_frontend_config_17(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=[2001:0db8::1234]:80'), (80, False))
+
+    def test_parse_frontend_config_18(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=[::1]:8443s'), (8443, True))
+
+    def test_parse_frontend_config_19(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=127.0.0.1:8443s+8000'), (8443, True))
+
+    def test_parse_frontend_config_20(self):
+        self.assertEqual(_parse_frontend_config('civetweb port=127.0.0.1:8080+443s'), (8080, False))
+
+    def test_parse_frontend_config_21(self):
+        with self.assertRaises(LookupError) as ctx:
+            _parse_frontend_config('civetweb port=xyz')
+        self.assertEqual(str(ctx.exception),
+                         'Failed to determine RGW port from "civetweb port=xyz"')
+
+    def test_parse_frontend_config_22(self):
+        with self.assertRaises(LookupError) as ctx:
+            _parse_frontend_config('civetweb')
+        self.assertEqual(str(ctx.exception), 'Failed to determine RGW port from "civetweb"')
+
+    def test_parse_frontend_config_23(self):
+        with self.assertRaises(LookupError) as ctx:
+            _parse_frontend_config('mongoose port=8080')
+        self.assertEqual(str(ctx.exception),
+                         'Failed to determine RGW port from "mongoose port=8080"')