def launch_asynchronous(scanid): log.debug("scanid: %s", scanid) with session_transaction() as session: scan = Scan.load_from_ext_id(scanid, session=session) IrmaScanStatus.filter_status(scan.status, IrmaScanStatus.ready, IrmaScanStatus.ready) scan_request = _create_scan_request(scan.files_web, scan.get_probelist(), scan.mimetype_filtering) scan_request = _add_empty_results(scan.files_web, scan_request, scan, session) # Nothing to do if scan_request.nb_files == 0: scan.set_status(IrmaScanStatus.finished) session.commit() log.warning("scanid: %s finished nothing to do", scanid) return try: upload_list = list() for file in scan.files: upload_list.append(file.path) ftp_ctrl.upload_scan(scanid, upload_list) except IrmaFtpError as e: log.error("scanid: %s ftp upload error %s", scanid, str(e)) scan.set_status(IrmaScanStatus.error_ftp_upload) session.commit() return # launch new celery scan task on brain celery_brain.scan_launch(scanid, scan_request.to_dict()) scan.set_status(IrmaScanStatus.uploaded) session.commit() log.info("scanid: %s uploaded", scanid) return
def check_probe(scan, probelist, session): """ check_probe specified scan :param scanid: id returned by scan_new :rtype: dict of 'code': int, 'msg': str [, optional 'probe_list':list] :return: on success 'probe_list' is the list of probes used for the scan on error 'msg' gives reason message :raise: IrmaDataBaseError, IrmaValueError """ IrmaScanStatus.filter_status(scan.status, IrmaScanStatus.ready, IrmaScanStatus.ready) all_probe_list = celery_brain.probe_list() if probelist is not None: unknown_probes = [] for p in probelist: if p not in all_probe_list: unknown_probes.append(p) if len(unknown_probes) != 0: reason = "probe {0} unknown".format(", ".join(unknown_probes)) raise IrmaValueError(reason) else: probelist = all_probe_list log.debug("scanid: %s probelist: %s", scan.external_id, probelist) scan.set_probelist(probelist) session.commit()
def add_files(scan, files, session): """ add file(s) to the specified scan :param scanid: id returned by scan_new :param files: dict of {filename, file-obj} :rtype: int :return: int - total number of files for the scan :raise: IrmaDataBaseError, IrmaValueError """ log.debug("scanid: %s", scan.external_id) IrmaScanStatus.filter_status(scan.status, IrmaScanStatus.empty, IrmaScanStatus.ready) if scan.status == IrmaScanStatus.empty: # on first file added update status to 'ready' scan.set_status(IrmaScanStatus.ready) for (filename, data) in files.items(): # Using ntpath.split as it handles # windows path and Linux path log.debug("filename: %s", filename) _new_fileweb(scan, filename, data, session) session.commit()
def add_files(request, scan_id: uuid): """ Attach a file to a scan. The request should be performed using a POST request method. """ log.debug("scan %s: add_files", scan_id) session = db.session scan = Scan.load_from_ext_id(scan_id, session) IrmaScanStatus.filter_status(scan.status, IrmaScanStatus.empty, IrmaScanStatus.ready) # request._params is init by Falcon form_dict = request._params if len(form_dict) == 0: raise HTTPInvalidParam("Empty list", "files") for (_, f) in form_dict.items(): # Multipart Middleware giving a dict of uploaded files filename = decode_utf8(f.filename) # ByteIO object is in file data = f.file log.debug("scan %s: add filename: %s", scan_id, filename) file = File.get_or_create(data, session) # Legacy v1.1 as we dont received a submitter parameter # choose one from FileCli/FileWeb based on path value (path, name) = ntpath.split(filename) if path != "": file_ext = FileCli(file, filename) else: file_ext = FileWeb(file, filename) session.add(file_ext) file_ext.scan = scan session.commit() scan.set_status(IrmaScanStatus.ready) session.commit() return scan_schema.dump(scan).data
def progress(scan_id): with session_query() as session: scan = Scan.load(scan_id, session) if IrmaScanStatus.is_error(scan.status): status_str = IrmaScanStatus.label[scan.status] raise IrmaValueError(status_str) status = IrmaScanStatus.label[scan.status] progress_details = None if scan.status == IrmaScanStatus.launched: (total, finished, success) = scan.progress() progress_details = {} progress_details['total'] = total progress_details['finished'] = finished progress_details['successful'] = success return (status, progress_details)
def cancel(scan, session): """ cancel all remaining jobs for specified scan :param scanid: id returned by scan_new :rtype: dict of 'cancel_details': total':int, 'finished':int, 'cancelled':int :return: informations about number of cancelled jobs by irma-brain :raise: IrmaDatabaseError, IrmaTaskError """ log.debug("scanid: %s", scan.external_id) if scan.status < IrmaScanStatus.uploaded: # If not launched answer directly scan.set_status(IrmaScanStatus.cancelled) session.commit() return None if scan.status != IrmaScanStatus.launched: # If too late answer directly status_str = IrmaScanStatus.label[scan.status] if IrmaScanStatus.is_error(scan.status): # let the cancel finish and keep the error status return None else: reason = "can not cancel scan in {0} status".format(status_str) raise IrmaValueError(reason) # Else ask brain for job cancel (retcode, res) = celery_brain.scan_cancel(scan.external_id) if retcode == IrmaReturnCode.success: s_processed = IrmaScanStatus.label[IrmaScanStatus.processed] if 'cancel_details' in res: scan.set_status(IrmaScanStatus.cancelled) session.commit() return res['cancel_details'] elif res['status'] == s_processed: # if scan is finished for the brain # it means we are just waiting for results scan.set_status(IrmaScanStatus.processed) session.commit() reason = "can not cancel scan in {0} status".format(res['status']) raise IrmaValueError(reason) else: raise IrmaTaskError(res)