def add(self, task): app.logger.info("Try to enqueue into {}: task={}".format( self.progress, task)) task["progress"] = TaskProgress.STOPPED.name task["ended_at"] = self.now # Update task progress TaskTable.update(task).where(TaskTable.uuid == task["uuid"]).execute() app.logger.info("Enqueued into {} successfully: task={}".format( self.progress, task["uuid"])) return
def poll(self): # Get all task entries that progress matches the task queue name, e.g., PENDING. task_query = (TaskTable.select( TaskTable, ScanTable.uuid.alias("scan_exists")).join( ScanTable, JOIN.LEFT_OUTER, on=(TaskTable.uuid == ScanTable.task_uuid)).where( TaskTable.progress == self.progress).order_by( TaskTable.updated_at.asc())) for task in task_query.dicts(): try: # Task UUID changes if the task is cancelled/rescheduled by user. # Here we cancel a task that is no longer connected to any scan entries. if task.pop("scan_exists") is None: raise Exception( "Cancelled: scan has been cancelled/rescheduled by user" ) # Cancel the task if that scan period has already elapsed scheduled_at = task["scheduled_at"].replace(tzinfo=pytz.utc) if self.now > (scheduled_at + timedelta(hours=task["max_duration"])): raise Exception("Cancelled: scheduled period has elapsed") # Call task process function prepared by each handler app.logger.info("Do process: task={}".format(task["uuid"])) self.process(task) except Exception as error: app.logger.warn("ERROR: task={}, error={}".format( task["uuid"], error)) self.finish(task, error)
async def insert_task(request: Request, content: str = Form(...), deadline: str = Form(...), credentials: HTTPBasicCredentials = Depends(security)): """ タスクを追加してJsonで追加したタスク情報を返す deadlineは %Y-%m-%d_%H:%M:%S (e.g. 2020-06-18_12:30:00) """ # 認証 username = basic_auth(credentials) # ユーザー情報を取得 user = db.session.query(UserTable).filter( UserTable.username == username).first() # タスクを追加 task = TaskTable(user.id, content, datetime.strptime(deadline, '%Y-%m-%d_%H:%M:%S')) db.session.add(task) db.session.commit() # 新しく追加したタスクを取得 new_task = db.session.query(TaskTable).all()[-1] db.session.close() # 新規タスクをJsonで返す return { 'id': new_task.id, 'content': new_task.content, 'deadline': new_task.deadline.strftime('%Y-%m-%d_%H:%M:%S'), 'published': new_task.date.strftime('%Y-%m-%d_%H:%M:%S'), 'done': new_task.done, }
async def add_task(request: Request, credentials: HTTPBasicCredentials = Depends(security)): # 認証 username = basic_auth(credentials) # ユーザー情報を取得 user = db.session.query(UserTable).filter( UserTable.username == username).first() # フォームからきたデータ取得 data = await request.form() print(data) year = int(data['year']) month = int(data['month']) day = int(data['day']) hour = int(data['hour']) minute = int(data['minute']) deadline = datetime(year=year, month=month, day=day, hour=hour, minute=minute) # 新しくタスクを作成しDBコミット task = TaskTable(user.id, data['content'], deadline) db.session.add(task) db.session.commit() db.session.close() return RedirectResponse('/admin')
def add(self, task): app.logger.info("Try to enqueue into {}: task={}".format( self.progress, task)) detector = dtm.load_detector(task["detection_module"], task["session"]) session = detector.run(task["target"], task["detection_mode"]) task["session"] = session task["progress"] = TaskProgress.RUNNING.name task["started_at"] = self.now with db.database.atomic(): # Update task progress TaskTable.update(task).where( TaskTable.uuid == task["uuid"]).execute() # Reflect started time to corresponding scan entry ScanTable.update({ "started_at": self.now }).where(ScanTable.task_uuid == task["uuid"]).execute() im.send(NotificationType.START, task) app.logger.info("Enqueued into {} successfully: task={}".format( self.progress, task["uuid"])) return
def finish(self, task, error_reason=""): app.logger.info("Try to delete: task={}, error_reason={}".format( task, error_reason)) if task["session"] is not None: detector = dtm.load_detector(task["detection_module"], task["session"]) detector.delete() with db.database.atomic(): TaskTable.delete().where(TaskTable.uuid == task["uuid"]).execute() # Here we use task uuid for finding corresponding scan entry # because task uuid of scan entry is changed by user's re-schedule ScanTable.update({ "scheduled_at": None, "task_uuid": None, "error_reason": error_reason }).where(ScanTable.task_uuid == task["uuid"]).execute() if error_reason != "": im.send(NotificationType.ERROR, task) app.logger.info( "Deleted successfully: task={}, error_reason={}".format( task["uuid"], error_reason))
def add(self, scan): app.logger.info("Try to enqueue into {}: scan={}".format(self.progress, scan)) detector = dtm.load_detector(scan["detection_module"], None) if detector.TARGET_TYPE == DetectionTarget.HOST.value: validate_host(scan["target"]) elif detector.TARGET_TYPE == DetectionTarget.URL.value: scan["target"] = get_safe_url(scan["target"]) # Avoid concurrent scanning for the same target task_query = TaskTable.select().where(TaskTable.target == scan["target"]) if task_query.count() > 0: app.logger.info( "Abandoned to enqueue scan={} because another scan for '{}' is still running".format( scan["id"], scan["target"] ) ) return None session = detector.create() task = { "audit_id": scan["audit_id"], "scan_id": scan["id"], "scan_uuid": scan["uuid"], "target": scan["target"], "scheduled_at": scan["scheduled_at"], "max_duration": scan["max_duration"], "detection_module": scan["detection_module"], "detection_mode": scan["detection_mode"], "session": session, "progress": TaskProgress.PENDING.name, } task = TaskTable(**task) task.save() app.logger.info("Enqueued into {} successfully: scan={}".format(self.progress, scan["id"])) return task