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