This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository mum. See http://git.chorem.org/mum.git commit 038fa24fcc81ccf7f5a64d9f7c5022e587429900 Author: Alexis Guilbaud <guilbaud@codelutin.com> Date: Mon Apr 20 17:43:34 2015 +0200 snmp monitoring modules implemented + hostpage : modal for confirmation of deletion of a host --- README | 11 +++- app/module_loader.py | 2 +- app/modules/connection_modules/snmp.py | 9 ++-- .../monitoring_modules/15_min_load_snmp_linux.py | 14 ++++++ app/modules/monitoring_modules/cpu_snmp_linux.py | 20 ++++++++ app/modules/monitoring_modules/disk_snmp_linux.py | 16 ++++++ .../monitoring_modules/memory_snmp_linux.py | 16 ++++++ app/modules/monitoring_modules/smtp.py | 18 +++++++ app/modules/monitoring_modules/swap_snmp_linux.py | 16 ++++++ app/modules/storage_modules/shelve_db.py | 8 +-- static/js/controllers/hostPageCtrl.js | 58 +++++++++++++++++----- views/hostpage.html | 46 +++++++++++++---- 12 files changed, 203 insertions(+), 31 deletions(-) diff --git a/README b/README index 757eed3..7821db3 100644 --- a/README +++ b/README @@ -40,6 +40,13 @@ all avaliable arguments, type : The service will be avaliable by default on 0.0.0.0:1337 +We recommand to parameter the default settings for each modules before adding any hosts. +The default parameters that will be applied are : +- minor limit at 90% and major limit at 98% for each "%" values +- major limit if down for boolean values +- minor limit at 8 and major limit at 10 for any other type of values +- a check frequency of 1 minute for every module. + --------- Updates --------- @@ -48,7 +55,9 @@ git pull bower install -edit local configuration file +./install.sh + +edit local configuration file by following the latest model remove database diff --git a/app/module_loader.py b/app/module_loader.py index eb95f05..8226bb2 100644 --- a/app/module_loader.py +++ b/app/module_loader.py @@ -317,7 +317,7 @@ class ModuleLoader: dict_deactivation_request['activated'] = {part_name: False} self.db.config_mod_activation(dict_deactivation_request) if not conn_found: - print "No necessary connection have been configured for " + part_name + " on " + addr_host +\ + print "No necessary connection have been properly configured for " + part_name + " on " + addr_host +\ ". Therefore it has been deactivated." process_monitoring.remove_to_waiting_list(addr_host, part_name) dict_deactivation_request = {} diff --git a/app/modules/connection_modules/snmp.py b/app/modules/connection_modules/snmp.py index 2541f62..79acf7b 100644 --- a/app/modules/connection_modules/snmp.py +++ b/app/modules/connection_modules/snmp.py @@ -2,6 +2,7 @@ __author__ = 'aguilbaud' from pysnmp.entity.rfc3413.oneliner import cmdgen + def get_class_name(): return "SNMP" @@ -9,6 +10,7 @@ def get_class_name(): class SNMP: def __init__(self, addr_host, params, key_loc, cnfe): self.parameters = {"port": "int"} + self.params_stored = params self.name = get_class_name() self.addr_host = addr_host self.known_port = 161 @@ -32,7 +34,7 @@ class SNMP: res = "" errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd( cmdgen.CommunityData('public'), - cmdgen.UdpTransportTarget((self.addr_host, self.parameters['port'])), + cmdgen.UdpTransportTarget((self.addr_host, int(self.params_stored['port']))), cmd ) @@ -44,8 +46,7 @@ class SNMP: print('%s at %s' % ( errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex)-1] or '?' - ) - ) + )) else: for name, val in varBinds: if val == "": @@ -54,7 +55,7 @@ class SNMP: ) raise exception_inst else: - res = val + res = val.prettyPrint() return res def disconnect(self): diff --git a/app/modules/monitoring_modules/15_min_load_snmp_linux.py b/app/modules/monitoring_modules/15_min_load_snmp_linux.py new file mode 100644 index 0000000..4275b85 --- /dev/null +++ b/app/modules/monitoring_modules/15_min_load_snmp_linux.py @@ -0,0 +1,14 @@ +# -*- coding: utf8 -*- +__author__ = 'aguilbaud' + +compatible_os = ['linux'] +block = "hardware" +part = "min_15_load" +unit = "" +connection = "snmp" + + +def check(conn, db, mnce): + oid = ".1.3.6.1.4.1.2021.10.1.3.3" + load = float(conn.exec_command(oid)) + return db.add_check(conn.get_addr_host(), part, load) \ No newline at end of file diff --git a/app/modules/monitoring_modules/cpu_snmp_linux.py b/app/modules/monitoring_modules/cpu_snmp_linux.py new file mode 100644 index 0000000..e17f638 --- /dev/null +++ b/app/modules/monitoring_modules/cpu_snmp_linux.py @@ -0,0 +1,20 @@ +# -*- coding: utf8 -*- +__author__ = 'aguilbaud' + +compatible_os = ['linux'] +block = "hardware" +part = "cpu" +unit = "%" +connection = "snmp" + + +def check(conn, db, mnce): + """ + Check the greatest between the user and system CPU charge + """ + oid = ".1.3.6.1.4.1.2021.11.9.0" + user_cpu_charge = int(conn.exec_command(oid)) + oid = ".1.3.6.1.4.1.2021.11.10.0" + system_cpu_charge = int(conn.exec_command(oid)) + res_cpu = max(user_cpu_charge, system_cpu_charge) + return db.add_check(conn.get_addr_host(), part, res_cpu) \ No newline at end of file diff --git a/app/modules/monitoring_modules/disk_snmp_linux.py b/app/modules/monitoring_modules/disk_snmp_linux.py new file mode 100644 index 0000000..d5a584a --- /dev/null +++ b/app/modules/monitoring_modules/disk_snmp_linux.py @@ -0,0 +1,16 @@ +__author__ = 'aguilbaud' + +compatible_os = ['linux'] +block = "hardware" +part = "disk" +unit = "%" +connection = "snmp" + + +def check(conn, db, mnce): + oid = ".1.3.6.1.4.1.2021.9.1.7.1" + total_space_on_disk = float(conn.exec_command(oid)) + oid = ".1.3.6.1.4.1.2021.9.1.8.1" + disk_used = float(conn.exec_command(oid)) + percent_disk_used = round((disk_used * 100) / total_space_on_disk, 2) + return db.add_check(conn.get_addr_host(), part, percent_disk_used) \ No newline at end of file diff --git a/app/modules/monitoring_modules/memory_snmp_linux.py b/app/modules/monitoring_modules/memory_snmp_linux.py new file mode 100644 index 0000000..9459346 --- /dev/null +++ b/app/modules/monitoring_modules/memory_snmp_linux.py @@ -0,0 +1,16 @@ +__author__ = 'aguilbaud' + +compatible_os = ['linux'] +block = "hardware" +part = "memory" +unit = "%" +connection = "snmp" + + +def check(conn, db, mnce): + oid = ".1.3.6.1.4.1.2021.4.5.0" + total_mem = float(conn.exec_command(oid)) + oid = ".1.3.6.1.4.1.2021.4.6.0" + mem_used = float(conn.exec_command(oid)) + percent_mem_used = round((mem_used * 100) / total_mem, 2) + return db.add_check(conn.get_addr_host(), part, percent_mem_used) \ No newline at end of file diff --git a/app/modules/monitoring_modules/smtp.py b/app/modules/monitoring_modules/smtp.py new file mode 100644 index 0000000..80cb00f --- /dev/null +++ b/app/modules/monitoring_modules/smtp.py @@ -0,0 +1,18 @@ +__author__ = 'aguilbaud' + +import smtplib + +compatible_os = ["all"] +block = "network" +part = "smtp" +unit = "bool" +connection = "" + +def check(db, addr_host, smtp_port): + res_smtp_check = True + try: + s = smtplib.SMTP(addr_host, smtp_port) + except Exception: + res_smtp_check = False + finally: + return db.add_check(addr_host, part, res_smtp_check) \ No newline at end of file diff --git a/app/modules/monitoring_modules/swap_snmp_linux.py b/app/modules/monitoring_modules/swap_snmp_linux.py new file mode 100644 index 0000000..cbb60a8 --- /dev/null +++ b/app/modules/monitoring_modules/swap_snmp_linux.py @@ -0,0 +1,16 @@ +__author__ = 'aguilbaud' + +compatible_os = ['linux'] +block = "hardware" +part = "swap" +unit = "%" +connection = "snmp" + + +def check(conn, db, mnce): + oid = ".1.3.6.1.4.1.2021.4.3.0" + total_swap = float(conn.exec_command(oid)) + oid = ".1.3.6.1.4.1.2021.4.4.0" + swap_used = total_swap - float(conn.exec_command(oid)) + percent_swap_used = round( (swap_used * 100) / total_swap, 2) + return db.add_check(conn.get_addr_host(), part, percent_swap_used) \ No newline at end of file diff --git a/app/modules/storage_modules/shelve_db.py b/app/modules/storage_modules/shelve_db.py index acecdd2..23c3a32 100644 --- a/app/modules/storage_modules/shelve_db.py +++ b/app/modules/storage_modules/shelve_db.py @@ -89,8 +89,8 @@ class shelve_db: unit = loaded_mod_moni[mod]['unit'] mod_conf['unit'] = unit if unit == '%': - mod_conf['minor_limit'] = 95 - mod_conf['major_limit'] = 100 + mod_conf['minor_limit'] = 90 + mod_conf['major_limit'] = 98 elif unit == 'bool': mod_conf['minor_limit'] = False mod_conf['major_limit'] = True @@ -854,8 +854,10 @@ class shelve_db: ... } """ - title = "[Mum] " + status + " for " + addr_host + title = "[Mum] " + status + " for " + addr_host + " " + moni_mod msg = "Mum reported a " + status + " value from the " + moni_mod + " module. " + msg += "The following users will be notified: " + msg += self.db['hosts'][addr_host]['subscribers'] dict_notif = {} notif_type = "" if status == 'warning': diff --git a/static/js/controllers/hostPageCtrl.js b/static/js/controllers/hostPageCtrl.js index 8a86c2a..b7f3e4c 100644 --- a/static/js/controllers/hostPageCtrl.js +++ b/static/js/controllers/hostPageCtrl.js @@ -72,6 +72,17 @@ mumApp.controller('hostPageCtrl', function($scope, $rootScope, $route, $routePar return res } + $scope.popover_message = function(){ + msg = ""; + if($scope.items.status == "idling"){ + msg = "Click to activate again the monitoring for this host."; + } + else{ + msg = "Click to suspend the monitoring for this host."; + } + return msg + } + $scope.$on("resCall", function (event, args) { if(args.func == 'update_os_name'){ $route.reload(); @@ -133,13 +144,6 @@ mumApp.controller('hostPageCtrl', function($scope, $rootScope, $route, $routePar $rootScope.$broadcast("sendViaWs", JSON.stringify({"GET_HOST_INFO": $scope.addr_host})); }); - $scope.$on("remHost", function (event, args) { - $timeout(function() { - $rootScope.$broadcast("sendViaWs", JSON.stringify({"GET_HOSTS": ""})); - $location.path('/'); - }, 0); - }); - // save custom informations $scope.save_custom_infos = function(){ var args = {}; @@ -148,12 +152,6 @@ mumApp.controller('hostPageCtrl', function($scope, $rootScope, $route, $routePar $rootScope.$broadcast("sendViaWs", JSON.stringify({"CALL_FUNC_DB": {'func': 'update_custom_informations', 'args': args}})); }; - $scope.remove_host = function(){ - var args = {}; - args['addr_host'] = $scope.addr_host; - $rootScope.$broadcast("sendViaWs", JSON.stringify({"REM_HOST": args})); - }; - // creation of modals $scope.open_modal_conf = function (mod_name) { var modalInstance = $modal.open({ @@ -206,6 +204,18 @@ mumApp.controller('hostPageCtrl', function($scope, $rootScope, $route, $routePar } }); }; + + $scope.open_modal_confirm_delete = function () { + var modalInstance = $modal.open({ + templateUrl: 'modal_confirm_delete_label.html', + controller: 'ModalConfirmDeleteInstanceCtrl', + resolve: { + confirm_delete_args: function(){ + return {'addr_host' : $scope.addr_host}; + } + } + }); + }; }); // modals controllers @@ -560,4 +570,26 @@ mumApp.controller('ModalBlockInstanceCtrl', function ($scope, $rootScope, $modal $scope.cancel = function () { $modalInstance.close(); }; +}); + +mumApp.controller('ModalConfirmDeleteInstanceCtrl', function ($scope, $rootScope, $modalInstance, $location, $timeout, confirm_delete_args) { + $scope.confirm_delete_args = confirm_delete_args; + + $scope.ok = function () { + var args = {}; + args['addr_host'] = $scope.confirm_delete_args.addr_host; + $rootScope.$broadcast("sendViaWs", JSON.stringify({"REM_HOST": args})); + }; + + $scope.$on("remHost", function (event, args) { + $timeout(function() { + $rootScope.$broadcast("sendViaWs", JSON.stringify({"GET_HOSTS": ""})); + $location.path('/'); + $modalInstance.close(); + }, 0); + }); + + $scope.cancel = function () { + $modalInstance.close(); + }; }); \ No newline at end of file diff --git a/views/hostpage.html b/views/hostpage.html index ce5b837..cc79503 100644 --- a/views/hostpage.html +++ b/views/hostpage.html @@ -1,20 +1,32 @@ <div class="col-md-offset-2 main"> - <h1 class="page-header">Current state of {{addr_host}} <small>{{items.hostname}}</small> + <h1 class="page-header">Current state of {{addr_host}} <small>{{items.hostname}} <button type="button" class="btn btn-{{get_idle_state()}}" aria-label="Button activation" + style="" + popover-placement="bottom" + popover="{{popover_message()}}" + popover-trigger="mouseenter" ng-click="set_idle_state()"> <span class="glyphicon glyphicon-off" aria-hidden="true"></span> - </button></h1> + </button></small></h1> <button type="button" class="btn btn-primary btn-xs" ng-click="open_modal_block()" - popover="Activate or deactivate monitoring modules by block." + popover="Activate or deactivate monitoring modules by section." popover-trigger="mouseenter" ng-disabled="items.status == 'idling'">Activate/Deactivate</button> - <button type="button" class="btn btn-primary btn-xs" ng-click="open_modal_conn()">Connection settings</button> - <button type="button" class="btn btn-info btn-xs" ng-click="launch_detection()">Launch a full detection</button> - <button type="button" class="btn btn-danger btn-xs" ng-click="remove_host()">Remove this host</button> + <button type="button" + class="btn btn-primary btn-xs" + ng-click="open_modal_conn()">Connection settings</button> + <button type="button" + class="btn btn-info btn-xs" + ng-click="launch_detection()" + popover="Needs SSH to be configured" + popover-trigger="mouseenter">Launch a full detection</button> + <button type="button" + class="btn btn-danger btn-xs" + ng-click="open_modal_confirm_delete()">Remove this host</button> <table class="table table-condensed table-hover" ng-show="items.status != 'idling'"> <thead> @@ -29,8 +41,8 @@ <tbody> <tr ng-repeat="(itemname, item) in items.monitoring" - class={{item.state}}> - <!--ng-show="items.activated_monitoring[itemname]"--> + class={{item.state}} + ng-show="items.activated_monitoring[itemname]"> <td>{{itemname}}</td> <td>{{item.value}} {{get_unit(itemname)}}</td> <td>{{item.state}}</td> @@ -198,7 +210,8 @@ <div class="modal-body"> <form> <div class="form-group"> - <h3>Choose the priority of each avaliable connection. The highest will be used first.</h3> + <h3>Choose the priority of each avaliable connection. The highest will be used first. + Set at 0 to not use this connection.</h3> <table class="table table-bordered table-hover"> <thead> <tr> @@ -320,4 +333,19 @@ ng-click="ok()">Save changes</button> </div> </script> + + <script type="text/ng-template" id="modal_confirm_delete_label.html"> + <div class="modal-header"> + <h3 class="modal-title">Are you sure you want to delete {{confirm_delete_args.addr_host}} ?</h3> + </div> + <div class="modal-body"> + <p>This action will be permanent.</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal" + ng-click="cancel()">Close</button> + <button type="button" class="btn btn-danger" + ng-click="ok()">Delete this host</button> + </div> + </script> </div> \ No newline at end of file -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.