Пример #1
0
    def view_json(self, FERListWidget, url, id, key):
        logger.info("[Field Extraction Rules]Viewing FER(s) as JSON")
        selecteditems = FERListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    for object in FERListWidget.currentcontent:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            fer = sumo.get_fer(item_id)
                            json_text = json_text + json.dumps(
                                fer, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return

        else:
            self.mainwindow.errorbox('No FER selected.')
        return
    def view_source_JSON(self, CollectorListWidget, SourceListWidget, url, id,
                         key):
        logger.info("[Collectors] Viewing Source JSON")
        sourcenames = SourceListWidget.selectedItems()
        if len(sourcenames) > 0:  # make sure at least one source is selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                collectornamesqstring = CollectorListWidget.selectedItems(
                )  # get collectors sources have been selected
                collectorname = str(collectornamesqstring[0].text())
                collector = sumo.get_collector_by_name_alternate(collectorname)
                sources = sumo.get_sources_sync(collector['id'])
                for sourcename in sourcenames:
                    for source in sources:
                        if ('name' in source
                                and str(sourcename.text()) == source['name']
                            ) or ('config' in source and str(sourcename.text())
                                  == source['config']['name']):
                            json_text = json_text + json.dumps(
                                source, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))

        else:
            self.mainwindow.errorbox('No Source Selected.')
Пример #3
0
    def view_role_json(self, RoleListWidget, url, id, key):
        logger.info("[Users and Roles]Viewing Roles(s) JSON")
        selecteditems = RoleListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    role_id = selecteditem.details['id']
                    role = sumo.get_role(role_id)
                    json_text = json_text + json.dumps(
                        role, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return
        else:
            self.mainwindow.errorbox('No role selected.')
        return
 def view_collector_JSON(self, CollectorListWidget, url, id, key):
     logger.info("[Collectors] Viewing Collector JSON")
     collectornamesqstring = CollectorListWidget.selectedItems(
     )  # get collectors sources have been selected
     if len(collectornamesqstring) > 0:  # make sure something was selected
         try:
             sumo = SumoLogic(id,
                              key,
                              endpoint=url,
                              log_level=self.mainwindow.log_level)
             json_text = ''
             for collectornameqstring in collectornamesqstring:
                 collector = sumo.get_collector_by_name_alternate(
                     str(collectornameqstring.text()))
                 # sources = sumo.get_sources_sync(collector['id'])
                 json_text = json_text + json.dumps(
                     collector, indent=4, sort_keys=True) + '\n\n'
                 # json_text = json_text + json.dumps(sources, indent=4, sort_keys=True) + '\n\n'
             self.json_window = ShowTextDialog('JSON', json_text,
                                               self.mainwindow.basedir)
             self.json_window.show()
         except Exception as e:
             logger.exception(e)
             self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
     else:
         self.mainwindow.errorbox('No Collector Selected.')
     return
    def view_monitor_json(self, MonitorListWidget, url, id, key):
        logger.info("[Monitors and Connections]Viewing Monitor(s) JSON")
        selecteditems = MonitorListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    for object in MonitorListWidget.currentcontent['children']:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            user = sumo.export_monitor(item_id)
                            json_text = json_text + json.dumps(user, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text, self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return
        else:
            self.mainwindow.errorbox('No monitor selected.')
        return
Пример #6
0
class field_extraction_rule_tab(QtWidgets.QWidget):
    def __init__(self, mainwindow):

        super(field_extraction_rule_tab, self).__init__()
        self.mainwindow = mainwindow
        self.tab_name = 'Field Extraction Rules'
        self.cred_usage = 'both'
        scheduled_view_widget_ui = os.path.join(
            self.mainwindow.basedir, 'data/field_extraction_rule.ui')
        uic.loadUi(scheduled_view_widget_ui, self)

        self.pushButtonUpdateFERLeft.clicked.connect(
            lambda: self.update_FER_list(
                self.FERListWidgetLeft, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonUpdateFERRight.clicked.connect(
            lambda: self.update_FER_list(
                self.FERListWidgetRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonFERDeleteLeft.clicked.connect(lambda: self.delete_fer(
            self.FERListWidgetLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonFERDeleteRight.clicked.connect(lambda: self.delete_fer(
            self.FERListWidgetRight, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonFERCopyLeftToRight.clicked.connect(
            lambda: self.copy_fers(
                self.FERListWidgetLeft, self.FERListWidgetRight, self.
                mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft
                                             .currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonFERCopyRightToLeft.clicked.connect(
            lambda: self.copy_fers(
                self.FERListWidgetRight, self.FERListWidgetLeft, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonFERBackupLeft.clicked.connect(lambda: self.backup_fer(
            self.FERListWidgetLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonFERBackupRight.clicked.connect(lambda: self.backup_fer(
            self.FERListWidgetRight, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonFERJSONLeft.clicked.connect(lambda: self.view_json(
            self.FERListWidgetLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonFERJSONRight.clicked.connect(lambda: self.view_json(
            self.FERListWidgetRight, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonFERRestoreLeft.clicked.connect(lambda: self.restore_fer(
            self.FERListWidgetLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonFERRestoreRight.clicked.connect(
            lambda: self.restore_fer(
                self.FERListWidgetRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

    def reset_stateful_objects(self, side='both'):

        if side == 'both':
            left = True
            right = True
        if side == 'left':
            left = True
            right = False
        if side == 'right':
            left = False
            right = True

        if left:
            self.FERListWidgetLeft.clear()
            self.FERListWidgetLeft.currentcontent = {}
            self.FERListWidgetLeft.updated = False

        if right:
            self.FERListWidgetRight.clear()
            self.FERListWidgetRight.currentcontent = {}
            self.FERListWidgetRight.updated = False

        return

    def update_FER_list(self, FERListWidget, url, id, key):
        sumo = SumoLogic(id,
                         key,
                         endpoint=url,
                         log_level=self.mainwindow.log_level)
        try:
            logger.info("[Field Extraction Rules]Updating FER List")
            FERListWidget.currentcontent = sumo.get_fers_sync()
            FERListWidget.clear()
            if len(FERListWidget.currentcontent) > 0:
                self.update_FER_listwidget(FERListWidget)
                return

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
            return

    def update_FER_listwidget(self, FERListWidget):
        try:
            FERListWidget.clear()
            FERListWidget.setSortingEnabled(True)
            for object in FERListWidget.currentcontent:
                item_name = object['name']
                FERListWidget.addItem(
                    item_name)  # populate the list widget in the GUI

            FERListWidget.updated = True

        except Exception as e:
            logger.exception(e)
        return

    def delete_fer(self, FERListWidget, url, id, key):
        logger.info("[Field Extraction Rules]Deleting FER(s)")
        selecteditems = FERListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            message = "You are about to delete the following item(s):\n\n"
            for selecteditem in selecteditems:
                message = message + str(selecteditem.text()) + "\n"
            message = message + '''
    This is exceedingly DANGEROUS!!!! 
    Please be VERY, VERY, VERY sure you want to do this!
    You could lose quite a bit of work if you delete the wrong thing(s).

    If you are absolutely sure, type "DELETE" in the box below.

                        '''
            text, result = QtWidgets.QInputDialog.getText(
                self, 'Warning!!', message)
            if (result and (str(text) == 'DELETE')):
                try:

                    sumo = SumoLogic(id,
                                     key,
                                     endpoint=url,
                                     log_level=self.mainwindow.log_level)
                    for selecteditem in selecteditems:
                        for object in FERListWidget.currentcontent:
                            if object['name'] == str(selecteditem.text()):
                                item_id = object['id']

                        result = sumo.delete_fer(item_id)

                    self.update_FER_list(FERListWidget, url, id, key)
                    return

                except Exception as e:
                    logger.exception(e)
                    self.mainwindow.errorbox('Something went wrong:\n\n' +
                                             str(e))

        else:
            self.mainwindow.errorbox(
                'You need to select something before you can delete it.')
        return

    def process_fer(self, exported_fer):
        processed = {}
        processed['name'] = exported_fer['name']
        processed['scope'] = exported_fer['scope']
        processed['parseExpression'] = exported_fer['parseExpression']
        processed['enabled'] = 'false'

        return processed

    def copy_fers(self, FERListWidgetFrom, FERListWidgetTo, fromurl, fromid,
                  fromkey, tourl, toid, tokey):

        logger.info("[Field Extraction Rules]Copying FER(s)")
        try:
            selecteditems = FERListWidgetFrom.selectedItems()
            if len(selecteditems) > 0:  # make sure something was selected
                fromsumo = SumoLogic(fromid,
                                     fromkey,
                                     endpoint=fromurl,
                                     log_level=self.mainwindow.log_level)
                tosumo = SumoLogic(toid,
                                   tokey,
                                   endpoint=tourl,
                                   log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    for object in FERListWidgetFrom.currentcontent:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            fer_export = fromsumo.get_fer(item_id)
                            status = tosumo.create_fer(
                                fer_export['name'], fer_export['scope'],
                                fer_export['parseExpression'])
                self.update_FER_list(FERListWidgetTo, tourl, toid, tokey)
                return

            else:
                self.mainwindow.errorbox('You have not made any selections.')
                return

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:' + str(e))
            self.update_FER_list(FERListWidgetTo, tourl, toid, tokey)
        return

    def backup_fer(self, FERListWidget, url, id, key):
        logger.info("[Field Extraction Rules]Backing Up FER(s)")
        selecteditems = FERListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            savepath = str(
                QtWidgets.QFileDialog.getExistingDirectory(
                    self, "Select Backup Directory"))
            if os.access(savepath, os.W_OK):
                message = ''
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    for object in FERListWidget.currentcontent:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            try:
                                export = sumo.get_fer(item_id)

                                savefilepath = pathlib.Path(
                                    savepath + r'/' +
                                    str(selecteditem.text()) + r'.fer.json')
                                if savefilepath:
                                    with savefilepath.open(
                                            mode='w') as filepointer:
                                        json.dump(export, filepointer)
                                    message = message + str(
                                        selecteditem.text()) + r'.json' + '\n'
                            except Exception as e:
                                logger.exception(e)
                                self.mainwindow.errorbox(
                                    'Something went wrong:\n\n' + str(e))
                                return
                self.mainwindow.infobox('Wrote files: \n\n' + message)
            else:
                self.mainwindow.errorbox(
                    "You don't have permissions to write to that directory")

        else:
            self.mainwindow.errorbox('No FER selected.')
        return

    def view_json(self, FERListWidget, url, id, key):
        logger.info("[Field Extraction Rules]Viewing FER(s) as JSON")
        selecteditems = FERListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    for object in FERListWidget.currentcontent:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            fer = sumo.get_fer(item_id)
                            json_text = json_text + json.dumps(
                                fer, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return

        else:
            self.mainwindow.errorbox('No FER selected.')
        return

    def restore_fer(self, FERListWidget, url, id, key):
        logger.info("[Field Extraction Rules]Restoring FER(s)")
        if FERListWidget.updated == True:

            filter = "JSON (*.json)"
            filelist, status = QtWidgets.QFileDialog.getOpenFileNames(
                self, "Open file(s)...", os.getcwd(), filter)
            if len(filelist) > 0:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for file in filelist:
                    try:
                        with open(file) as filepointer:
                            fer_backup = json.load(filepointer)
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox(
                            "Something went wrong reading the file. Do you have the right file permissions? Does it contain valid JSON?"
                        )
                        return
                    try:
                        status = sumo.create_fer(fer_backup['name'],
                                                 fer_backup['scope'],
                                                 fer_backup['parseExpression'])

                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' +
                                                 str(e))
                        return
                self.update_FER_list(FERListWidget, url, id, key)

            else:
                self.mainwindow.errorbox(
                    "Please select at least one file to restore.")
                return
        else:
            self.mainwindow.errorbox(
                "Please update the directory list before restoring content")
        return
Пример #7
0
class saml_tab(QtWidgets.QWidget):
    def __init__(self, mainwindow):

        super(saml_tab, self).__init__()
        self.mainwindow = mainwindow
        self.tab_name = 'SAML'
        self.cred_usage = 'both'
        saml_widget_ui = os.path.join(self.mainwindow.basedir, 'data/saml.ui')
        uic.loadUi(saml_widget_ui, self)

        self.pushButtonUpdateSAMLLeft.clicked.connect(
            lambda: self.update_SAML_list(
                self.SAMLListWidgetLeft, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonUpdateSAMLRight.clicked.connect(
            lambda: self.update_SAML_list(
                self.SAMLListWidgetRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonSAMLDeleteLeft.clicked.connect(lambda: self.delete_saml(
            self.SAMLListWidgetLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonSAMLDeleteRight.clicked.connect(
            lambda: self.delete_saml(
                self.SAMLListWidgetRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonSAMLCopyLeftToRight.clicked.connect(
            lambda: self.copy_saml(
                self.SAMLListWidgetLeft, self.SAMLListWidgetRight, self.
                mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft
                                             .currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonSAMLCopyRightToLeft.clicked.connect(
            lambda: self.copy_saml(
                self.SAMLListWidgetRight, self.SAMLListWidgetLeft, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonSAMLBackupLeft.clicked.connect(lambda: self.backup_saml(
            self.SAMLListWidgetLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonSAMLBackupRight.clicked.connect(
            lambda: self.backup_saml(
                self.SAMLListWidgetRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonSAMLJSONLeft.clicked.connect(lambda: self.view_json(
            self.SAMLListWidgetLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonSAMLJSONRight.clicked.connect(lambda: self.view_json(
            self.SAMLListWidgetRight, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonSAMLRestoreLeft.clicked.connect(
            lambda: self.restore_saml(
                self.SAMLListWidgetLeft, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonSAMLRestoreRight.clicked.connect(
            lambda: self.restore_saml(
                self.SAMLListWidgetRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

    def reset_stateful_objects(self, side='both'):

        if side == 'both':
            left = True
            right = True
        if side == 'left':
            left = True
            right = False
        if side == 'right':
            left = False
            right = True

        if left:
            self.SAMLListWidgetLeft.clear()
            self.SAMLListWidgetLeft.currentcontent = {}
            self.SAMLListWidgetLeft.updated = False

        if right:
            self.SAMLListWidgetRight.clear()
            self.SAMLListWidgetRight.currentcontent = {}
            self.SAMLListWidgetRight.updated = False

    def update_SAML_list(self, SAMLListWidget, url, id, key):
        sumo = SumoLogic(id,
                         key,
                         endpoint=url,
                         log_level=self.mainwindow.log_level)
        try:
            logger.info("[SAML]Updating SAML config List")
            SAMLListWidget.currentcontent = sumo.get_saml_configs()
            SAMLListWidget.clear()
            self.update_SAML_listwidget(SAMLListWidget)
            return
        except Exception as e:
            logger.exception(e)
            SAMLListWidget.updated = False
            self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
            return

    def update_SAML_listwidget(self, SAMLListWidget):
        try:
            SAMLListWidget.clear()
            SAMLListWidget.setSortingEnabled(True)
            for object in SAMLListWidget.currentcontent:
                item_name = object['configurationName']
                SAMLListWidget.addItem(
                    item_name)  # populate the list widget in the GUI
            SAMLListWidget.updated = True
        except Exception as e:
            logger.exception(e)
            SAMLListWidget.updated = False
            SAMLListWidget.clear()

        return

    def delete_saml(self, SAMLListWidget, url, id, key):
        logger.info("[SAML]Deleting SAML config(s)")
        selecteditems = SAMLListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            message = "You are about to delete the following item(s):\n\n"
            for selecteditem in selecteditems:
                message = message + str(selecteditem.text()) + "\n"
            message = message + '''
    This is exceedingly DANGEROUS!!!! 
    Please be VERY, VERY, VERY sure you want to do this!
    You could lose quite a bit of work if you delete the wrong thing(s).

    If you are absolutely sure, type "DELETE" in the box below.

                        '''
            text, result = QtWidgets.QInputDialog.getText(
                self, 'Warning!!', message)
            if (result and (str(text) == 'DELETE')):
                try:

                    sumo = SumoLogic(id,
                                     key,
                                     endpoint=url,
                                     log_level=self.mainwindow.log_level)
                    for selecteditem in selecteditems:
                        for object in SAMLListWidget.currentcontent:
                            if object['configurationName'] == str(
                                    selecteditem.text()):
                                item_id = object['id']

                        result = sumo.delete_saml_config(item_id)

                    self.update_SAML_list(SAMLListWidget, url, id, key)
                    return

                except Exception as e:
                    logger.exception(e)
                    self.mainwindow.errorbox('Something went wrong:\n\n' +
                                             str(e))

        else:
            self.mainwindow.errorbox(
                'You need to select something before you can delete it.')
        return

    def copy_saml(self, SAMLListWidgetFrom, SAMLListWidgetTo, fromurl, fromid,
                  fromkey, tourl, toid, tokey):

        logger.info("[SAML]Copying SAML config(s)")
        try:
            selecteditems = SAMLListWidgetFrom.selectedItems()
            if len(selecteditems) > 0:  # make sure something was selected
                message = "You are about to copy the following item(s):\n\n"
                for selecteditem in selecteditems:
                    message = message + str(selecteditem.text()) + "\n"
                message = message + '''
                    This is exceedingly DANGEROUS!!!! 
                    Please be VERY, VERY, VERY sure you want to do this!
                    You could cross the streams if you copy the wrong thing(s).

                    If you are absolutely sure, type "COPY" in the box below.

                                        '''
                text, result = QtWidgets.QInputDialog.getText(
                    self, 'Warning!!', message)
                if (result and (str(text) == 'COPY')):
                    fromsumo = SumoLogic(fromid,
                                         fromkey,
                                         endpoint=fromurl,
                                         log_level=self.mainwindow.log_level)
                    tosumo = SumoLogic(toid,
                                       tokey,
                                       endpoint=tourl,
                                       log_level=self.mainwindow.log_level)
                    for selecteditem in selecteditems:
                        for object in SAMLListWidgetFrom.currentcontent:
                            if object['configurationName'] == str(
                                    selecteditem.text()):
                                item_id = object['id']
                                saml_export = fromsumo.get_saml_config_by_id(
                                    item_id)
                                import_saml_config(saml_export, tosumo)
                                break
                    self.update_SAML_list(SAMLListWidgetTo, tourl, toid, tokey)
                return

            else:
                self.mainwindow.errorbox('You have not made any selections.')
                return

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:' + str(e))
            self.update_SAML_list(SAMLListWidgetTo, tourl, toid, tokey)
        return

    def backup_saml(self, SAMLListWidget, url, id, key):
        logger.info("[SAML]Backing Up SAML config(s)")
        selecteditems = SAMLListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            savepath = str(
                QtWidgets.QFileDialog.getExistingDirectory(
                    self, "Select Backup Directory"))
            if os.access(savepath, os.W_OK):
                message = ''
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    for object in SAMLListWidget.currentcontent:
                        if object['configurationName'] == str(
                                selecteditem.text()):
                            item_id = object['id']
                            try:

                                export = sumo.get_saml_config_by_id(item_id)

                                savefilepath = pathlib.Path(
                                    savepath + r'/' +
                                    str(selecteditem.text()) + r'.saml.json')
                                if savefilepath:
                                    with savefilepath.open(
                                            mode='w') as filepointer:
                                        json.dump(export, filepointer)
                                    message = message + str(
                                        selecteditem.text()) + r'.json' + '\n'
                            except Exception as e:
                                logger.exception(e)
                                self.mainwindow.errorbox(
                                    'Something went wrong:\n\n' + str(e))
                                return
                self.mainwindow.infobox('Wrote files: \n\n' + message)
            else:
                self.mainwindow.errorbox(
                    "You don't have permissions to write to that directory")

        else:
            self.mainwindow.errorbox('No content selected.')
        return

    def view_json(self, SAMLListWidget, url, id, key):
        logger.info("[SAML]Viewing SAML(s) as JSON")
        selecteditems = SAMLListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    for object in SAMLListWidget.currentcontent:
                        if object['configurationName'] == str(
                                selecteditem.text()):
                            item_id = object['id']
                            fer = sumo.get_saml_config_by_id(item_id)
                            json_text = json_text + json.dumps(
                                fer, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return

        else:
            self.mainwindow.errorbox('No FER selected.')
        return

    def restore_saml(self, SAMLListWidget, url, id, key):
        logger.info("[SAML]Restoring SAML config(s)")
        if SAMLListWidget.updated == True:

            filter = "JSON (*.json)"
            filelist, status = QtWidgets.QFileDialog.getOpenFileNames(
                self, "Open file(s)...", os.getcwd(), filter)
            if len(filelist) > 0:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for file in filelist:
                    try:
                        with open(file) as filepointer:
                            saml_export = json.load(filepointer)
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox(
                            "Something went wrong reading the file. Do you have the right file permissions? Does it contain valid JSON?"
                        )
                        return
                    try:
                        import_saml_config(saml_export, sumo)

                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' +
                                                 str(e))
                        return
                self.update_SAML_list(SAMLListWidget, url, id, key)

            else:
                self.mainwindow.errorbox(
                    "Please select at least one file to restore.")
                return
        else:
            self.mainwindow.errorbox(
                "Please update the SAML config list before restoring a config")
        return
Пример #8
0
class users_and_roles_tab(QtWidgets.QWidget):
    def __init__(self, mainwindow):
        super(users_and_roles_tab, self).__init__()
        self.mainwindow = mainwindow
        self.tab_name = 'Users and Roles'
        self.cred_usage = 'both'
        users_and_roles_widget_ui = os.path.join(self.mainwindow.basedir,
                                                 'data/users_and_roles.ui')
        uic.loadUi(users_and_roles_widget_ui, self)
        self.listWidgetUsersLeft.side = 'Left'
        self.listWidgetUsersRight.side = 'Right'
        self.listWidgetRolesLeft.side = 'Left'
        self.listWidgetRolesRight.side = 'Right'

        # Connect the UI buttons to methods

        # Connect Update Buttons
        self.pushButtonUpdateUsersAndRolesLeft.clicked.connect(
            lambda: self.update_users_and_roles_lists(
                self.listWidgetUsersLeft, self.listWidgetRolesLeft, self.
                mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft
                                             .currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonUpdateUsersAndRolesRight.clicked.connect(
            lambda: self.update_users_and_roles_lists(
                self.listWidgetUsersRight, self.listWidgetRolesRight, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        # Connect Search Bars
        self.lineEditSearchUsersLeft.textChanged.connect(
            lambda: self.set_listwidget_filter(
                self.listWidgetUsersLeft, self.lineEditSearchUsersLeft.text()))

        self.lineEditSearchUsersRight.textChanged.connect(
            lambda: self.set_listwidget_filter(
                self.listWidgetUsersRight, self.lineEditSearchUsersRight.text(
                )))

        self.lineEditSearchRolesLeft.textChanged.connect(
            lambda: self.set_listwidget_filter(
                self.listWidgetRolesLeft, self.lineEditSearchRolesLeft.text()))

        self.lineEditSearchRolesRight.textChanged.connect(
            lambda: self.set_listwidget_filter(
                self.listWidgetRolesRight, self.lineEditSearchRolesRight.text(
                )))

        self.pushButtonCopyUserLeftToRight.clicked.connect(
            lambda: self.copy_user(
                self.listWidgetUsersLeft, self.listWidgetUsersRight, self.
                listWidgetRolesRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonCopyUserRightToLeft.clicked.connect(
            lambda: self.copy_user(
                self.listWidgetUsersRight, self.listWidgetUsersLeft, self.
                listWidgetRolesLeft, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonBackupUserLeft.clicked.connect(lambda: self.backup_user(
            self.listWidgetUsersLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonBackupUserRight.clicked.connect(
            lambda: self.backup_user(
                self.listWidgetUsersRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonUserJSONLeft.clicked.connect(
            lambda: self.view_user_json(
                self.listWidgetUsersLeft, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonUserJSONRight.clicked.connect(
            lambda: self.view_user_json(
                self.listWidgetUsersRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonRestoreUserLeft.clicked.connect(
            lambda: self.restore_user(
                self.listWidgetRolesLeft, self.listWidgetUsersLeft, self.
                mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft
                                             .currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonRestoreUserRight.clicked.connect(
            lambda: self.restore_user(
                self.listWidgetRolesRight, self.listWidgetUsersRight, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonDeleteUserLeft.clicked.connect(lambda: self.delete_user(
            self.listWidgetRolesLeft, self.listWidgetUsersLeft, self.mainwindow
            .loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText(
            ))], str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonDeleteUserRight.clicked.connect(
            lambda: self.delete_user(
                self.listWidgetRolesRight, self.listWidgetUsersRight, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonCopyRoleLeftToRight.clicked.connect(
            lambda: self.copy_role(
                self.listWidgetRolesLeft, self.listWidgetRolesRight, self.
                listWidgetUsersRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonCopyRoleRightToLeft.clicked.connect(
            lambda: self.copy_role(
                self.listWidgetRolesRight, self.listWidgetRolesLeft, self.
                listWidgetUsersLeft, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonBackupRoleLeft.clicked.connect(lambda: self.backup_role(
            self.listWidgetRolesLeft, self.mainwindow.loadedapiurls[str(
                self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonBackupRoleRight.clicked.connect(
            lambda: self.backup_role(
                self.listWidgetRolesRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonRoleJSONLeft.clicked.connect(
            lambda: self.view_role_json(
                self.listWidgetRolesLeft, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonRoleJSONRight.clicked.connect(
            lambda: self.view_role_json(
                self.listWidgetRolesRight, self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonRestoreRoleLeft.clicked.connect(
            lambda: self.restore_role(
                self.listWidgetRolesLeft, self.listWidgetUsersLeft, self.
                mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft
                                             .currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonRestoreRoleRight.clicked.connect(
            lambda: self.restore_role(
                self.listWidgetRolesRight, self.listWidgetUsersRight, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonDeleteRoleLeft.clicked.connect(lambda: self.delete_role(
            self.listWidgetRolesLeft, self.listWidgetUsersLeft, self.mainwindow
            .loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText(
            ))], str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonDeleteRoleRight.clicked.connect(
            lambda: self.delete_role(
                self.listWidgetRolesRight, self.listWidgetUsersRight, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

    def reset_stateful_objects(self, side='both'):

        if side == 'both':
            left = True
            right = True
        if side == 'left':
            left = True
            right = False
        if side == 'right':
            left = False
            right = True

        if left:
            self.listWidgetUsersLeft.clear()
            self.listWidgetUsersLeft.currentcontent = {}
            self.listWidgetUsersLeft.updated = False
            self.listWidgetRolesLeft.clear()
            self.listWidgetRolesLeft.currentcontent = {}
            self.listWidgetRolesLeft.updated = False

        if right:
            self.listWidgetUsersRight.clear()
            self.listWidgetUsersRight.currentcontent = {}
            self.listWidgetUsersRight.updated = False
            self.listWidgetRolesRight.clear()
            self.listWidgetRolesRight.currentcontent = {}
            self.listWidgetRolesRight.updated = False

    def set_listwidget_filter(self, ListWidget, filtertext):
        for row in range(ListWidget.count()):
            item = ListWidget.item(row)
            widget = ListWidget.itemWidget(item)
            if filtertext:
                item.setHidden(not filtertext in item.text())
            else:
                item.setHidden(False)

    def update_users_and_roles_lists(self, UserListWidget, RoleListWidget, url,
                                     id, key):
        sumo = SumoLogic(id,
                         key,
                         endpoint=url,
                         log_level=self.mainwindow.log_level)
        try:
            logger.info("[Users and Roles] Updating Users and Roles Lists")
            UserListWidget.currentcontent = sumo.get_users_sync()
            RoleListWidget.currentcontent = sumo.get_roles_sync()
            self.update_users_and_roles_listwidgets(UserListWidget,
                                                    RoleListWidget)
            return
        except Exception as e:
            UserListWidget.updated = False
            RoleListWidget.updated = False
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
            return

    def update_users_and_roles_listwidgets(self, UserListWidget,
                                           RoleListWidget):
        try:
            UserListWidget.clear()
            RoleListWidget.clear()
            UserListWidget.setSortingEnabled(True)
            for object in UserListWidget.currentcontent:
                item_name = object['firstName'] + ' ' + object['lastName']
                item = QtWidgets.QListWidgetItem(item_name)
                item.details = object
                UserListWidget.addItem(
                    item)  # populate the list widget in the GUI
                if UserListWidget.side == 'Left':
                    self.set_listwidget_filter(
                        UserListWidget, self.lineEditSearchUsersLeft.text())
                elif UserListWidget.side == 'Right':
                    self.set_listwidget_filter(
                        UserListWidget, self.lineEditSearchUsersRight.text())
            UserListWidget.updated = True
            for object in RoleListWidget.currentcontent:
                item_name = object['name']
                item = QtWidgets.QListWidgetItem(item_name)
                item.details = object
                RoleListWidget.addItem(
                    item)  # populate the list widget in the GUI
                if RoleListWidget.side == 'Left':
                    self.set_listwidget_filter(
                        RoleListWidget, self.lineEditSearchRolesLeft.text())
                elif RoleListWidget.side == 'Right':
                    self.set_listwidget_filter(
                        RoleListWidget, self.lineEditSearchRolesRight.text())
            RoleListWidget.updated = True

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
            return

    def copy_user(self, UserListWidgetFrom, UserListWidgetTo, RoleListWidgetTo,
                  fromurl, fromid, fromkey, tourl, toid, tokey):

        # Need to add check if user already exists and interactively ask if any missing roles should be created
        logger.info("[Users and Roles]Copying User(s)")
        try:
            selecteditems = UserListWidgetFrom.selectedItems()
            if len(selecteditems) > 0:  # make sure something was selected
                fromsumo = SumoLogic(fromid,
                                     fromkey,
                                     endpoint=fromurl,
                                     log_level=self.mainwindow.log_level)
                tosumo = SumoLogic(toid,
                                   tokey,
                                   endpoint=tourl,
                                   log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    user_id = selecteditem.details['id']
                    user_and_roles = export_user_and_roles(user_id, fromsumo)
                    result = import_user_and_roles(user_and_roles, tosumo)

                self.update_users_and_roles_lists(UserListWidgetTo,
                                                  RoleListWidgetTo, tourl,
                                                  toid, tokey)
                return

            else:
                self.mainwindow.errorbox('You have not made any selections.')
                return

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:' + str(e))
            self.update_users_and_roles_lists(UserListWidgetTo,
                                              RoleListWidgetTo, tourl, toid,
                                              tokey)
        return

    def backup_user(self, UserListWidget, url, id, key):
        logger.info("[Users and Roles]Backing Up User(s)")
        selecteditems = UserListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            savepath = str(
                QtWidgets.QFileDialog.getExistingDirectory(
                    self, "Select Backup Directory"))
            if os.access(savepath, os.W_OK):
                message = ''
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    user_id = selecteditem.details['id']
                    try:
                        export = export_user_and_roles(user_id, sumo)

                        savefilepath = pathlib.Path(savepath + r'/' +
                                                    str(selecteditem.text()) +
                                                    r'.user.json')
                        if savefilepath:
                            with savefilepath.open(mode='w') as filepointer:
                                json.dump(export, filepointer)
                            message = message + str(
                                selecteditem.text()) + r'.json' + '\n'
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' +
                                                 str(e))
                        return
                self.mainwindow.infobox('Wrote files: \n\n' + message)
            else:
                self.mainwindow.errorbox(
                    "You don't have permissions to write to that directory")

        else:
            self.mainwindow.errorbox('No user selected.')
        return

    def view_user_json(self, UserListWidget, url, id, key):
        logger.info("[Users and Roles]Viewing User(s) JSON")
        selecteditems = UserListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    user_id = selecteditem.details['id']
                    user = sumo.get_user(user_id)
                    json_text = json_text + json.dumps(
                        user, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return
        else:
            self.mainwindow.errorbox('No user selected.')
        return

    def restore_user(self, RoleListWidget, UserListWidget, url, id, key):
        logger.info("[Users and Roles]Restoring User(s)")
        if UserListWidget.updated == True:

            filter = "JSON (*.json)"
            filelist, status = QtWidgets.QFileDialog.getOpenFileNames(
                self, "Open file(s)...", os.getcwd(), filter)
            if len(filelist) > 0:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for file in filelist:
                    try:
                        with open(file) as filepointer:
                            user = json.load(filepointer)
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox(
                            "Something went wrong reading the file. Do you have the right file permissions? Does it contain valid JSON?"
                        )
                        return
                    try:
                        result = import_user_and_roles(user, sumo)

                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' +
                                                 str(e))
                        return
                self.update_users_and_roles_lists(UserListWidget,
                                                  RoleListWidget, url, id, key)

            else:
                self.mainwindow.errorbox(
                    "Please select at least one file to restore.")
                return
        else:
            self.mainwindow.errorbox(
                "Please update the directory list before restoring content")
        return

    def delete_user(self, RoleListWidget, UserListWidget, url, id, key):
        logger.info("[Users and Roles]Deleting User(s)")
        selecteditems = UserListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            message = "You are about to delete the following item(s):\n\n"
            for selecteditem in selecteditems:
                message = message + str(selecteditem.text()) + "\n"
            message = message + '''
    This is exceedingly DANGEROUS!!!! 
    Please be VERY, VERY, VERY sure you want to do this!
    You could lose quite a bit of work if you delete the wrong thing(s).

    If you are absolutely sure, type "DELETE" in the box below.

                        '''
            text, result = QtWidgets.QInputDialog.getText(
                self, 'Warning!!', message)
            if (result and (str(text) == 'DELETE')):
                try:

                    sumo = SumoLogic(id,
                                     key,
                                     endpoint=url,
                                     log_level=self.mainwindow.log_level)
                    for selecteditem in selecteditems:
                        item_id = selecteditem.details['id']
                        result = sumo.delete_user(item_id)

                    self.update_users_and_roles_lists(UserListWidget,
                                                      RoleListWidget, url, id,
                                                      key)
                    return

                except Exception as e:
                    logger.exception(e)
                    self.mainwindow.errorbox('Something went wrong:\n\n' +
                                             str(e))

        else:
            self.mainwindow.errorbox(
                'You need to select something before you can delete it.')
        return

    def copy_role(self, RoleListWidgetFrom, RoleListWidgetTo, UserListWidgetTo,
                  fromurl, fromid, fromkey, tourl, toid, tokey):

        logger.info("[Users and Roles]Copying Role(s)")
        try:
            selecteditems = RoleListWidgetFrom.selectedItems()
            if len(selecteditems) > 0:  # make sure something was selected
                fromsumo = SumoLogic(fromid,
                                     fromkey,
                                     endpoint=fromurl,
                                     log_level=self.mainwindow.log_level)
                tosumo = SumoLogic(toid,
                                   tokey,
                                   endpoint=tourl,
                                   log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    role_id = selecteditem.details['id']
                    role = fromsumo.get_role(role_id)
                    status = tosumo.create_role(role)
                self.update_users_and_roles_lists(UserListWidgetTo,
                                                  RoleListWidgetTo, tourl,
                                                  toid, tokey)
                return

            else:
                self.mainwindow.errorbox('You have not made any selections.')
                return

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:' + str(e))
            self.update_users_and_roles_lists(UserListWidgetTo,
                                              RoleListWidgetTo, tourl, toid,
                                              tokey)
        return

    def backup_role(self, RoleListWidget, url, id, key):
        logger.info("[Users and Roles]Backing Up Role(s)")
        selecteditems = RoleListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            savepath = str(
                QtWidgets.QFileDialog.getExistingDirectory(
                    self, "Select Backup Directory"))
            if os.access(savepath, os.W_OK):
                message = ''
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    item_id = selecteditem.details['id']
                    try:
                        export = sumo.get_role(item_id)

                        savefilepath = pathlib.Path(savepath + r'/' +
                                                    str(selecteditem.text()) +
                                                    r'.role.json')
                        if savefilepath:
                            with savefilepath.open(mode='w') as filepointer:
                                json.dump(export, filepointer)
                            message = message + str(
                                selecteditem.text()) + r'.json' + '\n'
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' +
                                                 str(e))
                        return
                self.mainwindow.infobox('Wrote files: \n\n' + message)
            else:
                self.mainwindow.errorbox(
                    "You don't have permissions to write to that directory")

        else:
            self.mainwindow.errorbox('No content selected.')
        return

    def view_role_json(self, RoleListWidget, url, id, key):
        logger.info("[Users and Roles]Viewing Roles(s) JSON")
        selecteditems = RoleListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    role_id = selecteditem.details['id']
                    role = sumo.get_role(role_id)
                    json_text = json_text + json.dumps(
                        role, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return
        else:
            self.mainwindow.errorbox('No role selected.')
        return

    def restore_role(self, RoleListWidget, UserListWidget, url, id, key):
        logger.info("[Users and Roles]Restoring Role(s)")
        if RoleListWidget.updated == True:

            filter = "JSON (*.json)"
            filelist, status = QtWidgets.QFileDialog.getOpenFileNames(
                self, "Open file(s)...", os.getcwd(), filter)
            if len(filelist) > 0:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for file in filelist:
                    try:
                        with open(file) as filepointer:
                            role_backup = json.load(filepointer)
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox(
                            "Something went wrong reading the file. Do you have the right file permissions? Does it contain valid JSON?"
                        )
                        return
                    try:
                        role_backup['users'] = []
                        status = sumo.create_role(role_backup)

                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' +
                                                 str(e))
                        return
                self.update_users_and_roles_lists(UserListWidget,
                                                  RoleListWidget, url, id, key)

            else:
                self.mainwindow.errorbox(
                    "Please select at least one file to restore.")
                return
        else:
            self.mainwindow.errorbox(
                "Please update the directory list before restoring content")
        return

    def delete_role(self, RoleListWidget, UserListWidget, url, id, key):
        logger.info("[Users and Roles]Deleting Role(s)")
        selecteditems = RoleListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            message = "You are about to delete the following item(s):\n\n"
            for selecteditem in selecteditems:
                message = message + str(selecteditem.text()) + "\n"
            message = message + '''
    This is exceedingly DANGEROUS!!!! 
    Please be VERY, VERY, VERY sure you want to do this!
    You could lose quite a bit of work if you delete the wrong thing(s).

    If you are absolutely sure, type "DELETE" in the box below.

                        '''
            text, result = QtWidgets.QInputDialog.getText(
                self, 'Warning!!', message)
            if (result and (str(text) == 'DELETE')):
                try:
                    sumo = SumoLogic(id,
                                     key,
                                     endpoint=url,
                                     log_level=self.mainwindow.log_level)
                    for selecteditem in selecteditems:
                        item_id = selecteditem.details['id']
                        result = sumo.delete_role(item_id)
                    self.update_users_and_roles_lists(UserListWidget,
                                                      RoleListWidget, url, id,
                                                      key)
                    return

                except Exception as e:
                    logger.exception(e)
                    self.mainwindow.errorbox('Something went wrong:\n\n' +
                                             str(e))

        else:
            self.mainwindow.errorbox(
                'You need to select something before you can delete it.')
        return
class monitors_and_connections_tab(QtWidgets.QWidget):

    def __init__(self, mainwindow):
        super(monitors_and_connections_tab, self).__init__()
        self.mainwindow = mainwindow
        self.tab_name = 'Monitors and Connections'
        self.cred_usage = 'both'
        monitors_and_connections_widget_ui = os.path.join(self.mainwindow.basedir, 'data/monitors_and_connections.ui')
        uic.loadUi(monitors_and_connections_widget_ui, self)

        self.load_icons()
        self.reset_stateful_objects()

        # Connect the UI buttons to methods

        # Connect Update Buttons
        self.pushButtonUpdateMonitorsLeft.clicked.connect(lambda: self.update_monitors_list(
            self.listWidgetMonitorsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.labelMonitorPathLeft
        ))

        self.pushButtonUpdateMonitorsRight.clicked.connect(lambda: self.update_monitors_list(
            self.listWidgetMonitorsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.labelMonitorPathRight
        ))

        self.listWidgetMonitorsLeft.itemDoubleClicked.connect(lambda item: self.doubleclickedmonitorlist(
            item,
            self.listWidgetMonitorsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.labelMonitorPathLeft
        ))
        
        self.listWidgetMonitorsRight.itemDoubleClicked.connect(lambda item: self.doubleclickedmonitorlist(
            item,
            self.listWidgetMonitorsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.labelMonitorPathRight
        ))

        self.pushButtonParentDirMonitorsLeft.clicked.connect(lambda: self.parentdirmonitorlist(
            self.listWidgetMonitorsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.labelMonitorPathLeft
        ))
        self.pushButtonParentDirMonitorsRight.clicked.connect(lambda: self.parentdirmonitorlist(
            self.listWidgetMonitorsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.labelMonitorPathRight
        ))
        # Connect Search Bars
        self.lineEditSearchMonitorsLeft.textChanged.connect(lambda: self.set_listwidget_filter(
            self.listWidgetMonitorsLeft,
            self.lineEditSearchMonitorsLeft.text()
        ))

        self.lineEditSearchMonitorsRight.textChanged.connect(lambda: self.set_listwidget_filter(
            self.listWidgetMonitorsRight,
            self.lineEditSearchMonitorsRight.text()
        ))

        self.lineEditSearchConnectionsLeft.textChanged.connect(lambda: self.set_listwidget_filter(
            self.listWidgetConnectionsLeft,
            self.lineEditSearchConnectionsLeft.text()
        ))

        self.lineEditSearchConnectionsRight.textChanged.connect(lambda: self.set_listwidget_filter(
            self.listWidgetConnectionsRight,
            self.lineEditSearchConnectionsRight.text()
        ))

        self.pushButtonCopyMonitorLeftToRight.clicked.connect(lambda: self.copy_monitor(
            self.listWidgetMonitorsLeft,
            self.listWidgetMonitorsRight,
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.labelMonitorPathRight
        ))

        self.pushButtonCopyMonitorRightToLeft.clicked.connect(lambda: self.copy_monitor(
            self.listWidgetMonitorsRight,
            self.listWidgetMonitorsLeft,
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.labelMonitorPathLeft
        ))

        self.pushButtonMonitorNewFolderLeft.clicked.connect(lambda: self.create_folder(
            self.listWidgetMonitorsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.labelMonitorPathLeft
        ))

        self.pushButtonMonitorNewFolderRight.clicked.connect(lambda: self.create_folder(
            self.listWidgetMonitorsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.labelMonitorPathRight
        ))

        self.pushButtonBackupMonitorLeft.clicked.connect(lambda: self.backup_monitor(
            self.listWidgetMonitorsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonBackupMonitorRight.clicked.connect(lambda: self.backup_monitor(
            self.listWidgetMonitorsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))

        self.pushButtonMonitorJSONLeft.clicked.connect(lambda: self.view_monitor_json(
            self.listWidgetMonitorsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonMonitorJSONRight.clicked.connect(lambda: self.view_monitor_json(
            self.listWidgetMonitorsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))

        self.pushButtonRestoreMonitorLeft.clicked.connect(lambda: self.restore_monitor(
            self.listWidgetMonitorsLeft,
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.labelMonitorPathLeft
        ))

        self.pushButtonRestoreMonitorRight.clicked.connect(lambda: self.restore_monitor(
            self.listWidgetMonitorsRight,
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.labelMonitorPathRight
        ))

        self.pushButtonDeleteMonitorLeft.clicked.connect(lambda: self.delete_monitor(
            self.listWidgetMonitorsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.labelMonitorPathLeft

        ))

        self.pushButtonDeleteMonitorRight.clicked.connect(lambda: self.delete_monitor(
            self.listWidgetMonitorsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.labelMonitorPathRight
        ))

        self.pushButtonUpdateConnectionsLeft.clicked.connect(lambda: self.update_connection_list(
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonUpdateConnectionsRight.clicked.connect(lambda: self.update_connection_list(
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))
        
        self.pushButtonCopyConnectionLeftToRight.clicked.connect(lambda: self.copy_connection(
            self.listWidgetConnectionsLeft,
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text()),
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))

        self.pushButtonCopyConnectionRightToLeft.clicked.connect(lambda: self.copy_connection(
            self.listWidgetConnectionsRight,
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text()),
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonBackupConnectionLeft.clicked.connect(lambda: self.backup_connection(
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonBackupConnectionRight.clicked.connect(lambda: self.backup_connection(
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))

        self.pushButtonConnectionJSONLeft.clicked.connect(lambda: self.view_connection_json(
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonConnectionJSONRight.clicked.connect(lambda: self.view_connection_json(
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))

        self.pushButtonRestoreConnectionLeft.clicked.connect(lambda: self.restore_connection(
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonRestoreConnectionRight.clicked.connect(lambda: self.restore_connection(
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))

        self.pushButtonDeleteConnectionLeft.clicked.connect(lambda: self.delete_connection(
            self.listWidgetConnectionsLeft,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft.currentText())],
            str(self.mainwindow.lineEditUserNameLeft.text()),
            str(self.mainwindow.lineEditPasswordLeft.text())
        ))

        self.pushButtonDeleteConnectionRight.clicked.connect(lambda: self.delete_connection(
            self.listWidgetConnectionsRight,
            self.mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionRight.currentText())],
            str(self.mainwindow.lineEditUserNameRight.text()),
            str(self.mainwindow.lineEditPasswordRight.text())
        ))

    def reset_stateful_objects(self, side='both'):

        if side == 'both':
            left = True
            right = True
        if side == 'left':
            left = True
            right = False
        if side == 'right':
            left = False
            right = True

        if left:
            self.listWidgetMonitorsLeft.clear()
            self.listWidgetMonitorsLeft.currentcontent = {}
            self.listWidgetMonitorsLeft.currentdirlist = []
            self.listWidgetMonitorsLeft.updated = False
            self.listWidgetConnectionsLeft.clear()
            self.listWidgetConnectionsLeft.currentcontent = {}
            self.listWidgetConnectionsLeft.updated = False

        if right:
            self.listWidgetMonitorsRight.clear()
            self.listWidgetMonitorsRight.currentcontent = {}
            self.listWidgetMonitorsRight.currentdirlist = []
            self.listWidgetMonitorsRight.updated = False
            self.listWidgetConnectionsRight.clear()
            self.listWidgetConnectionsRight.currentcontent = {}
            self.listWidgetConnectionsRight.updated = False

    def load_icons(self):
        self.icons = {}
        iconpath = str(pathlib.Path(self.mainwindow.basedir + '/data/folder.svg'))
        self.icons['Folder'] = QtGui.QIcon(iconpath)
        iconpath = str(pathlib.Path(self.mainwindow.basedir + '/data/monitor.svg'))
        self.icons['Monitor'] = QtGui.QIcon(iconpath)

    def set_listwidget_filter(self, ListWidget, filtertext):
        for row in range(ListWidget.count()):
            item = ListWidget.item(row)
            widget = ListWidget.itemWidget(item)
            if filtertext:
                item.setHidden(not filtertext in item.text())
            else:
                item.setHidden(False)

    def update_monitors_list(self, MonitorsListWidget, url, id, key, directorylabel):
        sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
        logger.info("[Monitors and Connections]Updating Monitors List")
        if MonitorsListWidget.currentdirlist:
            currentdir = MonitorsListWidget.currentdirlist[-1]
        else:
            currentdir = {'name': None, 'id': 'TOP'}
        try:
            if (not MonitorsListWidget.currentcontent) or (currentdir['id'] == 'TOP'):
                MonitorsListWidget.currentdirlist = []
                dir = {'name': '/', 'id': 'TOP'}
                MonitorsListWidget.currentdirlist.append(dir)
                MonitorsListWidget.currentcontent = sumo.get_monitor_folder_root()
                self.updatemonitorlistwidget(MonitorsListWidget, directorylabel)
                return
            else:
                MonitorsListWidget.currentcontent = sumo.get_monitor(currentdir['id'])
                self.updatemonitorlistwidget(MonitorsListWidget, directorylabel)
                return

        except Exception as e:
            MonitorsListWidget.updated = False
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
            return

    def doubleclickedmonitorlist(self, item, MonitorListWidget, url, id, key, directorylabel):
        logger.info("[Monitors and Connections] Going Down One Monitor Folder")
        sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
        try:
            for child in MonitorListWidget.currentcontent['children']:
                if (child['name'] == item.text()) and (child['contentType'] == 'Folder'):
                    MonitorListWidget.currentcontent = sumo.get_monitor(child['id'])
                    dir = {'name': item.text(), 'id': child['id']}
                    MonitorListWidget.currentdirlist.append(dir)
                    self.update_monitors_list(MonitorListWidget, url, id, key, directorylabel)
                    break

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
            return

    def parentdirmonitorlist(self, MonitorListWidget, url, id, key, directorylabel):
        if MonitorListWidget.updated:
            logger.info("[Monitors and Connections] Going Up One Monitor Folder")
            sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
            currentdir = MonitorListWidget.currentdirlist[-1]
            if currentdir['id'] != 'TOP':
                parentdir = MonitorListWidget.currentdirlist[-2]
            else:
                return
            try:

                if parentdir['id'] == 'TOP':
                    MonitorListWidget.currentdirlist = []
                    self.update_monitors_list(MonitorListWidget, url, id, key, directorylabel)
                    return

                else:
                    MonitorListWidget.currentdirlist.pop()
                    MonitorListWidget.currentcontent = sumo.get_monitor(parentdir['id'])
                    self.update_monitors_list(MonitorListWidget, url, id, key, directorylabel)
                    return
                
            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))

            return

    def updatemonitorlistwidget(self, MonitorListWidget, directorylabel):
        try:
            MonitorListWidget.clear()
            for object in MonitorListWidget.currentcontent['children']:
                item_name = ''
                item_name = item_name + object['name']
                if object['contentType'] == 'Folder':
                    item = QtWidgets.QListWidgetItem(self.icons['Folder'], item_name)
                    #item.setIcon(self.icons['Folder'])
                    MonitorListWidget.addItem(item)  # populate the list widget in the GUI
                elif object['contentType'] == 'Monitor':
                    item = QtWidgets.QListWidgetItem(self.icons['Monitor'], item_name)
                    #item.setIcon(self.icons['Monitor'])
                    MonitorListWidget.addItem(item)  # populate the list widget in the GUI
                else:
                    MonitorListWidget.addItem(item_name)  # populate the list widget in the GUI with no icon (fallthrough)

            # build the string to show the current directory
            dirname = ''
            for dir in MonitorListWidget.currentdirlist:
                dirname = dirname + '/' + str(dir['name'])
            directorylabel.setText(dirname)
            MonitorListWidget.updated = True

        except Exception as e:
            MonitorListWidget.clear()
            MonitorListWidget.updated = False
            logger.exception(e)
        return

    def create_folder(self, MonitorListWidget, url, id, key, directorylabel):
        if MonitorListWidget.updated == True:

            message = '''
        Please enter the name of the folder you wish to create:

                        '''
            text, result = QtWidgets.QInputDialog.getText(self, 'Create Folder...', message)
            if result:
                for item in MonitorListWidget.currentcontent['children']:
                    if item['name'] == str(text):
                        self.mainwindow.errorbox('That Directory Name Already Exists!')
                        return
                try:

                    logger.info("[Monitors and Connections]Creating New Monitor Folder")
                    sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                    parent_id = MonitorListWidget.currentcontent['id']
                    error = sumo.create_monitor_folder(parent_id, text)
                    self.update_monitors_list(MonitorListWidget, url, id, key, directorylabel)
                    return

                except Exception as e:
                    logger.exception(e)
                    self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))

        else:
            self.mainwindow.errorbox("Please update the directory list before trying to create a new folder.")
        return
    
    def view_monitor_json(self, MonitorListWidget, url, id, key):
        logger.info("[Monitors and Connections]Viewing Monitor(s) JSON")
        selecteditems = MonitorListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    for object in MonitorListWidget.currentcontent['children']:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            user = sumo.export_monitor(item_id)
                            json_text = json_text + json.dumps(user, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text, self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return
        else:
            self.mainwindow.errorbox('No monitor selected.')
        return

    def copy_monitor(self, MonitorListWidgetFrom, MonitorListWidgetTo, ConnectionListWidgetTo, fromurl, fromid, fromkey,
                  tourl, toid, tokey, directory_label):

        # Need to add check if user already exists and interactively ask if any missing roles should be created 
        logger.info("[Monitors and Connections]Copying Monitor(s)")
        try:
            selecteditems = MonitorListWidgetFrom.selectedItems()
            if len(selecteditems) > 0:  # make sure something was selected
                fromsumo = SumoLogic(fromid, fromkey, endpoint=fromurl, log_level=self.mainwindow.log_level)
                tosumo = SumoLogic(toid, tokey, endpoint=tourl, log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    for object in MonitorListWidgetFrom.currentcontent['children']:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                    monitor = export_monitor_and_connections(item_id, fromsumo)
                    for index, connection in enumerate(monitor['connections']):
                        monitor['connections'][index]['type'] = str(connection['type']).replace('Connection',
                                                                                               'Definition')
                    parent_id = MonitorListWidgetTo.currentcontent['id']
                    if self.checkBoxCopyRestoreConnections.isChecked():
                        import_monitors_with_connections(parent_id, monitor, tosumo)
                    else:
                        import_monitors_without_connections(parent_id, monitor, tosumo)

                            
                self.update_monitors_list(MonitorListWidgetTo, tourl, toid, tokey, directory_label)
                self.update_connection_list(ConnectionListWidgetTo, tourl, toid, tokey)
                return

            else:
                self.mainwindow.errorbox('You have not made any selections.')
                return

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:' + str(e))
            self.update_monitors_list(MonitorListWidgetTo, tourl, toid, tokey, directory_label)
            self.update_connection_list(ConnectionListWidgetTo, tourl, toid, tokey)
        return

    def backup_monitor(self, MonitorListWidget, url, id, key):
        logger.info("[Monitors and Connections]Backing Up Monitors(s)")
        selecteditems = MonitorListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            savepath = str(QtWidgets.QFileDialog.getExistingDirectory(self, "Select Backup Directory"))
            if os.access(savepath, os.W_OK):
                message = ''
                sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    for object in MonitorListWidget.currentcontent['children']:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            try:
                                export = export_monitor_and_connections(item_id, sumo)
                                for index, connection in enumerate(export['connections']):
                                    export['connections'][index]['type'] = str(connection['type']).replace('Connection', 'Definition')

                                savefilepath = pathlib.Path(savepath + r'/' + str(selecteditem.text()) + r'.monitor.json')
                                if savefilepath:
                                    with savefilepath.open(mode='w') as filepointer:
                                        json.dump(export, filepointer)
                                    message = message + str(selecteditem.text()) + r'.monitor.json' + '\n'
                            except Exception as e:
                                logger.exception(e)
                                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                                return
                self.mainwindow.infobox('Wrote files: \n\n' + message)
            else:
                self.mainwindow.errorbox("You don't have permissions to write to that directory")

        else:
            self.mainwindow.errorbox('No monitor selected.')
        return



    def restore_monitor(self, MonitorListWidget, ConnectionListWidget, url, id, key, directory_label):
        logger.info("[Monitors and Connections]Restoring Monitor(s)")
        if MonitorListWidget.updated == True:

            filter = "JSON (*.json)"
            filelist, status = QtWidgets.QFileDialog.getOpenFileNames(self, "Open file(s)...", os.getcwd(),
                                                                      filter)
            if len(filelist) > 0:

                for file in filelist:
                    try:
                        with open(file) as filepointer:
                            monitor = json.load(filepointer)
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox(
                            "Something went wrong reading the file. Do you have the right file permissions? Does it contain valid JSON?")
                        return
                    try:
                        sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                        parent_id = MonitorListWidget.currentcontent['id']
                        if self.checkBoxCopyRestoreConnections.isChecked():
                            import_monitors_with_connections(parent_id ,monitor, sumo)
                        else:
                            import_monitors_without_connections(parent_id, monitor, sumo)



                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                        return
                self.update_connection_list(ConnectionListWidget, url, id, key)
                self.update_monitors_list(MonitorListWidget, url, id, key, directorylabel=directory_label)


            else:
                self.mainwindow.errorbox("Please select at least one file to restore.")
                return
        else:
            self.mainwindow.errorbox("Please update the monitor list before restoring content")
        return

    def delete_monitor(self, MonitorListWidget, url, id, key, directorylabel):
        logger.info("[Monitors and Connections]Deleting Monitor(s)")
        selecteditems = MonitorListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            message = "You are about to delete the following item(s):\n\n"
            for selecteditem in selecteditems:
                message = message + str(selecteditem.text()) + "\n"
            message = message + '''
    This is exceedingly DANGEROUS!!!! 
    Please be VERY, VERY, VERY sure you want to do this!
    You could lose quite a bit of work if you delete the wrong thing(s).

    If you are absolutely sure, type "DELETE" in the box below.

                        '''
            text, result = QtWidgets.QInputDialog.getText(self, 'Warning!!', message)
            if (result and (str(text) == 'DELETE')):
                try:

                    sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                    for selecteditem in selecteditems:
                        for object in MonitorListWidget.currentcontent['children']:
                            if object['name'] == str(selecteditem.text()):
                                item_id = object['id']

                        result = sumo.delete_monitor(item_id)

                    self.update_monitors_list(MonitorListWidget, url, id, key, directorylabel)
                    return


                except Exception as e:
                    logger.exception(e)
                    self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))

        else:
            self.mainwindow.errorbox('You need to select something before you can delete it.')
        return
    
    def update_connection_list(self, ConnectionListWidget, url, id, key):
        sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
        try:
            logger.info("[Monitors and Connections]Updating Connection List")
            ConnectionListWidget.currentcontent = sumo.get_connections_sync()
            ConnectionListWidget.clear()
            if len(ConnectionListWidget.currentcontent) > 0:
                self.update_connection_listwidget(ConnectionListWidget)
                return

        except Exception as e:
            
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
            return

    def update_connection_listwidget(self, ConnectionListWidget):
        try:
            ConnectionListWidget.clear()
            ConnectionListWidget.setSortingEnabled(True)
            for object in ConnectionListWidget.currentcontent:
                item_name = object['name']
                ConnectionListWidget.addItem(item_name)  # populate the list widget in the GUI

            ConnectionListWidget.updated = True

        except Exception as e:
            ConnectionListWidget.clear()
            ConnectionListWidget.updated = True
            logger.exception(e)
        return
    
    def copy_connection(self, ConnectionListWidgetFrom, ConnectionListWidgetTo, fromurl, fromid, fromkey,
                  tourl, toid, tokey):

        logger.info("[Monitors and Connections]Copying Connection(s)")
        try:
            selecteditems = ConnectionListWidgetFrom.selectedItems()
            if len(selecteditems) > 0:  # make sure something was selected
                fromsumo = SumoLogic(fromid, fromkey, endpoint=fromurl, log_level=self.mainwindow.log_level)
                tosumo = SumoLogic(toid, tokey, endpoint=tourl, log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    for object in ConnectionListWidgetFrom.currentcontent:
                        if object['name'] == str(selecteditem.text()):
                            connection_id = object['id']
                            connection_type = object['type']
                            connection = fromsumo.get_connection(connection_id, connection_type)
                            connection['type'] = str(connection['type']).replace('Connection', 'Definition')
                            status = tosumo.create_connection(connection)
                self.update_connection_list(ConnectionListWidgetTo, tourl, toid, tokey)
                return

            else:
                self.mainwindow.errorbox('You have not made any selections.')
                return

        except Exception as e:
            logger.exception(e)
            self.mainwindow.errorbox('Something went wrong:' + str(e))
            self.update_connection_list(ConnectionListWidgetTo, tourl, toid, tokey)
        return

    def backup_connection(self, ConnectionListWidget, url, id, key):
        logger.info("[Monitors and Connections]Backing Up Connection(s)")
        selecteditems = ConnectionListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            savepath = str(QtWidgets.QFileDialog.getExistingDirectory(self, "Select Backup Directory"))
            if os.access(savepath, os.W_OK):
                message = ''
                sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                for selecteditem in selecteditems:
                    for object in ConnectionListWidget.currentcontent:
                        if object['name'] == str(selecteditem.text()):
                            item_id = object['id']
                            item_type = object['type']
                            try:
                                export = sumo.get_connection(item_id, item_type)
                                export['type'] = str(export['type']).replace('Connection', 'Definition')

                                savefilepath = pathlib.Path(savepath + r'/' + str(selecteditem.text()) + r'.connection.json')
                                if savefilepath:
                                    with savefilepath.open(mode='w') as filepointer:
                                        json.dump(export, filepointer)
                                    message = message + str(selecteditem.text()) + r'.connection.json' + '\n'
                            except Exception as e:
                                logger.exception(e)
                                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                                return
                self.mainwindow.infobox('Wrote files: \n\n' + message)
            else:
                self.mainwindow.errorbox("You don't have permissions to write to that directory")

        else:
            self.mainwindow.errorbox('No connection selected.')
        return

    def view_connection_json(self, ConnectionListWidget, url, id, key):
        logger.info("[Monitors and Connections]Viewing Connection(s) JSON")
        selecteditems = ConnectionListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                json_text = ''
                for selecteditem in selecteditems:
                    for object in ConnectionListWidget.currentcontent:
                        if object['name'] == str(selecteditem.text()):
                            connection_id = object['id']
                            connection_type = object['type']
                            connection = sumo.get_connection(connection_id, connection_type)
                            json_text = json_text + json.dumps(connection, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text, self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                return
        else:
            self.mainwindow.errorbox('No connection selected.')
        return

    def restore_connection(self, ConnectionListWidget, url, id, key):
        logger.info("[Users and Roles]Restoring Role(s)")
        if ConnectionListWidget.updated == True:

            filter = "JSON (*.json)"
            filelist, status = QtWidgets.QFileDialog.getOpenFileNames(self, "Open file(s)...", os.getcwd(),
                                                                      filter)
            if len(filelist) > 0:
                sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                for file in filelist:
                    try:
                        with open(file) as filepointer:
                            connection_backup = json.load(filepointer)
                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox(
                            "Something went wrong reading the file. Do you have the right file permissions? Does it contain valid JSON?")
                        return
                    try:
                        status = sumo.create_connection(connection_backup)

                    except Exception as e:
                        logger.exception(e)
                        self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
                        return
                self.update_connection_list(ConnectionListWidget, url, id, key)


            else:
                self.mainwindow.errorbox("Please select at least one file to restore.")
                return
        else:
            self.mainwindow.errorbox("Please update the directory list before restoring content")
        return

    def delete_connection(self, ConnectionListWidget, url, id, key):
        logger.info("[Monitors and Connections]Deleting Connection(s)")
        selecteditems = ConnectionListWidget.selectedItems()
        if len(selecteditems) > 0:  # make sure something was selected
            message = "You are about to delete the following item(s):\n\n"
            for selecteditem in selecteditems:
                message = message + str(selecteditem.text()) + "\n"
            message = message + '''
    This is exceedingly DANGEROUS!!!! 
    Please be VERY, VERY, VERY sure you want to do this!
    You could lose quite a bit of work if you delete the wrong thing(s).

    If you are absolutely sure, type "DELETE" in the box below.

                        '''
            text, result = QtWidgets.QInputDialog.getText(self, 'Warning!!', message)
            if (result and (str(text) == 'DELETE')):
                try:

                    sumo = SumoLogic(id, key, endpoint=url, log_level=self.mainwindow.log_level)
                    for selecteditem in selecteditems:
                        for object in ConnectionListWidget.currentcontent:
                            if object['name'] == str(selecteditem.text()):
                                item_id = object['id']
                                item_type = object['type']

                        result = sumo.delete_connection(item_id, item_type)

                    self.update_connection_list(ConnectionListWidget, url, id, key)
                    return


                except Exception as e:
                    logger.exception(e)
                    self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))

        else:
            self.mainwindow.errorbox('You need to select something before you can delete it.')
        return
class collector_tab(QtWidgets.QWidget):
    def __init__(self, mainwindow):

        super(collector_tab, self).__init__()
        self.mainwindow = mainwindow
        self.tab_name = 'Collectors'
        self.cred_usage = 'both'
        collector_ui = os.path.join(self.mainwindow.basedir,
                                    'data/collector.ui')
        uic.loadUi(collector_ui, self)

        self.font = "Waree"
        self.font_size = 12
        self.load_icons()

        # UI Buttons for Collection API tab

        # Setup the search bars to work and to clear when update button is pushed
        self.lineEditCollectorSearchLeft.textChanged.connect(
            lambda: self.set_listwidget_filter(
                self.listWidgetCollectorsLeft,
                self.lineEditCollectorSearchLeft.text()))

        self.lineEditCollectorSearchRight.textChanged.connect(
            lambda: self.set_listwidget_filter(
                self.listWidgetCollectorsRight,
                self.lineEditCollectorSearchRight.text()))

        # self.pushButtonUpdateListLeft.clicked.connect(self.lineEditCollectorSearchLeft.clear)
        # self.pushButtonUpdateListRight.clicked.connect(self.lineEditCollectorSearchRight.clear)

        #

        self.pushButtonUpdateListLeft.clicked.connect(
            lambda: self.update_collector_list(
                self.listWidgetCollectorsLeft, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text()), self
                .buttonGroupFilterLeft, self.lineEditCollectorSearchLeft.text(
                )))

        self.pushButtonUpdateListRight.clicked.connect(
            lambda: self.update_collector_list(
                self.listWidgetCollectorsRight, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text()), self.
                buttonGroupFilterRight, self.lineEditCollectorSearchRight.text(
                )))

        self.buttonGroupFilterLeft.buttonClicked.connect(
            lambda: self.update_collector_listwidget(
                self.listWidgetCollectorsLeft, self.buttonGroupFilterLeft,
                self.lineEditCollectorSearchLeft.text()))

        self.buttonGroupFilterRight.buttonClicked.connect(
            lambda: self.update_collector_listwidget(
                self.listWidgetCollectorsRight, self.buttonGroupFilterRight,
                self.lineEditCollectorSearchRight.text()))

        self.pushButtonCopySourcesLeftToRight.clicked.connect(
            lambda: self.copysources(
                self.listWidgetCollectorsLeft, self.listWidgetCollectorsRight,
                self.listWidgetSourcesLeft, self.listWidgetSourcesRight, self.
                mainwindow.loadedapiurls[str(self.mainwindow.comboBoxRegionLeft
                                             .currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonCopySourcesRightToLeft.clicked.connect(
            lambda: self.copysources(
                self.listWidgetCollectorsRight, self.listWidgetCollectorsLeft,
                self.listWidgetSourcesRight, self.listWidgetSourcesLeft, self.
                mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text()
                    ), self.mainwindow.loadedapiurls[str(
                        self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonBackupCollectorLeft.clicked.connect(
            lambda: self.backupcollector(
                self.listWidgetCollectorsLeft, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonBackupCollectorRight.clicked.connect(
            lambda: self.backupcollector(
                self.listWidgetCollectorsRight, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonCollectorJSONLeft.clicked.connect(
            lambda: self.view_collector_JSON(
                self.listWidgetCollectorsLeft, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonCollectorJSONRight.clicked.connect(
            lambda: self.view_collector_JSON(
                self.listWidgetCollectorsRight, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonDeleteCollectorLeft.clicked.connect(
            lambda: self.deletecollectors(
                self.listWidgetCollectorsLeft, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonDeleteCollectorRight.clicked.connect(
            lambda: self.deletecollectors(
                self.listWidgetCollectorsRight, self.mainwindow.loadedapiurls[
                    str(self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonDeleteSourcesLeft.clicked.connect(
            lambda: self.deletesources(
                self.listWidgetCollectorsLeft, self.listWidgetSourcesLeft, self
                .mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonDeleteSourcesRight.clicked.connect(
            lambda: self.deletesources(
                self.listWidgetCollectorsRight, self.listWidgetSourcesRight,
                self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonRestoreSourcesLeft.clicked.connect(
            lambda: self.restoresources(
                self.listWidgetCollectorsLeft, self.listWidgetSourcesLeft, self
                .mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonRestoreSourcesRight.clicked.connect(
            lambda: self.restoresources(
                self.listWidgetCollectorsRight, self.listWidgetSourcesRight,
                self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        self.pushButtonSourceJSONLeft.clicked.connect(
            lambda: self.view_source_JSON(
                self.listWidgetCollectorsLeft, self.listWidgetSourcesLeft, self
                .mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.pushButtonSourceJSONRight.clicked.connect(
            lambda: self.view_source_JSON(
                self.listWidgetCollectorsRight, self.listWidgetSourcesRight,
                self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

        # set up a signal to update the source list if a new collector is set
        self.listWidgetCollectorsLeft.itemSelectionChanged.connect(
            lambda: self.update_source_list(
                self.listWidgetCollectorsLeft, self.listWidgetSourcesLeft, self
                .mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionLeft.currentText())],
                str(self.mainwindow.lineEditUserNameLeft.text()),
                str(self.mainwindow.lineEditPasswordLeft.text())))

        self.listWidgetCollectorsRight.itemSelectionChanged.connect(
            lambda: self.update_source_list(
                self.listWidgetCollectorsRight, self.listWidgetSourcesRight,
                self.mainwindow.loadedapiurls[str(
                    self.mainwindow.comboBoxRegionRight.currentText())],
                str(self.mainwindow.lineEditUserNameRight.text()),
                str(self.mainwindow.lineEditPasswordRight.text())))

    def reset_stateful_objects(self, side='both'):

        if side == 'both':
            left = True
            right = True
        if side == 'left':
            left = True
            right = False
        if side == 'right':
            left = False
            right = True

        if left:
            self.listWidgetCollectorsLeft.collectors = []
            self.listWidgetCollectorsLeft.clear()
            self.listWidgetSourcesLeft.clear()
            self.lineEditCollectorSearchLeft.clear()
            self.radioButtonFilterAllLeft.setChecked(True)

        if right:
            self.listWidgetCollectorsRight.collectors = []
            self.listWidgetCollectorsRight.clear()
            self.listWidgetSourcesRight.clear()
            self.lineEditCollectorSearchRight.clear()
            self.radioButtonFilterAllRight.setChecked(True)

    def load_icons(self):
        self.icons = {}
        iconpath = str(
            pathlib.Path(self.mainwindow.basedir +
                         '/data/hosted_collector.svg'))
        self.icons['Hosted'] = QtGui.QIcon(iconpath)
        iconpath = str(
            pathlib.Path(self.mainwindow.basedir +
                         '/data/installed_collector.svg'))
        self.icons['Installable'] = QtGui.QIcon(iconpath)

    def set_listwidget_filter(self, ListWidget, filtertext):
        for row in range(ListWidget.count()):
            item = ListWidget.item(row)
            widget = ListWidget.itemWidget(item)
            if filtertext:
                item.setHidden(not filtertext in item.text())
            else:
                item.setHidden(False)

    def getcollectorid(self, collectorname, url, id, key):
        logger.info("[Collectors] Getting Collector IDs")
        sumo = SumoLogic(id,
                         key,
                         endpoint=url,
                         log_level=self.mainwindow.log_level)
        try:
            sumocollectors = sumo.get_collectors_sync()

            for sumocollector in sumocollectors:
                if sumocollector['name'] == collectorname:
                    return sumocollector['id']
        except Exception as e:
            logger.exception(e)
        return

    def getsourceid(self, collectorid, sourcename, url, id, key):
        logger.info("[Collectors] Getting Source IDs")
        sumo = SumoLogic(id,
                         key,
                         endpoint=url,
                         log_level=self.mainwindow.log_level)
        try:
            sumosources = sumo.sources(collectorid)

            for sumosource in sumosources:
                if 'name' in sumosource and sumosource['name'] == sourcename:
                    return sumosource['id']
                elif 'config' in sumosource and sumosource['config'][
                        'name'] == sourcename:
                    return sumosource['id']
            return False
        except Exception as e:
            logger.exception(e)
        return

    def update_collector_list(self, CollectorListWidget, url, id, key,
                              radiobuttongroup, filter_text):
        logger.info("[Collectors] Updating Collector List")
        regexprog = re.compile(
            r'\S+')  # make sure username and password have something in them
        if (re.match(regexprog, id) != None) and (re.match(regexprog, key) !=
                                                  None):
            # access the API with provided credentials
            sumo = SumoLogic(id,
                             key,
                             endpoint=url,
                             log_level=self.mainwindow.log_level)
            try:
                CollectorListWidget.collectors = sumo.get_collectors_sync(
                )  # get list of collectors
                self.update_collector_listwidget(CollectorListWidget,
                                                 radiobuttongroup, filter_text)
            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
        else:
            self.mainwindow.errorbox('No user and/or password.')
        return

    def update_collector_listwidget(self, CollectorListWidget,
                                    radiobuttongroup, filter_text):
        CollectorListWidget.clear(
        )  # clear the list first since it might already be populated
        for collector in CollectorListWidget.collectors:
            try:
                item = QtWidgets.QListWidgetItem(
                    self.icons[collector['collectorType']], collector['name'])
            except Exception as e:
                item = QtWidgets.QListWidgetItem(collector['name'])
                logger.info(e)

            if (collector['collectorType']
                    == "Installable") and (collector['alive'] == False):
                item.setFont(
                    QtGui.QFont(self.font,
                                pointSize=self.font_size,
                                italic=True))

            if radiobuttongroup.checkedId() == -2:  # Show all collectors
                CollectorListWidget.addItem(
                    item)  # populate the list widget in the GUI
            elif radiobuttongroup.checkedId(
            ) == -3:  # Show only hosted collectors
                if collector['collectorType'] == "Hosted":
                    CollectorListWidget.addItem(
                        item)  # populate the list widget in the GUI
            elif radiobuttongroup.checkedId(
            ) == -4:  # Show only installed collectors
                if collector['collectorType'] == "Installable":
                    CollectorListWidget.addItem(
                        item)  # populate the list widget in the GUI
            elif radiobuttongroup.checkedId(
            ) == -5:  # Show only dead collectors
                if (collector['collectorType']
                        == "Installable") and (collector['alive'] == False):
                    CollectorListWidget.addItem(
                        item)  # populate the list widget in the GUI
            else:
                logger.info(
                    '[Collectors]Fell through conditions in update_list_widget'
                )
        self.set_listwidget_filter(CollectorListWidget, filter_text)

    def update_source_list(self, CollectorListWidget, SourceListWidget, url,
                           id, key):
        logger.info("[Collectors] Updating Source List")
        SourceListWidget.clear(
        )  # clear the list first since it might already be populated
        collectors = CollectorListWidget.selectedItems()
        if (len(collectors) > 1) or (len(collectors) < 1):
            return
        else:
            collector = self.getcollectorid(collectors[0].text(), url, id, key)
            sumo = SumoLogic(id,
                             key,
                             endpoint=url,
                             log_level=self.mainwindow.log_level)
            # populate the list of sources
            sources = sumo.sources(collector)
            for source in sources:
                if 'name' in source:
                    SourceListWidget.addItem(
                        source['name'])  # populate the display with sources
                elif 'config' in source:
                    SourceListWidget.addItem(
                        source['config']
                        ['name'])  # populate the display with sources
        return

    def copysources(self, CollectorListWidgetFrom, CollectorListWidgetTo,
                    SourceListWidgetFrom, SourceListWidgetTo, fromurl, fromid,
                    fromkey, tourl, toid, tokey):
        logger.info("[Collectors] Copying Sources")
        try:
            fromsumo = SumoLogic(fromid,
                                 fromkey,
                                 endpoint=fromurl,
                                 log_level=self.mainwindow.log_level)
            sourcecollectorlist = CollectorListWidgetFrom.selectedItems(
            )  # get the selected source collector
            if len(
                    sourcecollectorlist
            ) == 1:  # make sure there is a collector selected, otherwise bail
                sourcecollector = sourcecollectorlist[0].text(
                )  # qstring to string conversion
                sourcecollectorid = self.getcollectorid(
                    sourcecollector, fromurl, fromid, fromkey)
                destinationcollectorlist = CollectorListWidgetTo.selectedItems(
                )  # get the selected dest collector
                if len(
                        destinationcollectorlist
                ) > 0:  # make sure there is a collector selected, otherwise bail
                    fromsources = SourceListWidgetFrom.selectedItems(
                    )  # get the selected sources
                    if len(fromsources
                           ) > 0:  # make sure at least one source is selected
                        fromsourcelist = []
                        for fromsource in fromsources:  # iterate through source names to build a warning message
                            fromsourcelist.append(fromsource.text())
                    else:
                        self.mainwindow.errorbox('No Sources Selected.')
                        return
                    destinationcollectorstring = ''
                    for destinationcollector in destinationcollectorlist:
                        destinationcollectorstring = destinationcollectorstring + destinationcollector.text(
                        ) + ", "
                    message = "You are about to copy the following sources from collector \"" + sourcecollector + "\" to \"" + destinationcollectorstring + "\". Is this correct? \n\n"
                    for source in fromsourcelist:
                        message = message + source + "\n"
                    result = QtWidgets.QMessageBox.question(
                        self, 'Really Copy?', message,
                        QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                        QtWidgets.QMessageBox.No)  # bring up the copy dialog
                    if result:  # If they clicked "OK" rather than cancel
                        tosumo = SumoLogic(toid,
                                           tokey,
                                           endpoint=tourl,
                                           log_level=self.mainwindow.log_level)
                        for destinationcollector in destinationcollectorlist:
                            destinationcollectorname = destinationcollector.text(
                            )
                            destinationcollectorid = self.getcollectorid(
                                destinationcollectorname, tourl, toid,
                                tokey)  # qstring to string conversion
                            sumosources = fromsumo.sources(sourcecollectorid)
                            for source in fromsourcelist:  # iterate through the selected sources and copy them
                                for sumosource in sumosources:
                                    # if sumosource['name'] == source:
                                    if ('name' in sumosource
                                            and source == sumosource['name']
                                        ) or ('config' in sumosource and source
                                              == sumosource['config']['name']):
                                        if 'id' in sumosource:  # the API creates an ID so this must be deleted before sending
                                            del sumosource['id']
                                        if 'alive' in sumosource:
                                            del sumosource[
                                                'alive']  # the API sets this itself so this must be deleted before sending
                                        template = {}
                                        template[
                                            'source'] = sumosource  # the API expects a dict with a key called 'source'
                                        notduplicate = True
                                        sumotosourcelist = tosumo.sources(
                                            destinationcollectorid)
                                        for sumotosource in sumotosourcelist:
                                            # make sure the source doesn't already exist in the destination
                                            if ('name' in sumotosource
                                                    and sumotosource['name']
                                                    == source
                                                ) or ('config' in sumotosource
                                                      and
                                                      sumotosource['config']
                                                      ['name'] == source):
                                                notduplicate = False
                                        if notduplicate:  # finally lets copy this thing
                                            tosumo.create_source(
                                                destinationcollectorid,
                                                template)
                                        else:
                                            self.mainwindow.errorbox(
                                                source +
                                                ' already exists, skipping.')
                        # call the update method for the dest collector since they have changed after the copy
                        if len(destinationcollectorlist) > 1:
                            self.mainwindow.infobox(
                                "Copy Complete. Please select an individual destination collector to see an updated source list."
                            )

                        else:
                            self.update_source_list(CollectorListWidgetTo,
                                                    SourceListWidgetTo, tourl,
                                                    toid, tokey)

                else:
                    self.mainwindow.errorbox(
                        'You Must Select at Least 1 target.')
            else:
                self.mainwindow.errorbox('No Source Collector Selected.')
        except Exception as e:
            self.mainwindow.errorbox(
                'Encountered a bug. Check the console output.')
            logger.exception(e)
        return

    def backupcollector(self, CollectorListWidget, url, id, key):
        logger.info("[Collectors] Backing Up Collector")
        collectornamesqstring = CollectorListWidget.selectedItems(
        )  # get collectors sources have been selected
        if len(collectornamesqstring) > 0:  # make sure something was selected
            savepath = str(
                QtWidgets.QFileDialog.getExistingDirectory(
                    self, "Select Backup Directory"))
            if os.access(savepath, os.W_OK):
                message = ''
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for collectornameqstring in collectornamesqstring:
                    collectorid = self.getcollectorid(
                        str(collectornameqstring.text()), url, id, key)
                    savefilepath = pathlib.Path(
                        savepath + r'/' + str(collectornameqstring.text()) +
                        r'.collector.json')
                    savefilesourcespath = pathlib.Path(
                        savepath + r'/' + str(collectornameqstring.text()) +
                        r'_sources' + r'.sources.json')

                    if savefilepath:
                        with savefilepath.open(mode='w') as filepointer:
                            collector, _ = sumo.get_collector_by_id(
                                collectorid)
                            json.dump(collector, filepointer)
                    if savefilesourcespath:
                        with savefilesourcespath.open(mode='w') as filepointer:
                            json.dump(sumo.sources(collectorid), filepointer)
                    message = message + str(collectornameqstring.text()) + ' '
                self.mainwindow.infobox('Wrote files ' + message)
            else:
                self.mainwindow.errorbox(
                    "You don't have permissions to write to that directory")

        else:
            self.mainwindow.errorbox('No Source Collector Selected.')
        return

    def view_collector_JSON(self, CollectorListWidget, url, id, key):
        logger.info("[Collectors] Viewing Collector JSON")
        collectornamesqstring = CollectorListWidget.selectedItems(
        )  # get collectors sources have been selected
        if len(collectornamesqstring) > 0:  # make sure something was selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                for collectornameqstring in collectornamesqstring:
                    collector = sumo.get_collector_by_name_alternate(
                        str(collectornameqstring.text()))
                    # sources = sumo.get_sources_sync(collector['id'])
                    json_text = json_text + json.dumps(
                        collector, indent=4, sort_keys=True) + '\n\n'
                    # json_text = json_text + json.dumps(sources, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()
            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))
        else:
            self.mainwindow.errorbox('No Collector Selected.')
        return

    def view_source_JSON(self, CollectorListWidget, SourceListWidget, url, id,
                         key):
        logger.info("[Collectors] Viewing Source JSON")
        sourcenames = SourceListWidget.selectedItems()
        if len(sourcenames) > 0:  # make sure at least one source is selected
            try:
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                json_text = ''
                collectornamesqstring = CollectorListWidget.selectedItems(
                )  # get collectors sources have been selected
                collectorname = str(collectornamesqstring[0].text())
                collector = sumo.get_collector_by_name_alternate(collectorname)
                sources = sumo.get_sources_sync(collector['id'])
                for sourcename in sourcenames:
                    for source in sources:
                        if ('name' in source
                                and str(sourcename.text()) == source['name']
                            ) or ('config' in source and str(sourcename.text())
                                  == source['config']['name']):
                            json_text = json_text + json.dumps(
                                source, indent=4, sort_keys=True) + '\n\n'
                self.json_window = ShowTextDialog('JSON', json_text,
                                                  self.mainwindow.basedir)
                self.json_window.show()

            except Exception as e:
                logger.exception(e)
                self.mainwindow.errorbox('Something went wrong:\n\n' + str(e))

        else:
            self.mainwindow.errorbox('No Source Selected.')

    def deletecollectors(self, CollectorListWidget, url, id, key):
        logger.info("[Collectors] Deleting Collectors")
        collectornamesqstring = CollectorListWidget.selectedItems()
        if len(collectornamesqstring) > 0:  # make sure something was selected
            message = "You are about to delete the following collector(s):\n\n"
            for collectornameqstring in collectornamesqstring:
                message = message + str(collectornameqstring.text()) + "\n"
            message = message + '''
This is exceedingly DANGEROUS!!!! 
Please be VERY, VERY, VERY sure you want to do this!
Even if you have backed up your collectors to file you CANNOT
restore installed collectors using this tool or the Sumo Logic API.

If you are absolutely sure, type "DELETE" in the box below.

            '''
            text, result = QtWidgets.QInputDialog.getText(
                self, 'Warning!!', message)
            if (result and (str(text) == 'DELETE')):
                sumo = SumoLogic(id,
                                 key,
                                 endpoint=url,
                                 log_level=self.mainwindow.log_level)
                for collectornameqstring in collectornamesqstring:
                    try:
                        collectorid = self.getcollectorid(
                            str(collectornameqstring.text()), url, id, key)
                        sumo.delete_collector(collectorid)
                    except Exception as e:
                        self.mainwindow.errorbox(
                            'Failed to delete collector: ' +
                            str(collectornamesqstring.text()))
                        logger.exception(e)
                self.update_collector_list(CollectorListWidget, url, id, key)

        else:
            self.mainwindow.errorbox('No Collector Selected')
        return

    def restoresources(self, CollectorListWidget, SourceListWidget, url, id,
                       key):
        destinationcollectors = CollectorListWidget.selectedItems()
        if len(destinationcollectors) == 1:
            destinationcollectorqstring = destinationcollectors[0].text()
            destinationcollector = str(destinationcollectorqstring)
            destinationcollectorid = self.getcollectorid(
                destinationcollector, url, id, key)
            filter = "JSON (*.json)"
            restorefile, status = QtWidgets.QFileDialog.getOpenFileName(
                self, "Open file(s)...", os.getcwd(), filter)
            sources = None
            try:
                with open(restorefile) as data_file:
                    sources = json.load(data_file)
            except Exception as e:
                self.mainwindow.errorbox('Failed to load JSON file.')
                logger.exception(e)

            # a sources save file from the UI looks a little different than a save file from this tool, fix it here
            if sources:
                if 'sources' in sources:
                    sources = sources['sources']
                dialog = restoreSourcesDialog(sources)
                dialog.exec()
                dialog.show()
                if str(dialog.result()) == '1':
                    selectedsources = dialog.getresults()
                else:
                    return
                if len(selectedsources) > 0:
                    sumo = SumoLogic(id,
                                     key,
                                     endpoint=url,
                                     log_level=self.mainwindow.log_level)
                    for selectedsource in selectedsources:
                        for sumosource in sources:
                            if ('name' in sumosource and sumosource['name']
                                    == str(selectedsource)) or (
                                        'config' in sumosource
                                        and sumosource['config']['name']
                                        == str(selectedsource)):
                                if 'id' in sumosource:
                                    del sumosource['id']
                                if 'alive' in sumosource:
                                    del sumosource['alive']
                                template = {}
                                template['source'] = sumosource
                                sumo.create_source(destinationcollectorid,
                                                   template)
                    self.update_source_list(CollectorListWidget,
                                            SourceListWidget, url, id, key)
                else:
                    self.mainwindow.errorbox('No sources selected for import.')
        else:
            self.mainwindow.errorbox(
                'Please select 1 and only 1 collector to restore sources to.')
        return

    def deletesources(self, CollectorListWidget, SourceListWidget, url, id,
                      key):
        logger.info("[Collectors] Deleting Sources")
        collectornamesqstring = CollectorListWidget.selectedItems()
        if len(collectornamesqstring) == 1:  # make sure something was selected
            collectorid = self.getcollectorid(
                str(collectornamesqstring[0].text()), url, id, key)
            sourcenamesqstring = SourceListWidget.selectedItems()
            if len(sourcenamesqstring) > 0:  # make sure something was selected
                message = "You are about to delete the following source(s):\n\n"
                for sourcenameqstring in sourcenamesqstring:
                    message = message + str(sourcenameqstring.text()) + "\n"
                message = message + '''
This could be exceedingly DANGEROUS!!!! 
Please be VERY, VERY, VERY sure you want to do this!

If you are absolutely sure, type "DELETE" in the box below.

                        '''
                text, result = QtWidgets.QInputDialog.getText(
                    self, 'Warning!!', message)
                if (result and (str(text) == 'DELETE')):
                    sumo = SumoLogic(id,
                                     key,
                                     endpoint=url,
                                     log_level=self.mainwindow.log_level)
                    for sourcenameqstring in sourcenamesqstring:
                        try:
                            sourceid = self.getsourceid(
                                collectorid, str(sourcenameqstring.text()),
                                url, id, key)
                            sumo.delete_source(collectorid, sourceid)
                        except Exception as e:
                            self.mainwindow.errorbox(
                                'Failed to delete source: ' +
                                str(sourcenameqstring.text()))
                            logger.exception(e)
                    self.update_source_list(CollectorListWidget,
                                            SourceListWidget, url, id, key)

            else:
                self.mainwindow.errorbox('No Source(s) Selected')
        else:
            self.mainwindow.errorbox('You must select 1 and only 1 collector.')
        return