branch develop updated (dc38845 -> 30f20df)
This is an automated email from the git hooks/post-receive script. New change to branch develop in repository mum. See http://git.chorem.org/mum.git from dc38845 notifications page : 'all' retiré de la liste des groupes + ajout de la sélection dans le titre new 30f20df envoi de notification par e-mail fonctionnel (sans prendre en compte le nombre d'ittérations) The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 30f20df0170bef36e2f6e809e05c8f9c70a53768 Author: Alexis Guilbaud <guilbaud@codelutin.com> Date: Tue Mar 24 11:41:21 2015 +0100 envoi de notification par e-mail fonctionnel (sans prendre en compte le nombre d'ittérations) Summary of changes: app/app.py | 2 + app/module_loader.py | 51 ++++++++++++---- app/modules/monitoring_modules/disk.py | 2 +- app/modules/monitoring_modules/memory.py | 2 +- app/modules/monitoring_modules/ping.py | 2 +- app/modules/monitoring_modules/updated_packages.py | 2 +- app/modules/notification_modules/email_notif.py | 29 +++++---- app/modules/storage_modules/shelve_db.py | 71 +++++++++++++++++----- install.sh | 3 + 9 files changed, 118 insertions(+), 46 deletions(-) -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
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 30f20df0170bef36e2f6e809e05c8f9c70a53768 Author: Alexis Guilbaud <guilbaud@codelutin.com> Date: Tue Mar 24 11:41:21 2015 +0100 envoi de notification par e-mail fonctionnel (sans prendre en compte le nombre d'ittérations) --- app/app.py | 2 + app/module_loader.py | 51 ++++++++++++---- app/modules/monitoring_modules/disk.py | 2 +- app/modules/monitoring_modules/memory.py | 2 +- app/modules/monitoring_modules/ping.py | 2 +- app/modules/monitoring_modules/updated_packages.py | 2 +- app/modules/notification_modules/email_notif.py | 29 +++++---- app/modules/storage_modules/shelve_db.py | 71 +++++++++++++++++----- install.sh | 3 + 9 files changed, 118 insertions(+), 46 deletions(-) diff --git a/app/app.py b/app/app.py index e1afd3a..be74737 100755 --- a/app/app.py +++ b/app/app.py @@ -183,6 +183,8 @@ if __name__ == '__main__': ml.load_all_detection_modules() ml.load_all_notification_modules() wsc = WebSocketContainer(ml.get_db()) + #dict_notif = ml.db.add_check('127.0.0.1', "ping", False) + #ml.run_notification_modules(dict_notif) process_monitoring.init(ml, wsc) port = int(os.environ.get('PORT', 1337)) run(host='0.0.0.0', port=port, debug=True, server=GeventWebSocketServer) diff --git a/app/module_loader.py b/app/module_loader.py index 9ee6ac4..97ce3be 100644 --- a/app/module_loader.py +++ b/app/module_loader.py @@ -22,16 +22,18 @@ class ModuleLoader: and contains several methods in order to call the methods once these modules loaded. """ def __init__(self, add_func, rem_func): - dict_conf = {} # See conf.txt + self.conf = {} # See conf.txt fconf = open('mum.conf', 'r') for line in fconf.read().splitlines(): fields = line.split('=') - dict_conf[fields[0]] = fields[1] + self.conf[fields[0]] = fields[1] fconf.close() + ''' self.db_loc = dict_conf['db_location'] self.external_mod_loc = dict_conf['external_modules_location'] self.public_keys_loc = dict_conf['keys_location'] - self.db = self.load_db(add_func, rem_func, self.public_keys_loc) + ''' + self.db = self.load_db(add_func, rem_func, self.conf['keys_location']) self.loaded_mod_moni = {} # See load_all_monitoring_modules self.loaded_mod_detect = {} # See load_all_detection_modules self.loaded_mod_conn = {} # See load_all_connection_modules @@ -44,14 +46,14 @@ class ModuleLoader: """ db_name = "shelve_db" db = __import__("modules.storage_modules." + db_name, fromlist=modules.storage_modules) - db_instance = getattr(db, db_name)(self.db_loc, add_func, rem_func, key_loc) + db_instance = getattr(db, db_name)(self.conf['db_location'], add_func, rem_func, key_loc) return db_instance def get_db(self): return self.db def get_public_keys_loc(self): - return self.public_keys_loc + return self.conf['keys_location'] @staticmethod def run_nmap_detection(param, opt, db, ws, list_mod_conn, dict_mod_monitoring): @@ -84,7 +86,7 @@ class ModuleLoader: mod_inst = getattr(self.loaded_mod_conn[conn['conn_mod_name']]['imported'], self.loaded_mod_conn[conn['conn_mod_name']]['class_name'])(addr_host, conn['args'], - self.public_keys_loc, + self.conf['keys_location'], modules.CommandNotFoundException) else: print "Error: no connection have been configured yet" @@ -152,8 +154,8 @@ class ModuleLoader: print "Error : internal monitoring module " + mod_name + " could not have been loaded. " # Now for external modules: - sys.path.insert(0, self.external_mod_loc) # Adding the external diretory into pythonpath - for importer, mod_name, ispkg in pkgutil.iter_modules([self.external_mod_loc]): + sys.path.insert(0, self.conf['external_modules_location']) # Adding the external diretory into pythonpath + for importer, mod_name, ispkg in pkgutil.iter_modules([self.conf['external_modules_location']]): if mod_name not in sys.modules: try: loaded_mod = __import__(mod_name, fromlist=[mod_name]) @@ -192,7 +194,8 @@ class ModuleLoader: self.loaded_mod_moni[mod_name]['class_name'])(conn, db, modules.ModuleNotCompatibleException) try: - mod_inst.check() + dict_notif = mod_inst.check() + self.run_notification_modules(dict_notif) except modules.ModuleNotCompatibleException.ModuleNotCompatibleException as mnce: print mnce.__str__() except modules.CommandNotFoundException.CommandNotFoundException as cnfe: @@ -302,11 +305,10 @@ class ModuleLoader: try: loaded_mod = __import__("modules.notification_modules." + mod_name, fromlist=[mod_name]) class_name = getattr(loaded_mod, "get_class_name")() - mod_inst = getattr(loaded_mod, class_name)(None, None) + mod_inst = getattr(loaded_mod, class_name)(None, None, None, None) infos_mod = {} infos_mod['imported'] = loaded_mod infos_mod['class_name'] = getattr(mod_inst, 'get_name')() - infos_mod['params'] = getattr(mod_inst, 'get_parameters')() self.loaded_mod_notif[mod_name] = infos_mod except AttributeError: print "Error : internal notification module " + mod_name + " could not have been loaded. " @@ -326,9 +328,32 @@ class ModuleLoader: """ res = {} for mod in self.loaded_mod_notif: - res[mod] = self.loaded_mod_notif[mod]['params'] + res[mod] = '' return json.dumps(res) + def run_notification_modules(self, dict_notif): + """ + Runs the notifications modules specified in the dict_notif parameter. (called by run_one_monitoring_module) + :param dict_notif: + { + notif_mod: [{'username': string, 'moni_mod': string, 'title': string, 'msg': string}, ...], + ... + } + :return: + """ + for notif_mod in dict_notif: + while len(dict_notif[notif_mod]) > 0: + instr = dict_notif[notif_mod].pop() + mod_inst = getattr(self.loaded_mod_notif[notif_mod]['imported'], + self.loaded_mod_notif[notif_mod]['class_name'])(instr['user'], + instr['title'], + instr['msg'], + self.conf) + try: + mod_inst.notify() + except KeyError: + print 'Missing setting for notification module ' + notif_mod + def update_global_conf(self): """ Asks the database to update the configuration if new monitoring modules are added in function of the @@ -364,4 +389,4 @@ class ModuleLoader: self.db.config_mod_activation(args, self.get_monitoring_modules_list()) def get_public_keys_list(self): - return json.dumps(os.listdir(self.public_keys_loc)) \ No newline at end of file + return json.dumps(os.listdir(self.conf['keys_location'])) \ No newline at end of file diff --git a/app/modules/monitoring_modules/disk.py b/app/modules/monitoring_modules/disk.py index 15c734c..93a1e32 100644 --- a/app/modules/monitoring_modules/disk.py +++ b/app/modules/monitoring_modules/disk.py @@ -51,4 +51,4 @@ class Disk: ) raise exception_inst res_check = int(disk_used) - self.db.add_check(self.conn.get_addr_host(), 'disk', res_check) \ No newline at end of file + return self.db.add_check(self.conn.get_addr_host(), 'disk', res_check) \ No newline at end of file diff --git a/app/modules/monitoring_modules/memory.py b/app/modules/monitoring_modules/memory.py index 521fcf8..87c69f6 100644 --- a/app/modules/monitoring_modules/memory.py +++ b/app/modules/monitoring_modules/memory.py @@ -50,4 +50,4 @@ class Memory: ) raise exception_inst res_check = memused * 100 / int(memtotal) - self.db.add_check(self.conn.get_addr_host(), "memory", res_check) \ No newline at end of file + return self.db.add_check(self.conn.get_addr_host(), "memory", res_check) \ No newline at end of file diff --git a/app/modules/monitoring_modules/ping.py b/app/modules/monitoring_modules/ping.py index f7467a8..b9ad35a 100644 --- a/app/modules/monitoring_modules/ping.py +++ b/app/modules/monitoring_modules/ping.py @@ -43,4 +43,4 @@ class Ping: except pexpect.TIMEOUT: res_check = False finally: - self.db.add_check(self.addr_host, "ping", res_check) \ No newline at end of file + return self.db.add_check(self.addr_host, "ping", res_check) \ No newline at end of file diff --git a/app/modules/monitoring_modules/updated_packages.py b/app/modules/monitoring_modules/updated_packages.py index 87953fd..d511039 100644 --- a/app/modules/monitoring_modules/updated_packages.py +++ b/app/modules/monitoring_modules/updated_packages.py @@ -31,4 +31,4 @@ class UpdatedPackages: stdout = self.conn.exec_command(cmd) tab_res = stdout.split(':') res_check = len(tab_res) <= 2 - self.db.add_check(self.conn.get_addr_host(), "updated_packages", res_check) \ No newline at end of file + return self.db.add_check(self.conn.get_addr_host(), "updated_packages", res_check) \ No newline at end of file diff --git a/app/modules/notification_modules/email_notif.py b/app/modules/notification_modules/email_notif.py index 09f495e..9769242 100644 --- a/app/modules/notification_modules/email_notif.py +++ b/app/modules/notification_modules/email_notif.py @@ -9,25 +9,24 @@ def get_class_name(): class EMail: - def __init__(self, msg, params): + def __init__(self, user_data, title, msg, settings): self.name = get_class_name() + self.user_data = user_data # {'email': val, ...} + self.title = title self.msg = msg - self.params = params - self.parameters = {"users": "dict", "smtp_server": "string"} # dict = {user: {'username': val, 'email'; val}} + self.settings = settings # = conf attribute on ModuleLoader class def get_name(self): return self.name - def get_parameters(self): - return self.parameters - def notify(self): - for user in self.params["users"]: - msg_to_send = MIMEText(self.msg) - msg_to_send['Subject'] = self.params["users"][user]['subject'] - msg_to_send['From'] = "mum@mum.com" - msg_to_send['To'] = self.params["users"][user]['email'] - - s = smtplib.SMTP(self.params['smtp_server']) - s.sendmail(msg_to_send['From'], [msg_to_send['To']], msg_to_send.as_string()) - s.quit() \ No newline at end of file + msg_to_send = MIMEText(self.msg) + msg_to_send['Subject'] = self.title + msg_to_send['From'] = self.settings['smtp_address'] + msg_to_send['To'] = self.user_data['email'] + if self.settings['smtp_port'] == '': + s = smtplib.SMTP(self.settings['smtp_server']) + else: + s = smtplib.SMTP(self.settings['smtp_server'], int(self.settings['smtp_port'])) + s.sendmail(msg_to_send['From'], [msg_to_send['To']], msg_to_send.as_string()) + s.quit() \ 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 15b9482..685f7c0 100644 --- a/app/modules/storage_modules/shelve_db.py +++ b/app/modules/storage_modules/shelve_db.py @@ -656,8 +656,13 @@ class shelve_db: :param addr_host: the IP adress of the host checked :param mod_name: the name of the monitoring_module which have done the check :param val: the value observed + :return: data that will be used to launch the notification modules in the form : + { + notif_mod: [{'username': string, 'moni_mod': string, 'title': string, 'msg': string}, ...], + ... + } """ - #failure = None + dict_notif = {} self.open_db() new_val = {"date": str(datetime.now()), "value": val} try: @@ -700,19 +705,9 @@ class shelve_db: and not state == 'danger': state = 'warning' self.db['hosts'][addr_host]['status']['state'] = state - # create a notify structure if the state is not a success - """ + # create a notification structure if the state is not a success if not new_val['state'] == 'success': - failure = {} - failure['addr_host'] = addr_host - failure['mod_name'] = mod_name - failure['state'] = new_val['state'] - failure['subscribers'] = {} - for subscriber in self.db['hosts'][addr_host]['conf']['subscribers']: - failure['subscribers'][subscriber] = {} - failure['subscribers'][subscriber][''] - failure['groups_to_notify'] = self.db['hosts'][addr_host]['conf']['groups'] - """ + dict_notif = self.create_notif_structure(addr_host, mod_name, new_val['state']) # now performing archiving """ if mod_name in self.db['hosts'][addr_host]['archive']: @@ -723,7 +718,7 @@ class shelve_db: print e.__str__() finally: self.close_db() - #return failure + return dict_notif def update_stats(self, stats, val): """ @@ -746,6 +741,53 @@ class shelve_db: stats['M2'] += stats['delta'] * (val - stats['mean']) return stats + def create_notif_structure(self, addr_host, moni_mod, status): + """ + Creates and returns a data structure that will be used by the notification modules + :param addr_host: the IP address of the host + :param moni_mod: the name of the monitoring module which have been launched + :param status: the status of the last check + :return: data that will be used to launch the notification modules in the form : + { + notif_mod: [{'user': dict, 'moni_mod': string, 'title': string, 'msg': string}, ...], + ... + } + """ + title = "[Mum] " + status + " on " + addr_host + msg = "Mum repported a " + status + " value by the " + moni_mod + " mod " + dict_notif = {} + notif_type = "" + if status == 'warning': + notif_type = 'minor' + else: + notif_type = 'major' + for username in self.db['hosts'][addr_host]['conf']['subscribers']: + # creates a message for all subscribers in the host + for notif_mod in self.db['hosts'][addr_host]['conf']['subscribers'][username][notif_type]: + #{'priority': int, 'activated': bool} + param_notif = self.db['hosts'][addr_host]['conf']['subscribers'][username][notif_type][notif_mod] + if param_notif['activated']: + if notif_mod not in dict_notif: + dict_notif[notif_mod] = [] + dict_notif[notif_mod].append({'user': self.db['users'][username]['settings'], + 'moni_mod': moni_mod, + 'title': "[Mum] " + status + " on " + addr_host, + 'msg': msg}) + for group in self.db['groups']: + # creates a message for all subscribers in a group which the host is member + if addr_host in self.db['groups'][group]: + for username in self.db['groups'][group]['subscribers']: + for notif_mod in self.db['groups'][group]['subscribers'][username][notif_type]: + param_notif = self.db['groups'][group]['subscribers'][username][notif_type][notif_mod] + if param_notif['activated']: + if notif_mod not in dict_notif: + dict_notif[notif_mod] = [] + dict_notif[notif_mod].append({'user': self.db['users'][username]['settings'], + 'moni_mod': moni_mod, + 'title': title, + 'msg': msg}) + return dict_notif + def add_host_list_to_group(self, args): """ Add given hosts to a group. If the group doesn't exists on the database, it will be created. @@ -900,6 +942,7 @@ class shelve_db: self.db['users'][username]['preferences']['minor_notifications'] = {} self.db['users'][username]['preferences']['major_notifications'] = {} self.db['users'][username]['account'] = {} + self.db['users'][username]['settings'] = {} except Exception as e: print e.__str__() finally: diff --git a/install.sh b/install.sh index 589c9be..090594e 100755 --- a/install.sh +++ b/install.sh @@ -14,6 +14,9 @@ touch mum.conf echo "db_location=$HOME/.mum/mum.db" >> mum.conf echo "external_modules_location=$HOME/.mum/external" >> mum.conf echo "keys_location=$HOME/.mum/keys/" >> mum.conf +echo "smtp_server=" >> mum.conf +echo "smtp_port=" >> mum.conf +echo "smtp_address=" >> mum.conf # creating the basic folders mkdir $HOME/.mum -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm