def _thread_save_to_db(host, parsed_metadata): """ method used by the various threads to save inside the local.db all the metadata that we need. Here the things gets a little tricky: basically, parsed_metadata is a list of dictionaries. Each dictionary is an alarm. If you want to know how the dictionary is built look at _parse_all_alarms_xml(_root) @param host: specifies the host IP @param parsed_metadata: is a list of dictionaries that is coming from the method '_parse_all_alarms_xml(_root)' @return: void """ _config_manager = ConfigManager() flag = _config_manager.get_alarm_dummy_data_flag() if flag == True: # we do not want to save again the same alarms (DEBUG), should refactor this to be clearer parsed_metadata = __filter_if_alarm_exists_in_db(host, parsed_metadata) for alarm_dict in parsed_metadata: try: lock.acquire() # need to lock also here because sqlite is s**t severity_levels = config_m.get_severity_levels() severity = severity_levels[alarm_dict['notification-code']] description = alarm_dict['condition-description'] timestamp = alarm_dict['ne-condition-timestamp'] db_handler = DBHandler().open_connection() db_handler.insert_row_alarm(device_ip=host, severity=severity, description=description, _time=timestamp) db_handler.close_connection() except Exception as e: logging.log(logging.ERROR, str(e)) finally: lock.release()
def summary(update, context): """gives the user the received severities with correspondent counters""" msg = '' getNewData = CommonFunctions() results = getNewData.fetchDataFromDB() try: if (len(results) == 0): raise Exception("No msg sent to the subscribers") totalAlarmsPerSeverity = getNewData.organizeTotalAlarmsPerSeverity(results) for severity in sorted(totalAlarmsPerSeverity): _config_manager = ConfigManager() description=_config_manager.get_severity_mapping(int(severity)) msg += f'<i>{description}</i>: {(totalAlarmsPerSeverity[severity])}\n' update.message.reply_text('<b>Alarms\' Summary</b>:\n' + msg, parse_mode='HTML') except Exception as e: logging.log(logging.ERROR, "Error loading data in the telegram bot: " + str(e)) msg += 'No Alarms in DB!' update.message.reply_text(msg)
def singleHostAlarms(update, context): """gives the user the received severities for each host""" msg = '' getNewData = CommonFunctions() results = getNewData.fetchDataFromDB() try: if (len(results) == 0): raise Exception("No msg sent to the subscribers") alarmsPerHost = getNewData.organizeAlarmsPerHost(results) for host in sorted(alarmsPerHost): msg += f'<b>Ip Address</b>:{host}\n' for severity in sorted(alarmsPerHost[host]): _config_manager = ConfigManager() description = _config_manager.get_severity_mapping(int(severity)) msg += f'{severity} - <i>{description}</i>:# {(alarmsPerHost[host][severity])}\n' msg+='\n' update.message.reply_text('<b>Alarms \' per Host </b>:\n\n' + msg, parse_mode='HTML') except Exception as e: logging.log(logging.ERROR, "Error loading data in the telegram bot: " + str(e)) msg += 'No Alarms in DB!' update.message.reply_text(msg)
def send_mail(msg_body, msg_subject='SDN Alarm notification'): config_manager = ConfigManager() if msg_body is None: raise Exception("you need to specify the the email body!") try: data = config_manager.get_notification_config() email_address_sender = data['Sender_email'] email_password_sender = data['Sender_email_password'] email_address_receiver = data['Receiver_Email'] smtp_server = data['SMTP_SERVER'] smtp_port = data['SMTP_PORT'] except Exception as e: print("something went wrong reading config.json file! ->" + str(e)) debug_mode = config_manager.get_debug_mode() if debug_mode: # overwrite with my personal credentials try: filename = os.path.join(dirname, '../config/personal_credentials.json') with open(filename) as json_data_file: data = json.load(json_data_file) email_address_sender = str(data['email']) email_password_sender = str(data['password']) email_address_receiver = str( data['email'] ) # not a typo, I'm sending notifications to myself smtp_server = 'smtp.office365.com' smtp_port = 587 except Exception as e: print( "something went wrong reading personal_credentials.json file! ->" + str(e)) ################### implementation ####################### with smtplib.SMTP(smtp_server, smtp_port) as smtp: smtp.ehlo() smtp.starttls() smtp.ehlo() smtp.login(email_address_sender, email_password_sender) # email message setup msg = EmailMessage() msg['Subject'] = msg_subject msg['From'] = email_address_sender msg['To'] = email_address_receiver msg.set_content(msg_body) try: smtp.send_message(msg) except Exception as e: logging.log(logging.WARNING, "Failed to send email!" + str(e)) smtp.close()
import threading, time, traceback, logging, os from models.database_manager import DBHandler from models.config_manager import ConfigManager from models.device import Device from models.customXMLParser import CustomXMLParser from ncclient import manager from typing import List ####################setting up globals################### logging.basicConfig(filename="log.log", level=logging.ERROR) config_m = ConfigManager() # reading the config.json and creating the devices devices = [ Device(d['device_ip'], d['netconf_fetch_rate_in_sec'], d['netconf_port'], d['netconf_user'], d['netconf_password']) for d in config_m.get_network_params() ] lock = threading.Lock() ######################################### def _worker(_delay, task, *args): # todo specify thread's stop condition? maybe through a SIGINT
def setupUi(self, MainWindow): self.setObjectName("MainWindow") self.resize(1200, 650) self.setWindowIcon(QtGui.QIcon(alarm_icon)) self.centralwidget = QtWidgets.QWidget() self.centralwidget.setObjectName("centralwidget") #Toolbar Definitions self.tabWidget = QtWidgets.QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QtCore.QRect(0, 0, 1200, 650)) self.tabWidget.setObjectName("tabWidget") self.tab = QtWidgets.QWidget() self.tab.setObjectName("tab") self.tabWidget.addTab(self.tab, "") self.tab_2 = QtWidgets.QWidget() self.tab_2.setObjectName("tab_2") self.tabWidget.addTab(self.tab_2, "") self.tab_2.setEnabled(False) self.tab_3 = QtWidgets.QWidget() self.tab_3.setObjectName("tab_3") self.tabWidget.addTab(self.tab_3, "") self.tab_3.setEnabled(False) self.tab_4 = QtWidgets.QWidget() self.tab_4.setObjectName("tab_4") self.tabWidget.addTab(self.tab_4, "") self.tab_4.setEnabled(False) #Title and subtitle of the main window self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(410, 10, 400, 50)) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(16) font.setBold(False) font.setWeight(50) self.label.setFont(font) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(520, 50, 181, 51)) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(14) font.setBold(False) font.setWeight(50) self.label_2.setFont(font) self.label_2.setObjectName("label_2") #Defining and setting the table self.tableWidget = QtWidgets.QTableWidget(self.tab) self.tableWidget.setGeometry(QtCore.QRect(420, 100, 720, 350)) self.tableWidget.setObjectName("tableWidget") self.tableWidget.setColumnCount(7) self.tableWidget.setRowCount(0) #Defining the Load Button self.load_db = QtWidgets.QPushButton(self.tab) self.load_db.setGeometry(QtCore.QRect(740, 465, 75, 23)) self.load_db.setObjectName("load_db") self.load_db.setEnabled(False) # Defining the Notification Button self.button_Notification = QtWidgets.QPushButton(self.tab) self.button_Notification.setGeometry(QtCore.QRect(120, 270, 180, 20)) self.button_Notification.setObjectName("button_Notification") #Defining the new Device Button self.button_Device = QtWidgets.QPushButton(self.tab) self.button_Device.setGeometry(QtCore.QRect(120, 465, 110, 20)) self.button_Device.setObjectName("button_Device") #Defining the Run Button self.button_RUN = QtWidgets.QPushButton(self.tab) self.button_RUN.setGeometry(QtCore.QRect(550, 525, 110, 20)) self.button_RUN.setObjectName("button_RUN") # Defining the Refresh Button self.refreshButton = QtWidgets.QPushButton(self.tab) self.refreshButton.setGeometry(QtCore.QRect(870, 525, 110, 25)) self.refreshButton.setObjectName("button_refreash") self.refreshButton.setEnabled(False) #Defining the Notification Options Box self.Send_Mail = QLineEdit() self.Password = QLineEdit() self.Password.setEchoMode(2) self.Reciver_Mail = QLineEdit() self.Severity = QSpinBox() conf_manager = ConfigManager() totalSeverities = conf_manager.getSeveritiesNumber() self.Severity.setMaximum(totalSeverities - 1) self.Mail_Button = QCheckBox() self.Mail_Button.setAutoExclusive(False) self.Message_Button = QCheckBox() self.Message_Button.setAutoExclusive(False) self.formGroupBox = QGroupBox(self.tab) self.formGroupBox.setGeometry(QtCore.QRect(20, 100, 300, 160)) layout = QFormLayout() layout.addRow(QLabel("Sender_email:"), self.Send_Mail) layout.addRow(QLabel("Password:"******"Receiver_Email:"), self.Reciver_Mail) layout.addRow(QLabel("Severity Threshold:"), self.Severity) layout.addRow(QLabel("Send E-mail:"), self.Mail_Button) layout.addRow(QLabel("Send Message:"), self.Message_Button) self.formGroupBox.setLayout(layout) # Defining the Device Options Box self.device_ip = QLineEdit() self.Fetch_sec = QSpinBox() self.Fetch_sec.setMaximum(10) self.netconf_password = QLineEdit() self.netconf_password.setEchoMode(2) self.netconf_port = QSpinBox() self.netconf_port.setMaximum(1000) self.netconf_admin = QLineEdit() self.formGroupBox2 = QGroupBox(self.tab) self.formGroupBox2.setGeometry(QtCore.QRect(20, 300, 300, 150)) layout2 = QFormLayout() layout2.addRow(QLabel("Device Ip:"), self.device_ip) layout2.addRow(QLabel("Netconf User:"******"Netconf Password:"******"Netconf Port:"), self.netconf_port) layout2.addRow(QLabel("Fetch Rate:"), self.Fetch_sec) self.formGroupBox2.setLayout(layout2) #Triggered (Clicked) Buttons connections with respective methods self.tableWidget.verticalHeader().hide() self.tableWidget.horizontalHeader().hide() self.load_db.clicked.connect(self.loadDataB) self.button_Notification.clicked.connect(self.Json_Notification) self.button_Device.clicked.connect(self.Json_Network) self.button_RUN.clicked.connect(self.Verification_changes) self.refreshButton.clicked.connect(self.reFresh) #Defining Graphs self.plotWidget1 = Graph1(self.tab_2, width=12, height=4.5, dpi=100) self.plotWidget1.move(0, 100) self.plotWidget2 = Graph2(self.tab_3, width=12, height=5, dpi=100) self.plotWidget2.move(0, 80) self.plotWidget3 = Graph3(self.tab_4, width=12, height=4.5, dpi=100) self.plotWidget3.move(20, 100) self.setCentralWidget(self.centralwidget) #DEfining and setting the toolbar self.menubar = QtWidgets.QMenuBar() self.menubar.setGeometry(QtCore.QRect(0, 0, 918, 21)) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuAbout = QtWidgets.QMenu(self.menubar) self.menuAbout.setObjectName("menuAbout") self.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar() self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.actionExit = QtWidgets.QAction() self.actionExit.setObjectName("actionExit") self.actionExit.setIcon(QtGui.QIcon(exit_icon)) self.actionAbout = QtWidgets.QAction() self.actionAbout.setObjectName("actionAbout") self.actionAbout.triggered.connect(self.About) self.actionSaveAll = QtWidgets.QAction() self.actionSaveAll.setObjectName("actionSaveAll") self.actionSaveAll.setIcon(QtGui.QIcon(floppy_icon)) self.actionSave1 = QtWidgets.QAction() self.actionSave1.setObjectName("actionSave1") self.actionSave1.setIcon(QtGui.QIcon(floppy_icon)) self.actionSave2 = QtWidgets.QAction() self.actionSave2.setObjectName("actionSave2") self.actionSave2.setIcon(QtGui.QIcon(floppy_icon)) self.actionSave3 = QtWidgets.QAction() self.actionSave3.setObjectName("actionSave3") self.actionSave3.setIcon(QtGui.QIcon(floppy_icon)) #Toolbar buttons connections self.actionExit.triggered.connect(self.Exit) self.actionSaveAll.triggered.connect(self.saveAllClicked) self.actionSave1.triggered.connect(self.save1Clicked) self.actionSave2.triggered.connect(self.save2Clicked) self.actionSave3.triggered.connect(self.save3Clicked) self.menuFile.addAction(self.actionSaveAll) self.menuFile.addAction(self.actionSave1) self.menuFile.addAction(self.actionSave2) self.menuFile.addAction(self.actionSave3) self.menuFile.addAction(self.actionExit) self.menuAbout.addAction(self.actionAbout) self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuAbout.menuAction()) self.retranslateUi(self) self.tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(self)
def __init__(self): self._config_manager = ConfigManager() self.msg = '' self._worker = None
class NotificationManager(object, metaclass=Singleton): def __init__(self): self._config_manager = ConfigManager() self.msg = '' self._worker = None def notify(self, msg="DEBUG FROM NOTIFICATION MANAGER!"): """ method that broadcast the alarm through all the technologies defined here (eg. email, messages...)""" self._send_mail(msg) self._broadcast_alarm(msg) def _send_mail(self, msg): """ helper method that sends the email through the service if the flag inside config.json is set to true""" send_email_flag = self._config_manager.get_email_notification_flag() if send_email_flag: mail_sender_service.send_mail(msg) def _broadcast_alarm(self, msg): """ broadcast the alarm using the bot""" send_message_flag = self._config_manager.get_message_notification_flag( ) try: if send_message_flag: telegram_bot_service.send_to_bot_group(msg) except Exception as e: logging.log(logging.ERROR, 'Failed to send a broadcast message' + str(e)) def start(self): """method available on the outside. It just starts the thread responsible to deliver notifications to users.""" # TODO make the delay of notification available on the config.json if self._worker is None: self._worker = threading.Thread( target=lambda: self.__notificationThread(5)) self._worker.start() return self._worker def __build_new_alarm_msg(self, _list) -> str: """ helper method that build the msg to be notified @param _list: list of dictionaries. each dictionary is an alarm @return a message formatted with all the information """ self.message = 'New Alarm(s): \n' for alarm in _list: device = alarm[1] severity = alarm[2] description = alarm[3] timestamp = alarm[4] self.message += f'\tDeviceIp: \'{device}\',\n' \ f'\tDescription: {description},\n' \ f'\ttime: \'{timestamp}\'.\n' \ f'\tSeverity: {severity}\n\n' return self.message def __update_alarms_table_notified(self, _list): """ method used to update the DB's table. It sets the notified attribute to 1 to all the alarms that were notified. @param _list: list of alarms """ ids = [] for alarm in _list: ids.append(alarm[0]) db = DBHandler().open_connection() db.update_notified_by_ID(ids) db.close_connection() def __notificationThread(self, _delay): """ worker definition for notification task. It queries the DB and chooses what alarms to notify. @param _delay: it specifies the delay in which the task will be performed @return: void """ next_time = time.time() + _delay severity_threshold = self._config_manager.get_severity_notification_threshold( ) while True: time.sleep( max(0, next_time - time.time())) # making the thread not wasting CPU cycles db = DBHandler() try: db.open_connection() result = db.select_alarm_by_severity_unnotified( severity_threshold) if len( result ) != 0: # it means that there are some alarms that need to be notified! self.notify(self.__build_new_alarm_msg(result)) self.__update_alarms_table_notified(result) except Exception as e: traceback.print_exc() logging.exception("Problem while trying notify alarms' data." + str(e)) finally: db.close_connection() next_time += (time.time() - next_time ) // _delay * _delay + _delay # next scheduling