]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/cephadm/services/iscsi.py
import 15.2.4
[ceph.git] / ceph / src / pybind / mgr / cephadm / services / iscsi.py
1 import json
2 import logging
3 from typing import List, cast
4
5 from mgr_module import MonCommandFailed
6 from ceph.deployment.service_spec import IscsiServiceSpec
7
8 from orchestrator import DaemonDescription
9 from .cephadmservice import CephadmService
10 from .. import utils
11
12 logger = logging.getLogger(__name__)
13
14
15 class IscsiService(CephadmService):
16 def config(self, spec: IscsiServiceSpec):
17 self.mgr._check_pool_exists(spec.pool, spec.service_name())
18
19 logger.info('Saving service %s spec with placement %s' % (
20 spec.service_name(), spec.placement.pretty_str()))
21 self.mgr.spec_store.save(spec)
22
23 def create(self, igw_id, host, spec) -> str:
24 ret, keyring, err = self.mgr.check_mon_command({
25 'prefix': 'auth get-or-create',
26 'entity': utils.name_to_auth_entity('iscsi') + '.' + igw_id,
27 'caps': ['mon', 'profile rbd, '
28 'allow command "osd blacklist", '
29 'allow command "config-key get" with "key" prefix "iscsi/"',
30 'osd', f'allow rwx pool={spec.pool}'],
31 })
32
33 if spec.ssl_cert:
34 if isinstance(spec.ssl_cert, list):
35 cert_data = '\n'.join(spec.ssl_cert)
36 else:
37 cert_data = spec.ssl_cert
38 ret, out, err = self.mgr.mon_command({
39 'prefix': 'config-key set',
40 'key': f'iscsi/{utils.name_to_config_section("iscsi")}.{igw_id}/iscsi-gateway.crt',
41 'val': cert_data,
42 })
43
44 if spec.ssl_key:
45 if isinstance(spec.ssl_key, list):
46 key_data = '\n'.join(spec.ssl_key)
47 else:
48 key_data = spec.ssl_key
49 ret, out, err = self.mgr.mon_command({
50 'prefix': 'config-key set',
51 'key': f'iscsi/{utils.name_to_config_section("iscsi")}.{igw_id}/iscsi-gateway.key',
52 'val': key_data,
53 })
54
55 context = {
56 'client_name': '{}.{}'.format(utils.name_to_config_section('iscsi'), igw_id),
57 'spec': spec
58 }
59 igw_conf = self.mgr.template.render('services/iscsi/iscsi-gateway.cfg.j2', context)
60 extra_config = {'iscsi-gateway.cfg': igw_conf}
61 return self.mgr._create_daemon('iscsi', igw_id, host, keyring=keyring,
62 extra_config=extra_config)
63
64 def daemon_check_post(self, daemon_descrs: List[DaemonDescription]):
65 try:
66 _, out, _ = self.mgr.check_mon_command({
67 'prefix': 'dashboard iscsi-gateway-list'
68 })
69 except MonCommandFailed as e:
70 logger.warning('Failed to get existing iSCSI gateways from the Dashboard: %s', e)
71 return
72
73 gateways = json.loads(out)['gateways']
74 for dd in daemon_descrs:
75 spec = cast(IscsiServiceSpec,
76 self.mgr.spec_store.specs.get(dd.service_name(), None))
77 if not spec:
78 logger.warning('No ServiceSpec found for %s', dd)
79 continue
80 if not all([spec.api_user, spec.api_password]):
81 reason = 'api_user or api_password is not specified in ServiceSpec'
82 logger.warning(
83 'Unable to add iSCSI gateway to the Dashboard for %s: %s', dd, reason)
84 continue
85 host = self._inventory_get_addr(dd.hostname)
86 service_url = 'http://{}:{}@{}:{}'.format(
87 spec.api_user, spec.api_password, host, spec.api_port or '5000')
88 gw = gateways.get(dd.hostname)
89 if not gw or gw['service_url'] != service_url:
90 try:
91 logger.info('Adding iSCSI gateway %s to Dashboard', service_url)
92 _, out, _ = self.mgr.check_mon_command({
93 'prefix': 'dashboard iscsi-gateway-add',
94 'service_url': service_url,
95 'name': dd.hostname
96 })
97 except MonCommandFailed as e:
98 logger.warning(
99 'Failed to add iSCSI gateway %s to the Dashboard: %s', service_url, e)