Skip to content

Commit

Permalink
Ciac 6453/improve generic polling - hotfix (#26372)
Browse files Browse the repository at this point in the history
* Fixed script issues

* updated rn

* Updated rn

* Apply suggestions from code review

Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com>

* updated script min version

* fix pre-commit issues

* updated the script to support only XSOAR

* Bump pack from version CommonScripts to 1.11.69.

* update to use endTime instead of using the context

* updated rn

* Bump pack from version CommonScripts to 1.11.70.

* updated rn

* Update Packs/CommonScripts/ReleaseNotes/1_11_70.md

* updated rn and readme

* Updated rn

* updated rn

* updated script

* Apply suggestions from code review

Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com>

* Update Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.py

Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com>

* Bump pack from version CommonScripts to 1.11.72.

* Bump pack from version CommonScripts to 1.11.73.

* updated script

* updated rn

* updated docker image

* updated script

* updated scripts

---------

Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com>
Co-authored-by: Content Bot <bot@demisto.com>
  • Loading branch information
3 people committed May 11, 2023
1 parent 5d0671f commit 6f65a3e
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 75 deletions.
15 changes: 15 additions & 0 deletions Packs/CommonScripts/ReleaseNotes/1_11_73.md
@@ -0,0 +1,15 @@

#### Scripts

##### ScheduleCommand

- Added the *scheduledEntryGuid* arguments to support the new ***GenericPolling*** playbook mechanism which improves the playbook performance.

##### GenericPollingScheduledTask

- Added the *scheduledEntryGuid* arguments to support the new ***GenericPolling*** playbook mechanism which improves the playbook performance.

##### ScheduleGenericPolling
- Updated the Docker image to: *demisto/python3:3.10.11.57890*.

- Added the *scheduledEntryGuid* arguments to support the new ***GenericPolling*** playbook mechanism which improves the playbook performance.
Expand Up @@ -16,6 +16,14 @@
* ID - the key that contains the id for polling
*/

// Constant to verify the minimum build number and XSIAM version for the new polling command (stopScheduleEntry feature).
//const MINIMUM_XSIAM_VERSION = '8.3.0';
//const MINIMUM_BUILD_NUMBER_XSIAM = 313276;
const MINIMUM_XSOAR_VERSION = '8.2.0';
const MINIMUM_BUILD_NUMBER_XSOAR = 309463;



function listOfStrings(v) {
if (!Array.isArray(v)) {
v = [v];
Expand All @@ -37,7 +45,7 @@ function intersect(a, b) {
});
}

function finish(playbookId, tag, err) {
function finish(playbookId, tag, err, entryGUID) {
var params = { 'id': tag };
if (err === undefined) {
params.input = 'YES';
Expand All @@ -47,9 +55,16 @@ function finish(playbookId, tag, err) {
if (playbookId) {
params.parentPlaybookID = playbookId;
}
if ((entryGUID !== undefined) && (entryGUID)) {
var res = executeCommand("stopScheduleEntry", {'scheduledEntryGuid': entryGUID});
if (isError(res[0])) {
logError('Failed to stop scheduled entry: ' + res[0]);
}
}
return executeCommand("taskComplete", params);
}


function setNextRun(ids, playbookId, pollingCommand, pollingCommandArgName, pendingIds, interval, timeout, tag, additionalArgNames, additionalArgValues) {
var idsStr = ids.replace(/"/g, '\\"');
var playbookIdStr = '';
Expand All @@ -66,70 +81,112 @@ function setNextRun(ids, playbookId, pollingCommand, pollingCommandArgName, pend
});
}

try {
if (args.timeout <= 0) {
return finish(args.playbookId, args.tag);
function shouldRunWithGuid() {
res = getDemistoVersion();
platform = res.platform;
version = res.version;
buildNumber = res.buildNumber;

// conditions to add when the feature is supported in XSIAM:
// ((platform === "x2") && (compareVersions(version, MINIMUM_XSIAM_VERSION) >= 0) && (parseInt(buildNumber) >= MINIMUM_BUILD_NUMBER_XSIAM))

// Checking if the stopScheduleEntry command is available.
// If not, we are running on an older version of platform and we need to use the old polling mechanism.
// The try/catch mechanism is to support development and to ignore parseInt errors.
try {
if ((platform === "xsoar") && (compareVersions(version, MINIMUM_XSOAR_VERSION) >= 0) && (parseInt(buildNumber) >= MINIMUM_BUILD_NUMBER_XSOAR)) {
return true;
}
}

// Get ids that have not finished yet
var ids = argToList(args.ids);
for (var i = 0; i < ids.length; i++) {
ids[i] = ids[i].replace(/[\\]*"/g, '');
catch (err) {
return false;
}
}

function genericPollingScheduled(){
try {
shouldRunWithGuid = shouldRunWithGuid();
if (shouldRunWithGuid) {
var endTime = stringToDate(args.endTime, "%Y-%m-%d %H:%M:%S");
var currentTime = new Date();

// Set the context of the scheduled task to the local playbook context
var idsToPoll = ids;
var pendingPath = args.pendingIds;
if ('playbookId' in args) {
playbookContext = 'subplaybook-' + args.playbookId;
pendingPath = playbookContext + "." + args.pendingIds;
}
var pendings = dq(invContext, pendingPath);
if (currentTime >= endTime) {
return finish(args.playbookId, args.tag, undefined, args.scheduledEntryGuid);
}
}
else {
if (args.timeout <= 0) {
return finish(args.playbookId, args.tag, undefined, args.scheduledEntryGuid);
}
}

if (pendings === null) {
return finish(args.playbookId, args.tag);
}
// Get ids that have not finished yet
var ids = argToList(args.ids);
for (var i = 0; i < ids.length; i++) {
ids[i] = ids[i].replace(/[\\]*"/g, '');
}

var idsStrArr = listOfStrings(ids);
var pendingsStrArr = listOfStrings(pendings);
idsToPoll = intersect(idsStrArr, pendingsStrArr);
if (idsToPoll.length === 0) {
return finish(args.playbookId, args.tag);
}
0
// Set the context of the scheduled task to the local playbook context
var idsToPoll = ids;
var pendingPath = args.pendingIds;

// Run the polling command for each id
var pollingCommandArgs = {};
var names = argToList(args.additionalPollingCommandArgNames);
var values = argToList(args.additionalPollingCommandArgValues);
if ('playbookId' in args) {
playbookContext = 'subplaybook-' + args.playbookId;
pendingPath = playbookContext + "." + args.pendingIds;
}
var pendings = dq(invContext, pendingPath);

for (var index = 0; index < names.length; index++)
pollingCommandArgs[names[index]] = values[index];
if (pendings === null) {
return finish(args.playbookId, args.tag, undefined, args.scheduledEntryGuid);
}

pollingCommandArgs[args.pollingCommandArgName] = idsToPoll.join(',');
var res = executeCommand(args.pollingCommand, pollingCommandArgs);
var idsStrArr = listOfStrings(ids);
var pendingsStrArr = listOfStrings(pendings);
idsToPoll = intersect(idsStrArr, pendingsStrArr);
if (idsToPoll.length === 0) {
return finish(args.playbookId, args.tag, undefined, args.scheduledEntryGuid);
}

// Change the context output of the polling results to the local playbook context
if ('playbookId' in args) {
for (var i = 0; i < res.length; i++) {
if ('EntryContext' in res[i]) {
for (var k in res[i].EntryContext) {
res[i].EntryContext[playbookContext + "." + k] = res[i].EntryContext[k];
delete res[i].EntryContext[k];
// Run the polling command for each id
var pollingCommandArgs = {};
var names = argToList(args.additionalPollingCommandArgNames);
var values = argToList(args.additionalPollingCommandArgValues);

for (var index = 0; index < names.length; index++)
pollingCommandArgs[names[index]] = values[index];

pollingCommandArgs[args.pollingCommandArgName] = idsToPoll.join(',');
var res = executeCommand(args.pollingCommand, pollingCommandArgs);

// Change the context output of the polling results to the local playbook context
if ('playbookId' in args) {
for (var i = 0; i < res.length; i++) {
if ('EntryContext' in res[i]) {
for (var k in res[i].EntryContext) {
res[i].EntryContext[playbookContext + "." + k] = res[i].EntryContext[k];
delete res[i].EntryContext[k];
}
}
}
}
}

// Schedule the next iteration
var scheduleTaskRes = setNextRun(args.ids, args.playbookId, args.pollingCommand, args.pollingCommandArgName, args.pendingIds, args.interval, args.timeout, args.tag, args.additionalPollingCommandArgNames, args.additionalPollingCommandArgValues);
if (isError(scheduleTaskRes[0])) {
res.push(scheduleTaskRes);
if (!shouldRunWithGuid) {
// Schedule the next iteration, old version.
var scheduleTaskRes = setNextRun(args.ids, args.playbookId, args.pollingCommand, args.pollingCommandArgName, args.pendingIds, args.interval, args.timeout, args.tag, args.additionalPollingCommandArgNames, args.additionalPollingCommandArgValues);
if (isError(scheduleTaskRes[0])) {
res.push(scheduleTaskRes);
}
}
return res;
}
catch (err) {
finish(args.playbookId, args.tag, err, args.scheduledEntryGuid);
throw err;
}

return res;
}
catch (err) {
finish(args.playbookId, args.tag, err);
throw err;

function main() {
return genericPollingScheduled();
}
return main();
Expand Up @@ -42,6 +42,10 @@ args:
- name: additionalPollingCommandArgValues
description: Commas separated arguments values of the polling command
isArray: true
- name: scheduledEntryGuid
description: The GUID of the scheduled entry that runs the polling command.
- name: endTime
description: The time to end the polling.
scripttarget: 0
runonce: false
tests:
Expand Down
29 changes: 17 additions & 12 deletions Packs/CommonScripts/Scripts/GenericPollingScheduledTask/README.md
@@ -1,29 +1,34 @@
Runs the polling command repeatedly and completes a blocking manual task when polling is done.
Runs the polling command repeatedly, completes a blocking manual task when polling is done.

## Script Data

---

| **Name** | **Description** |
| --- | --- |
| Script Type | javascript |
| Tags | - |

| Cortex XSOAR Version | 5.0.0 |

## Inputs

---

| **Argument Name** | **Description** |
| --- | --- |
| ids | The list of IDs to poll. |
| pendingIds | The IDs with pending status. |
| pollingCommand | The name of the polling command to run. |
| pollingCommandArgName | The name of the argument of the polling command. |
| interval | The frequency to poll. How often the polling command should run (in minutes). |
| timeout | The amount of time to poll before declaring a timeout and resuming the playbook (in minutes). |
| ids | List of IDs to poll |
| pendingIds | IDs with pending status |
| pollingCommand | Name of the polling command to run |
| pollingCommandArgName | Name of the argument of the polling command |
| interval | Polling frequency - how often the polling command should run \(minutes\) |
| timeout | How much time to poll before declaring a timeout and resuming the playbook \(minutes\) |
| playbookId | The ID of the playbook that contains the manual task which will be completed once the polling is done. |
| tag | The tag of the blocking manual task ("Wait For Polling Task To Finish"). |
| additionalPollingCommandArgNames | The names of the additional arguments for the polling command. For example, arg1,arg2,... |
| additionalPollingCommandArgValues | The commas-separated arguments values of the polling command. |
| tag | The tag of the blocking manual task \("Wait For Polling Task To Finish"\) |
| additionalPollingCommandArgNames | Names of additional arguments for the polling command \(e.g. arg1,arg2,...\) |
| additionalPollingCommandArgValues | Commas separated arguments values of the polling command |
| scheduledEntryGuid | The GUID of the scheduled entry that runs the polling command. |
| endTime | The time to end the polling. |

## Outputs

---
There are no outputs for this script.
19 changes: 15 additions & 4 deletions Packs/CommonScripts/Scripts/ScheduleCommand/README.md
@@ -1,24 +1,35 @@
Schedules a command to run inside the War Room at a future time. Can be once or reoccurring.

## Script Data

---

| **Name** | **Description** |
| --- | --- |
| Script Type | javascript |
| Tags | Utility |
| Cortex XSOAR Version | 5.0.0 |

## Used In

---
This script is used in the following playbooks and scripts.

* Schedule Task and Poll

## Inputs

---

| **Argument Name** | **Description** |
| --- | --- |
| command | The command to schedule. |
| cron | The scheduled time to run. |
| endDate | When should the schedule end. This is relevant only if "times" are not provided (Optional). The format is "Mon, 02 Jan 2006 15:04:05 MST". |
| times | The number of times to run (Optional). |
| command | The command to schedule |
| cron | The scheduled time to run |
| endDate | When should we end the schedule. Will be only relevant if times is not provided. Optional. Format is 'Mon, 02 Jan 2006 15:04:05 MST' |
| times | The number of times to run. Optional. |
| scheduledEntryGuid | The GUID of the scheduled entry that runs the polling command. |

## Outputs

---
There are no outputs for this script.
Expand Up @@ -22,6 +22,8 @@ args:
not provided. Optional. Format is 'Mon, 02 Jan 2006 15:04:05 MST'
- name: times
description: The number of times to run. Optional.
- name: scheduledEntryGuid
description: The GUID of the scheduled entry that runs the polling command.
scripttarget: 0
dependson: {}
timeout: 0s
Expand Down

0 comments on commit 6f65a3e

Please sign in to comment.