]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Load iSCSI config from local store and orchestrator
authorSebastian Wagner <sebastian.wagner@suse.com>
Mon, 13 May 2019 09:44:46 +0000 (11:44 +0200)
committerSebastian Wagner <sebastian.wagner@suse.com>
Tue, 21 May 2019 13:06:52 +0000 (15:06 +0200)
As iSCSI is not supported by Rook, users need a way to manage
  ceph-iscsi without Rook knowledge

Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
src/pybind/mgr/dashboard/controllers/iscsi.py
src/pybind/mgr/dashboard/services/iscsi_config.py
src/pybind/mgr/mgr_util.py

index 9f0e9829014520964722a6ea9a4402c9645f96e9..b58ef66a9f2ec6ddfb54793577bea786217de8cc 100644 (file)
@@ -51,10 +51,14 @@ class IscsiUi(BaseController):
             status['available'] = True
         except RequestException as e:
             if e.content:
-                content = json.loads(e.content)
-                content_message = content.get('message')
+                try:
+                    content = json.loads(e.content)
+                    content_message = content.get('message')
+                except ValueError:
+                    content_message = e.content
                 if content_message:
                     status['message'] = content_message
+
         return status
 
     @Endpoint()
index bb6de51a99e822eb3b46e0984d3d8f4f07234364..963d2f990d7c3df8323384ddc574819aaffd4cae 100644 (file)
@@ -3,11 +3,14 @@ from __future__ import absolute_import
 
 import json
 
+from orchestrator import OrchestratorError
+
 try:
     from urlparse import urlparse
 except ImportError:
     from urllib.parse import urlparse
 
+from mgr_util import merge_dicts
 from .orchestrator import OrchClient
 from .. import mgr
 
@@ -48,13 +51,24 @@ _ISCSI_STORE_KEY = "_iscsi_config"
 
 class IscsiGatewaysConfig(object):
     @classmethod
-    def _load_config(cls):
-        if OrchClient().available():
-            raise ManagedByOrchestratorException()
+    def _load_config_from_store(cls):
         json_db = mgr.get_store(_ISCSI_STORE_KEY,
                                 '{"gateways": {}}')
         return json.loads(json_db)
 
+    @staticmethod
+    def _load_config_from_orchestrator():
+        config = {'gateways': {}}
+        try:
+            instances = OrchClient().list_service_info("iscsi")
+            for instance in instances:
+                config['gateways'][instance.nodename] = {
+                    'service_url': instance.service_url
+                }
+        except (RuntimeError, OrchestratorError, ImportError):
+            pass
+        return config
+
     @classmethod
     def _save_config(cls, config):
         mgr.set_store(_ISCSI_STORE_KEY, json.dumps(config))
@@ -67,7 +81,7 @@ class IscsiGatewaysConfig(object):
 
     @classmethod
     def add_gateway(cls, name, service_url):
-        config = cls._load_config()
+        config = cls.get_gateways_config()
         if name in config:
             raise IscsiGatewayAlreadyExists(name)
         IscsiGatewaysConfig.validate_service_url(service_url)
@@ -76,7 +90,10 @@ class IscsiGatewaysConfig(object):
 
     @classmethod
     def remove_gateway(cls, name):
-        config = cls._load_config()
+        if name in cls._load_config_from_orchestrator()['gateways']:
+            raise ManagedByOrchestratorException()
+
+        config = cls._load_config_from_store()
         if name not in config['gateways']:
             raise IscsiGatewayDoesNotExist(name)
 
@@ -85,16 +102,10 @@ class IscsiGatewaysConfig(object):
 
     @classmethod
     def get_gateways_config(cls):
-        try:
-            config = cls._load_config()
-        except ManagedByOrchestratorException:
-            config = {'gateways': {}}
-            instances = OrchClient().list_service_info("iscsi")
-            for instance in instances:
-                config['gateways'][instance.nodename] = {
-                    'service_url': instance.service_url
-                }
-        return config
+        orch_config = cls._load_config_from_orchestrator()
+        local_config = cls._load_config_from_store()
+
+        return {'gateways': merge_dicts(orch_config['gateways'], local_config['gateways'])}
 
     @classmethod
     def get_gateway_config(cls, name):
index fed3c54e9a6fba4a1d95c8991cab67c58acf6396..3a48e9330267f87d0226146f203aef02efa4baa5 100644 (file)
@@ -71,3 +71,17 @@ def format_dimless(n, width, colored=True):
 
 def format_bytes(n, width, colored=True):
     return format_units(n, width, colored, decimal=False)
+
+
+def merge_dicts(*args):
+    # type: (dict) -> dict
+    """
+    >>> assert merge_dicts({1:2}, {3:4}) == {1:2, 3:4}
+        You can also overwrite keys:
+    >>> assert merge_dicts({1:2}, {1:4}) == {1:4}
+    :rtype: dict[str, Any]
+    """
+    ret = {}
+    for arg in args:
+        ret.update(arg)
+    return ret