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
Пример #6
0
    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