Add Ceph CheckMK check

This commit is contained in:
Joshua Boniface 2024-11-24 18:42:55 -05:00
parent dd451c70c3
commit 398dce44d0
2 changed files with 131 additions and 0 deletions

View File

@ -178,4 +178,10 @@
command: ceph osd crush rule create-replicated replicated_rule default osd
when: pvc_nodes | length == 1
- name: install check_mk agent check
template:
src: ceph/ceph.cmk.j2
dest: /usr/lib/check_mk_agent/plugins/ceph
mode: 0755
- meta: flush_handlers

View File

@ -0,0 +1,125 @@
#!/usr/bin/env python3
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# (c) 2021 Heinlein Support GmbH
# Robert Sander <r.sander@heinlein-support.de>
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation in version 2. This file is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
# ails. You should have received a copy of the GNU General Public
# License along with GNU Make; see the file COPYING. If not, write
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.
import json
import rados
import os, os.path
import subprocess
import socket
class RadosCMD(rados.Rados):
def command_mon(self, cmd, params=None):
data = {'prefix': cmd, 'format': 'json'}
if params:
data.update(params)
return self.mon_command(json.dumps(data), b'', timeout=5)
def command_mgr(self, cmd):
return self.mgr_command(json.dumps({'prefix': cmd, 'format': 'json'}), b'', timeout=5)
def command_osd(self, osdid, cmd):
return self.osd_command(osdid, json.dumps({'prefix': cmd, 'format': 'json'}), b'', timeout=5)
def command_pg(self, pgid, cmd):
return self.pg_command(pgid, json.dumps({'prefix': cmd, 'format': 'json'}), b'', timeout=5)
ceph_config='/etc/ceph/ceph.conf'
ceph_client='client.admin'
try:
with open(os.path.join(os.environ['MK_CONFDIR'], 'ceph.cfg'), 'r') as config:
for line in config.readlines():
if '=' in line:
key, value = line.strip().split('=')
if key == 'CONFIG':
ceph_config = value
if key == 'CLIENT':
ceph_client = value
except FileNotFoundError:
pass
cluster = RadosCMD(conffile=ceph_config, name=ceph_client)
cluster.connect()
hostname = socket.gethostname().split('.', 1)[0]
fqdn = socket.getfqdn()
res = cluster.command_mon("status")
if res[0] == 0:
status = json.loads(res[1])
mons = status.get('quorum_names', [])
fsid = status.get("fsid", "")
if hostname in mons or fqdn in mons:
# only on MON hosts
print("<<<cephstatus:sep(0)>>>")
print(json.dumps(status))
res = cluster.command_mon("df", params={'detail': 'detail'})
if res[0] == 0:
print("<<<cephdf:sep(0)>>>")
print(json.dumps(json.loads(res[1])))
localosds = []
res = cluster.command_mon("osd metadata")
if res[0] == 0:
print("<<<cephosdbluefs:sep(0)>>>")
out = {'end': {}}
for osd in json.loads(res[1]):
if osd.get('hostname') in [hostname, fqdn]:
localosds.append(osd['id'])
if "container_hostname" in osd:
adminsocket = "/run/ceph/%s/ceph-osd.%d.asok" % (fsid, osd['id'])
else:
adminsocket = "/run/ceph/ceph-osd.%d.asok" % osd['id']
if os.path.exists(adminsocket):
chunks = []
try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(adminsocket)
sock.sendall(b'{"prefix": "perf dump"}\n')
sock.shutdown(socket.SHUT_WR)
while len(chunks) == 0 or chunks[-1] != b'':
chunks.append(sock.recv(4096))
sock.close()
chunks[0] = chunks[0][4:]
except:
chunks = [b'{"bluefs": {}}']
out[osd['id']] = {'bluefs': json.loads(b"".join(chunks))['bluefs']}
print(json.dumps(out))
osddf_raw = cluster.command_mon("osd df")
osdperf_raw = cluster.command_mon("osd perf")
if osddf_raw[0] == 0 and osdperf_raw[0] == 0:
osddf = json.loads(osddf_raw[1])
osdperf = json.loads(osdperf_raw[1])
osds = []
for osd in osddf['nodes']:
if osd['id'] in localosds:
osds.append(osd)
summary = osddf['summary']
perfs = []
if 'osd_perf_infos' in osdperf:
for osd in osdperf['osd_perf_infos']:
if osd['id'] in localosds:
perfs.append(osd)
if 'osdstats' in osdperf and 'osd_perf_infos' in osdperf['osdstats']:
for osd in osdperf['osdstats']['osd_perf_infos']:
if osd['id'] in localosds:
perfs.append(osd)
print("<<<cephosd:sep(0)>>>")
out = {'df': {'nodes': osds},
'perf': {'osd_perf_infos': perfs}}
print(json.dumps(out))