QRadar v3

IBM QRadar SIEM helps security teams accurately detect and prioritize threats across the enterprise, supports API versions 10.1 and above. Provides intelligent insights that enable teams to respond quickly to reduce the impact of incidents.

Analytics & SIEM · IBM QRadar

Details

IDQRadar v3
ProviderPalo Alto Networks
CategoryAnalytics & SIEM
From Version5.5.0
Docker Imagedemisto/python3:3.12.13.10399583
Supported ModulesAgentix Cloud Runtime Security Cloud Posture Security XSIAM EDR Cortex Cloud

README

IBM QRadar SIEM helps security teams accurately detect and prioritize threats across the enterprise, supports API versions 10.1 and above. Provides intelligent insights that enable teams to respond quickly to reduce the impact of incidents.
This integration was integrated and tested with version 14-20 of QRadar v3

This is the default integration for this content pack when configured by the Data Onboarder in Cortex XSIAM.

Configure IBM QRadar v3 in Cortex

Parameter Description Required
Server URL (e.g., https://1.1.1.1) True
Username   True
Password   True
QRadar API Version API version of QRadar (e.g., ‘12.0’). Minimum API version is 10.1. True
Incident Type   False
First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days) if no offenses are found within the range of first fetch, will be set to fetch the earliest offense. False
Fetch mode   True
Retry events fetch Whenever enabled, the integration retries to fetch all events if the number of events fetched is less than `event_count`. Default number of tries is 3, but can be configured via the Advanced Parameter: EVENTS_SEARCH_TRIES. e.g EVENTS_SEARCH_TRIES=5 False
Maximum number of events per incident. The maximal amount of events to pull per incident. False
Number of offenses to pull per API call (max 50) In case of mirroring with events, this value will be used for mirroring API calls as well, and it is advised to have a small value. False
Query to fetch offenses. Define a query to determine which offenses to fetch. E.g., “severity >= 4 AND id > 5”. False
Incidents Enrichment IPs enrichment transforms IDs of the IPs of the offense to IP values. Asset enrichment adds correlated assets to the fetched offenses. True
Event fields to return from the events query (WARNING: This parameter is correlated to the incoming mapper and changing the values may adversely affect mapping). The parameter uses the AQL SELECT syntax. For more information, see: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.4/com.ibm.qradar.doc/c_aql_intro.html. Selecting over 100 fields can result in long waiting times for queries. False
Mirroring Options How mirroring from QRadar to Cortex XSOAR should be done, available from QRadar 7.3.3 Fix Pack 3. For further explanation on how to check your QRadar version, see the integration documentation at https://xsoar.pan.dev. False
Close Mirrored XSOAR Incident When selected, closing the QRadar offense is mirrored in Cortex XSOAR. False
The number of incoming incidents to mirror each time Maximum number of incoming incidents to mirror each time. False
Advanced Parameters Comma-separated configuration for advanced parameter values. E.g., EVENTS_INTERVAL_SECS=20,FETCH_SLEEP=5 False
Trust any certificate (not secure)   False
Use system proxy settings   False
Timeout for http-requests The timeout of the HTTP requests sent to the Qradar API (in seconds). If no value is provided, the timeout will be set to 60 seconds. False
Fetch Incidents Interval The fetch interval between before each fetch-incidents execution. (seconds) False

Required Permissions

Component Permission
Assets Vulnerability Management or Assets
Domains Admin
Offenses (Manage Closing Reason) Manage Offense Closing Reasons
Offenses (Assign Offenses to Users) Assign Offenses to Users
Offenses (Read) Offenses
References (Create/Update) Admin
References (Read) View Reference Data

Mapping Limitation for Cortex XSOAR Versions below 6.0.0

The Pull from instance option to create a new mapper is not supported in Cortex XSOAR versions below 6.0.0.

Creating a Classifier Using the Pull from instance Parameter

QRadar fetches incidents using a long-running execution, not in real time. Therefore, Pull from instance pulls incidents from the QRadar service to create a classifier using samples, not real time data. This results in seeing the latest sample stored, and not the latest offense that was fetched.

Important Note Regarding the Query to fetch offenses Parameter

The Query to fetch offenses feature enables defining a specific query for offenses to be retrieved, e.g., ‘status = OPEN and id = 5’. The QRadar integration keeps track of IDs that have already been fetched in order to avoid duplicate fetching.
If you change the Query to fetch offenses value, it will not re-fetch offenses that have already been fetched. To re-fetch those offenses, run the qradar-reset-last-run command.
Note:
The list of QRadar IDs that were already fetched will be reset and duplicate offenses could be re-fetched, depending on the user query.

In case of setting a query with the intent to fetch specific offenses or older offenses, make sure that the First fetch timestamp parameter is set to a value that covers the desired time range for the offenses to be fetched. If using an already existing instance that has performed fetch, run the qradar-reset-last-run command before starting the fetch with the new query.

Migration from QRadar v2 to QRadar v3

Every command and playbook that runs in QRadar v2 also runs in QRadar v3. No adjustments are required.

Additions and Changes from QRadar v2 to QRadar v3

New Commands

  • qradar-rule-groups-list
  • qradar-searches-list
  • qradar-geolocations-for-ip
  • qradar-log-sources-list
  • qradar-upload-indicators
  • get-modified-remote-data

Command Name Changes

QRadar v2 command QRadar V3 command Notes  
qradar-offenses qradar-offenses-list    
qradar-offense-by-id qradar-offenses-list Specify the offense_id argument in the command.  
qradar-update-offense qradar-offense-update    
qradar-get-closing-reasons qradar-closing-reasons    
qradar-get-note qradar-offense-notes-list    
qradar-create-note qradar-offense-note-create    
qradar-get-assets qradar-assets-list    
qradar-get-asset-by-id qradar-assets-list Specify the asset_id argument in the command.  
qradar-searches qradar-search-create    
qradar-get-search qradar-search-status-get    
qradar-get-search-results qradar-search-results-get    
qradar-get-reference-by-name qradar-reference-sets-list Specify the ref_name argument in the command.  
qradar-create-reference-set qradar-reference-set-create    
qradar-delete-reference-set qradar-reference-set-delete    
qradar-create-reference-set-value qradar-reference-set-value-upsert    
qradar-update-reference-set-value qradar-reference-set-value-upsert    
qradar-delete-reference-set-value qradar-reference-set-value-delete    
qradar-get-domains qradar-domains-list    
qradar-get-domain-by-id qradar-domains-list Specify the domain_id argument in the command.  

Mirroring

This integration supports in mirroring from QRadar offenses to Cortex XSOAR.
When a field of an offense is updated in QRadar services, the update is mirrored in Cortex XSOAR.

Mirroring Events

  • Mirroring events from QRadar to Cortex XSOAR is supported via the Mirror Offense and Events option.
  • Events will only be mirrored in the incoming direction.
  • Mirroring events will only work when the Long running instance parameter is enabled.
  • Filtering events using the events_limit and events_columns options for mirrored incidents will be the same as in the fetched incidents.
  • The integration will always mirror the events that occurred first in each offense.

For more information about mirroring configurations, see here.

Use the API Token Instead of Username and Password

  • In the Username / API Key field, type _api_token_key.
  • In the Password field, type your API token.

Choose Your API Version

  1. Visit the QRadar API versions page for a full list of available API versions according to the QRadar version.
  2. Choose one of the API versions listed under the Supported REST API versions column in the line corresponding to your QRadar version.

Note:
If you’re uncertain which API version to use, it is recommended to use the latest API version listed in the Supported REST API versions column in the line corresponding to your QRadar version.

View Your QRadar Version

  1. Enter QRadar service.
  2. Click the Menu toolbar. A scrolling toolbar will appear.
  3. Click About. A new window will appear with the details of your QRadar version.

Troubleshooting

Fetch with Events Retries

When “Fetch with events” is configured, the integration will fetch the offense events from IBM QRadar.
Nevertheless, some events may not be available when trying to fetch them during an incident creation. If Retry events fetch is enabled, the integration tries to fetch more events when the number fetched is less than the expected event_count. In the default setting, the integration will try 3 times, with a wait time of 100 seconds between retries.
In order to change the default values, configure the following Advanced Parameters in the instance configuration:

EVENTS_SEARCH_TRIES=<amount of tries for events search> (default 3),EVENTS_SEARCH_RETRY_SECONDS=<amount of seconds to wait between tries> (default 100),EVENTS_POLLING_TRIES=<number of times to poll for one search> (default 10),

It is recommended to enable mirroring, as it should fetch previously missed events when the offense is updated.
Alternatively, the retrieve events command can be used to retrieve the events immediately.
If the command takes too long to finish executing, try setting the interval_in_seconds to a lower value (down to a minimum of 10 seconds).

API Call Metrics

This feature collects metadata on QRadar API calls and their success status.

API Call metrics are not available for long-running commands such as fetch incidents.

API Metrics are shown in the built-in API Execution Metrics dashboard, and are available to use in custom widgets.

Duplicate Incidents

When running on an Engine Load-Balancing Group, concurrent fetches may run on multiple containers, leading to the creation of duplicate Incidents.

Recommended workarounds:

  • Option A - Preserve high availability: Continue running the integration on the Load-Balancing Group for optimal fault tolerance and higher availability. Create an Incident Pre-processing Rule to drop duplicate incidents.
  • Option B - Use a simplified setup: Alternatively, run the integration on a single custom engine or use the default “No engine” option if possible for a more streamlined configuration.

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

qradar-offenses-list


Gets offenses from QRadar.

Base Command

qradar-offenses-list

Input

Argument Name Description Required
offense_id The offense ID to retrieve its details. Specify offense_id to get details about a specific offense. Optional
enrichment IPs enrichment transforms IDs of the IPs of the offense to IP values. Asset enrichment adds correlated assets to the fetched offenses. Possible values are: IPs, IPs And Assets, None. Default is None. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query to filter offenses, e.g., “severity >= 4 AND id > 5 AND status=OPEN”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,severity,status”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–siem-offenses-GET.html. Optional

Context Output

Path Type Description
QRadar.Offense.Description String Description of the offense.
QRadar.Offense.Rules.id Number The ID of the rule.
QRadar.Offense.Rules.type String The type of the rule.
QRadar.Offense.Rules.name String The name of the rule.
QRadar.Offense.EventCount Number Number of events that are associated with the offense.
QRadar.Offense.FlowCount Number Number of flows that are associated with the offense.
QRadar.Offense.AssignedTo String The user to whom the offense is assigned.
QRadar.Offense.Followup Boolean Whether the offense is marked for follow-up.
QRadar.Offense.SourceAddress Number Source addresses (IPs if IPs enrich have been requested, else IDs of the IPs) that are associated with the offense.
QRadar.Offense.Protected Boolean Whether the offense is protected.
QRadar.Offense.ClosingUser String The user who closed the offense.
QRadar.Offense.DestinationHostname String Destination networks that are associated with the offense.
QRadar.Offense.CloseTime Date Time when the offense was closed.
QRadar.Offense.RemoteDestinationCount Number Number of remote destinations that are associated with the offense.
QRadar.Offense.StartTime Date Date of the earliest item that contributed to the offense.
QRadar.Offense.Magnitude Number Magnitude of the offense.
QRadar.Offense.LastUpdatedTime String Date of the most recent item that contributed to the offense.
QRadar.Offense.Credibility Number Credibility of the offense.
QRadar.Offense.ID Number ID of the offense.
QRadar.Offense.Categories String Event categories that are associated with the offense.
QRadar.Offense.Severity Number Severity of the offense.
QRadar.Offense.ClosingReason String Reason the offense was closed.
QRadar.Offense.OffenseType String Type of the offense.
QRadar.Offense.Relevance Number Relevance of the offense.
QRadar.Offense.OffenseSource String Source of the offense.
QRadar.Offense.DestinationAddress Number Destination addresses (IPs if IPs enrichment have been requested, else IDs of the IPs) that are associated with the offense.
QRadar.Offense.Status String Status of the offense. Possible values: “OPEN”, “HIDDEN”, “CLOSED”.
QRadar.Offense.LinkToOffense String Link to the URL containing information about the offense.
QRadar.Offense.Assets String Assets correlated to the offense, if enrichment was requested.

Command example

!qradar-offenses-list enrichment=IPs filter="status=OPEN" range=0-2

Context Example

{
    "QRadar": {
        "Offense": [
            {
                "AssignedTo": "admin",
                "Categories": [
                    "Information",
                    "Suspicious Activity",
                    "Process Creation Success",
                    "Suspicious Windows Events",
                    "User Login Attempt",
                    "Misc Login Succeeded",
                    "Virtual Machine Creation Attempt",
                    "Read Activity Attempted",
                    "Object Download Attempt"
                ],
                "Credibility": 4,
                "Description": "Detected A Successful Login From Different Geographies For the Same Username - AWSCloud (Exp Center)\n preceded by An AWS API Has Been Invoked From Kali - AWSCloud (Exp Center)\n preceded by Microsoft Word Launc\n preceded by Detected a Massive Creation of EC2 Instances - AWSCloud (Exp Center)\n containing Mail Server Info Message\n",
                "DestinationAddress": [
                    "1.1.1.1",
                    "1.1.1.1"
                ],
                "DestinationHostname": [
                    "other",
                    "Net-10-172-192.Net_192_168_0_0"
                ],
                "EventCount": 35651,
                "FlowCount": 0,
                "Followup": true,
                "ID": 14,
                "LastUpdatedTime": "2023-07-26T15:31:11.839000+00:00",
                "LinkToOffense": "https://ec2.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=14",
                "Magnitude": 4,
                "OffenseSource": "userD",
                "OffenseType": "Username",
                "Protected": false,
                "Relevance": 0,
                "RemoteDestinationCount": 1,
                "Rules": [
                    {
                        "id": 102539,
                        "name": "EC: AWS Cloud - Detected An Email with An Attachment From a Spam Sender",
                        "type": "CRE_RULE"
                    },
                    {
                        "id": 102589,
                        "name": "EC: AWS Cloud - Microsoft Word Launched a Command Shell",
                        "type": "CRE_RULE"
                    },
                    {
                        "id": 102639,
                        "name": "EC: AWS Cloud - Detected A Successful Login From Different Geographies For the Same Username",
                        "type": "CRE_RULE"
                    },
                    {
                        "id": 102389,
                        "name": "EC: AWS Cloud - An AWS API Has Been Invoked From Kali",
                        "type": "CRE_RULE"
                    },
                    {
                        "id": 102439,
                        "name": "EC: AWS Cloud - A Database backup Has Been Downloaded From S3 Bucket",
                        "type": "CRE_RULE"
                    },
                    {
                        "id": 102489,
                        "name": "EC: AWS Cloud - Detected a Massive Creation of EC2 Instances",
                        "type": "CRE_RULE"
                    }
                ],
                "Severity": 10,
                "SourceAddress": [
                    "1.1.1.1",
                    "1.1.1.1",
                    "1.1.1.1",
                    "1.1.1.1"
                ],
                "StartTime": "2023-07-26T14:31:13.387000+00:00",
                "Status": "OPEN"
            },
            {
                "Categories": [
                    "Mail",
                    "System Failure"
                ],
                "Credibility": 2,
                "Description": "Flow Source/Interface Stopped Sending Flows\n",
                "DestinationAddress": [
                    "1.1.1.1"
                ],
                "DestinationHostname": [
                    "Net-10-172-192.Net_10_0_0_0"
                ],
                "EventCount": 2,
                "FlowCount": 6026,
                "Followup": true,
                "ID": 13,
                "LastUpdatedTime": "2023-06-12T08:49:50.145000+00:00",
                "LinkToOffense": "https://ec2.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=13",
                "Magnitude": 1,
                "OffenseSource": "Flow Source Stopped Sending Flows",
                "OffenseType": "Rule",
                "Protected": true,
                "Relevance": 0,
                "RemoteDestinationCount": 0,
                "Rules": [
                    {
                        "id": 100270,
                        "name": "Flow Source Stopped Sending Flows",
                        "type": "CRE_RULE"
                    }
                ],
                "Severity": 1,
                "SourceAddress": [
                    "1.1.1.1",
                    "1.1.1.1",
                    "1.1.1.1"
                ],
                "StartTime": "2023-06-12T08:19:02.020000+00:00",
                "Status": "OPEN"
            },
            {
                "Categories": [
                    "User Activity"
                ],
                "Credibility": 3,
                "Description": "User Account Created and Used and Deleted within a short time frame (Exp Center)\n",
                "DestinationAddress": [
                    "1.1.1.1"
                ],
                "DestinationHostname": [
                    "Net-10-172-192.Net_172_16_0_0"
                ],
                "EventCount": 8,
                "FlowCount": 0,
                "Followup": true,
                "ID": 12,
                "LastUpdatedTime": "2023-06-12T08:17:33.008000+00:00",
                "LinkToOffense": "https://ec2.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=12",
                "Magnitude": 2,
                "OffenseSource": "badadmin",
                "OffenseType": "Username",
                "Protected": true,
                "Relevance": 0,
                "RemoteDestinationCount": 0,
                "Rules": [
                    {
                        "id": 102989,
                        "name": "EC: User Account Created and Used and Removed",
                        "type": "CRE_RULE"
                    }
                ],
                "Severity": 5,
                "SourceAddress": [
                    "1.1.1.1"
                ],
                "StartTime": "2023-06-12T08:15:54.740000+00:00",
                "Status": "OPEN"
            }
        ]
    }
}

Human Readable Output

Offenses List

ID Description OffenseType Status Severity DestinationHostname LastUpdatedTime Credibility Rules SourceAddress AssignedTo OffenseSource Followup EventCount StartTime FlowCount DestinationAddress LinkToOffense RemoteDestinationCount Relevance Categories Magnitude Protected
14 Detected A Successful Login From Different Geographies For the Same Username - AWSCloud (Exp Center)
preceded by An AWS API Has Been Invoked From Kali - AWSCloud (Exp Center)
preceded by Microsoft Word Launc
preceded by Detected a Massive Creation of EC2 Instances - AWSCloud (Exp Center)
containing Mail Server Info Message
Username OPEN 10 other,
Net-10-172-192.Net_192_168_0_0
2023-07-26T15:31:11.839000+00:00 4 {‘id’: 102539, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Detected An Email with An Attachment From a Spam Sender’},
{‘id’: 102589, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Microsoft Word Launched a Command Shell’},
{‘id’: 102639, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Detected A Successful Login From Different Geographies For the Same Username’},
{‘id’: 102389, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - An AWS API Has Been Invoked From Kali’},
{‘id’: 102439, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - A Database backup Has Been Downloaded From S3 Bucket’},
{‘id’: 102489, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Detected a Massive Creation of EC2 Instances’}
1.1.1.1,
1.1.1.1,
1.1.1.1,
1.1.1.1
admin userD true 35651 2023-07-26T14:31:13.387000+00:00 0 1.1.1.1,
1.1.1.1
https://ec2.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=14 1 0 Information,
Suspicious Activity,
Process Creation Success,
Suspicious Windows Events,
User Login Attempt,
Misc Login Succeeded,
Virtual Machine Creation Attempt,
Read Activity Attempted,
Object Download Attempt
4 false
13 Flow Source/Interface Stopped Sending Flows
Rule OPEN 1 Net-10-172-192.Net_10_0_0_0 2023-06-12T08:49:50.145000+00:00 2 {‘id’: 100270, ‘type’: ‘CRE_RULE’, ‘name’: ‘Flow Source Stopped Sending Flows’} 1.1.1.1,
1.1.1.1,
1.1.1.1
  Flow Source Stopped Sending Flows true 2 2023-06-12T08:19:02.020000+00:00 6026 1.1.1.1 https://ec2-1.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=13 0 0 Mail,
System Failure
1 true
12 User Account Created and Used and Deleted within a short time frame (Exp Center)
Username OPEN 5 Net-10-172-192.Net_172_16_0_0 2023-06-12T08:17:33.008000+00:00 3 {‘id’: 102989, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: User Account Created and Used and Removed’} 1.1.1.1   badadmin true 8 2023-06-12T08:15:54.740000+00:00 0 1.1.1.1 https://ec2-3.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=12 0 0 User Activity 2 true

qradar-offense-update


Updates an offense.

Base Command

qradar-offense-update

Input

Argument Name Description Required
offense_id The ID of the offense to update. Required
enrichment IPs enrichment transforms IDs of the IPs of the offense to IP values. Asset enrichment adds correlated assets to the fetched offenses. Possible values are: IPs, IPs And Assets, None. Default is None. Optional
protected Whether the offense should be protected. Possible values are: true, false. Optional
follow_up Whether the offense should be marked for follow-up. Possible values are: true, false. Optional
status The new status for the offense. When the status of an offense is set to CLOSED, a valid closing_reason_id must be provided. To hide an offense, use the HIDDEN status. To show a previously hidden offense, use the OPEN status. Possible values are: OPEN, HIDDEN, CLOSED. Optional
closing_reason_id The ID of a closing reason. You must provide a valid closing_reason_id when you close an offense. For a full list of closing reason IDs, use the ‘qradar-closing-reasons’ command. Optional
closing_reason_name The name of a closing reason. You must provide a valid closing_reason_name when you close an offense. The default closing_reasons are: (1) False-Positive, Tuned (2) Non-Issues (3) Policy Violation. Optional
assigned_to User to assign the offense to. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,severity,status”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–siem-offenses-offense_id-POST.html. Optional

Context Output

Path Type Description
QRadar.Offense.Description String Description of the offense.
QRadar.Offense.Rules.id Number The ID of the rule.
QRadar.Offense.Rules.type String The type of the rule.
QRadar.Offense.Rules.name String The name of the rule.
QRadar.Offense.EventCount Number Number of events that are associated with the offense.
QRadar.Offense.FlowCount Number Number of flows that are associated with the offense.
QRadar.Offense.AssignedTo String The user to whom the offense is assigned.
QRadar.Offense.Followup Boolean Whether the offense is marked for follow-up.
QRadar.Offense.SourceAddress Number Source addresses (IPs if IPs enrich have been requested, else IDs of the IPs) that are associated with the offense.
QRadar.Offense.Protected Boolean Whether the offense is protected.
QRadar.Offense.ClosingUser String The user who closed the offense.
QRadar.Offense.DestinationHostname String Destination networks that are associated with the offense.
QRadar.Offense.CloseTime Date Time when the offense was closed.
QRadar.Offense.RemoteDestinationCount Number Number of remote destinations that are associated with the offense.
QRadar.Offense.StartTime Date Date of the earliest item that contributed to the offense.
QRadar.Offense.Magnitude Number Magnitude of the offense.
QRadar.Offense.LastUpdatedTime String Date of the most recent item that contributed to the offense.
QRadar.Offense.Credibility Number Credibility of the offense.
QRadar.Offense.ID Number ID of the offense.
QRadar.Offense.Categories String Event categories that are associated with the offense.
QRadar.Offense.Severity Number Severity of the offense.
QRadar.Offense.ClosingReason String Reason the offense was closed.
QRadar.Offense.OffenseType String Type of the offense.
QRadar.Offense.Relevance Number Relevance of the offense.
QRadar.Offense.OffenseSource String Source of the offense.
QRadar.Offense.DestinationAddress Number Destination addresses (IPs if IPs enrichment have been requested, else IDs of the IPs) that are associated with the offense.
QRadar.Offense.Status String Status of the offense. Possible values: “OPEN”, “HIDDEN”, “CLOSED”.
QRadar.Offense.LinkToOffense String Link to the URL containing information about the offense.
QRadar.Offense.Assets String Assets correlated to the offense, if enrichment was requested.

Command example

!qradar-offense-update offense_id=14 assigned_to=admin enrichment="IPs And Assets" follow_up=true status=OPEN protected=false

Context Example

{
    "QRadar": {
        "Offense": {
            "AssignedTo": "admin",
            "Categories": [
                "Information",
                "Suspicious Activity",
                "Process Creation Success",
                "Suspicious Windows Events",
                "User Login Attempt",
                "Misc Login Succeeded",
                "Virtual Machine Creation Attempt",
                "Read Activity Attempted",
                "Object Download Attempt"
            ],
            "Credibility": 4,
            "Description": "Detected A Successful Login From Different Geographies For the Same Username - AWSCloud (Exp Center)\n preceded by An AWS API Has Been Invoked From Kali - AWSCloud (Exp Center)\n preceded by Microsoft Word Launc\n preceded by Detected a Massive Creation of EC2 Instances - AWSCloud (Exp Center)\n containing Mail Server Info Message\n",
            "DestinationAddress": [
                "1.1.1.1",
                "1.1.1.1"
            ],
            "DestinationHostname": [
                "other",
                "Net-10-172-192.Net_192_168_0_0"
            ],
            "EventCount": 35651,
            "FlowCount": 0,
            "Followup": true,
            "ID": 14,
            "LastUpdatedTime": "2023-07-26T15:31:11.839000+00:00",
            "LinkToOffense": "https://ec2-1.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=14",
            "Magnitude": 4,
            "OffenseSource": "userD",
            "OffenseType": "Username",
            "Protected": false,
            "Relevance": 0,
            "RemoteDestinationCount": 1,
            "Rules": [
                {
                    "id": 102539,
                    "name": "EC: AWS Cloud - Detected An Email with An Attachment From a Spam Sender",
                    "type": "CRE_RULE"
                },
                {
                    "id": 102589,
                    "name": "EC: AWS Cloud - Microsoft Word Launched a Command Shell",
                    "type": "CRE_RULE"
                },
                {
                    "id": 102639,
                    "name": "EC: AWS Cloud - Detected A Successful Login From Different Geographies For the Same Username",
                    "type": "CRE_RULE"
                },
                {
                    "id": 102389,
                    "name": "EC: AWS Cloud - An AWS API Has Been Invoked From Kali",
                    "type": "CRE_RULE"
                },
                {
                    "id": 102439,
                    "name": "EC: AWS Cloud - A Database backup Has Been Downloaded From S3 Bucket",
                    "type": "CRE_RULE"
                },
                {
                    "id": 102489,
                    "name": "EC: AWS Cloud - Detected a Massive Creation of EC2 Instances",
                    "type": "CRE_RULE"
                }
            ],
            "Severity": 10,
            "SourceAddress": [
                "1.1.1.1",
                "1.1.1.1",
                "1.1.1.1",
                "1.1.1.1"
            ],
            "StartTime": "2023-07-26T14:31:13.387000+00:00",
            "Status": "OPEN"
        }
    }
}

Human Readable Output

offense Update

ID Description OffenseType Status Severity DestinationHostname LastUpdatedTime Credibility Rules SourceAddress AssignedTo OffenseSource Followup EventCount StartTime FlowCount DestinationAddress LinkToOffense RemoteDestinationCount Relevance Categories Magnitude Protected
14 Detected A Successful Login From Different Geographies For the Same Username - AWSCloud (Exp Center)
preceded by An AWS API Has Been Invoked From Kali - AWSCloud (Exp Center)
preceded by Microsoft Word Launc
preceded by Detected a Massive Creation of EC2 Instances - AWSCloud (Exp Center)
containing Mail Server Info Message
Username OPEN 10 other,
Net-10-172-192.Net_192_168_0_0
2023-07-26T15:31:11.839000+00:00 4 {‘id’: 102539, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Detected An Email with An Attachment From a Spam Sender’},
{‘id’: 102589, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Microsoft Word Launched a Command Shell’},
{‘id’: 102639, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Detected A Successful Login From Different Geographies For the Same Username’},
{‘id’: 102389, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - An AWS API Has Been Invoked From Kali’},
{‘id’: 102439, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - A Database backup Has Been Downloaded From S3 Bucket’},
{‘id’: 102489, ‘type’: ‘CRE_RULE’, ‘name’: ‘EC: AWS Cloud - Detected a Massive Creation of EC2 Instances’}
1.1.1.1,
1.1.1.1,
1.1.1.1,
1.1.1.1
admin userD true 35651 2023-07-26T14:31:13.387000+00:00 0 1.1.1.1,
1.1.1.1
https://ec2-1.eu.compute-1.amazonaws.com/console/do/sem/offensesummary?appName=Sem&pageId=OffenseSummary&summaryId=14 1 0 Information,
Suspicious Activity,
Process Creation Success,
Suspicious Windows Events,
User Login Attempt,
Misc Login Succeeded,
Virtual Machine Creation Attempt,
Read Activity Attempted,
Object Download Attempt
4 false

qradar-closing-reasons


Retrieves a list of offense closing reasons.

Base Command

qradar-closing-reasons

Input

Argument Name Description Required
closing_reason_id The closing reason ID for which to retrieve its details. Specify closing_reason_id to get details about a specific closing reason. Optional
include_reserved If true, reserved closing reasons are included in the response. Possible values are: true, false. Default is false. Optional
include_deleted If true, deleted closing reasons are included in the response. Possible values are: true, false. Default is false. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query to filter closing reasons, e.g. “id > 5”. For reference see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,text”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–siem-offense_closing_reasons-GET.html. Optional

Context Output

Path Type Description
QRadar.Offense.ClosingReasons.IsDeleted Boolean Whether the closing reason is deleted. Deleted closing reasons cannot be used to close an offense.
QRadar.Offense.ClosingReasons.IsReserved Boolean Whether the closing reason is reserved. Reserved closing reasons cannot be used to close an offense.
QRadar.Offense.ClosingReasons.Name String Name of the closing reason.
QRadar.Offense.ClosingReasons.ID Number ID of the closing reason.

Command example

!qradar-closing-reasons include_deleted=true include_reserved=true

Context Example

{
    "QRadar": {
        "Offense": {
            "ClosingReasons": [
                {
                    "ID": 2,
                    "IsDeleted": false,
                    "IsReserved": false,
                    "Name": "False-Positive, Tuned"
                },
                {
                    "ID": 1,
                    "IsDeleted": false,
                    "IsReserved": false,
                    "Name": "Non-Issue"
                },
                {
                    "ID": 3,
                    "IsDeleted": false,
                    "IsReserved": false,
                    "Name": "Policy Violation"
                },
                {
                    "ID": 4,
                    "IsDeleted": false,
                    "IsReserved": true,
                    "Name": "System Change (Upgrade, Reset, etc.)"
                }
            ]
        }
    }
}

Human Readable Output

Closing Reasons

ID Name IsReserved IsDeleted
2 False-Positive, Tuned false false
1 Non-Issue false false
3 Policy Violation false false
4 System Change (Upgrade, Reset, etc.) true false

qradar-offense-notes-list


Retrieves a list of notes for an offense.

Base Command

qradar-offense-notes-list

Input

Argument Name Description Required
offense_id The offense ID to retrieve the notes for. Required
note_id The note ID for which to retrieve its details. Specify note_id to get details about a specific note. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query to filter offense notes, e.g., “username=admin”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “username,note_text”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–siem-offenses-offense_id-notes-GET.html. Optional

Context Output

Path Type Description
QRadar.Note.Text String The text of the note.
QRadar.Note.CreateTime Date Creation date of the note.
QRadar.Note.ID Number ID of the note.
QRadar.Note.CreatedBy String The user who created the note.

Command example

!qradar-offense-notes-list offense_id=14 filter="username='API_user: admin'" range=0-1

Context Example

{
    "QRadar": {
        "Note": [
            {
                "CreateTime": "2023-07-27T13:58:46.428000+00:00",
                "CreatedBy": "API_user: admin",
                "ID": 53,
                "Text": "Note Regarding The Offense"
            },
            {
                "CreateTime": "2023-08-02T08:23:05.473000+00:00",
                "CreatedBy": "API_user: admin",
                "ID": 60,
                "Text": "Note Regarding The Offense"
            }
        ]
    }
}

Human Readable Output

Offense Notes List For Offense ID 14

ID Text CreatedBy CreateTime
53 Note Regarding The Offense API_user: admin 2023-07-27T13:58:46.428000+00:00
60 Note Regarding The Offense API_user: admin 2023-08-02T08:23:05.473000+00:00

qradar-offense-note-create


Creates a note on an offense.

Base Command

qradar-offense-note-create

Input

Argument Name Description Required
offense_id The offense ID to add the note to. Required
note_text The text of the note. Required
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “username,note_text”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–siem-offenses-offense_id-notes-POST.html. Optional

Context Output

Path Type Description
QRadar.Note.Text String The text of the note.
QRadar.Note.CreateTime Date Creation date of the note.
QRadar.Note.ID Number ID of the note.
QRadar.Note.CreatedBy String The user who created the note.

Command example

!qradar-offense-note-create note_text="Note Regarding The Offense" offense_id=14

Context Example

{
    "QRadar": {
        "Note": {
            "CreateTime": "2023-08-02T08:39:15.813000+00:00",
            "CreatedBy": "API_user: admin",
            "ID": 65,
            "Text": "Note Regarding The Offense"
        }
    }
}

Human Readable Output

Create Note

ID Text CreatedBy CreateTime
65 Note Regarding The Offense API_user: admin 2023-08-02T08:39:15.813000+00:00

qradar-rules-list


Retrieves a list of rules.

Base Command

qradar-rules-list

Input

Argument Name Description Required
rule_id The rule ID for which to retrieve its details. Specify rule_id to get details about a specific rule. Optional
rule_type Retrieves rules corresponding to the specified rule type. Possible values are: EVENT, FLOW, COMMON, USER. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter rules, e.g., “type=EVENT”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “owner,identifier,origin”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–analytics-rules-GET.html. Optional

Context Output

Path Type Description
QRadar.Rule.Owner String Owner of the rule.
QRadar.Rule.BaseHostID Number ID of the host from which the rule’s base capacity was determined.
QRadar.Rule.CapacityTimestamp Number Date when the rule’s capacity values were last updated.
QRadar.Rule.Origin String Origin of the rule. Possible values: “SYSTEM”, “OVERRIDE”, “USER”.
QRadar.Rule.CreationDate Date Date when rule was created.
QRadar.Rule.Type String Type of the rule. Possible values: “EVENT”, “FLOW”, “COMMON”, “USER”.
QRadar.Rule.Enabled Boolean Whether rule is enabled.
QRadar.Rule.ModificationDate Date Date when the rule was last modified.
QRadar.Rule.Name String Name of the rule.
QRadar.Rule.AverageCapacity Number Moving average capacity in EPS of the rule across all hosts.
QRadar.Rule.ID Number ID of the rule.
QRadar.Rule.BaseCapacity Number Base capacity of the rule in events per second.

Command example

!qradar-rules-list rule_type=COMMON range=0-2

Context Example

{
    "QRadar": {
        "Rule": [
            {
                "AverageCapacity": 0,
                "BaseCapacity": 0,
                "BaseHostID": 0,
                "CapacityTimestamp": 0,
                "CreationDate": "2007-10-14T20:12:00.374000+00:00",
                "Enabled": true,
                "ID": 100068,
                "ModificationDate": "2022-11-21T18:44:32.696000+00:00",
                "Name": "Login Successful After Scan Attempt",
                "Origin": "SYSTEM",
                "Owner": "admin",
                "Type": "COMMON"
            },
            {
                "AverageCapacity": 0,
                "BaseCapacity": 0,
                "BaseHostID": 0,
                "CapacityTimestamp": 0,
                "CreationDate": "2006-03-27T10:54:12.077000+00:00",
                "Enabled": false,
                "ID": 100102,
                "ModificationDate": "2023-02-23T14:12:52.067000+00:00",
                "Name": "Potential Botnet Connection (DNS)",
                "Origin": "SYSTEM",
                "Owner": "admin",
                "Type": "COMMON"
            },
            {
                "AverageCapacity": 0,
                "BaseCapacity": 0,
                "BaseHostID": 0,
                "CapacityTimestamp": 0,
                "CreationDate": "2005-12-22T00:54:48.708000+00:00",
                "Enabled": true,
                "ID": 100109,
                "ModificationDate": "2023-02-23T14:12:49.992000+00:00",
                "Name": "Host Port Scan Detected by Remote Host",
                "Origin": "SYSTEM",
                "Owner": "admin",
                "Type": "COMMON"
            }
        ]
    }
}

Human Readable Output

Rules List

ID Name Type Enabled BaseHostID Origin ModificationDate CreationDate BaseCapacity AverageCapacity Owner CapacityTimestamp
100068 Login Successful After Scan Attempt COMMON true 0 SYSTEM 2022-11-21T18:44:32.696000+00:00 2007-10-14T20:12:00.374000+00:00 0 0 admin 0
100102 Potential Botnet Connection (DNS) COMMON false 0 SYSTEM 2023-02-23T14:12:52.067000+00:00 2006-03-27T10:54:12.077000+00:00 0 0 admin 0
100109 Host Port Scan Detected by Remote Host COMMON true 0 SYSTEM 2023-02-23T14:12:49.992000+00:00 2005-12-22T00:54:48.708000+00:00 0 0 admin 0

qradar-rule-groups-list


Retrieves a list of the rule groups.

Base Command

qradar-rule-groups-list

Input

Argument Name Description Required
rule_group_id The rule group ID for which to retrieve its details. Specify rule_group_id to get details about a specific rule group. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter rules, e.g., “id >= 125”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “owner,parent_id”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–analytics-rule_groups-GET.html. Optional

Context Output

Path Type Description
QRadar.RuleGroup.Owner String Owner of the group.
QRadar.RuleGroup.ModifiedTime Date Date since the group was last modified.
QRadar.RuleGroup.Level Number Depth of the group in the group hierarchy.
QRadar.RuleGroup.Name String Name of the group.
QRadar.RuleGroup.Description String Description of the group.
QRadar.RuleGroup.ID Number ID of the group.
QRadar.RuleGroup.ChildItems String Child items of the group.
QRadar.RuleGroup.ChildGroups Number Child group IDs.
QRadar.RuleGroup.Type String The type of the group.
QRadar.RuleGroup.ParentID Number ID of the parent group.

Command example

!qradar-rule-groups-list range=0-2

Context Example

{
    "QRadar": {
        "RuleGroup": [
            {
                "ChildItems": [
                    "100045",
                    "100046",
                    "100047",
                    "100048",
                    "100049",
                    "100050",
                    "100051",
                    "100052",
                    "100053",
                    "100054",
                    "100055",
                    "100056",
                    "1607",
                    "1608",
                    "1609",
                    "1610",
                    "1611",
                    "1612",
                    "1613",
                    "1614",
                    "1615",
                    "1616",
                    "1617",
                    "1618"
                ],
                "Description": "Rules focused on detection of suspicious asset reconciliation behavior.",
                "ID": 125,
                "Level": 2,
                "ModifiedTime": "2014-01-06T15:23:26.060000+00:00",
                "Name": "Asset Reconciliation Exclusion",
                "Owner": "admin",
                "ParentID": 3,
                "Type": "RULE_GROUP"
            },
            {
                "ChildItems": [
                    "100057",
                    "100059"
                ],
                "Description": "Rules that indicate post-intrusion access activity",
                "ID": 100020,
                "Level": 2,
                "ModifiedTime": "2015-07-08T20:14:12.250000+00:00",
                "Name": "Horizontal Movement",
                "Owner": "admin",
                "ParentID": 3,
                "Type": "RULE_GROUP"
            },
            {
                "ChildItems": [
                    "100001",
                    "100003",
                    "100044",
                    "100323",
                    "1219",
                    "1265",
                    "1335",
                    "1410",
                    "1411",
                    "1412",
                    "1431",
                    "1443",
                    "1460",
                    "1461",
                    "1471",
                    "1481",
                    "1509",
                    "1552",
                    "1566"
                ],
                "Description": "Rules based on log source and event anomalies such as high event rates or excessive connections.",
                "ID": 101,
                "Level": 1,
                "ModifiedTime": "2010-08-21T11:48:27.850000+00:00",
                "Name": "Anomaly",
                "Owner": "admin",
                "ParentID": 3,
                "Type": "RULE_GROUP"
            }
        ]
    }
}

Human Readable Output

Rules Group List

ID Name Description Owner ModifiedTime ParentID Type ChildItems Level
125 Asset Reconciliation Exclusion Rules focused on detection of suspicious asset reconciliation behavior. admin 2014-01-06T15:23:26.060000+00:00 3 RULE_GROUP 100045,
100046,
100047,
100048,
100049,
100050,
100051,
100052,
100053,
100054,
100055,
100056,
1607,
1608,
1609,
1610,
1611,
1612,
1613,
1614,
1615,
1616,
1617,
1618
2
100020 Horizontal Movement Rules that indicate post-intrusion access activity admin 2015-07-08T20:14:12.250000+00:00 3 RULE_GROUP 100057,
100059
2
101 Anomaly Rules based on log source and event anomalies such as high event rates or excessive connections. admin 2010-08-21T11:48:27.850000+00:00 3 RULE_GROUP 100001,
100003,
100044,
100323,
1219,
1265,
1335,
1410,
1411,
1412,
1431,
1443,
1460,
1461,
1471,
1481,
1509,
1552,
1566
1

qradar-assets-list


Retrieves assets list.

Base Command

qradar-assets-list

Input

Argument Name Description Required
asset_id The asset ID for which to retrieve its details. Specify asset_id to get details about a specific asset. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter assets, e.g., “domain_id=0”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,interfaces,users,properties”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–asset_model-assets-GET.html. Optional

Context Output

Path Type Description
Endpoint.Domain String DNS name.
Endpoint.OS String Asset operating system.
Endpoint.MACAddress String Asset MAC address.
Endpoint.IPAddress Unknown IP addresses of the endpoint.
QRadar.Asset.Interfaces.id Number ID of the interface.
QRadar.Asset.Interfaces.mac_address String MAC address of the interface. Null if unknown.
QRadar.Asset.Interfaces.ip_addresses.id Number ID of the interface.
QRadar.Asset.Interfaces.ip_addresses.network_id Number Network ID of the network the IP belongs to.
QRadar.Asset.Interfaces.ip_addresses.value String The IP address.
QRadar.Asset.Interfaces.ip_addresses.type String Type of IP address. Possible values: “IPV4”, “IPV6”.
QRadar.Asset.Interfaces.ip_addresses.created Date Date when the IP address was created.
QRadar.Asset.Interfaces.ip_addresses.first_seen_scanner Date Date when the IP address was first seen during a vulnerability scan.
QRadar.Asset.Interfaces.ip_addresses.first_seen_profiler Date Date when the IP address was first seen in event or flow traffic.
QRadar.Asset.Interfaces.ip_addresses.last_seen_scanner Date Date when the IP address was most recently seen during a vulnerability scan.
QRadar.Asset.Interfaces.ip_addresses.last_seen_profiler Date Date when the IP address was most recently seen in event or flow traffic.
QRadar.Asset.Products.id Number The ID of this software product instance in QRadar’s asset model.
QRadar.Asset.Products.product_variant_id Number The ID of this software product variant in QRadar’s catalog of products.
QRadar.Asset.Products.first_seen_scanner Date Date when the product was first seen during a vulnerability scan.
QRadar.Asset.Products.first_seen_profiler Date Date when the product was first seen in event or flow traffic.
QRadar.Asset.Products.last_seen_scanner Date Date when the product was most recently seen seen during a vulnerability scan.
QRadar.Asset.Products.last_seen_profiler Date Date when the product was most recently seen in event or flow traffic.
QRadar.Asset.VulnerabilityCount Number The total number of vulnerabilities associated with this asset.
QRadar.Asset.RiskScoreSum Number The sum of the CVSS scores of the vulnerabilities on this asset.
QRadar.Asset.Hostnames.last_seen_profiler Date Date when the host was most recently seen in event or flow traffic.
QRadar.Asset.Hostnames.created Date Date when the host was created.
QRadar.Asset.Hostnames.last_seen_scanner Date Date when the host was most recently seen during a vulnerability scan.
QRadar.Asset.Hostnames.name String Name of the host.
QRadar.Asset.Hostnames.first_seen_scanner Date Date when the host was first seen during a vulnerability scan.
QRadar.Asset.Hostnames.id Number ID of the host.
QRadar.Asset.Hostnames.type String Type of the host. Possible values: “DNS”, “NETBIOS”, “NETBIOSGROUP”.
QRadar.Asset.Hostnames.first_seen_profiler Date Date when the host was first seen in event or flow traffic.
QRadar.Asset.ID Number ID of the asset.
QRadar.Asset.Users.last_seen_profiler Date Date when the user was most recently seen in event or flow traffic.
QRadar.Asset.Users.last_seen_scanner Date Date when the user was most recently seen during a vulnerability scan.
QRadar.Asset.Users.first_seen_scanner Date Date when the user was first seen during a vulnerability scan.
QRadar.Asset.Users.id Number ID of the user.
QRadar.Asset.Users.first_seen_profiler Date Date when the user was first seen in event or flow traffic.
QRadar.Asset.Users.username String Name of the user.
QRadar.Asset.DomainID Number ID of the domain this asset belongs to.
QRadar.Asset.Properties.last_reported Date Date when the property was last updated.
QRadar.Asset.Properties.name String Name of the property.
QRadar.Asset.Properties.type_id Number Type ID of the property.
QRadar.Asset.Properties.id Number ID of the property.
QRadar.Asset.Properties.last_reported_by String The source of the most recent update to this property.
QRadar.Asset.Properties.value String Property value.

Command example

!qradar-assets-list filter="id<1100" range=0-2

Context Example

{
    "Endpoint": [
        {
            "IPAddress": [
                "1.1.1.1"
            ]
        }
    ],
    "QRadar": {
        "Asset": {
            "DomainID": 0,
            "ID": 1003,
            "Interfaces": [
                {
                    "created": "2023-07-26T14:32:01.789000+00:00",
                    "id": 1003,
                    "ip_addresses": [
                        {
                            "created": "2023-07-26T14:32:01.789000+00:00",
                            "id": 1003,
                            "network_id": 2,
                            "type": "IPV4",
                            "value": "1.1.1.1"
                        }
                    ]
                }
            ],
            "Properties": [
                {
                    "id": 1020,
                    "last_reported": "2023-07-26T14:32:01.802000+00:00",
                    "last_reported_by": "USER:admin",
                    "name": "Unified Name",
                    "type_id": 1002,
                    "value": "1.1.1.1"
                }
            ],
            "RiskScoreSum": 0,
            "VulnerabilityCount": 0
        }
    }
}

Human Readable Output

Assets List

DomainID ID Interfaces Properties RiskScoreSum VulnerabilityCount
0 1003 {‘created’: ‘2023-07-26T14:32:01.789000+00:00’, ‘ip_addresses’: [{‘created’: ‘2023-07-26T14:32:01.789000+00:00’, ‘network_id’: 2, ‘id’: 1003, ‘type’: ‘IPV4’, ‘value’: ‘1.1.1.1’}], ‘id’: 1003} {‘last_reported’: ‘2023-07-26T14:32:01.802000+00:00’, ‘name’: ‘Unified Name’, ‘type_id’: 1002, ‘id’: 1020, ‘last_reported_by’: ‘USER:admin’, ‘value’: ‘1.1.1.1’} 0.0 0

Endpoints

IPAddress
1.1.1.1

qradar-saved-searches-list


Retrieves a list of Ariel saved searches.

Base Command

qradar-saved-searches-list

Input

Argument Name Description Required
saved_search_id The saved search ID for which to retrieve its details. Specify saved_search_id to get details about a specific saved search. Optional
timeout Number of seconds until timeout for the specified command. Default is 35. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter saved searches, e.g., “database=EVENTS and is_dashboard=true”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,owner,description”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–ariel-saved_searches-GET.html. Optional

Context Output

Path Type Description
QRadar.SavedSearch.Owner String Owner of the saved search.
QRadar.SavedSearch.Description String Description of the saved search.
QRadar.SavedSearch.CreationDate Date Date when saved search was created.
QRadar.SavedSearch.UID String UID of the saved search.
QRadar.SavedSearch.Database String The database of the Ariel saved search, events, or flows.
QRadar.SavedSearch.QuickSearch Boolean Whether the saved search is a quick search.
QRadar.SavedSearch.Name String Name of the saved search.
QRadar.SavedSearch.ModifiedDate Date Date when the saved search was most recently modified.
QRadar.SavedSearch.ID Number ID of the saved search.
QRadar.SavedSearch.AQL String The AQL query.
QRadar.SavedSearch.IsShared Boolean Whether the saved search is shared with other users.

Command example

!qradar-saved-searches-list range=0-1

Context Example

{
    "QRadar": {
        "SavedSearch": [
            {
                "AQL": "select QIDNAME(qid) as 'Event Name',logsourcename(logSourceId) as 'Log Source',\"eventCount\" as 'Event Count',\"startTime\" as 'Time',categoryname(category) as 'Low Level Category',\"sourceIP\" as 'Source IP',\"sourcePort\" as 'Source Port',\"destinationIP\" as 'Destination IP',\"destinationPort\" as 'Destination Port',\"userName\" as 'Username',\"magnitude\" as 'Magnitude' from events where \"Experience Center\" ilike '%AWSCloud%' order by \"startTime\" desc LIMIT 1000 start '2023-08-02 08:34' stop '2023-08-02 08:39'",
                "CreationDate": "2019-04-02T17:39:08.493000+00:00",
                "Database": "EVENTS",
                "Description": "",
                "ID": 2817,
                "IsShared": false,
                "ModifiedDate": "2023-02-23T14:12:52.611000+00:00",
                "Name": "EC: AWS Cloud Attack Events",
                "Owner": "admin",
                "QuickSearch": false,
                "UID": "0144c7d8-a3fe-47c1-b16b-12721a34077e"
            },
            {
                "AQL": "select * from flows where destinationport = '445' and (FORMAT::PAYLOAD_TO_HEX(sourcepayload) like '%70 00 73 00 65 00 78 00 65 00 63 00 73 00 76 00 63 00%' OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like '%50 00 53 00 45 00 58 00 45 00 53 00 56 00 43 00 2e 00 45 00 58 00 45%' OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like '%73 00 76 00 63 00 63 00 74 00 6c 00%' OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like '%5c 00 61 00 64 00 6d 00 69 00 6e 00 24 00%' OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like '%ff 53 4d 42 72 00 00 00 00 18 07 c0%') last 24 HOURS",
                "CreationDate": "2017-07-02T18:11:44.984000+00:00",
                "Database": "FLOWS",
                "Description": "",
                "ID": 2835,
                "IsShared": true,
                "ModifiedDate": "2023-03-05T13:34:00.352000+00:00",
                "Name": "Potential Ransomware (Suspicious activity, Possible Petya, NotPetya)",
                "Owner": "admin",
                "QuickSearch": false,
                "UID": "0791701a-80e3-4a1c-b11f-7bc943b96bf6"
            }
        ]
    }
}

Human Readable Output

Saved Searches List

ID Name IsShared AQL UID QuickSearch ModifiedDate CreationDate Database Owner
2817 EC: AWS Cloud Attack Events false select QIDNAME(qid) as ‘Event Name’,logsourcename(logSourceId) as ‘Log Source’,”eventCount” as ‘Event Count’,”startTime” as ‘Time’,categoryname(category) as ‘Low Level Category’,”sourceIP” as ‘Source IP’,”sourcePort” as ‘Source Port’,”destinationIP” as ‘Destination IP’,”destinationPort” as ‘Destination Port’,”userName” as ‘Username’,”magnitude” as ‘Magnitude’ from events where “Experience Center” ilike ‘%AWSCloud%’ order by “startTime” desc LIMIT 1000 start ‘2023-08-02 08:34’ stop ‘2023-08-02 08:39’ 0144c7d8-a3fe-47c1-b16b-12721a34077e false 2023-02-23T14:12:52.611000+00:00 2019-04-02T17:39:08.493000+00:00 EVENTS admin
2835 Potential Ransomware (Suspicious activity, Possible Petya, NotPetya) true select * from flows where destinationport = ‘445’ and (FORMAT::PAYLOAD_TO_HEX(sourcepayload) like ‘%70 00 73 00 65 00 78 00 65 00 63 00 73 00 76 00 63 00%’ OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like ‘%50 00 53 00 45 00 58 00 45 00 53 00 56 00 43 00 2e 00 45 00 58 00 45%’ OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like ‘%73 00 76 00 63 00 63 00 74 00 6c 00%’ OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like ‘%5c 00 61 00 64 00 6d 00 69 00 6e 00 24 00%’ OR FORMAT::PAYLOAD_TO_HEX(sourcepayload) like ‘%ff 53 4d 42 72 00 00 00 00 18 07 c0%’) last 24 HOURS 0791701a-80e3-4a1c-b11f-7bc943b96bf6 false 2023-03-05T13:34:00.352000+00:00 2017-07-02T18:11:44.984000+00:00 FLOWS admin

qradar-searches-list


Retrieves the list of Ariel searches IDs. Search status and results can be polled by sending the search ID to the ‘qradar-search-status-get’ and ‘qradar-search-results-get’ commands.

Base Command

qradar-searches-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional

Context Output

Path Type Description
QRadar.SearchID.SearchID String ID of the search.

Command example


#### Context Example

```json
{
    "QRadar": {
        "SearchID": [
            {
                "SearchID": "111e7107-48da-4645-8c2c-a8285d113eac"
            },
            {
                "SearchID": "4ad8f58f-d63b-4555-9d5e-62529e6ac089"
            },
            {
                "SearchID": "909075e0-b450-400c-b641-dd04e46b65bf"
            },
            {
                "SearchID": "f6387ac3-342a-41e7-bcd4-14fe5525dc5c"
            },
            {
                "SearchID": "e15caa93-a01f-49f4-b6be-5c666b0e08c7"
            },
            {
                "SearchID": "36ad7331-149d-4419-947d-ff0d3dd23cf1"
            },
            {
                "SearchID": "a893fc4f-f405-4cb2-a6c3-698dfad6045d"
            },
            {
                "SearchID": "47f40fcd-b7fd-48d7-abbc-05fb447acee2"
            },
            {
                "SearchID": "8967788b-f746-4e5b-9174-c145196eddb1"
            },
            {
                "SearchID": "1d743e24-a524-417f-9747-c967e0328b48"
            },
            {
                "SearchID": "be14bcb5-363e-4547-9b7f-923578a16ae6"
            },
            {
                "SearchID": "a4f4d846-9057-41ae-b558-0dd47134a72a"
            },
            {
                "SearchID": "2c98e5f6-4988-4fe3-bbac-43acbbfaaea2"
            },
            {
                "SearchID": "7e4bd0cf-b04e-446f-ba94-16e1811740e9"
            },
            {
                "SearchID": "76e9ed8a-4f59-42ad-8135-9b1781568935"
            },
            {
                "SearchID": "04e953e2-153a-488b-9a53-8701d16431c4"
            },
            {
                "SearchID": "cd44255c-0496-4663-a6ac-9662ad4a13ef"
            },
            {
                "SearchID": "92e5d6ec-1c60-4c7b-ad97-7610c1e7ed90"
            },
            {
                "SearchID": "8ded0056-8853-443f-9f99-3fff30c08cd6"
            },
            {
                "SearchID": "5ced0d93-4237-461a-ba12-6513d5674fb0"
            },
            {
                "SearchID": "1de985b2-2d45-4d0e-ac86-d25c5b7d8803"
            },
            {
                "SearchID": "b19000dd-1eda-4b85-a45e-334478f0755f"
            },
            {
                "SearchID": "ae52c4d7-689f-4274-8f74-6de74bd3652c"
            },
            {
                "SearchID": "70fe39d6-4e8e-4c48-8207-12d5930544f4"
            },
            {
                "SearchID": "011e1de5-c985-462a-8252-e291acaed012"
            },
            {
                "SearchID": "174d5a7c-b004-4b9c-96fb-868c043daa3c"
            },
            {
                "SearchID": "12b576a1-410e-4c46-bd95-61b2bebb4ceb"
            },
            {
                "SearchID": "8f1b645a-6f81-43fc-86f3-23c2213359b6"
            },
            {
                "SearchID": "12463d5a-4d2c-4c5b-9640-88e4cdee245c"
            },
            {
                "SearchID": "e1d2697f-4c40-46d0-b8b3-90a51e732814"
            },
            {
                "SearchID": "e9dea979-039c-409a-8a60-fe1fe44fa3c2"
            },
            {
                "SearchID": "66ca4a44-a3ac-482b-9d7a-300d621eb8a9"
            },
            {
                "SearchID": "a42ef950-fd27-42c9-af3d-8d466bf73d5d"
            },
            {
                "SearchID": "73ee61f0-c480-4145-a00b-d8c3a55de791"
            },
            {
                "SearchID": "e73b8002-b47d-4fb3-9dae-34a99dd21943"
            },
            {
                "SearchID": "5b812a3b-624d-4cf7-a2ed-f2d1f469b0a4"
            },
            {
                "SearchID": "4f6e37db-8c4f-4e2f-9b27-b8ae68d0c38b"
            },
            {
                "SearchID": "df9cf783-d706-46ed-8be7-680a0830d3eb"
            },
            {
                "SearchID": "d2aa7f7c-dbf4-405f-9652-b6bb776164f0"
            },
            {
                "SearchID": "de72022b-8070-4151-a826-16eb913db2cd"
            },
            {
                "SearchID": "32501bb7-22b8-4d79-aa7b-0b565c4bd806"
            },
            {
                "SearchID": "f89f3515-6d27-4616-a1bb-7dc008aa1562"
            },
            {
                "SearchID": "1ba37caf-c969-43fa-b037-6c164535b512"
            },
            {
                "SearchID": "78b709c4-8037-43dc-8bf0-dfd94629674f"
            },
            {
                "SearchID": "88096e2b-4feb-4071-807e-96e3dfc080ff"
            },
            {
                "SearchID": "1a7576fc-2cc1-41c6-85b6-3728d4d44f3d"
            },
            {
                "SearchID": "b4414e3b-b5ec-4cc8-9db2-35a7a2057e46"
            },
            {
                "SearchID": "c6a82de6-cfef-444e-9b0f-b124b5599b7b"
            },
            {
                "SearchID": "185971cc-ebbb-453d-b826-bffc59836be1"
            },
            {
                "SearchID": "2a45ec38-d060-4aae-9a9c-730f49966fdc"
            }
        ]
    }
}

Human Readable Output

Search ID List

SearchID
111e7107-48da-4645-8c2c-a8285d113eac
4ad8f58f-d63b-4555-9d5e-62529e6ac089
909075e0-b450-400c-b641-dd04e46b65bf
f6387ac3-342a-41e7-bcd4-14fe5525dc5c
e15caa93-a01f-49f4-b6be-5c666b0e08c7
36ad7331-149d-4419-947d-ff0d3dd23cf1
a893fc4f-f405-4cb2-a6c3-698dfad6045d
47f40fcd-b7fd-48d7-abbc-05fb447acee2
8967788b-f746-4e5b-9174-c145196eddb1
1d743e24-a524-417f-9747-c967e0328b48
be14bcb5-363e-4547-9b7f-923578a16ae6
a4f4d846-9057-41ae-b558-0dd47134a72a
2c98e5f6-4988-4fe3-bbac-43acbbfaaea2
7e4bd0cf-b04e-446f-ba94-16e1811740e9
76e9ed8a-4f59-42ad-8135-9b1781568935
04e953e2-153a-488b-9a53-8701d16431c4
cd44255c-0496-4663-a6ac-9662ad4a13ef
92e5d6ec-1c60-4c7b-ad97-7610c1e7ed90
8ded0056-8853-443f-9f99-3fff30c08cd6
5ced0d93-4237-461a-ba12-6513d5674fb0
1de985b2-2d45-4d0e-ac86-d25c5b7d8803
b19000dd-1eda-4b85-a45e-334478f0755f
ae52c4d7-689f-4274-8f74-6de74bd3652c
70fe39d6-4e8e-4c48-8207-12d5930544f4
011e1de5-c985-462a-8252-e291acaed012
174d5a7c-b004-4b9c-96fb-868c043daa3c
12b576a1-410e-4c46-bd95-61b2bebb4ceb
8f1b645a-6f81-43fc-86f3-23c2213359b6
12463d5a-4d2c-4c5b-9640-88e4cdee245c
e1d2697f-4c40-46d0-b8b3-90a51e732814
e9dea979-039c-409a-8a60-fe1fe44fa3c2
66ca4a44-a3ac-482b-9d7a-300d621eb8a9
a42ef950-fd27-42c9-af3d-8d466bf73d5d
73ee61f0-c480-4145-a00b-d8c3a55de791
e73b8002-b47d-4fb3-9dae-34a99dd21943
5b812a3b-624d-4cf7-a2ed-f2d1f469b0a4
4f6e37db-8c4f-4e2f-9b27-b8ae68d0c38b
df9cf783-d706-46ed-8be7-680a0830d3eb
d2aa7f7c-dbf4-405f-9652-b6bb776164f0
de72022b-8070-4151-a826-16eb913db2cd
32501bb7-22b8-4d79-aa7b-0b565c4bd806
f89f3515-6d27-4616-a1bb-7dc008aa1562
1ba37caf-c969-43fa-b037-6c164535b512
78b709c4-8037-43dc-8bf0-dfd94629674f
88096e2b-4feb-4071-807e-96e3dfc080ff
1a7576fc-2cc1-41c6-85b6-3728d4d44f3d
b4414e3b-b5ec-4cc8-9db2-35a7a2057e46
c6a82de6-cfef-444e-9b0f-b124b5599b7b
185971cc-ebbb-453d-b826-bffc59836be1
2a45ec38-d060-4aae-9a9c-730f49966fdc

qradar-search-create


Creates a new asynchronous Ariel search. Returns the search ID. Search status and results can be polled by sending the search ID to the ‘qradar-search-status-get’ and ‘qradar-search-results-get’ commands. Accepts SELECT query expressions only.

Base Command

qradar-search-create

Input

Argument Name Description Required
offense_id The ID of the offense to retrieve. Mutually exclusive with query_expression and saved_search_id. Optional
events_limit The number of events to return. Mutually exclusive with query_expression and saved_search_id. Optional
events_columns Comma separated list of columns to return. Mutually exclusive with query_expression and saved_search_id. Optional
fetch_mode The mode to use when fetching events. Mutually exclusive with query_expression and saved_search_id. Possible values are: Fetch With All Events, Fetch Correlation Events Only. Optional
start_time The start time of the search. Optional
query_expression The AQL query to execute. Mutually exclusive with all other arguments. Optional
saved_search_id Saved search ID to execute. Mutually exclusive with all other arguments. Saved search ID is the ‘id’ field returned by the ‘qradar-saved-searches-list’ command. Optional

Context Output

Path Type Description
QRadar.Search.Status String Status of the newly created search.
QRadar.Search.ID String ID of the newly created search.

Command example

!qradar-search-create query_expression="""SELECT "destinationPort" AS 'Destination Port', UniqueCount("sourceIP") AS 'Source IP (Unique Count)', UniqueCount("destinationIP") AS 'Destination IP (Unique Count)', UniqueCount(qid) AS 'Event Name (Unique Count)', UniqueCount(logSourceId) AS 'Log Source (Unique Count)', UniqueCount(category) AS 'Low Level Category (Unique Count)', UniqueCount("protocolId") AS 'Protocol (Unique Count)', UniqueCount("userName") AS 'Username (Unique Count)', MAX("magnitude") AS 'Magnitude (Maximum)', SUM("eventCount") AS 'Event Count (Sum)', COUNT(*) AS 'Count' from events where ( ("creEventList"='100120') or ("creEventList"='100122') or ("creEventList"='100135') AND "eventDirection"='R2L' ) GROUP BY "destinationPort" order by "Event Count (Sum)" desc last 6 hours"""

Context Example

{
    "QRadar": {
        "Search": {
            "ID": "68d4e4e6-f512-4171-b130-d671334cb47d",
            "Status": "WAIT"
        }
    }
}

Human Readable Output

Create Search

ID Status
68d4e4e6-f512-4171-b130-d671334cb47d WAIT

qradar-search-status-get


Retrieves status information for a search, based on the search ID.

Base Command

qradar-search-status-get

Input

Argument Name Description Required
search_id The identifier for an Ariel search. Required

Context Output

Path Type Description
QRadar.Search.Status String Status of the search.
QRadar.Search.ID String ID of the search.

qradar-search-results-get


Retrieves search results.

Base Command

qradar-search-results-get

Input

Argument Name Description Required
search_id The identifier for an Ariel search. Required
output_path Replaces the default context output path for the query result (QRadar.Search.Result). E.g., for output_path=QRadar.Correlations, the result will be under the ‘QRadar.Correlations’ key in the context data. Optional
range Range of events to return. (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional

Context Output

Path Type Description
QRadar.Search.Result Unknown The result of the search.

qradar-search-delete


Deleted search from Qradar, based on the search ID.

Base Command

qradar-search-delete

Input

Argument Name Description Required
search_id The identifier for an Ariel search. Required

qradar-reference-sets-list

qradar-search-cancel


Cancelled search in QRadar based on search_id.

Base Command

qradar-search-cancel

Input

Argument Name Description Required
search_id The identifier for an Ariel search. Required

qradar-reference-sets-list


Retrieves a list of reference sets.

Base Command

qradar-reference-sets-list

Input

Argument Name Description Required
ref_name The reference name of the reference set for which to retrieve its details. Specify ref_name to get details about a specific reference set. Optional
date_value If set to true will try to convert the data values to ISO-8601 string. Possible values are: True, False. Default is False. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter reference sets, e.g., “timeout_type=FIRST_SEEN”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “name,timeout_type”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–reference_data-sets-GET.html. Optional

Context Output

Path Type Description
QRadar.Reference.TimeoutType String Timeout type of the reference set. Possible values: “UNKNOWN”, “FIRST_SEEN”, “LAST_SEEN”.
QRadar.Reference.NumberOfElements Number Number of elements in the reference set.
QRadar.Reference.TimeToLive String Time left to live for the reference.
QRadar.Reference.Data.LastSeen Date Date when this data was last seen.
QRadar.Reference.Data.FirstSeen Date Date when this data was first seen.
QRadar.Reference.Data.Source String Source of this data.
QRadar.Reference.Data.Value String Data value.
QRadar.Reference.CreationTime Date Date when the reference set was created.
QRadar.Reference.Name String Name of the reference set.
QRadar.Reference.ElementType String Type of the elements in the reference set.

Command example

!qradar-reference-sets-list filter="timeout_type=FIRST_SEEN" range=0-2

Context Example

{
    "QRadar": {
        "Reference": [
            {
                "CreationTime": "2015-08-27T17:15:40.583000+00:00",
                "ElementType": "IP",
                "Name": "Critical Assets",
                "NumberOfElements": 0,
                "TimeoutType": "FIRST_SEEN"
            },
            {
                "CreationTime": "2017-10-25T16:31:15.992000+00:00",
                "ElementType": "ALNIC",
                "Name": "BadRabbit_FileHash",
                "NumberOfElements": 6,
                "TimeoutType": "FIRST_SEEN"
            },
            {
                "CreationTime": "2022-10-03T10:38:51.140000+00:00",
                "ElementType": "IP",
                "Name": "Windows RCE IPs",
                "NumberOfElements": 19,
                "TimeoutType": "FIRST_SEEN"
            }
        ]
    }
}

Human Readable Output

Reference Sets List

Name ElementType TimeoutType CreationTime NumberOfElements
Critical Assets IP FIRST_SEEN 2015-08-27T17:15:40.583000+00:00 0
BadRabbit_FileHash ALNIC FIRST_SEEN 2017-10-25T16:31:15.992000+00:00 6
Windows RCE IPs IP FIRST_SEEN 2022-10-03T10:38:51.140000+00:00 19

qradar-reference-set-create


Creates a new reference set.

Base Command

qradar-reference-set-create

Input

Argument Name Description Required
ref_name The name of the reference set to be created. Reference names can be found by ‘Name’ field in ‘qradar-reference-sets-list’ command. Required
element_type The element type for the values allowed in the reference set. Possible values are: ALN, ALNIC, NUM, IP, PORT, DATE. Required
timeout_type Indicates if the time_to_live interval is based on when the data was first seen or last seen. Possible values are: FIRST_SEEN, LAST_SEEN, UNKNOWN. Default is UNKNOWN. Optional
time_to_live The time to live interval, time range. for example: ‘1 month’ or ‘5 minutes’. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “name,timeout_type”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–reference_data-sets-POST.html. Optional

Context Output

Path Type Description
QRadar.Reference.TimeoutType String Timeout type of the reference set. Possible values: “UNKNOWN”, “FIRST_SEEN”, “LAST_SEEN”.
QRadar.Reference.NumberOfElements Number Number of elements in the reference set.
QRadar.Reference.TimeToLive String Time left to live for the reference.
QRadar.Reference.Data.LastSeen Date Date when this data was last seen.
QRadar.Reference.Data.FirstSeen Date Date when this data was first seen.
QRadar.Reference.Data.Source String Source of this data.
QRadar.Reference.Data.Value String Data value.
QRadar.Reference.CreationTime Date Date when the reference set was created.
QRadar.Reference.Name String Name of the reference set.
QRadar.Reference.ElementType String Type of the elements in the reference set.

Command example

!qradar-reference-set-create element_type=IP ref_name="Malicious IPs" time_to_live="1 year" timeout_type=FIRST_SEEN

Context Example

{
    "QRadar": {
        "Reference": {
            "CreationTime": "2023-08-02T08:39:30.887000+00:00",
            "ElementType": "IP",
            "Name": "Malicious IPs",
            "NumberOfElements": 0,
            "TimeToLive": "1 years 0 mons 0 days 0 hours 0 mins 0.0 secs",
            "TimeoutType": "FIRST_SEEN"
        }
    }
}

Human Readable Output

Reference Set Create

Name ElementType TimeToLive TimeoutType CreationTime NumberOfElements
Malicious IPs IP 1 years 0 mons 0 days 0 hours 0 mins 0.0 secs FIRST_SEEN 2023-08-02T08:39:30.887000+00:00 0

qradar-reference-set-delete


Removes a reference set or purges its contents.

Base Command

qradar-reference-set-delete

Input

Argument Name Description Required
ref_name The name of the reference set to be deleted. Reference names can be found by ‘Name’ field in ‘qradar-reference-sets-list’ command. Required
purge_only Indicates if the reference set should have its contents purged (true), keeping the reference set structure. If the value is ‘false’, or not specified the reference set is removed completely. Possible values are: true, false. Default is false. Optional

Context Output

There is no context output for this command.

Command example

!qradar-reference-set-delete ref_name="Malicious IPs"

Human Readable Output

Request to delete reference Malicious IPs was submitted. Current deletion status: QUEUED

qradar-reference-set-value-upsert


Adds or updates an element in a reference set.

Base Command

qradar-reference-set-value-upsert

Input

Argument Name Description Required
ref_name The name of the reference set to add or update an element in. Reference names can be found by the ‘Name’ field in the ‘qradar-reference-sets-list’ command. Required
value Comma-separated list of the values to add or update in the reference set. If the values are dates, the supported date formats are: epoch, ISO, and time range (<number> <time unit>’, e.g., 12 hours, 7 days.). Required
source An indication of where the data originated. Default is reference data api. Optional
date_value True if the specified value type was date. Possible values are: true, false. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “name,timeout_type”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–reference_data-sets-name-POST.html. Optional
quiet_mode If true, does not output the updated reference set data. This argument helps avoid large outputs when the reference set is large. Possible values are: true, false. Optional

Context Output

Path Type Description
QRadar.Reference.TimeoutType String Timeout type of the reference set. Possible values: “UNKNOWN”, “FIRST_SEEN”, “LAST_SEEN”.
QRadar.Reference.NumberOfElements Number Number of elements in the reference set.
QRadar.Reference.TimeToLive String Time left to live for the reference.
QRadar.Reference.Data.LastSeen Date Date when this data was last seen.
QRadar.Reference.Data.FirstSeen Date Date when this data was first seen.
QRadar.Reference.Data.Source String Source of this data.
QRadar.Reference.Data.Value String Data value.
QRadar.Reference.CreationTime Date Date when the reference set was created.
QRadar.Reference.Name String Name of the reference set.
QRadar.Reference.ElementType String Type of the elements in the reference set.

Command example

!qradar-reference-set-value-upsert ref_name="Malicious IPs" value="1.1.1.1,1.1.1.1,1.1.1.1"

Context Example

{
    "QRadar": {
        "Reference": {
            "CreationTime": "2023-08-02T08:39:30.887000+00:00",
            "Data": [
                {
                    "first_seen": 1690965572017,
                    "last_seen": 1690965572017,
                    "source": "reference data api",
                    "value": "1.1.1.1"
                },
                {
                    "first_seen": 1690965572017,
                    "last_seen": 1690965572017,
                    "source": "reference data api",
                    "value": "1.1.1.1"
                },
                {
                    "first_seen": 1690965572017,
                    "last_seen": 1690965572017,
                    "source": "reference data api",
                    "value": "1.1.1.1"
                }
            ],
            "ElementType": "IP",
            "Name": "Malicious IPs",
            "NumberOfElements": 3,
            "TimeToLive": "1 years 0 mons 0 days 0 hours 0 mins 0.0 secs",
            "TimeoutType": "FIRST_SEEN"
        }
    }
}

Human Readable Output

Reference Update Create

CreationTime Data ElementType Name NumberOfElements TimeToLive TimeoutType
2023-08-02T08:39:30.887000+00:00 {‘last_seen’: 1690965572017, ‘first_seen’: 1690965572017, ‘source’: ‘reference data api’, ‘value’: ‘1.1.1.1’},
{‘last_seen’: 1690965572017, ‘first_seen’: 1690965572017, ‘source’: ‘reference data api’, ‘value’: ‘1.1.1.1’},
{‘last_seen’: 1690965572017, ‘first_seen’: 1690965572017, ‘source’: ‘reference data api’, ‘value’: ‘1.1.1.1’}
IP Malicious IPs 3 1 years 0 mons 0 days 0 hours 0 mins 0.0 secs FIRST_SEEN

qradar-reference-set-value-delete


Removes a value from a reference set.

Base Command

qradar-reference-set-value-delete

Input

Argument Name Description Required
ref_name The name of the reference set from which to remove a value. Reference names can be found by the ‘Name’ field in the ‘qradar-reference-sets-list’ command. Required
value The value to remove from the reference set. If the specified value is date, the supported date formats are: epoch, ISO, and time range (<number> <time unit>, e.g., 12 hours, 7 days.). Required
date_value True if the specified value type was date. Possible values are: True, False. Optional

Context Output

There is no context output for this command.

Command example

!qradar-reference-set-value-delete ref_name="Malicious IPs" value="1.1.1.1"

Human Readable Output

value: 1.1.1.1 of reference: Malicious IPs was deleted successfully

qradar-domains-list


Gets the list of domains. You must have System Administrator or Security Administrator permissions to call this endpoint if you are trying to retrieve the details of all domains. You can retrieve details of domains that are assigned to your Security Profile without having the System Administrator or Security Administrator permissions. If you do not have the System Administrator or Security Administrator permissions, then for each domain assigned to your security profile you can only view the values for the ID and name fields. All other values return null.

Base Command

qradar-domains-list

Input

Argument Name Description Required
domain_id The domain ID from which to retrieve its details. Specify domain_id to get details about a specific domain. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter domains, e.g., “id > 3”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–config-domain_management-domains-GET.html. Optional

Context Output

Path Type Description
QRadar.Domains.AssetScannerIDs Number Asset scanner IDs that are associated with the domain.
QRadar.Domains.CustomProperties Unknown Custom properties of the domain.
QRadar.Domains.Deleted Boolean Whether the domain has been deleted.
QRadar.Domains.Description String Description of the domain.
QRadar.Domains.EventCollectorIDs Number Event collector IDs that are assigned to this domain.
QRadar.Domains.FlowCollectorIDs Number Flow collector IDs that are assigned to this domain.
QRadar.Domains.FlowSourceIDs Number Flow source IDs that are assigned to this domain.
QRadar.Domains.ID Number ID of the domain.
QRadar.Domains.LogSourceGroupIDs Number Log source group IDs that are assigned to this domain.
QRadar.Domains.LogSourceIDs Number Log source IDs that are assigned to this domain.
QRadar.Domains.Name String Name of the domain.
QRadar.Domains.QVMScannerIDs Number QVM scanner IDs that are assigned to this domain.
QRadar.Domains.TenantID Number ID of the tenant that this domain belongs to.

Command example


#### Context Example

```json
{
    "QRadar": {
        "Domains": {
            "Deleted": false,
            "Description": "",
            "ID": 0,
            "Name": "",
            "TenantID": 0
        }
    }
}

Human Readable Output

Domains List

Deleted ID TenantID
false 0 0

qradar-indicators-upload


Uploads indicators to QRadar.

Base Command

qradar-indicators-upload

Input

Argument Name Description Required
ref_name The name of set to add or update data in. Reference names can be found by the ‘Name’ field in the ‘qradar-reference-sets-list’ command. Required
query The query for getting indicators from Cortex XSOAR. Optional
limit The maximum number of indicators to fetch from Cortex XSOAR. Default is 50. Optional
page The page from which to get the indicators. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “name,timeout_type”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–reference_data-maps-bulk_load-namespace-name-domain_id-POST.html. Optional
quiet_mode If true, does not output the updated reference set data. This argument helps avoid large outputs when the reference set is large. Possible values are: true, false. Optional

Context Output

Path Type Description
QRadar.Reference.TimeoutType String Timeout type of the reference set. Possible values: “UNKNOWN”, “FIRST_SEEN”, “LAST_SEEN”.
QRadar.Reference.NumberOfElements Number Number of elements in the reference set.
QRadar.Reference.TimeToLive String Time left to live for the reference.
QRadar.Reference.Data.LastSeen Date Date when this data was last seen.
QRadar.Reference.Data.FirstSeen Date Date when this data was first seen.
QRadar.Reference.Data.Source String Source of this data.
QRadar.Reference.Data.Value String Data value.
QRadar.Reference.CreationTime Date Date when the reference set was created.
QRadar.Reference.Name String Name of the reference set.
QRadar.Reference.ElementType String Type of the elements in the reference set.

qradar-geolocations-for-ip


Retrieves the MaxMind GeoIP data for the specified IP address.

Base Command

qradar-geolocations-for-ip

Input

Argument Name Description Required
ip Comma-separated list of IPs fro which to retrieve their geolocation. Required
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “continent,ip_address”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–services-geolocations-GET.html. Optional

Context Output

Path Type Description
QRadar.GeoForIP.CityName String Name of the city that is associated with the IP address.
QRadar.GeoForIP.ContinentName String Name of the continent that is associated with the IP address.
QRadar.GeoForIP.LocationAccuracyRadius Number The approximate accuracy radius in kilometers around the latitude and longitude for the IP address.
QRadar.GeoForIP.LocationAverageIncome Number The average income associated with the IP address.
QRadar.GeoForIP.LocationLatitude Number The approximate latitude of the location associated with the IP address.
QRadar.GeoForIP.LocationTimezone String Timezone of the location.
QRadar.GeoForIP.LocationLongitude Number The approximate longitude of the location associated with the IP address.
QRadar.GeoForIP.LocationMetroCode Number The metro code associated with the IP address. These are only available for IP addresses in the US. Returns the same metro codes as the Google AdWords API.
QRadar.GeoForIP.LocationPopulationDensity Number The estimated number of people per square kilometer.
QRadar.GeoForIP.PhysicalCountryIsoCode String ISO code of country where MaxMind believes the end user is located.
QRadar.GeoForIP.PhysicalCountryName String Name of country where MaxMind believes the end user is located.
QRadar.GeoForIP.RegisteredCountryIsoCode String ISO code of the country that the ISP has registered the IP address.
QRadar.GeoForIP.RegisteredCountryName String Name of the country that the ISP has registered the IP address.
QRadar.GeoForIP.RepresentedCountryIsoCode String ISO code of the country that is represented by users of the IP address.
QRadar.GeoForIP.RepresentedCountryName String Name of the country that is represented by users of the IP address.
QRadar.GeoForIP.RepresentedCountryConfidence Number Value between 0-100 that represents MaxMind’s confidence that the represented country is correct.
QRadar.GeoForIP.IPAddress String IP address to look up.
QRadar.GeoForIP.Traits.autonomous_system_number Number The autonomous system number associated with the IP address.
QRadar.GeoForIP.Traits.autonomous_system_organization String The organization associated with the registered autonomous system number for the IP address.
QRadar.GeoForIP.Traits.domain String The second level domain associated with the IP address.
QRadar.GeoForIP.Traits.internet_service_provider String The name of the internet service provider associated with the IP address.
QRadar.GeoForIP.Traits.organization String The name of the organization associated with the IP address.
QRadar.GeoForIP.Traits.user_type String The user type associated with the IP address.
QRadar.GeoForIP.Coordinates Number Latitude and longitude by MaxMind.
QRadar.GeoForIP.PostalCode String The postal code associated with the IP address.
QRadar.GeoForIP.PostalCodeConfidence Number Value between 0-100 that represents MaxMind’s confidence that the postal code is correct.

Command example

!qradar-geolocations-for-ip ip="1.1.1.1,1.1.1.1" range=0-1

Context Example

{
    "QRadar": {
        "GeoForIP": [
            {
                "CityName": "Mukilteo",
                "ContinentName": "NorthAmerica",
                "Coordinates": [
                    47.913,
                    -122.3042
                ],
                "IPAddress": "1.1.1.1",
                "LocationAccuracyRadius": 1000,
                "LocationLatitude": 47.913,
                "LocationLongitude": -122.3042,
                "LocationMetroCode": 819,
                "LocationTimezone": "America/Los_Angeles",
                "PhysicalCountryIsoCode": "US",
                "PhysicalCountryName": "United States",
                "PostalCode": "98275",
                "RegisteredCountryIsoCode": "US",
                "RegisteredCountryName": "United States"
            },
            {
                "CityName": "Mukilteo",
                "ContinentName": "NorthAmerica",
                "Coordinates": [
                    47.913,
                    -122.3042
                ],
                "IPAddress": "1.1.1.1",
                "LocationAccuracyRadius": 1000,
                "LocationLatitude": 47.913,
                "LocationLongitude": -122.3042,
                "LocationMetroCode": 819,
                "LocationTimezone": "America/Los_Angeles",
                "PhysicalCountryIsoCode": "US",
                "PhysicalCountryName": "United States",
                "PostalCode": "98275",
                "RegisteredCountryIsoCode": "US",
                "RegisteredCountryName": "United States"
            }
        ]
    }
}

Human Readable Output

Geolocation For IP

CityName ContinentName Coordinates IPAddress LocationAccuracyRadius LocationLatitude LocationLongitude LocationMetroCode LocationTimezone PhysicalCountryIsoCode PhysicalCountryName PostalCode RegisteredCountryIsoCode RegisteredCountryName
Mukilteo NorthAmerica 47.913,
-122.3042
1.1.1.1 1000 47.913 -122.3042 819 America/Los_Angeles US United States 98275 US United States
Mukilteo NorthAmerica 47.913,
-122.3042
1.1.1.1 1000 47.913 -122.3042 819 America/Los_Angeles US United States 98275 US United States

qradar-log-sources-list


Retrieves a list of log sources.

Base Command

qradar-log-sources-list

Input

Argument Name Description Required
qrd_encryption_algorithm The algorithm to use for encrypting the sensitive data of this endpoint. Possible values are: AES128, AES256. Default is AES128. Required
qrd_encryption_password The password to use for encrypting the sensitive data of this endpoint. If password was not given, random password will be generated. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter log sources, e.g., “auto_discovered=false”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,status”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–config-event_sources-log_source_management-log_sources-GET.html. Optional
id ID of a specific log source. Optional

Context Output

Path Type Description
QRadar.LogSource.SendingIP String IP of the system which the log source is associated with, or fed by.
QRadar.LogSource.Internal Boolean Whether log source is internal.
QRadar.LogSource.ProtocolParameters Unknown Protocol parameters.
QRadar.LogSource.Description String Description of the log source.
QRadar.LogSource.Enabled Boolean Whether log source is enabled.
QRadar.LogSource.GroupIDs Number Log source group IDs.
QRadar.LogSource.Credibility Number Credibility of the log source.
QRadar.LogSource.ID Number ID of the log source.
QRadar.LogSource.ProtocolTypeID Number Protocol type used by log source.
QRadar.LogSource.CreationDate Date Date when log source was created.
QRadar.LogSource.Name String Name of the log source.
QRadar.LogSource.AutoDiscovered Boolean Whether log source was auto discovered.
QRadar.LogSource.ModifiedDate Date Date when log source was last modified.
QRadar.LogSource.TypeID Number The log source type.
QRadar.LogSource.LastEventTime Date Date when the last event was received by the log source.
QRadar.LogSource.Gateway Boolean Whether log source is configured as a gateway.
QRadar.LogSource.Status Unknown Status of the log source.

Command example

!qradar-log-sources-list qrd_encryption_algorithm=AES128 range=0-2

Context Example

{
    "QRadar": {
        "LogSource": [
            {
                "AutoDiscovered": false,
                "CreationDate": "2022-11-21T18:45:24.624000+00:00",
                "Credibility": 10,
                "Description": "Search Results",
                "Enabled": true,
                "Gateway": false,
                "GroupIDs": [
                    0
                ],
                "ID": 68,
                "Internal": true,
                "LastEventTime": "1970-01-01T00:00:00+00:00",
                "ModifiedDate": "2022-11-21T18:45:24.624000+00:00",
                "Name": "Search Results-2 :: ip-172-31-17-10",
                "ProtocolParameters": [
                    {
                        "id": 0,
                        "name": "identifier",
                        "value": "1.1.1.1"
                    },
                    {
                        "id": 1,
                        "name": "incomingPayloadEncoding",
                        "value": "UTF-8"
                    }
                ],
                "ProtocolTypeID": 0,
                "Status": {
                    "last_updated": 0,
                    "status": "NA"
                },
                "TypeID": 355
            },
            {
                "AutoDiscovered": false,
                "CreationDate": "2022-11-21T18:45:24.621000+00:00",
                "Credibility": 10,
                "Description": "System Notification",
                "Enabled": true,
                "Gateway": false,
                "GroupIDs": [
                    0
                ],
                "ID": 65,
                "Internal": true,
                "LastEventTime": "2023-08-02T08:39:00.106000+00:00",
                "ModifiedDate": "2022-11-21T18:45:24.621000+00:00",
                "Name": "System Notification-2 :: ip-172-31-17-10",
                "ProtocolParameters": [
                    {
                        "id": 0,
                        "name": "identifier",
                        "value": "1.1.1.1"
                    },
                    {
                        "id": 1,
                        "name": "incomingPayloadEncoding",
                        "value": "UTF-8"
                    }
                ],
                "ProtocolTypeID": 0,
                "Status": {
                    "last_updated": 0,
                    "status": "SUCCESS"
                },
                "TypeID": 147
            },
            {
                "AutoDiscovered": true,
                "CreationDate": "2018-10-24T15:25:21.928000+00:00",
                "Credibility": 5,
                "Description": "WindowsAuthServer device",
                "Enabled": true,
                "Gateway": false,
                "GroupIDs": [
                    0
                ],
                "ID": 1262,
                "Internal": false,
                "LastEventTime": "2023-06-12T08:17:22.292000+00:00",
                "ModifiedDate": "2023-02-23T14:12:45.774000+00:00",
                "Name": "Experience Center: WindowsAuthServer @ 1.1.1.1",
                "ProtocolParameters": [
                    {
                        "id": 0,
                        "name": "identifier",
                        "value": "1.1.1.1"
                    },
                    {
                        "id": 1,
                        "name": "incomingPayloadEncoding",
                        "value": "UTF-8"
                    }
                ],
                "ProtocolTypeID": 0,
                "Status": {
                    "last_updated": 0,
                    "messages": [
                        {
                            "severity": "ERROR",
                            "text": "Events have not been received from this Log Source in over 720 minutes."
                        }
                    ],
                    "status": "ERROR"
                },
                "TypeID": 12
            }
        ]
    }
}

Human Readable Output

Log Sources List

ID Name Description Internal ProtocolParameters Credibility GroupIDs CreationDate Status Enabled ProtocolTypeID AutoDiscovered Gateway TypeID ModifiedDate LastEventTime
68 Search Results-2 :: ip-172-31-17-10 Search Results true {‘name’: ‘identifier’, ‘id’: 0, ‘value’: ‘1.1.1.1’},
{‘name’: ‘incomingPayloadEncoding’, ‘id’: 1, ‘value’: ‘UTF-8’}
10 0 2022-11-21T18:45:24.624000+00:00 last_updated: 0
status: NA
true 0 false false 355 2022-11-21T18:45:24.624000+00:00 1970-01-01T00:00:00+00:00
65 System Notification-2 :: ip-172-31-17-10 System Notification true {‘name’: ‘identifier’, ‘id’: 0, ‘value’: ‘1.1.1.1’},
{‘name’: ‘incomingPayloadEncoding’, ‘id’: 1, ‘value’: ‘UTF-8’}
10 0 2022-11-21T18:45:24.621000+00:00 last_updated: 0
status: SUCCESS
true 0 false false 147 2022-11-21T18:45:24.621000+00:00 2023-08-02T08:39:00.106000+00:00
1262 Experience Center: WindowsAuthServer @ 1.1.1.1 WindowsAuthServer device false {‘name’: ‘identifier’, ‘id’: 0, ‘value’: ‘1.1.1.1’},
{‘name’: ‘incomingPayloadEncoding’, ‘id’: 1, ‘value’: ‘UTF-8’}
5 0 2018-10-24T15:25:21.928000+00:00 last_updated: 0
messages: {‘severity’: ‘ERROR’, ‘text’: ‘Events have not been received from this Log Source in over 720 minutes.’}
status: ERROR
true 0 true false 12 2023-02-23T14:12:45.774000+00:00 2023-06-12T08:17:22.292000+00:00

qradar-get-custom-properties


Retrieves a list of event regex properties.

Base Command

qradar-get-custom-properties

Input

Argument Name Description Required
field_name A comma-separated list of names of the exact properties to search for. Optional
limit The maximum number of regex event properties to fetch. Default is 25. Optional
like_name A comma-separated list names of a properties to search for. Values are case insensitive. Optional
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter regex properties, e.g., “auto_discovered=false”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,gateway”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–config-event_sources-custom_properties-regex_properties-GET.html. Optional

Context Output

Path Type Description
QRadar.Properties.identifier String ID of the event regex property.
QRadar.Properties.modification_date Date Date when the event regex property was last updated.
QRadar.Properties.datetime_format String Date/time pattern that the event regex property matches.
QRadar.Properties.property_type String Property type. Possible values: “STRING”, “NUMERIC”, “IP”, “PORT”, “TIME”.
QRadar.Properties.name String Name of the event regex property.
QRadar.Properties.auto_discovered Boolean Whether the event regex property was auto discovered.
QRadar.Properties.description String Description of the event regex property.
QRadar.Properties.id Number ID of the event regex property.
QRadar.Properties.use_for_rule_engine Boolean Whether the event regex property is parsed when the event is received.
QRadar.Properties.creation_date Date Date when the event regex property was created.
QRadar.Properties.locale String Language tag of what locale the property matches.
QRadar.Properties.username String The owner of the event regex property.

Command example

!qradar-get-custom-properties filter="id between 90 and 100" range=1-1231

Context Example

{
    "QRadar": {
        "Properties": [
            {
                "auto_discovered": false,
                "creation_date": "2012-07-04T17:05:02+00:00",
                "datetime_format": "",
                "description": "Default custom extraction of Event Summary from DSM payload.",
                "id": 97,
                "identifier": "DEFAULT_EVENT_SUMMARY",
                "locale": "en-US",
                "modification_date": "2022-11-21T18:44:07.572000+00:00",
                "name": "Event Summary",
                "property_type": "string",
                "use_for_rule_engine": true,
                "username": "admin"
            },
            {
                "auto_discovered": false,
                "creation_date": "2009-09-04T16:58:12.961000+00:00",
                "datetime_format": "",
                "description": "Default custom extraction of Avt-App-VolumePackets from DSM payload.",
                "id": 99,
                "identifier": "4d616180-00d0-4ba0-b423-bfb54e1b8677",
                "locale": "en-US",
                "modification_date": "2022-11-21T18:44:08.049000+00:00",
                "name": "Packets",
                "property_type": "numeric",
                "use_for_rule_engine": false,
                "username": "admin"
            },
            {
                "auto_discovered": false,
                "creation_date": "2010-07-27T13:32:44.494000+00:00",
                "datetime_format": "NULL::character varying",
                "description": "",
                "id": 96,
                "identifier": "8eb82a2c-bba7-478f-9248-69fba8baf8c7",
                "locale": "NULL::character varying",
                "modification_date": "2022-11-21T18:59:14.020000+00:00",
                "name": "Parent",
                "property_type": "string",
                "use_for_rule_engine": true,
                "username": "admin"
            }
        ]
    }
}

Human Readable Output

Custom Properties

auto_discovered creation_date datetime_format description id identifier locale modification_date name property_type use_for_rule_engine username
false 2012-07-04T17:05:02+00:00   Default custom extraction of Event Summary from DSM payload. 97 DEFAULT_EVENT_SUMMARY en-US 2022-11-21T18:44:07.572000+00:00 Event Summary string true admin
false 2009-09-04T16:58:12.961000+00:00   Default custom extraction of Avt-App-VolumePackets from DSM payload. 99 4d616180-00d0-4ba0-b423-bfb54e1b8677 en-US 2022-11-21T18:44:08.049000+00:00 Packets numeric false admin
false 2010-07-27T13:32:44.494000+00:00 NULL::character varying   96 8eb82a2c-bba7-478f-9248-69fba8baf8c7 NULL::character varying 2022-11-21T18:59:14.020000+00:00 Parent string true admin

qradar-reset-last-run


Resets the fetch incidents last run value, which resets the fetch to its initial fetch state. (Will try to fetch the first available offense).

Base Command

qradar-reset-last-run

Input

There are no input arguments for this command.

Context Output

There is no context output for this command.

qradar-print-context


Returns a redacted snapshot of integration context metrics (queued, in-progress, finished, meta sizes, concurrent active, samples count). This command is intended for debugging purposes and may return sensitive data.

Base Command

qradar-print-context

Input

There are no input arguments for this command.

Context Output

Path Type Description
QRadar.Debug.snapshot.queried_count number The number of queried mirrored offenses.
QRadar.Debug.snapshot.finished_count number The number of finished mirrored offenses.
QRadar.Debug.snapshot.fetched_count number The number of fetched mirrored offenses.
QRadar.Debug.snapshot.in_progress_count number The number of currently in progress mirrored offenses.
QRadar.Debug.snapshot.waiting_markers_count number The number of currently waiting mirrored offenses.
QRadar.Debug.snapshot.concurrent_active number The number of currently active queries for offenses.
QRadar.Debug.snapshot.samples_count number The number of sample incidents.

get-mapping-fields


Returns the list of fields for an incident type. This command should be used for debugging purposes.

Base Command

get-mapping-fields

Input

There are no input arguments for this command.

Context Output

There is no context output for this command.

get-remote-data


Gets remote data from a remote incident. This method does not update the current incident, and should be used for debugging purposes.

Base Command

get-remote-data

Input

Argument Name Description Required
id The offense ID. Required
lastUpdate Date string in local time representing the last time the incident was updated. The incident is only returned if it was modified after the last update time. Required

Context Output

There is no context output for this command.

get-modified-remote-data


Returns the list of incidents IDs that were modified since the last update time. Note that this method is for debugging purposes. The get-modified-remote-data command is used as part of the mirroring feature, which is available from version 6.1.

Base Command

get-modified-remote-data

Input

Argument Name Description Required
lastUpdate Date string in local time representing the last time the incident was updated. The incident is only returned if it was modified after the last update time. Optional

Context Output

There is no context output for this command.

qradar-offenses


Gets offenses from QRadar.

Base Command

qradar-offenses

Input

Argument Name Description Required
filter Query by which to filter offenses. For reference, consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html. Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not explicitly named, are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names. For reference, consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-GET.html. Optional
range Range of results to return. e.g.: 0-20. Optional
headers Table headers to use the human readable output (if none provided, will show all table headers). Optional

Context Output

Path Type Description
QRadar.Offense.Followup boolean Offense followup.
QRadar.Offense.Credibility number The credibility of the offense.
QRadar.Offense.Relevance number The relevance of the offense.
QRadar.Offense.Severity number The severity of the offense.
QRadar.Offense.SourceAddress Unknown The source addresses that are associated with the offense.
QRadar.Offense.DestinationAddress Unknown The destination addresses that are associated with the offense.
QRadar.Offense.AssignedTo string The user the offense is assigned to.
QRadar.Offense.StartTime date The time (ISO) when the offense was started.
QRadar.Offense.ID int The ID of the offense.
QRadar.Offense.DestinationHostname Unknown Destintion hostname.
QRadar.Offense.Description string The description of the offense.
QRadar.Offense.EventCount number The number of events that are associated with the offense.
QRadar.Offense.OffenseSource string The source of the offense.
QRadar.Offense.Status string The status of the offense. One of “OPEN”, “HIDDEN”, or “CLOSED”.
QRadar.Offense.Magnitude number The magnitude of the offense.
QRadar.Offense.ClosingUser string The user that closed the offense.
QRadar.Offense.ClosingReason string The offense closing reason.
QRadar.Offense.CloseTime date The time when the offense was closed.
QRadar.Offense.LastUpdatedTime date The time (ISO) when the offense was last updated.
QRadar.Offense.Categories Unknown Event categories that are associated with the offense.
QRadar.Offense.FlowCount number The number of flows that are associated with the offense.
QRadar.Offense.FollowUp boolean Offense followup.
QRadar.Offense.OffenseType string A number that represents the offense type.
QRadar.Offense.Protected boolean Is the offense protected.
QRadar.Offense.RemoteDestinationCount Unknown The remote destinations that are associated with the offesne. If this value is greater than 0 that means your offense has a remote destination, you will need to use QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip

qradar-offense-by-id


Gets offense with matching offense ID from qradar.

Base Command

qradar-offense-by-id

Input

Argument Name Description Required
offense_id Offense ID. Required
filter Query to filter offense. For reference please consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html. Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not explicitly named are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names, for reference, consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-GET.html. Optional
headers Table headers to use in the human readable output (if none provided, will show all table headers). Optional

Context Output

Path Type Description
QRadar.Offense.Followup boolean Offense followup.
QRadar.Offense.Credibility number The credibility of the offense.
QRadar.Offense.Relevance number The relevance of the offense.
QRadar.Offense.Severity number The severity of the offense.
QRadar.Offense.SourceAddress Unknown The source addresses that are associated with the offense.
QRadar.Offense.DestinationAddress Unknown The local destination addresses that are associated with the offense. If your offense has a remote destination, you will need to use the QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip.
QRadar.Offense.RemoteDestinationCount Unknown The remote destination that are associated with the offesne. If this value is greater than 0, it means that your offense has a remote destination, you will need to use the QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip.
QRadar.Offense.AssignedTo string The user the offense is assigned to.
QRadar.Offense.StartTime date The time (ISO) when the offense was started.
QRadar.Offense.ID int The ID of the offense.
QRadar.Offense.DestinationHostname Unknown Destintion hostname.
QRadar.Offense.Description string The description of the offense.
QRadar.Offense.EventCount number The number of events that are associated with the offense.
QRadar.Offense.OffenseSource string The source of the offense.
QRadar.Offense.Status string The status of the offense. One of “OPEN”, “HIDDEN”, or “CLOSED”.
QRadar.Offense.Magnitude number The magnitude of the offense.
QRadar.Offense.ClosingUser string The user that closed the offense.
QRadar.Offense.ClosingReason string The offense closing reason.
QRadar.Offense.CloseTime date The time when the offense was closed.
QRadar.Offense.LastUpdatedTime date The time (ISO) when the offense was last updated.
QRadar.Offense.Categories Unknown Event categories that are associated with the offense.
QRadar.Offense.FlowCount number The number of flows that are associated with the offense.
QRadar.Offense.FollowUp boolean Offense followup.
QRadar.Offense.OffenseType string A number that represents the offense type.
QRadar.Offense.Protected boolean Is the offense protected.
QRadar.Offense.RemoteDestinationCount Unknown The remote destinations that are associated with the offesne. If this value is greater than 0 that means your offense has a remote destination, you will need to use QRadarFullSearch playbook with the following query - SELECT destinationip FROM events WHERE inOffense(<offenseID>) GROUP BY destinationip

qradar-searches


Searches in QRadar using AQL. It is highly recommended to use the playbook ‘QRadarFullSearch’ instead of this command - it will execute the search, and will return the result.

Base Command

qradar-searches

Input

Argument Name Description Required
query_expression The query expressions in AQL (for more information about Ariel Query Language, review “https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.0/com.ibm.qradar.doc/c_aql_intro.html”). Required
headers Table headers to use the human readable output (if none provided, will show all table headers). Optional

Context Output

Path Type Description
QRadar.Search.ID number Search ID.
QRadar.Search.Status string The status of the search.

qradar-get-search


Gets a specific search id and status.

Base Command

qradar-get-search

Input

Argument Name Description Required
search_id The search id. Required
headers Table headers to use the human readable output (if none provided, will show all table headers). Optional

Context Output

Path Type Description
QRadar.Search.ID number Search ID.
QRadar.Search.Status string The status of the search.

qradar-get-search-results


Gets search results.

Base Command

qradar-get-search-results

Input

Argument Name Description Required
search_id The search id. Required
range Range of results to return. e.g.: 0-20. Optional
headers Table headers to use the human readable output (if none provided, will show all table headers). Optional
output_path Replaces the default context output path for the query result (QRadar.Search.Result). e.g. for output_path=QRadar.Correlations the result will be under the key “QRadar.Correlations” in the context data. Optional

Context Output

Path Type Description
QRadar.Search.Result Unknown The result of the search.

qradar-get-assets


List all assets found in the model.

Base Command

qradar-get-assets

Input

Argument Name Description Required
filter Query to filter assets. For reference please consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html. Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names, for reference, consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–asset_model-assets-GET.html. Optional
range Range of results to return. e.g.: 0-20. Optional
headers Table headers to use the human readable output (if none provided, will show all table headers). Optional

Context Output

Path Type Description
QRadar.Asset.ID number The ID of the asset.
Endpoint.IPAddress Unknown IP address of the asset.
QRadar.Asset.Name.Value string Name of the asset.
Endpoint.OS number Asset OS.
QRadar.Asset.AggregatedCVSSScore.Value number CVSSScore.
QRadar.Asset.AggregatedCVSSScore.LastUser string Last user who updated the Aggregated CVSS Score.
QRadar.Asset.Weight.Value number Asset weight.
QRadar.Asset.Weight.LastUser string Last user who updated the weight.
QRadar.Asset.Name.LastUser string Last user who updated the name.

qradar-get-asset-by-id


Retrieves the asset by id.

Base Command

qradar-get-asset-by-id

Input

Argument Name Description Required
asset_id The ID of the requested asset. Required

Context Output

Path Type Description
QRadar.Asset.ID number The ID of the asset.
Endpoint.MACAddress Unknown Asset MAC address.
Endpoint.IPAddress Unknown IP address of the endpoint.
QRadar.Asset.ComplianceNotes.Value string Compliance notes.
QRadar.Asset.CompliancePlan.Value string Compliance plan.
QRadar.Asset.CollateralDamagePotential.Value Unknown Collateral damage potential.
QRadar.Asset.AggregatedCVSSScore.Value number CVSSScore.
QRadar.Asset.Name.Value string Name of the asset.
QRadar.Asset.GroupName string Name of the asset’s group.
Endpoint.Domain Unknown DNS name.
Endpoint.OS Unknown Asset OS.
QRadar.Asset.Weight.Value number Asset weight.
QRadar.Asset.Vulnerabilities.Value Unknown Vulnerabilities.
QRadar.Asset.Location string Location.
QRadar.Asset.Description string The asset description.
QRadar.Asset.SwitchID number Switch ID.
QRadar.Asset.SwitchPort number Switch port.
QRadar.Asset.Name.LastUser string Last user who updated the name.
QRadar.Asset.AggregatedCVSSScore.LastUser string Last user who updated the Aggregated CVSS Score.
QRadar.Asset.Weight.LastUser string Last user who updated the weight.
QRadar.Asset.ComplianceNotes.LastUser string Last user who updated the compliance notes.
QRadar.Asset.CompliancePlan.LastUser string Last user who updated the compliance plan.
QRadar.Asset.CollateralDamagePotential.LastUser string Last user who updated the collateral damage potential.
QRadar.Asset.Vulnerabilities.LastUser string Last user who updated the vulnerabilities.

qradar-get-closing-reasons


Get closing reasons.

Base Command

qradar-get-closing-reasons

Input

Argument Name Description Required
include_reserved If true, reserved closing reasons are included in the response. Possible values are: true, false. Default is true. Optional
include_deleted If true, deleted closing reasons are included in the response. Possible values are: true, false. Default is true. Optional
filter Query to filter results. For reference, consult: https://www.ibm.com/support/knowledgecenter/en/SS42VS_7.3.1/com.ibm.qradar.doc/c_rest_api_filtering.html. Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not explicitly named are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names. For reference, consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offense_closing_reasons-GET.html. Optional
range Range of results to return. e.g.: 0-20. Optional

Context Output

Path Type Description
QRadar.Offense.ClosingReasons.ID number Closing reason ID.
QRadar.Offense.ClosingReasons.Name string Closing reason name.

qradar-get-note


Retrieve a note for an offense.

Base Command

qradar-get-note

Input

Argument Name Description Required
offense_id The offense ID to retrieve the note from. Required
note_id The note ID. Optional
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not explicitly named are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names. For reference, consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-notes-note_id-GET.html. Optional
headers Table headers to use the human readable output (if none provided, will show all table headers). Optional

Context Output

Path Type Description
QRadar.Note.ID number Note ID.
QRadar.Note.Text string Note text.
QRadar.Note.CreateTime date The creation time of the note.
QRadar.Note.CreatedBy string The user who created the note.

qradar-create-note


Create a note on an offense.

Base Command

qradar-create-note

Input

Argument Name Description Required
offense_id The offense ID to add the note to. Required
note_text The note text. Required
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not explicitly named are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names. For reference, consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-notes-POST.html. Optional
headers Table headers to use the human readable output (if none provided, will show all table headers). Optional

Context Output

Path Type Description
QRadar.Note.ID number Note ID.
QRadar.Note.Text string Note text.
QRadar.Note.CreateTime date The creation time of the note.
QRadar.Note.CreatedBy string The user who created the note.

qradar-get-reference-by-name


Information about the reference set that had data added or updated. This returns the information set, but not the contained data. This feature is supported from version 8.1 and upward.

Base Command

qradar-get-reference-by-name

Input

Argument Name Description Required
ref_name The name of the requestered reference. Required
headers Table headers to use in the human readable output (if none provided, will show all table headers). Optional
date_value If set to true will try to convert the data values to ISO-8601 string. Possible values are: True, False. Default is False. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeToLive string Reference time to live.
QRadar.Reference.TimeoutType string Reference timeout type. Valid values are: UNKNOWN, FIRST_SEEN, LAST_SEEN.
QRadar.Reference.Data Unknown Reference set items.

qradar-create-reference-set


Creates a new reference set. If the provided name is already in use, this command will fail.

Base Command

qradar-create-reference-set

Input

Argument Name Description Required
ref_name Reference name to be created. Required
element_type The element type for the values allowed in the reference set. The allowed values are: ALN (alphanumeric), ALNIC (alphanumeric ignore case), IP (IP address), NUM (numeric), PORT (port number) or DATE. Note that date values need to be represented in milliseconds since the Unix Epoch January 1st 1970. Possible values are: ALN, ALNIC, IP, NUM, PORT, DATE. Required
timeout_type The allowed values are “FIRST_SEEN”, LAST_SEEN and UNKNOWN. The default value is UNKNOWN. Possible values are: FIRST_SEEN, LAST_SEEN, UNKNOWN. Optional
time_to_live The time to live interval, for example: “1 month” or “5 minutes”. Optional

Context Output

Path Type Description
QRadar.Reference.CreationTime date Creation time of the reference set.
QRadar.Reference.ElementType string The element type for the values allowed in the reference set. The allowed values are: ALN (alphanumeric), ALNIC (alphanumeric ignore case), IP (IP address), NUM (numeric), PORT (port number) or DATE.
QRadar.Reference.Name string Name of the reference set.
QRadar.Reference.NumberOfElements number Number of elements in the created reference set.
QRadar.Reference.TimeoutType string Timeout type of the reference. The allowed values are FIRST_SEEN, LAST_SEEN and UNKNOWN.

qradar-delete-reference-set


Deletes a reference set corresponding to the name provided.

Base Command

qradar-delete-reference-set

Input

Argument Name Description Required
ref_name The name of reference set to delete. Required

Context Output

There is no context output for this command.

qradar-create-reference-set-value


Add or update a value in a reference set.

Base Command

qradar-create-reference-set-value

Input

Argument Name Description Required
ref_name The name of the reference set to add or update a value in. Required
value The value/s to add or update in the reference set. Note: Date values must be represented in epoch in reference sets (milliseconds since the Unix Epoch January 1st 1970). If ‘date_value’ is set to ‘True’, then the argument will be converted from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Required
source An indication of where the data originated. The default value is ‘reference data api’. Optional
date_value If set to True, will convert ‘value’ argument from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Possible values are: True, False. Default is False. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN.

qradar-update-reference-set-value


Adds or updates a value in a reference set.

Base Command

qradar-update-reference-set-value

Input

Argument Name Description Required
ref_name The name of the reference set to add or update a value in. Required
value A comma-separated list of values to add or update in the reference set. Date values must be represented in milliseconds since the Unix Epoch January 1st 1970. Required
source An indication of where the data originated. The default value is ‘reference data api’. Optional
date_value If set to True, will convert ‘value’ argument from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Possible values are: True, False. Default is False. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN

qradar-delete-reference-set-value


Deletes a value in a reference set.

Base Command

qradar-delete-reference-set-value

Input

Argument Name Description Required
ref_name The name of the reference set to remove a value from. Required
value The value to remove from the reference set. Required
date_value If set to True will convert ‘value’ argument from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g., ‘2018-11-06T08:56:41.000000Z’) to epoch. Possible values are: True, False. Default is False. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN.

qradar-delete-reference-set-value


Deletes a value in a reference set.

Base Command

qradar-delete-reference-set-value

Input

Argument Name Description Required
ref_name The name of the reference set to remove a value from. Required
value The value to remove from the reference set. Required
date_value If set to True will convert ‘value’ argument from date in format: ‘%Y-%m-%dT%H:%M:%S.%f000Z’ (e.g. ‘2018-11-06T08:56:41.000000Z’) to epoch. Possible values are: True, False. Default is False. Optional

Context Output

Path Type Description
QRadar.Reference.Name string The name of the reference set.
QRadar.Reference.CreationTime date The creation time (ISO) of the reference.
QRadar.Reference.ElementType string Reference element type.
QRadar.Reference.NumberOfElements number Number of elements.
QRadar.Reference.TimeoutType string Reference timeout type. One of: UNKNOWN, FIRST_SEEN, LAST_SEEN

qradar-get-domains


Retrieve all Domains.

Base Command

qradar-get-domains

Input

Argument Name Description Required
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not explicitly named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-notes-note_id-GET.html. Optional
range Number of results in return. Optional
filter Query to filter offenses. Optional

Context Output

Path Type Description
QRadar.Domains.AssetScannerIDs Number Array of Asset Scanner IDs.
QRadar.Domains.CustomProperties String Custom properties of the domain.
QRadar.Domains.Deleted Boolean Indicates if the domain is deleted.
QRadar.Domains.Description String Description of the domain.
QRadar.Domains.EventCollectorIDs Number Array of Event Collector IDs.
QRadar.Domains.FlowCollectorIDs Number Array of Flow Collector IDs.
QRadar.Domains.FlowSourceIDs Number Array of Flow Source IDs.
QRadar.Domains.ID Number ID of the domain.
QRadar.Domains.LogSourceGroupIDs Number Array of Log Source Group IDs.
QRadar.Domains.LogSourceIDs Number Array of Log Source IDs.
QRadar.Domains.Name String Name of the Domain.
QRadar.Domains.QVMScannerIDs Number Array of QVM Scanner IDs.
QRadar.Domains.TenantID Number ID of the Domain tenant.

qradar-get-domain-by-id


Retrieves Domain information By ID.

Base Command

qradar-get-domain-by-id

Input

Argument Name Description Required
id ID of the domain. Required
fields If used, will filter all fields except for the specified ones. Use this parameter to specify which fields you would like to get back in the response. Fields that are not explicitly named are excluded. Specify subfields in brackets and multiple fields in the same object are separated by commas. The filter uses QRadar’s field names, for reference please consult: https://www.ibm.com/support/knowledgecenter/SSKMKU/com.ibm.qradar.doc_cloud/9.1–siem-offenses-offense_id-notes-note_id-GET.html. Optional

Context Output

Path Type Description
QRadar.Domains.AssetScannerIDs Number Array of Asset Scanner IDs.
QRadar.Domains.CustomProperties String Custom properties of the domain.
QRadar.Domains.Deleted Boolean Indicates if the domain is deleted.
QRadar.Domains.Description String Description of the domain.
QRadar.Domains.EventCollectorIDs Number Array of Event Collector IDs.
QRadar.Domains.FlowCollectorIDs Number Array of Flow Collector IDs.
QRadar.Domains.FlowSourceIDs Number Array of Flow Source IDs.
QRadar.Domains.ID Number ID of the domain.
QRadar.Domains.LogSourceGroupIDs Number Array of Log Source Group IDs.
QRadar.Domains.LogSourceIDs Number Array of Log Source IDs.
QRadar.Domains.Name String Name of the Domain.
QRadar.Domains.QVMScannerIDs Number Array of QVM Scanner IDs.
QRadar.Domains.TenantID Number ID of the Domain tenant.

qradar-upload-indicators


Uploads indicators from Demisto to QRadar.

Base Command

qradar-upload-indicators

Input

Argument Name Description Required
ref_name The name of the reference set to add or update a value in. To create a new reference set, you need to set the element type. Required
element_type The element type for the values permitted in the reference set. Only required when creating a new reference set. The valid values are: ALN (alphanumeric), ALNIC (alphanumeric ignore case), IP (IP address), NUM (numeric), PORT (port number) or DATE. Note that date values need to be represented in milliseconds since the Unix Epoch January 1st 1970. Possible values are: ALN, ALNIC, IP, NUM, PORT, DATE. Optional
timeout_type The timeout_type can be “FIRST_SEEN”, “LAST_SEEN”, or “UNKNOWN”. The default value is UNKNOWN. Only required for creating a new reference set. Possible values are: FIRST_SEEN, LAST_SEEN, UNKNOWN. Optional
time_to_live The time to live interval, for example: “1 month” or “5 minutes”. Only required when creating a new reference set. Optional
query The query for getting indicators. Required
limit The maximum number of indicators to return. The default value is 1000. Default is 1000. Optional
page The page from which to get the indicators. Default is 0. Optional

Context Output

There is no context output for this command.

qradar-ips-source-get


Get Source IPs

Base Command

qradar-ips-source-get

Input

Argument Name Description Required
source_ip Comma separated list. Source IPs to retrieve their data, E.g “1.1.1.1,1.1.1.1”. Optional
filter Query to filter IPs. E.g, filter=source_ip="1.1.1.1". For reference please consult: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields If used, will filter all fields except for the ones specified. Use this argument to specify which fields should be returned in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names, for reference, consult: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–siem-source_addresses-GET.html. Optional
range Range of results to return. e.g.: 0-20. Optional

Context Output

Path Type Description
QRadar.SourceIP.ID Number The ID of the destination address.
QRadar.SourceIP.DomainID String The ID of associated domain.
QRadar.SourceIP.EventFlowCount Number The number of events and flows that are associated with the destination address.
QRadar.SourceIP.FirstEventFlowSeen Date Date when the first event or flow was seen.
QRadar.SourceIP.LastEventFlowSeen Date Date when the last event or flow was seen.
QRadar.SourceIP.SourceIP String The IP address.
QRadar.SourceIP.Magnitude Number The magnitude of the destination address.
QRadar.SourceIP.Network String The network of the destination address.
QRadar.SourceIP.OffenseIDs Unknown List of offense IDs the destination address is part of.
QRadar.SourceIP.LocalDestinationAddressIDs Unknown List of local destination address IDs associated with the source address.

Command example

!qradar-ips-source-get filter=`source_ip="1.1.1.1"` range=0-2

Context Example

{
    "QRadar": {
        "SourceIP": {
            "DomainID": 0,
            "EventFlowCount": 654,
            "FirstEventFlowSeen": "2023-07-26T14:31:44.753000+00:00",
            "ID": 31,
            "LastEventFlowSeen": "2023-07-26T15:31:06.386000+00:00",
            "LocalDestinationAddressIDs": [
                64
            ],
            "Magnitude": 0,
            "Network": "Net-10-172-192.Net_192_168_0_0",
            "OffenseIDs": [
                14
            ],
            "SourceIP": "1.1.1.1"
        }
    }
}

Human Readable Output

Source IPs

DomainID EventFlowCount FirstEventFlowSeen ID LastEventFlowSeen LocalDestinationAddressIDs Magnitude Network OffenseIDs SourceIP
0 654 2023-07-26T14:31:44.753000+00:00 31 2023-07-26T15:31:06.386000+00:00 64 0 Net-10-172-192.Net_192_168_0_0 14 1.1.1.1

qradar-ips-local-destination-get


Get Source IPs

Base Command

qradar-ips-local-destination-get

Input

Argument Name Description Required
local_destination_ip Comma separated list. Local destination IPs to retrieve their data, E.g “1.1.1.1,1.1.1.1”. Optional
filter Query to filter IPs. E.g, filter=local_destination_ip="1.1.1.1" For reference please consult: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields If used, will filter all fields except for the ones specified. Use this argument to specify which fields should be returned in the response. Fields that are not named are excluded. Specify subfields in brackets and multiple fields in the same object separated by commas. The filter uses QRadar’s field names, for reference, consult: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–siem-local_destination_addresses-GET.html. Optional
range Range of results to return. e.g.: 0-20. Optional

Context Output

Path Type Description
QRadar.LocalDestinationIP.ID Number The ID of the destination address.
QRadar.LocalDestinationIP.DomainID String The ID of associated domain.
QRadar.LocalDestinationIP.EventFlowCount Number The number of events and flows that are associated with the destination address.
QRadar.LocalDestinationIP.FirstEventFlowSeen Date Date when the first event or flow was seen.
QRadar.LocalDestinationIP.LastEventFlowSeen Date Date when the last event or flow was seen.
QRadar.LocalDestinationIP.LocalDestinationIP String The IP address.
QRadar.LocalDestinationIP.Magnitude Number The magnitude of the destination address.
QRadar.LocalDestinationIP.Network String The network of the destination address.
QRadar.LocalDestinationIP.OffenseIDs Unknown List of offense IDs the destination address is part of.
QRadar.LocalDestinationIP.SourceAddressIDs Unknown List of source address IDs associated with the destination address.

Command example

!qradar-ips-local-destination-get filter=`local_destination_ip="1.1.1.1"`

Human Readable Output

Local Destination IPs

No entries.

qradar-search-retrieve-events


Polling command to search for events of a specific offense.

Base Command

qradar-search-retrieve-events

Input

Argument Name Description Required
offense_id The ID of the offense to retrieve. Mutually exclusive with query_expression. Optional
events_limit The number of events to return. Mutually exclusive with query_expression. Optional
events_columns Comma separated list of columns to return. Mutually exclusive with query_expression. Optional
fetch_mode The mode to use when fetching events. Mutually exclusive with query_expression. Possible values are: Fetch With All Events, Fetch Correlation Events Only. Optional
start_time The start time of the search. Mutually exclusive with query_expression. Optional
query_expression The AQL query to execute. Mutually exclusive with the other arguments. Optional
interval_in_seconds The interval in seconds to use when polling events. Optional
search_id The search id to query the results. Optional
retry_if_not_all_fetched Whenever set to true, the command retries to fetch all events if the number of events fetched is less than event_count. Possible values are: true, false. Optional
polling Wait for search results. Possible values are: true, false. Optional

Context Output

Path Type Description
QRadar.SearchEvents.ID Unknown The search id of the query.
QRadar.SearchEvents.Events Unknown The events from QRadar search.
QRadar.SearchEvents.Status Unknown The status of the search (‘wait’, ‘partial’, ‘success’).

Command example

!qradar-search-retrieve-events offense_id=14

Context Example

{
    "QRadar": {
        "SearchEvents": {
            "ID": "9c2c18a8-5e06-4edb-bc26-53ad44421148",
            "Status": "wait"
        }
    }
}

Human Readable Output

Search ID: 9c2c18a8-5e06-4edb-bc26-53ad44421148

qradar-remote-network-cidr-create


Create remote network CIDRs.

Base Command

qradar-remote-network-cidr-create

Input

Argument Name Description Required
cidrs An input list of CIDRs to add to QRadar (can be obtained automatically from EDL integrations and playbook). Multiple values in the same object are separated by commas. A CIDR or query is required. Optional
query The query for getting indicators from Cortex XSOAR. A CIDR or query is required. Optional
name A CIDR (remote network) name that will be displayed for all uploaded values in QRadar. Required
description Description that will be displayed and associated with all the newly uploaded CIDRs in QRadar. Required
group The exact name of the remote network group that CIDRs should be associated with as it appears in QRadar. A single group can be assigned to each create command. A new remote network group can be created in QRadar by giving a new unique remote network group name (that does not already exist in QRadar remote networks). Required
fields Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded from the output. Specify subfields in brackets, and multiple fields in the same object are separated by commas. The possible fields are id, group, name, CIDR, and description. Optional

Context Output

There is no context output for this command.

qradar-remote-network-cidr-list


Retrieves the list of staged remote networks.

Base Command

qradar-remote-network-cidr-list

Input

Argument Name Description Required
limit The maximum number of results to return. The default is 50. Optional
page The page offset. Optional
page_size Maximum number of results to retrieve in each page. Optional
group The name of the remote network group that the CIDRs are associated with, as it appears in QRadar. Optional
id ID of the CIDR (remote network). Optional
name The name of the CIDRs (remote network) as it appears in QRadar. Optional
filter Additional options to filter results using a query expression. Optional
fields Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. By default, this argument returns all fields (id, name, cidrs, group, description). Optional

Context Output

Path Type Description
QRadar.RemoteNetworkCIDR Number A list of all the retrieved CIDRs.
QRadar.RemoteNetworkCIDR.id Number ID of each CIDR remote network that is part of the group.
QRadar.RemoteNetworkCIDR.name String The associated CIDR name as it appears in QRadar.
QRadar.RemoteNetworkCIDR.description String The associated CIDR description as it appears in QRadar.

qradar-remote-network-cidr-delete


Deletes an existing staged remote network.

Base Command

qradar-remote-network-cidr-delete

Input

Argument Name Description Required
id ID that is used to locate the staged remote network that users want to remove from QRadar. Required

Context Output

There is no context output for this command.

qradar-remote-network-cidr-update


Updates an existing staged remote network.

Base Command

qradar-remote-network-cidr-update

Input

Argument Name Description Required
id The ID that is associated with the CIDR object that needs to be modified. Required
name The CIDR name in QRadar. If the CIDR name should be changed, it can be inserted here. Required
cidrs An input list of CIDRs to add to QRadar (can be obtained automatically from EDL integrations and playbook). Multiple values in the same object are separated by commas. A CIDR or query is required. Optional
query The query for getting indicators from Cortex XSOAR. A CIDR or query is required. Optional
description CIDR associated description presented in QRadar. If the CIDR description should be changed, it can be inserted here. Required
group The remote network group that CIDRs should belong to. If the CIDR-associated group should be changed, it can be inserted here. Required
fields Use this parameter to specify which fields you would like to get back in the response. Fields that are not named are excluded. Specify subfields in brackets, and multiple fields in the same object are separated by commas. The possible fields are id,group,name,cidr,description. Optional

Context Output

Path Type Description
QRadar.RemoteNetworkCIDR Number A list of all the CIDR ranges that were changed.
QRadar.RemoteNetworkCIDR.id Number The associated CIDR ID.
QRadar.RemoteNetworkCIDR.name String The associated CIDR name.
QRadar.RemoteNetworkCIDR.group String The group to which the remote network belongs.
QRadar.RemoteNetworkCIDR.description String The description of the remote network.

qradar-remote-network-deploy-execution


Executes a deployment.
Potentially harmful: This API command executes any waiting system deployments in QRadar within the same deployment type and hosts defined.

Base Command

qradar-remote-network-deploy-execution

Input

Argument Name Description Required
host_ip The IP of QRadar console host. Required
status The deployment status. Must be in capital letters (“INITIATING”). Possible values are: INITIATING. Optional
deployment_type The deployment type. Must be in capital letters (“INCREMENTAL” or “FULL”). Possible values are: INCREMENTAL, FULL. Required

Context Output

Path Type Description
QRadar.deploy.status String The deployment status (INITIALIZING, IN_PROGRESS, COMPLETE).

qradar-log-source-extensions-list


Retrieves a list of log source extensions.

Base Command

qradar-log-source-extensions-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter disconnected log collectors, e.g., “protocol=udp”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,protocol”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-log_source_extensions-GET.html. Optional
id ID of a specific disconnected log collector. Optional

Context Output

Path Type Description
QRadar.LogSourceExtension.Name String The name of the log source extension.
QRadar.LogSourceExtension.Description String The description of the log source extension.
QRadar.LogSourceExtension.ID Number The ID of the extension.
QRadar.LogSourceExtension.UUID String The UUID string of the log source extension.

qradar-log-source-delete


Deletes a log source by ID or name. One of the arguments must be provided.

Base Command

qradar-log-source-delete

Input

Argument Name Description Required
id The ID of the log source to be deleted. If this argument is not provided, name must be provided. Optional
name The unique name of the log source to be deleted. If this argument is not provided, the ID must be provided. Optional

Context Output

There is no context output for this command.

qradar-wincollect-destinations-list


Retrieves a list of WinCollect destinations.
In order to get wincollect_internal_destination_ids - filter internal=true needs to be used
In order to get wincollect_external_destination_ids - filter internal=false needs to be used.

Base Command

qradar-wincollect-destinations-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter wincollect destinations, e.g., “internal=true”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,host”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-wincollect-wincollect_destinations-GET.html. Optional
id ID of a specific WinCollect destination. Optional

Context Output

Path Type Description
QRadar.WinCollectDestination.ID Number The ID of the WinCollect destination.
QRadar.WinCollectDestination.Name String The name of the WinCollect destination.
QRadar.WinCollectDestination.Host String The IP or hostname of the WinCollect destination. WinCollect agents that use this destination send syslog event data to this host.
QRadar.WinCollectDestination.TlsCertificate String The TLS Certificate of the WinCollect destination.
QRadar.WinCollectDestination.Port Number The listen port of the WinCollect destination. WinCollect agents that use this destination send syslog event data to this port.
QRadar.WinCollectDestination.TransportProtocol String The protocol that is used to send event data to this WinCollect destination. Possible values are TCP or UDP.
QRadar.WinCollectDestination.IsInternal Boolean Set to “true” if the destination corresponds to a QRadar event collector process from this deployment; otherwise, it is set to false if it is any other host.
QRadar.WinCollectDestination.EventRateThrottle Number The events-per-second rate that is used to throttle the event flow to this destination.

qradar-log-source-create


Creates a new log source.

Base Command

qradar-log-source-create

Input

Argument Name Description Required
name The unique name of the log source. Required
protocol_type_id The type of protocol that is used by the log source. Must correspond to an existing protocol type. Required
type_id The type of the log source. Must correspond to an existing log source type. Required
protocol_parameters The list of protocol parameters corresponding with the selected protocol type ID. The syntax for this argument should follow: protocol_parameters=”name_1=value_1,name_2=value_2,…,name_n=value_n” where each name should correspond to a name of a protocol parameter from the protocol type and each value should fit the type of the protocol parameter. The command qradar-log-source-protocol-types-list can be used to list all available protocol types. Required
target_event_collector_id The ID of the event collector where the log source sends its data. The ID must correspond to an existing event collector. Required
sending_ip The IP of the system which the log source is associated to, or fed by. Optional
description The description of the log source. Optional
coalesce_events Determines if events collected by this log source are coalesced based on common properties. If each individual event is stored, then the condition is set to false. Defaults to true. Optional
enabled Determines if the log source is enabled. Defaults to true. Optional
parsing_order The order in which log sources will parse if multiples exist with a common identifier. Optional
group_ids The set of log source group IDs this log source is a member of. Each ID must correspond to an existing log source group. The command qradar-log-sources-groups-list can be used to list all available groups. See the Log Source Group API (https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-log_source_groups-id-GET.html). Optional
credibility On a scale of 0-10, the amount of credibility that the QRadar administrator places on this log source. Optional
store_event_payload If the payloads of events that are collected by this log source are stored, the condition is set to ‘true’. If only the normalized event records are stored, then the condition is set to ‘false’. Optional
disconnected_log_collector_id The ID of the disconnected log collector where this log source will run. The ID must correspond to an existing disconnected log collector. Optional
language_id The language of the events that are being processed by this log source. Must correspond to an existing log source language. Optional
requires_deploy Set to ‘true’ if you need to deploy changes to enable the log source for use; otherwise, set to ‘false’ if the log source is already active. Optional
wincollect_internal_destination_id The internal WinCollect destination for this log source, if applicable. Log sources without an associated WinCollect agent have a null value. Must correspond to an existing WinCollect destination. Optional
wincollect_external_destination_ids The set of external WinCollect destinations for this log source, if applicable. Log sources without an associated WinCollect agent have a null value. Each ID must correspond to an existing WinCollect destination. Optional
gateway If the log source is configured as a gateway, the condition is set to ‘true’; otherwise, the condition is set to ‘false’. A gateway log source is a standalone protocol configuration. The log source receives no events itself, and serves as a host for a protocol configuration that retrieves event data to feed other log sources. It acts as a “gateway” for events from multiple systems to enter the event pipeline. Optional

Context Output

Path Type Description
QRadar.LogSource.SendingIP String IP of the system which the log source is associated with, or fed by.
QRadar.LogSource.Internal Boolean Whether log source is internal.
QRadar.LogSource.ProtocolParameters Unknown Protocol parameters.
QRadar.LogSource.Description String Description of the log source.
QRadar.LogSource.Enabled Boolean Whether log source is enabled.
QRadar.LogSource.GroupIDs Number Log source group IDs.
QRadar.LogSource.Credibility Number Credibility of the log source.
QRadar.LogSource.ID Number ID of the log source.
QRadar.LogSource.ProtocolTypeID Number Protocol type used by log source.
QRadar.LogSource.CreationDate Date Date when log source was created.
QRadar.LogSource.Name String Name of the log source.
QRadar.LogSource.AutoDiscovered Boolean Whether log source was auto discovered.
QRadar.LogSource.ModifiedDate Date Date when log source was last modified.
QRadar.LogSource.TypeID Number The log source type.
QRadar.LogSource.LastEventTime Date Date when the last event was received by the log source.
QRadar.LogSource.Gateway Boolean Whether log source is configured as a gateway.
QRadar.LogSource.Status unknown Status of the log source.
QRadar.LogSource.TargetEventCollectorID Number The ID of the event collector where the log source sends its data.

qradar-log-source-languages-list


Retrieves a list of log source languages.

Base Command

qradar-log-source-languages-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter disconnected log collectors, e.g., “protocol=udp”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,protocol”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-log_source_languages-GET.html. Optional
id ID of a specific disconnected log collector. Optional

Context Output

Path Type Description
QRadar.LogSourceLanguage.ID Number The ID of the language. This ID does not change across deployments.
QRadar.LogSourceLanguage.Name String The display name of the language.

qradar-log-source-protocol-types-list


Retrieves the list of protocol types.

Base Command

qradar-log-source-protocol-types-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter disconnected log collectors, e.g., “protocol=udp”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,protocol_parameters”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-protocol_types-GET.html. Optional
id ID of a specific disconnected log collector. Optional

Context Output

Path Type Description
QRadar.LogSourceProtocolType.GatewaySupported Boolean If this protocol type can be configured for a gateway log source, the condition is set to ‘true’; otherwise, the condition is set to ‘false’. A gateway log source is a standalone protocol configuration. The log source receives no events itself, and serves as a host for a protocol configuration that retrieves event data to feed other log sources. It acts as a ‘gateway’ for events from multiple systems to enter the event pipeline. Not all protocol types can be used as a gateway if they don’t support collecting event data from multiple sources.
QRadar.LogSourceProtocolType.ID Number The ID of the protocol type.
QRadar.LogSourceProtocolType.Inbound Boolean Indicates whether this is an inbound protocol.
QRadar.LogSourceProtocolType.LatestVersion String The latest version available of the protocol type component.
QRadar.LogSourceProtocolType.Name String The unique name of the protocol type.
QRadar.LogSourceProtocolType.ParameterGroups.id Number The ID of the protocol parameter group.
QRadar.LogSourceProtocolType.ParameterGroups.name String The name of the protocol parameter group.
QRadar.LogSourceProtocolType.ParameterGroups.required Boolean If at least one parameter in this group must be set, the condition is set to true; otherwise, the condition is set to false.
QRadar.LogSourceProtocolType.Parameters.allowed_values.name String An allowed value for the name of the parameter.
QRadar.LogSourceProtocolType.Parameters.allowed_values.value String An allowed value for the value of the parameter.
QRadar.LogSourceProtocolType.Parameters.default_value String The optional default parameter value.
QRadar.LogSourceProtocolType.Parameters.description String The description of the parameter.
QRadar.LogSourceProtocolType.Parameters.group_id Number The ID of the protocol parameter group that this parameter belongs to. The group_id is optional.
QRadar.LogSourceProtocolType.Parameters.id Number The ID of the parameter.
QRadar.LogSourceProtocolType.Parameters.label String The label of the parameter.
QRadar.LogSourceProtocolType.Parameters.max_length Number The maximum length of the parameter value for the following parameter types: STRING, TEXT, HOST, PASSWORD, REGEX. The max_length is optional.
QRadar.LogSourceProtocolType.Parameters.max_value String The maximum of the parameter value for the following parameter types: INTEGER, REAL, DATE, TIME, DATETIME, INTERVAL. The max_value is optional.
QRadar.LogSourceProtocolType.Parameters.min_length Number The minimum length of the parameter value for the following parameter types: STRING, TEXT, HOST, PASSWORD, REGEX. The max_length is optional.
QRadar.LogSourceProtocolType.Parameters.min_value String The minimum of the parameter value for the following parameter types: INTEGER, REAL, DATE, TIME, DATETIME, INTERVAL. The max_value is optional.
QRadar.LogSourceProtocolType.Parameters.name String The name of the parameter.
QRadar.LogSourceProtocolType.Parameters.pattern String An optional Java regex pattern restriction on the parameter value for the following parameter types: STRING, TEXT, HOST, PASSWORD.
QRadar.LogSourceProtocolType.Parameters.pattern_description String The description of the pattern of the parameter.
QRadar.LogSourceProtocolType.Parameters.required Boolean If the parameter is mandatory, the condition is set to true; otherwise, the condition is set to false.
QRadar.LogSourceProtocolType.Parameters.rules.affected_property String The affected property. For possible values visit: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-protocol_types-GET.html
QRadar.LogSourceProtocolType.Parameters.rules.affected_property_value String The value to be applied to the affected parameter when the rule is triggered. For further info visit: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-protocol_types-GET.html
QRadar.LogSourceProtocolType.Parameters.rules.parameter_id Number The ID of the parameter affected by the rule.
QRadar.LogSourceProtocolType.Parameters.rules.trigger_parameter_id Number The ID of the trigger parameter.
QRadar.LogSourceProtocolType.Parameters.rules.trigger_pattern String The pattern that triggers the rule. For example, if the value of trigger_parameter_id matches the regular expression of this field, the rule triggers.
QRadar.LogSourceProtocolType.Parameters.type String The type of the parameter. Possible values are: STRING, TEXT, INTEGER, REAL, BOOLEAN, DATE, TIME, DATETIME, INTERVAL, HOST, PASSWORD, REGEX.
QRadar.LogSourceProtocolType.TestingCapabilities.can_accept_sample_events Boolean Indicates whether the protocol type can accept sample events (only applicable to inbound protocol types).
QRadar.LogSourceProtocolType.TestingCapabilities.can_collect_events Boolean Indicates whether the protocol type can collect test events.
QRadar.LogSourceProtocolType.TestingCapabilities.testable Boolean Indicates whether the protocol type is testable.
QRadar.LogSourceProtocolType.Version String The version of the protocol type component.

qradar-disconnected-log-collectors-list


Retrieves a list of disconnected log collectors.

Base Command

qradar-disconnected-log-collectors-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter disconnected log collectors, e.g., “protocol=udp”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,protocol”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-disconnected_log_collectors-GET.html. Optional
id ID of a specific disconnected log collector. Optional

Context Output

Path Type Description
QRadar.DisconnectedLogCollector.ID Number The ID of the disconnected log collector.
QRadar.DisconnectedLogCollector.Name String The name of the disconnected log Collector.
QRadar.DisconnectedLogCollector.Description String The description of the disconnected log collector.
QRadar.DisconnectedLogCollector.Protocol String The transport protocol used by the disconnected log collector to send events to QRadar. Possible values are TLS and UDP.
QRadar.DisconnectedLogCollector.UUID String The UUID of the disconnected log collector.
QRadar.DisconnectedLogCollector.Version String The version of the disconnected log collector.

qradar-log-source-update


Updates an exising log source.

Base Command

qradar-log-source-update

Input

Argument Name Description Required
id The ID of the log source. Required
name The unique name of the log source. Optional
protocol_type_id The type of protocol that is used by the log source. Must correspond to an existing protocol type. Optional
type_id The type of the log source. Must correspond to an existing log source type. Optional
protocol_parameters The list of protocol parameters corresponding with the selected protocol type ID. The syntax for this argument should follow: protocol_parameters=”name_1=value_1,name_2=value_2,…,name_n=value_n” where each name should correspond to a name of a protocol parameter from the protocol type and each value should fit the type of the protocol parameter. The command qradar-log-source-protocol-types-list can be used to list all available protocol types. Optional
target_event_collector_id The ID of the event collector where the log source sends its data. The ID must correspond to an existing event collector. Optional
sending_ip The IP of the system which the log source is associated to, or fed by. Optional
description The description of the log source. Optional
coalesce_events Determines if events collected by this log source are coalesced based on common properties. If each individual event is stored, then the condition is set to false. Defaults to true. Optional
enabled Determines if the log source is enabled. Defaults to true. Optional
parsing_order The order in which log sources will parse if multiples exist with a common identifier. Optional
group_ids The set of log source group IDs this log source is a member of. Each ID must correspond to an existing log source group. The command qradar-log-sources-groups-list can be used to list all available groups. See the Log Source Group API (https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-log_source_groups-id-GET.html). Optional
credibility On a scale of 0-10, the amount of credibility that the QRadar administrator places on this log source. Optional
store_event_payload If the payloads of events that are collected by this log source are stored, the condition is set to ‘true’. If only the normalized event records are stored, then the condition is set to ‘false’. Optional
disconnected_log_collector_id The ID of the disconnected log collector where this log source will run. The ID must correspond to an existing disconnected log collector. Optional
language_id The language of the events that are being processed by this log source. Must correspond to an existing log source language. Optional
requires_deploy Set to ‘true’ if you need to deploy changes to enable the log source for use; otherwise, set to ‘false’ if the log source is already active. Optional
wincollect_internal_destination_id The internal WinCollect destination for this log source, if applicable. Log sources without an associated WinCollect agent have a null value. Must correspond to an existing WinCollect destination. Optional
wincollect_external_destination_ids The set of external WinCollect destinations for this log source, if applicable. Log Sources without an associated WinCollect agent have a null value. Each ID must correspond to an existing WinCollect destination. Optional
gateway If the log source is configured as a gateway, the condition is set to ‘true’; otherwise, the condition is set to ‘false’. A gateway log source is a standalone protocol configuration. The log source receives no events itself, and serves as a host for a protocol configuration that retrieves event data to feed other log sources. It acts as a “gateway” for events from multiple systems to enter the event pipeline. Optional

Context Output

There is no context output for this command.

qradar-log-source-types-list


Retrieves a list of log sources types.

Base Command

qradar-log-source-types-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter disconnected log collectors, e.g., “protocol=udp”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,protocol”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-log_source_types-GET.html. Optional
id ID of a specific disconnected log collector. Optional

Context Output

Path Type Description
QRadar.LogSourceTypesList.Custom Boolean The condition is set to true if this is a custom log source type; otherwise, the condition is set to false.
QRadar.LogSourceTypesList.DefaultProtocolID Number The ID of the default protocol type for this log source type. The ID must correspond to an existing protocol type. See the Protocol Type API (/api/config/event_sources/log_source_management/protocol_types/).
QRadar.LogSourceTypesList.ID Number The ID of the log source type.
QRadar.LogSourceTypesList.Internal Boolean The condition is set to true if the log source type is an internal log source type (for example, System Notification, SIM Audit, Asset Profiler, and so on) for which log sources cannot be created, edited, or deleted. If this is a user configurable log source type, the condition is set to false.
QRadar.LogSourceTypesList.LatestVersion String The latest available version of the log source type component.
QRadar.LogSourceTypesList.LogSourceExtensionID Number The log source extension that is associated with the log source type. The ID must correspond to an existing log source extension or be set to null. See the Log Source Extension API (/api/config/event_sources/log_source_management/log_source_extensions/).
QRadar.LogSourceTypesList.Name String The unique name of the log source type. The name is not localized.
QRadar.LogSourceTypesList.protocol_types.documented Boolean Indicates whether the protocol is documented/fully supported for this log source type.
QRadar.LogSourceTypesList.protocol_types.protocol_id Number ID of the protocol type.
QRadar.LogSourceTypesList.supported_language_ids List The IDs of the languages supported by this log source type. Each ID must correspond to an existing log source language. See the Log Source Language API: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-log_source_languages-id-GET.html
QRadar.LogSourceTypesList.uuid String A UUID string of the log source type.
QRadar.LogSourceTypesList.version String The log source type plugin version.

qradar-log-source-groups-list


Retrieves a list of log source languages.

Base Command

qradar-log-source-groups-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter disconnected log collectors, e.g., “protocol=udp”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,protocol”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-log_source_management-log_source_groups-GET.html. Optional
id ID of a specific disconnected log collector. Optional

Context Output

Path Type Description
QRadar.LogSourceGroup.Assignable Boolean If log sources can be assigned to this group, the condition is set to true; otherwise, the condition is set to false. Log sources cannot be assigned directly to the “Other” group or to the root log source group node.
QRadar.LogSourceGroup.ChildGroupIDs List The list of IDs of any child log source groups that belong to this group.
QRadar.LogSourceGroup.Description String The description of the group.
QRadar.LogSourceGroup.ID Number The ID of the group.
QRadar.LogSourceGroup.ModificationDate Number The date and time (expressed as milliseconds since epoch) that the group was last modified.
QRadar.LogSourceGroup.Name String The name of the group.
QRadar.LogSourceGroup.Owner String The name of the user who owns the group.
QRadar.LogSourceGroup.ParentID Number The ID of the group’s parent group. The root node group has a null parent_ID.

qradar-event-collectors-list


Retrieves a list of event collectors.

Base Command

qradar-event-collectors-list

Input

Argument Name Description Required
range Range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter Query by which to filter event collectors, e.g., “auto_discovered=false”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. Optional
fields Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “id,name,status”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_20.0/20.0–config-event_sources-event_collectors-GET.html. Optional
id ID of a specific event collector. Optional

Context Output

Path Type Description
QRadar.EventCollector.Name String The display name of the event collector. Not localized because it is derived from a process/component name and the hostname of the managed host it runs on, neither of which are translatable.
QRadar.EventCollector.HostID Number The ID of the host on which this event collector process runs.
QRadar.EventCollector.ComponentName String The name of the component backing this event collector process. Also contained in the “name” field.
QRadar.EventCollector.ID Number The unique ID of the event collector.

qradar-reference-maps-list


Retrieves a list of reference maps.

Base Command

qradar-reference-maps-list

Input

Argument Name Description Required
ref_name The reference name of the reference map for which to retrieve its details. Specify ref_name to get details about a specific reference map. Optional
range The range of results to return (e.g.: 0-20, 3-5, 3-3). Default is 0-49. Optional
filter The query by which to filter reference maps, e.g., “timeout_type=FIRST_SEEN”. For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html.
When using both ref_name and filter arguments, the filter should be from the data values of the specified reference map, e.g. “value=’1.1.1.1’”.
Optional
fields A comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., “name,timeout_type”. Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0–reference_data-maps-GET.html. Optional

Context Output

Path Type Description
QRadar.ReferenceMaps.CollectionID Number The collection ID of the reference map.
QRadar.ReferenceMaps.NumberOfElements Number The number of elements in the reference map.
QRadar.ReferenceMaps.TimeToLive String The time left to live for the reference.
QRadar.ReferenceMaps.Data.LastSeen Date The date when this data was last seen in ISO 8601 format (e.g., 2024-01-15T12:34:56Z).
QRadar.ReferenceMaps.Data.FirstSeen Date The date when this data was first seen in ISO 8601 format (e.g., 2024-01-15T12:34:56Z).
QRadar.ReferenceMaps.Data.Source String The source of this data.
QRadar.ReferenceMaps.Data.Value String The data map entry value.
QRadar.ReferenceMaps.Data.Key String The data map entry key.
QRadar.ReferenceMaps.CreationTime Date The date when the reference map was created in ISO 8601 format (e.g., 2024-01-15T12:34:56Z).
QRadar.ReferenceMaps.Name String The name of the reference map.
QRadar.ReferenceMaps.Namespace String The namespace of the reference map. Possible values: “PRIVATE”, “SHARED”, “TENANT”.
QRadar.ReferenceMaps.ElementType String The type of the elements in the reference map.

Command example


#### Context Example

```json
{
    "QRadar": {
        "ReferenceMaps": [
            {
                "CollectionID": 145,
                "CreationTime": "2025-06-03T07:15:04.824000+00:00",
                "ElementType": "ALN",
                "Name": "Monitoring Identifier Groups",
                "Namespace": "SHARED",
                "NumberOfElements": 6,
                "TimeoutType": "LAST_SEEN",
                "ValueLabel": "Log Source Group"
            },
            {
                "CollectionID": 136,
                "CreationTime": "2025-05-14T15:12:07.932000+00:00",
                "ElementType": "NUM",
                "Name": "Monitoring Identifier Gaps",
                "Namespace": "SHARED",
                "NumberOfElements": 3,
                "TimeoutType": "UNKNOWN"
            }
        ]
    }
}

Human Readable Output

Reference Maps List

Name ElementType Namespace CollectionID TimeoutType NumberOfElements ValueLabel CreationTime TimeToLive
Monitoring Identifier Groups ALN SHARED 145 LAST_SEEN 6 Log Source Group 2025-06-03T07:15:04.824000+00:00  
Monitoring Identifier Gaps NUM SHARED 136 UNKNOWN 3   2025-05-14T15:12:07.932000+00:00  

Command example

!qradar-reference-maps-list ref_name="Monitoring Identifier Gaps"

Context Example

{
    "QRadar": {
        "ReferenceMaps": {
            "CollectionID": 136,
            "CreationTime": "2025-05-14T15:12:07.932000+00:00",
            "Data": [
                {
                    "FirstSeen": "2026-02-10T13:22:50.372000+00:00",
                    "Key": "Key1",
                    "LastSeen": "2026-02-10T13:22:50.372000+00:00",
                    "Source": "reference data api",
                    "Value": "1234.0"
                },
                {
                    "FirstSeen": "2026-02-10T13:27:57.647000+00:00",
                    "Key": "Key2",
                    "LastSeen": "2026-02-10T13:27:57.647000+00:00",
                    "Source": "reference data api",
                    "Value": "4567.0"
                },
                {
                    "FirstSeen": "2026-08-07T06:29:06.602000+00:00",
                    "Key": "demoKey",
                    "LastSeen": "2026-08-11T10:40:15.379000+00:00",
                    "Source": "reference data api",
                    "Value": "12345.0"
                }
            ],
            "ElementType": "NUM",
            "Name": "Monitoring Identifier Gaps",
            "Namespace": "SHARED",
            "NumberOfElements": 3,
            "TimeoutType": "UNKNOWN"
        }
    }
}

Human Readable Output

Reference Maps List

Name ElementType Namespace CollectionID TimeoutType NumberOfElements CreationTime
Monitoring Identifier Gaps NUM SHARED 136 UNKNOWN 3 2025-05-14T15:12:07.932000+00:00

Reference Map Data

FirstSeen Key LastSeen Source Value
2026-02-10T13:22:50.372000+00:00 Key1 2026-02-10T13:22:50.372000+00:00 reference data api 1234.0
2026-02-10T13:27:57.647000+00:00 Key2 2026-02-10T13:27:57.647000+00:00 reference data api 4567.0
2026-08-07T06:29:06.602000+00:00 demoKey 2026-08-11T10:40:15.379000+00:00 reference data api 12345.0

qradar-reference-map-value-upsert


Adds or updates an element in a reference map.

Base Command

qradar-reference-map-value-upsert

Input

Argument Name Description Required
ref_name The name of the reference map to add or update an element in. Reference names can be found by the ‘Name’ field in the ‘qradar-reference-maps-list’ command. Required
value The value to insert or update in the reference map. Required
key The key to update. Required
source The indication of where the data originated. Default is reference data api. Optional

Context Output

There is no context output for this command.

Command example

!qradar-reference-map-value-upsert ref_name="Monitoring Identifier Gaps" value="12345" key="demoKey"

Human Readable Output

Reference map “Monitoring Identifier Gaps” successfully updated: “demoKey” set to “12345”.

Configuration parameters

  • server — Server URL (required)
  • credentials — Username (required)
  • api_version — QRadar API Version (required)
  • incident_type — Incident Type
  • first_fetch — First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)
  • fetch_mode — Fetch mode
  • retry_events_fetch — Retry events fetch
  • events_limit — Maximum number of events per incident.
  • offenses_per_fetch — Number of offenses to pull per API call (max 50)
  • query — Query to fetch offenses.
  • enrichment — Incidents Enrichment
  • limit_assets — Maximum number of assets to fetch
  • events_columns — Event fields to return from the events query (WARNING: This parameter is correlated to the incoming mapper and changing the values may adversely affect mapping).
  • mirror_options — Mirroring Options
  • close_incident — Close Mirrored XSOAR Incident
  • mirror_limit — The number of incoming incidents to mirror each time
  • adv_params — Advanced Parameters
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • timeout — Timeout for http-requests
  • fetch_interval — Fetch Incidents Interval

Commands (71)

  • get-mapping-fields

    Returns the list of fields for an incident type. This command should be used for debugging purposes.

  • get-modified-remote-data

    Returns the list of incidents IDs that were modified since the last update time. Note that this method is for debugging purposes. The get-modified-remote-data command is used as part of the mirroring feature, which is available from version 6.1.

  • get-remote-data

    Gets remote data from a remote incident. This method does not update the current incident, and should be used for debugging purposes.

  • qradar-assets-list

    Retrieves assets list.

  • qradar-closing-reasons

    Retrieves a list of offense closing reasons.

  • qradar-create-note Deprecated

    Create a note on an offense. Deprecated, Use qradar-offense-note-create instead.

  • qradar-create-reference-set Deprecated

    Creates a new reference set. If the provided name is already in use, this command will fail. Deprecated, Use qradar-reference-set-create instead.

  • qradar-create-reference-set-value Deprecated

    Add or update a value in a reference set. Deprecated, Use qradar-reference-set-value-upsert instead.

  • qradar-delete-reference-set Deprecated

    Deletes a reference set corresponding to the name provided. Deprecated, Use qradar-reference-set-delete instead.

  • qradar-delete-reference-set-value Deprecated

    Deletes a value in a reference set. Deprecated, Use qradar-reference-set-value-delete instead.

  • qradar-disconnected-log-collectors-list

    Retrieves a list of disconnected log collectors.

  • qradar-domains-list

    Gets the list of domains. You must have System Administrator or Security Administrator permissions to call this endpoint if you are trying to retrieve the details of all domains. You can retrieve details of domains that are assigned to your Security Profile without having the System Administrator or Security Administrator permissions. If you do not have the System Administrator or Security Administrator permissions, then for each domain assigned to your security profile you can only view the values for the ID and name fields. All other values return null.

  • qradar-event-collectors-list

    Retrieves a list of event collectors.

  • qradar-geolocations-for-ip

    Retrieves the MaxMind GeoIP data for the specified IP address.

  • qradar-get-asset-by-id Deprecated

    Retrieves the asset by id. Deprecated, Use qradar-assets-list instead.

  • qradar-get-assets Deprecated

    List all assets found in the model. Deprecated, Use qradar-assets-list instead.

  • qradar-get-closing-reasons Deprecated

    Get closing reasons. Deprecated, Use qradar-closing-reasons instead.

  • qradar-get-custom-properties

    Retrieves a list of event regex properties.

  • qradar-get-domain-by-id Deprecated

    Retrieves Domain information By ID. Deprecated, Use qradar-domains-list instead.

  • qradar-get-domains Deprecated

    Retrieve all Domains. Deprecated, Use qradar-domains-list instead.

  • qradar-get-note Deprecated

    Retrieve a note for an offense. Deprecated, Use qradar-offense-notes-list instead.

  • qradar-get-reference-by-name Deprecated

    Information about the reference set that had data added or updated. This returns the information set, but not the contained data. This feature is supported from version 8.1 and upward. Deprecated, Use qradar-reference-sets-list instead.

  • qradar-get-search Deprecated

    Gets a specific search ID and status. Deprecated, Use qradar-search-status-get instead.

  • qradar-get-search-results Deprecated

    Gets search results. Deprecated, Use qradar-search-results-get instead.

  • qradar-indicators-upload

    Uploads indicators to QRadar.

  • qradar-ips-local-destination-get

    Get Source IPs.

  • qradar-ips-source-get

    Get Source IPs.

  • qradar-log-source-create

    Creates a new log source.

  • qradar-log-source-delete

    Deletes a log source by ID or name. One of the arguments must be provided.

  • qradar-log-source-extensions-list

    Retrieves a list of log source extensions.

  • qradar-log-source-groups-list

    Retrieves a list of log source languages.

  • qradar-log-source-languages-list

    Retrieves a list of log source languages.

  • qradar-log-source-protocol-types-list

    Retrieves the list of protocol types.

  • qradar-log-source-types-list

    Retrieves a list of log sources types.

  • qradar-log-source-update

    Updates an exising log source.

  • qradar-log-sources-list

    Retrieves a list of log sources.

  • qradar-offense-by-id Deprecated

    Gets offense with matching offense ID from qradar.Deprecated, Use qradar-offense-list instead.

  • qradar-offense-note-create

    Creates a note on an offense.

  • qradar-offense-notes-list

    Retrieves a list of notes for an offense.

  • qradar-offense-update

    Updates an offense.

  • qradar-offenses Deprecated

    Gets offenses from QRadar. Deprecated, Use qradar-offenses-list instead.

  • qradar-offenses-list

    Gets offenses from QRadar.

  • qradar-print-context

    Returns a redacted snapshot of integration context metrics (queued, in-progress, finished, meta sizes, concurrent active, samples count). This command is intended for debugging purposes and may return sensitive data.

  • qradar-reference-map-value-upsert

    Adds or updates an element in a reference map.

  • qradar-reference-maps-list

    Retrieves a list of reference maps.

  • qradar-reference-set-create

    Creates a new reference set.

  • qradar-reference-set-delete

    Removes a reference set or purges its contents.

  • qradar-reference-set-value-delete

    Removes a value from a reference set.

  • qradar-reference-set-value-upsert

    Adds or updates an element in a reference set.

  • qradar-reference-sets-list

    Retrieves a list of reference sets.

  • qradar-remote-network-cidr-create

    Create remote network CIDRs.

  • qradar-remote-network-cidr-delete

    Deletes an existing staged remote network.

  • qradar-remote-network-cidr-list

    Retrieves the list of staged remote networks.

  • qradar-remote-network-cidr-update

    Updates an existing staged remote network.

  • qradar-remote-network-deploy-execution

    Executes a deployment. Potentially harmful: This API command executes any waiting system deployments in QRadar within the same deployment type and hosts defined.

  • qradar-reset-last-run

    Resets the fetch incidents last run value, which resets the fetch to its initial fetch state. (Will try to fetch the first available offense).

  • qradar-rule-groups-list

    Retrieves a list of the rule groups.

  • qradar-rules-list

    Retrieves a list of rules.

  • qradar-saved-searches-list

    Retrieves a list of Ariel saved searches.

  • qradar-search-cancel

    Cancels the search in QRadar.

  • qradar-search-create

    Creates a new asynchronous Ariel search. Returns the search ID. Search status and results can be polled by sending the search ID to the 'qradar-search-status-get' and 'qradar-search-results-get' commands. Accepts SELECT query expressions only.

  • qradar-search-delete

    Deletes the search from Qradar.

  • qradar-search-results-get

    Retrieves search results.

  • qradar-search-retrieve-events

    Polling command to search for events of a specific offense.

  • qradar-search-status-get

    Retrieves status information for a search, based on the search ID.

  • qradar-searches Deprecated

    Searches in QRadar using AQL. It is highly recommended to use the playbook 'QRadarFullSearch' instead of this command - it will execute the search, and will return the result. Deprecated, Use qradar-search-create instead.

  • qradar-searches-list

    Retrieves the list of Ariel searches IDs. Search status and results can be polled by sending the search ID to the 'qradar-search-status-get' and 'qradar-search-results-get' commands.

  • qradar-update-offense Deprecated

    Update an offense. Deprecated, Use qradar-offense-update instead.

  • qradar-update-reference-set-value Deprecated

    Adds or updates a value in a reference set. Deprecated, Use qradar-reference-set-value-upsert instead.

  • qradar-upload-indicators

    Uploads indicators from Demisto to QRadar.

  • qradar-wincollect-destinations-list

    Retrieves a list of WinCollect destinations. In order to get wincollect_internal_destination_ids - filter internal=true needs to be used In order to get wincollect_external_destination_ids - filter internal=false needs to be used.

"""
QRadar v3 integration for Cortex XSOAR - Unit Tests file
"""

import copy
import json
from collections.abc import Callable
from datetime import datetime
from unittest.mock import patch

import demistomock as demisto
import pytest
import pytz
import QRadar_v3  # import module separately for mocker
import requests
from CommonServerPython import (
    CommandResults,
    DemistoException,
    GetModifiedRemoteDataResponse,
    GetRemoteDataResponse,
    get_integration_context,
    set_integration_context,
)
from QRadar_v3 import (
    ASSET_PROPERTIES_NAME_MAP,
    FULL_ASSET_PROPERTIES_NAMES_MAP,
    LAST_FETCH_KEY,
    LAST_MIRROR_CLOSED_KEY,
    LAST_MIRROR_KEY,
    MINIMUM_API_VERSION,
    MIRROR_OFFENSE_AND_EVENTS,
    MIRRORED_OFFENSES_FETCHED_CTX_KEY,
    MIRRORED_OFFENSES_FINISHED_CTX_KEY,
    MIRRORED_OFFENSES_QUERIED_CTX_KEY,
    SAMPLE_INCIDENTS_KEY,
    OFFENSE_OLD_NEW_NAMES_MAP,
    REFERENCE_SETS_RAW_FORMATTED,
    USECS_ENTRIES,
    SAMPLE_SIZE,
    Client,
    EntryFormat,
    EntryType,
    FetchMode,
    IndicatorsSearcher,
    QueryStatus,
    add_iso_entries_to_asset,
    add_iso_entries_to_dict,
    build_final_outputs,
    build_headers,
    convert_dict_to_actual_values,
    convert_list_to_actual_values,
    create_incidents_from_offenses,
    create_search_with_retry,
    create_single_asset_for_offense_enrichment,
    enrich_asset_properties,
    enrich_assets_results,
    enrich_offense_with_assets,
    enrich_offense_with_events,
    flatten_nested_geolocation_values,
    get_cidrs_indicators,
    get_domain_names,
    get_minimum_id_to_fetch,
    get_modified_remote_data_command,
    get_offense_addresses,
    get_offense_closing_reasons,
    get_offense_enrichment,
    get_offense_types,
    get_remote_data_command,
    get_rules_names,
    get_time_parameter,
    is_positive,
    is_valid_ip,
    migrate_integration_ctx,
    perform_long_running_loop,
    poll_offense_events,
    qradar_assets_list_command,
    qradar_closing_reasons_list_command,
    qradar_disconnected_log_collectors_list_command,
    qradar_domains_list_command,
    qradar_event_collectors_list_command,
    qradar_geolocations_for_ip_command,
    qradar_get_custom_properties_command,
    qradar_indicators_upload_command,
    should_get_time_parameter,
    qradar_ips_local_destination_get_command,
    qradar_ips_source_get_command,
    qradar_log_source_create_command,
    qradar_log_source_delete_command,
    qradar_log_source_extensions_list_command,
    qradar_log_source_groups_list_command,
    qradar_log_source_languages_list_command,
    qradar_log_source_protocol_types_list_command,
    qradar_log_source_types_list_command,
    qradar_log_source_update_command,
    qradar_log_sources_list_command,
    qradar_offense_notes_create_command,
    qradar_offense_notes_list_command,
    qradar_offense_update_command,
    qradar_offenses_list_command,
    qradar_reference_set_create_command,
    qradar_reference_set_delete_command,
    qradar_reference_set_value_delete_command,
    qradar_reference_set_value_upsert_command,
    qradar_reference_sets_list_command,
    qradar_reference_maps_list_command,
    qradar_reference_map_value_upsert_command,
    qradar_remote_network_cidr_create_command,
    qradar_remote_network_cidr_delete_command,
    qradar_remote_network_cidr_list_command,
    qradar_remote_network_cidr_update_command,
    qradar_remote_network_deploy_execution_command,
    qradar_rule_groups_list_command,
    qradar_rules_list_command,
    qradar_saved_searches_list_command,
    qradar_search_cancel_command,
    qradar_search_create_command,
    qradar_search_results_get_command,
    qradar_search_status_get_command,
    qradar_searches_list_command,
    qradar_wincollect_destinations_list_command,
    sanitize_outputs,
    validate_integration_context,
    verify_args_for_remote_network_cidr,
    verify_args_for_remote_network_cidr_list,
)
from requests.exceptions import ReadTimeout

QRadar_v3.FAILURE_SLEEP = 0
QRadar_v3.SLEEP_FETCH_EVENT_RETRIES = 0

client = Client(
    server="https://192.168.0.1",
    verify=False,
    proxy=False,
    api_version=str(MINIMUM_API_VERSION),
    credentials={"identifier": "admin", "password": "1234"},
)

QRadar_v3.EVENTS_SEARCH_RETRY_SECONDS = 0


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


asset_enrich_data = util_load_json("./test_data/asset_enrich_test.json")

command_test_data = util_load_json("./test_data/command_test_data.json")
ip_command_test_data = util_load_json("./test_data/ips_commands_data.json")
ctx_test_data = util_load_json("./test_data/integration_context_tests.json")

event_columns_default_value = (
    "QIDNAME(qid), LOGSOURCENAME(logsourceid), CATEGORYNAME(highlevelcategory), "
    "CATEGORYNAME(category), PROTOCOLNAME(protocolid), sourceip, sourceport, destinationip, "
    "destinationport, QIDDESCRIPTION(qid), username, PROTOCOLNAME(protocolid), "
    'RULENAME("creEventList"), sourcegeographiclocation, sourceMAC, sourcev6, '
    "destinationgeographiclocation, destinationv6, LOGSOURCETYPENAME(devicetype), "
    "credibility, severity, magnitude, eventcount, eventDirection, postNatDestinationIP, "
    "postNatDestinationPort, postNatSourceIP, postNatSourcePort, preNatDestinationPort, "
    "preNatSourceIP, preNatSourcePort, UTF8(payload), starttime, devicetime "
)


@pytest.mark.parametrize(
    "arg, iso_format, epoch_format, expected",
    [
        (
            "2020-11-22T16:31:14-02:00",
            False,
            False,
            datetime(2020, 11, 22, 18, 31, 14, tzinfo=pytz.utc),
        ),
        (None, False, False, None),
        (None, True, False, None),
        ("2020-12-12", True, False, "2020-12-12T00:00:00+00:00"),
        ("2020-12-12T10:11:22", True, False, "2020-12-12T10:11:22+00:00"),
        ("2020-12-12T22:11:22-03:00", True, False, "2020-12-13T01:11:22+00:00"),
        ("2020-12-12", False, True, 1607731200000),
        ("2020-12-12T10:11:22", False, True, 1607767882000),
        ("2020-12-12T22:11:22-03:00", False, True, 1607821882000),
    ],
)
def test_get_optional_time_parameter_valid_time_argument(arg, iso_format, epoch_format, expected):
    """
    Given:
     - Demisto arguments.
     - Argument of type time to extract from Demisto arguments as epoch time.

    When:
     - Case a: Argument exists, has expected date format, parse format was not asked,.
     - Case b: Argument does not exist, parse format was not asked.
     - Case c: Argument does not exist, parse format was asked.
     - Case d: Argument exist and has ISO format, parse format was asked.
     - Case e: Argument exist and has ISO format, parse format was asked.

    Then:
     - Case a: Ensure that the corresponding epoch time is returned.
     - Case b: Ensure that None is returned.
     - Case c: Ensure that None is returned.
     - Case d: Ensure that correct FraudWatch format is returned.
     - Case e: Ensure that correct FraudWatch format is returned.
    """
    assert (get_time_parameter(arg, iso_format=iso_format, epoch_format=epoch_format)) == expected


def test_connection_errors_recovers(mocker):
    """
    Given:
     - Connection Error, ReadTimeout error and a success response

    When:
     - running the http_request method

    Then:
     - Ensure that success message is printed and recovery for http request happens.
    """
    mocker.patch.object(demisto, "error")
    mocker.patch("QRadar_v3.time.sleep")
    mocker.patch.object(
        client,
        "_http_request",
        side_effect=[
            DemistoException(message="error", exception=requests.ConnectionError("error")),
            requests.ReadTimeout("error"),
            "success",
        ],
    )
    assert client.http_request(method="GET", url_suffix="url") == "success"


@pytest.mark.parametrize(
    "dict_key, inner_keys, expected",
    [
        ("continent", ["name"], {"ContinentName": "NorthAmerica"}),
        ("city", ["name"], {"CityName": "Mukilteo"}),
        (
            "represented_country",
            ["unknown", "confidence"],
            {"RepresentedCountryUnknown": None, "RepresentedCountryConfidence": None},
        ),
        (
            "registered_country",
            ["iso_code", "name"],
            {
                "RegisteredCountryIsoCode": "US",
                "RegisteredCountryName": "United States",
            },
        ),
        (
            "location",
            [
                "accuracy_radius",
                "timezone",
                "latitude",
                "metro_code",
                "average_income",
                "population_density",
                "longitude",
            ],
            {
                "LocationAccuracyRadius": 1000,
                "LocationTimezone": "America/Los_Angeles",
                "LocationLatitude": 47.913,
                "LocationMetroCode": 819,
                "LocationAverageIncome": None,
                "LocationPopulationDensity": None,
                "LocationLongitude": -122.3042,
            },
        ),
    ],
)
def test_flatten_nested_geolocation_values(dict_key, inner_keys, expected):
    """
    Given:
     - Dict of IP details returned by QRadar service for geolocations for ip command.
     - Dict key to flatten its inner values.
     - Inner values to be flattened

    When:
     - Creating outputs to Demisto form geolocations for ip command.

    Then:
     Ensure values are flattened as expected
    """
    assert (
        flatten_nested_geolocation_values(
            command_test_data["geolocations_for_ip"]["response"][0],
            dict_key,
            inner_keys,
        )
        == expected
    )


@pytest.mark.parametrize(
    "properties, properties_to_enrich_dict, expected",
    [
        (
            asset_enrich_data["assets"][0]["properties"],
            ASSET_PROPERTIES_NAME_MAP,
            {"Name": {"Value": "192.168.0.1", "LastUser": "admin"}},
        ),
        (
            asset_enrich_data["assets"][0]["properties"],
            FULL_ASSET_PROPERTIES_NAMES_MAP,
            {"ComplianceNotes": {"Value": "note", "LastUser": "Adam"}},
        ),
        ([], FULL_ASSET_PROPERTIES_NAMES_MAP, {}),
    ],
)
def test_enrich_asset_properties(properties, properties_to_enrich_dict: dict, expected):
    """
    Given:
     - Properties of an asset.
     - Dict containing properties keys to enrich, and the new names of the enrichment as corresponding values.

    When:
     - Case a: Basic enrichment of properties have been asked.
     - Case b: Full enrichment of properties have been asked.
     - Case c: Full enrichment of properties have been asked, properties are empty.

    Then:
     - Case a: Ensure that only properties keys that are contained in basic enrichment are enriched.
     - Case b: Ensure that only properties keys that are contained in full enrichment are enriched.
     - Case c: Ensure that empty dict is returned
    """
    assert enrich_asset_properties(properties, properties_to_enrich_dict) == expected


@pytest.mark.parametrize(
    "enrichment, expected",
    [
        ("None", (False, False)),
        ("IPs", (True, False)),
        ("IPs And Assets", (True, True)),
    ],
)
def test_get_offense_enrichment(enrichment, expected):
    """
    Given:
     - Enrichment asked by the user.

    When:
     - Case a: Enrichment was not asked (None).
     - Case b: Enrichment asked was for IPs only.
     - Case c: Enrichment asked was for IPs and assets.

    Then:
     - Case a: Ensure False, False is returned.
     - Case b: Ensure True, False is returned.
     - Case c: Ensure True, True is returned.
    """
    assert get_offense_enrichment(enrichment) == expected


def test_add_iso_entries_to_dict():
    """
    Given:
     - Dict containing entries with epoch time.

    When:
     - Adding to entries with epoch time entries with iso time.

    Then:
     - All 'usecs' keys in the dict are replaced with 'iso time' entries with correct iso values.
     - The dict is cloned and its values are not changed, and a new one is created
    """
    tested_dict = {usec_entry: 1600000000000 for usec_entry in USECS_ENTRIES}
    tested_dict["host_name"] = "QRadar Host"
    output_dict = add_iso_entries_to_dict([tested_dict])[0]
    assert tested_dict["host_name"] == "QRadar Host"
    assert output_dict["host_name"] == "QRadar Host"
    assert all(tested_dict.get(iso_entry) == 1600000000000 for iso_entry in USECS_ENTRIES)
    assert all(output_dict.get(iso_entry) == "2020-09-13T12:26:40+00:00" for iso_entry in USECS_ENTRIES)
    assert len(tested_dict) == (1 + len(USECS_ENTRIES))
    assert len(output_dict) == (1 + len(USECS_ENTRIES))


def test_add_iso_entries_to_asset():
    """
    Given:
     - Asset.

    When:
     - Replacing epoch values with ISO values

    Then:
     - Ensure epoch values are replaced with the expected ISO values.
    """
    assets = asset_enrich_data["assets"]
    assert [add_iso_entries_to_asset(asset) for asset in assets] == asset_enrich_data["iso_transform"]


@pytest.mark.parametrize(
    "output, old_new_dict, expected",
    [
        ([{"a": 2, "c": 3}], {"a": "b"}, [{"b": 2}]),
        (
            [OFFENSE_OLD_NEW_NAMES_MAP],
            OFFENSE_OLD_NEW_NAMES_MAP,
            [{v: v for v in OFFENSE_OLD_NEW_NAMES_MAP.values()}],
        ),
        ([{"description": "bla"}], {"name": "Adam"}, [{}]),
        (
            [{"a": 1, "b": 2, "c": 3}, {"a": 4, "d": 5, "e": 6}],
            {"a": "A", "b": "B", "d": "D"},
            [{"A": 1, "B": 2}, {"A": 4, "D": 5}],
        ),
    ],
)
def test_build_final_outputs(output, old_new_dict, expected):
    """
    Given:
     - Output.
     - Dict mapping old key names to be replaced with new key names

    When:
     - Case a: Part of the keys of the output intersects with 'old_new' dictionary and some are not
     - Case b: All of the keys of the output intersects in 'old_new' dictionary.
     - Case c: No key of the output intersects with 'old_new' dictionary

    Then:
     - Case a: Correct keys are replaced (only those who intersects).
     - Case b: All of the keys are replaced (because all keys intersects).
     - Case c: No key is replaced (no intersect).
    """
    assert (build_final_outputs(output, old_new_dict)) == expected


@pytest.mark.parametrize(
    "first_headers, all_headers",
    [
        (["ID", "Description"], {"A", "B", "C", "ID", "Description"}),
        (["A"], {"A", "B"}),
    ],
)
def test_build_headers(first_headers, all_headers):
    """
    Given:
     - List of first headers to be shown in entry room.
     - Set of all of the headers to be shown in the entry room.

    When:
     - Case a: Building headers for human readable.
     - Case b: Building headers for human readable.

    Then:
     - Case a: First headers are first in the list.
     - Case b: First headers are first in the list.
    """
    assert (build_headers(first_headers, all_headers))[: len(first_headers)] == first_headers


@pytest.mark.parametrize(
    "last_run_offense_id, user_query, expected",
    [
        (1, None, 1),
        (2, "status=open or id > 4", 4),
        (6, "username_count > 2 and id > 3 or event_count < 6", 6),
        (4, "id >= 4", 4),
        (2, "id >= 4", 3),
        (32, "as4ll a4as ll5ajs 352lk aklj id     >           35 zjfzlkfj selkj", 35),
        (32, "as4ll a4as ll5ajs 352lk aklj id     >=           35 zjfzlkfj selkj", 34),
        (32, "a id     >=           35001 ", 35000),
        (1523, "closing_reason_id > 5000", 1523),
        (0, "id > 4", 4),
        (0, "id > 1", 2),
    ],
)
def test_get_minimum_id_to_fetch(last_run_offense_id, user_query, expected, mocker):
    """
    Given:
     - The highest fetched offense ID from last run.
     - The user query for fetch.

    When:
     - Fetching incidents in long time execution.

    Then:
     - Ensure that returned value is the lowest ID to fetch from.
    """
    mocker.patch.object(client, "offenses_list", return_value=[{"id": "3"}])
    assert get_minimum_id_to_fetch(last_run_offense_id, user_query, "3 days", client) == expected


@pytest.mark.parametrize(
    "outputs, key_replace_dict, expected",
    [
        (
            {"a": 2, "number_of_elements": 3, "creation_time": 1600000000000},
            REFERENCE_SETS_RAW_FORMATTED,
            [{"NumberOfElements": 3, "CreationTime": "2020-09-13T12:26:40+00:00"}],
        ),
        (
            {"a": 2, "number_of_elements": 3, "creation_time": 1600000000000},
            None,
            [
                {
                    "a": 2,
                    "number_of_elements": 3,
                    "creation_time": "2020-09-13T12:26:40+00:00",
                }
            ],
        ),
    ],
)
def test_sanitize_outputs(outputs, key_replace_dict, expected):
    """
    Given:
     - Outputs.
     - Dict, containing old names as keys, and new names as values.

    When:
     - Case a: Sanitizing outputs, 'key_replace_dict' exists.
     - Case b: Sanitizng outputs, 'key_replace_dict' does not exist.

    Then:
     - Case a: Ensure that outputs keys not included in 'key_replace_dict' are dismissed, and key names are changed.
     - Case b: Ensure that outputs are sanitized, but keys remains the same.
    """
    assert sanitize_outputs(outputs, key_replace_dict) == expected


def test_create_single_asset_for_offense_enrichment():
    """
    Given:
     - Asset to enrich

    When:
     - Enriching offense with asset values.

    Then:
     - Ensure enrichment asset object returned is as expected.
    """
    assets = asset_enrich_data["assets"]
    enriched_assets = [create_single_asset_for_offense_enrichment(asset) for asset in assets]
    assert enriched_assets == asset_enrich_data["offense_enrich"]


@pytest.mark.parametrize(
    "status_exception, status_response, results_response, search_id, expected",
    [
        (
            None,
            command_test_data["search_status_get"]["response"],
            command_test_data["search_results_get"]["response"],
            "19e90792-1a17-403b-ae5b-d0e60740b95e",
            (
                sanitize_outputs(command_test_data["search_results_get"]["response"]["events"]),
                QueryStatus.SUCCESS.value,
            ),
        ),
        (
            DemistoException("error occurred"),
            None,
            None,
            None,
            ([], QueryStatus.ERROR.value),
        ),
    ],
)
def test_poll_offense_events_with_retry(
    mocker,
    requests_mock,
    status_exception,
    status_response,
    results_response,
    search_id,
    expected,
):
    """
    Given:
     - Client to perform API calls.
     - Search ID of the query to enrich events.

    When:
     - Case a: QRadar returns a valid and terminated results to the search.
     - Case b: Error occurred in request to QRadar during poll.

    Then:
     - Case a: Ensure that expected events are returned.
     - Case b: Ensure that None is returned.
    """
    mocker.patch.object(demisto, "error")
    context_data = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
    }
    set_integration_context(context_data)
    if status_exception:
        requests_mock.get(f"{client.server}/api/ariel/searches/{search_id}", exc=status_exception)
    else:
        requests_mock.get(f"{client.server}/api/ariel/searches/{search_id}", json=status_response)
    requests_mock.get(f"{client.server}/api/ariel/searches/{search_id}/results", json=results_response)
    assert poll_offense_events(client, search_id, True, 16) == expected


@pytest.mark.parametrize(
    "search_exception, fetch_mode, search_response",
    [
        (None, "Fetch With All Events", command_test_data["search_create"]["response"]),
        (DemistoException("error occurred"), "Fetch With All Events", None),
        (
            None,
            "Fetch Correlation Events Only",
            command_test_data["search_create"]["response"],
        ),
        (DemistoException("error occurred"), "Fetch Correlation Events Only", None),
    ],
)
def test_create_search_with_retry(mocker, search_exception, fetch_mode, search_response):
    """
    Given:
     - Client to perform API calls.
     - Query for creating search in QRadar service.
    When:
     - Case a: QRadar manages to create search, fetch_mode is all events.
     - Case b: Error occurred in request to QRadar search creation, fetch_mode is all events.
     - Case c: QRadar manages to create search, fetch_mode is correlation events only.
     - Case d: Error occurred in request to QRadar search creation, fetch_mode is correlation events only.

    Then:
     - Case a: Ensure that QRadar service response is returned.
     - Case b: Ensure that None is returned.
     - Case c: Ensure that QRadar service response is returned.
     - Case d: Ensure that None is returned.
    """
    context_data = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
    }
    set_integration_context(context_data)
    offense = command_test_data["offenses_list"]["response"][0]
    if search_exception:
        mocker.patch.object(client, "search_create", side_effect=[search_exception])
    else:
        mocker.patch.object(client, "search_create", return_value=search_response)
    expected_search_id = search_response["search_id"] if search_response else QueryStatus.ERROR.value
    assert (
        create_search_with_retry(
            client,
            fetch_mode=fetch_mode,
            offense=offense,
            event_columns=event_columns_default_value,
            events_limit=20,
            max_retries=1,
        )
        == expected_search_id
    )


@pytest.mark.parametrize(
    "offense, fetch_mode, mock_search_response, poll_events_response, events_limit",
    [
        # success cases
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.correlations_events_only.value,
            command_test_data["search_create"]["response"],
            (
                sanitize_outputs(command_test_data["search_results_get"]["response"]["events"]),
                "",
            ),
            3,
        ),
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.correlations_events_only.value,
            command_test_data["search_create"]["response"],
            (
                sanitize_outputs(command_test_data["search_results_get"]["response"]["events"][:1]),
                "",
            ),
            2,
        ),
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.all_events.value,
            command_test_data["search_create"]["response"],
            (
                sanitize_outputs(command_test_data["search_results_get"]["response"]["events"]),
                "",
            ),
            3,
        ),
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.all_events.value,
            command_test_data["search_create"]["response"],
            (
                sanitize_outputs(command_test_data["search_results_get"]["response"]["events"][:1]),
                "",
            ),
            1,
        ),
        # failure cases
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.correlations_events_only.value,
            None,
            None,
            3,
        ),
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.correlations_events_only.value,
            command_test_data["search_create"]["response"],
            (
                sanitize_outputs(command_test_data["search_results_get"]["response"]["events"][:1]),
                "",
            ),
            3,
        ),
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.all_events.value,
            None,
            None,
            3,
        ),
        (
            command_test_data["offenses_list"]["response"][0],
            FetchMode.all_events.value,
            command_test_data["search_create"]["response"],
            (
                sanitize_outputs(command_test_data["search_results_get"]["response"]["events"][:1]),
                "",
            ),
            3,
        ),
    ],
)
def test_enrich_offense_with_events(
    mocker,
    offense: dict,
    fetch_mode: FetchMode,
    mock_search_response: dict,
    poll_events_response,
    events_limit,
):
    """
    Given:
     - Offense to enrich with events.
     - Fetch modes of the events.

    When:
    Success cases:
     - Case a: Fetch mode is 'correlations_events_only', number of events returned equals to event count, lower than
               'events_limit'.
     - Case b: Fetch mode is 'correlations_events_only', number of events returned is lower than event count, but equals
               to 'events_limit'.
     - Case c: Fetch mode is 'all_events', number of events returned equals to event count, lower than 'events_limit'.
     - Case d: Fetch mode is 'all_events', number of events returned is lower than event count, but equals
               to 'events_limit'.
     Failure cases:
     - Case a: Fetch mode is 'correlations_events_only', fails to enrich offense (fails to create search).
     - Case b: Fetch mode is 'correlations_events_only', fails to enrich offense (not enough events).
     - Case c: Fetch mode is 'all_events', fails to enrich offense (fails to create search).
     - Case d: Fetch mode is 'all_events', fails to enrich offense (not enough events).


    Then:
        For success cases:
        - Ensure additional where clause is added to the query if fetch mode is 'correlations_events_only'.
        - Ensure expected events are returned.
        - Ensure expected count of events are returned.
        - Ensure poll events is queried with the expected search ID.
        For failure cases:
        - Ensure additional where clause is added to the query if fetch mode is 'correlations_events_only'.
        - Ensure empty list of events are returned.
        - Ensure poll events is queried with the expected search ID, if search ID succeeded.
    """
    offense = offense.copy()
    context_data = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
    }
    set_integration_context(context_data)
    poll_events = poll_events_response[0] if poll_events_response else []
    num_events = sum(event.get("eventcount", 1) for event in poll_events)
    if poll_events and num_events >= min(events_limit, offense.get("event_count")):
        events = poll_events[: min(events_limit, len(poll_events))] if poll_events else []
        num_events = sum(event.get("eventcount", 1) for event in poll_events)
        expected_offense: dict[str, list | int] = dict(
            offense,
            events=events,
            events_fetched=num_events,
        )
    else:
        expected_offense = dict(
            offense,
            events_fetched=num_events,
        )
        if poll_events:
            expected_offense = dict(expected_offense, events=poll_events)
    expected_id = mock_search_response["search_id"] if mock_search_response else QueryStatus.ERROR.value
    mocker.patch.object(QRadar_v3, "create_search_with_retry", return_value=expected_id)
    poll_events_mock = mocker.patch.object(QRadar_v3, "poll_offense_events_with_retry", return_value=poll_events_response)
    is_all_events_fetched = mock_search_response and (
        (num_events >= min(offense["event_count"], events_limit)) or (fetch_mode == FetchMode.correlations_events_only.value)
    )
    mocker.patch.object(QRadar_v3, "is_all_events_fetched", return_value=is_all_events_fetched)
    enriched_offense, is_success = enrich_offense_with_events(
        client,
        offense,
        fetch_mode,
        event_columns_default_value,
        events_limit=events_limit,
    )
    assert "mirroring_events_message" in enriched_offense
    del enriched_offense["mirroring_events_message"]
    if mock_search_response:
        assert is_success == is_all_events_fetched
        assert poll_events_mock.call_args[0][1] == mock_search_response["search_id"]
    else:
        assert not is_success
    if not expected_offense.get("events"):
        expected_offense["events"] = []
    assert enriched_offense == expected_offense


def test_enrich_offense_with_events_initial_sleep_after_search_creation(mocker):
    """
    Given:
     - An offense to enrich with events.
     - create_search_with_retry returns a valid search ID (not an error).

    When:
     - enrich_offense_with_events is called.

    Then:
     - Ensure time.sleep(FETCH_INITIAL_SLEEP) is called AFTER create_search_with_retry
       and BEFORE poll_offense_events_with_retry.
    """

    offense = {"id": 1, "start_time": 1000, "event_count": 5}
    context_data = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
    }
    set_integration_context(context_data)

    # Use a shared call tracker to verify ordering across different mocks
    call_order: list[str] = []

    mock_create_search = mocker.patch.object(
        QRadar_v3,
        "create_search_with_retry",
        side_effect=lambda *args, **kwargs: (
            call_order.append("create_search_with_retry"),
            "some_search_id",
        )[1],
    )
    mock_sleep = mocker.patch(
        "QRadar_v3.time.sleep",
        side_effect=lambda *args, **kwargs: call_order.append(f"time.sleep({args[0]})"),
    )
    mock_poll = mocker.patch.object(
        QRadar_v3,
        "poll_offense_events_with_retry",
        side_effect=lambda *args, **kwargs: (
            call_order.append("poll_offense_events_with_retry"),
            ([], ""),
        )[1],
    )
    mocker.patch.object(QRadar_v3, "is_all_events_fetched", return_value=True)
    mocker.patch.object(QRadar_v3, "update_events_mirror_message", return_value="")
    mocker.patch("QRadar_v3.time.time", return_value=0)

    enrich_offense_with_events(
        client,
        offense,
        FetchMode.all_events.value,
        event_columns_default_value,
        events_limit=20,
    )

    # Verify create_search was called
    mock_create_search.assert_called_once()
    # Verify sleep was called with FETCH_INITIAL_SLEEP (1)
    mock_sleep.assert_any_call(QRadar_v3.FETCH_INITIAL_SLEEP)
    # Verify poll was called
    mock_poll.assert_called_once()

    # Verify ordering: create_search -> sleep(FETCH_INITIAL_SLEEP) -> poll
    assert call_order.index("create_search_with_retry") < call_order.index(f"time.sleep({QRadar_v3.FETCH_INITIAL_SLEEP})")
    assert call_order.index(f"time.sleep({QRadar_v3.FETCH_INITIAL_SLEEP})") < call_order.index("poll_offense_events_with_retry")


def test_create_incidents_from_offenses():
    """
    Given:
     - List of offenses.
     - Incident type.

    When:
     - Creating incidents by the offenses with the corresponding incident type.

    Then:
     - Ensure expected incidents are created.
    """
    offenses = command_test_data["offenses_list"]["enrich_offenses_result"]
    assert create_incidents_from_offenses(offenses, "QRadar Incident") == [
        {
            "name": f"""{offense.get("id")} {offense.get("description", "")}""",
            "rawJSON": json.dumps(offense),
            "occurred": get_time_parameter(offense.get("start_time"), iso_format=True),
            "type": "QRadar Incident",
            "haIntegrationEventID": str(offense.get("id")),
        }
        for offense in offenses
    ]


@pytest.mark.parametrize(
    "enrich_func, mock_func_name, args, mock_response, expected",
    [
        (
            get_offense_types,
            "offense_types",
            {
                "client": client,
                "offenses": [
                    {"offense_type": 1, "offense_name": "offense1"},
                    {"offense_type": 2, "offense_name": "offense2"},
                ],
            },
            [
                {"id": 1, "name": "Scheduled Search"},
                {"id": 2, "name": "Destination IP Identity"},
            ],
            {1: "Scheduled Search", 2: "Destination IP Identity"},
        ),
        (
            get_offense_closing_reasons,
            "closing_reasons_list",
            {
                "client": client,
                "offenses": [
                    {"closing_reason_id": 3, "offense_name": "offense1"},
                    {"closing_reason_id": 4, "offense_name": "offense2"},
                ],
            },
            [{"id": 3, "text": "Non-Issue"}, {"id": 4, "text": "Policy Violation"}],
            {3: "Non-Issue", 4: "Policy Violation"},
        ),
        (
            get_domain_names,
            "domains_list",
            {
                "client": client,
                "outputs": [
                    {"domain_id": 5, "offense_name": "offense1"},
                    {"domain_id": 6, "offense_name": "offense2"},
                ],
            },
            [{"id": 5, "name": "domain1"}, {"id": 6, "name": "domain2"}],
            {5: "domain1", 6: "domain2"},
        ),
        (
            get_rules_names,
            "rules_list",
            {
                "client": client,
                "offenses": [
                    {"rules": [{"id": 7}, {"id": 8}], "offense_name": "offense1"},
                    {"rules": [{"id": 9}], "offense_name": "offense2"},
                ],
            },
            [
                {"id": 7, "name": "Devices with High Event Rates"},
                {"id": 8, "name": "Excessive Database Connections"},
                {
                    "id": 9,
                    "name": "Anomaly: Excessive Firewall Accepts Across Multiple Hosts",
                },
            ],
            {
                7: "Devices with High Event Rates",
                8: "Excessive Database Connections",
                9: "Anomaly: Excessive Firewall Accepts Across Multiple Hosts",
            },
        ),
        (
            get_offense_addresses,
            "get_addresses",
            {
                "client": client,
                "offenses": [
                    {"source_address_ids": [1, 2], "offense_name": "offense1"},
                    {"source_address_ids": [3, 4], "offense_name": "offense2"},
                ],
                "is_destination_addresses": False,
            },
            [
                {"id": 1, "source_ip": "1.2.3.4"},
                {"id": 2, "source_ip": "1.2.3.5"},
                {"id": 3, "source_ip": "192.168.1.3"},
                {"id": 4, "source_ip": "192.168.0.2"},
            ],
            {1: "1.2.3.4", 2: "1.2.3.5", 3: "192.168.1.3", 4: "192.168.0.2"},
        ),
        (
            get_offense_addresses,
            "get_addresses",
            {
                "client": client,
                "offenses": [
                    {
                        "local_destination_address_ids": [1, 2],
                        "offense_name": "offense1",
                    },
                    {
                        "local_destination_address_ids": [3, 4],
                        "offense_name": "offense2",
                    },
                ],
                "is_destination_addresses": True,
            },
            [
                {"id": 1, "local_destination_ip": "1.2.3.4"},
                {"id": 2, "local_destination_ip": "1.2.3.5"},
                {"id": 3, "local_destination_ip": "192.168.1.3"},
                {"id": 4, "local_destination_ip": "192.168.0.2"},
            ],
            {1: "1.2.3.4", 2: "1.2.3.5", 3: "192.168.1.3", 4: "192.168.0.2"},
        ),
        (
            enrich_offense_with_assets,
            "assets_list",
            {"client": client, "offense_ips": ["8.8.8.8", "1.1.1.1", "2.2.2.2"]},
            asset_enrich_data["assets"],
            asset_enrich_data["offense_enrich"],
        ),
        (
            enrich_assets_results,
            "domains_list",
            {
                "client": client,
                "assets": asset_enrich_data["assets"],
                "full_enrichment": asset_enrich_data["case_one"]["full_enrichment"],
            },
            asset_enrich_data["domain_mock_response"],
            asset_enrich_data["case_one"]["expected"],
        ),
        (
            enrich_assets_results,
            "domains_list",
            {
                "client": client,
                "assets": asset_enrich_data["assets"],
                "full_enrichment": asset_enrich_data["case_two"]["full_enrichment"],
            },
            asset_enrich_data["domain_mock_response"],
            asset_enrich_data["case_two"]["expected"],
        ),
        # Empty cases
        (
            get_offense_types,
            "offense_types",
            {
                "client": client,
                "offenses": [
                    {"offense_name": "offense1"},
                    {"offense_name": "offense2"},
                ],
            },
            None,
            {},
        ),
        (
            get_offense_closing_reasons,
            "closing_reasons_list",
            {
                "client": client,
                "offenses": [
                    {"offense_name": "offense1"},
                    {"offense_name": "offense2"},
                ],
            },
            None,
            {},
        ),
        (
            get_domain_names,
            "domains_list",
            {
                "client": client,
                "outputs": [{"offense_name": "offense1"}, {"offense_name": "offense2"}],
            },
            None,
            {},
        ),
        (
            get_rules_names,
            "rules_list",
            {
                "client": client,
                "offenses": [
                    {"offense_name": "offense1"},
                    {"offense_name": "offense2"},
                ],
            },
            None,
            {},
        ),
        (
            get_offense_addresses,
            "get_addresses",
            {
                "client": client,
                "offenses": [
                    {"source_address_ids": [], "offense_name": "offense1"},
                    {"source_address_ids": [], "offense_name": "offense2"},
                ],
                "is_destination_addresses": False,
            },
            None,
            {},
        ),
        (
            get_offense_addresses,
            "get_addresses",
            {
                "client": client,
                "offenses": [
                    {"local_destination_address_ids": [], "offense_name": "offense1"},
                    {"local_destination_address_ids": [], "offense_name": "offense2"},
                ],
                "is_destination_addresses": True,
            },
            None,
            {},
        ),
        (
            enrich_assets_results,
            "domains_list",
            {
                "client": client,
                "assets": asset_enrich_data["empty_case"]["assets"],
                "full_enrichment": False,
            },
            asset_enrich_data["domain_mock_response"],
            asset_enrich_data["empty_case"]["expected_basic_enrichment"],
        ),
        (
            enrich_assets_results,
            "domains_list",
            {
                "client": client,
                "assets": asset_enrich_data["empty_case"]["assets"],
                "full_enrichment": True,
            },
            asset_enrich_data["domain_mock_response"],
            asset_enrich_data["empty_case"]["expected_full_enrichment"],
        ),
    ],
)
def test_outputs_enriches(mocker, enrich_func, mock_func_name, args, mock_response, expected):
    """
    Given:
     - Function to do enrichment.
     - List of outputs.

    When:
     - Calling function to return the dict containing values of the enrichment.

    Then:
     - Ensure dict containing the enrichment is as expected.
    """
    mock_func = mocker.patch.object(client, mock_func_name, return_value=mock_response)
    mock_func.__name__ = mock_func.__name  # magic mock objects have different attributes from actual functions
    res = enrich_func(**args)
    assert res == expected


@pytest.mark.parametrize(
    "command_func, command_name",
    [
        (qradar_closing_reasons_list_command, "closing_reasons_list"),
        (qradar_offense_notes_list_command, "offense_notes_list"),
        (qradar_offense_notes_create_command, "offense_notes_create"),
        (qradar_rules_list_command, "rules_list"),
        (qradar_rule_groups_list_command, "rule_groups_list"),
        (qradar_saved_searches_list_command, "saved_searches_list"),
        (qradar_searches_list_command, "searches_list"),
        (qradar_search_create_command, "search_create"),
        (qradar_search_status_get_command, "search_status_get"),
        (qradar_search_results_get_command, "search_results_get"),
        (qradar_search_cancel_command, "search_cancel"),
        (qradar_reference_sets_list_command, "reference_sets_list"),
        (qradar_reference_set_create_command, "reference_set_create"),
        (qradar_reference_set_delete_command, "reference_set_delete"),
        (qradar_reference_set_value_delete_command, "reference_set_value_delete"),
        (qradar_reference_set_value_upsert_command, "reference_set_bulk_load"),
        (qradar_domains_list_command, "domains_list"),
        (qradar_geolocations_for_ip_command, "geolocations_for_ip"),
        (qradar_get_custom_properties_command, "custom_properties"),
        (qradar_remote_network_cidr_list_command, "get_remote_network_cidr"),
        (
            qradar_remote_network_cidr_update_command,
            "create_and_update_remote_network_cidr",
        ),
        (
            qradar_remote_network_deploy_execution_command,
            "remote_network_deploy_execution",
        ),
        (qradar_indicators_upload_command, "reference_set_bulk_load"),
        (qradar_reference_maps_list_command, "reference_maps_list"),
    ],
)
def test_commands(mocker, command_func: Callable[[Client, dict], CommandResults], command_name: str):
    """
    Given:
     - Command function.
     - Demisto arguments.

    When:
     - Executing a command

    Then:
     - Ensure that the expected CommandResults object is returned by the command function.
    """
    mocker.patch.object(QRadar_v3.ScheduledCommand, "raise_error_if_not_supported")
    args = command_test_data[command_name].get("args", {})
    response = command_test_data[command_name]["response"]
    expected = command_test_data[command_name]["expected"]
    expected_command_results = CommandResults(
        outputs_prefix=expected.get("outputs_prefix"),
        outputs_key_field=expected.get("outputs_key_field"),
        outputs=expected.get("outputs"),
        raw_response=response,
    )
    mocker.patch.object(client, command_name, return_value=response)
    if command_func == qradar_search_create_command:
        results = command_func(client, {}, args)
    elif command_func == qradar_reference_set_value_upsert_command:
        results = command_func(args, client, {"api_version": "14"})
    elif command_func == qradar_indicators_upload_command:
        mocker.patch.object(
            IndicatorsSearcher,
            "search_indicators_by_version",
            return_value={
                "iocs": [
                    {"value": "test1", "indicator_type": "ip"},
                    {"value": "test2", "indicator_type": "ip"},
                    {"value": "test3", "indicator_type": "ip"},
                ]
            },
        )
        mocker.patch.object(client, "reference_sets_list")
        results = command_func(args, client, {"api_version": "14"})

    else:
        results = command_func(client, args)

    assert results.outputs_prefix == expected_command_results.outputs_prefix
    assert results.outputs_key_field == expected_command_results.outputs_key_field
    assert results.outputs == expected_command_results.outputs
    assert results.raw_response == expected_command_results.raw_response


@pytest.mark.parametrize(
    "command_func, command_name, enrichment_func_name",
    [
        (qradar_offenses_list_command, "offenses_list", "enrich_offenses_result"),
        (qradar_offense_update_command, "offense_update", "enrich_offenses_result"),
        (qradar_assets_list_command, "assets_list", "enrich_assets_results"),
    ],
)
def test_commands_with_enrichment(
    mocker,
    command_func: Callable[[Client, dict], CommandResults],
    command_name: str,
    enrichment_func_name: str,
):
    """
    Given:
     - Command function that requires another API calls for enrichment.
     - Demisto arguments.

    When:
     - Executing a command.

    Then:
     - Ensure that the expected CommandResults object is returned by the command function.
    """
    response = command_test_data[command_name]["response"]
    expected = command_test_data[command_name]["expected"]
    args = command_test_data[command_name].get("args", {})
    enriched_response = command_test_data[command_name][enrichment_func_name]
    expected_command_results = CommandResults(
        outputs_prefix=expected.get("outputs_prefix"),
        outputs_key_field=expected.get("outputs_key_field"),
        outputs=expected.get("outputs"),
        raw_response=response,
    )
    mocker.patch.object(client, command_name, return_value=response)
    mocked_enrich = mocker.patch.object(QRadar_v3, enrichment_func_name, return_value=enriched_response)

    results = command_func(client, args)

    assert mocked_enrich.call_args[0][1] == response

    assert results.outputs_prefix == expected_command_results.outputs_prefix
    assert results.outputs_key_field == expected_command_results.outputs_key_field
    assert results.outputs == expected_command_results.outputs
    assert results.raw_response == expected_command_results.raw_response


def mock_mirroring_response(filter_, **kwargs):
    if "status=closed" in filter_:
        return list(
            filter(
                lambda x: x["status"] == "CLOSED",
                command_test_data["get_modified_remote_data"]["response"],
            )
        )
    else:
        return list(
            filter(
                lambda x: x["status"] != "CLOSED",
                command_test_data["get_modified_remote_data"]["response"],
            )
        )


def test_get_modified_remote_data_command(mocker):
    """
    Given:
     - QRadar client.
     - Demisto arguments.

    When:
     - Command 'get-modified-remote-data' is being called.

    Then:
     - Ensure that command outputs the IDs of the offenses to update.
    """
    set_integration_context(
        {
            MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
            MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
            "last_update": 1,
        }
    )
    expected = GetModifiedRemoteDataResponse(list(map(str, command_test_data["get_modified_remote_data"]["outputs"])))
    mocker.patch.object(client, "offenses_list", side_effect=mock_mirroring_response)
    result = get_modified_remote_data_command(client, {}, command_test_data["get_modified_remote_data"]["args"])
    assert {int(id_) for id_ in expected.modified_incident_ids} == {int(id_) for id_ in result.modified_incident_ids}


@pytest.mark.parametrize(
    "params, offense, enriched_offense, note_response, expected",
    [
        (
            {},
            command_test_data["get_remote_data"]["response"],
            command_test_data["get_remote_data"]["enrich_offenses_result"],
            None,
            GetRemoteDataResponse(
                sanitize_outputs(command_test_data["get_remote_data"]["enrich_offenses_result"])[0],
                [],
            ),
        ),
        (
            {},
            command_test_data["get_remote_data"]["closed"],
            command_test_data["get_remote_data"]["enrich_closed_offense"],
            None,
            GetRemoteDataResponse(
                sanitize_outputs(command_test_data["get_remote_data"]["enrich_closed_offense"])[0],
                [],
            ),
        ),
        (
            {"close_incident": True},
            command_test_data["get_remote_data"]["closed"],
            command_test_data["get_remote_data"]["enrich_closed_offense"],
            [],
            GetRemoteDataResponse(
                sanitize_outputs(command_test_data["get_remote_data"]["enrich_closed_offense"])[0],
                [
                    {
                        "Type": EntryType.NOTE,
                        "Contents": {
                            "dbotIncidentClose": True,
                            "closeReason": "False-Positive, Tuned",
                            "closeNotes": "From QRadar: False-Positive, Tuned",
                        },
                        "ContentsFormat": EntryFormat.JSON,
                    }
                ],
            ),
        ),
        (
            {"close_incident": True},
            command_test_data["get_remote_data"]["closed"],
            command_test_data["get_remote_data"]["enrich_closed_offense"],
            [{"note_text": "This offense was closed with reason: False-Positive, Tuned."}],
            GetRemoteDataResponse(
                sanitize_outputs(command_test_data["get_remote_data"]["enrich_closed_offense"])[0],
                [
                    {
                        "Type": EntryType.NOTE,
                        "Contents": {
                            "dbotIncidentClose": True,
                            "closeReason": "False-Positive, Tuned",
                            "closeNotes": "From QRadar: This offense was closed with reason: False-Positive, Tuned.",
                        },
                        "ContentsFormat": EntryFormat.JSON,
                    }
                ],
            ),
        ),
        (
            {"close_incident": True},
            command_test_data["get_remote_data"]["closed"],
            command_test_data["get_remote_data"]["enrich_closed_offense"],
            [
                {
                    "note_text": "This offense was closed with reason: False-Positive, Tuned. Notes: "
                    "Closed because it is on our white list."
                }
            ],
            GetRemoteDataResponse(
                sanitize_outputs(command_test_data["get_remote_data"]["enrich_closed_offense"])[0],
                [
                    {
                        "Type": EntryType.NOTE,
                        "Contents": {
                            "dbotIncidentClose": True,
                            "closeReason": "False-Positive, Tuned",
                            "closeNotes": "From QRadar: This offense was closed with reason: "
                            "False-Positive, Tuned. Notes: Closed because it is on our "
                            "white list.",
                        },
                        "ContentsFormat": EntryFormat.JSON,
                    }
                ],
            ),
        ),
    ],
)
def test_get_remote_data_command(
    mocker,
    params,
    offense: dict,
    enriched_offense,
    note_response,
    expected: GetRemoteDataResponse,
):
    """
    Given:
     - QRadar client.
     - Demisto params.
     - Demisto arguments.

    When:
     - Case a: Offense updated, not closed, no events.
     - Case b: Offense updated, closed, no events, close_incident is false.
     - Case c: Offense updated, closed, no events, close_incident is true, close was made through API call (no note).
     - Case d: Offense updated, closed, no events, close_incident is true, close was made through QRadar UI, empty note.
     - Case e: Offense updated, closed, no events, close_incident is true, close was made through QRadar UI, with note.

    Then:
     - Case a: Ensure that offense is returned as is.
     - Case b: Ensure that offense is returned as is.
     - Case c: Ensure that offense is returned, along with expected entries.
     - Case d: Ensure that offense is returned, along with expected entries.
     - Case e: Ensure that offense is returned, along with expected entries.
    """
    set_integration_context(
        {
            MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
            MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
            "last_update": 1,
        }
    )
    mocker.patch.object(client, "offenses_list", return_value=offense)
    mocker.patch.object(QRadar_v3, "enrich_offenses_result", return_value=enriched_offense)
    if "close_incident" in params:
        mocker.patch.object(
            client,
            "closing_reasons_list",
            return_value=command_test_data["closing_reasons_list"]["response"][0],
        )
    if note_response is not None:
        mocker.patch.object(client, "offense_notes_list", return_value=note_response)
    result = get_remote_data_command(client, params, {"id": offense.get("id"), "lastUpdate": 1})
    expected.mirrored_object["last_mirror_in_time"] = result.mirrored_object["last_mirror_in_time"]
    expected.mirrored_object["events_fetched"] = 0
    assert result.mirrored_object == expected.mirrored_object
    assert result.entries == expected.entries


@pytest.mark.parametrize(
    "ip_address, expected",
    [
        ("1.2.3.4", True),
        ("1.2.3.4.765", False),
        ("", False),
        ("192.0.0.1", True),
        ("::1", True),
        ("2001:0db8:0a0b:12f0:0000:0000:0000:0001", True),
        ("1", False),
    ],
)
def test_is_valid_ip(ip_address: str, expected: bool):
    """
    Given:
     - IP address returned by QRadar, could be valid and could be invalid.

    When:
     - Checking whether IP is valid or not.

    Then:
     - Ensure expected bool is returned indicating whether IP is valid.
    """
    assert is_valid_ip(ip_address) == expected


def test_validate_long_running_params():
    """
    Given:
     - Cortex XSOAR params.

    When:
     - Running long running execution.

    Then:
     - Ensure that error is thrown.
    """
    from QRadar_v3 import LONG_RUNNING_REQUIRED_PARAMS, validate_long_running_params

    for param_name, _param_value in LONG_RUNNING_REQUIRED_PARAMS.items():
        params_without_required_param = {k: v for k, v in LONG_RUNNING_REQUIRED_PARAMS.items() if k is not param_name}
        with pytest.raises(DemistoException):
            validate_long_running_params(params_without_required_param)


@pytest.mark.parametrize(
    "command_func, command_name",
    [
        (qradar_ips_source_get_command, "source_ip"),
        (qradar_ips_local_destination_get_command, "local_destination"),
    ],
)
def test_ip_commands(mocker, command_func: Callable[[Client, dict], CommandResults], command_name: str):
    """
    Given:
     - Command function.
     - Demisto arguments.

    When:
     - Executing a command

    Then:
     - Ensure that the expected CommandResults object is returned by the command function.
    """
    args = {}
    response = ip_command_test_data[command_name]["response"]
    expected = ip_command_test_data[command_name]["expected"]
    expected_command_results = CommandResults(
        outputs_prefix=expected.get("outputs_prefix"),
        outputs_key_field=expected.get("outputs_key_field"),
        outputs=expected.get("outputs"),
        raw_response=response,
    )
    mocker.patch.object(client, "get_addresses", return_value=response)

    results = command_func(client, args)

    assert results.outputs_prefix == expected_command_results.outputs_prefix
    assert results.outputs_key_field == expected_command_results.outputs_key_field
    assert results.outputs == expected_command_results.outputs
    assert results.raw_response == expected_command_results.raw_response


class MockResults:
    def __init__(self, value):
        self.value = value

    def result(self, timeout=None):
        return self.value


def test_get_modified_with_events(mocker):
    """
    Given:
        Context data with mirrored offenses, queried and finished.

    When:
        Calling get_modified_with_events.

    Then:
        Ensure that finished queries goes to finished queue,
        and modified incidents returns the modified offenses and the finished queries.
    """
    context_data = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {
            "1": "123",
            "2": "456",
            "10": QueryStatus.WAIT.value,
        },
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {"3": "789", "4": "012"},
        MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
    }
    expected_updated_context = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {"2": "456", "10": "555"},
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {"3": "789", "4": "012", "1": "123"},
        LAST_MIRROR_KEY: 3444,
        MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
        LAST_MIRROR_CLOSED_KEY: 3444,
        SAMPLE_INCIDENTS_KEY: [],
    }
    set_integration_context(context_data)
    status = {
        "123": {"status": "COMPLETED"},
        "456": {"status": "WAIT"},
        "555": {"status": "PENDING"},
    }

    mocker.patch.object(
        client,
        "offenses_list",
        return_value=[{"id": 6, "last_persisted_time": "3444", "close_time": "3444"}],
    )
    mocker.patch.object(QRadar_v3, "create_events_search", return_value="555")
    mocker.patch.object(client, "search_status_get", side_effect=lambda offense_id: status[offense_id])
    modified = get_modified_remote_data_command(client, {"mirror_options": MIRROR_OFFENSE_AND_EVENTS}, {"lastUpdate": "0"})
    assert set(modified.modified_incident_ids) == {"1", "6"}
    assert get_integration_context() == expected_updated_context


@pytest.mark.parametrize("offense_id", ["1", "2", "3", "4", "5", "10"])
def test_remote_data_with_events(mocker, offense_id):
    """
    Given:
        - Offense ID.

    When:
        - Calling get_remote_data_command with offense ID after `get-modified`

    Then:
        - Ensure that the offense data is returned and context_data is updated.
    """
    context_data = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {
            "1": "123",
            "2": "456",
            "10": QueryStatus.WAIT.value,
        },
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {"3": "789", "4": "012"},
        MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
    }
    set_integration_context(copy.deepcopy(context_data))

    mocker.patch.object(QRadar_v3, "create_events_search", return_value="555")

    # we expect the total events fetched to be the sum of `eventcount`, meaning 5 + int(offense_id)
    events = {
        "events": [
            {"eventcount": int(offense_id)},
            {"eventcount": 2},
            {"eventcount": 3},
        ]
    }
    mocker.patch.object(client, "search_results_get", return_value=events)
    mocker.patch.object(client, "search_status_get", return_value={"status": "EXECUTE"})
    offense = {"id": offense_id}
    mocker.patch.object(client, "offenses_list", return_value=offense)
    if offense_id in context_data[MIRRORED_OFFENSES_FINISHED_CTX_KEY]:
        offense_data = get_remote_data_command(
            client,
            {"mirror_options": MIRROR_OFFENSE_AND_EVENTS},
            {"id": offense_id, "lastUpdate": "0"},
        ).mirrored_object

    else:
        # if not finished we expect to get an exception
        with pytest.raises(DemistoException):
            get_remote_data_command(
                client,
                {"mirror_options": MIRROR_OFFENSE_AND_EVENTS},
                {"id": offense_id, "lastUpdate": "0"},
            )

    updated_context = get_integration_context()
    if offense_id in context_data[MIRRORED_OFFENSES_FINISHED_CTX_KEY]:
        # offense is already finished, so we expect it to being deleted from the context
        assert offense_id not in updated_context[MIRRORED_OFFENSES_FINISHED_CTX_KEY]
        assert offense_data.get("events") == events["events"]
        expected_events_fetched = 5 + int(offense_id)
        assert offense_data.get("events_fetched") == expected_events_fetched
        assert updated_context[MIRRORED_OFFENSES_FETCHED_CTX_KEY][offense_id] == expected_events_fetched

    elif offense_id not in context_data[MIRRORED_OFFENSES_QUERIED_CTX_KEY] or (
        offense_id in context_data[MIRRORED_OFFENSES_QUERIED_CTX_KEY]
        and context_data[MIRRORED_OFFENSES_QUERIED_CTX_KEY][offense_id] == QueryStatus.WAIT.value
    ):
        # offense is not yet queried, so we expect it to be added to the context
        assert updated_context[MIRRORED_OFFENSES_QUERIED_CTX_KEY][offense_id] == "555"
    else:
        # offense is unchanged, so we expect it to be unchanged in the context
        assert offense_id in updated_context[MIRRORED_OFFENSES_QUERIED_CTX_KEY]


def test_qradar_remote_network_cidr_create_command(mocker):
    """
    Given:
        - A network CIDR to create.

    When:
        - Calling qradar_remote_network_cidr_create_command.

    Then:
        - Ensure the correct request was called and the correct response is returned.
    """
    expected_response_from_api = {
        "name": "test_name",
        "description": "description",
        "cidrs": ["1.2.3.4/32", "8.8.8.8/24"],
        "id": 12,
        "group": "test_group",
    }

    mocker.patch.object(
        client,
        "create_and_update_remote_network_cidr",
        return_value=expected_response_from_api,
    )

    res = qradar_remote_network_cidr_create_command(
        client,
        {
            "name": "test_name",
            "description": "description",
            "cidrs": "1.2.3.4/32,8.8.8.8/24",
            "group": "test_group",
        },
    )

    assert expected_response_from_api == res.raw_response
    assert "| description | test_group | 12 | test_name |" in res.readable_output


def test_qradar_remote_network_cidr_delete_command(mocker):
    expected_command_result = command_test_data["remote_network_cidr_delete"]["readable_output"]

    mocker.patch.object(client, "delete_remote_network_cidr", return_value=b"")
    result = qradar_remote_network_cidr_delete_command(client, {"id": "46"})

    assert result.readable_output == expected_command_result


@pytest.mark.parametrize(
    "test_case_data",
    [
        (ctx_test_data["ctx_compatible"]["empty_ctx_no_mirroring_two_loops_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offense_two_loops_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offense_and_events_two_loops_offenses"]),
        (ctx_test_data["ctx_compatible"]["no_mirroring_two_offenses_loop"]),
        (ctx_test_data["ctx_compatible"]["mirror_offense_two_offenses_loop"]),
        (ctx_test_data["ctx_compatible"]["mirror_offense_and_events_two_offenses_loop"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_no_mirroring_first_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offense_first_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offense_and_events_first_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["no_mirroring_first_offenses_loop"]),
        (ctx_test_data["ctx_compatible"]["mirror_offense_first_offenses_loop"]),
        (ctx_test_data["ctx_compatible"]["mirror_offense_and_events_first_offenses_loop"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_no_mirroring_second_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offenses_second_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offenses_and_events_second_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["no_mirroring_second_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["mirror_offenses_second_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["mirror_offenses_and_events_second_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_no_mirroring_no_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offenses_no_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["empty_ctx_mirror_offenses_and_events_no_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["no_mirroring_no_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["mirror_offense_no_loop_offenses"]),
        (ctx_test_data["ctx_compatible"]["mirror_offense_and_events_no_loop_offenses"]),
    ],
)
def test_integration_context_during_run(test_case_data, mocker):
    mocker.patch.object(QRadar_v3, "LAST_FETCHED_ID", 0)
    """
    Given:
    - Cortex XSOAR parameters.

    When:
    - Performing `long-running-execution` command

    Then:
    - Assure the whole flow of managing the context is as expected.
    1) Call to change_ctx_to_be_compatible_with_retry is performed.
    2) Resetting the mirroring events variables.
    3) Performing long-running loop.
    4) Assuring context is as expected after first loop.
    5) Performing another long-running loop.
    6) Assure context is as expected after the second loop.

    Cases:
    a) Integration ctx is empty (first instance run), no mirroring.
    b) Integration ctx is empty (first instance run), mirroring of offense only.
    c) Integration ctx is empty (first instance run), mirroring offense with events.
    a, b, c are only relevant for cases where the integration context is compatible with retries, as empty integration
    context is always compatible with retries.
    d) Integration context is not empty, no mirroring.
    e) Integration context is not empty, mirroring of offense only.
    f) Integration context is not empty, mirroring offense with events.

    All those cases will be tested where:
    A) With init integration context not compatible with retry.
    B) With init integration context compatible with retry.
    And for one of A, B, checks the following:
        1) In both loop runs, offenses were fetched.
        2) Only in first loop run offenses were fetched.
        3) Only in second loop run offenses were fetched.
        4) In both loop runs no offenses were fetched.
    """
    mirror_direction = test_case_data["mirror_direction"]
    mirror_options = test_case_data["mirror_options"]

    init_context = test_case_data["init_context"].copy()
    if mirror_options == MIRROR_OFFENSE_AND_EVENTS:
        init_context |= {
            MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
            MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
            MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
            LAST_FETCH_KEY: init_context.get(LAST_FETCH_KEY, 0),
            SAMPLE_INCIDENTS_KEY: init_context.get(SAMPLE_INCIDENTS_KEY, []),
        }
    else:
        init_context |= {
            LAST_FETCH_KEY: init_context.get(LAST_FETCH_KEY, 0),
            SAMPLE_INCIDENTS_KEY: init_context.get(SAMPLE_INCIDENTS_KEY, []),
        }

    set_integration_context(init_context)
    if is_offenses_first_loop := test_case_data["offenses_first_loop"]:
        first_loop_offenses_with_success = ctx_test_data["offenses_first_loop"]
        first_loop_offenses_with_events = [
            (dict(offense, events=ctx_test_data["events"]), is_success)
            for offense, is_success in first_loop_offenses_with_success
        ]
        first_loop_offenses = [offense for offense, _ in first_loop_offenses_with_success]
        mocker.patch.object(client, "offenses_list", return_value=first_loop_offenses)
        mocker.patch.object(QRadar_v3, "enrich_offenses_result", return_value=first_loop_offenses)
        enrich_mock = mocker.patch.object(QRadar_v3, "enrich_offense_with_events")
        enrich_mock.side_effect = first_loop_offenses_with_events
        expected_ctx_first_loop = ctx_test_data["context_data_first_loop_default"].copy()
    else:
        mocker.patch.object(client, "offenses_list", return_value=[])
        expected_ctx_first_loop = ctx_test_data["context_data_after_retry_compatible"].copy()

    first_loop_ctx_not_default_values = test_case_data.get("first_loop_ctx_not_default_values", {})
    for k, v in first_loop_ctx_not_default_values.items():
        expected_ctx_first_loop[k] = v

    perform_long_running_loop(
        client=client,
        offenses_per_fetch=2,
        fetch_mode="Fetch With All Events",
        user_query="id > 5",
        events_columns="QIDNAME(qid), LOGSOURCENAME(logsourceid)",
        events_limit=3,
        ip_enrich=False,
        asset_enrich=False,
        incident_type=None,
        mirror_direction=mirror_direction,
        first_fetch="3 days",
        mirror_options=mirror_options,
        assets_limit=100,
        long_running_container_id="12345",
    )
    if mirror_options == MIRROR_OFFENSE_AND_EVENTS:
        expected_ctx_first_loop.update(
            {
                MIRRORED_OFFENSES_QUERIED_CTX_KEY: {"15": QueryStatus.WAIT.value} if is_offenses_first_loop else {},
                MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
                MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
            }
        )
        if LAST_FETCH_KEY not in expected_ctx_first_loop:
            expected_ctx_first_loop[LAST_FETCH_KEY] = 0
        if SAMPLE_INCIDENTS_KEY not in expected_ctx_first_loop:
            expected_ctx_first_loop[SAMPLE_INCIDENTS_KEY] = []

    current_context = get_integration_context()

    assert current_context == expected_ctx_first_loop

    if test_case_data["offenses_second_loop"]:
        second_loop_offenses_with_success = ctx_test_data["offenses_second_loop"]
        second_loop_offenses_with_events = [
            (dict(offense, events=ctx_test_data["events"]), is_success)
            for offense, is_success in second_loop_offenses_with_success
        ]
        second_loop_offenses = [offense for offense, _ in second_loop_offenses_with_success]
        mocker.patch.object(client, "offenses_list", return_value=second_loop_offenses)
        mocker.patch.object(QRadar_v3, "enrich_offenses_result", return_value=second_loop_offenses)
        enrich_mock = mocker.patch.object(QRadar_v3, "enrich_offense_with_events")
        enrich_mock.side_effect = second_loop_offenses_with_events
        expected_ctx_second_loop = ctx_test_data["context_data_second_loop_default"].copy()
        # The samples from the second loop take priority over first loop samples (new samples first)
        if is_offenses_first_loop:
            expected_ctx_second_loop[SAMPLE_INCIDENTS_KEY] = (
                expected_ctx_second_loop.get(SAMPLE_INCIDENTS_KEY, []) + expected_ctx_first_loop.get(SAMPLE_INCIDENTS_KEY, [])
            )[:SAMPLE_SIZE]
    else:
        mocker.patch.object(client, "offenses_list", return_value=[])
        expected_ctx_second_loop = expected_ctx_first_loop.copy()
        # When no new offenses in second loop, existing samples remain unchanged (no new samples to prepend)
        # The old behavior was to append existing samples to themselves, but with the fix,
        # since there are no new samples, the existing samples stay as-is
    perform_long_running_loop(
        client=client,
        offenses_per_fetch=2,
        fetch_mode="Fetch With All Events",
        user_query="id > 15",
        events_columns="QIDNAME(qid), LOGSOURCENAME(logsourceid)",
        events_limit=3,
        ip_enrich=False,
        asset_enrich=False,
        incident_type=None,
        mirror_direction=mirror_direction,
        first_fetch="3 days",
        mirror_options=mirror_options,
        assets_limit=100,
        long_running_container_id="12345",
    )
    second_loop_ctx_not_default_values = test_case_data.get("second_loop_ctx_not_default_values", {})
    for k, v in second_loop_ctx_not_default_values.items():
        expected_ctx_second_loop[k] = v

    if mirror_options == MIRROR_OFFENSE_AND_EVENTS:
        expected_ctx_second_loop.update(
            {
                MIRRORED_OFFENSES_QUERIED_CTX_KEY: {"15": QueryStatus.WAIT.value} if is_offenses_first_loop else {},
                MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
                MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
            }
        )
        if LAST_FETCH_KEY not in expected_ctx_second_loop:
            expected_ctx_second_loop[LAST_FETCH_KEY] = 0
        if SAMPLE_INCIDENTS_KEY not in expected_ctx_second_loop:
            expected_ctx_second_loop[SAMPLE_INCIDENTS_KEY] = []

    current_context = get_integration_context()

    assert current_context == expected_ctx_second_loop
    set_integration_context({})


def test_convert_ctx():
    """
    Given: Old context structure

    When: Calling to update structure

    Then: New structure is returned
    """
    new_context = migrate_integration_ctx(ctx_test_data.get("old_ctxs")[0])
    expected = {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
        MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
        LAST_FETCH_KEY: 15,
        LAST_MIRROR_KEY: 0,
        SAMPLE_INCIDENTS_KEY: [],
    }
    assert new_context == expected


def test_convert_ctx_to_new_structure(mocker):
    mocker.patch.object(QRadar_v3, "LAST_FETCHED_ID", 0)
    context = {LAST_FETCH_KEY: "15", LAST_MIRROR_KEY: "0", SAMPLE_INCIDENTS_KEY: "[]"}
    set_integration_context(context)
    validate_integration_context()
    assert get_integration_context() == {
        MIRRORED_OFFENSES_QUERIED_CTX_KEY: {},
        MIRRORED_OFFENSES_FINISHED_CTX_KEY: {},
        MIRRORED_OFFENSES_FETCHED_CTX_KEY: {},
        LAST_FETCH_KEY: 15,
        LAST_MIRROR_KEY: 0,
        SAMPLE_INCIDENTS_KEY: [],
    }


@pytest.mark.parametrize("query, expected", [("", []), ("cidr", ["1.2.3.4/32", "5.6.7.8/2"])])
def test_get_cidrs_indicators(query, expected, mocker):
    """
    Given: A query to get cidr indicators

    When: Calling the function

    Then: Extract and return a clean list of cidrs only
    """
    mocker.patch.object(
        demisto,
        "searchIndicators",
        return_value={
            "iocs": [
                {
                    "id": "14",
                    "version": 1,
                    "indicator_type": "CIDR",
                    "value": "1.2.3.4/32",
                },
                {
                    "id": "12",
                    "version": 1,
                    "indicator_type": "CIDR",
                    "value": "5.6.7.8/2",
                },
            ]
        },
    )

    assert get_cidrs_indicators(query) == expected


VERIFY_MESSAGES_ERRORS = [
    "Cannot specify both cidrs and query arguments.",
    "Must specify either cidrs or query arguments.",
    "1.2.3.4 is not a valid CIDR.",
    "Name and group arguments only allow letters, numbers, '_' and '-'.",
    "cidr is not a valid field. Possible fields are: ['id', 'name', 'group', 'cidrs', 'description'].",
]


@pytest.mark.parametrize(
    "cidrs_list, cidrs_from_query, name, group, fields, expected",
    [
        (
            ["1.2.3.4/32", "5.6.7.8/2"],
            ["8.8.8.8/12"],
            "test1",
            "test_group1",
            "",
            VERIFY_MESSAGES_ERRORS[0],
        ),
        ([], [], "test2", "test_group2", "", VERIFY_MESSAGES_ERRORS[1]),
        (["1.2.3.4"], [], "test3", "test_group3", "", VERIFY_MESSAGES_ERRORS[2]),
        (["1.2.3.4/32"], [], "test4!", "test_group4", "", VERIFY_MESSAGES_ERRORS[3]),
        (["1.2.3.4/32"], [], "test5", "test_group5!", "", VERIFY_MESSAGES_ERRORS[3]),
        (
            ["1.2.3.4/32"],
            [],
            "test9",
            "test_group9",
            "id,cidr",
            VERIFY_MESSAGES_ERRORS[4],
        ),
    ],
)
def test_verify_args_for_remote_network_cidr(cidrs_list, cidrs_from_query, name, group, fields, expected):
    """
    Given: Command arguments

    When: Calling to verify arguments

    Then: Verify that the correct error message is returned
    """
    error_message = verify_args_for_remote_network_cidr(cidrs_list, cidrs_from_query, name, group, fields)

    assert error_message == expected


@pytest.mark.parametrize(
    "values, expected",
    [
        ([50, 2, 25], True),
        ([None, 2, None], True),
        ([None, None, 0], False),
        ([4, -5], False),
        ([None], True),
    ],
)
def test_is_positive(values, expected):
    assert is_positive(*values) == expected


VERIFY_LIST_MESSAGES_ERRORS = [
    "Please provide either limit argument or page and page_size arguments.",
    "Please provide both page and page_size arguments.",
    "Limit, page and page_size arguments must be positive numbers.",
    "You can not use filter argument with group, id or name arguments.",
]


@pytest.mark.parametrize(
    "limit, page, page_size, filter_, group, id_, name, expected",
    [
        (50, 2, 25, None, None, None, None, VERIFY_LIST_MESSAGES_ERRORS[0]),
        (None, 2, None, None, None, None, None, VERIFY_LIST_MESSAGES_ERRORS[1]),
        (None, None, 25, None, None, None, None, VERIFY_LIST_MESSAGES_ERRORS[1]),
        (-1, None, None, None, None, None, None, VERIFY_LIST_MESSAGES_ERRORS[2]),
        (None, -1, -1, None, None, None, None, VERIFY_LIST_MESSAGES_ERRORS[2]),
        (
            None,
            None,
            None,
            "test",
            "test",
            "test",
            "test",
            VERIFY_LIST_MESSAGES_ERRORS[3],
        ),
    ],
)
def test_verify_args_for_remote_network_cidr_list(limit, page, page_size, filter_, group, id_, name, expected):
    """
    Given: Command arguments

    When: Calling to verify arguments

    Then: Verify that the correct error message is returned
    """
    error_message = verify_args_for_remote_network_cidr_list(limit, page, page_size, filter_, group, id_, name)

    assert error_message == expected


@pytest.mark.parametrize("api_version", ("16.2", "17.0"))
@pytest.mark.parametrize("status", ("COMPLETED", "IN_PROGRESS"))
@pytest.mark.parametrize(
    "func",
    (qradar_reference_set_value_upsert_command, qradar_indicators_upload_command),
)
def test_reference_set_upsert_commands_new_api(mocker, api_version, status, func):
    """
    Given:
        - A reference set name and data to upload

    When:
        - Calling the reference set upsert command or the indicators upload command

    Then:
        - Verify that the correct API is used.
        - Verify that the data is returned if the status is COMPLETED.
        - Verify that the task id is returned if the status is IN_PROGRESS.
    """
    if func == qradar_indicators_upload_command:
        mocker.patch.object(client, "reference_sets_list")
        mocker.patch.object(
            IndicatorsSearcher,
            "search_indicators_by_version",
            return_value={
                "iocs": [
                    {"value": "test1", "indicator_type": "ip"},
                    {"value": "test2", "indicator_type": "ip"},
                    {"value": "test3", "indicator_type": "ip"},
                ]
            },
        )

    mocker.patch.object(QRadar_v3.ScheduledCommand, "raise_error_if_not_supported")
    mocker.patch.object(client, "reference_set_entries", return_value={"id": 1234})
    mocker.patch.object(client, "get_reference_data_bulk_task_status", return_value={"status": status})
    response = command_test_data["reference_set_bulk_load"]["response"]
    mocker.patch.object(client, "reference_sets_list", return_value=response)
    args = {"ref_name": "test_ref"}
    if func == qradar_reference_set_value_upsert_command:
        args["value"] = "test1,test2,test3"
    results = func(args, client, {"api_version": api_version})
    if status == "COMPLETED":
        expected = command_test_data["reference_set_bulk_load"]["expected"]
        expected_command_results = CommandResults(
            outputs_prefix=expected.get("outputs_prefix"),
            outputs_key_field=expected.get("outputs_key_field"),
            outputs=expected.get("outputs"),
            raw_response=response,
        )

        assert results.outputs_prefix == expected_command_results.outputs_prefix
        assert results.outputs_key_field == expected_command_results.outputs_key_field
        assert results.outputs == expected_command_results.outputs
        assert results.raw_response == expected_command_results.raw_response

    else:
        assert results.readable_output == "Reference set test_ref is still being updated in task 1234"
        assert results.scheduled_command._args.get("task_id") == 1234


def test_qradar_reference_set_value_upsert_command_continue_polling_with_connection_issues(
    mocker,
):
    """
    Given:
        - get_reference_data_bulk_task_status that returns ReadTimeout exception, IN_PROGRESS and COMPLETED statuses

    When:
        - qradar_reference_set_value_upsert_command function

    Then:
        - Verify the command would keep polling when there are temporary connection issues.
    """
    mocker.patch.object(QRadar_v3.ScheduledCommand, "raise_error_if_not_supported")
    mocker.patch.object(client, "reference_set_entries", return_value={"id": 1234})
    mocker.patch.object(
        client,
        "get_reference_data_bulk_task_status",
        side_effect=[ReadTimeout, {"status": "IN_PROGRESS"}, {"status": "COMPLETED"}],
    )
    args = {"ref_name": "test_ref", "value": "value1"}
    api_version = {"api_version": "17.0"}
    mocker.patch.object(
        client,
        "reference_sets_list",
        return_value=command_test_data["reference_set_bulk_load"]["response"],
    )

    result = qradar_reference_set_value_upsert_command(args, client=client, params=api_version)
    # make sure in ReadTimeout that no outputs are returned
    assert not result.outputs
    result = qradar_reference_set_value_upsert_command(args, client=client, params=api_version)
    # make sure when status is IN_PROGRESS no outputs are returned
    assert not result.outputs
    result = qradar_reference_set_value_upsert_command(args, client=client, params=api_version)
    # make sure when status is COMPLETED that outputs are returned
    assert result.outputs


@pytest.mark.parametrize(
    "command_func, endpoint, resource_id",
    [
        (
            qradar_event_collectors_list_command,
            "/config/event_sources/event_collectors",
            0,
        ),
        (
            qradar_wincollect_destinations_list_command,
            "/config/event_sources/wincollect/wincollect_destinations",
            0,
        ),
        (
            qradar_disconnected_log_collectors_list_command,
            "/config/event_sources/disconnected_log_collectors",
            0,
        ),
        (
            qradar_log_source_types_list_command,
            "/config/event_sources/log_source_management/log_source_types",
            0,
        ),
        (
            qradar_log_source_protocol_types_list_command,
            "/config/event_sources/log_source_management/protocol_types",
            0,
        ),
        (
            qradar_log_source_extensions_list_command,
            "/config/event_sources/log_source_management/log_source_extensions",
            0,
        ),
        (
            qradar_log_source_languages_list_command,
            "/config/event_sources/log_source_management/log_source_languages",
            0,
        ),
        (
            qradar_log_source_groups_list_command,
            "/config/event_sources/log_source_management/log_source_groups",
            0,
        ),
    ],
)
def test_id_commands(
    mocker,
    command_func: Callable[[Client, dict], CommandResults],
    endpoint: str,
    resource_id: int,
):
    """
    Given:
        - A command an endpoint and an ID.
    When:
        - Running the command with the corresponding endpoint and ID packed in an args object.
    Then:
        - Verify that the correct GET function is called with the ID and the endpoint.
    """
    args = {"id": resource_id}
    get_by_id_mock = mocker.patch.object(client, "get_resource_by_id", return_value={})
    try:
        command_func(client, args)
    except KeyError:
        demisto.log(f"command {command_func.__name__} raised key error")
    get_by_id_mock.assert_called_with(resource_id, endpoint, None, None)


@pytest.mark.parametrize(
    "command_func, endpoint",
    [
        (
            qradar_event_collectors_list_command,
            "/config/event_sources/event_collectors",
        ),
        (
            qradar_wincollect_destinations_list_command,
            "/config/event_sources/wincollect/wincollect_destinations",
        ),
        (
            qradar_disconnected_log_collectors_list_command,
            "/config/event_sources/disconnected_log_collectors",
        ),
        (
            qradar_log_source_types_list_command,
            "/config/event_sources/log_source_management/log_source_types",
        ),
        (
            qradar_log_source_protocol_types_list_command,
            "/config/event_sources/log_source_management/protocol_types",
        ),
        (
            qradar_log_source_extensions_list_command,
            "/config/event_sources/log_source_management/log_source_extensions",
        ),
        (
            qradar_log_source_languages_list_command,
            "/config/event_sources/log_source_management/log_source_languages",
        ),
        (
            qradar_log_source_groups_list_command,
            "/config/event_sources/log_source_management/log_source_groups",
        ),
    ],
)
def test_list_commands(mocker, command_func: Callable[[Client, dict], CommandResults], endpoint: str):
    """
    Given:
        - A command and an endpoint.
    When:
        - Running the command with the corresponding endpoint.
    Then:
        - Verify that the correct GET function is called with the correct endpoint
    """
    args = {"range": "0-49"}
    get_list_mock = mocker.patch.object(client, "get_resource_list", return_value=[{}])
    try:
        command_func(client, args)
    except KeyError:
        demisto.log(f"command {command_func.__name__} raised key error")
    get_list_mock.assert_called_with(f"items={args['range']}", endpoint, None, None, None)


@pytest.mark.parametrize("id", [(0), (None)])
def test_get_resource(mocker, id: int | None):
    """
    Given:
        - An existing ID or None.
    When:
        - Running the get_resource function with the int or None value.
    Then:
        - Verify that the correct GET function is called.
    """
    endpoint = "example.com"
    range = "items=0-49"
    get_resource_by_id_mock = mocker.patch.object(client, "get_resource_by_id")
    get_resource_list_mock = mocker.patch.object(client, "get_resource_list")

    client.get_resource(id, range, endpoint)
    if id is not None:
        get_resource_by_id_mock.assert_called()
    else:
        get_resource_list_mock.assert_called()


def test_get_log_sources_list(mocker):
    """
    Given:
        - An endpoint, a range, an algorithm and a password.
    When:
        - Running the qradar_log_sources_list command with the corresponding arguments.
    Then:
        - Verify that the get_resource_list function is called with the correct parameters.
    """
    qrd_encryption_details = {
        "qrd_encryption_algorithm": "algorithm",
        "qrd_encryption_password": "password",
    }
    args = {"range": "0-49", **qrd_encryption_details}
    get_list_mock = mocker.patch.object(client, "get_resource_list", return_value=[{}])
    endpoint = "/config/event_sources/log_source_management/log_sources"
    expected_additional_headers = {
        "x-qrd-encryption-algorithm": "algorithm",
        "x-qrd-encryption-password": "password",
    }
    try:
        qradar_log_sources_list_command(client, args)
    except KeyError:
        demisto.log("command log_sources_list_command raised key error")
    get_list_mock.assert_called_with(f"items={args['range']}", endpoint, None, None, expected_additional_headers)


def test_get_log_source_by_id(mocker):
    """
    Given:
        - An endpoint, a range, an algorithm a password and an id.
    When:
        - Running the qradar_log_sources_list command with the corresponding arguments and an id.
    Then:
        - Verify that the get_resource_by_id function is called with the correct parameters.
    """
    mock_id = 1880
    qrd_encryption_details = {
        "qrd_encryption_algorithm": "algorithm",
        "qrd_encryption_password": "password",
    }
    args = {"id": mock_id, **qrd_encryption_details}
    get_by_id_mock = mocker.patch.object(client, "get_resource_by_id", return_value={})
    endpoint = "/config/event_sources/log_source_management/log_sources"
    expected_additional_headers = {
        "x-qrd-encryption-algorithm": "algorithm",
        "x-qrd-encryption-password": "password",
    }
    try:
        qradar_log_sources_list_command(client, args)
    except KeyError:
        demisto.log("command log_sources_list_command raised key error")
    get_by_id_mock.assert_called_with(mock_id, endpoint, None, expected_additional_headers)


def test_create_log_source(mocker):
    """
    Given:
        - The required arguments for creating a log source.
    When:
        - Running the qradar_log_source_create command with the required arguments.
    Then:
        - Verify that the create_log_source function is called with the body correctly parsed and formatted.
    """
    args = command_test_data["create_log_source"]["args"]
    expected_body = command_test_data["create_log_source"]["expected_body"]
    return_value = command_test_data["create_log_source"]["response"]
    create_log_source_mock = mocker.patch.object(client, "create_log_source", return_value=return_value)
    qradar_log_source_create_command(client, args)
    create_log_source_mock.assert_called_with(expected_body)


def test_update_log_source(mocker):
    """
    Given:
        - The required arguments for updating a log source.
    When:
        - Running the qradar_log_source_update command with the required arguments.
    Then:
        - Verify that the update_log_source function is called with nothing but the correct fields.
    """
    args = command_test_data["update_log_source"]["args"]
    expected_body = command_test_data["update_log_source"]["expected_body"]
    update_log_source_mock = mocker.patch.object(client, "update_log_source", return_value={})
    qradar_log_source_update_command(client, args)
    update_log_source_mock.assert_called_with(expected_body)


def test_delete_log_source(mocker):
    """
    Given:
        - An id.
    When:
        - Running the qradar_log_source_delete command with the id.
    Then:
        - Verify that the delete_log_source function is called with the correct id.
    """
    id = 0
    args = {"id": id}
    update_log_source_mock = mocker.patch.object(client, "delete_log_source")

    qradar_log_source_delete_command(client, args)
    update_log_source_mock.assert_called_with(id)


def test_dict_converter():
    """
    Given:
        - A dictionary with string represented values.
    When:
        - Converting the dictionary to actual values using the conversion function.
    Then:
        - Verify that the outputted dictionary contains the expected values.
    """
    input_dict = {"age": "0"}
    expected_output = {"age": 0}
    converted_dict = convert_dict_to_actual_values(input_dict)
    assert not isinstance(converted_dict["age"], bool)
    assert converted_dict == expected_output

    input_dict = {"enabled": "true", "year": "2024", "name": "Moshe"}
    expected_output = {"enabled": True, "year": 2024, "name": "Moshe"}
    assert convert_dict_to_actual_values(input_dict) == expected_output

    input_nested_dict = {
        "enabled": "true",
        "year": "2024",
        "name": "Moshe",
        "details": {"age": "30", "score": "95.5"},
    }
    expected_nested_output = {
        "enabled": True,
        "year": 2024,
        "name": "Moshe",
        "details": {"age": 30, "score": 95.5},
    }
    assert convert_dict_to_actual_values(input_nested_dict) == expected_nested_output

    input_dict_with_list = {
        "enabled": "true",
        "year": "2024",
        "name": "Moshe",
        "lst": ["true", "22", "str"],
    }
    expected_output_with_list = {
        "enabled": True,
        "year": 2024,
        "name": "Moshe",
        "lst": [True, 22, "str"],
    }
    assert convert_dict_to_actual_values(input_dict_with_list) == expected_output_with_list

    input_nested_with_list_dict = {
        "enabled": "true",
        "year": "2024",
        "name": "Moshe",
        "details": {"age": "30", "score": "95.5"},
        "lst": [{"age": "30", "score": "95"}, {"name": "Moshe"}],
    }
    expected_nested_with_list_output = {
        "enabled": True,
        "year": 2024,
        "name": "Moshe",
        "details": {"age": 30, "score": 95.5},
        "lst": [{"age": 30, "score": 95}, {"name": "Moshe"}],
    }
    assert convert_dict_to_actual_values(input_nested_with_list_dict) == expected_nested_with_list_output


def test_list_converter():
    """
    Given:
        - A list with string represented values.
    When:
        - Converting the list to actual values using the conversion function.
    Then:
        - Verify that the outputted list contains the expected values.
    """
    simple_input_list = ["true", "2024", "moshe"]
    expected_output = [True, 2024, "moshe"]
    assert convert_list_to_actual_values(simple_input_list) == expected_output

    expected_nested_output = [True, 2024, "Moshe", [30, 95.5, False, "string"]]
    input_nested_list = ["true", "2024", "Moshe", ["30", "95.5", "false", "string"]]
    assert convert_list_to_actual_values(input_nested_list) == expected_nested_output

    input_list_with_dict = [
        "true",
        "2024",
        "Moshe",
        {"enabled": "true", "year": "2024", "name": "Moshe"},
    ]
    expected_output_with_dict = [
        True,
        2024,
        "Moshe",
        {"enabled": True, "year": 2024, "name": "Moshe"},
    ]
    assert convert_list_to_actual_values(input_list_with_dict) == expected_output_with_dict


def test_recovery_lastrun(mocker):
    mocker.patch.object(QRadar_v3, "LAST_FETCHED_ID", 2)
    """
    Given:
        - Last run is more up-to-date than the integration context.
        - Last run is the same as the integration context.

    When:
        - The container starts and the recovery method is called

    Then:
        - Ensure that the integration context is updated to the last run.
        - If there are not changes, make sure that the context is not updated
    """
    set_integration_context(
        {
            LAST_FETCH_KEY: 2,
            MIRRORED_OFFENSES_QUERIED_CTX_KEY: {0: 0},
            MIRRORED_OFFENSES_FINISHED_CTX_KEY: {0: 0},
        }
    )
    mocker.patch.object(QRadar_v3.demisto, "getLastRun", return_value={LAST_FETCH_KEY: 4})
    QRadar_v3.recover_from_last_run()
    context_data = get_integration_context()
    assert context_data[LAST_FETCH_KEY] == 4

    # now the last run and the integration context are the same, make sure that update context is not called
    update_context_mock = mocker.patch.object(QRadar_v3, "safely_update_context_data_partial")
    set_integration_context(
        {
            LAST_FETCH_KEY: 2,
            MIRRORED_OFFENSES_QUERIED_CTX_KEY: {0: 0},
            MIRRORED_OFFENSES_FINISHED_CTX_KEY: {0: 0},
        }
    )
    mocker.patch.object(QRadar_v3.demisto, "getLastRun", return_value={LAST_FETCH_KEY: 2})
    QRadar_v3.recover_from_last_run()
    context_data = get_integration_context()
    assert context_data[LAST_FETCH_KEY] == 2
    assert not update_context_mock.called


@pytest.mark.parametrize("quiet_mode", [False, True])
def test_qradar_reference_set_value_upsert_command_quiet_mode(mocker, quiet_mode):
    """
    Given:
        - A reference set with data
    When:
        - Running qradar-reference-set-value-upsert with quiet_mode, once set to true and once to false
        - The polling status is "completed" (i.e. the results should be returned in the current interval)
    Then:
        - Ensure the command does not output the reference set data iff quiet_mode=true
        - Ensure the data is always in the raw response
    """
    args = {
        "ref_name": "test_ref",
        "value": "value1",
        "task_id": "test",
        "quiet_mode": quiet_mode,
    }

    mocker.patch.object(QRadar_v3.ScheduledCommand, "raise_error_if_not_supported")
    mocker.patch.object(
        client,
        "get_reference_data_bulk_task_status",
        return_value={"status": "COMPLETED"},
    )
    mock_response = command_test_data["reference_set_bulk_load"]["response"] | {"data": ["some_data"]}
    mocker.patch.object(client, "reference_sets_list", return_value=mock_response)

    result = qradar_reference_set_value_upsert_command(args, client=client, params={"api_version": "17.0"})

    assert all("Name" in i for i in result.outputs)
    assert all("Data" not in i for i in result.outputs) or not quiet_mode
    assert "data" in result.raw_response


@pytest.mark.parametrize("quiet_mode", [False, True])
def test_qradar_indicators_upload_command_quiet_mode(mocker, quiet_mode):
    """
    Given:
        - A reference set with data
    When:
        - Running qradar-indicators-upload with quiet_mode, once set to true and once to false
        - The polling status is "completed" (i.e. the results should be returned in the current interval)
    Then:
        - Ensure the command does not output the reference set data iff quiet_mode=true
        - Ensure the data is always in the raw response
    """
    args = {"ref_name": "test_ref", "quiet_mode": quiet_mode, "task_id": "test"}

    mocker.patch.object(QRadar_v3.ScheduledCommand, "raise_error_if_not_supported")
    mocker.patch.object(
        client,
        "get_reference_data_bulk_task_status",
        return_value={"status": "COMPLETED"},
    )
    mocker.patch.object(
        IndicatorsSearcher,
        "search_indicators_by_version",
        return_value={"iocs": [{"value": "test", "indicator_type": "ip"}]},
    )
    mock_response = command_test_data["reference_set_bulk_load"]["response"] | {"data": ["some_data"]}
    mocker.patch.object(client, "reference_sets_list", return_value=mock_response)

    result = qradar_indicators_upload_command(args, client=client, params={"api_version": "17.0"})

    assert all("Name" in i for i in result.outputs)
    assert all("Data" not in i for i in result.outputs) or not quiet_mode
    assert "data" in result.raw_response


@pytest.mark.parametrize(
    "key, value, expected_results",
    [
        ("last_persisted_time", "1.1.2025", True),
        ("last_persisted_time", 1741790340000, True),
        ("last_persisted_time", 9223372036854775807, False),
        ("last_persisted_times", 1741790340000, False),
    ],
)
def test_should_get_time_parameter(key, value, expected_results):
    """
    Given:
        - A key and a value
        - Case 1: A key that appears in the USECS_ENTRIES list and a valid str value.
        - Case 2: A key that appears in the USECS_ENTRIES list and a valid int value.
        - Case 3: A key that appears in the USECS_ENTRIES list and an invalid int value.
        - Case 4: A key that doesn't appear in the USECS_ENTRIES list and a valid int value.
    When:
        - Running should_get_time_parameter.
    Then:
        - Ensure the right results returned.
        - Case 1: Should return True.
        - Case 2: Should return True.
        - Case 3: Should return False.
        - Case 4: Should return False.
    """
    assert should_get_time_parameter(key, value) is expected_results


def test_add_iso_entries_to_dict_placeholder_edge_case():
    """
    Given:
        - A dict with valid and invalid time values.
    When:
        - Running add_iso_entries_to_dict.
    Then:
        - Ensure the right results returned and no error is thrown.
    """
    dicts = [{"start_time": 9223372036854775807, "last_persisted_time": 1741790340000}]
    results = add_iso_entries_to_dict(dicts)
    assert results == [
        {
            "start_time": 9223372036854775807,
            "last_persisted_time": "2025-03-12T14:39:00+00:00",
        }
    ]


MAX_SAMPLE_SIZE_MB = 1
MAX_SAMPLE_SIZE_BYTES = MAX_SAMPLE_SIZE_MB * 1024 * 1024


@pytest.fixture(autouse=True)
def patch_constants(monkeypatch):
    monkeypatch.setattr("QRadar_v3.MAX_SAMPLE_SIZE_BYTES", MAX_SAMPLE_SIZE_BYTES)
    monkeypatch.setattr("QRadar_v3.MAX_SAMPLE_SIZE_MB", MAX_SAMPLE_SIZE_MB)


class NonSerializable:
    def __str__(self):
        return "NonSerializable"


@pytest.mark.parametrize(
    "incident,expected_min_size",
    [
        ({"name": "Test Incident", "details": "A" * 1024}, 1024),
        ({"id": 123, "active": True}, 10),
    ],
)
def test_calculate_object_size_success_json_serialization(incident, expected_min_size):
    """
    Given a JSON-serializable incident dictionary
    When calculate_object_size is called
    Then it should return a byte length >= expected_min_size and not raise any exception
    """
    size = QRadar_v3.calculate_object_size(incident)
    assert isinstance(size, int)
    assert size >= expected_min_size


def test_calculate_object_size_fallback_to_str(monkeypatch):
    """
    Given an incident dictionary that includes a non-serializable object
    When calculate_object_size is called
    Then it should fallback to str() and log a debug message
    """
    from QRadar_v3 import calculate_object_size

    incident = {"data": NonSerializable()}

    def json_dumps_fail(*args, **kwargs):
        raise TypeError("Object of type NonSerializable is not JSON serializable")

    monkeypatch.setattr("QRadar_v3.json.dumps", json_dumps_fail)

    with patch("QRadar_v3.demisto.debug") as mock_debug:
        size = calculate_object_size(incident)
        assert isinstance(size, int)
        assert size > 0

        debug_calls = [call.args[0] for call in mock_debug.call_args_list]
        assert any("Could not serialize object to JSON" in msg for msg in debug_calls)


def test_calculate_object_size_encoding_fallback(monkeypatch):
    """
    Given an incident with characters that cause UTF-8 encoding failure
    When calculate_object_size is called
    Then it should fallback to 'replace' encoding and log a debug message
    """
    from QRadar_v3 import calculate_object_size

    broken_string = "Test\x80Incident"
    incident = {"details": broken_string}

    class MockStr(str):
        def encode(self, encoding="utf-8", errors=None):
            if errors is None:
                raise UnicodeEncodeError("utf-8", self, 0, 1, "invalid start byte")
            return super().encode(encoding, errors)

    with (
        patch("QRadar_v3.json.dumps", return_value=MockStr(broken_string)),
        patch("QRadar_v3.demisto.debug") as mock_debug,
    ):
        size = calculate_object_size(incident)
        assert isinstance(size, int)

        debug_calls = [call.args[0] for call in mock_debug.call_args_list]
        assert any("Could not encode string to UTF-8" in msg for msg in debug_calls)


def test_is_incident_size_acceptable_true():
    """
    Given an incident smaller than the MAX_SAMPLE_SIZE_BYTES limit
    When is_incident_size_acceptable is called
    Then it should return True
    """
    small_incident = {"data": "A" * 512}
    assert QRadar_v3.is_incident_size_acceptable(small_incident) is True


def test_is_incident_size_acceptable_false():
    """
    Given an incident larger than the MAX_SAMPLE_SIZE_BYTES limit
    When is_incident_size_acceptable is called
    Then it should return False and a debug message should be logged
    """
    large_incident = {"data": "A" * (MAX_SAMPLE_SIZE_BYTES + 1)}
    with patch("QRadar_v3.demisto.debug") as mock_debug:
        result = QRadar_v3.is_incident_size_acceptable(large_incident)
        assert result is False
        assert any("exceeds maximum sample size" in call.args[0] for call in mock_debug.call_args_list)


@pytest.mark.parametrize(
    "current_samples, new_samples, expected_samples",
    [
        pytest.param(
            ["sample1", "sample2"],
            ["sample3", "sample4"],
            ["sample3", "sample4"],
            id="Two new samples with two existing samples - new samples take priority",
        ),
        pytest.param(
            [],
            ["sample3", "sample4", "sample5"],
            ["sample3", "sample4"],
            id="No existing samples with new samples list - new samples stored",
        ),
        pytest.param(
            '["sample1"]',
            ["sample2", "sample3", "sample4"],
            ["sample2", "sample3"],
            id="Handling legacy string format - new samples override",
        ),
        pytest.param(
            ["sample1"],
            ["sample2"],
            ["sample2", "sample1"],
            id="One new sample with one existing sample - new sample first",
        ),
        pytest.param(
            [],
            [],
            [],
            id="No samples",
        ),
    ],
)
def test_merge_samples(current_samples: list, new_samples: list, expected_samples: list):
    """
    Given samples in the existing integration context and new samples in the changes to be merged
    When calling merge_samples
    Then ensure merged samples do not exceed `SAMPLE_SIZE` and new samples take priority over old samples
    """
    from QRadar_v3 import merge_samples

    initial_ctx = copy.deepcopy({SAMPLE_INCIDENTS_KEY: current_samples})
    changes = copy.deepcopy({SAMPLE_INCIDENTS_KEY: new_samples})

    merge_samples(initial_ctx, changes)

    assert initial_ctx == {SAMPLE_INCIDENTS_KEY: expected_samples}


@pytest.mark.parametrize(
    "current_ctx, changes, override_keys, expected_ctx",
    [
        pytest.param(
            {"a": 1, "b": 2, "c": 3},
            {"b": 99, "d": 4},
            ["a", "b", "c"],
            {"a": 1, "c": 3},
            id="Key 'b' in current_ctx and changes removed",
        ),
        pytest.param(
            {"a": 1, "b": 2, "c": 3},
            {"d": 4, "e": 5},
            ["a", "b", "c"],
            {"a": 1, "b": 2, "c": 3},
            id="No common keys in current_ctx and changes",
        ),
        pytest.param(
            {"a": 1, "b": 2},
            {"a": 99},
            [],
            {"a": 1, "b": 2},
            id="No override keys",
        ),
        pytest.param(
            {"k1": 1, "k2": 2, "k3": 3},
            {"k2": "val", "k3": "another_val"},
            ["k1", "k2", "k3"],
            {"k1": 1},
            id="Keys 'k1' and 'k3' in current_ctx and changes removed",
        ),
    ],
)
def test_remove_context_keys(current_ctx, changes, override_keys, expected_ctx):
    """
    Given current_ctx and changes to be merged
    When calling remove_context_keys with override_keys
    Then ensure common keys in the override_keys list are removed from current_ctx
    """
    from QRadar_v3 import remove_context_keys

    initial_ctx = copy.deepcopy(current_ctx)

    remove_context_keys(initial_ctx, changes, override_keys)

    assert initial_ctx == expected_ctx


def test_get_rules_names(mocker):
    """
    Given a list of fetched offences
    When calling get_rules_names
    Then ensure HTTP request is re-attempted after one failure and the mapping of {rule_id: rule_name} is as expected
    """
    from QRadar_v3 import get_rules_names

    mock_api_response = [
        {"id": 101, "name": "Suspicious Activity"},
        {"id": 102, "name": "Unauthorized Login"},
        {"id": 103, "name": "Malware Detected"},
    ]
    mock_client_rules_list = mocker.patch.object(client, "rules_list", side_effect=[Exception("API Timeout"), mock_api_response])
    mock_client_rules_list.__name__ = "mock_rules_list"  # magic mock objects have different attributes from actual functions

    offenses = [
        {"id": 1, "rules": [{"id": 101}, {"id": 102}]},
        {"id": 2, "rules": [{"id": 102}, {"id": 103}]},
    ]
    rule_id_rule_name_mapping = get_rules_names(client, offenses)

    # Assert `client.rules_list` method was called exactly twice (first time failed due to 'API Timeout' exception)
    assert mock_client_rules_list.call_count == 2
    assert rule_id_rule_name_mapping == {
        101: "Suspicious Activity",
        102: "Unauthorized Login",
        103: "Malware Detected",
    }


def test_get_integration_context_not_versioned(mocker):
    """
    Given:
        - is_versioned_context_available returns False
    When:
        - Calling get_integration_context
    Then:
        - Ensure demisto.getIntegrationContext is called
        - Ensure the correct context is returned
    """
    mocker.patch("QRadar_v3.is_versioned_context_available", return_value=False)
    mocker.patch.object(demisto, "getIntegrationContext", return_value={"a": 1})

    assert QRadar_v3.get_integration_context() == {"a": 1}


def test_qradar_set_integration_context(mocker):
    """
    Given:
        - Context data with LAST_FETCH_KEY
    When:
        - Calling qradar_set_integration_context
    Then:
        - Ensure set_integration_context is called
        - Ensure LAST_FETCHED_ID global variable is updated
    """
    mock_set = mocker.patch("QRadar_v3.set_integration_context")
    context_data = {QRadar_v3.LAST_FETCH_KEY: 123}

    QRadar_v3.qradar_set_integration_context(context_data)

    mock_set.assert_called_with(context_data)
    assert QRadar_v3.LAST_FETCHED_ID == 123


def test_qradar_set_integration_context_no_last_fetch(mocker):
    """
    Given:
        - Context data without LAST_FETCH_KEY
    When:
        - Calling qradar_set_integration_context
    Then:
        - Ensure set_integration_context is called
        - Ensure LAST_FETCHED_ID global variable is NOT updated (or remains as is/None)
    """
    mock_set = mocker.patch("QRadar_v3.set_integration_context")
    context_data = {"other": "data"}

    # Reset global if needed
    QRadar_v3.LAST_FETCHED_ID = None

    QRadar_v3.qradar_set_integration_context(context_data)

    mock_set.assert_called_with(context_data)
    assert QRadar_v3.LAST_FETCHED_ID is None


@pytest.mark.parametrize(
    "command, ref_name, key, value", [("reference_map_value_upsert", "Monitoring Identifier Gaps", "testkey", "12345")]
)
def test_qradar_reference_map_value_upsert_command(mocker, command, ref_name, key, value):
    mocker.patch.object(
        client,
        "http_request",
        return_value=command_test_data[command]["response"],
    )
    res = qradar_reference_map_value_upsert_command(client, {"ref_name": ref_name, "key": key, "value": value})

    assert res.raw_response == command_test_data[command]["expected"]["raw_response"]
    assert res.outputs is None


def test_qradar_reference_map_value_upsert_command_exception(mocker):
    mocker.patch.object(
        client,
        "http_request",
        side_effect=[DemistoException(message="Error in API call [404] - 404\ntest123 does not exist")],
    )
    res = qradar_reference_map_value_upsert_command(client, {"ref_name": "test123", "key": "identifier_1", "value": "1"})
    assert res.entry_type == EntryType.ERROR
    assert (
        res.readable_output
        == "Failed to insert or update identifier_1 in test123: Error in API call [404] - 404\ntest123 does not exist"
    )