Best Python code snippet using slash
api_client.py
Source:api_client.py  
1"""2TIM Python Client3TIM Engine Swagger: https://timws.tangent.works/v4/swagger-ui.html4TIM Engine Redoc:   https://timws.tangent.works/v4/redoc.html5"""6import pandas as pd7from pandas import DataFrame8from typing import Dict, List, Tuple, Union9import yaml10import requests11from time import sleep12from requests import Response13import json14import logging15from logging import Logger16import functools17from datetime import datetime18import os19import inspect20from pathlib import Path21from tim_client.credentials import Credentials22from tim_client.prediction_model import PredictionModel23from tim_client.detection_model import DetectionModel24from tim_client.prediction import Prediction25from tim_client.detection import Detection26from tim_client.helpers import dict_to_dataframe, dataframe_to_request_dict27FREQUENCY_OF_REQUESTS = 3  # in seconds, how often we ask for status28MAX_NUMBER_OF_TRIES = 600  # number of tries, after which waiting for result is abondoned29DEFAULT_JSON_SAVING_FOLDER = 'logs/'30class ApiClient:31    __credentials: Credentials = None32    __logger: Logger = None33    __default_headers: Dict = {}34    __verify_ssl: bool = True  # ONLY for debug purposes35    __save_json: bool = False36    __json_saving_folder_path: Path = Path(DEFAULT_JSON_SAVING_FOLDER)37    def __init__(self, credentials: Credentials, logger: Logger = None, default_headers: Dict = {}, verify_ssl: bool = True):38        self.__credentials = credentials39        self.__logger = logger40        self.__default_headers = default_headers41        self.__verify_ssl = verify_ssl42        if self.__logger is None:43            self.__logger = logging.getLogger(__name__)44    @property45    def save_json(self) -> bool:46        return self.__save_json47    @save_json.setter48    def save_json(self, save_json: bool):49        self.__save_json = save_json50        self.__logger.info('Saving JSONs functionality has been %s', 'enabled' if save_json else 'disabled')51    @property52    def json_saving_folder_path(self) -> Path:53        return self.__json_saving_folder_path54    @json_saving_folder_path.setter55    def json_saving_folder_path(self, json_saving_folder_path: str):56        self.__json_saving_folder_path = Path(json_saving_folder_path)57        self.__logger.info('JSON destination folder changed to %s', str(self.__json_saving_folder_path))58    def wait_for_task_to_finish(self, uri: str) -> Tuple[int, Dict]:59        """Keep getting task result until task is finished or tries threshold is reached."""60        counter_of_tries: int = 061        while counter_of_tries < MAX_NUMBER_OF_TRIES:62            get_status, get_response = self.send_tim_request('GET', uri)63            self.__logger.debug('Waiting for task to finish: %s: %s%s (%d/%d)', get_response["status"], get_response["progress"] if "progress" in get_response else 0.0, '%', counter_of_tries+1, MAX_NUMBER_OF_TRIES)64            if(200 <= get_status < 300):65                if self.is_request_finished(get_response['status']):66                    return get_status, get_response67                else:68                    counter_of_tries += 169                    sleep(FREQUENCY_OF_REQUESTS)70            else:71                self.__logger.error(f'Get request error: {get_status} {get_response}')72                raise ValueError(f'Get request error, status code: {get_status}')73        self.__logger.error('Waiting for task to finish exceeded limit! Terminating.')74        raise ValueError('Waiting for task to finish exceeded limit')75    def prediction_build_model(self, data: DataFrame, configuration: Dict, wait_to_finish: bool = True, target_index: int = 1, timestamp_index: int = 0, predictors_update: Dict = None) -> PredictionModel:76        """77        Build prediction model.78        :param data: Dataset in pandas DataFrame format79        :param configuration: Configuration object of prediction model80        :param wait_to_finish: Optional flag to wait for the built model, default is True81        :return: Build prediction model and wait to finish building if the wait_to_finish argument is True else returns build model with current status.82        """83        request_payload: Dict = {84            'configuration': configuration,85            'data': dataframe_to_request_dict(data, target_index=target_index, timestamp_index=timestamp_index, predictors_update=predictors_update)86        }87        88        now = datetime.now()89        self.__log_request(now, 'prediction-build-model', self.__credentials.get_auth_headers(), request_payload)90        self.__logger.debug('Sending POST request to /prediction/build-model')91        request_status, request_response = self.send_tim_request('POST', f'/prediction/build-model', request_payload)92        self.__logger.debug('Response from /prediction/build-model: %d', request_status)93        if request_status < 200 or request_status >= 300:94            self.__logger.error(f'ApiClient.prediction_build_model: {request_status} {request_response}')95            raise ValueError(f'ApiClient.prediction_build_model: {request_status}')96        request_uuid: str = request_response['requestUUID']97        self.__logger.debug('UUID of /prediction/build-model request: %s', request_uuid)98        if wait_to_finish:99            _, request_response = self.wait_for_task_to_finish(f'/prediction/build-model/{request_uuid}')100        self.__log_response(now, 'prediction-build-model', request_response)101        return PredictionModel.from_json(request_response)102    103    def prediction_build_model_detail(self, request_uuid: str) -> PredictionModel:104        """105        Get prediction build model detail.106        :param request_uuid: UUID of the predction model building request107        :return: Build prediction model with current build status. If failes returns None.108        """109        request_status, request_response = self.send_tim_request('GET', f'/prediction/build-model/{request_uuid}')110        if request_status < 200 or request_status >= 300:111            self.__logger.error(f'ApiClient.prediction_build_model_detail: {request_status} {request_response}')112            raise ValueError(f'ApiClient.prediction_build_model_detail: {request_status}')113        return PredictionModel.from_json(request_response)114    def prediction_predict(self, data: DataFrame, model: PredictionModel, configuration: Dict = None, wait_to_finish: bool = True, target_index: int = 1, timestamp_index: int = 0, predictors_update: Dict = None) -> Prediction:115        """Make and return prediction."""116        request_payload: Dict = {117            'model': model.get_model(),118            'data': dataframe_to_request_dict(data, target_index=target_index, timestamp_index=timestamp_index, predictors_update=predictors_update)119        }120        if configuration is not None:121            request_payload['configuration'] = configuration122        now = datetime.now()123        self.__log_request(now, 'prediction-predict', self.__credentials.get_auth_headers(), request_payload)124        125        self.__logger.debug('Sending POST request to /prediction/predict')126        request_status, request_response = self.send_tim_request('POST', f'/prediction/predict', request_payload)127        self.__logger.debug('Response from /prediction/predict: %d', request_status)128        if request_status < 200 or request_status >= 300:129            self.__logger.error(f'ApiClient.prediction_predict: {request_status} {request_response}')130            raise ValueError(f'ApiClient.prediction_predict: {request_status}')131        request_uuid: str = request_response['requestUUID']132        self.__logger.debug('UUID of /prediction/predict request: %s', request_uuid)133        if wait_to_finish:134            _, request_response = self.wait_for_task_to_finish(f'/prediction/predict/{request_uuid}')135        136        self.__log_response(now, 'prediction-predict', request_response)137        return Prediction.from_json(request_response)138    139    def prediction_predict_detail(self, request_uuid: str) -> Prediction:140        request_status, request_response = self.send_tim_request('GET', f'/prediction/predict/{request_uuid}')141        if request_status < 200 or request_status >= 300:142            self.__logger.error(f'ApiClient.prediction_predict_detail: {request_status} {request_response}')143            raise ValueError(f'ApiClient.prediction_predict_detail: {request_status}')144        return Prediction.from_json(request_response)145    def prediction_build_model_predict(self, data: DataFrame, configuration: Dict, wait_to_finish: bool = True, target_index: int = 1, timestamp_index: int = 0, predictors_update: Dict = None) -> Prediction:146        """147        Submit data and configuration to model building and consequent prediction process.148        :param data: Dataset in pandas DataFrame format149        :param configuration: Configuration object of prediction model150        :param wait_to_finish: Optional flag to wait for the built model, default is True151        :return: Build prediction model and wait to finish building if the wait_to_finish argument is True else returns build model with current status.152        """153        request_payload: Dict = {154            'configuration': configuration,155            'data': dataframe_to_request_dict(data, target_index=target_index, timestamp_index=timestamp_index, predictors_update=predictors_update)156        }157        now = datetime.now()158        self.__log_request(now, 'prediction-build-model-predict', self.__credentials.get_auth_headers(), request_payload)159        160        self.__logger.debug('Sending POST request to /prediction/build-model-predict')161        request_status, request_response = self.send_tim_request('POST', f'/prediction/build-model-predict', request_payload)162        self.__logger.debug('Response from /prediction/build-model-predict: %d', request_status)163        if request_status < 200 or request_status >= 300:164            self.__logger.error(f'ApiClient.prediction_build_model_predict: {request_status} {request_response}')165            raise ValueError(f'ApiClient.prediction_build_model_predict: {request_status}')166        request_uuid: str = request_response['requestUUID']167        self.__logger.debug('UUID of /prediction/build-model-predict request: %s', request_uuid)168        if wait_to_finish:169            _, request_response = self.wait_for_task_to_finish(f'/prediction/build-model-predict/{request_uuid}')170        self.__log_response(now, 'prediction-build-model-predict', request_response)171        return Prediction.from_json(request_response)172    173    def prediction_build_model_predict_detail(self, request_uuid: str) -> Prediction:174        request_status, request_response = self.send_tim_request('GET', f'/prediction/build-model-predict/{request_uuid}')175        if request_status < 200 or request_status >= 300:176            self.__logger.error(f'ApiClient.prediction_build_model_predict_detail: {request_status} {request_response}')177            raise ValueError(f'ApiClient.prediction_build_model_predict_detail: {request_status}')178        return Prediction.from_json(request_response)179    def detection_build_model(self, data: DataFrame, configuration: Dict = None, wait_to_finish: bool = True, target_index: int = 1, timestamp_index: int = 0, predictors_update: Dict = None) -> DetectionModel:180        """Build and return anomaly detection model."""181        request_payload: Dict = {182            'data': dataframe_to_request_dict(data, target_index=target_index, timestamp_index=timestamp_index, predictors_update=predictors_update)183        }184        if configuration is not None:185            request_payload['configuration'] = configuration186        now = datetime.now()187        self.__log_request(now, 'detection-build-model', self.__credentials.get_auth_headers(), request_payload)188        189        self.__logger.debug('Sending POST request to /detection/build-model')190        request_status, request_response = self.send_tim_request('POST', f'/detection/build-model', request_payload)191        self.__logger.debug('Response from /detection/build-model: %d', request_status)192        if request_status < 200 or request_status >= 300:193            self.__logger.error(f'ApiClient.detection_build_model: {request_status} {request_response}')194            raise ValueError(f'ApiClient.detection_build_model: {request_status}')195        request_uuid: str = request_response['requestUUID']196        self.__logger.debug('UUID of /detection/build-model request: %s', request_uuid)197        if wait_to_finish:198            _, request_response = self.wait_for_task_to_finish(f'/detection/build-model/{request_uuid}')199        self.__log_response(now, 'detection-build-model', request_response)200        return DetectionModel.from_json(request_response)201    202    def detection_build_model_detail(self, request_uuid: str) -> DetectionModel:203        request_status, request_response = self.send_tim_request('GET', f'/detection/build-model/{request_uuid}')204        if request_status < 200 or request_status >= 300:205            self.__logger.error(f'ApiClient.detection_build_model_detail: {request_status} {request_response}')206            raise ValueError(f'ApiClient.detection_build_model_detail: {request_status}')207        return DetectionModel.from_json(request_response)208    def detection_rebuild_model(self, data: DataFrame, model: DetectionModel, configuration: Dict = None, wait_to_finish: bool = True, target_index: int = 1, timestamp_index: int = 0, predictors_update: Dict = None) -> DetectionModel:209        """Rebuild and return anomaly detection model."""210        request_payload: Dict = {211            'data': dataframe_to_request_dict(data, target_index=target_index, timestamp_index=timestamp_index, predictors_update=predictors_update),212            'model': model.get_model()213        }214        if configuration is not None:215            request_payload['configuration'] = configuration216        now = datetime.now()217        self.__log_request(now, 'detection-rebuild-model', self.__credentials.get_auth_headers(), request_payload)218        219        self.__logger.debug('Sending POST request to /detection/rebuild-model')220        request_status, request_response = self.send_tim_request('POST', f'/detection/rebuild-model', request_payload)221        self.__logger.debug('Response from /detection/rebuild-model: %d', request_status)222        if request_status < 200 or request_status >= 300:223            self.__logger.error(f'ApiClient.detection_rebuild_model: {request_status} {request_response}')224            raise ValueError(f'ApiClient.detection_rebuild_model: {request_status}')225        request_uuid: str = request_response['requestUUID']226        self.__logger.debug('UUID of /detection/rebuild-model request: %s', request_uuid)227        if wait_to_finish:228            _, request_response = self.wait_for_task_to_finish(f'/detection/rebuild-model/{request_uuid}')229        self.__log_response(now, 'detection-rebuild-model', request_response)230        return DetectionModel.from_json(request_response)231    232    def detection_rebuild_model_detail(self, request_uuid: str) -> DetectionModel:233        request_status, request_response = self.send_tim_request('GET', f'/detection/rebuild-model/{request_uuid}')234        if request_status < 200 or request_status >= 300:235            self.__logger.error(f'ApiClient.detection_rebuild_model_detail: {request_status} {request_response}')236            raise ValueError(f'ApiClient.detection_rebuild_model_detail: {request_status}')237        return DetectionModel.from_json(request_response)238    def detection_detect(self, data: DataFrame, model: DetectionModel, wait_to_finish: bool = True, target_index: int = 1, timestamp_index: int = 0, predictors_update: Dict = None) -> Detection:239        """Make anomaly detection and return anomaly indicator."""240        request_payload: Dict = {241            'data': dataframe_to_request_dict(data, target_index=target_index, timestamp_index=timestamp_index, predictors_update=predictors_update),242            'model': model.get_model()243        }244        245        now = datetime.now()246        self.__log_request(now, 'detection-detect', self.__credentials.get_auth_headers(), request_payload)247        self.__logger.debug('Sending POST request to /detection/detect')248        request_status, request_response = self.send_tim_request('POST', f'/detection/detect', request_payload)249        self.__logger.debug('Response from /detection/detect: %d', request_status)250        if request_status < 200 or request_status >= 300:251            self.__logger.error(f'ApiClient.detection_detect: {request_status} {request_response}')252            raise ValueError(f'ApiClient.detection_detect: {request_status}')253        request_uuid: str = request_response['requestUUID']254        self.__logger.debug('UUID of /detection/detect request: %s', request_uuid)255        if wait_to_finish:256            _, request_response = self.wait_for_task_to_finish(f'/detection/detect/{request_uuid}')257        self.__log_response(now, 'detection-detect', request_response)258        return Detection.from_json(request_response)259    260    def detection_detect_detail(self, request_uuid: str) -> Detection:261        request_status, request_response = self.send_tim_request('GET', f'/detection/detect/{request_uuid}')262        if request_status < 200 or request_status >= 300:263            self.__logger.error(f'ApiClient.detection_detect_detail: {request_status} {request_response}')264            raise ValueError(f'ApiClient.detection_detect_detail: {request_status}')265        return Detection.from_json(request_response)266    def send_tim_request(self, method: str, uri: str, payload: Dict = None, headers: Dict = {}) -> Tuple[int, Dict]:267        """Send HTTP request to TIM Engine."""268        method = method.upper()269        url = f'{self.__credentials.get_tim_url()}{uri}'270        all_headers = self.__default_headers.copy()271        all_headers.update(headers)272        all_headers.update(self.__credentials.get_auth_headers())273        # self.__logger.debug('Sending request: %s %s', method, url)274        response: Response = requests.request(method=method, url=url, headers=all_headers, json=payload)275        return response.status_code, response.json()276    def is_request_finished_successfully(self, status: str) -> bool:277        """278        Check if status represents successfully finished request.279        :param status: Status string returned from TIM Engine.280        :return: True if request is successfully finished.281        """282        return status in ('Finished', 'FinishedWithWarning')283    def is_request_failed(self, status: str) -> bool:284        """285        Check if status represents failed request.286        :param status: Status string returned from TIM Engine.287        :return: True if request has failed.288        """289        return status in ('NotFound', 'Failed')290    def is_request_finished(self, status: str) -> bool:291        """292        Check if status represents finished request (successfully or failed).293        :param status: Status string returned from TIM Engine.294        :return: True if request has finished.295        """296        return self.is_request_finished_successfully(status) or self.is_request_failed(status)297    def __create_directory_if_not_exist(self, destination_folder_path):298        if not os.path.isdir(destination_folder_path):299            self.__logger.debug('Creating new directory for JSON files: %s', str(destination_folder_path))300            os.mkdir(destination_folder_path)301    def __log_request(self, timestamp: datetime, endpoint: str, headers: Dict, payload: Dict):302        """Save TIM request to file."""303        if self.__save_json is False:304            return305        self.__create_directory_if_not_exist(self.__json_saving_folder_path)306        filename = f'{timestamp.strftime("%Y%m%d%H%M%S")}_request_{endpoint}.json'307        filepath = self.__json_saving_folder_path / filename308        output_json = {309            'datetime': timestamp.strftime('%Y-%m-%d %H:%M:%S'),310            'tim_url': self.__credentials.get_tim_url(),311            'endpoint': endpoint,312            'headers': headers,313            'request_content': payload314        }315        self.__logger.debug('Saving request JSON to %s', str(filepath))316        try:317            with open(filepath, 'w') as outfile:318                json.dump(output_json, outfile)319        except Exception as e:320            self.__logger.error('Failed to save request JSON: %s', str(e))321    def __log_response(self, timestamp: datetime, endpoint: str, payload: Dict):322        """Save TIM response to file."""323        if self.__save_json is False:324            return325        uuid = payload['requestUUID'] if 'requestUUID' in payload else 'N/A'326        status = payload['status'] if 'status' in payload else 'N/A'327        328        self.__create_directory_if_not_exist(self.__json_saving_folder_path)329        filename = f'{timestamp.strftime("%Y%m%d%H%M%S")}_response_{endpoint}_{uuid}.json'330        filepath = self.__json_saving_folder_path / filename331        output_json = {332            'datetime': timestamp.strftime('%Y-%m-%d %H:%M:%S'),333            'endpoint': endpoint,334            'request_uuid': uuid,335            'http_status': status,336            'response_content': payload337        }338        self.__logger.debug('Saving response JSON of %s to %s', uuid, str(filepath))339        340        try:341            with open(filepath, 'w') as outfile:342                json.dump(output_json, outfile)343        except Exception as e:...fsm_discovery.py
Source:fsm_discovery.py  
1#!/usr/bin/python2#3# This file is part of Ansible4#5# Ansible is free software: you can redistribute it and/or modify6# it under the terms of the GNU General Public License as published by7# the Free Software Foundation, either version 3 of the License, or8# (at your option) any later version.9#10# Ansible is distributed in the hope that it will be useful,11# but WITHOUT ANY WARRANTY; without even the implied warranty of12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the13# GNU General Public License for more details.14#15# You should have received a copy of the GNU General Public License16# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.17#18from __future__ import absolute_import, division, print_function19__metaclass__ = type20ANSIBLE_METADATA = {21    "metadata_version": "1.1",22    "status": ["preview"],23    "supported_by": "community"24}25DOCUMENTATION = '''26---27module: fsm_discovery28version_added: "2.8"29author: Luke Weighall (@lweighall)30short_description: Submits and Queries for Discovery Tasks.31description:32  - Able to submit ad-hoc discoveries and query for the results of any task ID that was a discovery.33options:34  host:35    description:36      - The FortiSIEM's FQDN or IP Address.37    required: true38  username:39    description:40      - The username used to authenticate with the FortiManager.41      - organization/username format. The Organization is important, and will only return data from specified Org.42    required: false43  password:44    description:45      - The password associated with the username account.46    required: false47  ignore_ssl_errors:48    description:49      - When Enabled this will instruct the HTTP Libraries to ignore any ssl validation errors.50    required: false51    default: "enable"52    choices: ["enable", "disable"]53  export_json_to_screen:54    description:55      - When enabled this will print the JSON results to screen.56    required: false57    default: "enable"58    choices: ["enable", "disable"]59  export_json_to_file_path:60    description:61      - When populated, an attempt to write JSON dictionary to file is made.62      - An error will be thrown if this fails.63    required: false64    default: None65  export_xml_to_file_path:66    description:67      - When populated, an attempt to write XML to file is made.68      - An error will be thrown if this fails.69    required: false70    default: None71  wait_to_finish:72    description:73      - When enabled, the module will WAIT until the discovery actually finishes.74        This may or may not be desired depending on how big the discovery range is.75      - When disabled, the module will simply submit the discovery and exit.76        You'll have to record the task ID that was exported, and re-run the module with type = status.77    required: false78    default: "enable"79    choices: ["enable", "disable"]80  type:81    description:82      - Discovery type to use in FortiSIEM.83    required: true84    choices: ["RangeScan", "SmartScan", "L2Scan", "status"]85  root_ip:86    description:87      - Specifies the IP of a device to use as the "root" scanning device. Usually a router or switch.88      - Ignored unless "SmartScan" is set for mode89    required: false90  include_range:91    description:92      - Specifies the IP ranges to specify, in comma seperated format.93    required: false94  exclude_range:95    description:96      - Specifies the IP ranges to specify, in comma seperated format.97    required: false98  no_ping:99    description:100      - Tells FortiSIEM not to attempt to ping a device before attempting to discover it.101      - Useful when ICMP is blocked on target devices.102    required: false103    default: false104    type: bool105  only_ping:106    description:107      - Tells FortiSIEM to only discover devices with ICMP pings.108    required: false109    default: false110    type: bool111  task_id:112    description:113      - Tells the module which task ID to query for when type = status.114    required: false115    type: int116  delta:117    description:118      - Only discovers new devices.119    required: false120    default: false121    type: bool122  vm_off:123    description:124      - Doesn't discover VMs.125    required: false126    default: false127    type: bool128  vm_templates:129    description:130      - Discover VM templates.131    required: false132    default: false133    type: bool134  discover_routes:135    description:136      - Discovers routes and follows those in smart scans.137    required: false138    default: true139    type: bool140  winexe_based:141    description:142      - Discovers windows boxes with winExe.143    required: false144    default: false145    type: bool146  unmanaged:147    description:148      - Sets newly discovered devices to unmanaged.149    required: false150    default: false151    type: bool152  monitor_win_events:153    description:154      - Turns on or off Windows Event log mointor for newly discovered devices.155    required: false156    default: true157    type: bool158  monitor_win_patches:159    description:160      - Turns on or off Windows Patching logging.161    required: false162    default: true163    type: bool164  monitor_installed_sw:165    description:166      - Turns on or off Windows Installed Software monitoring.167    required: false168    default: true169    type: bool170  name_resolution_dns_first:171    description:172      - Specifies to use DNS for name resolution first, and then SNMP/NETBIOS/SSH.173      - When false, uses SNMP/NETBIOS/SSH first, then DNS174    required: false175    default: true176    type: bool177'''178EXAMPLES = '''179- name: SUBMIT RANGE SCAN FOR SINGLE DEVICE180  fsm_discovery:181    host: "{{ inventory_hostname }}"182    username: "{{ username }}"183    password: "{{ password }}"184    ignore_ssl_errors: "enable"185    export_json_to_screen: "enable"186    export_json_to_file_path: "/root/range_scan.json"187    export_xml_to_file_path: "/root/range_scan.xml"188    type: "RangeScan"189    include_range: "10.0.0.254"190- name: SUBMIT RANGE SCAN FOR SINGLE DEVICE AND WAIT FOR FINISH WITH MANY OPTIONS191  fsm_discovery:192    host: "{{ inventory_hostname }}"193    username: "{{ username }}"194    password: "{{ password }}"195    ignore_ssl_errors: "enable"196    export_json_to_screen: "enable"197    export_json_to_file_path: "/root/range_scan2.json"198    export_xml_to_file_path: "/root/range_scan2.xml"199    type: "RangeScan"200    include_range: "10.0.0.5-10.0.0.20"201    wait_to_finish: True202    only_ping: False203    vm_off: True204    unmanaged: True205    delta: True206    name_resolution_dns_first: False207    winexe_based: True208    vm_templates: True209    discover_routes: True210    monitor_win_events: False211    monitor_win_patches: False212    monitor_installed_sw: False213- name: SUBMIT RANGE SCAN FOR SINGLE DEVICE AND WAIT FOR FINISH WITH NO PING214  fsm_discovery:215    host: "{{ inventory_hostname }}"216    username: "{{ username }}"217    password: "{{ password }}"218    ignore_ssl_errors: "enable"219    export_json_to_screen: "enable"220    export_json_to_file_path: "/root/json_test_out.json"221    export_xml_to_file_path: "/root/xml_test_out.xml"222    type: "RangeScan"223    include_range: "10.0.0.5-10.0.0.50"224    wait_to_finish: True225    no_ping: True226- name: SUBMIT RANGE SCAN FOR RANGE OF DEVICES227  fsm_discovery:228    host: "{{ inventory_hostname }}"229    username: "{{ username }}"230    password: "{{ password }}"231    ignore_ssl_errors: "enable"232    export_json_to_screen: "enable"233    export_json_to_file_path: "/root/json_test_out.json"234    export_xml_to_file_path: "/root/xml_test_out.xml"235    type: "RangeScan"236    include_range: "10.0.0.1-10.0.0.10"237    exclude_range: "10.0.0.5-10.0.0.6"238- name: SUBMIT SMART SCAN239  fsm_discovery:240    host: "{{ inventory_hostname }}"241    username: "{{ username }}"242    password: "{{ password }}"243    ignore_ssl_errors: "enable"244    export_json_to_screen: "enable"245    export_json_to_file_path: "/root/json_test_out.json"246    export_xml_to_file_path: "/root/xml_test_out.xml"247    type: "SmartScan"248    root_ip: "10.0.0.254"249- name: SUBMIT L2SCAN250  fsm_discovery:251    host: "{{ inventory_hostname }}"252    username: "{{ username }}"253    password: "{{ password }}"254    ignore_ssl_errors: "enable"255    export_json_to_screen: "enable"256    export_json_to_file_path: "/root/json_test_out.json"257    export_xml_to_file_path: "/root/xml_test_out.xml"258    type: "L2Scan"259    include_range: "10.0.0.1-10.0.0.254"260'''261RETURN = """262api_result:263  description: full API response, includes status code and message264  returned: always265  type: str266"""267from ansible.module_utils.basic import AnsibleModule, env_fallback268import time269from ansible.module_utils.network.fortisiem.common import FSMEndpoints270from ansible.module_utils.network.fortisiem.common import FSMBaseException271from ansible.module_utils.network.fortisiem.common import DEFAULT_EXIT_MSG272from ansible.module_utils.network.fortisiem.fortisiem import FortiSIEMHandler273def main():274    argument_spec = dict(275        host=dict(required=True, type="str"),276        username=dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"])),277        password=dict(fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True),278        ignore_ssl_errors=dict(required=False, type="str", choices=["enable", "disable"], default="enable"),279        export_json_to_screen=dict(required=False, type="str", choices=["enable", "disable"], default="enable"),280        export_json_to_file_path=dict(required=False, type="str"),281        export_xml_to_file_path=dict(required=False, type="str"),282        export_csv_to_file_path=dict(required=False, type="str"),283        wait_to_finish=dict(required=False, type="bool", default="false"),284        type=dict(required=True, type="str",285                  choices=["RangeScan", "SmartScan", "L2Scan", "status"]),286        root_ip=dict(required=False, type="str"),287        include_range=dict(required=False, type="str"),288        exclude_range=dict(required=False, type="str"),289        no_ping=dict(required=False, type="bool", default="false"),290        only_ping=dict(required=False, type="bool", default="false"),291        task_id=dict(required=False, type="int"),292        delta=dict(required=False, type="bool", default="false"),293        vm_off=dict(required=False, type="bool", default="false"),294        vm_templates=dict(required=False, type="bool", default="false"),295        discover_routes=dict(required=False, type="bool", default="true"),296        winexe_based=dict(required=False, type="bool", default="false"),297        unmanaged=dict(required=False, type="bool", default="false"),298        monitor_win_events=dict(required=False, type="bool", default="true"),299        monitor_win_patches=dict(required=False, type="bool", default="true"),300        monitor_installed_sw=dict(required=False, type="bool", default="true"),301        name_resolution_dns_first=dict(required=False, type="bool", default="true"),302    )303    required_if = [304        ['type', 'SmartScan', ['root_ip']],305        ['type', 'RangeScan', ['include_range']],306        ['type', 'L2Scan', ['include_range']],307        ['type', 'status', ['task_id']],308    ]309    module = AnsibleModule(argument_spec, supports_check_mode=False, required_if=required_if)310    paramgram = {311        "host": module.params["host"],312        "username": module.params["username"],313        "password": module.params["password"],314        "export_json_to_screen": module.params["export_json_to_screen"],315        "export_json_to_file_path": module.params["export_json_to_file_path"],316        "export_xml_to_file_path": module.params["export_xml_to_file_path"],317        "export_csv_to_file_path": module.params["export_csv_to_file_path"],318        "ignore_ssl_errors": module.params["ignore_ssl_errors"],319        "type": module.params["type"],320        "wait_to_finish": module.params["wait_to_finish"],321        "root_ip": module.params["root_ip"],322        "include_range": module.params["include_range"],323        "exclude_range": module.params["exclude_range"],324        "no_ping": module.params["no_ping"],325        "only_ping": module.params["only_ping"],326        "task_id": module.params["task_id"],327        "delta": module.params["delta"],328        "vm_off": module.params["vm_off"],329        "vm_templates": module.params["vm_templates"],330        "discover_routes": module.params["discover_routes"],331        "winexe_based": module.params["winexe_based"],332        "unmanaged": module.params["unmanaged"],333        "monitor_win_events": module.params["monitor_win_events"],334        "monitor_win_patches": module.params["monitor_win_patches"],335        "monitor_installed_sw": module.params["monitor_installed_sw"],336        "name_resolution_dns_first": module.params["name_resolution_dns_first"],337        "uri": FSMEndpoints.SET_DISCOVERY,338        "input_xml": None339    }340    module.paramgram = paramgram341    # TRY TO INIT THE CONNECTION SOCKET PATH AND FortiManagerHandler OBJECT AND TOOLS342    fsm = None343    results = DEFAULT_EXIT_MSG344    try:345        fsm = FortiSIEMHandler(module)346    except BaseException as err:347        raise FSMBaseException("Couldn't load FortiSIEM Handler from mod_utils. Error: " + str(err))348    # EXECUTE THE MODULE OPERATION349    # SEND THE DISCOVERY XML PAYLOAD350    if paramgram["type"] != "status":351        paramgram["input_xml"] = fsm._xml.create_discover_payload()352        try:353            results = fsm.handle_simple_payload_request(paramgram["input_xml"])354        except BaseException as err:355            raise FSMBaseException(err)356        # REFACTOR THE GENERIC RESPONSE BECAUSE IT WASN'T STRUCTURED BY FORTISIEM IN AN XML RESPONSE357        # RECORD THE TASK ID358        try:359            paramgram["task_id"] = results["json_results"]["fsm_response"]360            del results["json_results"]["fsm_response"]361            results["json_results"]["task_id"] = paramgram["task_id"]362            results["xml_results"] = "<task_id>" + str(paramgram["task_id"]) + "</task_id>"363        except BaseException as err:364            raise FSMBaseException(msg="Couldn't extract discovery task ID from response! Error: " + str(err))365    # START THE STATUS CHECKING PORTION366    if paramgram["type"] == "status" or paramgram["wait_to_finish"]:367        if not paramgram["task_id"]:368            raise FSMBaseException(msg="fsm_discovery was called to status "369                                       "or wait_to_finish but the task ID was empty")370        if paramgram["task_id"]:371            paramgram["uri"] = FSMEndpoints.GET_DISCOVERY + str(paramgram["task_id"])372            module.paramgram = paramgram373            try:374                results = fsm.handle_simple_request()375            except BaseException as err:376                raise FSMBaseException(msg="Failed to get status of task ID: " +377                                           str(paramgram["task_id"]) + " - Error: " + str(err))378            # PROCESS WAIT TO FINISH!379            if paramgram["wait_to_finish"]:380                try:381                    task_status_result = results["json_results"]["fsm_response"].split(":")382                    # SLEEP FOR 5 SECOND INTERVALS AND KEEP CHECKING UNTIL PROGRESS IS 100%383                    while task_status_result[1] != "Done":384                        time.sleep(5)385                        try:386                            results = fsm.handle_simple_request()387                        except BaseException as err:388                            raise FSMBaseException(msg="Failed to get status of task ID: " +389                                                       str(paramgram["task_id"]) + " - Error: " + str(err))390                        try:391                            if results["json_results"]["taskResults"]:392                                task_status_result = [str(paramgram["task_id"]), "Done"]393                        except BaseException:394                            try:395                                task_status_result = results["json_results"]["fsm_response"].split(":")396                            except BaseException as err:397                                raise FSMBaseException(err)398                except BaseException:399                    try:400                        if results["json_results"]["taskResults"]:401                            pass402                    except BaseException as err:403                        raise FSMBaseException(msg="Something happened while looping "404                                                   "for the status. Error: " + str(err))405                    pass406    # EXIT USING GOVERN_RESPONSE()407    fsm.govern_response(module=module, results=results, changed=False,408                        ansible_facts=fsm.construct_ansible_facts(results["json_results"],409                                                                  module.params,410                                                                  paramgram))411    return module.exit_json(msg=results)412if __name__ == "__main__":...qsub_help.py
Source:qsub_help.py  
1def qsub_job_submission_line(jobname,2                             script,3                             elog,4                             olog,5                             email="",6                             email_if="-m as ",7                             wait_to_finish="-sync n ",8                             pe="-pe smp 1 ",9                             memory_per_core="500M"):10    """11    jobname12    script13    elog14    olog15    n_cores16    memory_per_core_Gb17    # THESE REQUIRE TRAILING SPACES:18    pe "-pe smp 1 "19    email "-M username@domain.com "20    email_if "-m aes "21        a: if aborted22        s: if suspended23        e: when job ends24    wait_to_finish "-sync n " or "-sync y "25    """26    jobline = "qsub "27    jobline += "-N %s " % jobname28    jobline += "-e %s " % elog29    jobline += "-o %s " % olog30    jobline += email31    jobline += email_if32    jobline += wait_to_finish33    jobline += pe34    jobline += "-l h_vmem=%s " % memory_per_core35    jobline += "-l m_mem_free=%s " % memory_per_core36    jobline += "-cwd "37    jobline += "%s\n" % script...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
