]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: config iSCSI gateways in Dashboard
authorKiefer Chang <kiefer.chang@suse.com>
Fri, 15 May 2020 09:20:55 +0000 (17:20 +0800)
committerKiefer Chang <kiefer.chang@suse.com>
Sun, 17 May 2020 01:21:14 +0000 (09:21 +0800)
- Add `daemon_check_post` fuction to allow services implement actions
  needed to be done after daemons are checked.
- After iSCSI daemons are spawned, call dashboard CLI to
  set the API URL of the daemons.

Fixes: https://tracker.ceph.com/issues/45163
Signed-off-by: Kiefer Chang <kiefer.chang@suse.com>
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/services/cephadmservice.py
src/pybind/mgr/cephadm/services/iscsi.py
src/pybind/mgr/cephadm/services/monitoring.py

index 966d75236a971ec42a38c890f8ace238fa6e9d70..0881f4780dfff2bc0a1e346b4f4bd5e474bfc85d 100644 (file)
@@ -1708,6 +1708,7 @@ you may want to run:
 
         daemons = self.cache.get_daemons()
         grafanas = []  # type: List[orchestrator.DaemonDescription]
+        iscsi_daemons = []
         for dd in daemons:
             # orphan?
             spec = self.spec_store.specs.get(dd.service_name(), None)
@@ -1725,6 +1726,8 @@ you may want to run:
             if dd.daemon_type == 'grafana':
                 # put running instances at the front of the list
                 grafanas.insert(0, dd)
+            elif dd.daemon_type == 'iscsi':
+                iscsi_daemons.append(dd)
             deps = self._calc_daemon_deps(dd.daemon_type, dd.daemon_id)
             last_deps, last_config = self.cache.get_daemon_last_config_deps(
                 dd.hostname, dd.name())
@@ -1750,21 +1753,10 @@ you may want to run:
                 self._create_daemon(dd.daemon_type, dd.daemon_id,
                                     dd.hostname, reconfig=True)
 
-        # make sure the dashboard [does not] references grafana
-        try:
-            current_url = self.get_module_option_ex('dashboard',
-                                                    'GRAFANA_API_URL')
-            if grafanas:
-                host = grafanas[0].hostname
-                url = f'https://{self.inventory.get_addr(host)}:3000'
-                if current_url != url:
-                    self.log.info('Setting dashboard grafana config to %s' % url)
-                    self.set_module_option_ex('dashboard', 'GRAFANA_API_URL',
-                                              url)
-                    # FIXME: is it a signed cert??
-        except Exception as e:
-            self.log.debug('got exception fetching dashboard grafana state: %s',
-                           e)
+        if grafanas:
+            self.grafana_service.daemon_check_post(grafanas)
+        if iscsi_daemons:
+            self.iscsi_service.daemon_check_post(iscsi_daemons)
 
     def _add_daemon(self, daemon_type, spec,
                     create_func: Callable[..., T], config_func=None) -> List[T]:
index a810026810aff372c371f759a49c433048794e7c..5e331d619809af7b67ad5ea9b166af6222d2be7b 100644 (file)
@@ -1,8 +1,8 @@
 import logging
-from typing import  TYPE_CHECKING
+from typing import TYPE_CHECKING, List
 
 from ceph.deployment.service_spec import ServiceSpec, RGWSpec
-from orchestrator import OrchestratorError
+from orchestrator import OrchestratorError, DaemonDescription
 from cephadm import utils
 
 if TYPE_CHECKING:
@@ -18,6 +18,10 @@ class CephadmService:
     def __init__(self, mgr: "CephadmOrchestrator"):
         self.mgr: "CephadmOrchestrator" = mgr
 
+    def daemon_check_post(self, daemon_descrs: List[DaemonDescription]):
+        """The post actions needed to be done after daemons are checked"""
+        raise NotImplementedError()
+
 
 class MonService(CephadmService):
     def create(self, name, host, network):
index 1739aacfa54c102fc26aa3a5dfffca9da699f0a7..18bf1699f783b7767a6aaf5e286f8f0314d99127 100644 (file)
@@ -1,8 +1,11 @@
 import json
 import logging
+from typing import List, cast
 
+from mgr_module import MonCommandFailed
 from ceph.deployment.service_spec import IscsiServiceSpec
 
+from orchestrator import DaemonDescription
 from .cephadmservice import CephadmService
 from .. import utils
 
@@ -68,3 +71,40 @@ class IscsiService(CephadmService):
         extra_config = {'iscsi-gateway.cfg': igw_conf}
         return self.mgr._create_daemon('iscsi', igw_id, host, keyring=keyring,
                                    extra_config=extra_config)
+
+    def daemon_check_post(self, daemon_descrs: List[DaemonDescription]):
+        try:
+            _, out, _ = self.mgr.check_mon_command({
+                'prefix': 'dashboard iscsi-gateway-list'
+            })
+        except MonCommandFailed as e:
+            logger.warning('Failed to get existing iSCSI gateways from the Dashboard: %s', e)
+            return
+
+        gateways = json.loads(out)['gateways']
+        for dd in daemon_descrs:
+            spec = cast(IscsiServiceSpec,
+                        self.mgr.spec_store.specs.get(dd.service_name(), None))
+            if not spec:
+                logger.warning('No ServiceSpec found for %s', dd)
+                continue
+            if not all([spec.api_user, spec.api_password]):
+                reason = 'api_user or api_password is not specified in ServiceSpec'
+                logger.warning(
+                    'Unable to add iSCSI gateway to the Dashboard for %s: %s', dd, reason)
+                continue
+            host = self.mgr.inventory.get_addr(dd.hostname)
+            service_url = 'http://{}:{}@{}:{}'.format(
+                spec.api_user, spec.api_password, host, spec.api_port or '5000')
+            gw = gateways.get(dd.hostname)
+            if not gw or gw['service_url'] != service_url:
+                try:
+                    logger.info('Adding iSCSI gateway %s to Dashboard', service_url)
+                    _, out, _ = self.mgr.check_mon_command({
+                        'prefix': 'dashboard iscsi-gateway-add',
+                        'service_url': service_url,
+                        'name': dd.hostname
+                    })
+                except MonCommandFailed as e:
+                    logger.warning(
+                        'Failed to add iSCSI gateway %s to the Dashboard: %s', service_url, e)
index e3ca8a804f65b187359bf046711e0f86c5703cb8..89c025e02b43a40c98bebcd5f2314c3626113fd6 100644 (file)
@@ -2,6 +2,7 @@ import logging
 import os
 from typing import List, Any, Tuple, Dict
 
+from orchestrator import DaemonDescription
 from cephadm.services.cephadmservice import CephadmService
 from mgr_util import verify_tls, ServerConfigException, create_self_signed_cert
 
@@ -104,6 +105,19 @@ datasources:
         }
         return config_file, sorted(deps)
 
+    def daemon_check_post(self, daemon_descrs: List[DaemonDescription]):
+        # make sure the dashboard [does not] references grafana
+        try:
+            current_url = self.mgr.get_module_option_ex('dashboard', 'GRAFANA_API_URL')
+            host = daemon_descrs[0].hostname
+            url = f'https://{self.mgr.inventory.get_addr(host)}:3000'
+            if current_url != url:
+                logger.info('Setting dashboard grafana config to %s' % url)
+                self.mgr.set_module_option_ex('dashboard', 'GRAFANA_API_URL', url)
+                # FIXME: is it a signed cert??
+        except Exception as e:
+            logger.debug('got exception fetching dashboard grafana state: %s', e)
+
 
 class AlertmanagerService(CephadmService):
     def create(self, daemon_id, host) -> str: