From 75b3033f66fa6d263aa0e66937845242046aba12 Mon Sep 17 00:00:00 2001 From: sebalix Date: Mon, 14 Dec 2015 15:56:59 +0100 Subject: [PATCH 01/13] [ADD] Module 'nsca_client' - Send passive alerts to a NSCA daemon --- nsca_client/README.rst | 112 ++++++++++++++ nsca_client/__init__.py | 5 + nsca_client/__openerp__.py | 27 ++++ nsca_client/data/ir_config_parameter.xml | 13 ++ nsca_client/demo/demo_data.xml | 21 +++ nsca_client/i18n/fr.po | 180 +++++++++++++++++++++++ nsca_client/i18n/nsca_client.pot | 180 +++++++++++++++++++++++ nsca_client/models/__init__.py | 5 + nsca_client/models/nsca_check.py | 128 ++++++++++++++++ nsca_client/models/nsca_server.py | 15 ++ nsca_client/security/ir.model.access.csv | 3 + nsca_client/static/description/icon.png | Bin 0 -> 9463 bytes nsca_client/views/nsca_check.xml | 78 ++++++++++ nsca_client/views/nsca_menu.xml | 12 ++ nsca_client/views/nsca_server.xml | 50 +++++++ 15 files changed, 829 insertions(+) create mode 100644 nsca_client/README.rst create mode 100644 nsca_client/__init__.py create mode 100644 nsca_client/__openerp__.py create mode 100644 nsca_client/data/ir_config_parameter.xml create mode 100644 nsca_client/demo/demo_data.xml create mode 100644 nsca_client/i18n/fr.po create mode 100644 nsca_client/i18n/nsca_client.pot create mode 100644 nsca_client/models/__init__.py create mode 100644 nsca_client/models/nsca_check.py create mode 100644 nsca_client/models/nsca_server.py create mode 100644 nsca_client/security/ir.model.access.csv create mode 100644 nsca_client/static/description/icon.png create mode 100644 nsca_client/views/nsca_check.xml create mode 100644 nsca_client/views/nsca_menu.xml create mode 100644 nsca_client/views/nsca_server.xml diff --git a/nsca_client/README.rst b/nsca_client/README.rst new file mode 100644 index 000000000..d799b56ff --- /dev/null +++ b/nsca_client/README.rst @@ -0,0 +1,112 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=========== +NSCA Client +=========== + +Send passive alert to your favorite NSCA daemon (Nagios, Shinken...). +This module is based on the Odoo cron system and requires a NSCA client +installed on the system to satisfy the ``/usr/sbin/send_nsca`` command. + +Installation +============ + +To install this module, you need to install a NSCA client. + +On Debian/Ubuntu:: + + $ sudo apt-get install nsca-client + +Then configure the NSCA client in ``/etc/send_nsca.cfg`` (password +and encryption method). + +Configuration +============= + +To configure this module, you need to: + +* Configure your server and a passive service in your moniroting tool + (e.g service ``ODOO MAIL QUEUE`` on host ``MY-SERVER``). +* On Odoo, set the previous hostname in the system parameters:: + + nsca_client.hostname = MY-SERVER + +* Declare your NSCA server in the menu Configuration / Technical / NSCA Client / Servers +* Create NSCA checks in the menu Configuration / Technical / NSCA Client / Checks +* Code the methods which will be called by the NSCA checks. + +Such methods must return a tuple (RC, MESSAGE) where RC is an integer, +and MESSAGE a unicode string. ``RC`` values and the corresponding status are: + +- 0: OK +- 1: WARNING +- 2: CRITICAL +- 3: UNKNOWN + +E.g: + +.. code-block:: python + + class MailMail(models.Model): + _inherit = 'mail.mail' + + @api.model + def nsca_check_mails(self): + mails = self.search([('state', '=', 'exception')]) + if mails: + return (1, u"%s mails not sent" % len(mails)) + return (0, u"OK") + +Usage +===== + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/149/8.0 + +Known issues / Roadmap +====================== + +* Send performance data + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed `feedback +`_. + +Credits +======= + +Images +------ + +* Daniel Foré: `Icon `_ (Elementary theme, GPL). + +Contributors +------------ + +* Sébastien Alix + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/nsca_client/__init__.py b/nsca_client/__init__.py new file mode 100644 index 000000000..f71417703 --- /dev/null +++ b/nsca_client/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2015 ABF OSIELL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/nsca_client/__openerp__.py b/nsca_client/__openerp__.py new file mode 100644 index 000000000..bd70cb762 --- /dev/null +++ b/nsca_client/__openerp__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# © 2015 ABF OSIELL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "NSCA Client", + "summary": "Send passive alerts to monitor your Odoo application.", + "version": "8.0.1.0.0", + "category": "Tools", + "website": "http://osiell.com/", + "author": "ABF OSIELL, Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "external_dependencies": { + "bin": ['/usr/sbin/send_nsca'], + }, + "data": [ + "security/ir.model.access.csv", + "data/ir_config_parameter.xml", + "views/nsca_menu.xml", + "views/nsca_check.xml", + "views/nsca_server.xml", + ], + "demo": [ + "demo/demo_data.xml", + ], +} diff --git a/nsca_client/data/ir_config_parameter.xml b/nsca_client/data/ir_config_parameter.xml new file mode 100644 index 000000000..5a7cac83a --- /dev/null +++ b/nsca_client/data/ir_config_parameter.xml @@ -0,0 +1,13 @@ + + + + + + + nsca_client.hostname + localhost + + + + diff --git a/nsca_client/demo/demo_data.xml b/nsca_client/demo/demo_data.xml new file mode 100644 index 000000000..9904136a2 --- /dev/null +++ b/nsca_client/demo/demo_data.xml @@ -0,0 +1,21 @@ + + + + + + nagios.example.net + 5667 + + + + + ODOO MAIL QUEUE + + minutes + mail.mail + nsca_check_mails + + + + + diff --git a/nsca_client/i18n/fr.po b/nsca_client/i18n/fr.po new file mode 100644 index 000000000..2e7331c54 --- /dev/null +++ b/nsca_client/i18n/fr.po @@ -0,0 +1,180 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * nsca_client +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-15 12:00+0000\n" +"PO-Revision-Date: 2015-12-15 12:00+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "(1, u\"3 mails not sent\")" +msgstr "(1, u\"3 mails non-envoyés\")" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "0: OK" +msgstr "0: OK" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "1: WARNING" +msgstr "1: WARNING" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "2: CRITICAL" +msgstr "2: CRITICAL" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "3: UNKNOWN" +msgstr "3: UNKNOWN" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "Any other RC value will be treated as CRITICAL." +msgstr "Tout autre valeur RC sera traitée comme CRITICAL." + +#. module: nsca_client +#: field:nsca.check,nsca_args:0 +msgid "Arguments" +msgstr "Arguments" + +#. module: nsca_client +#: model:ir.actions.act_window,name:nsca_client.action_nsca_check_tree +#: model:ir.ui.menu,name:nsca_client.menu_action_nsca_check_tree +#: view:nsca.server:nsca_client.view_nsca_server_form +#: field:nsca.server,check_ids:0 +msgid "Checks" +msgstr "Contrôles" + +#. module: nsca_client +#: field:nsca.check,create_uid:0 +#: field:nsca.server,create_uid:0 +msgid "Created by" +msgstr "Créé par" + +#. module: nsca_client +#: field:nsca.check,create_date:0 +#: field:nsca.server,create_date:0 +msgid "Created on" +msgstr "Créé le" + +#. module: nsca_client +#: field:nsca.check,cron_id:0 +msgid "Cron" +msgstr "Cron" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "E.g." +msgstr "Ex :" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "Frequency" +msgstr "Fréquence" + +#. module: nsca_client +#: field:nsca.server,name:0 +msgid "Hostname" +msgstr "Serveur" + +#. module: nsca_client +#: field:nsca.check,id:0 +#: field:nsca.server,id:0 +msgid "ID" +msgstr "ID" + +#. module: nsca_client +#: field:nsca.check,write_uid:0 +#: field:nsca.server,write_uid:0 +msgid "Last Updated by" +msgstr "Dernière modification par" + +#. module: nsca_client +#: field:nsca.check,write_date:0 +#: field:nsca.server,write_date:0 +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: nsca_client +#: field:nsca.check,nsca_function:0 +msgid "Method" +msgstr "Méthode" + +#. module: nsca_client +#: field:nsca.check,nsca_model:0 +msgid "Model" +msgstr "Modèle" + +#. module: nsca_client +#: code:addons/nsca_client/models/nsca_check.py:52 +#: model:ir.model,name:nsca_client.model_nsca_check +#: view:nsca.check:nsca_client.view_nsca_check_form +#, python-format +msgid "NSCA Check" +msgstr "Contrôle NSCA" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_tree +msgid "NSCA Checks" +msgstr "Contrôles NSCA" + +#. module: nsca_client +#: model:ir.ui.menu,name:nsca_client.menu_nsca_client +msgid "NSCA Client" +msgstr "Client NSCA" + +#. module: nsca_client +#: model:ir.model,name:nsca_client.model_nsca_server +#: view:nsca.server:nsca_client.view_nsca_server_form +msgid "NSCA Server" +msgstr "Serveur NSCA" + +#. module: nsca_client +#: view:nsca.server:nsca_client.view_nsca_server_tree +msgid "NSCA Servers" +msgstr "Serveurs NSCA" + +#. module: nsca_client +#: field:nsca.server,port:0 +msgid "Port" +msgstr "Port" + +#. module: nsca_client +#: field:nsca.check,server_id:0 +msgid "Server" +msgstr "Serveur" + +#. module: nsca_client +#: model:ir.actions.act_window,name:nsca_client.action_nsca_server_tree +#: model:ir.ui.menu,name:nsca_client.menu_action_nsca_server_tree +msgid "Servers" +msgstr "Serveurs" + +#. module: nsca_client +#: field:nsca.check,service:0 +msgid "Service" +msgstr "Service" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "Settings" +msgstr "Paramètres" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "The method must return a tuple (RC, MESSAGE) where RC is an integer:" +msgstr "La méthode doit retourner un tuple (RC, MESSAGE) où RC est un entier :" + diff --git a/nsca_client/i18n/nsca_client.pot b/nsca_client/i18n/nsca_client.pot new file mode 100644 index 000000000..63636c149 --- /dev/null +++ b/nsca_client/i18n/nsca_client.pot @@ -0,0 +1,180 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * nsca_client +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-15 11:57+0000\n" +"PO-Revision-Date: 2015-12-15 11:57+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "(1, u\"3 mails not sent\")" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "0: OK" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "1: WARNING" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "2: CRITICAL" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "3: UNKNOWN" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "Any other RC value will be treated as CRITICAL." +msgstr "" + +#. module: nsca_client +#: field:nsca.check,nsca_args:0 +msgid "Arguments" +msgstr "" + +#. module: nsca_client +#: model:ir.actions.act_window,name:nsca_client.action_nsca_check_tree +#: model:ir.ui.menu,name:nsca_client.menu_action_nsca_check_tree +#: view:nsca.server:nsca_client.view_nsca_server_form +#: field:nsca.server,check_ids:0 +msgid "Checks" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,create_uid:0 +#: field:nsca.server,create_uid:0 +msgid "Created by" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,create_date:0 +#: field:nsca.server,create_date:0 +msgid "Created on" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,cron_id:0 +msgid "Cron" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "E.g." +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "Frequency" +msgstr "" + +#. module: nsca_client +#: field:nsca.server,name:0 +msgid "Hostname" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,id:0 +#: field:nsca.server,id:0 +msgid "ID" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,write_uid:0 +#: field:nsca.server,write_uid:0 +msgid "Last Updated by" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,write_date:0 +#: field:nsca.server,write_date:0 +msgid "Last Updated on" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,nsca_function:0 +msgid "Method" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,nsca_model:0 +msgid "Model" +msgstr "" + +#. module: nsca_client +#: code:addons/nsca_client/models/nsca_check.py:52 +#: model:ir.model,name:nsca_client.model_nsca_check +#: view:nsca.check:nsca_client.view_nsca_check_form +#, python-format +msgid "NSCA Check" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_tree +msgid "NSCA Checks" +msgstr "" + +#. module: nsca_client +#: model:ir.ui.menu,name:nsca_client.menu_nsca_client +msgid "NSCA Client" +msgstr "" + +#. module: nsca_client +#: model:ir.model,name:nsca_client.model_nsca_server +#: view:nsca.server:nsca_client.view_nsca_server_form +msgid "NSCA Server" +msgstr "" + +#. module: nsca_client +#: view:nsca.server:nsca_client.view_nsca_server_tree +msgid "NSCA Servers" +msgstr "" + +#. module: nsca_client +#: field:nsca.server,port:0 +msgid "Port" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,server_id:0 +msgid "Server" +msgstr "" + +#. module: nsca_client +#: model:ir.actions.act_window,name:nsca_client.action_nsca_server_tree +#: model:ir.ui.menu,name:nsca_client.menu_action_nsca_server_tree +msgid "Servers" +msgstr "" + +#. module: nsca_client +#: field:nsca.check,service:0 +msgid "Service" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "Settings" +msgstr "" + +#. module: nsca_client +#: view:nsca.check:nsca_client.view_nsca_check_form +msgid "The method must return a tuple (RC, MESSAGE) where RC is an integer:" +msgstr "" + diff --git a/nsca_client/models/__init__.py b/nsca_client/models/__init__.py new file mode 100644 index 000000000..32927f70a --- /dev/null +++ b/nsca_client/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2015 ABF OSIELL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import nsca_check, nsca_server diff --git a/nsca_client/models/nsca_check.py b/nsca_client/models/nsca_check.py new file mode 100644 index 000000000..21c6ae3d7 --- /dev/null +++ b/nsca_client/models/nsca_check.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# © 2015 ABF OSIELL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging +import shlex +import subprocess + +from openerp import models, fields, api, _ + +from openerp.addons.base.ir.ir_cron import str2tuple + +_logger = logging.getLogger(__name__) + + +class NscaCheck(models.Model): + _name = "nsca.check" + _description = u"NSCA Check" + _inherits = {'ir.cron': 'cron_id'} + + cron_id = fields.Many2one( + 'ir.cron', string=u"Cron", + required=True, ondelete='cascade', readonly=True) + server_id = fields.Many2one( + 'nsca.server', string=u"Server", required=True) + service = fields.Char(u"Service", required=True) + nsca_model = fields.Char(u"Model") + nsca_function = fields.Char(u"Method") + nsca_args = fields.Char(u"Arguments") + + @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) + NscaServer = self.env['nsca.server'] + res['name'] = 'TEMP' # Required on 'ir.cron', replaced later + res['interval_number'] = 10 + res['interval_type'] = 'minutes' + res['server_id'] = NscaServer.search([])[0].id + return res + + @api.multi + def _force_values(self): + """Force some values: + - Compute the name of the NSCA check to be readable + among the others 'ir.cron' records. + """ + for check in self: + vals = { + 'name': u"%s - %s" % (_(u"NSCA Check"), check.service), + 'model': self._name, + 'function': '_cron_check', + 'args': '(%s,)' % check.id, + 'doall': False, + 'numbercall': -1 + } + super(NscaCheck, check).write(vals) + + @api.model + def create(self, vals): + check = super(NscaCheck, self).create(vals) + check._force_values() + return check + + @api.multi + 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): + check = self.browse(check_id) + rc, message = 3, "Unknown" + try: + args = str2tuple(check.nsca_args) + NscaModel = self.env[check.nsca_model] + rc, message = getattr(NscaModel, check.nsca_function)(*args) + except Exception, exc: + rc, message = 2, "%s" % exc + _logger.error("%s - %s", check.service, message) + check._send_nsca(rc, message) + return True + + @api.multi + def _send_nsca(self, rc, message): + """Send the result of the check to the NSCA daemon.""" + for check in self: + check_result = self._format_check_result(check, rc, message) + cmd = self._prepare_command(check) + self._run_command(check, cmd, check_result) + + @api.model + def _format_check_result(self, check, rc, message): + """Format the check result with tabulations as delimiter.""" + message = message.replace('\t', ' ') + hostname = self.env['ir.config_parameter'].get_param( + 'nsca_client.hostname', 'localhost') + check_result = u"%s\t%s\t%s\t%s" % ( + hostname, check.service, rc, message) + return check_result.encode('utf-8') + + @api.model + def _prepare_command(self, check): + """Prepare the shell command used to send the check result + to the NSCA daemon. + """ + cmd = u"/usr/sbin/send_nsca -H %s -p %s" % ( + check.server_id.name, check.server_id.port) + return shlex.split(cmd) + + @api.model + def _run_command(self, check, cmd, check_result): + """Send the check result through the '/usr/sbin/send_nsca' command.""" + try: + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate( + input=check_result)[0] + _logger.info("%s: %s", check_result, stdout.strip()) + except Exception, exc: + _logger.error(exc) diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py new file mode 100644 index 000000000..596f25eed --- /dev/null +++ b/nsca_client/models/nsca_server.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# © 2015 ABF OSIELL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import models, fields + + +class NscaServer(models.Model): + _name = "nsca.server" + _description = u"NSCA Server" + + name = fields.Char(u"Hostname", required=True) + port = fields.Integer(u"Port", default=5667, required=True) + check_ids = fields.One2many( + 'nsca.check', 'server_id', string=u"Checks") diff --git a/nsca_client/security/ir.model.access.csv b/nsca_client/security/ir.model.access.csv new file mode 100644 index 000000000..da2d09485 --- /dev/null +++ b/nsca_client/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_nsca_check,access_nsca_check,model_nsca_check,base.group_erp_manager,1,1,1,1 +access_nsca_server,access_nsca_server,model_nsca_server,base.group_erp_manager,1,1,1,1 diff --git a/nsca_client/static/description/icon.png b/nsca_client/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b9f884a283539fee238539f02f65201a1a7c7625 GIT binary patch literal 9463 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 + + + + + + + nsca.check.form + nsca.check + +
+ + + + + + + + + + +
+

The method must return a tuple (RC, MESSAGE) where RC is an integer:

+ +
    +
  • 0: OK
  • +
  • 1: WARNING
  • +
  • 2: CRITICAL
  • +
  • 3: UNKNOWN
  • +
+ +

Any other RC value will be treated as CRITICAL.

+

E.g. (1, u"3 mails not sent")

+
+
+
+
+
+
+
+ + + nsca.check.tree + nsca.check + + + + + + + + + + + + Checks + ir.actions.act_window + nsca.check + form + + + ['|', ('active', '=', True), ('active', '=', False)] + + + + +
+
diff --git a/nsca_client/views/nsca_menu.xml b/nsca_client/views/nsca_menu.xml new file mode 100644 index 000000000..4472e82c5 --- /dev/null +++ b/nsca_client/views/nsca_menu.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/nsca_client/views/nsca_server.xml b/nsca_client/views/nsca_server.xml new file mode 100644 index 000000000..d9b98e52f --- /dev/null +++ b/nsca_client/views/nsca_server.xml @@ -0,0 +1,50 @@ + + + + + + + + nsca.server.form + nsca.server + +
+ + + + + + + + + +
+
+
+ + + nsca.server.tree + nsca.server + + + + + + + + + + Servers + ir.actions.act_window + nsca.server + form + + + + + +
+
From e3f00518d4455de61c1edfe5a6153b96231145bb Mon Sep 17 00:00:00 2001 From: sebalix Date: Wed, 16 Dec 2015 14:17:24 +0100 Subject: [PATCH 02/13] [IMP] Module 'nsca_client' - Review + Default NSCA server added + Configuration file path added on the NSCA server (each server can require a different password) --- nsca_client/README.rst | 16 ++++++++++++---- nsca_client/__openerp__.py | 5 ++++- nsca_client/data/nsca_server.xml | 13 +++++++++++++ nsca_client/demo/demo_data.xml | 9 ++------- nsca_client/models/nsca_check.py | 8 +++++--- nsca_client/models/nsca_server.py | 4 +++- nsca_client/static/description/check.png | Bin 0 -> 37328 bytes nsca_client/static/description/server.png | Bin 0 -> 17483 bytes nsca_client/views/nsca_server.xml | 2 ++ 9 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 nsca_client/data/nsca_server.xml create mode 100644 nsca_client/static/description/check.png create mode 100644 nsca_client/static/description/server.png diff --git a/nsca_client/README.rst b/nsca_client/README.rst index d799b56ff..5f0715841 100644 --- a/nsca_client/README.rst +++ b/nsca_client/README.rst @@ -27,18 +27,26 @@ Configuration To configure this module, you need to: -* Configure your server and a passive service in your moniroting tool - (e.g service ``ODOO MAIL QUEUE`` on host ``MY-SERVER``). +* Configure your server and a passive service in your monitoring tool + (e.g service ``Odoo Mail Queue`` on host ``MY-SERVER``). * On Odoo, set the previous hostname in the system parameters:: nsca_client.hostname = MY-SERVER * Declare your NSCA server in the menu Configuration / Technical / NSCA Client / Servers + +.. image:: nsca_client/static/description/server.png + :width: 400 px + * Create NSCA checks in the menu Configuration / Technical / NSCA Client / Checks + +.. image:: nsca_client/static/description/check.png + :width: 400 px + * Code the methods which will be called by the NSCA checks. -Such methods must return a tuple (RC, MESSAGE) where RC is an integer, -and MESSAGE a unicode string. ``RC`` values and the corresponding status are: +Such methods must return a tuple ``(RC, MESSAGE)`` where ``RC`` is an integer, +and ``MESSAGE`` a unicode string. ``RC`` values and the corresponding status are: - 0: OK - 1: WARNING diff --git a/nsca_client/__openerp__.py b/nsca_client/__openerp__.py index bd70cb762..2c073676e 100644 --- a/nsca_client/__openerp__.py +++ b/nsca_client/__openerp__.py @@ -12,11 +12,14 @@ "application": False, "installable": True, "external_dependencies": { - "bin": ['/usr/sbin/send_nsca'], + "bin": [ + '/usr/sbin/send_nsca', + ], }, "data": [ "security/ir.model.access.csv", "data/ir_config_parameter.xml", + "data/nsca_server.xml", "views/nsca_menu.xml", "views/nsca_check.xml", "views/nsca_server.xml", diff --git a/nsca_client/data/nsca_server.xml b/nsca_client/data/nsca_server.xml new file mode 100644 index 000000000..77453502c --- /dev/null +++ b/nsca_client/data/nsca_server.xml @@ -0,0 +1,13 @@ + + + + + + + nagios.example.net + 5667 + + + + diff --git a/nsca_client/demo/demo_data.xml b/nsca_client/demo/demo_data.xml index 9904136a2..2c9f91b18 100644 --- a/nsca_client/demo/demo_data.xml +++ b/nsca_client/demo/demo_data.xml @@ -2,14 +2,9 @@ - - nagios.example.net - 5667 - - - - ODOO MAIL QUEUE + + Odoo Mail Queue minutes mail.mail diff --git a/nsca_client/models/nsca_check.py b/nsca_client/models/nsca_check.py index 21c6ae3d7..79bdcaa2f 100644 --- a/nsca_client/models/nsca_check.py +++ b/nsca_client/models/nsca_check.py @@ -6,7 +6,7 @@ import logging import shlex import subprocess -from openerp import models, fields, api, _ +from openerp import _, api, fields, models from openerp.addons.base.ir.ir_cron import str2tuple @@ -108,8 +108,10 @@ class NscaCheck(models.Model): """Prepare the shell command used to send the check result to the NSCA daemon. """ - cmd = u"/usr/sbin/send_nsca -H %s -p %s" % ( - check.server_id.name, check.server_id.port) + cmd = u"/usr/sbin/send_nsca -H %s -p %s -c %s" % ( + check.server_id.name, + check.server_id.port, + check.server_id.config_file_path) return shlex.split(cmd) @api.model diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py index 596f25eed..ea66c348c 100644 --- a/nsca_client/models/nsca_server.py +++ b/nsca_client/models/nsca_server.py @@ -2,7 +2,7 @@ # © 2015 ABF OSIELL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp import models, fields +from openerp import fields, models class NscaServer(models.Model): @@ -11,5 +11,7 @@ class NscaServer(models.Model): name = fields.Char(u"Hostname", required=True) port = fields.Integer(u"Port", default=5667, required=True) + config_file_path = fields.Char( + u"Configuration file", default="/etc/send_nsca.cfg", required=True) check_ids = fields.One2many( 'nsca.check', 'server_id', string=u"Checks") diff --git a/nsca_client/static/description/check.png b/nsca_client/static/description/check.png new file mode 100644 index 0000000000000000000000000000000000000000..5fdd064a49080e99631686466acd151e567b378f GIT binary patch literal 37328 zcmeFZWmFtp*rr>!1xc{r1a}DT5G1&3@B|C)ZXGm%;O_43ZXrN$cNz%pZVe4gzwbA5 z)_mWbKj+N+oV9wb>Rr2PRae#CPuhe$2Rn0C7gJ|*b9qD&9Y3ia+S#i5f1TpF(T454Dr-+w^@c%ad|6Yx@5~0kCU!_r}p?!OB;zjzG zBMVy=ivCoPv6pAaXL9i>Hg6Aq;rH(!X4h~1{B0+%I>i70hc=z4ILa96Jl)}W+4c(| zOEPF)a=n&%4*|frks2kP3rvnDC}G@elY=uEy+}S3Aq9XxGwX(3!Chdt80GByk-b6W zux<)W14JM-(Enqx*V45sbbDC#xhmkLBN^p;ctHJ^TEXMZ;$Mro6J=w<07q+e*UjpU zF{%V=?%*<+%+Uz^c=huay(TLE2c;sS$8|}}N|u2Bl#8BE?&tT}C`-Akvsx2FRVmj( zF7;36`-$;c6gR#$R?oNRfwT@5{nEzzO&p$}^tZb{*paMWJ8g2mS{x612)oaSF%4R& z{O$kD^SP#sd5+X@+**_e!3G&vMFXc2Zv3{1LjRn7d6C4AEmHS3SfY_dIg#74=v9G6 z-!Y#*z<&m9P`RsSr$I`upSHS^x$S%2u$9UXq|^3~75Z!b1OWMA*bU=eJFFsZT7OAb zgq$Jl0WY;0?8f$!>!^G8n_E>=P5|&-eR5(nH_!8hj~q6i;T$ZlV(&fnCR#07t%Avw z;U>O)o51#3n!4HofSGNl`Zw1u$*ir z)p7@tQS^>N1kGgMg-A4R4z@ZxNviL^rSyJ2x>~=>LIQ5<^NU?|khW&RgnQjRHSvB% zBb?iw{pm<_v0vsCy)#S}cw1I1QvWNV*-X1e_@JS^@wwb|3+O1e;W()D`m2MII~cp& z%=_X-;d2qLMhJ=R`2)0Ir1+@7+iN)RZx`;A%D9}mA-)7{z}F-Ot&h7Q<0AQ6lmeB-GXVsI zT~q+T!Fx=M&Rd=eDW{X*0dQ*55>t-{vyH#24IWmt-;0b#>$XQNB0~VhcrF#9fQNWm zm#UT?VP5B)Bb$|tJ19TMmM%WWs7s=}tFHfDB&NUUxmUMGa5pMYm-04~(JR$o``$Z? z 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 F;6JxyH?IHy literal 0 HcmV?d00001 diff --git a/nsca_client/static/description/server.png b/nsca_client/static/description/server.png new file mode 100644 index 0000000000000000000000000000000000000000..7d19803cab2a9045e2faf17034791c78ee43062b GIT binary patch literal 17483 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 W{t1M)_Rk_AfRenrT*aIBpZ^2cJWg`} literal 0 HcmV?d00001 diff --git a/nsca_client/views/nsca_server.xml b/nsca_client/views/nsca_server.xml index d9b98e52f..f03263dd9 100644 --- a/nsca_client/views/nsca_server.xml +++ b/nsca_client/views/nsca_server.xml @@ -14,6 +14,7 @@ + @@ -30,6 +31,7 @@ + From a02d8d6bc49aaaea611496daf48fd83a9c6d3d7d Mon Sep 17 00:00:00 2001 From: sebalix Date: Wed, 16 Dec 2015 18:17:57 +0100 Subject: [PATCH 03/13] [IMP] Module 'nsca_client' - External dependency on '/usr/sbin/nsca_send' removed, replaced by a check at the runtime --- nsca_client/__openerp__.py | 5 ----- nsca_client/models/nsca_check.py | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/nsca_client/__openerp__.py b/nsca_client/__openerp__.py index 2c073676e..6bfaf81a4 100644 --- a/nsca_client/__openerp__.py +++ b/nsca_client/__openerp__.py @@ -11,11 +11,6 @@ "license": "AGPL-3", "application": False, "installable": True, - "external_dependencies": { - "bin": [ - '/usr/sbin/send_nsca', - ], - }, "data": [ "security/ir.model.access.csv", "data/ir_config_parameter.xml", diff --git a/nsca_client/models/nsca_check.py b/nsca_client/models/nsca_check.py index 79bdcaa2f..1159d7e76 100644 --- a/nsca_client/models/nsca_check.py +++ b/nsca_client/models/nsca_check.py @@ -3,15 +3,23 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import logging +import os import shlex import subprocess from openerp import _, api, fields, models +from openerp.exceptions import Warning as UserError from openerp.addons.base.ir.ir_cron import str2tuple _logger = logging.getLogger(__name__) +SEND_NSCA_BIN = '/usr/sbin/send_nsca' + + +def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + class NscaCheck(models.Model): _name = "nsca.check" @@ -73,6 +81,7 @@ class NscaCheck(models.Model): @api.model def _cron_check(self, check_id): + self._check_send_nsca_command() check = self.browse(check_id) rc, message = 3, "Unknown" try: @@ -128,3 +137,11 @@ class NscaCheck(models.Model): _logger.info("%s: %s", check_result, stdout.strip()) except Exception, exc: _logger.error(exc) + + def _check_send_nsca_command(self): + """Check if the NSCA client is installed.""" + if not is_exe(SEND_NSCA_BIN): + raise UserError( + _(u"Command '%s' not found. Please install the NSCA client.\n" + u"On Debian/Ubuntu: apt-get install nsca-client") % ( + SEND_NSCA_BIN)) From f6a78637c399adf184ef0af1405cc8088599cb7c Mon Sep 17 00:00:00 2001 From: sebalix Date: Thu, 17 Dec 2015 08:26:18 +0100 Subject: [PATCH 04/13] [IMP] Module 'nsca_client' - Translations updated --- nsca_client/i18n/fr.po | 19 ++++++++++++++++--- nsca_client/i18n/nsca_client.pot | 18 +++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/nsca_client/i18n/fr.po b/nsca_client/i18n/fr.po index 2e7331c54..a1418c4f1 100644 --- a/nsca_client/i18n/fr.po +++ b/nsca_client/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-15 12:00+0000\n" -"PO-Revision-Date: 2015-12-15 12:00+0000\n" +"POT-Creation-Date: 2015-12-17 07:07+0000\n" +"PO-Revision-Date: 2015-12-17 07:07+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -58,6 +58,19 @@ msgstr "Arguments" msgid "Checks" msgstr "Contrôles" +#. module: nsca_client +#: code:addons/nsca_client/models/nsca_check.py:145 +#, python-format +msgid "Command '%s' not found. Please install the NSCA client.\n" +"On Debian/Ubuntu: apt-get install nsca-client" +msgstr "Commande '%s' non-disponible. Veuillez installer le client NSCA.\n" +"Sur Debian/Ubuntu: apt-get install nsca-client" + +#. module: nsca_client +#: field:nsca.server,config_file_path:0 +msgid "Configuration file" +msgstr "Fichier de configuration" + #. module: nsca_client #: field:nsca.check,create_uid:0 #: field:nsca.server,create_uid:0 @@ -119,7 +132,7 @@ msgid "Model" msgstr "Modèle" #. module: nsca_client -#: code:addons/nsca_client/models/nsca_check.py:52 +#: code:addons/nsca_client/models/nsca_check.py:60 #: model:ir.model,name:nsca_client.model_nsca_check #: view:nsca.check:nsca_client.view_nsca_check_form #, python-format diff --git a/nsca_client/i18n/nsca_client.pot b/nsca_client/i18n/nsca_client.pot index 63636c149..c9cb934f2 100644 --- a/nsca_client/i18n/nsca_client.pot +++ b/nsca_client/i18n/nsca_client.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-15 11:57+0000\n" -"PO-Revision-Date: 2015-12-15 11:57+0000\n" +"POT-Creation-Date: 2015-12-17 07:05+0000\n" +"PO-Revision-Date: 2015-12-17 07:05+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -58,6 +58,18 @@ msgstr "" msgid "Checks" msgstr "" +#. module: nsca_client +#: code:addons/nsca_client/models/nsca_check.py:145 +#, python-format +msgid "Command '%s' not found. Please install the NSCA client.\n" +"On Debian/Ubuntu: apt-get install nsca-client" +msgstr "" + +#. module: nsca_client +#: field:nsca.server,config_file_path:0 +msgid "Configuration file" +msgstr "" + #. module: nsca_client #: field:nsca.check,create_uid:0 #: field:nsca.server,create_uid:0 @@ -119,7 +131,7 @@ msgid "Model" msgstr "" #. module: nsca_client -#: code:addons/nsca_client/models/nsca_check.py:52 +#: code:addons/nsca_client/models/nsca_check.py:60 #: model:ir.model,name:nsca_client.model_nsca_check #: view:nsca.check:nsca_client.view_nsca_check_form #, python-format From 871172444b014db859e711758456451166ec11e8 Mon Sep 17 00:00:00 2001 From: sebalix Date: Thu, 7 Apr 2016 09:05:49 +0200 Subject: [PATCH 05/13] [IMP] nsca_client - Configure the node hostname at the NSCA server level --- nsca_client/__openerp__.py | 1 - nsca_client/data/ir_config_parameter.xml | 13 ------------- nsca_client/models/nsca_check.py | 3 +-- nsca_client/models/nsca_server.py | 4 ++++ nsca_client/views/nsca_server.xml | 3 +++ 5 files changed, 8 insertions(+), 16 deletions(-) delete mode 100644 nsca_client/data/ir_config_parameter.xml diff --git a/nsca_client/__openerp__.py b/nsca_client/__openerp__.py index 6bfaf81a4..5571fb51d 100644 --- a/nsca_client/__openerp__.py +++ b/nsca_client/__openerp__.py @@ -13,7 +13,6 @@ "installable": True, "data": [ "security/ir.model.access.csv", - "data/ir_config_parameter.xml", "data/nsca_server.xml", "views/nsca_menu.xml", "views/nsca_check.xml", diff --git a/nsca_client/data/ir_config_parameter.xml b/nsca_client/data/ir_config_parameter.xml deleted file mode 100644 index 5a7cac83a..000000000 --- a/nsca_client/data/ir_config_parameter.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - nsca_client.hostname - localhost - - - - diff --git a/nsca_client/models/nsca_check.py b/nsca_client/models/nsca_check.py index 1159d7e76..71734cbd2 100644 --- a/nsca_client/models/nsca_check.py +++ b/nsca_client/models/nsca_check.py @@ -106,8 +106,7 @@ class NscaCheck(models.Model): def _format_check_result(self, check, rc, message): """Format the check result with tabulations as delimiter.""" message = message.replace('\t', ' ') - hostname = self.env['ir.config_parameter'].get_param( - 'nsca_client.hostname', 'localhost') + hostname = check.server_id.node_hostname check_result = u"%s\t%s\t%s\t%s" % ( hostname, check.service, rc, message) return check_result.encode('utf-8') diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py index ea66c348c..441fd1c27 100644 --- a/nsca_client/models/nsca_server.py +++ b/nsca_client/models/nsca_server.py @@ -11,6 +11,10 @@ class NscaServer(models.Model): name = fields.Char(u"Hostname", required=True) port = fields.Integer(u"Port", default=5667, required=True) + node_hostname = fields.Char( + u"Hostname of this node", required=True, + help=u"This is the hostname of the current node declared in the " + u"monitoring server.") config_file_path = fields.Char( u"Configuration file", default="/etc/send_nsca.cfg", required=True) check_ids = fields.One2many( diff --git a/nsca_client/views/nsca_server.xml b/nsca_client/views/nsca_server.xml index f03263dd9..d5b00472d 100644 --- a/nsca_client/views/nsca_server.xml +++ b/nsca_client/views/nsca_server.xml @@ -16,6 +16,9 @@ + + + From 86e7a3fffe92bafa465cf3e3bcc6dbb458b7038a Mon Sep 17 00:00:00 2001 From: sebalix Date: Thu, 7 Apr 2016 09:08:09 +0200 Subject: [PATCH 06/13] [IMP] nsca_client - A check method could not return, and as such no message will be sent to the NSCA server instead of a CRITICAL one --- nsca_client/models/nsca_check.py | 12 +++++++++++- nsca_client/views/nsca_check.xml | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nsca_client/models/nsca_check.py b/nsca_client/models/nsca_check.py index 71734cbd2..079d9df8a 100644 --- a/nsca_client/models/nsca_check.py +++ b/nsca_client/models/nsca_check.py @@ -35,6 +35,10 @@ class NscaCheck(models.Model): nsca_model = fields.Char(u"Model") nsca_function = fields.Char(u"Method") nsca_args = fields.Char(u"Arguments") + allow_void_result = fields.Boolean( + u"Allow void result", default=False, + help=u"By default, a CRITICAL message is sent if the method does not " + u"return.\nIf checked, no message will be sent in such a case.") @api.model def default_get(self, fields_list): @@ -87,7 +91,13 @@ class NscaCheck(models.Model): try: args = str2tuple(check.nsca_args) NscaModel = self.env[check.nsca_model] - rc, message = getattr(NscaModel, check.nsca_function)(*args) + result = getattr(NscaModel, check.nsca_function)(*args) + if not result: + if check.allow_void_result: + return False + raise ValueError( + "'%s' method does not return" % check.nsca_function) + rc, message = result except Exception, exc: rc, message = 2, "%s" % exc _logger.error("%s - %s", check.service, message) diff --git a/nsca_client/views/nsca_check.xml b/nsca_client/views/nsca_check.xml index 87ed38238..ce2f29cf9 100644 --- a/nsca_client/views/nsca_check.xml +++ b/nsca_client/views/nsca_check.xml @@ -27,6 +27,7 @@ +

The method must return a tuple (RC, MESSAGE) where RC is an integer:

From d0feabc2c7e999da362e948698082e970fb87471 Mon Sep 17 00:00:00 2001 From: sebalix Date: Thu, 7 Apr 2016 14:19:37 +0200 Subject: [PATCH 07/13] [IMP] nsca_client - Auto-create the configuration file used by the 'send_nsca' binary, password and encryption method are set in 'nsca.server' records --- nsca_client/models/nsca_server.py | 78 +++++++++++++++++++++++++++++-- nsca_client/views/nsca_server.xml | 2 + 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py index 441fd1c27..d2a96725b 100644 --- a/nsca_client/models/nsca_server.py +++ b/nsca_client/models/nsca_server.py @@ -2,7 +2,10 @@ # © 2015 ABF OSIELL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp import fields, models +import os + +from openerp import api, fields, models +from openerp.tools import config class NscaServer(models.Model): @@ -11,11 +14,80 @@ class NscaServer(models.Model): name = fields.Char(u"Hostname", required=True) port = fields.Integer(u"Port", default=5667, required=True) + password = fields.Char(u"Password") + encryption_method = fields.Selection( + selection='_selection_encryption_method', + string=u"Encryption method", default='1', required=True) + config_file_path = fields.Char( + u"Configuration file", + compute='_compute_config_file_path') node_hostname = fields.Char( u"Hostname of this node", required=True, help=u"This is the hostname of the current node declared in the " u"monitoring server.") - config_file_path = fields.Char( - u"Configuration file", default="/etc/send_nsca.cfg", required=True) check_ids = fields.One2many( 'nsca.check', 'server_id', string=u"Checks") + + def _selection_encryption_method(self): + return [ + ('0', u"0 - None (Do NOT use this option)"), + ('1', u"1 - Simple XOR"), + ('2', u"2 - DES"), + ('3', u"3 - 3DES (Triple DES)"), + ('4', u"4 - CAST-128"), + ('5', u"5 - CAST-256"), + ('6', u"6 - xTEA"), + ('7', u"7 - 3WAY"), + ('8', u"8 - BLOWFISH"), + ('9', u"9 - TWOFISH"), + ('10', u"10 - LOKI97"), + ('11', u"11 - RC2"), + ('12', u"12 - ARCFOUR"), + ('14', u"14 - RIJNDAEL-128"), + ('15', u"15 - RIJNDAEL-192"), + ('16', u"16 - RIJNDAEL-256"), + ('19', u"19 - WAKE"), + ('20', u"20 - SERPENT"), + ('22', u"22 - ENIGMA (Unix crypt)"), + ('23', u"23 - GOST"), + ('24', u"24 - SAFER64"), + ('25', u"25 - SAFER128"), + ('26', u"26 - SAFER+"), + ] + + @api.multi + def _compute_config_file_path(self): + for server in self: + data_dir_path = config.get('data_dir') + file_name = 'send_nsca_%s.cfg' % server.id + full_path = os.path.join(data_dir_path, 'nsca_client', file_name) + server.config_file_path = full_path + + @api.multi + def write_config_file(self): + for server in self: + data_dir_path = config.get('data_dir') + config_dir_path = os.path.join(data_dir_path, 'nsca_client') + try: + os.makedirs(config_dir_path) + except OSError as exception: + if exception.errno != os.errno.EEXIST: + raise + with open(server.config_file_path, 'w') as config_file: + if server.password: + config_file.write('password=%s\n' % server.password) + config_file.write( + 'encryption_method=%s\n' % server.encryption_method) + return True + + @api.multi + def write(self, vals): + res = super(NscaServer, self).write(vals) + self.write_config_file() + return res + + @api.model + def create(self, vals): + res = super(NscaServer, self).create(vals) + res.write_config_file() + return res diff --git a/nsca_client/views/nsca_server.xml b/nsca_client/views/nsca_server.xml index d5b00472d..db725a51d 100644 --- a/nsca_client/views/nsca_server.xml +++ b/nsca_client/views/nsca_server.xml @@ -14,6 +14,8 @@ + + From 0ed977743cb1625883623b500e22d154a8365c8e Mon Sep 17 00:00:00 2001 From: sebalix Date: Thu, 7 Apr 2016 15:05:04 +0200 Subject: [PATCH 08/13] [IMP] nsca_client - Translations updated --- nsca_client/i18n/fr.po | 50 +++++++++++++++++++++++++------ nsca_client/models/nsca_server.py | 2 +- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/nsca_client/i18n/fr.po b/nsca_client/i18n/fr.po index a1418c4f1..c092b5b2f 100644 --- a/nsca_client/i18n/fr.po +++ b/nsca_client/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-17 07:07+0000\n" -"PO-Revision-Date: 2015-12-17 07:07+0000\n" +"POT-Creation-Date: 2016-04-07 12:33+0000\n" +"PO-Revision-Date: 2016-04-07 12:33+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -40,6 +40,11 @@ msgstr "2: CRITICAL" msgid "3: UNKNOWN" msgstr "3: UNKNOWN" +#. module: nsca_client +#: field:nsca.check,allow_void_result:0 +msgid "Allow void result" +msgstr "Autoriser l'absence de résultat" + #. module: nsca_client #: view:nsca.check:nsca_client.view_nsca_check_form msgid "Any other RC value will be treated as CRITICAL." @@ -50,6 +55,13 @@ msgstr "Tout autre valeur RC sera traitée comme CRITICAL." msgid "Arguments" msgstr "Arguments" +#. module: nsca_client +#: help:nsca.check,allow_void_result:0 +msgid "By default, a CRITICAL message is sent if the method does not return.\n" +"If checked, no message will be sent in such a case." +msgstr "Par défaut, un message de niveau CRITICAL sera envoyé si la méthode ne retourne aucun résultat.\n" +"Si cette option est cochée, aucun message ne sera envoyé dans un tel cas." + #. module: nsca_client #: model:ir.actions.act_window,name:nsca_client.action_nsca_check_tree #: model:ir.ui.menu,name:nsca_client.menu_action_nsca_check_tree @@ -59,18 +71,13 @@ msgid "Checks" msgstr "Contrôles" #. module: nsca_client -#: code:addons/nsca_client/models/nsca_check.py:145 +#: code:addons/nsca_client/models/nsca_check.py:154 #, python-format msgid "Command '%s' not found. Please install the NSCA client.\n" "On Debian/Ubuntu: apt-get install nsca-client" msgstr "Commande '%s' non-disponible. Veuillez installer le client NSCA.\n" "Sur Debian/Ubuntu: apt-get install nsca-client" -#. module: nsca_client -#: field:nsca.server,config_file_path:0 -msgid "Configuration file" -msgstr "Fichier de configuration" - #. module: nsca_client #: field:nsca.check,create_uid:0 #: field:nsca.server,create_uid:0 @@ -93,6 +100,11 @@ msgstr "Cron" msgid "E.g." msgstr "Ex :" +#. module: nsca_client +#: field:nsca.server,encryption_method:0 +msgid "Encryption method" +msgstr "Méthode de chiffrement" + #. module: nsca_client #: view:nsca.check:nsca_client.view_nsca_check_form msgid "Frequency" @@ -103,6 +115,11 @@ msgstr "Fréquence" msgid "Hostname" msgstr "Serveur" +#. module: nsca_client +#: field:nsca.server,node_hostname:0 +msgid "Hostname of this node" +msgstr "Nom d'hôte du noeud" + #. module: nsca_client #: field:nsca.check,id:0 #: field:nsca.server,id:0 @@ -132,7 +149,7 @@ msgid "Model" msgstr "Modèle" #. module: nsca_client -#: code:addons/nsca_client/models/nsca_check.py:60 +#: code:addons/nsca_client/models/nsca_check.py:64 #: model:ir.model,name:nsca_client.model_nsca_check #: view:nsca.check:nsca_client.view_nsca_check_form #, python-format @@ -160,6 +177,16 @@ msgstr "Serveur NSCA" msgid "NSCA Servers" msgstr "Serveurs NSCA" +#. module: nsca_client +#: view:nsca.server:nsca_client.view_nsca_server_form +msgid "Node identity" +msgstr "Identité du noeud" + +#. module: nsca_client +#: field:nsca.server,password:0 +msgid "Password" +msgstr "Mot de passe" + #. module: nsca_client #: field:nsca.server,port:0 msgid "Port" @@ -191,3 +218,8 @@ msgstr "Paramètres" msgid "The method must return a tuple (RC, MESSAGE) where RC is an integer:" msgstr "La méthode doit retourner un tuple (RC, MESSAGE) où RC est un entier :" +#. module: nsca_client +#: help:nsca.server,node_hostname:0 +msgid "This is the hostname of the current Odoo node declared in the monitoring server." +msgstr "C'est le nom d'hôte identifiant le serveur Odoo dans la configuration du serveur NSCA." + diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py index d2a96725b..68460d7d9 100644 --- a/nsca_client/models/nsca_server.py +++ b/nsca_client/models/nsca_server.py @@ -23,7 +23,7 @@ class NscaServer(models.Model): compute='_compute_config_file_path') node_hostname = fields.Char( u"Hostname of this node", required=True, - help=u"This is the hostname of the current node declared in the " + help=u"This is the hostname of the current Odoo node declared in the " u"monitoring server.") check_ids = fields.One2many( 'nsca.check', 'server_id', string=u"Checks") From 003bec52e90b8539d09dc4cc604d6d8c51c3ff6e Mon Sep 17 00:00:00 2001 From: sebalix Date: Thu, 7 Apr 2016 15:21:44 +0200 Subject: [PATCH 09/13] [IMP] nsca_client - README and screenshots updated --- nsca_client/README.rst | 11 +++-------- nsca_client/static/description/check.png | Bin 37328 -> 43912 bytes nsca_client/static/description/server.png | Bin 17483 -> 33163 bytes 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/nsca_client/README.rst b/nsca_client/README.rst index 5f0715841..25a4facad 100644 --- a/nsca_client/README.rst +++ b/nsca_client/README.rst @@ -6,22 +6,20 @@ NSCA Client =========== -Send passive alert to your favorite NSCA daemon (Nagios, Shinken...). +This is a technical module to send passive alerts to your favorite NSCA daemon +(Nagios, Shinken...). This module is based on the Odoo cron system and requires a NSCA client installed on the system to satisfy the ``/usr/sbin/send_nsca`` command. Installation ============ -To install this module, you need to install a NSCA client. +To use this module, you need to install a NSCA client. On Debian/Ubuntu:: $ sudo apt-get install nsca-client -Then configure the NSCA client in ``/etc/send_nsca.cfg`` (password -and encryption method). - Configuration ============= @@ -29,9 +27,6 @@ To configure this module, you need to: * Configure your server and a passive service in your monitoring tool (e.g service ``Odoo Mail Queue`` on host ``MY-SERVER``). -* On Odoo, set the previous hostname in the system parameters:: - - nsca_client.hostname = MY-SERVER * Declare your NSCA server in the menu Configuration / Technical / NSCA Client / Servers diff --git a/nsca_client/static/description/check.png b/nsca_client/static/description/check.png index 5fdd064a49080e99631686466acd151e567b378f..48d11df0f66503cf89a00c049a0d2c69975fedfa 100644 GIT binary patch literal 43912 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%0Ah1Gzn;p1N`azLwnWUXi9 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 z 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 F;6JxyH?IHy diff --git a/nsca_client/static/description/server.png b/nsca_client/static/description/server.png index 7d19803cab2a9045e2faf17034791c78ee43062b..2008692092a5c575ea616cfbab5a8e7ebf861b9a 100644 GIT binary patch literal 33163 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%0AvGh_BSXY?+PmM&_n&=jEh)$sZ&I_M=cZl@Ioa4 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 r&3|4AC4RBC#Nn1cmPV4!nJ>EK~aG{pbG%+?3P; literal 17483 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 W{t1M)_Rk_AfRenrT*aIBpZ^2cJWg`} From db31ac96beb4024c5584128264d4a3d0b251773e Mon Sep 17 00:00:00 2001 From: sebalix Date: Thu, 7 Apr 2016 15:44:13 +0200 Subject: [PATCH 10/13] [FIX] nsca_client - Fix XML data --- nsca_client/data/nsca_server.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/nsca_client/data/nsca_server.xml b/nsca_client/data/nsca_server.xml index 77453502c..bcc61939d 100644 --- a/nsca_client/data/nsca_server.xml +++ b/nsca_client/data/nsca_server.xml @@ -7,6 +7,7 @@ nagios.example.net 5667 + MY-SERVER From b09084bb52167f1bb65871c1430e00e5c0666507 Mon Sep 17 00:00:00 2001 From: sebalix Date: Wed, 13 Apr 2016 12:14:58 +0200 Subject: [PATCH 11/13] [FIX] nsca_client - Add the database as a subfolder for the configuration file path in order to be compatible with a multi-databases instance --- nsca_client/models/nsca_server.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py index 68460d7d9..77fbad9a6 100644 --- a/nsca_client/models/nsca_server.py +++ b/nsca_client/models/nsca_server.py @@ -18,6 +18,9 @@ class NscaServer(models.Model): encryption_method = fields.Selection( selection='_selection_encryption_method', string=u"Encryption method", default='1', required=True) + config_dir_path = fields.Char( + u"Configuration directory", + compute='_compute_config_dir_path') config_file_path = fields.Char( u"Configuration file", compute='_compute_config_file_path') @@ -56,20 +59,25 @@ class NscaServer(models.Model): ] @api.multi - def _compute_config_file_path(self): + def _compute_config_dir_path(self): for server in self: data_dir_path = config.get('data_dir') + dir_path = os.path.join( + data_dir_path, 'nsca_client', self.env.cr.dbname) + server.config_dir_path = dir_path + + @api.multi + def _compute_config_file_path(self): + for server in self: file_name = 'send_nsca_%s.cfg' % server.id - full_path = os.path.join(data_dir_path, 'nsca_client', file_name) + full_path = os.path.join(server.config_dir_path, file_name) server.config_file_path = full_path @api.multi def write_config_file(self): for server in self: - data_dir_path = config.get('data_dir') - config_dir_path = os.path.join(data_dir_path, 'nsca_client') try: - os.makedirs(config_dir_path) + os.makedirs(server.config_dir_path) except OSError as exception: if exception.errno != os.errno.EEXIST: raise From e9fd5269982e7b9d924e1450236cae585f206571 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Thu, 7 Jun 2018 13:08:05 +0200 Subject: [PATCH 12/13] [MIG] nsca_client --- .travis.yml | 1 + nsca_client/README.rst | 41 +++-- nsca_client/__init__.py | 1 - .../{__openerp__.py => __manifest__.py} | 6 +- nsca_client/data/nsca_server.xml | 14 -- nsca_client/demo/demo_data.xml | 32 ++-- nsca_client/models/__init__.py | 4 - nsca_client/models/nsca_check.py | 68 +++++--- nsca_client/models/nsca_server.py | 52 +++++- nsca_client/tests/__init__.py | 1 + nsca_client/tests/test_nsca.py | 97 +++++++++++ nsca_client/views/nsca_check.xml | 151 ++++++++++-------- nsca_client/views/nsca_menu.xml | 4 +- nsca_client/views/nsca_server.xml | 94 +++++------ 14 files changed, 368 insertions(+), 198 deletions(-) rename nsca_client/{__openerp__.py => __manifest__.py} (82%) delete mode 100644 nsca_client/data/nsca_server.xml create mode 100644 nsca_client/tests/__init__.py create mode 100644 nsca_client/tests/test_nsca.py diff --git a/.travis.yml b/.travis.yml index 614e5e0df..2b3375599 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ addons: packages: - expect-dev # provides unbuffer utility - python-lxml # because pip installation is slow + - nsca-client env: global: diff --git a/nsca_client/README.rst b/nsca_client/README.rst index 25a4facad..381db2e6a 100644 --- a/nsca_client/README.rst +++ b/nsca_client/README.rst @@ -40,14 +40,28 @@ To configure this module, you need to: * Code the methods which will be called by the NSCA checks. -Such methods must return a tuple ``(RC, MESSAGE)`` where ``RC`` is an integer, -and ``MESSAGE`` a unicode string. ``RC`` values and the corresponding status are: +Such methods must return a tuple ``(RC, MESSAGE, PERFORMANCE_DATA)`` where ``RC`` is an integer, +``MESSAGE`` a unicode string AND ``PERFOMANCE_DATA`` is a dictionary. +``RC`` values and the corresponding status are: - 0: OK - 1: WARNING - 2: CRITICAL - 3: UNKNOWN +``PERFORMANCE_DATA`` is not mandatory, so it could be possible to send +``(RC, MESSAGE)``. +Each element of ``PERFORMANCE_DATA`` will be a dictionary that could contain: + +- value: value of the data (required) +- max: Max value on the chart +- min: Minimum value on the chart +- warn: Warning value on the chart +- crit: Critical value on the chart +- uom: Unit of Measure on the chart (s - Seconds, % - Percentage, B - Bytes, c - Continuous) + +The key of the dictionary will be used as the performance_data label. + E.g: .. code-block:: python @@ -59,20 +73,19 @@ E.g: def nsca_check_mails(self): mails = self.search([('state', '=', 'exception')]) if mails: - return (1, u"%s mails not sent" % len(mails)) - return (0, u"OK") + return (1, u"%s mails not sent" % len(mails), { + 'exceptions': {'value': len(mails)}}) + return (0, u"OK", {'exceptions': {'value': len(mails)}}) + +On the example, the performance data will use the label ``exceptions`` and the +value will be the number of exception of mails. Usage ===== .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/149/8.0 - -Known issues / Roadmap -====================== - -* Send performance data + :target: https://runbot.odoo-community.org/runbot/149/11.0 Bug Tracker =========== @@ -80,11 +93,8 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, -help us smashing it by providing a detailed and welcomed `feedback -`_. +help us smashing it by providing a detailed and welcomed feedback. + Credits ======= @@ -98,6 +108,7 @@ Contributors ------------ * Sébastien Alix +* Enric Tobella Maintainer ---------- diff --git a/nsca_client/__init__.py b/nsca_client/__init__.py index f71417703..b9367d7f2 100644 --- a/nsca_client/__init__.py +++ b/nsca_client/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2015 ABF OSIELL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/nsca_client/__openerp__.py b/nsca_client/__manifest__.py similarity index 82% rename from nsca_client/__openerp__.py rename to nsca_client/__manifest__.py index 5571fb51d..0aebc1cea 100644 --- a/nsca_client/__openerp__.py +++ b/nsca_client/__manifest__.py @@ -1,19 +1,17 @@ -# -*- coding: utf-8 -*- # © 2015 ABF OSIELL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "NSCA Client", "summary": "Send passive alerts to monitor your Odoo application.", - "version": "8.0.1.0.0", + "version": "11.0.1.0.0", "category": "Tools", - "website": "http://osiell.com/", + "website": "http://github.com/OCA/server-tools", "author": "ABF OSIELL, Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, "installable": True, "data": [ "security/ir.model.access.csv", - "data/nsca_server.xml", "views/nsca_menu.xml", "views/nsca_check.xml", "views/nsca_server.xml", diff --git a/nsca_client/data/nsca_server.xml b/nsca_client/data/nsca_server.xml deleted file mode 100644 index bcc61939d..000000000 --- a/nsca_client/data/nsca_server.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - nagios.example.net - 5667 - MY-SERVER - - - - diff --git a/nsca_client/demo/demo_data.xml b/nsca_client/demo/demo_data.xml index 2c9f91b18..ae53551e0 100644 --- a/nsca_client/demo/demo_data.xml +++ b/nsca_client/demo/demo_data.xml @@ -1,16 +1,22 @@ - - + + - - - Odoo Mail Queue - - minutes - mail.mail - nsca_check_mails - - + + nagios.example.net + 5667 + MY-SERVER + - - + + + Odoo Mail Queue + + minutes + mail.mail + nsca_check_mails + + + + + diff --git a/nsca_client/models/__init__.py b/nsca_client/models/__init__.py index 32927f70a..b1b898df9 100644 --- a/nsca_client/models/__init__.py +++ b/nsca_client/models/__init__.py @@ -1,5 +1 @@ -# -*- coding: utf-8 -*- -# © 2015 ABF OSIELL -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - from . import nsca_check, nsca_server diff --git a/nsca_client/models/nsca_check.py b/nsca_client/models/nsca_check.py index 079d9df8a..c846d881e 100644 --- a/nsca_client/models/nsca_check.py +++ b/nsca_client/models/nsca_check.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- -# © 2015 ABF OSIELL +# (Copyright) 2015 ABF OSIELL +# (Copyright) 2018 Creu Blanca # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import logging @@ -7,10 +7,9 @@ import os import shlex import subprocess -from openerp import _, api, fields, models -from openerp.exceptions import Warning as UserError - -from openerp.addons.base.ir.ir_cron import str2tuple +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.tools.safe_eval import safe_eval _logger = logging.getLogger(__name__) @@ -46,11 +45,9 @@ class NscaCheck(models.Model): has the side effect to re-create the fields on the current model). """ res = super(NscaCheck, self).default_get(fields_list) - NscaServer = self.env['nsca.server'] - res['name'] = 'TEMP' # Required on 'ir.cron', replaced later + res['name'] = 'TEMP' # Required on 'ir.cron', replaced later res['interval_number'] = 10 res['interval_type'] = 'minutes' - res['server_id'] = NscaServer.search([])[0].id return res @api.multi @@ -59,12 +56,13 @@ class NscaCheck(models.Model): - 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': u"%s - %s" % (_(u"NSCA Check"), check.service), - 'model': self._name, - 'function': '_cron_check', - 'args': '(%s,)' % check.id, + 'model_id': model.id, + 'state': 'code', + 'code': 'model._cron_check(%s,)' % check.id, 'doall': False, 'numbercall': -1 } @@ -72,6 +70,11 @@ class NscaCheck(models.Model): @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 @@ -87,28 +90,47 @@ class NscaCheck(models.Model): def _cron_check(self, check_id): self._check_send_nsca_command() check = self.browse(check_id) - rc, message = 3, "Unknown" + rc, message, performance = 3, "Unknown", {} try: - args = str2tuple(check.nsca_args) NscaModel = self.env[check.nsca_model] - result = getattr(NscaModel, check.nsca_function)(*args) + results = {'model': NscaModel} + safe_eval( + 'result = model.%s(%s)' % ( + 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) - rc, message = result - except Exception, exc: + if len(result) == 2: + rc, message = result + else: + rc, message, performance = result + except Exception as exc: rc, message = 2, "%s" % exc - _logger.error("%s - %s", check.service, message) - check._send_nsca(rc, message) + _logger.warning("%s - %s", check.service, message) + check._send_nsca(rc, message, performance) return True @api.multi - def _send_nsca(self, rc, message): + def _send_nsca(self, rc, message, performance): """Send the result of the check to the NSCA daemon.""" for check in self: - check_result = self._format_check_result(check, rc, message) + msg = message + if len(performance) > 0: + msg += '| ' + ''.join( + ["%s=%s%s;%s;%s;%s;%s" % ( + key, + performance[key]['value'], + performance[key].get('uom', ''), + performance[key].get('warn', ''), + performance[key].get('crit', ''), + performance[key].get('min', ''), + performance[key].get('max', ''), + ) for key in sorted(performance)]) + check_result = self._format_check_result(check, rc, msg) cmd = self._prepare_command(check) self._run_command(check, cmd, check_result) @@ -143,8 +165,8 @@ class NscaCheck(models.Model): stderr=subprocess.STDOUT) stdout = proc.communicate( input=check_result)[0] - _logger.info("%s: %s", check_result, stdout.strip()) - except Exception, exc: + _logger.debug("%s: %s", check_result, stdout.strip()) + except Exception as exc: _logger.error(exc) def _check_send_nsca_command(self): diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py index 77fbad9a6..5fed760c8 100644 --- a/nsca_client/models/nsca_server.py +++ b/nsca_client/models/nsca_server.py @@ -1,11 +1,12 @@ -# -*- coding: utf-8 -*- -# © 2015 ABF OSIELL -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# (Copyright) 2015 ABF OSIELL +# (Copyright) 2018 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import psutil import os -from openerp import api, fields, models -from openerp.tools import config +from odoo import api, fields, models +from odoo.tools import config class NscaServer(models.Model): @@ -99,3 +100,44 @@ class NscaServer(models.Model): res = super(NscaServer, self).create(vals) res.write_config_file() return res + + @api.model + def current_status(self): + ram = 0 + cpu = 0 + if psutil: + process = psutil.Process(os.getpid()) + # psutil changed its api through versions + processes = [process] + if config.get( + 'workers') and process.parent: # pragma: no cover + if hasattr(process.parent, '__call__'): + process = process.parent() + else: + process = process.parent + if hasattr(process, 'children'): + processes += process.children(True) + elif hasattr(process, 'get_children'): + processes += process.get_children(True) + for process in processes: + if hasattr(process, 'memory_percent'): + ram += process.memory_percent() + if hasattr(process, 'cpu_percent'): + cpu += process.cpu_percent(interval=1) + user_count = 0 + if 'bus.presence' in self.env.registry: + user_count = self.env['bus.presence'].search_count([ + ('status', '=', 'online'), + ]) + performance = { + 'cpu': { + 'value': cpu, + }, + 'ram': { + 'value': ram, + }, + 'user_count': { + 'value': user_count, + }, + } + return 0, u"OK", performance diff --git a/nsca_client/tests/__init__.py b/nsca_client/tests/__init__.py new file mode 100644 index 000000000..3cc2c357b --- /dev/null +++ b/nsca_client/tests/__init__.py @@ -0,0 +1 @@ +from . import test_nsca diff --git a/nsca_client/tests/test_nsca.py b/nsca_client/tests/test_nsca.py new file mode 100644 index 000000000..bf797d561 --- /dev/null +++ b/nsca_client/tests/test_nsca.py @@ -0,0 +1,97 @@ +# Copyright 2018 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import mock + +from odoo.tests.common import TransactionCase + + +class Popen: + def __init__(self, cmd, stdout, stdin, stderr): + self.cmd = cmd + self.stdout = stdout + self.stdin = stdin + self.stderr = stderr + + def communicate(input): + return ['test'] + + +class TestNsca(TransactionCase): + + def test_nsca(self): + server = self.env['nsca.server'].create({ + 'name': 'localhost', + 'password': 'pass', + 'encryption_method': '3', + 'node_hostname': 'odoodev', + }) + self.assertTrue(server.config_file_path) + with mock.patch('subprocess.Popen') as post: + post.return_value = Popen + check = self.env['nsca.check'].create({ + 'server_id': server.id, + 'service': 'test', + 'nsca_model': 'nsca.server', + 'nsca_function': 'current_status' + }) + self.assertTrue(check.model_id) + self.env['nsca.check']._cron_check(check.id,) + + def test_write(self): + server = self.env['nsca.server'].create({ + 'name': 'localhost', + 'password': 'pass', + 'encryption_method': '3', + 'node_hostname': 'odoodev', + }) + self.assertTrue(server.config_file_path) + check = self.env['nsca.check'].create({ + 'server_id': server.id, + 'service': 'test', + 'nsca_model': 'nsca.server', + 'nsca_function': 'current_status' + }) + check.cron_id.state = 'object_create' + check.write({'interval_number': 1}) + self.assertEqual(check.cron_id.state, 'object_create') + check.write({'service': 'change'}) + self.assertNotEqual(check.cron_id.state, 'object_create') + + def test_void_failure(self): + server = self.env['nsca.server'].create({ + 'name': 'localhost', + 'password': 'pass', + 'encryption_method': '3', + 'node_hostname': 'odoodev', + }) + check = self.env['nsca.check'].create({ + 'server_id': server.id, + 'service': 'test', + 'nsca_model': 'nsca.check', + 'allow_void_result': False, + 'nsca_function': '_check_send_nsca_command' + }) + with mock.patch('subprocess.Popen') as post: + post.return_value = Popen + self.env['nsca.check']._cron_check(check.id,) + post.assert_called_once() + + def test_void_ok(self): + server = self.env['nsca.server'].create({ + 'name': 'localhost', + 'password': 'pass', + 'encryption_method': '3', + 'node_hostname': 'odoodev', + }) + check = self.env['nsca.check'].create({ + 'server_id': server.id, + 'service': 'test', + 'nsca_model': 'nsca.check', + 'allow_void_result': True, + 'nsca_function': '_check_send_nsca_command' + }) + with mock.patch('subprocess.Popen') as post: + post.return_value = Popen + self.env['nsca.check']._cron_check(check.id,) + post.assert_not_called() diff --git a/nsca_client/views/nsca_check.xml b/nsca_client/views/nsca_check.xml index ce2f29cf9..9713d9cf3 100644 --- a/nsca_client/views/nsca_check.xml +++ b/nsca_client/views/nsca_check.xml @@ -2,78 +2,89 @@ - - + + - - nsca.check.form - nsca.check - -

- - - - - - - - - - - -
-

The method must return a tuple (RC, MESSAGE) where RC is an integer:

- -
    -
  • 0: OK
  • -
  • 1: WARNING
  • -
  • 2: CRITICAL
  • -
  • 3: UNKNOWN
  • -
- -

Any other RC value will be treated as CRITICAL.

-

E.g. (1, u"3 mails not sent")

-
-
-
-
- - - + + nsca.check.form + nsca.check + +
+ + + + + + + + + + + +
+

The method must return a tuple (RC, + MESSAGE) where RC is an integer: +

+ +
    +
  • 0: OK
  • +
  • 1: WARNING
  • +
  • 2: CRITICAL
  • +
  • 3: UNKNOWN
  • +
+ +

Any other RC value will be treated as + CRITICAL. +

+

E.g. + (1, u"3 mails not sent") +

+
+
+
+
+
+
+
- - nsca.check.tree - nsca.check - - - - - - - - - + + nsca.check.tree + nsca.check + + + + + + + + + - - Checks - ir.actions.act_window - nsca.check - form - - - ['|', ('active', '=', True), ('active', '=', False)] - + + Checks + ir.actions.act_window + nsca.check + form + + + ['|', ('active', '=', True), ('active', '=', + False)] + + - + - - + + diff --git a/nsca_client/views/nsca_menu.xml b/nsca_client/views/nsca_menu.xml index 4472e82c5..1a35df036 100644 --- a/nsca_client/views/nsca_menu.xml +++ b/nsca_client/views/nsca_menu.xml @@ -1,7 +1,7 @@ - + - + diff --git a/nsca_client/views/nsca_server.xml b/nsca_client/views/nsca_server.xml index db725a51d..145ba0d35 100644 --- a/nsca_client/views/nsca_server.xml +++ b/nsca_client/views/nsca_server.xml @@ -2,56 +2,56 @@ - - + + - - nsca.server.form - nsca.server - -
- - - + + nsca.server.form + nsca.server + + + + + + + + + + + + + + + + + + + + + + + nsca.server.tree + nsca.server + + + - - - - - - - - - -
- -
-
- - - nsca.server.tree - nsca.server - - - - - - - - + + + - - Servers - ir.actions.act_window - nsca.server - form - - + + Servers + ir.actions.act_window + nsca.server + form + + - + -
-
+ + From 180b020caa6d74aa796a532c96fd3eca762d6b72 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Mon, 8 Oct 2018 11:04:08 +0200 Subject: [PATCH 13/13] [IMP] nsca_client: Pass nsca code to server, in order to allow other integrations, not only checks --- nsca_client/models/nsca_check.py | 74 +---------------------- nsca_client/models/nsca_server.py | 98 ++++++++++++++++++++++++++++++- nsca_client/tests/test_nsca.py | 11 +++- nsca_client/views/nsca_server.xml | 12 +++- 4 files changed, 117 insertions(+), 78 deletions(-) diff --git a/nsca_client/models/nsca_check.py b/nsca_client/models/nsca_check.py index c846d881e..a96bb9f60 100644 --- a/nsca_client/models/nsca_check.py +++ b/nsca_client/models/nsca_check.py @@ -1,24 +1,12 @@ # (Copyright) 2015 ABF OSIELL # (Copyright) 2018 Creu Blanca # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - import logging -import os -import shlex -import subprocess - from odoo import _, api, fields, models -from odoo.exceptions import UserError from odoo.tools.safe_eval import safe_eval _logger = logging.getLogger(__name__) -SEND_NSCA_BIN = '/usr/sbin/send_nsca' - - -def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - class NscaCheck(models.Model): _name = "nsca.check" @@ -88,7 +76,7 @@ class NscaCheck(models.Model): @api.model def _cron_check(self, check_id): - self._check_send_nsca_command() + self.env['nsca.server']._check_send_nsca_command() check = self.browse(check_id) rc, message, performance = 3, "Unknown", {} try: @@ -116,63 +104,5 @@ class NscaCheck(models.Model): @api.multi def _send_nsca(self, rc, message, performance): - """Send the result of the check to the NSCA daemon.""" for check in self: - msg = message - if len(performance) > 0: - msg += '| ' + ''.join( - ["%s=%s%s;%s;%s;%s;%s" % ( - key, - performance[key]['value'], - performance[key].get('uom', ''), - performance[key].get('warn', ''), - performance[key].get('crit', ''), - performance[key].get('min', ''), - performance[key].get('max', ''), - ) for key in sorted(performance)]) - check_result = self._format_check_result(check, rc, msg) - cmd = self._prepare_command(check) - self._run_command(check, cmd, check_result) - - @api.model - def _format_check_result(self, check, rc, message): - """Format the check result with tabulations as delimiter.""" - message = message.replace('\t', ' ') - hostname = check.server_id.node_hostname - check_result = u"%s\t%s\t%s\t%s" % ( - hostname, check.service, rc, message) - return check_result.encode('utf-8') - - @api.model - def _prepare_command(self, check): - """Prepare the shell command used to send the check result - to the NSCA daemon. - """ - cmd = u"/usr/sbin/send_nsca -H %s -p %s -c %s" % ( - check.server_id.name, - check.server_id.port, - check.server_id.config_file_path) - return shlex.split(cmd) - - @api.model - def _run_command(self, check, cmd, check_result): - """Send the check result through the '/usr/sbin/send_nsca' command.""" - try: - proc = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.STDOUT) - stdout = proc.communicate( - input=check_result)[0] - _logger.debug("%s: %s", check_result, stdout.strip()) - except Exception as exc: - _logger.error(exc) - - def _check_send_nsca_command(self): - """Check if the NSCA client is installed.""" - if not is_exe(SEND_NSCA_BIN): - raise UserError( - _(u"Command '%s' not found. Please install the NSCA client.\n" - u"On Debian/Ubuntu: apt-get install nsca-client") % ( - SEND_NSCA_BIN)) + check.server_id._send_nsca(check.service, rc, message, performance) diff --git a/nsca_client/models/nsca_server.py b/nsca_client/models/nsca_server.py index 5fed760c8..39cc7f9e2 100644 --- a/nsca_client/models/nsca_server.py +++ b/nsca_client/models/nsca_server.py @@ -4,9 +4,22 @@ import psutil import os +import shlex +import subprocess +import logging -from odoo import api, fields, models +from odoo import api, fields, models, _ from odoo.tools import config +from odoo.exceptions import UserError + + +def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + +_logger = logging.getLogger(__name__) + +SEND_NSCA_BIN = '/usr/sbin/send_nsca' class NscaServer(models.Model): @@ -31,6 +44,14 @@ class NscaServer(models.Model): u"monitoring server.") check_ids = fields.One2many( 'nsca.check', 'server_id', string=u"Checks") + check_count = fields.Integer( + compute='_compute_check_count' + ) + + @api.depends('check_ids') + def _compute_check_count(self): + for r in self: + r.check_count = len(r.check_ids) def _selection_encryption_method(self): return [ @@ -141,3 +162,78 @@ class NscaServer(models.Model): }, } return 0, u"OK", performance + + @api.multi + def _prepare_command(self): + """Prepare the shell command used to send the check result + to the NSCA daemon. + """ + cmd = u"/usr/sbin/send_nsca -H %s -p %s -c %s" % ( + self.name, + self.port, + self.config_file_path) + return shlex.split(cmd) + + @api.model + def _run_command(self, cmd, check_result): + """Send the check result through the '/usr/sbin/send_nsca' command.""" + try: + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate( + input=check_result)[0] + _logger.debug("%s: %s", check_result, stdout.strip()) + except Exception as exc: + _logger.error(exc) + + def _check_send_nsca_command(self): + """Check if the NSCA client is installed.""" + if not is_exe(SEND_NSCA_BIN): + raise UserError( + _(u"Command '%s' not found. Please install the NSCA client.\n" + u"On Debian/Ubuntu: apt-get install nsca-client") % ( + SEND_NSCA_BIN)) + + def _format_check_result(self, service, rc, message): + """Format the check result with tabulations as delimiter.""" + message = message.replace('\t', ' ') + hostname = self.node_hostname + check_result = u"%s\t%s\t%s\t%s" % ( + hostname, service, rc, message) + return check_result.encode('utf-8') + + def _send_nsca(self, service, rc, message, performance): + """Send the result of the check to the NSCA daemon.""" + msg = message + if len(performance) > 0: + msg += '| ' + ''.join( + ["%s=%s%s;%s;%s;%s;%s" % ( + key, + performance[key]['value'], + performance[key].get('uom', ''), + performance[key].get('warn', ''), + performance[key].get('crit', ''), + performance[key].get('min', ''), + performance[key].get('max', ''), + ) for key in sorted(performance)]) + check_result = self._format_check_result( + service, rc, msg) + cmd = self._prepare_command() + self._run_command(cmd, check_result) + + @api.multi + def show_checks(self): + self.ensure_one() + action = self.env.ref('nsca_client.action_nsca_check_tree') + result = action.read()[0] + context = {'default_server_id': self.id} + result['context'] = context + result['domain'] = [('server_id', '=', self.id)] + if len(self.check_ids) == 1: + res = self.env.ref('nsca_client.view_nsca_check_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = self.check_ids.id + return result diff --git a/nsca_client/tests/test_nsca.py b/nsca_client/tests/test_nsca.py index bf797d561..99cd5b46f 100644 --- a/nsca_client/tests/test_nsca.py +++ b/nsca_client/tests/test_nsca.py @@ -68,7 +68,7 @@ class TestNsca(TransactionCase): check = self.env['nsca.check'].create({ 'server_id': server.id, 'service': 'test', - 'nsca_model': 'nsca.check', + 'nsca_model': 'nsca.server', 'allow_void_result': False, 'nsca_function': '_check_send_nsca_command' }) @@ -84,13 +84,20 @@ class TestNsca(TransactionCase): 'encryption_method': '3', 'node_hostname': 'odoodev', }) + self.assertEqual(server.check_count, 0) check = self.env['nsca.check'].create({ 'server_id': server.id, 'service': 'test', - 'nsca_model': 'nsca.check', + 'nsca_model': 'nsca.server', 'allow_void_result': True, 'nsca_function': '_check_send_nsca_command' }) + self.assertEqual(server.check_count, 1) + action = server.show_checks() + self.assertEqual(check, self.env['nsca.check'].browse( + action['res_id'])) + self.assertEqual(check, self.env['nsca.check'].search( + action['domain'])) with mock.patch('subprocess.Popen') as post: post.return_value = Popen self.env['nsca.check']._cron_check(check.id,) diff --git a/nsca_client/views/nsca_server.xml b/nsca_client/views/nsca_server.xml index 145ba0d35..4736a7dfc 100644 --- a/nsca_client/views/nsca_server.xml +++ b/nsca_client/views/nsca_server.xml @@ -11,6 +11,15 @@
+
+ +
@@ -21,9 +30,6 @@ - - -