From: Sage Weil Date: Fri, 21 Jul 2017 03:53:18 +0000 (-0400) Subject: mgr/PyState: add set_health_checks method X-Git-Tag: v12.1.2~52^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ed57f8c7a4591f264a099c5205b23b09f9a0215a;p=ceph.git mgr/PyState: add set_health_checks method Signed-off-by: Sage Weil --- diff --git a/src/mgr/PyState.cc b/src/mgr/PyState.cc index ae237b2e599e..efde95877081 100644 --- a/src/mgr/PyState.cc +++ b/src/mgr/PyState.cc @@ -182,6 +182,107 @@ ceph_send_command(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject* +ceph_set_health_checks(PyObject *self, PyObject *args) +{ + char *handle = nullptr; + PyObject *checks = NULL; + if (!PyArg_ParseTuple(args, "sO:ceph_set_health_checks", &handle, &checks)) { + return NULL; + } + if (!PyDict_Check(checks)) { + derr << __func__ << " arg not a dict" << dendl; + Py_RETURN_NONE; + } + PyObject *checksls = PyDict_Items(checks); + health_check_map_t out_checks; + for (int i = 0; i < PyList_Size(checksls); ++i) { + PyObject *kv = PyList_GET_ITEM(checksls, i); + char *check_name = nullptr; + PyObject *check_info = nullptr; + if (!PyArg_ParseTuple(kv, "sO:pair", &check_name, &check_info)) { + derr << __func__ << " dict item " << i + << " not a size 2 tuple" << dendl; + continue; + } + if (!PyDict_Check(check_info)) { + derr << __func__ << " item " << i << " " << check_name + << " value not a dict" << dendl; + continue; + } + health_status_t severity = HEALTH_OK; + string summary; + list detail; + PyObject *infols = PyDict_Items(check_info); + for (int j = 0; j < PyList_Size(infols); ++j) { + PyObject *pair = PyList_GET_ITEM(infols, j); + if (!PyTuple_Check(pair)) { + derr << __func__ << " item " << i << " pair " << j + << " not a tuple" << dendl; + continue; + } + char *k = nullptr; + PyObject *v = nullptr; + if (!PyArg_ParseTuple(pair, "sO:pair", &k, &v)) { + derr << __func__ << " item " << i << " pair " << j + << " not a size 2 tuple" << dendl; + continue; + } + string ks(k); + if (ks == "severity") { + if (!PyString_Check(v)) { + derr << __func__ << " check " << check_name + << " severity value not string" << dendl; + continue; + } + string vs(PyString_AsString(v)); + if (vs == "warning") { + severity = HEALTH_WARN; + } else if (vs == "error") { + severity = HEALTH_ERR; + } + } else if (ks == "summary") { + if (!PyString_Check(v)) { + derr << __func__ << " check " << check_name + << " summary value not string" << dendl; + continue; + } + summary = PyString_AsString(v); + } else if (ks == "detail") { + if (!PyList_Check(v)) { + derr << __func__ << " check " << check_name + << " detail value not list" << dendl; + continue; + } + for (int k = 0; k < PyList_Size(v); ++k) { + PyObject *di = PyList_GET_ITEM(v, k); + if (!PyString_Check(di)) { + derr << __func__ << " check " << check_name + << " detail item " << k << " not a string" << dendl; + continue; + } + detail.push_back(PyString_AsString(di)); + } + } else { + derr << __func__ << " check " << check_name + << " unexpected key " << k << dendl; + } + } + auto& d = out_checks.add(check_name, severity, summary); + d.detail.swap(detail); + } + + JSONFormatter jf(true); + dout(10) << "module " << handle << " health checks:\n"; + out_checks.dump(&jf); + jf.flush(*_dout); + *_dout << dendl; + + global_handle->set_health_checks(handle, std::move(out_checks)); + + Py_RETURN_NONE; +} + static PyObject* ceph_state_get(PyObject *self, PyObject *args) @@ -359,6 +460,8 @@ PyMethodDef CephStateMethods[] = { "Get a service's status"}, {"send_command", ceph_send_command, METH_VARARGS, "Send a mon command"}, + {"set_health_checks", ceph_set_health_checks, METH_VARARGS, + "Set health checks for this module"}, {"get_mgr_id", ceph_get_mgr_id, METH_NOARGS, "Get the mgr id"}, {"get_config", ceph_config_get, METH_VARARGS, diff --git a/src/pybind/mgr/mgr_module.py b/src/pybind/mgr/mgr_module.py index 49c7efe15ca8..2463bafe75d8 100644 --- a/src/pybind/mgr/mgr_module.py +++ b/src/pybind/mgr/mgr_module.py @@ -169,6 +169,30 @@ class MgrModule(object): """ ceph_state.send_command(self._handle, *args, **kwargs) + def set_health_checks(self, checks): + """ + Set module's health checks + + Set the module's current map of health checks. Argument is a + dict of check names to info, in this form: + + { + 'CHECK_FOO': { + 'severity': 'warning', # or 'error' + 'summary': 'summary string', + 'detail': [ 'list', 'of', 'detail', 'strings' ], + }, + 'CHECK_BAR': { + 'severity': 'error', + 'summary': 'bars are bad', + 'detail': [ 'too hard' ], + }, + } + + :param list: dict of health check dicts + """ + ceph_state.set_health_checks(self._handle, checks) + def handle_command(self, cmd): """ Called by ceph-mgr to request the plugin to handle one