def operation(self): expired_or_expiring = yield self.pgp_validation_check() admin_user = yield admin_serialize_user('admin') node_desc = yield admin_serialize_node(admin_user['language']) notification_settings = yield get_notification(admin_user['language']) if expired_or_expiring: yield self.send_admin_pgp_alerts(node_desc, admin_user, notification_settings, expired_or_expiring) for receiver_desc in expired_or_expiring: yield self.send_pgp_alerts(node_desc, receiver_desc, notification_settings)
def send_pgp_alerts(self, receiver_desc): user_language = receiver_desc["language"] node_desc = yield admin_serialize_node(user_language) notification_settings = yield get_notification(user_language) fakeevent = OD() fakeevent.type = u"pgp_expiration_alert" fakeevent.node_info = node_desc fakeevent.context_info = None fakeevent.receiver_info = receiver_desc fakeevent.tip_info = None fakeevent.subevent_info = None subject = Templating().format_template(notification_settings["pgp_alert_mail_title"], fakeevent) body = Templating().format_template(notification_settings["pgp_alert_mail_template"], fakeevent) yield sendmail(receiver_desc["mail_address"], subject, body)
def send_pgp_alerts(self, receiver_desc): user_language = receiver_desc['language'] node_desc = yield admin_serialize_node(user_language) notification_settings = yield get_notification(user_language) fakeevent = OD() fakeevent.type = u'pgp_expiration_alert' fakeevent.node_info = node_desc fakeevent.context_info = None fakeevent.receiver_info = receiver_desc fakeevent.tip_info = None fakeevent.subevent_info = None subject = Templating().format_template( notification_settings['pgp_alert_mail_title'], fakeevent) body = Templating().format_template( notification_settings['pgp_alert_mail_template'], fakeevent) yield sendmail(receiver_desc['mail_address'], subject, body)
def send_admin_pgp_alerts(self, admin_desc, expired_or_expiring): user_language = admin_desc["language"] node_desc = yield admin_serialize_node(user_language) notification_settings = yield get_notification(user_language) fakeevent = OD() fakeevent.type = u"admin_pgp_expiration_alert" fakeevent.node_info = node_desc fakeevent.context_info = None fakeevent.receiver_info = None fakeevent.tip_info = None fakeevent.subevent_info = {"expired_or_expiring": expired_or_expiring} subject = Templating().format_template(notification_settings["admin_pgp_alert_mail_title"], fakeevent) body = Templating().format_template(notification_settings["admin_pgp_alert_mail_template"], fakeevent) admin_users = yield get_admin_users() for u in admin_users: yield sendmail(u["mail_address"], subject, body)
def send_admin_pgp_alerts(self, admin_desc, expired_or_expiring): user_language = admin_desc['language'] node_desc = yield admin_serialize_node(user_language) notification_settings = yield get_notification(user_language) fakeevent = OD() fakeevent.type = u'admin_pgp_expiration_alert' fakeevent.node_info = node_desc fakeevent.context_info = None fakeevent.receiver_info = None fakeevent.tip_info = None fakeevent.subevent_info = {'expired_or_expiring': expired_or_expiring} subject = Templating().format_template( notification_settings['admin_pgp_alert_mail_title'], fakeevent) body = Templating().format_template( notification_settings['admin_pgp_alert_mail_template'], fakeevent) admin_users = yield get_admin_users() for u in admin_users: yield sendmail(u['mail_address'], subject, body)
def post(self, rtip_id): files_dict = yield download_all_files(self.current_user.user_id, rtip_id) node_dict = yield node.admin_serialize_node(self.request.language) receiver_dict = yield get_receiver_from_rtip(rtip_id, self.request.language) rtip_dict = yield get_rtip_info(rtip_id, self.request.language) collection_tip_dict = yield get_collection_info(rtip_id) context_dict = yield context.get_context(rtip_dict['context_id'], 'en') notif_dict = yield notification.get_notification(self.request.language) mock_event = Event( type=u'archive_description', trigger='Download', node_info=node_dict, receiver_info=receiver_dict, context_info=context_dict, tip_info=rtip_dict, subevent_info=collection_tip_dict, do_mail=False, ) formatted_coll = Templating().format_template(notif_dict['archive_description'], mock_event).encode('utf-8') files_dict.append( { 'buf': formatted_coll, 'name': "COLLECTION_INFO.txt" } ) self.set_status(200) self.set_header('X-Download-Options', 'noopen') self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment; filename=\"collection.zip\"') for data in ZipStream(files_dict): self.write(data) self.finish()
def admin_alarm_notification(event_matrix): """ This function put a mail in queue for the Admin, if the Admin notification is disable or if another Anomaly has been raised in the last 15 minutes, email is not send. """ # import here in order to avoid circular import error from globaleaks.handlers.admin.notification import get_notification do_not_stress_admin_with_more_than_an_email_after_minutes = 15 @transact_ro def _get_node_admin_email(store): node = store.find(models.Node).one() return node.email @transact_ro def _get_admin_user_language(store): admin_user = store.find(models.User, models.User.username == u'admin').one() return admin_user.language @transact_ro def _get_message_template(store): admin_user = store.find(models.User, models.User.username == u'admin').one() notif = store.find(models.Notification).one() template = notif.admin_anomaly_template if admin_user.language in template: return template[admin_user.language] elif GLSetting.memory_copy.language in template: return template[GLSetting.memory_copy.language] else: raise Exception("Cannot find any language for admin notification") def _activity_alarm_level(): return "%s" % Alarm.stress_levels['activity'] def _activity_dump(): retstr = "" for event, amount in event_matrix.iteritems(): retstr = "%s: %d\n%s" % (event, amount, retstr) return retstr def _disk_alarm_level(): return "%s" % Alarm.stress_levels['disk_space'] def _disk_dump(): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace) def _disk_status_message(): if Alarm.stress_levels['disk_message']: return unicode(Alarm.stress_levels['disk_message']) else: return "Disk space OK" @transact_ro def _node_name(store): node = store.find(models.Node).one() return unicode(node.name) KeyWordTemplate = { "%ActivityAlarmLevel%": _activity_alarm_level, "%ActivityDump%": _activity_dump, "%DiskAlarmLevel%": _disk_alarm_level, "%DiskDump%": _disk_dump, "%DiskErrorMessage%": _disk_status_message, "%NodeName%": _node_name } # ------------------------------------------------------------------ # Here start the Anomaly Notification code, before checking if we have to send email if not (Alarm.stress_levels['activity'] or Alarm.stress_levels['disk_space']): # lucky, no stress activities recorded: no mail needed defer.returnValue(None) if not GLSetting.memory_copy.admin_notif_enable: # event_matrix is {} if we are here only for disk log.debug("Anomaly to be reported %s, but Admin has Notification disabled" % "[%s]" % event_matrix if event_matrix else "") defer.returnValue(None) if Alarm.last_alarm_email: if not is_expired(Alarm.last_alarm_email, minutes=do_not_stress_admin_with_more_than_an_email_after_minutes): log.debug("Alert email want be send, but the threshold of %d minutes is not yet reached since %s" % ( do_not_stress_admin_with_more_than_an_email_after_minutes, datetime_to_ISO8601(Alarm.last_alarm_email))) defer.returnValue(None) # and now, processing the template message = yield _get_message_template() for keyword, templ_funct in KeyWordTemplate.iteritems(): where = message.find(keyword) if where == -1: continue # based on the type of templ_funct, we've to use 'yield' or not # cause some returns a deferred. if isinstance(templ_funct, type(sendmail)): content = templ_funct() else: content = yield templ_funct() message = "%s%s%s" % ( message[:where], content, message[where + len(keyword):]) admin_email = yield _get_node_admin_email() admin_language = yield _get_admin_user_language() notification_settings = yield get_notification(admin_language) message = MIME_mail_build(GLSetting.memory_copy.notif_source_email, GLSetting.memory_copy.notif_source_email, admin_email, admin_email, notification_settings['admin_anomaly_mail_title'], message) log.debug('Alarm Email for admin (%s): connecting to [%s:%d], ' 'the next mail should be in %d minutes' % (event_matrix, GLSetting.memory_copy.notif_server, GLSetting.memory_copy.notif_port, do_not_stress_admin_with_more_than_an_email_after_minutes)) Alarm.last_alarm_email = datetime_now()
def admin_alarm_generate_mail(event_matrix): """ This function put a mail in queue for the Admin, if the Admin notification is disable or if another Anomaly has been raised in the last 15 minutes, email is not send. """ do_not_stress_admin_with_more_than_an_email_every_minutes = 120 # if emergency is set to True, the previous time check is ignored. emergency_notification = False @transact_ro def _get_node_admin_email(store): node = store.find(models.Node).one() return node.email @transact_ro def _get_admin_user_language(store): admin_user = store.find(models.User, models.User.username == u'admin').one() return admin_user.language # THE THREE FUNCTIONS BELOW ARE POORLY SUBOPTIMAL, # AND THIS IS BAD: REFACTOR TO BE DONE ON THIS SUBJECT @transact_ro def _get_message_template(store): admin_user = store.find(models.User, models.User.username == u'admin').one() notif = store.find(models.Notification).one() template = notif.admin_anomaly_mail_template if admin_user.language in template: localized_template = template[admin_user.language] elif GLSettings.memory_copy.default_language in template: localized_template = template[GLSettings.memory_copy.default_language] else: raise Exception("Cannot find any language for admin notification") return localized_template @transact_ro def _disk_anomaly_detail(store): # This happen all the time anomalies are present but disk is ok if Alarm.stress_levels['disk_space'] == 0: return u'' admin_user = store.find(models.User, models.User.username == u'admin').one() notif = store.find(models.Notification).one() if Alarm.stress_levels['disk_space'] == 1: template = notif.admin_anomaly_disk_low elif Alarm.stress_levels['disk_space'] == 2: template = notif.admin_anomaly_disk_medium elif Alarm.stress_levels['disk_space'] == 3: template = notif.admin_anomaly_disk_high else: raise Exception("Invalid disk stess level %d" % Alarm.stress_levels['disk_space']) if admin_user.language in template: localized_template = template[admin_user.language] elif GLSettings.memory_copy.default_language in template: localized_template = template[GLSettings.memory_copy.default_language] else: raise Exception("Cannot find any language for Admin disk alarm (level %d)" % Alarm.stress_levels['disk_space']) return localized_template @transact_ro def _activities_anomaly_detail(store): # This happen all the time there is not anomalous traffic if Alarm.stress_levels['activity'] == 0: return u'' admin_user = store.find(models.User, models.User.username == u'admin').one() notif = store.find(models.Notification).one() template = notif.admin_anomaly_activities if admin_user.language in template: localized_template = template[admin_user.language] elif GLSettings.memory_copy.default_language in template: localized_template = template[GLSettings.memory_copy.default_language] else: raise Exception("Cannot find any language for admin notification") return localized_template # END OF THE SUB-OPTIMAL SECTION OF CODE THAT HAS TO BE RESTRUCTURED def _activity_alarm_level(): return "%s" % Alarm.stress_levels['activity'] def _activity_dump(): retstr = "" for event, amount in event_matrix.iteritems(): if not amount: continue retstr = "%s%s%d\n%s" % \ (event, (25 - len(event)) * " ", amount, retstr) return retstr @transact_ro def _node_name(store): node = store.find(models.Node).one() return unicode(node.name) def _free_disk_space(): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace) def _total_disk_space(): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace) def _notification_suppressed(): if Alarm.stress_levels['notification'] == []: return u'' emergency_notification = True return "** %s **" % Alarm.stress_levels['notification'] KeyWordTemplate = { "%AnomalyDetailDisk%": _disk_anomaly_detail, "%AnomalyDetailActivities%": _activities_anomaly_detail, "%ActivityAlarmLevel%": _activity_alarm_level, "%ActivityDump%": _activity_dump, "%NotificationSuppressed%": _notification_suppressed, "%NodeName%": _node_name, "%FreeMemory%": _free_disk_space, "%TotalMemory%": _total_disk_space, } # ------------------------------------------------------------------ # Independently from the event_matrix, the status of the stress level can # be in non-0 value. # Here start the Anomaly Notification code, before checking if we have to send email if not (Alarm.stress_levels['activity'] or Alarm.stress_levels['disk_space'] or Alarm.stress_levels['notification']): # lucky, no stress activities recorded: no mail needed defer.returnValue(None) if GLSettings.memory_copy.disable_admin_notification_emails: # event_matrix is {} if we are here only for disk log.debug("Anomaly to be reported %s, but Admin has Notification disabled" % "[%s]" % event_matrix if event_matrix else "") defer.returnValue(None) if Alarm.last_alarm_email and not emergency_notification: if not is_expired(Alarm.last_alarm_email, minutes=do_not_stress_admin_with_more_than_an_email_every_minutes): defer.returnValue(None) # This is skipped then: log.debug("Alert [%s] want be sent, but the threshold of %d minutes still unexpired %s" % ( Alarm.stress_levels, do_not_stress_admin_with_more_than_an_email_every_minutes, datetime_to_ISO8601(Alarm.last_alarm_email))) admin_email = yield _get_node_admin_email() admin_language = yield _get_admin_user_language() notification_settings = yield get_notification(admin_language) # and now, processing the template message = yield _get_message_template() message_title = notification_settings['admin_anomaly_mail_title'] recursion_time = 2 # since the ActivityDetails, we've to manage recursion while recursion_time: recursion_time -= 1 for keyword, templ_funct in KeyWordTemplate.iteritems(): where = message.find(keyword) if where == -1: continue # based on the type of templ_funct, we've to use 'yield' or not # cause some returns a deferred. if isinstance(templ_funct, type(sendmail)): content = templ_funct() else: content = yield templ_funct() message = "%s%s%s" % ( message[:where], content, message[where + len(keyword):]) # message title, we can't put the loop together at the moment for keyword, templ_funct in KeyWordTemplate.iteritems(): where = message_title.find(keyword) if where == -1: continue if isinstance(templ_funct, type(sendmail)): content = templ_funct() else: content = yield templ_funct() message_title = "%s%s%s" % ( message_title[:where], content, message_title[where + len(keyword):]) message = MIME_mail_build(GLSettings.memory_copy.notif_source_name, GLSettings.memory_copy.notif_source_email, admin_email, admin_email, message_title, message) log.debug('Alarm Email generated for Admin (%s): connecting to [%s:%d], ' 'the next mail should be in %d minutes' % (event_matrix, GLSettings.memory_copy.notif_server, GLSettings.memory_copy.notif_port, do_not_stress_admin_with_more_than_an_email_every_minutes)) defer.returnValue({ 'admin_email': admin_email, 'message': message, })
def admin_alarm_generate_mail(event_matrix): """ This function put a mail in queue for the Admin, if the Admin notification is disable or if another Anomaly has been raised in the last 15 minutes, email is not send. """ do_not_stress_admin_with_more_than_an_email_every_minutes = 120 # if emergency is set to True, the previous time check is ignored. emergency_notification = False @transact_ro def _get_node_admin_email(store): node = store.find(models.Node).one() return node.email @transact_ro def _get_admin_user_language(store): admin_user = store.find(models.User, models.User.username == u'admin').one() return admin_user.language # THE THREE FUNCTIONS BELOW ARE POORLY SUBOPTIMAL, # AND THIS IS BAD: REFACTOR TO BE DONE ON THIS SUBJECT @transact_ro def _get_message_template(store): admin_user = store.find(models.User, models.User.username == u'admin').one() notif = store.find(models.Notification).one() template = notif.admin_anomaly_mail_template if admin_user.language in template: localized_template = template[admin_user.language] elif GLSettings.memory_copy.default_language in template: localized_template = template[ GLSettings.memory_copy.default_language] else: raise Exception( "Cannot find any language for admin notification") return localized_template @transact_ro def _disk_anomaly_detail(store): # This happen all the time anomalies are present but disk is ok if Alarm.stress_levels['disk_space'] == 0: return u'' admin_user = store.find(models.User, models.User.username == u'admin').one() notif = store.find(models.Notification).one() if Alarm.stress_levels['disk_space'] == 1: template = notif.admin_anomaly_disk_low elif Alarm.stress_levels['disk_space'] == 2: template = notif.admin_anomaly_disk_medium elif Alarm.stress_levels['disk_space'] == 3: template = notif.admin_anomaly_disk_high else: raise Exception("Invalid disk stess level %d" % Alarm.stress_levels['disk_space']) if admin_user.language in template: localized_template = template[admin_user.language] elif GLSettings.memory_copy.default_language in template: localized_template = template[ GLSettings.memory_copy.default_language] else: raise Exception( "Cannot find any language for Admin disk alarm (level %d)" % Alarm.stress_levels['disk_space']) return localized_template @transact_ro def _activities_anomaly_detail(store): # This happen all the time there is not anomalous traffic if Alarm.stress_levels['activity'] == 0: return u'' admin_user = store.find(models.User, models.User.username == u'admin').one() notif = store.find(models.Notification).one() template = notif.admin_anomaly_activities if admin_user.language in template: localized_template = template[admin_user.language] elif GLSettings.memory_copy.default_language in template: localized_template = template[ GLSettings.memory_copy.default_language] else: raise Exception( "Cannot find any language for admin notification") return localized_template # END OF THE SUB-OPTIMAL SECTION OF CODE THAT HAS TO BE RESTRUCTURED def _activity_alarm_level(): return "%s" % Alarm.stress_levels['activity'] def _activity_dump(): retstr = "" for event, amount in event_matrix.iteritems(): if not amount: continue retstr = "%s%s%d\n%s" % \ (event, (25 - len(event)) * " ", amount, retstr) return retstr @transact_ro def _node_name(store): node = store.find(models.Node).one() return unicode(node.name) def _free_disk_space(): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace) def _total_disk_space(): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace) def _notification_suppressed(): if Alarm.stress_levels['notification'] == []: return u'' emergency_notification = True return "** %s **" % Alarm.stress_levels['notification'] KeyWordTemplate = { "%AnomalyDetailDisk%": _disk_anomaly_detail, "%AnomalyDetailActivities%": _activities_anomaly_detail, "%ActivityAlarmLevel%": _activity_alarm_level, "%ActivityDump%": _activity_dump, "%NotificationSuppressed%": _notification_suppressed, "%NodeName%": _node_name, "%FreeMemory%": _free_disk_space, "%TotalMemory%": _total_disk_space, } # ------------------------------------------------------------------ # Independently from the event_matrix, the status of the stress level can # be in non-0 value. # Here start the Anomaly Notification code, before checking if we have to send email if not (Alarm.stress_levels['activity'] or Alarm.stress_levels['disk_space'] or Alarm.stress_levels['notification']): # lucky, no stress activities recorded: no mail needed defer.returnValue(None) if GLSettings.memory_copy.disable_admin_notification_emails: # event_matrix is {} if we are here only for disk log.debug( "Anomaly to be reported %s, but Admin has Notification disabled" % "[%s]" % event_matrix if event_matrix else "") defer.returnValue(None) if Alarm.last_alarm_email and not emergency_notification: if not is_expired( Alarm.last_alarm_email, minutes= do_not_stress_admin_with_more_than_an_email_every_minutes): defer.returnValue(None) # This is skipped then: log.debug( "Alert [%s] want be sent, but the threshold of %d minutes still unexpired %s" % (Alarm.stress_levels, do_not_stress_admin_with_more_than_an_email_every_minutes, datetime_to_ISO8601(Alarm.last_alarm_email))) admin_email = yield _get_node_admin_email() admin_language = yield _get_admin_user_language() notification_settings = yield get_notification(admin_language) # and now, processing the template message = yield _get_message_template() message_title = notification_settings['admin_anomaly_mail_title'] recursion_time = 2 # since the ActivityDetails, we've to manage recursion while recursion_time: recursion_time -= 1 for keyword, templ_funct in KeyWordTemplate.iteritems(): where = message.find(keyword) if where == -1: continue # based on the type of templ_funct, we've to use 'yield' or not # cause some returns a deferred. if isinstance(templ_funct, type(sendmail)): content = templ_funct() else: content = yield templ_funct() message = "%s%s%s" % (message[:where], content, message[where + len(keyword):]) # message title, we can't put the loop together at the moment for keyword, templ_funct in KeyWordTemplate.iteritems(): where = message_title.find(keyword) if where == -1: continue if isinstance(templ_funct, type(sendmail)): content = templ_funct() else: content = yield templ_funct() message_title = "%s%s%s" % (message_title[:where], content, message_title[where + len(keyword):]) message = MIME_mail_build(GLSettings.memory_copy.notif_source_name, GLSettings.memory_copy.notif_source_email, admin_email, admin_email, message_title, message) log.debug( 'Alarm Email generated for Admin (%s): connecting to [%s:%d], ' 'the next mail should be in %d minutes' % (event_matrix, GLSettings.memory_copy.notif_server, GLSettings.memory_copy.notif_port, do_not_stress_admin_with_more_than_an_email_every_minutes)) defer.returnValue({ 'admin_email': admin_email, 'message': message, })
def admin_alarm_generate_mail(event_matrix): """ This function put a mail in queue for the Admin, if the Admin notification is disable or if another Anomaly has been raised in the last 15 minutes, email is not send. """ ret = [] do_not_stress_admin_with_more_than_an_email_every_minutes = 120 def replace_keywords(text): iterations = 3 stop = False while (stop == False and iterations > 0): iterations -= 1 count = 0 for keyword, function in KeywordTemplate.iteritems(): where = text.find(keyword) if where == -1: continue count += 1 text = "%s%s%s" % (text[:where], function(notification_dict), text[where + len(keyword):]) if count == 0: # finally! stop = True break def _disk_anomaly_detail(notification_dict): # This happens all the time anomalies are present but disk is ok if Alarm.stress_levels['disk_space'] == 0: return u'' if Alarm.stress_levels['disk_space'] == 1: return notification_dict['admin_anomaly_disk_low'] elif Alarm.stress_levels['disk_space'] == 2: return notification_dict['admin_anomaly_disk_medium'] else: return notification_dict['admin_anomaly_disk_high'] def _activities_anomaly_detail(notification_dict): # This happens all the time there is not anomalous traffic if Alarm.stress_levels['activity'] == 0: return u'' return notification_dict['admin_anomaly_activities'] def _activity_alarm_level(notification_dict): return "%s" % Alarm.stress_levels['activity'] def _activity_dump(notification_dict): retstr = "" for event, amount in event_matrix.iteritems(): if not amount: continue retstr = "%s%s%d\n%s" % \ (event, (25 - len(event)) * " ", amount, retstr) return retstr def _node_name(notification_dict): return unicode(GLSettings.memory_copy.nodename) def _free_disk_space(notification_dict): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace) def _total_disk_space(notification_dict): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace) def _notifications_suppressed(notification_dict): if Alarm.stress_levels['notification'] == []: return u'' return "** %s **" % Alarm.stress_levels['notification'] KeywordTemplate = { "%AnomalyDetailDisk%": _disk_anomaly_detail, "%AnomalyDetailActivities%": _activities_anomaly_detail, "%ActivityAlarmLevel%": _activity_alarm_level, "%ActivityDump%": _activity_dump, "%NotificationsSuppressed%": _notifications_suppressed, "%NodeName%": _node_name, "%FreeMemory%": _free_disk_space, "%TotalMemory%": _total_disk_space, } # ------------------------------------------------------------------ if not (Alarm.stress_levels['activity'] or Alarm.stress_levels['disk_space'] or Alarm.stress_levels['notification']): # we are lucky! no stress activities detected, no mail needed defer.returnValue([]) if GLSettings.memory_copy.disable_admin_notification_emails: defer.returnValue([]) if Alarm.last_alarm_email: if not is_expired( Alarm.last_alarm_email, minutes= do_not_stress_admin_with_more_than_an_email_every_minutes): defer.returnValue([]) admin_users = yield get_admin_users() for u in admin_users: notification_dict = yield get_notification(u['language']) subject = notification_dict['admin_anomaly_mail_title'] body = notification_dict['admin_anomaly_mail_template'] replace_keywords(subject) replace_keywords(body) ret.append({ 'mail_address': u['mail_address'], 'subject': subject, 'body': body }) defer.returnValue(ret)
def admin_alarm_generate_mail(event_matrix): """ This function put a mail in queue for the Admin, if the Admin notification is disable or if another Anomaly has been raised in the last 15 minutes, email is not send. """ ret = [] do_not_stress_admin_with_more_than_an_email_every_minutes = 120 def replace_keywords(text): iterations = 3 stop = False while (stop == False and iterations > 0): iterations -= 1 count = 0 for keyword, function in KeywordTemplate.iteritems(): where = text.find(keyword) if where == -1: continue count += 1 text = "%s%s%s" % (text[:where], function(notification_dict), text[where + len(keyword):]) if count == 0: # finally! stop = True break return text def _disk_anomaly_detail(notification_dict): # This happens all the time anomalies are present but disk is ok if Alarm.stress_levels['disk_space'] == 0: return u'' if Alarm.stress_levels['disk_space'] == 1: return notification_dict['admin_anomaly_disk_low'] elif Alarm.stress_levels['disk_space'] == 2: return notification_dict['admin_anomaly_disk_medium'] else: return notification_dict['admin_anomaly_disk_high'] def _activities_anomaly_detail(notification_dict): # This happens all the time there is not anomalous traffic if Alarm.stress_levels['activity'] == 0: return u'' return notification_dict['admin_anomaly_activities'] def _activity_alarm_level(notification_dict): return "%s" % Alarm.stress_levels['activity'] def _activity_dump(notification_dict): retstr = "" for event, amount in event_matrix.iteritems(): if not amount: continue retstr = "%s%s%d\n%s" % \ (event, (25 - len(event)) * " ", amount, retstr) return retstr def _node_name(notification_dict): return unicode(GLSettings.memory_copy.nodename) def _free_disk_space(notification_dict): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace) def _total_disk_space(notification_dict): return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace) def _notifications_suppressed(notification_dict): if Alarm.stress_levels['notification'] == []: return u'' return "** %s **" % Alarm.stress_levels['notification'] KeywordTemplate = { "%AnomalyDetailDisk%": _disk_anomaly_detail, "%AnomalyDetailActivities%": _activities_anomaly_detail, "%ActivityAlarmLevel%": _activity_alarm_level, "%ActivityDump%": _activity_dump, "%NotificationsSuppressed%": _notifications_suppressed, "%NodeName%": _node_name, "%FreeMemory%": _free_disk_space, "%TotalMemory%": _total_disk_space, } # ------------------------------------------------------------------ if not (Alarm.stress_levels['activity'] or Alarm.stress_levels['disk_space'] or Alarm.stress_levels['notification']): # we are lucky! no stress activities detected, no mail needed defer.returnValue([]) if GLSettings.memory_copy.disable_admin_notification_emails: defer.returnValue([]) if Alarm.last_alarm_email: if not is_expired(Alarm.last_alarm_email, minutes=do_not_stress_admin_with_more_than_an_email_every_minutes): defer.returnValue([]) admin_users = yield get_admin_users() for u in admin_users: notification_dict = yield get_notification(u['language']) subject = notification_dict['admin_anomaly_mail_title'] body = notification_dict['admin_anomaly_mail_template'] subject = replace_keywords(subject) body = replace_keywords(body) ret.append({ 'mail_address': u['mail_address'], 'subject': subject, 'body': body }) defer.returnValue(ret)