From: Sebastian Wagner Date: Mon, 13 May 2019 09:44:46 +0000 (+0200) Subject: mgr/dashboard: Load iSCSI config from local store and orchestrator X-Git-Tag: v14.2.2~30^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3e9d47f4c15beabb781fe39491fff7ed7f3321ee;p=ceph.git mgr/dashboard: Load iSCSI config from local store and orchestrator As iSCSI is not supported by Rook, users need a way to manage ceph-iscsi without Rook knowledge Signed-off-by: Sebastian Wagner (cherry picked from commit 7b80537c84c0ff00314f36113335351db4e7e0a9) --- diff --git a/src/pybind/mgr/dashboard/controllers/iscsi.py b/src/pybind/mgr/dashboard/controllers/iscsi.py index 9f0e98290145..b58ef66a9f2e 100644 --- a/src/pybind/mgr/dashboard/controllers/iscsi.py +++ b/src/pybind/mgr/dashboard/controllers/iscsi.py @@ -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() diff --git a/src/pybind/mgr/dashboard/services/iscsi_config.py b/src/pybind/mgr/dashboard/services/iscsi_config.py index bb6de51a99e8..963d2f990d7c 100644 --- a/src/pybind/mgr/dashboard/services/iscsi_config.py +++ b/src/pybind/mgr/dashboard/services/iscsi_config.py @@ -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): diff --git a/src/pybind/mgr/mgr_util.py b/src/pybind/mgr/mgr_util.py index fed3c54e9a6f..3a48e9330267 100644 --- a/src/pybind/mgr/mgr_util.py +++ b/src/pybind/mgr/mgr_util.py @@ -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