SearchIncidentsSummary

Searches Cortex XSOAR Incidents and returnrs the most relevant fields. Default search range is the last 30 days, if you want to change this, use the fromDate argument. Returns the id, name, type, severity, status, owner, and created/closed times to context. You can add additional fields using the add_field_to_context argument. This automation runs using the default Limited User role, unless you explicitly change the permissions. Based on the SearchIncidentsV2 from the Common Scripts pack, but more efficient.

python · Common Scripts

Source

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

special = ["n", "t", "\\", '"', "'", "7", "r"]


def check_if_found_incident(res: list):
    if res and isinstance(res, list) and isinstance(res[0].get("Contents"), dict):
        if "data" not in res[0]["Contents"]:
            raise DemistoException(res[0].get("Contents"))
        elif res[0]["Contents"]["data"] is None:
            return False
        return True
    else:
        raise DemistoException(f"failed to get incidents from xsoar.\nGot: {res}")


def is_valid_args(args: dict):
    array_args: list[str] = ["id", "name", "status", "notstatus", "reason", "level", "owner", "type", "query"]
    error_msg: list[str] = []
    for _key, value in args.items():
        if _key in array_args:
            try:
                if _key == "id":
                    if not isinstance(value, int | str | list):
                        error_msg.append(
                            f"Error while parsing the incident id with the value: {value}. The given type: "
                            f"{type(value)} is not a valid type for an ID. The supported id types are: int, list and str"
                        )
                    elif isinstance(value, str):
                        _ = bytes(value, "utf-8").decode("unicode_escape")
                else:
                    _ = bytes(value, "utf-8").decode("unicode_escape")
            except UnicodeDecodeError as ex:
                error_msg.append(f'Error while parsing the argument: "{_key}" \nError:\n- "{ex!s}"')

    if len(error_msg) != 0:
        raise DemistoException("\n".join(error_msg))

    return True


def apply_filters(incidents: list, args: dict):
    names_to_filter = set(argToList(args.get("name")))
    types_to_filter = set(argToList(args.get("type")))
    filtered_incidents = []
    fields = ["id", "name", "type", "severity", "status", "owner", "created", "closed"]
    if args.get("add_fields_to_context"):
        fields = fields + args.get("add_fields_to_context", "").split(",")
        fields = [x.strip() for x in fields]  # clear out whitespace
    for incident in incidents:
        if names_to_filter and incident["name"] not in names_to_filter:
            continue
        if types_to_filter and incident["type"] not in types_to_filter:
            continue

        style_incident = {}
        for field in fields:
            style_incident[field] = incident.get(field, incident["CustomFields"].get(field, "n/a"))
        filtered_incidents.append(style_incident)

    return filtered_incidents


def add_incidents_link(data: list):
    server_url = demisto.demistoUrls().get("server")
    for incident in data:
        incident_link = urljoin(server_url, f'#/Details/{incident.get("id")}')
        incident["incidentLink"] = incident_link
    return data


def search_incidents(args: dict):  # pragma: no cover
    if not is_valid_args(args):
        return None

    if fromdate := arg_to_datetime(args.get("fromdate")):
        from_date = fromdate.isoformat()
        args["fromdate"] = from_date
    if todate := arg_to_datetime(args.get("todate")):
        to_date = todate.isoformat()
        args["todate"] = to_date

    if args.get("trimevents") == "0":
        args.pop("trimevents")

    # handle list of ids
    if args.get("id"):
        args["id"] = ",".join(argToList(args.get("id"), transform=str))

    res: list = execute_command("getIncidents", args, extract_contents=False)
    incident_found: bool = check_if_found_incident(res)
    if incident_found is False:
        return "Incidents not found.", {}, {}

    data = apply_filters(res[0]["Contents"]["data"], args)
    data = add_incidents_link(data)
    headers: list[str] = ["id", "name", "severity", "status", "owner", "created", "closed", "incidentLink"]
    if args.get("add_fields_to_context"):
        add_headers: list[str] = args.get("add_fields_to_context", "").split(",")
        headers = headers + add_headers
    md: str = tableToMarkdown(name="Incidents found", t=data, headers=headers)
    return md, data, res


def main():  # pragma: no cover
    args: dict = demisto.args()
    try:
        readable_output, outputs, raw_response = search_incidents(args)
        if search_results_label := args.get("searchresultslabel"):
            for output in outputs:
                output["searchResultsLabel"] = search_results_label
        results = CommandResults(
            outputs_prefix="foundIncidents",
            outputs_key_field="id",
            readable_output=readable_output,
            outputs=outputs,
            raw_response=raw_response,
            ignore_auto_extract=True,
        )
        return_results(results)
    except DemistoException as error:
        return_error(str(error), error)


if __name__ in ("__main__", "__builtin__", "builtins"):  # pragma: no cover
    main()

README

Searches Cortex XSOAR Incidents. Default search range is the last 30 days, if you want to change this, use the fromDate argument.

Returns the id, name, type, severity, status, owner, and created/closed times to context. You can add additional fields using the add_field_to_context argument.

This automation runs using the default Limited User role, unless you explicitly change the permissions. Based on the SearchIncidentsV2 from the Common Scripts pack, but more efficient.

Script Data


Name Description
Script Type python3
Tags Utility

Inputs


Argument Name Description
id A comma-separated list of incident IDs by which to filter the results.
name A comma-separated list of incident names by which to filter the results.
status A comma-separated list of incident statuses by which to filter the results. For example: assigned.
notstatus A comma-separated list of incident statuses to exclude from the results. For example: assigned.
reason A comma-separated list of incident close reasons by which to filter the results.
fromdate Filter by from date (e.g. “3 days ago” or 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z), default is “30 days ago”
todate Filter by to date (e.g. “3 days ago” or 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z)
fromclosedate Filter by from close date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z)
toclosedate Filter by to close date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z)
fromduedate Filter by from due date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z)
toduedate Filter by to due date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z)
level Filter by Severity
owner Filter by incident owners
details Filter by incident details
type Filter by incident type
query Use free form query (use Lucene syntax) as filter. All other filters will be ignored when this filter is used.
page Filter by the page number
trimevents The number of events to return from the alert JSON. The default is 0, which returns all events.
Note that the count is from the head of the list, regardless of event time or other properties.
size Number of incidents per page (per fetch)
sort Sort in format of field.asc,field.desc,…
searchresultslabel If provided, the value of this argument will be set under the searchResultsLabel context key for each incident found.
add_fields_to_context A comma seperated list of fields to return to the context, (default: id,name,type,severity,status,owner,created,closed)

Outputs


Path Description Type
foundIncidents.id A list of incident IDs returned from the query. Unknown
foundIncidents.name A list of incident names returned from the query. Unknown
foundIncidents.severity A list of incident severities returned from the query. Unknown
foundIncidents.status A list of incident statuses returned from the query. Unknown
foundIncidents.owner A list of incident owners returned from the query. Unknown
foundIncidents.created A list of the incident create date returned from the query. Unknown
foundIncidents.closed A list of incident close dates returned from the query. Unknown
foundIncidents.incidentLink A list with links to the incidents returned from the query. Unknown
foundIncidents.searchResultsLabel The value provided in the searchresultslabel argument. String