def search_pack(client: demisto_client,
                pack_display_name: str,
                pack_id: str,
                lock: Lock) -> dict:
    """ Make a pack search request.

    Args:
        client (demisto_client): The configured client to use.
        pack_display_name (string): The pack display name.
        pack_id (string): The pack ID.
        lock (Lock): A lock object.
    Returns:
        (dict): Returns the pack data if found, or empty dict otherwise.
    """

    try:
        # make the search request
        response_data, status_code, _ = demisto_client.generic_request_func(client,
                                                                            path=f'/contentpacks/marketplace/{pack_id}',
                                                                            method='GET',
                                                                            accept='application/json',
                                                                            _request_timeout=None)

        if 200 <= status_code < 300:
            result_object = ast.literal_eval(response_data)

            if result_object and result_object.get('currentVersion'):
                logging.debug(f'Found pack "{pack_display_name}" by its ID "{pack_id}" in bucket!')

                pack_data = {
                    'id': result_object.get('id'),
                    'version': result_object.get('currentVersion')
                }
                return pack_data

            else:
                raise Exception(f'Did not find pack "{pack_display_name}" by its ID "{pack_id}" in bucket.')
        else:
            result_object = ast.literal_eval(response_data)
            msg = result_object.get('message', '')
            err_msg = f'Search request for pack "{pack_display_name}" with ID "{pack_id}", failed with status code ' \
                      f'{status_code}\n{msg}'
            raise Exception(err_msg)
    except Exception:
        logging.exception(f'Search request for pack "{pack_display_name}" with ID "{pack_id}", failed.')

        lock.acquire()
        global SUCCESS_FLAG
        SUCCESS_FLAG = False
        lock.release()
Example #2
0
def get_pack_dependencies(client, prints_manager, pack_data):
    """ Get the pack's required dependencies.

    Args:
        client (demisto_client): The configured client to use.
        prints_manager (ParallelPrintsManager): A prints manager object.
        pack_data (dict): Contains the pack ID and version.

    Returns:
        (list) The pack's dependencies.
    """
    pack_id = pack_data['id']

    try:
        response_data, status_code, _ = demisto_client.generic_request_func(
            client,
            path='/contentpacks/marketplace/search/dependencies',
            method='POST',
            body=[pack_data],
            accept='application/json',
            _request_timeout=None)

        if 200 <= status_code < 300:
            dependencies_data = []
            dependants_ids = [pack_id]
            reseponse_data = ast.literal_eval(response_data).get(
                'dependencies', [])
            create_dependencies_data_structure(reseponse_data, dependants_ids,
                                               dependencies_data,
                                               dependants_ids)
            dependencies_str = ', '.join(
                [dep['id'] for dep in dependencies_data])
            if dependencies_data:
                message = 'Found the following dependencies for pack {}:\n{}\n'.format(
                    pack_id, dependencies_str)
                prints_manager.add_print_job(message, print_color, 0,
                                             LOG_COLORS.GREEN)
                prints_manager.execute_thread_prints(0)
            return dependencies_data
        else:
            result_object = ast.literal_eval(response_data)
            msg = result_object.get('message', '')
            err_msg = 'Failed to get pack {} dependencies - with status code {}\n{}\n'.format(
                pack_id, status_code, msg)
            raise Exception(err_msg)
    except Exception as e:
        err_msg = 'The request to get pack {} dependencies has failed. Reason:\n{}\n'.format(
            pack_id, str(e))
        raise Exception(err_msg)
def __test_integration_instance(client,
                                module_instance,
                                prints_manager,
                                thread_index=0):
    connection_retries = 3
    response_code = 0
    prints_manager.add_print_job("trying to connect.", print_warning,
                                 thread_index)
    for i in range(connection_retries):
        try:
            response_data, response_code, _ = demisto_client.generic_request_func(
                self=client,
                method='POST',
                path='/settings/integration/test',
                body=module_instance,
                _request_timeout=120)
            break
        except ApiException as conn_err:
            error_msg = 'Failed to test integration instance, error trying to communicate with demisto '\
                        'server: {} '.format(conn_err)
            prints_manager.add_print_job(error_msg, print_error, thread_index)
            return False, None
        except urllib3.exceptions.ReadTimeoutError:
            warning_msg = "Could not connect. Trying to connect for the {} time".format(
                i + 1)
            prints_manager.add_print_job(warning_msg, print_warning,
                                         thread_index)

    if int(response_code) != 200:
        test_failed_msg = 'Integration-instance test ("Test" button) failed.\nBad status code: ' + str(
            response_code)
        prints_manager.add_print_job(test_failed_msg, print_error,
                                     thread_index)
        return False, None

    result_object = ast.literal_eval(response_data)
    success, failure_message = bool(
        result_object.get('success')), result_object.get('message')
    if not success:
        if failure_message:
            test_failed_msg = 'Test integration failed.\nFailure message: {}'.format(
                failure_message)
            prints_manager.add_print_job(test_failed_msg, print_error,
                                         thread_index)
        else:
            test_failed_msg = 'Test integration failed\nNo failure message.'
            prints_manager.add_print_job(test_failed_msg, print_error,
                                         thread_index)
    return success, failure_message
Example #4
0
def install_packs(client,
                  host,
                  prints_manager,
                  packs_to_install,
                  request_timeout=9999999):
    """ Make a packs installation request.

    Args:
        client (demisto_client): The configured client to use.
        host (str): The server URL.
        prints_manager (ParallelPrintsManager): Print manager object.
        packs_to_install (list): A list of the packs to install.
        request_timeout (int): Timeout settings for the installation request.
    """

    request_data = {'packs': packs_to_install, 'ignoreWarnings': True}

    packs_to_install_str = ', '.join([pack['id'] for pack in packs_to_install])
    message = 'Installing the following packs in server {}:\n{}'.format(
        host, packs_to_install_str)
    prints_manager.add_print_job(message, print_color, 0, LOG_COLORS.GREEN)
    prints_manager.execute_thread_prints(0)

    # make the pack installation request
    try:
        response_data, status_code, _ = demisto_client.generic_request_func(
            client,
            path='/contentpacks/marketplace/install',
            method='POST',
            body=request_data,
            accept='application/json',
            _request_timeout=request_timeout)

        if 200 <= status_code < 300:
            message = 'Packs were successfully installed!'
            prints_manager.add_print_job(message, print_color, 0,
                                         LOG_COLORS.GREEN)
            prints_manager.execute_thread_prints(0)
        else:
            result_object = ast.literal_eval(response_data)
            message = result_object.get('message', '')
            err_msg = 'Failed to install packs - with status code {}\n{}\n'.format(
                status_code, message)
            raise Exception(err_msg)
    except Exception as e:
        err_msg = 'The request to install packs has failed. Reason:\n{}\n'.format(
            str(e))
        raise Exception(err_msg)
Example #5
0
def __delete_integration_instance_if_determined_by_name(
        client, instance_name, prints_manager, thread_index=0):
    """Deletes integration instance by it's name.

    Args:
        client (demisto_client): The configured client to use.
        instance_name (str): The name of the instance to delete.
        prints_manager (ParallelPrintsManager): Print manager object.
        thread_index: The index of the thread running the execution.

    Notes:
        This function is needed when the name of the instance is pre-defined in the tests configuration, and the test
        itself depends on the instance to be called as the `instance name`.
        In case we need to configure another instance with the same name, the client will throw an error, so we
        will call this function first, to delete the instance with this name.

    """
    try:
        int_resp = demisto_client.generic_request_func(
            self=client,
            method='POST',
            path='/settings/integration/search',
            body={'size': 1000})
        int_instances = ast.literal_eval(int_resp[0])
    except requests.exceptions.RequestException as conn_err:
        error_message = 'Failed to delete integrations instance, 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 integration instance 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 delete", print, thread_index)
        return

    for instance in int_instances['instances']:
        if instance.get('name') == instance_name:
            prints_manager.add_print_job(
                f'Deleting integration instance {instance_name} since it is defined by name',
                print_color,
                thread_index,
                message_color=LOG_COLORS.GREEN)
            __delete_integration_instance(client, instance.get('id'),
                                          prints_manager, thread_index)
Example #6
0
def __delete_integration_instance(client, instance_id):
    try:
        res = demisto_client.generic_request_func(self=client, method='DELETE',
                                                  path='/settings/integration/' + urllib.quote(
                                                      instance_id))
    except requests.exceptions.RequestException as conn_err:
        print_error(
            'Failed to delete integration instance, error trying to communicate with demisto '
            'server: {} '.format(
                conn_err))
        return False
    if int(res[1]) != 200:
        print_error('delete integration instance failed\nStatus code' + str(res[1]))
        print_error(pformat(res))
        return False
    return True
Example #7
0
def __get_investigation_playbook_state(client, inv_id, prints_manager, thread_index=0):
    try:
        investigation_playbook_raw = demisto_client.generic_request_func(self=client, method='GET',
                                                                         path='/inv-playbook/' + inv_id)
        investigation_playbook = ast.literal_eval(investigation_playbook_raw[0])
    except requests.exceptions.RequestException as conn_err:
        error_message = 'Failed to get investigation playbook state, error trying to communicate with demisto ' \
                        'server: {} '.format(conn_err)
        prints_manager.add_print_job(error_message, print_error, thread_index)
        return PB_Status.FAILED

    try:
        state = investigation_playbook['state']
        return state
    except:  # noqa: E722
        return PB_Status.NOT_SUPPORTED_VERSION
Example #8
0
def __delete_integration_instance(client, instance_id, prints_manager, thread_index=0):
    try:
        res = demisto_client.generic_request_func(self=client, method='DELETE',
                                                  path='/settings/integration/' + urllib.quote(
                                                      instance_id))
    except requests.exceptions.RequestException as conn_err:
        error_message = 'Failed to delete integration instance, error trying to communicate with demisto ' \
                        'server: {} '.format(conn_err)
        prints_manager.add_print_job(error_message, print_error, thread_index)
        return False
    if int(res[1]) != 200:
        error_message = 'delete integration instance failed\nStatus code' + str(res[1])
        prints_manager.add_print_job(error_message, print_error, thread_index)
        prints_manager.add_print_job(pformat(res), print_error, thread_index)
        return False
    return True
Example #9
0
def __get_investigation_playbook_state(client, inv_id, logging_manager):
    try:
        investigation_playbook_raw = demisto_client.generic_request_func(self=client, method='GET',
                                                                         path='/inv-playbook/' + inv_id)
        investigation_playbook = ast.literal_eval(investigation_playbook_raw[0])
    except ApiException:
        logging_manager.exception(
            'Failed to get investigation playbook state, error trying to communicate with demisto server'
        )
        return PB_Status.FAILED

    try:
        state = investigation_playbook['state']
        return state
    except:  # noqa: E722
        return PB_Status.NOT_SUPPORTED_VERSION
Example #10
0
def reset_base_pack_version(client: demisto_client):
    """
    Resets base pack version to prod version.

    Args:
        client (demisto_client): The client to connect to.


    """
    host = client.api_client.configuration.host.replace(
        'https://api-', 'https://')  # disable-secrets-detection
    try:
        # make the search request
        response_data, status_code, _ = demisto_client.generic_request_func(
            client,
            path='/contentpacks/marketplace/Base',
            method='GET',
            accept='application/json',
            _request_timeout=None)
        if 200 <= status_code < 300:
            result_object = ast.literal_eval(response_data)

            if result_object and result_object.get('currentVersion'):
                logging.debug('Found Base pack in bucket!')

                pack_data = {
                    'id': result_object.get('id'),
                    'version': result_object.get('currentVersion')
                }
                # install latest version of Base pack
                logging.info(
                    f'updating base pack to version {result_object.get("currentVersion")}'
                )
                return install_packs(client, host, [pack_data], False)

            else:
                raise Exception('Did not find Base pack')
        else:
            result_object = ast.literal_eval(response_data)
            msg = result_object.get('message', '')
            err_msg = f'Search request for base pack, failed with status code ' \
                      f'{status_code}\n{msg}'
            raise Exception(err_msg)
    except Exception:
        logging.exception('Search request Base pack has failed.')
        return False
Example #11
0
def search_pack(client, prints_manager, pack_display_name):
    """ Make a pack search request.

    Args:
        client (demisto_client): The configured client to use.
        prints_manager (ParallelPrintsManager): Print manager object.
        pack_display_name (string): The pack display name.

    Returns:
        (dict): Returns the pack data if found, or empty dict otherwise.
    """

    try:
        # make the search request
        response_data, status_code, _ = demisto_client.generic_request_func(client,
                                                                            path='/contentpacks/marketplace/search',
                                                                            method='POST',
                                                                            body={"packsQuery": pack_display_name},
                                                                            accept='application/json',
                                                                            _request_timeout=None)

        if 200 <= status_code < 300:
            result_object = ast.literal_eval(response_data)
            search_results = result_object.get('packs', [])
            pack_data = get_pack_data_from_results(search_results, pack_display_name)
            if pack_data:
                print_msg = 'Found pack {} in bucket!\n'.format(pack_display_name)
                prints_manager.add_print_job(print_msg, print_color, 0, LOG_COLORS.GREEN)
                prints_manager.execute_thread_prints(0)
                return pack_data

            else:
                print_msg = 'Did not find pack {} in bucket.\n'.format(pack_display_name)
                prints_manager.add_print_job(print_msg, print_color, 0, LOG_COLORS.YELLOW)
                prints_manager.execute_thread_prints(0)
                return {}
        else:
            result_object = ast.literal_eval(response_data)
            msg = result_object.get('message', '')
            err_msg = 'Pack {} search request failed - with status code {}\n{}'.format(pack_display_name,
                                                                                       status_code, msg)
            raise Exception(err_msg)
    except Exception as e:
        err_msg = 'The request to search pack {} has failed. Reason:\n{}'.format(pack_display_name, str(e))
        raise Exception(err_msg)
Example #12
0
def get_pack_dependencies(client: demisto_client, pack_data: dict, lock: Lock):
    """ Get the pack's required dependencies.

    Args:
        client (demisto_client): The configured client to use.
        pack_data (dict): Contains the pack ID and version.
        lock (Lock): A lock object.
    Returns:
        (list) The pack's dependencies.
    """
    pack_id = pack_data['id']
    logging.debug(f'Getting dependencies for pack {pack_id}')
    try:
        response_data, status_code, _ = demisto_client.generic_request_func(
            client,
            path='/contentpacks/marketplace/search/dependencies',
            method='POST',
            body=[pack_data],
            accept='application/json',
            _request_timeout=None
        )

        if 200 <= status_code < 300:
            dependencies_data: list = []
            dependants_ids = [pack_id]
            reseponse_data = ast.literal_eval(response_data).get('dependencies', [])
            create_dependencies_data_structure(reseponse_data, dependants_ids, dependencies_data, dependants_ids)
            dependencies_str = ', '.join([dep['id'] for dep in dependencies_data])
            if dependencies_data:
                logging.debug(f'Found the following dependencies for pack {pack_id}: {dependencies_str}')
            return dependencies_data
        if status_code == 400:
            logging.error(f'Unable to find dependencies for {pack_id}.')
            return []
        else:
            result_object = ast.literal_eval(response_data)
            msg = result_object.get('message', '')
            raise Exception(f'Failed to get pack {pack_id} dependencies - with status code {status_code}\n{msg}\n')
    except Exception:
        logging.exception(f'The request to get pack {pack_id} dependencies has failed.')

        lock.acquire()
        global SUCCESS_FLAG
        SUCCESS_FLAG = False
        lock.release()
def get_playbook_state(client: demisto_client, inv_id: str):
    # returns current investigation playbook state - 'inprogress'/'failed'/'completed'
    try:
        investigation_playbook_raw = demisto_client.generic_request_func(
            self=client, method='GET', path='/inv-playbook/' + inv_id)
        investigation_playbook = ast.literal_eval(
            investigation_playbook_raw[0])
    except ApiException:
        print(
            'Failed to get investigation playbook state, error trying to communicate with demisto server'
        )
        return PB_Status.FAILED

    try:
        state = investigation_playbook['state']
        return state
    except:  # noqa: E722
        return PB_Status.NOT_SUPPORTED_VERSION
Example #14
0
def disable_all_integrations(dem_client, 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
    """
    try:
        body = {'size': 1000}
        int_resp = demisto_client.generic_request_func(
            self=dem_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(dem_client,
                                         to_disable,
                                         prints_manager,
                                         thread_index=thread_index)
Example #15
0
def __delete_integration_instance(client,
                                  instance_id,
                                  logging_manager=logging):
    try:
        res = demisto_client.generic_request_func(
            self=client,
            method='DELETE',
            path='/settings/integration/' + urllib.parse.quote(instance_id))
    except ApiException:
        logging_manager.exception(
            'Failed to delete integration instance, error trying to communicate with demisto.'
        )
        return False
    if int(res[1]) != 200:
        logging_manager.error(
            f'delete integration instance failed\nStatus code {res[1]}')
        logging_manager.error(pformat(res))
        return False
    return True
Example #16
0
def __delete_incident(client: DefaultApi, incident: Incident, logging_manager):
    try:
        body = {
            'ids': [incident.id],
            'filter': {},
            'all': False
        }
        res = demisto_client.generic_request_func(self=client, method='POST',
                                                  path='/incident/batchDelete', body=body)
    except ApiException:
        logging_manager.exception('Failed to delete incident, error trying to communicate with demisto server')
        return False

    if int(res[1]) != 200:
        logging_manager.error(f'delete incident failed with Status code {res[1]}')
        logging_manager.error(pformat(res))
        return False

    return True
Example #17
0
def __disable_integrations_instances(client, module_instances, logging_module=logging):
    for configured_instance in module_instances:
        # tested with POSTMAN, this is the minimum required fields for the request.
        module_instance = {
            key: configured_instance[key] for key in ['id', 'brand', 'name', 'data', 'isIntegrationScript', ]
        }
        module_instance['enable'] = "false"
        module_instance['version'] = -1
        logging.debug(f'Disabling integration {module_instance.get("name")}')
        try:
            res = demisto_client.generic_request_func(self=client, method='PUT',
                                                      path='/settings/integration',
                                                      body=module_instance)
        except ApiException:
            logging_module.exception('Failed to disable integration instance')
            return

        if res[1] != 200:
            logging_module.error(f'disable instance failed, Error: {pformat(res)}')
Example #18
0
def __delete_incident(client, incident):
    try:
        body = {'ids': [incident['id']], 'filter': {}, 'all': False}
        res = demisto_client.generic_request_func(self=client,
                                                  method='POST',
                                                  path='/incident/batchDelete',
                                                  body=body)
    except requests.exceptions.RequestException as conn_err:
        print_error(
            'Failed to delete incident, error trying to communicate with demisto server: {} '
            ''.format(conn_err))
        return False

    if int(res[1]) != 200:
        print_error('delete incident failed\nStatus code' + str(res[1]))
        print_error(pformat(res))
        return False

    return True
def __print_investigation_error(client,
                                playbook_id,
                                investigation_id,
                                prints_manager,
                                color=LOG_COLORS.RED,
                                thread_index=0):
    try:
        empty_json = {"pageSize": 1000}
        res = demisto_client.generic_request_func(
            self=client,
            method='POST',
            path='/investigation/' + urllib.quote(investigation_id),
            body=empty_json)
    except requests.exceptions.RequestException as conn_err:
        error_message = 'Failed to print investigation error, error trying to communicate with demisto ' \
            'server: {} '.format(conn_err)
        prints_manager.add_print_job(error_message, print_error, thread_index)
    if res and int(res[1]) == 200:
        resp_json = ast.literal_eval(res[0])
        entries = resp_json['entries']
        prints_manager.add_print_job('Playbook ' + playbook_id +
                                     ' has failed:',
                                     print_color,
                                     thread_index,
                                     message_color=color)
        for entry in entries:
            if entry['type'] == ENTRY_TYPE_ERROR and entry['parentContent']:
                prints_manager.add_print_job('- Task ID: ' +
                                             entry['taskId'].encode('utf-8'),
                                             print_color,
                                             thread_index,
                                             message_color=color)
                prints_manager.add_print_job(
                    '  Command: ' + entry['parentContent'].encode('utf-8'),
                    print_color,
                    thread_index,
                    message_color=color)
                body_contents_str = '  Body:\n' + entry['contents'].encode(
                    'utf-8') + '\n'
                prints_manager.add_print_job(body_contents_str,
                                             print_color,
                                             thread_index,
                                             message_color=color)
def set_marketplace_gcp_bucket_for_build(client, prints_manager, branch_name, ci_build_number):
    """Sets custom marketplace GCP bucket based on branch name and build number

    Args:
        client (demisto_client): The configured client to use.
        prints_manager (ParallelPrintsManager): Print manager object
        branch_name (str): GitHub branch name
        ci_build_number (str): CI build number

    Returns:
        None
    """
    host = client.api_client.configuration.host
    installed_content_message = \
        '\nMaking "POST" request to server - "{}" to set GCP bucket server configuration.'.format(host)
    prints_manager.add_print_job(installed_content_message, print_color, 0, LOG_COLORS.GREEN)

    # make request to update server configs
    data = {
        'data': {
            'content.pack.verify': 'false',
            'marketplace.initial.sync.delay': '0',
            'content.pack.ignore.missing.warnings.contentpack': 'true',
            'marketplace.bootstrap.bypass.url':
                'https://storage.googleapis.com/marketplace-ci-build/content/builds/{}/{}'.format(
                    branch_name, ci_build_number
                )
        },
        'version': -1
    }
    response_data, status_code, _ = demisto_client.generic_request_func(self=client, path='/system/config',
                                                                        method='POST', body=data)

    try:
        result_object = ast.literal_eval(response_data)
    except ValueError as err:
        print_error('failed to parse response from demisto. response is {}.\nError:\n{}'.format(response_data, err))
        return

    if status_code >= 300 or status_code < 200:
        message = result_object.get('message', '')
        msg = "Failed to set GCP bucket server config - with status code " + str(status_code) + '\n' + message
        print_error(msg)
Example #21
0
def __delete_integration_instance_if_determined_by_name(
        client, instance_name, logging_manager):
    """Deletes integration instance by it's name.

    Args:
        client (demisto_client): The configured client to use.
        instance_name (str): The name of the instance to delete.
        logging_manager (ParallelLoggingManager): logging manager object.

    Notes:
        This function is needed when the name of the instance is pre-defined in the tests configuration, and the test
        itself depends on the instance to be called as the `instance name`.
        In case we need to configure another instance with the same name, the client will throw an error, so we
        will call this function first, to delete the instance with this name.

    """
    try:
        int_resp = demisto_client.generic_request_func(
            self=client,
            method='POST',
            path='/settings/integration/search',
            body={'size': 1000})
        int_instances = ast.literal_eval(int_resp[0])
    except ApiException:
        logging_manager.exception(
            'Failed to delete integrations instance, error trying to communicate with demisto server'
        )
        return
    if int(int_resp[1]) != 200:
        logging_manager.error(
            f'Get integration instance failed with status code: {int_resp[1]}')
        return
    if 'instances' not in int_instances:
        logging_manager.info('No integrations instances found to delete')
        return

    for instance in int_instances['instances']:
        if instance.get('name') == instance_name:
            logging_manager.info(
                f'Deleting integration instance {instance_name} since it is defined by name'
            )
            __delete_integration_instance(client, instance.get('id'),
                                          logging_manager)
def __delete_incident(client, incident, prints_manager, thread_index=0):
    try:
        body = {'ids': [incident['id']], 'filter': {}, 'all': False}
        res = demisto_client.generic_request_func(self=client,
                                                  method='POST',
                                                  path='/incident/batchDelete',
                                                  body=body)
    except requests.exceptions.RequestException as conn_err:
        error_message = 'Failed to delete incident, error trying to communicate with demisto server: {} '\
            ''.format(conn_err)
        prints_manager.add_print_job(error_message, print_error, thread_index)
        return False

    if int(res[1]) != 200:
        error_message = 'delete incident failed\nStatus code' + str(res[1])
        prints_manager.add_print_job(error_message, print_error, thread_index)
        prints_manager.add_print_job(pformat(res), print_error, thread_index)
        return False

    return True
Example #23
0
def __print_investigation_error(client, playbook_id, investigation_id, color=LOG_COLORS.RED):
    try:
        empty_json = {"pageSize": 1}
        res = demisto_client.generic_request_func(self=client, method='POST',
                                                  path='/investigation/' + urllib.quote(
                                                      investigation_id), body=empty_json)
    except requests.exceptions.RequestException as conn_err:
        print_error(
            'Failed to print investigation error, error trying to communicate with demisto '
            'server: {} '.format(
                conn_err))
    if res and int(res[1]) == 200:
        resp_json = ast.literal_eval(res[0])
        entries = resp_json['entries']
        print_color('Playbook ' + playbook_id + ' has failed:', color)
        for entry in entries:
            if entry['type'] == ENTRY_TYPE_ERROR:
                if entry['parentContent']:
                    print_color('\t- Command: ' + entry['parentContent'].encode('utf-8'), color)
                print_color('\t- Body: ' + entry['contents'].encode('utf-8'), color)
def __enable_integrations_instances(client, module_instances):
    for configured_instance in module_instances:
        # tested with POSTMAN, this is the minimum required fields for the request.
        module_instance = {
            key: configured_instance[key] for key in ['id', 'brand', 'name', 'data', 'isIntegrationScript', ]
        }
        module_instance['enable'] = "true"
        module_instance['version'] = -1

        try:
            res = demisto_client.generic_request_func(self=client, method='PUT',
                                                      path='/settings/integration',
                                                      body=module_instance)
            if res[1] != 200:
                print_error('Enabling instance failed with status code ' + str(res[1]) + '\n' + pformat(res))
        except ApiException as conn_err:
            print_error(
                'Failed to enable integration instance, error trying to communicate with demisto '
                'server: {} '.format(conn_err.body)
            )
def __get_integration_config(client,
                             integration_name,
                             prints_manager,
                             thread_index=0):
    body = {'page': 0, 'size': 100, 'query': 'name:' + integration_name}
    try:
        res_raw = demisto_client.generic_request_func(
            self=client,
            path='/settings/integration/search',
            method='POST',
            body=body)
    except ApiException as conn_error:
        prints_manager.add_print_job(conn_error, print, thread_index)
        return None

    res = ast.literal_eval(res_raw[0])
    TIMEOUT = 180
    SLEEP_INTERVAL = 5
    total_sleep = 0
    while 'configurations' not in res:
        if total_sleep == TIMEOUT:
            error_message = "Timeout - failed to get integration {} configuration. Error: {}".format(
                integration_name, res)
            prints_manager.add_print_job(error_message, print_error,
                                         thread_index)
            return None

        time.sleep(SLEEP_INTERVAL)
        total_sleep += SLEEP_INTERVAL

    all_configurations = res['configurations']
    match_configurations = [
        x for x in all_configurations if x['name'] == integration_name
    ]

    if not match_configurations or len(match_configurations) == 0:
        prints_manager.add_print_job('integration was not found', print_error,
                                     thread_index)
        return None

    return match_configurations[0]
Example #26
0
def test_integration_instance(client, module_instance, logging_module=logging):
    connection_retries = 3
    response_code = 0
    integration_of_instance = module_instance.get('brand', '')
    instance_name = module_instance.get('name', '')
    logging_module.info(
        f'Running "test-module" for instance "{instance_name}" of integration "{integration_of_instance}".'
    )
    for i in range(connection_retries):
        try:
            response_data, response_code, _ = demisto_client.generic_request_func(
                self=client,
                method='POST',
                path='/settings/integration/test',
                body=module_instance,
                _request_timeout=120)
            break
        except ApiException:
            logging_module.exception(
                'Failed to test integration instance, error trying to communicate with demisto server'
            )
            return False, None
        except urllib3.exceptions.ReadTimeoutError:
            logging_module.warning(
                f"Could not connect. Trying to connect for the {i + 1} time")

    if int(response_code) != 200:
        logging_module.error(
            f'Integration-instance test ("Test" button) failed. Bad status code: {response_code}'
        )
        return False, None

    result_object = ast.literal_eval(response_data)
    success, failure_message = bool(
        result_object.get('success')), result_object.get('message')
    if not success:
        server_url = client.api_client.configuration.host
        test_failed_msg = f'Test integration failed - server: {server_url}.'
        test_failed_msg += f'\nFailure message: {failure_message}' if failure_message else ' No failure message.'
        logging_module.error(test_failed_msg)
    return success, failure_message
Example #27
0
def disable_all_integrations(demisto_api_key, server):
    """
    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:
        print_error(
            'Failed to disable all integrations, error trying to communicate with demisto server: '
            '{} '.format(conn_err))
        return
    if int(int_resp[1]) != 200:
        print_error(
            'Get all integration instances failed with status code: {}'.format(
                int_resp[1]))
        return
    if 'instances' not in int_instances:
        print("No integrations instances found to disable all")
        return
    to_disable = []
    for instance in int_instances['instances']:
        if instance.get('enabled') == 'true' and instance.get(
                "isIntegrationScript"):
            print("Adding to disable list. Name: {}. Brand: {}".format(
                instance.get("name"), instance.get("brand")))
            to_disable.append(instance)
    if len(to_disable) > 0:
        __disable_integrations_instances(client, to_disable)
Example #28
0
def __disable_integrations_instances(client,
                                     module_instances,
                                     prints_manager,
                                     thread_index=0):
    for configured_instance in module_instances:
        # tested with POSTMAN, this is the minimum required fields for the request.
        module_instance = {
            key: configured_instance[key]
            for key in [
                'id',
                'brand',
                'name',
                'data',
                'isIntegrationScript',
            ]
        }
        module_instance['enable'] = "false"
        module_instance['version'] = -1

        try:
            res = demisto_client.generic_request_func(
                self=client,
                method='PUT',
                path='/settings/integration',
                body=module_instance)
        except ApiException as conn_err:
            error_message = 'Failed to disable integration instance, error trying to communicate with demisto ' \
                            'server: {} '.format(conn_err)
            prints_manager.add_print_job(error_message, print_error,
                                         thread_index)
            return

        if res[1] != 200:
            error_message = 'disable instance failed with status code ' + str(
                res[1])
            prints_manager.add_print_job(error_message, print_error,
                                         thread_index)
            prints_manager.add_print_job(pformat(res), print_error,
                                         thread_index)
Example #29
0
def get_all_installed_packs(client: demisto_client):
    """

    Args:
        client (demisto_client): The client to connect to.

    Returns:
        list of installed python
    """
    try:
        logging.info("Attempting to fetch all installed packs.")
        response_data, status_code, _ = demisto_client.generic_request_func(
            client,
            path='/contentpacks/metadata/installed',
            method='GET',
            accept='application/json',
            _request_timeout=None)
        if 200 <= status_code < 300:
            installed_packs = ast.literal_eval(response_data)
            installed_packs_ids = [pack.get('id') for pack in installed_packs]
            logging.success('Successfully fetched all installed packs.')
            installed_packs_ids_str = ', '.join(installed_packs_ids)
            logging.debug(
                f'The following packs are currently installed from a previous build run:\n{installed_packs_ids_str}'
            )
            if 'Base' in installed_packs_ids:
                installed_packs_ids.remove('Base')
            return installed_packs_ids
        else:
            result_object = ast.literal_eval(response_data)
            message = result_object.get('message', '')
            raise Exception(
                f'Failed to fetch installed packs - with status code {status_code}\n{message}'
            )
    except Exception as e:
        logging.exception(
            f'The request to fetch installed packs has failed. Additional info: {str(e)}'
        )
        return None
def get_content_version_details(client):
    '''Make request for details about the content installed on the demisto instance.

    Args:
        client (demisto_client): The configured client to use.

    Returns:
        (tuple): The release version and asset ID of the content installed on the demisto instance.
    '''
    host = client.api_client.configuration.host
    print('\nMaking "POST" request to server - "{}" to check installed content.'.format(host))

    # make request to installed content details
    response_data, status_code, _ = demisto_client.generic_request_func(self=client, path='/content/installed',
                                                                        method='POST')

    result_object = ast.literal_eval(response_data)
    if status_code >= 300 or status_code < 200:
        message = result_object.get('message', '')
        msg = "Failed to check if installed content details - with status code " + str(status_code) + '\n' + message
        print_error(msg)
    return result_object.get('release', ''), result_object.get('assetId', 0)