def test_instances(secret_conf_path, server, username, password): integrations = get_integrations(secret_conf_path) instance_ids = [] failed_integrations = [] integrations_counter = 0 prints_manager = ParallelPrintsManager(1) content_installation_client = demisto_client.configure(base_url=server, username=username, password=password, verify_ssl=False) install_new_content(content_installation_client, server) for integration in integrations: c = demisto_client.configure(base_url=server, username=username, password=password, verify_ssl=False) integrations_counter += 1 integration_name = integration.get('name') integration_instance_name = integration.get('instance_name', '') integration_params = integration.get('params') devops_comments = integration.get('devops_comments') product_description = integration.get('product_description', '') is_byoi = integration.get('byoi', True) has_integration = integration.get('has_integration', True) validate_test = integration.get('validate_test', True) if has_integration: instance_id, failure_message, _ = __create_integration_instance( c, integration_name, integration_instance_name, integration_params, is_byoi, prints_manager, validate_test=validate_test) if failure_message == 'No configuration': print_warning( "Warning: skipping {} as it exists in content-test-conf conf.json but not " "in content repo".format(integration_name)) continue if not instance_id: print_error( 'Failed to create instance of {} with message: {}'.format( integration_name, failure_message)) failed_integrations.append( "{} {} - devops comments: {}".format( integration_name, product_description, devops_comments)) else: instance_ids.append(instance_id) print('Create integration %s succeed' % (integration_name, )) __delete_integrations_instances(c, instance_ids, prints_manager) prints_manager.execute_thread_prints(0) return failed_integrations, integrations_counter
def test_instances(secret_conf_path, server, username, password): integrations = get_integrations(secret_conf_path) instance_ids = [] failed_integrations = [] integrations_counter = 0 content_installation_client = demisto_client.configure(base_url=server, username=username, password=password, verify_ssl=False) install_new_content(content_installation_client, server) for integration in integrations: c = demisto_client.configure(base_url=server, username=username, password=password, verify_ssl=False) integrations_counter += 1 integration_name = integration.get('name') integration_instance_name = integration.get('instance_name', '') integration_params = integration.get('params') devops_comments = integration.get('devops_comments') product_description = integration.get('product_description', '') is_byoi = integration.get('byoi', True) has_integration = integration.get('has_integration', True) validate_test = integration.get('validate_test', True) if has_integration: instance_id, failure_message, _ = __create_integration_instance( server, username, password, integration_name, integration_instance_name, integration_params, is_byoi, validate_test=validate_test) if failure_message == 'No configuration': logging.warning( f"skipping {integration_name} as it exists in content-test-conf conf.json but not in content repo" ) continue if not instance_id: logging.error( f'Failed to create instance of {integration_name} with message: {failure_message}' ) failed_integrations.append( "{} {} - devops comments: {}".format( integration_name, product_description, devops_comments)) else: instance_ids.append(instance_id) logging.success( f'Create integration {integration_name} succeed') __delete_integrations_instances(c, instance_ids) return failed_integrations, integrations_counter
def disable_all_integrations(demisto_api_key, server, prints_manager, thread_index=0): """ Disable all enabled integrations. Should be called at start of test loop to start out clean Arguments: client -- demisto py client """ client = demisto_client.configure(base_url=server, api_key=demisto_api_key, verify_ssl=False) try: body = {'size': 1000} int_resp = demisto_client.generic_request_func(self=client, method='POST', path='/settings/integration/search', body=body) int_instances = ast.literal_eval(int_resp[0]) except requests.exceptions.RequestException as conn_err: error_message = 'Failed to disable all integrations, error trying to communicate with demisto server: ' \ '{} '.format(conn_err) prints_manager.add_print_job(error_message, print_error, thread_index) return if int(int_resp[1]) != 200: error_message = 'Get all integration instances failed with status code: {}'.format(int_resp[1]) prints_manager.add_print_job(error_message, print_error, thread_index) return if 'instances' not in int_instances: prints_manager.add_print_job("No integrations instances found to disable all", print, thread_index) return to_disable = [] for instance in int_instances['instances']: if instance.get('enabled') == 'true' and instance.get("isIntegrationScript"): add_to_disable_message = "Adding to disable list. Name: {}. Brand: {}".format(instance.get("name"), instance.get("brand")) prints_manager.add_print_job(add_to_disable_message, print, thread_index) to_disable.append(instance) if len(to_disable) > 0: __disable_integrations_instances(client, to_disable, prints_manager, thread_index=thread_index)
def run(): body = "*****@*****.**" responses.add('POST', '/entry/exportArtifact', body=body, status=200, content_type='application/json') api_instance = demisto_client.configure(base_url=host, api_key=api_key, debug=False) download_entry = demisto_client.demisto_api.DownloadEntry( ) # DownloadEntry | (optional) download_entry.id = '6@1770' download_entry.investigation_id = '1770' api_result = api_instance.entry_export_artifact( download_entry=download_entry) assert api_result == '*****@*****.**' assert len(responses.calls) == 1 assert responses.calls[0].request.url == '/entry/exportArtifact' assert responses.calls[0].request.host == 'localhost' assert responses.calls[0].request.scheme == 'http'
def run(): body = '[{"created_by":"DBot","dashboard":"None","decoder":{},"description":"This report ' \ 'generates Mean Time to Resolve by Incident type for last 2 Quarters",' \ '"id":"MTTRbyIncidentType2Quar","locked":false,"name":"Mean time to Resolve by ' \ 'Incident Type (Last 2 Quarters)","orientation":"portrait","prev_name":"Mean time to ' \ 'Resolve by Incident Type (Last 2 Quarters)","prev_type":"pdf","type":"pdf",' \ '"version":4}]' responses.add('GET', '/reports', body=body, status=200, content_type='application/json') api_instance = demisto_client.configure(base_url=host, api_key=api_key, debug=False) api_response = api_instance.get_all_reports() assert api_response[0].id == 'MTTRbyIncidentType2Quar' assert api_response[ 0].description == 'This report generates Mean Time to Resolve by Incident type for ' \ '' \ 'last 2 Quarters' assert api_response[0].version == 4 assert len(responses.calls) == 1 assert responses.calls[0].request.url == '/reports' assert responses.calls[0].request.host == 'localhost' assert responses.calls[0].request.scheme == 'http'
def update_content(content_zip_path, server=None, username=None, password=None, client=None): """Update the content on a demisto instance with the content files in a zip file. Args: server (str): URL of the demisto server instance. username (str): Username to login to the demisto instance. password (str): Password of the associated username to login to the demisto insatnce. content_zip_path (str): The path to the zip file containing content files. client (demisto_client): The configured client to use. """ try: # Configure Demisto Client and make request to upload content zip file if not client: client = demisto_client.configure(base_url=server, username=username, password=password, verify_ssl=False) file_path = os.path.abspath(content_zip_path) files = {'file': file_path} header_params = {'Content-Type': 'multipart/form-data'} msg = '\nMaking "POST" request to server - "{}" to upload'.format(server) msg += ' the content zip file "{}"'.format(content_zip_path) print(msg) response_data, status_code, _ = client.api_client.call_api(resource_path='/content/upload', method='POST', header_params=header_params, files=files) if status_code >= 300 or status_code < 200: result_object = ast.literal_eval(response_data) message = result_object['message'] msg = "Upload has failed with status code " + str(status_code) + '\n' + message raise Exception(msg) else: print('\n"{}" successfully uploaded to server "{}"'.format(content_zip_path, server)) except Exception as e: print_error(str(e))
def test_instances(secret_conf_path, server, username, password): integrations = get_integrations(secret_conf_path) instance_ids = [] failed_integrations = [] integrations_counter = 0 for integration in integrations: c = demisto_client.configure(base_url=server, username=username, password=password, verify_ssl=False) integrations_counter += 1 integration_name = integration.get('name') integration_instance_name = integration.get('instance_name', '') integration_params = integration.get('params') devops_comments = integration.get('devops_comments') product_description = integration.get('product_description', '') is_byoi = integration.get('byoi', True) has_integration = integration.get('has_integration', True) if has_integration: instance_id, failure_message = __create_integration_instance( c, integration_name, integration_instance_name, integration_params, is_byoi ) if not instance_id: print_error('Failed to create instance of {} with message: {}'.format(integration_name, failure_message)) failed_integrations.append("{} {} - devops comments: {}".format( integration_name, product_description, devops_comments)) else: instance_ids.append(instance_id) print('Create integration %s succeed' % (integration_name,)) __delete_integrations_instances(c, instance_ids) return failed_integrations, integrations_counter
def __init__(self, path: str, insecure: bool = False, verbose: bool = False): self.path = path self.log_verbose = verbose self.unify = os.path.isdir(self.path) self.client = demisto_client.configure(verify_ssl=not insecure)
def __init__(self, input: str, insecure: bool = False, verbose: bool = False): self.path = input self.log_verbose = verbose self.client = demisto_client.configure(verify_ssl=not insecure) self.status_code = 0 self.successfully_uploaded_files: List[Tuple[str, str]] = [] self.failed_uploaded_files: List[Tuple[str, str]] = []
def __init__(self, query: str, insecure: bool = False, debug: str = None, debug_path: str = None, verbose: bool = False): self.query = query if query.startswith('!') else f'!{query}' self.log_verbose = verbose self.debug = debug self.debug_path = debug_path self.client = demisto_client.configure(verify_ssl=not insecure) if self.debug: self.query += ' debug-mode="true"'
def __init__(self, playbook_id: str, url: str, wait: bool, timeout: int): self.playbook_id = playbook_id self.should_wait = wait self.timeout = timeout # if url parameter is not provided, demisto_client will search the DEMISTO_BASE_URL env variable self.demisto_client = demisto_client.configure(base_url=url, verify_ssl=False) self.base_link_to_workplan = self.get_base_link_to_workplan(url)
def run(): body = r''' { "iocObjects": [{ "id": "4737", "version": 1, "modified": "2019-07-14T16:54:02.719044+03:00", "account": "", "timestamp": "2019-07-14T16:54:02.718422+03:00", "indicator_type": "IP", "value": "92.63.197.153", "source": "Recorded Future", "investigationIDs": ["1750"], "lastSeen": "2019-07-14T16:54:02.718378+03:00", "firstSeen": "2019-07-14T16:54:02.718378+03:00", "lastSeenEntryID": "API", "firstSeenEntryID": "API", "score": 3, "manualScore": true, "setBy": "DBotWeak", "manualSetTime": "0001-01-01T00:00:00Z", "insightCache": null, "calculatedTime": "2019-07-14T16:54:02.718378+03:00", "lastReputationRun": "0001-01-01T00:00:00Z", "comment": "From Recorded Future risk list, Score - 89", "manuallyEditedFields": null }], "total": 1 } ''' responses.add('POST', '/indicators/search', body=body, status=200, content_type='application/json') api_instance = demisto_client.configure(base_url=host, api_key=api_key, debug=False) indicator_filter = demisto_client.demisto_api.IndicatorFilter( ) # IndicatorFilter | (optional) indicator_filter.query = 'value:92.63.197.153' api_response = api_instance.indicators_search( indicator_filter=indicator_filter) assert api_response.ioc_objects[0].get( 'comment') == 'From Recorded Future risk list, Score - 89' # assert api_response.type == 'Unclassified' # assert api_response.owner == 'Admin' assert len(responses.calls) == 1 assert responses.calls[0].request.url == '/indicators/search' assert responses.calls[0].request.host == 'localhost' assert responses.calls[0].request.scheme == 'http'
def get_installed_packs(self) -> List[Dict[str, str]]: """ Gets the current installed packs on the machine. """ client = demisto_client.configure(verify_ssl=self.insecure) res = client.generic_request('/contentpacks/metadata/installed', "GET") installed_packs_data = eval(res[0]) installed_packs = [{ "id": pack["id"], "version": pack['currentVersion'] } for pack in installed_packs_data] return installed_packs
def __init__(self, input: str, insecure: bool = False, verbose: bool = False): self.path = input self.log_verbose = verbose verify = ( not insecure ) if insecure else None # set to None so demisto_client will use env var DEMISTO_VERIFY_SSL self.client = demisto_client.configure(verify_ssl=verify) self.status_code = 0 self.successfully_uploaded_files: List[Tuple[str, str]] = [] self.failed_uploaded_files: List[Tuple[str, str]] = []
def __init__(self, query: str, insecure: bool = False, debug: str = None, debug_path: str = None, verbose: bool = False): self.query = query self.log_verbose = verbose self.debug = debug self.debug_path = debug_path self.client = demisto_client.configure(verify_ssl=not insecure) if self.debug is not None: self.query += ' debug-mode="true"'
def main(): options = arguments_handler() investigation_id = options.investigation_id api_key = options.api_key if investigation_id and api_key: client = demisto_client.configure(base_url=GOLD_SERVER_URL, api_key=api_key, verify_ssl=False) wait_for_playbook_to_complete(investigation_id, client) else: print( "Secrets detection step failed - API key or investigation ID were not supplied." ) sys.exit(1)
def __init__(self, test_playbook_path: str = '', all: bool = False, wait: bool = True, timeout: int = 90, insecure: bool = False): self.test_playbook_path = test_playbook_path self.all_test_playbooks = all self.should_wait = wait self.timeout = timeout # we set to None so demisto_client will use env var DEMISTO_VERIFY_SSL self.verify = (not insecure) if insecure else None self.demisto_client = demisto_client.configure(verify_ssl=self.verify) self.base_link_to_workplan = self.get_base_link_to_workplan()
def __init__(self, playbook_id: str, url: str, wait: bool, timeout: int, insecure: bool = False): self.playbook_id = playbook_id self.should_wait = wait self.timeout = timeout verify = ( not insecure ) if insecure else None # we set to None so demisto_client will use env var DEMISTO_VERIFY_SSL # if url parameter is not provided, demisto_client will search the DEMISTO_BASE_URL env variable self.demisto_client = demisto_client.configure(base_url=url, verify_ssl=verify) self.base_link_to_workplan = self.get_base_link_to_workplan(url)
def test_import_layout(mocker): """ Given: - Path for a layoutscontainer. When - Using client.import_layout() to upload a new layout. Then - The layout is being uploaded and getting back the layout metadata. """ client = demisto_client.configure(base_url=host, api_key=api_key, debug=False, verify_ssl=False) mocker.patch.object(client, 'import_layout_with_http_info', return_value={'test': 'test'}) res = client.import_layout('tests_data/layoutscontainer-test.json') assert res.get('test') == 'test'
def update_content(content_zip_path, server=None, username=None, password=None, client=None): """Update the content on a demisto instance with the content files in a zip file. Args: server (str): URL of the demisto server instance. username (str): Username to login to the demisto instance. password (str): Password of the associated username to login to the demisto instance. content_zip_path (str): The path to the zip file containing content files. client (demisto_client): The configured client to use. """ try: # Configure Demisto Client and make request to upload content zip file if not client: client = demisto_client.configure(base_url=server, username=username, password=password, verify_ssl=False) file_path = os.path.abspath(content_zip_path) files = {'file': file_path} header_params = {'Content-Type': 'multipart/form-data'} logging.info( f'Making "POST" request to server - "{server}" to upload the content zip file "{content_zip_path}"' ) response_data, status_code, _ = client.api_client.call_api( resource_path='/content/upload', method='POST', header_params=header_params, files=files) if status_code >= 300 or status_code < 200: result_object = ast.literal_eval(response_data) message = result_object['message'] raise Exception( f"Upload has failed with status code {status_code}\n{message}") success_msg = f'"{content_zip_path}" successfully uploaded to server "{server}"' logging.success(success_msg) except Exception: logging.exception( f'Failed to upload {content_zip_path} to server {server}')
def test_import_layout_with_http_info_without_knowing_server_version(mocker): """ Given: - Path for a layoutscontainer. When - Not knowing demisto version, and working with 6.0.0 or higher Then - The layout is being uploaded and getting back the layout metadata. """ client = demisto_client.configure(base_url=host, api_key=api_key, debug=False, verify_ssl=False) mocker.patch.object(client.api_client, 'call_api', side_effect=[("{'demistoVersion': '6.0.0'}", 404, { 'Content-type': 'application/json' }), { 'test': 'test' }]) res = client.import_layout('tests_data/layoutscontainer-test.json') assert res.get('test') == 'test'
def run(): body = '{"name":"Test Incident","owner":"Admin","parent":"","phase":"",' \ '"playbookId":"playbook0","playbook_id":"playbook0","rawCategory":"",' \ '"rawCloseReason":"","rawJSON":"","rawName":"Test Incident","rawPhase":"",' \ '"rawType":"Unclassified","raw_category":"","raw_close_reason":"","raw_json":"",' \ '"raw_name":"Test Incident","raw_phase":"","raw_type":"Unclassified","reason":"",' \ '"runStatus":"","run_status":"","severity":0,"sourceBrand":"Manual",' \ '"sourceInstance":"admin","source_brand":"Manual","source_instance":"admin",' \ '"status":0,"type":"Unclassified","version":1}' responses.add('POST', '/incident', body=body, status=200, content_type='application/json') # create an instance of the API class api_instance = demisto_client.configure(base_url=host, api_key=api_key) create_incident_request = demisto_client.demisto_api.CreateIncidentRequest( ) create_incident_request.name = 'Test Incident' create_incident_request.type = 'Unclassified' create_incident_request.owner = 'Admin' create_incident_request.occurred = datetime.now() api_response = api_instance.create_incident( create_incident_request=create_incident_request) assert api_response.name == 'Test Incident' assert api_response.type == 'Unclassified' assert api_response.owner == 'Admin' assert len(responses.calls) == 1 req = responses.calls[0].request assert req.url == '/incident' assert req.host == 'localhost' assert req.scheme == 'http' # veriy date field occurred according to rfc 3339 req_body = json.loads(req.body) assert req_body['occurred'][-6] == '+' or req_body['occurred'][ -6] == '-' # end with +/- offset
def run(): responses.add('POST', '/test', body="all good", status=200, content_type='text/plain') api_instance = demisto_client.configure(base_url=host, api_key=api_key, debug=False) (res, code, headers) = api_instance.generic_request('/test', 'POST', body="this is a test", content_type='text/plain', accept='text/plain') assert res == 'all good' assert code == 200 assert len(responses.calls) == 1 assert responses.calls[0].request.url == '/test' assert responses.calls[0].request.host == 'localhost' assert responses.calls[0].request.scheme == 'http'
def main(): install_logging('cleanup_xsiam_instance.log', logger=logging) # in xsiam we dont use demisto username os.environ.pop('DEMISTO_USERNAME', None) options = options_handler() host = options.xsiam_machine xsiam_servers = get_json_file(options.xsiam_servers_path) api_key, base_url, xdr_auth_id = get_xsiam_configuration( options.xsiam_machine, xsiam_servers) logging.info(f'Starting cleanup for XSIAM server {host}') client = demisto_client.configure(base_url=base_url, verify_ssl=False, api_key=api_key, auth_id=xdr_auth_id) success = reset_base_pack_version(client) and uninstall_all_packs( client, host) and wait_for_uninstallation_to_complete(client) if not success: sys.exit(2) logging.info('Uninstalling packs done.')
def __init__(self, input: str, insecure: bool = False, verbose: bool = False, pack_names: list = None, skip_validation: bool = False, detached_files: bool = False, reattach: bool = False): self.path = input self.log_verbose = verbose verify = ( not insecure ) if insecure else None # set to None so demisto_client will use env var DEMISTO_VERIFY_SSL self.client = demisto_client.configure(verify_ssl=verify) self.successfully_uploaded_files: List[Tuple[str, str]] = [] self.failed_uploaded_files: List[Tuple[str, str, str]] = [] self.unuploaded_due_to_version: List[Tuple[str, str, Version, Version, Version]] = [] self.demisto_version = get_demisto_version(self.client) self.pack_names = pack_names self.skip_upload_packs_validation = skip_validation self.is_files_to_detached = detached_files self.reattach_files = reattach
def __init__(self, query: str, insecure: bool = False, debug: str = None, debug_path: str = None, verbose: bool = False, json_to_outputs: bool = False, prefix: str = '', raw_response: bool = False): self.query = query if query.startswith('!') else f'!{query}' self.log_verbose = verbose self.debug = debug self.debug_path = debug_path verify = ( not insecure ) if insecure else None # set to None so demisto_client will use env var DEMISTO_VERIFY_SSL self.client = demisto_client.configure(verify_ssl=verify) self.json2outputs = json_to_outputs self.prefix = prefix self.raw_response = raw_response if self.debug or self.json2outputs: self.query += ' debug-mode="true"'
def run(): responses.add('POST', '/test', body="Not good", status=400, content_type='text/plain') api_instance = demisto_client.configure(base_url=host, api_key=api_key, debug=False) with self.assertRaises(ApiException) as context: (_, _, _) = api_instance.generic_request('/test', 'POST', body="this is a test", content_type='text/plain', accept='text/plain') self.assertTrue('HTTP response body' in str(context.exception)) self.assertFalse('HTTP response headers' in str(context.exception)) assert len(responses.calls) == 1 assert responses.calls[0].request.url == '/test' assert responses.calls[0].request.host == 'localhost' assert responses.calls[0].request.scheme == 'http'
def test_import_layout_with_http_info_with_old_layout_format(mocker): """ Given: - Path for a layout When - Working with 5.0.0 and uploading a layout(the old version) Then - The layout is being uploaded and getting back the layout metadata. """ client = demisto_client.configure(base_url=host, api_key=api_key, debug=False, verify_ssl=False) mocker.patch.object(client.api_client, 'call_api', side_effect=[("{'demistoVersion': '5.0.0'}", 200, { 'Content-type': 'application/json' }), { 'test': 'test' }]) res = client.import_layout('tests_data/layout-details-test-V2.json') assert res.get('test') == 'test'
def wait_for_playbook_to_complete(investigation_id, client): investigation_url = f'{GOLD_SERVER_URL}/#/Custom/caseinfoid/{investigation_id}' print(f'Investigation URL: {investigation_url}') timeout = time.time() + DEFAULT_TIMEOUT # wait for playbook to finish run while True: # give playbook time to run time.sleep(SLEEP_WAIT_SECONDS) try: playbook_state = get_playbook_state(client, investigation_id) except demisto_client.demisto_api.rest.ApiException: playbook_state = 'Pending' client = demisto_client.configure( base_url=client.api_client.configuration.host, api_key=client.api_client.configuration.api_key, verify_ssl=False) if playbook_state == PB_Status.COMPLETED: print( "Secrets playbook finished successfully, no secrets were found." ) break if playbook_state == PB_Status.FAILED: print( f'Secrets playbook was failed as secrets were found. To investigate go to: {investigation_url}' ) sys.exit(1) if time.time() > timeout: print( f'Secrets playbook timeout reached. To investigate go to: {investigation_url}' ) sys.exit(1)
def run(): body = '{ "images": [{"id": "aae7b8aaba8c", "repository": ' \ '"openapitools/openapi-generator-cli", "tag": "latest", "createdSince": "3 days ago", ' \ '"createdAt": "2019-08-19 13:34:22 +0300 IDT", "size": "131MB" }]}' responses.add('GET', '/settings/docker-images', body=body, status=200, content_type='application/json') # create an instance of the API class api_instance = demisto_client.configure(base_url=host, api_key=api_key) api_response = api_instance.get_docker_images() assert api_response.images[ 0].created_at == '2019-08-19 13:34:22 +0300 IDT' assert api_response.images[0].id == 'aae7b8aaba8c' assert api_response.images[ 0].repository == 'openapitools/openapi-generator-cli' assert len(responses.calls) == 1 assert responses.calls[0].request.url == '/settings/docker-images' assert responses.calls[0].request.host == 'localhost' assert responses.calls[0].request.scheme == 'http'