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