blob: 4a72bfb07a2835455cb767bc7b94a7ceb673a9ac [file] [log] [blame]
Ved-vampira915a012015-03-18 14:38:52 +03001""" Collect data about ceph nodes"""
2import json
koder aka kdanilov3a6633e2015-03-26 18:20:00 +02003import logging
koder aka kdanilov73084622016-11-16 21:51:08 +02004from typing import List, Set, Dict
koder aka kdanilov3a6633e2015-03-26 18:20:00 +02005
Ved-vampira915a012015-03-18 14:38:52 +03006
koder aka kdanilov73084622016-11-16 21:51:08 +02007from ..node_interfaces import NodeInfo, IRPCNode
8from ..ssh_utils import ConnCreds
9from ..common_types import IP
Ved-vampira915a012015-03-18 14:38:52 +030010
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030011logger = logging.getLogger("wally.discover")
koder aka kdanilov3a6633e2015-03-26 18:20:00 +020012
13
koder aka kdanilov73084622016-11-16 21:51:08 +020014def discover_ceph_nodes(node: IRPCNode,
15 cluster: str = "ceph",
16 conf: str = None,
17 key: str = None) -> List[NodeInfo]:
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030018 """Return list of ceph's nodes NodeInfo"""
koder aka kdanilove06762a2015-03-22 23:32:09 +020019
koder aka kdanilov73084622016-11-16 21:51:08 +020020 if conf is None:
21 conf = "/etc/ceph/{}.conf".format(cluster)
koder aka kdanilove06762a2015-03-22 23:32:09 +020022
koder aka kdanilov73084622016-11-16 21:51:08 +020023 if key is None:
24 key = "/etc/ceph/{}.client.admin.keyring".format(cluster)
25
26 try:
27 osd_ips = get_osds_ips(node, conf, key)
28 except Exception as exc:
29 logger.error("OSD discovery failed: %s", exc)
30 osd_ips = set()
31
32 try:
33 mon_ips = get_mons_ips(node, conf, key)
34 except Exception as exc:
35 logger.error("MON discovery failed: %s", exc)
36 mon_ips = set()
37
38 ips = {} # type: Dict[str, List[str]]
Ved-vampira915a012015-03-18 14:38:52 +030039 for ip in osd_ips:
koder aka kdanilov73084622016-11-16 21:51:08 +020040 ips.setdefault(ip, []).append("ceph-osd")
koder aka kdanilove06762a2015-03-22 23:32:09 +020041
Ved-vampira915a012015-03-18 14:38:52 +030042 for ip in mon_ips:
koder aka kdanilov73084622016-11-16 21:51:08 +020043 ips.setdefault(ip, []).append("ceph-mon")
koder aka kdanilove06762a2015-03-22 23:32:09 +020044
koder aka kdanilov73084622016-11-16 21:51:08 +020045 ssh_key = node.get_file_content("~/.ssh/id_rsa")
46 return [NodeInfo(ConnCreds(host=ip, user="root", key=ssh_key), set(roles)) for ip, roles in ips.items()]
Ved-vampira915a012015-03-18 14:38:52 +030047
48
koder aka kdanilov73084622016-11-16 21:51:08 +020049def get_osds_ips(node: IRPCNode, conf: str, key: str) -> Set[IP]:
50 """Get set of osd's ip"""
Ved-vampira915a012015-03-18 14:38:52 +030051
koder aka kdanilov73084622016-11-16 21:51:08 +020052 data = node.run("ceph -c {} -k {} --format json osd dump".format(conf, key))
53 jdata = json.loads(data)
54 ips = set() # type: Set[IP]
55 first_error = True
56 for osd_data in jdata["osds"]:
57 if "public_addr" not in osd_data:
58 if first_error:
59 osd_id = osd_data.get("osd", "<OSD_ID_MISSED>")
60 logger.warning("No 'public_addr' field in 'ceph osd dump' output for osd %s" +
61 "(all subsequent errors omitted)", osd_id)
62 first_error = False
63 else:
64 ip_port = osd_data["public_addr"]
65 if '/' in ip_port:
66 ip_port = ip_port.split("/", 1)[0]
67 ips.add(IP(ip_port.split(":")[0]))
koder aka kdanilove06762a2015-03-22 23:32:09 +020068 return ips
Ved-vampira915a012015-03-18 14:38:52 +030069
70
koder aka kdanilov73084622016-11-16 21:51:08 +020071def get_mons_ips(node: IRPCNode, conf: str, key: str) -> Set[IP]:
72 """Return mon ip set"""
73
74 data = node.run("ceph -c {} -k {} --format json mon_status".format(conf, key))
75 jdata = json.loads(data)
76 ips = set() # type: Set[IP]
77 first_error = True
78 for mon_data in jdata["monmap"]["mons"]:
79 if "addr" not in mon_data:
80 if first_error:
81 mon_name = mon_data.get("name", "<MON_NAME_MISSED>")
82 logger.warning("No 'addr' field in 'ceph mon_status' output for mon %s" +
83 "(all subsequent errors omitted)", mon_name)
84 first_error = False
85 else:
86 ip_port = mon_data["addr"]
87 if '/' in ip_port:
88 ip_port = ip_port.split("/", 1)[0]
89 ips.add(IP(ip_port.split(":")[0]))
90
koder aka kdanilove06762a2015-03-22 23:32:09 +020091 return ips