]>
Commit | Line | Data |
---|---|---|
f6b5b4d7 | 1 | import logging |
801d1391 | 2 | import re |
f6b5b4d7 TL |
3 | import json |
4 | from enum import Enum | |
5 | from functools import wraps | |
6 | from typing import Optional, Callable, TypeVar, List, NewType, TYPE_CHECKING | |
801d1391 TL |
7 | from orchestrator import OrchestratorError |
8 | ||
f6b5b4d7 TL |
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: | |
801d1391 TL |
28 | """ |
29 | Map from daemon names to ceph entity names (as seen in config) | |
30 | """ | |
31 | daemon_type = name.split('.', 1)[0] | |
1911f103 | 32 | if daemon_type in ['rgw', 'rbd-mirror', 'nfs', 'crash', 'iscsi']: |
f6b5b4d7 | 33 | return ConfEntity('client.' + name) |
801d1391 | 34 | elif daemon_type in ['mon', 'osd', 'mds', 'mgr', 'client']: |
f6b5b4d7 | 35 | return ConfEntity(name) |
801d1391 | 36 | else: |
f6b5b4d7 | 37 | return ConfEntity('mon') |
e306af50 TL |
38 | |
39 | ||
f6b5b4d7 TL |
40 | def name_to_auth_entity(daemon_type: str, |
41 | daemon_id: str, | |
42 | host: str = "", | |
43 | ) -> AuthEntity: | |
e306af50 | 44 | """ |
f6b5b4d7 | 45 | Map from daemon names/host to ceph entity names (as seen in config) |
e306af50 | 46 | """ |
f6b5b4d7 TL |
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) | |
e306af50 | 53 | elif daemon_type == 'mon': |
f6b5b4d7 TL |
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) | |
e306af50 TL |
59 | else: |
60 | raise OrchestratorError("unknown auth entity name") | |
f6b5b4d7 TL |
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'] |