server-tools/nsca_client/models/nsca_check.py

113 lines
3.9 KiB
Python

# (Copyright) 2015 ABF OSIELL <http://osiell.com>
# (Copyright) 2018 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import _, api, fields, models
from odoo.tools.safe_eval import safe_eval
_logger = logging.getLogger(__name__)
class NscaCheck(models.Model):
_name = "nsca.check"
_description = "NSCA Check"
_inherits = {"ir.cron": "cron_id"}
cron_id = fields.Many2one(
"ir.cron", string="Cron", required=True, ondelete="cascade", readonly=True
)
server_id = fields.Many2one("nsca.server", string="Server", required=True)
service = fields.Char(required=True)
nsca_model = fields.Char("NSCA Model")
nsca_function = fields.Char("Method")
nsca_args = fields.Char("Arguments")
allow_void_result = fields.Boolean(
"Allow void result",
default=False,
help="By default, a CRITICAL message is sent if the method does not "
"return.\nIf checked, no message will be sent in such a case.",
)
@api.model
def default_get(self, fields_list):
"""Set some default values on the fly, without overriding fields (which
has the side effect to re-create the fields on the current model).
"""
res = super(NscaCheck, self).default_get(fields_list)
res["name"] = "TEMP" # Required on 'ir.cron', replaced later
res["interval_number"] = 10
res["interval_type"] = "minutes"
return res
def _force_values(self):
"""Force some values:
- Compute the name of the NSCA check to be readable
among the others 'ir.cron' records.
"""
model = self.env["ir.model"].search([("model", "=", self._name)])
for check in self:
vals = {
"name": "{} - {}".format(_("NSCA Check"), check.service),
"model_id": model.id,
"state": "code",
"code": "model._cron_check(%s,)" % check.id,
"doall": False,
"numbercall": -1,
}
res = super(NscaCheck, check).write(vals)
return res
@api.model
def create(self, vals):
if not vals.get("model_id", False):
vals["model_id"] = (
self.env["ir.model"].search([("model", "=", self._name)]).id
)
if not vals.get("state", False):
vals["state"] = "code"
check = super(NscaCheck, self).create(vals)
check._force_values()
return check
def write(self, vals):
res = super(NscaCheck, self).write(vals)
if "service" in vals:
self._force_values()
return res
@api.model
def _cron_check(self, check_id):
self.env["nsca.server"]._check_send_nsca_command()
check = self.browse(check_id)
rc, message, performance = 3, "Unknown", {}
try:
NscaModel = self.env[check.nsca_model]
results = {"model": NscaModel}
safe_eval(
"result = model.{}({})".format(
check.nsca_function, check.nsca_args or ""
),
results,
mode="exec",
nocopy=True,
)
result = results["result"]
if not result:
if check.allow_void_result:
return False
raise ValueError("'%s' method does not return" % check.nsca_function)
if len(result) == 2:
rc, message = result
else:
rc, message, performance = result
except Exception as exc:
rc, message = 2, "%s" % exc
_logger.warning("%s - %s", check.service, message)
check._send_nsca(rc, message, performance)
return True
def _send_nsca(self, rc, message, performance):
for check in self:
check.server_id._send_nsca(check.service, rc, message, performance)