]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/cephadm/utils.py
import 15.2.5
[ceph.git] / ceph / src / pybind / mgr / cephadm / utils.py
1 import logging
2 import re
3 import json
4 from enum import Enum
5 from functools import wraps
6 from typing import Optional, Callable, TypeVar, List, NewType, TYPE_CHECKING
7 from orchestrator import OrchestratorError
8
9 if TYPE_CHECKING:
10 from cephadm import CephadmOrchestrator
11
12 T = TypeVar('T')
13 logger = logging.getLogger(__name__)
14
15 ConfEntity = NewType('ConfEntity', str)
16 AuthEntity = NewType('AuthEntity', str)
17
18
19 class CephadmNoImage(Enum):
20 token = 1
21
22
23 # Used for _run_cephadm used for check-host etc that don't require an --image parameter
24 cephadmNoImage = CephadmNoImage.token
25
26
27 def name_to_config_section(name: str) -> ConfEntity:
28 """
29 Map from daemon names to ceph entity names (as seen in config)
30 """
31 daemon_type = name.split('.', 1)[0]
32 if daemon_type in ['rgw', 'rbd-mirror', 'nfs', 'crash', 'iscsi']:
33 return ConfEntity('client.' + name)
34 elif daemon_type in ['mon', 'osd', 'mds', 'mgr', 'client']:
35 return ConfEntity(name)
36 else:
37 return ConfEntity('mon')
38
39
40 def name_to_auth_entity(daemon_type: str,
41 daemon_id: str,
42 host: str = "",
43 ) -> AuthEntity:
44 """
45 Map from daemon names/host to ceph entity names (as seen in config)
46 """
47 if daemon_type in ['rgw', 'rbd-mirror', 'nfs', "iscsi"]:
48 return AuthEntity('client.' + daemon_type + "." + daemon_id)
49 elif daemon_type == 'crash':
50 if host == "":
51 raise OrchestratorError("Host not provided to generate <crash> auth entity name")
52 return AuthEntity('client.' + daemon_type + "." + host)
53 elif daemon_type == 'mon':
54 return AuthEntity('mon.')
55 elif daemon_type == 'mgr':
56 return AuthEntity(daemon_type + "." + daemon_id)
57 elif daemon_type in ['osd', 'mds', 'client']:
58 return AuthEntity(daemon_type + "." + daemon_id)
59 else:
60 raise OrchestratorError("unknown auth entity name")
61
62
63 def forall_hosts(f: Callable[..., T]) -> Callable[..., List[T]]:
64 @wraps(f)
65 def forall_hosts_wrapper(*args) -> List[T]:
66 from cephadm.module import CephadmOrchestrator
67
68 # Some weired logic to make calling functions with multiple arguments work.
69 if len(args) == 1:
70 vals = args[0]
71 self = None
72 elif len(args) == 2:
73 self, vals = args
74 else:
75 assert 'either f([...]) or self.f([...])'
76
77 def do_work(arg):
78 if not isinstance(arg, tuple):
79 arg = (arg, )
80 try:
81 if self:
82 return f(self, *arg)
83 return f(*arg)
84 except Exception as e:
85 logger.exception(f'executing {f.__name__}({args}) failed.')
86 raise
87
88 assert CephadmOrchestrator.instance is not None
89 return CephadmOrchestrator.instance._worker_pool.map(do_work, vals)
90
91 return forall_hosts_wrapper
92
93
94 def get_cluster_health(mgr: 'CephadmOrchestrator') -> str:
95 # check cluster health
96 ret, out, err = mgr.check_mon_command({
97 'prefix': 'health',
98 'format': 'json',
99 })
100 try:
101 j = json.loads(out)
102 except Exception as e:
103 raise OrchestratorError('failed to parse health status')
104
105 return j['status']