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