def getCommands(calendarName, worker_name): """ CELERY remote task List worker registered tools in configuration folder. Store the results in mongo database in pollenisator.workers database. """ mongoInstance = MongoCalendar.getInstance() mongoInstance.connectToDb(calendarName) tools_to_register = Utils.loadToolsConfig() print("Registering commands : " + str(list(tools_to_register.keys()))) mongoInstance.registerCommands(worker_name, list(tools_to_register.keys())) return
def openModifyWindow(self): """ Creates a tkinter form using Forms classes. This form aims to update or delete an existing Tool """ modelData = self.controller.getData() top_panel = self.form.addFormPanel(grid=True) top_panel.addFormLabel("Name", modelData["name"]) dates_panel = self.form.addFormPanel(grid=True) dates_panel.addFormLabel("Start date") dates_panel.addFormDate("Start date", self.mainApp, modelData["dated"], column=1) dates_panel.addFormLabel("End date", row=1) dates_panel.addFormDate("End date", self.mainApp, modelData["datef"], row=1, column=1) dates_panel.addFormLabel("Scanner", row=2) dates_panel.addFormStr("Scanner", r"", modelData["scanner_ip"], row=2, column=1) dates_panel.addFormLabel("Command executed", row=3) dates_panel.addFormStr("Command executed", "", modelData["text"], row=3, column=1, state="disabled") notes = modelData.get("notes", "") top_panel = self.form.addFormPanel() top_panel.addFormLabel("Notes", side="top") top_panel.addFormText("Notes", r"", notes, None, side="top", height=15) actions_panel = self.form.addFormPanel() #Ready is legacy, OOS and/or OOT should be used if "ready" in self.controller.getStatus(): actions_panel.addFormButton("Local launch", self.localLaunchCallback, side="right") if self.mainApp.scanManager.monitor.hasWorkers(): actions_panel.addFormButton("Run on worker", self.launchCallback, side="right") else: actions_panel.addFormLabel( "Info", "Tool is ready but no celery worker found", side="right") elif "OOS" in self.controller.getStatus( ) or "OOT" in self.controller.getStatus(): actions_panel.addFormButton("Local launch", self.localLaunchCallback, side="right") if self.mainApp.scanManager.monitor.hasWorkers(): actions_panel.addFormButton("Run on worker", self.launchCallback, side="right") else: actions_panel.addFormLabel( "Info", "Tool is ready but no celery worker found", side="right") elif "running" in self.controller.getStatus(): actions_panel.addFormButton("Stop", self.stopCallback, side="right") elif "done" in self.controller.getStatus(): actions_panel.addFormButton("Download result file", self.downloadResultFile, side="right") tools_infos = Utils.loadToolsConfig() try: mod = Utils.loadPlugin( tools_infos[self.controller.getName()]["plugin"]) pluginActions = mod.getActions(self.controller.model) except KeyError: # Happens when parsed an existing file.: pluginActions = None if pluginActions is not None: for pluginAction in pluginActions: actions_panel.addFormButton(pluginAction, pluginActions[pluginAction], side="right") actions_panel.addFormButton("Reset", self.resetCallback, side="right") defect_panel = self.form.addFormPanel(grid=True) defect_panel.addFormButton("Create defect", self.createDefectCallback) self.completeModifyWindow()
def executeCommand(calendarName, toolId, parser=""): """ CELERY remote task Execute the tool with the given toolId on the given calendar name. Then execute the plugin corresponding. Any unhandled exception will result in a task-failed event in the Monitor class. Args: calendarName: The calendar to search the given tool id for. toolId: the mongo Object id corresponding to the tool to execute. parser: plugin name to execute. If empty, the plugin specified in tools.d will be feteched. Raises: Terminated: if the task gets terminated OSError: if the output directory cannot be created (not if it already exists) Exception: if an exception unhandled occurs during the bash command execution. Exception: if a plugin considered a failure. """ # Connect to given calendar mongoInstance = MongoCalendar.getInstance() mongoInstance.connectToDb(calendarName) msg = "" # retrieve tool from tool sid toolModel = Tool.fetchObject({"_id": ObjectId(toolId)}) if toolModel is None: raise Exception("Tool does not exist : " + str(toolId)) command = Command.fetchObject({"name": toolModel.name}, calendarName) # Get time limit and output directory if toolModel.wave == "Custom commands": timeLimit = None else: timeLimit = getWaveTimeLimit(toolModel.wave) if command is not None: timeLimit = min(datetime.now() + timedelta(0, int(command.timeout)), timeLimit) outputRelDir = toolModel.getOutputDir(calendarName) abs_path = os.path.dirname(os.path.abspath(__file__)) outputDir = os.path.join(abs_path, "./results", outputRelDir) # Create the output directory try: os.makedirs(outputDir) except OSError as exc: if exc.errno == errno.EEXIST and os.path.isdir(outputDir): pass else: raise exc # Read Tool config file tools_infos = Utils.loadToolsConfig() comm = toolModel.getCommandToExecute(outputDir) if parser.strip() == "": if toolModel.name not in list(tools_infos.keys()): msg = "TASK FAILED Received tool that was not registered : " + \ str(toolModel.name)+" not in "+str(list(tools_infos.keys())) raise Exception(msg) # Fetch the command to execute if tools_infos.get(toolModel.name, None) is None: bin_path = "" else: bin_path = tools_infos[toolModel.name].get("bin") if bin_path is not None: if not bin_path.endswith(" "): bin_path = bin_path + " " comm = bin_path + comm if comm != "": try: # Load the plugin if parser.strip() == "": mod = Utils.loadPlugin(tools_infos[toolModel.name]["plugin"]) elif parser.strip() == "auto-detect": mod = Utils.loadPluginByBin(toolModel.name.split("::")[0]) else: mod = Utils.loadPlugin(parser) # Complete command with file output toolFileName = toolModel.name+"_" + \ str(time.time())+mod.getFileOutputExt() comm = mod.changeCommand(comm, outputDir, toolFileName) print(('TASK STARTED:' + toolModel.name)) print("Will timeout at " + str(timeLimit)) # Execute the command with a timeout returncode = Utils.execute(comm, timeLimit, True) except Exception as e: raise e # Execute found plugin if there is one if mod is not None: filepath = mod.getFileOutputPath(comm) try: # Open generated file as utf8 with io.open(filepath, "r", encoding="utf-8", errors='ignore') as file_opened: # Check return code by plugin (can be always true if the return code is inconsistent) if mod.checkReturnCode(returncode): notes, tags, _, _ = mod.Parse(file_opened) if notes is None: notes = "No results found by plugin." if tags is None: tags = [] if isinstance(tags, str): tags = [tags] # Success could be change to False by the plugin function (evaluating the return code for exemple) # if the success is validated, mark tool as done toolModel.markAsDone( os.path.join(outputRelDir, os.path.basename(filepath))) # And update the tool in database toolModel.notes = notes toolModel.tags = tags toolModel.update() # Upload file to SFTP mod.centralizeFile(filepath, outputDir) msg = "TASK SUCCESS : " + toolModel.name else: # BAS RESULT OF PLUGIN msg = "TASK FAILED (says the mod) : " + toolModel.name msg += "The return code was not the expected one. (" + str( returncode) + ")." toolModel.markAsError() raise Exception(msg) except IOError as e: toolModel.tags = ["todo"] toolModel.notes = "Failed to read results file" toolModel.markAsDone() else: msg = "TASK FAILED (no plugin found) : " + toolModel.name toolModel.markAsNotDone() raise Exception(msg) # Delay if command is not None: if float(command.sleep_between) > 0.0: msg += " (will sleep for " + \ str(float(command.sleep_between))+")" print(msg) time.sleep(float(command.sleep_between)) return
def editToolConfig(command_name, remote_bin, plugin): tools_to_register = Utils.loadToolsConfig() tools_to_register[command_name] = {"bin": remote_bin, "plugin": plugin} Utils.saveToolsConfig(tools_to_register)