From 00b759cd6e583c61a9908a46069fca47918d197c Mon Sep 17 00:00:00 2001 From: Tyler Schmidtke <86071102+ax-tschmidtke@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:04:27 -0500 Subject: [PATCH] Automox 2.0.0: Fixes to the Vulnerability Sync Actions (#2029) * Fixes to the Vulnerability Sync Actions * remove debugging print * fix bug in update_device action * help.md generation seems broken, fix manually * feedback * review feedback --- plugins/automox/.CHECKSUM | 40 +- plugins/automox/bin/icon_automox | 18 +- plugins/automox/help.md | 1247 ++++++++--------- .../automox/icon_automox/actions/__init__.py | 11 +- .../__init__.py | 2 - .../action.py | 21 - .../__init__.py | 2 - .../action.py | 21 - .../schema.py | 81 -- .../__init__.py | 2 + .../action.py | 22 + .../schema.py | 28 +- .../__init__.py | 2 + .../action.py | 48 + .../schema.py | 109 ++ .../__init__.py | 2 + .../action.py | 27 + .../schema.py | 456 ++++++ .../get_vulnerability_sync_batch/__init__.py | 2 - .../get_vulnerability_sync_batch/action.py | 21 - .../get_vulnerability_sync_batch/schema.py | 220 --- .../__init__.py | 2 + .../action.py | 29 + .../schema.py | 113 ++ .../__init__.py | 2 + .../action.py | 33 + .../schema.py | 325 +++++ .../__init__.py | 2 + .../action.py | 39 + .../schema.py | 531 +++++++ .../__init__.py | 2 - .../list_vulnerability_sync_batches/action.py | 20 - .../list_vulnerability_sync_batches/schema.py | 212 --- .../list_vulnerability_sync_tasks/__init__.py | 2 - .../list_vulnerability_sync_tasks/action.py | 22 - .../list_vulnerability_sync_tasks/schema.py | 455 ------ .../actions/update_device/action.py | 7 +- .../upload_vulnerability_sync_file/action.py | 6 +- .../upload_vulnerability_sync_file/schema.py | 30 +- .../automox/icon_automox/util/api_client.py | 114 +- plugins/automox/icon_automox/util/cleaner.py | 11 + .../automox/icon_automox/util/param_parser.py | 16 + plugins/automox/plugin.spec.yaml | 679 ++++++--- plugins/automox/setup.py | 2 +- ...test_action_on_vulnerability_sync_batch.py | 49 - .../test_action_on_vulnerability_sync_task.py | 49 - .../test_get_vulnerability_sync_batch.py | 73 - 47 files changed, 3002 insertions(+), 2205 deletions(-) delete mode 100755 plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/__init__.py delete mode 100755 plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/action.py delete mode 100755 plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/__init__.py delete mode 100755 plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/action.py delete mode 100755 plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/schema.py create mode 100755 plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/__init__.py create mode 100755 plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/action.py rename plugins/automox/icon_automox/actions/{action_on_vulnerability_sync_batch => delete_vulnerability_sync_action_set}/schema.py (62%) create mode 100755 plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/__init__.py create mode 100755 plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/action.py create mode 100755 plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/schema.py create mode 100755 plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/__init__.py create mode 100755 plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/action.py create mode 100755 plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/schema.py delete mode 100755 plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/__init__.py delete mode 100755 plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/action.py delete mode 100755 plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/schema.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/__init__.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/action.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/schema.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/__init__.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/action.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/schema.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/__init__.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/action.py create mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/schema.py delete mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/__init__.py delete mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/action.py delete mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/schema.py delete mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/__init__.py delete mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/action.py delete mode 100755 plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/schema.py create mode 100644 plugins/automox/icon_automox/util/cleaner.py create mode 100644 plugins/automox/icon_automox/util/param_parser.py delete mode 100644 plugins/automox/unit_test/test_action_on_vulnerability_sync_batch.py delete mode 100644 plugins/automox/unit_test/test_action_on_vulnerability_sync_task.py delete mode 100644 plugins/automox/unit_test/test_get_vulnerability_sync_batch.py diff --git a/plugins/automox/.CHECKSUM b/plugins/automox/.CHECKSUM index 8d267166be..6c5735663d 100644 --- a/plugins/automox/.CHECKSUM +++ b/plugins/automox/.CHECKSUM @@ -1,16 +1,8 @@ { - "spec": "cef7bb305cd296dcfe4c91ad08817421", - "manifest": "3a0cbf67b2811b37bdb4b2261d7dfc9e", - "setup": "7cbcfbc077dc2f9a706059bea2ef8853", + "spec": "44a6dd12631d663c562f99b9d60d90c6", + "manifest": "396c2cf6f1b72004065cd3d9b4cddd24", + "setup": "23fa3840aa940ced79bbee21e7ed4ebd", "schemas": [ - { - "identifier": "action_on_vulnerability_sync_batch/schema.py", - "hash": "4b3f998313fe5fcb484c5c4fff7fa004" - }, - { - "identifier": "action_on_vulnerability_sync_task/schema.py", - "hash": "52c436eab10c0aeaa9a45b9c9401a4d3" - }, { "identifier": "create_group/schema.py", "hash": "b30f9e829c46827c90d201b294ecf048" @@ -23,6 +15,14 @@ "identifier": "delete_group/schema.py", "hash": "66b18c900b75652494434b68687062c3" }, + { + "identifier": "delete_vulnerability_sync_action_set/schema.py", + "hash": "c572818adf8aa5b2663a99a676af543d" + }, + { + "identifier": "execute_vulnerability_sync_actions/schema.py", + "hash": "7575fcc4876accb8b39938cb9ec17514" + }, { "identifier": "get_device_by_hostname/schema.py", "hash": "13226c5058256e3368c7392eaad8b64d" @@ -36,8 +36,8 @@ "hash": "42d9b8777f46e6709a38cf4faf40633c" }, { - "identifier": "get_vulnerability_sync_batch/schema.py", - "hash": "5765f142f96aa185edc42e9b11f175c4" + "identifier": "get_vulnerability_sync_action_set/schema.py", + "hash": "8f10053a4d8feaf624367ef9c3470bd6" }, { "identifier": "list_devices/schema.py", @@ -60,12 +60,16 @@ "hash": "b8d3145226dcf46c7cf14ef0d71e78cd" }, { - "identifier": "list_vulnerability_sync_batches/schema.py", - "hash": "90bff67fac53fab74fab99f576f6c789" + "identifier": "list_vulnerability_sync_action_set_issues/schema.py", + "hash": "473e78302dc489953559411691330fd9" + }, + { + "identifier": "list_vulnerability_sync_action_set_solutions/schema.py", + "hash": "067fc017cdf8fbfdfae8834db77970c5" }, { - "identifier": "list_vulnerability_sync_tasks/schema.py", - "hash": "4b6eb5774bcfc5e7c0a7c0e0707b83ee" + "identifier": "list_vulnerability_sync_action_sets/schema.py", + "hash": "e9b02d295c7cb84f3dccda85d0c82bb2" }, { "identifier": "run_command/schema.py", @@ -81,7 +85,7 @@ }, { "identifier": "upload_vulnerability_sync_file/schema.py", - "hash": "47597b34d180d84050c8ea8297f44e0e" + "hash": "e6577f542f46a5035c6423bbff4bcbb5" }, { "identifier": "connection/schema.py", diff --git a/plugins/automox/bin/icon_automox b/plugins/automox/bin/icon_automox index f7a72be12c..04dd2d820c 100755 --- a/plugins/automox/bin/icon_automox +++ b/plugins/automox/bin/icon_automox @@ -6,7 +6,7 @@ from sys import argv Name = "Automox" Vendor = "automox" -Version = "1.2.0" +Version = "2.0.0" Description = "Automox is modernizing IT operations with continuous visibility, insight, and agility for your entire IT environment" @@ -36,23 +36,23 @@ def main(): ) self.add_trigger(triggers.GetEvents()) - self.add_action(actions.ActionOnVulnerabilitySyncBatch()) - - self.add_action(actions.ActionOnVulnerabilitySyncTask()) - self.add_action(actions.CreateGroup()) self.add_action(actions.DeleteDevice()) self.add_action(actions.DeleteGroup()) + self.add_action(actions.DeleteVulnerabilitySyncActionSet()) + + self.add_action(actions.ExecuteVulnerabilitySyncActions()) + self.add_action(actions.GetDeviceByHostname()) self.add_action(actions.GetDeviceByIp()) self.add_action(actions.GetDeviceSoftware()) - self.add_action(actions.GetVulnerabilitySyncBatch()) + self.add_action(actions.GetVulnerabilitySyncActionSet()) self.add_action(actions.ListDevices()) @@ -64,9 +64,11 @@ def main(): self.add_action(actions.ListPolicies()) - self.add_action(actions.ListVulnerabilitySyncBatches()) + self.add_action(actions.ListVulnerabilitySyncActionSetIssues()) + + self.add_action(actions.ListVulnerabilitySyncActionSetSolutions()) - self.add_action(actions.ListVulnerabilitySyncTasks()) + self.add_action(actions.ListVulnerabilitySyncActionSets()) self.add_action(actions.RunCommand()) diff --git a/plugins/automox/help.md b/plugins/automox/help.md index c5236e94a2..f1480a8d05 100644 --- a/plugins/automox/help.md +++ b/plugins/automox/help.md @@ -21,7 +21,7 @@ outcomes on endpoints, and basic Automox platform administration. # Supported Product Versions -* All as of 1/21/2022 +* All as of 10/13/2023 # Documentation @@ -43,7 +43,81 @@ Example input: ## Technical Details -### Actions +### Triggers + +#### Get Automox Events + +This trigger is used to retrieve Automox events to trigger workflows. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|event_type|string|None|True|Name of event type to be retrieved (list of event types found at https://developer.automox.com/openapi/axconsole/operation/getEvents/#!in=query&path=eventName&t=request)|None|https://example.com| +|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| + +Example input: + +``` +{ + "event_type": "user.login", + "org_id": 1234 +} +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|event|event|True|Event with details| + +Example output: + +``` +``` + +#### Actions + +#### Upload Vulnerability Sync File + +This action is used to upload a CSV file to vulnerability sync for processing. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|csv_file|bytes|None|True|Base64 encoded CSV data from which to create the vulnerability sync batch|None|PGgxPlJhcGlkNzwvaDE+| +|csv_file_name|string|https://example.com|False|Name for CSV file uploaded and shown within Automox|None|https://example.com| +|org_id|integer|None|True|Identifier of organization|None|1234| +|report_source|string|generic|False|The third-party source of the vulnerability report|['generic', 'crowd-strike', 'rapid7', 'tenable', 'qualys']|rapid7| + +Example input: + +``` +{ + "csv_file": "PGgxPlJhcGlkNzwvaDE+", + "csv_file_name": "insightconnect-uploaded-report.csv", + "org_id": 1234, + "report_source": "rapid7" +} +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|id|integer|True|Identifier of the vulnerability sync action set| +|status|string|True|Status of the vulnerability sync action set| + +Example output: + +``` +{ + "$success": true, + "id": 1234, + "status": "building" +} +``` #### Update Group @@ -91,31 +165,39 @@ Example output: ``` { + "$success": true, "success": true } ``` -#### Upload Vulnerability Sync File +#### Update Device -This action is used to upload CSV file to vulnerability sync for processing. +This action is used to update Automox device. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|csv_file|bytes|None|True|Base64 encoded CSV data from which to create the vulnerability sync batch|None|PGgxPlJhcGlkNzwvaDE+| -|csv_file_name|string|insightconnect-uploaded-report.csv|False|Name for CSV file uploaded and shown within Automox|None|insightconnect-uploaded-report.csv| -|org_id|integer|None|True|Identifier of organization|None|1234| -|report_source|string|Generic Report|False|The third-party source of the vulnerability report|['Generic Report', 'CrowdStrike', 'Rapid7', 'TenableIO', 'Qualys']|Rapid7| +|custom_name|string|None|False|Custom name to set on device|None|custom-name| +|device_id|integer|None|True|Identifier of device|None|1234| +|exception|boolean|False|True|Exclude the device from reports and statistics|None|False| +|org_id|integer|None|False|Identifier of organization|None|1234| +|server_group_id|integer|None|False|Identifier of server group|None|1234| +|tags|[]string|None|False|List of tags|None|["tag1", "tag2"]| Example input: ``` { - "csv_file": "PGgxPlJhcGlkNzwvaDE+", - "csv_file_name": "insightconnect-uploaded-report.csv", + "custom_name": "custom-name", + "device_id": 1234, + "exception": false, "org_id": 1234, - "report_source": "Rapid7" + "server_group_id": 1234, + "tags": [ + "tag1", + "tag2" + ] } ``` @@ -123,35 +205,42 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|batch_id|integer|True|Identifier of vulnerability sync batch| +|success|boolean|True|Was operation successful| Example output: ``` { - "batch_id": 424 + "$success": true, + "success": true } ``` -#### List Vulnerability Sync Tasks +#### Run Device Command -This action is used to retrieve list of vulnerability sync tasks. +This action is used to run a command on a device. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|batch_id|integer|None|False|Filter by batch identifier|None|1234| -|org_id|integer|None|True|Identifier of organization|None|1234| -|status|string|None|False|Filter by status of tasks|None|in_progress| +|command|string|None|True|Command to run on device|['GetOS', 'InstallUpdate', 'InstallAllUpdates', 'PolicyTest', 'PolicyRemediate', 'Reboot']|GetOS| +|device_id|integer|None|True|Identifier of device|None|1234| +|org_id|integer|None|False|Identifier of organization|None|1234| +|patches|[]string|None|False|List of patches to be installed by name (Note: this only works with the InstallUpdate command)|None|["Security Update (KB4549947)"]| +|policy_id|integer|None|False|Identifier of policy|None|1234| Example input: ``` { - "batch_id": 1234, + "command": "GetOS", + "device_id": 1234, "org_id": 1234, - "status": "in_progress" + "patches": [ + "Security Update (KB4549947)" + ], + "policy_id": 1234 } ``` @@ -159,51 +248,18 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|tasks|[]task|False|List of vulnerability sync tasks| +|success|boolean|True|Was operation successful| Example output: ``` { - "tasks": [ - { - "created_at": "2021-09-24T18:45:04+0000", - "last_updated_by_user": { - "firstname": "John", - "id": 1234, - "lastname": "Smith", - "email": "user@example.com" - }, - "status": "in_progress", - "task_type": "patch-now", - "created_by_user": { - "email": "user@example.com", - "firstname": "John", - "id": 1234, - "lastname": "Smith" - }, - "id": 1234, - "organization_id": 1234, - "payload": { - "severity": "medium", - "package_versions": [ - { - "display_name": "2021-06 Cumulative Update for Windows 10 Version 2...", - "id": "1234", - "name": "f2ac1cd6-4c7f-4481-bf8c-abf3ed49d39b", - "version": "1" - } - ], - "patch_id": "CVE-2021-31952" - }, - "source": "Automox", - "updated_at": "2021-09-24T18:47:11+0000" - } - ] + "$success": true, + "success": true } ``` -#### List Vulnerability Sync Batches +#### List Vulnerability Sync Action Sets This action is used to retrieve list of vulnerability sync batches. @@ -211,13 +267,43 @@ This action is used to retrieve list of vulnerability sync batches. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| +|configuration_id_equals|string|None|False|Filter by configuration ID|None|00000000-0000-0000-0000-000000000000| +|configuration_id_is_set|boolean|None|False|Filter based on whether the configuration ID is set|None|True| +|group_sort|string|None|False|Sort results by field|['asc', 'desc', 'latest_updated_at:asc', 'latest_updated_at:desc', 'source:asc', 'source:desc', '']|latest_updated_at:desc| +|include_all_runs_equals|boolean|None|False|Whether to include all runs in the response|None|True| |org_id|integer|None|True|Identifier of organization|None|1234| +|sort|string|None|False|Sort results by field|['created_at', 'updated_at', 'status', 'source_type', 'source_name', 'configuration_id', '']|created_at| +|source_type_in|[]string|None|False|Filter by source type|None|["Generic Report", "CrowdStrike", "Rapid7", "TenableIO", "Qualys"]| +|status_in|[]string|None|False|Filter by status|None|["building", "ready", "error"]| +|status_not_in|[]string|None|False|Filter by status|None|["building", "ready", "error"]| Example input: ``` { - "org_id": 1234 + "configuration_id_equals": "00000000-0000-0000-0000-000000000000", + "configuration_id_is_set": true, + "group_sort": "latest_updated_at:desc", + "include_all_runs_equals": true, + "org_id": 1234, + "sort": "created_at", + "source_type_in": [ + "Generic Report", + "CrowdStrike", + "Rapid7", + "TenableIO", + "Qualys" + ], + "status_in": [ + "building", + "ready", + "error" + ], + "status_not_in": [ + "building", + "ready", + "error" + ] } ``` @@ -225,55 +311,90 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|batches|[]batch|False|List of vulnerability sync batches| +|action_sets|[]action_set|False|List of vulnerability sync action sets| Example output: ``` { - "batches": [ + "$success": true, + "action_sets": [ { + "created_at": "2023-10-10T03:45:26+0000", + "created_by_user": { + "email": "engineer@example.com", + "firstname": "Engineer", + "id": 1234, + "lastname": "Example" + }, "id": 1234, "organization_id": 1234, - "source": "report.csv", - "status": "awaiting_approval", - "created_by_user": { - "lastname": "Smith", - "email": "user@example.com", - "firstname": "John", - "id": 1234 + "source": { + "name": "insightconnect-uploaded-report.csv", + "type": "generic" }, - "unknown_host_count": 41, - "updated_at": "2021-12-02T20:24:09+0000", - "updated_by_user": { - "id": 43852, - "lastname": "Smith", - "email": "user@example.com", - "firstname": "John" + "statistics": { + "issues": { + "unknown-host": { + "count": 4 + } + }, + "solutions": { + "patch-with-worklet": { + "count": 1, + "device_count": 18, + "vulnerability_count": 1 + } + } }, - "created_at": "2021-12-02T20:24:08+0000" + "status": "ready", + "updated_at": "2023-10-10T03:45:30+0000", + "updated_by_user": { + "email": "engineer@example.com", + "firstname": "Engineer", + "id": 1234, + "lastname": "Example" + } } ] } ``` -#### Get Vulnerability Sync Batch +#### List Vulnerability Sync Action Set Solutions -This action is used to retrieve details for a specified vulnerability sync batch. +This action is used to retrieve a list of vulnerability sync remediations. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|batch_id|integer|None|True|Identifier of batch|None|1234| +|action_set_id|integer|None|True|Filter by action set identifier|None|1234| |org_id|integer|None|True|Identifier of organization|None|1234| +|remediation_type_in|[]string|None|False|Filter by remediation type|None|["patch-now", "patch-with-worklet"]| +|severity_in|[]string|None|False|Filter by severity|None|["critical", "high", "medium", "low", "unknown"]| +|vulnerability_in|[]string|None|False|Filter by vulnerability|None|["CVE-2020-1234", "CVE-2020-5678"]| Example input: ``` { - "batch_id": 1234, - "org_id": 1234 + "action_set_id": 1234, + "org_id": 1234, + "remediation_type_in": [ + "patch-now", + "patch-with-worklet" + ], + "severity_in": [ + "critical", + "high", + "medium", + "low", + "unknown" + ], + "vulnerability_in": [ + "CVE-2020-1234", + "CVE-2020-5678" + ] } ``` @@ -281,59 +402,258 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|batch|batch|True|Details of a specified vulnerability sync batch| +|solutions|[]solution|False|List of vulnerability sync Solutions| Example output: ``` { - "batch": { - "task_count": 2, - "updated_at": "2021-09-24T18:46:22+0000", - "cve_count": 2, - "organization_id": 1234, - "status": "approved", - "impacted_device_count": 6, - "issue_count": 3, - "source": "example.csv", - "unknown_host_count": 2, - "updated_by": { - "firstname": "John", - "id": 1234, - "lastname": "Smith", - "email": "user@example.com" - }, - "created_at": "2021-09-24T18:45:04+0000", - "created_by": { - "email": "user@example.com", - "firstname": "John", + "$success": true, + "solutions": [ + { + "device_ids": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18 + ], + "devices": [ + { + "custom_name": "Unknown", + "id": 1, + "ip_addrs_private": [ + "10.0.0.68", + "fe80::98ad:4391:f22f:d3ae" + ], + "name": "demo-windows2019-0", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 2, + "ip_addrs_private": [ + "10.0.0.244", + "fe80::6910:9c6e:8be4:7b35" + ], + "name": "demo-windows2019-3", + "status": "timed_out" + }, + { + "custom_name": "ip-10-0-0-28", + "id": 3, + "ip_addrs_private": [ + "10.0.0.28", + "fe80::9ddf:1baa:ef6f:32b8" + ], + "name": "ip-10-0-0-28", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 4, + "ip_addrs_private": [ + "10.0.0.209", + "fe80::e112:6743:d6ba:aac" + ], + "name": "ip-10-0-0-209", + "status": "timed_out" + }, + { + "custom_name": "ip-10-0-0-40", + "id": 5, + "ip_addrs_private": [ + "10.0.0.40", + "fe80::f842:e66a:b80e:c396" + ], + "name": "ip-10-0-0-40", + "status": "timed_out" + }, + { + "custom_name": "DESKTOP", + "id": 6, + "ip_addrs_private": [ + "10.0.0.133", + "fe80::ad22:6aa1:6cf1:18b7" + ], + "name": "DESKTOP", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 7, + "ip_addrs_private": [ + "10.0.0.119", + "fe80::b58e:5cd8:c618:3036" + ], + "name": "demo-windows2019-7", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 8, + "ip_addrs_private": [ + "10.0.0.116", + "fe80::9871:3b0e:56c0:8ddc" + ], + "name": "demo-windows2019-2", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 9, + "ip_addrs_private": [ + "10.0.0.74", + "fe80::9c8b:5ae8:6ce9:40d0" + ], + "name": "demo-windows2019-8", + "status": "timed_out" + }, + { + "custom_name": "ip-10-0-0-22", + "id": 10, + "ip_addrs_private": [ + "10.0.0.22", + "fe80::8008:8027:7533:c02d" + ], + "name": "ip-10-0-0-22", + "status": "timed_out" + }, + { + "custom_name": "DESKTOP", + "id": 11, + "ip_addrs_private": [ + "10.0.0.14", + "10.0.0.15", + "169.254.178.151", + "fe80::7894:fefd:f512:4af9", + "fe80::cc6e:37c9:687d:3edc" + ], + "name": "DESKTOP", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 12, + "ip_addrs_private": [ + "10.0.0.173", + "fe80::552:fc9b:fcad:3dbf" + ], + "name": "demo-windows2019-1", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 13, + "ip_addrs_private": [ + "10.0.0.160", + "fe80::540c:5365:3ef2:56de" + ], + "name": "demo-windows2019-4", + "status": "timed_out" + }, + { + "custom_name": "ip-10-0-0-227", + "id": 14, + "ip_addrs_private": [ + "10.0.0.227", + "fe80::a1eb:2ed7:5d55:a009" + ], + "name": "ip-10-0-0-227", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 15, + "ip_addrs_private": [ + "10.0.0.6", + "fe80::79ec:127f:8af1:2266" + ], + "name": "demo-windows2019-6", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "id": 16, + "ip_addrs_private": [ + "10.0.0.214", + "fe80::f5f3:b5b2:972c:b51f" + ], + "name": "demo-windows2019-5", + "status": "timed_out" + }, + { + "custom_name": "ip-10-0-0-42", + "id": 17, + "ip_addrs_private": [ + "10.0.0.42", + "fe80::18a5:516d:6c66:c516" + ], + "name": "ip-10-0-0-42", + "status": "timed_out" + }, + { + "custom_name": "Unknown", + "deleted": true, + "id": 18, + "ip_addrs_private": [ + "10.0.0.253", + "fe80::e141:1176:a4e0:6093" + ], + "name": "demo-windows2019-9", + "status": "timed_out" + } + ], "id": 1234, - "lastname": "Smith" - }, - "id": 45 - } + "organization_id": 1234, + "remediation_type": "patch-with-worklet", + "solution_type": "unmatched", + "vulnerabilities": [ + { + "id": "CVE-2021-24111", + "severity": "high", + "title": ".NET Framework Denial of Service Vulnerability" + } + ] + } + ] } ``` -#### Execute or Cancel Vulnerability Sync Task +#### List Vulnerability Sync Action Set Issues -This action is used to take action to execute or cancel vulnerability sync task. +This action is used to retrieve the issues identified for a specified vulnerability sync action set. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|action|string|None|True|Action to take on vulnerability sync task|['execute', 'cancel']|execute| +|action_set_id|integer|None|True|Identifier of the action set|None|1234| +|issue_type_in|[]string|None|False|Filter by issue type|None|["unknown-host"]| |org_id|integer|None|True|Identifier of organization|None|1234| -|task_id|integer|None|True|Identifier of task|None|1234| Example input: ``` { - "action": "execute", - "org_id": 1234, - "task_id": 1234 + "action_set_id": 1234, + "issue_type_in": [ + "unknown-host" + ], + "org_id": 1234 } ``` @@ -341,34 +661,60 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|success|boolean|True|Was operation successful| +|issues|[]action_set_issue|True|Issues associated with the specified vulnerability sync action_set| Example output: ``` { - "success": true + "$success": true, + "issues": [ + { + "id": 1237, + "issue_details": { + "hostname": "win2016-demo" + }, + "issue_type": "unknown-host" + }, + { + "id": 1236, + "issue_details": { + "hostname": "Win10-VM-1" + }, + "issue_type": "unknown-host" + }, + { + "id": 1235, + "issue_details": { + "hostname": "windows2019-1" + }, + "issue_type": "unknown-host" + }, + { + "id": 1234, + "issue_details": { + "hostname": "windows2019-0" + }, + "issue_type": "unknown-host" + } + ] } ``` -#### Accept or Reject Vulnerability Sync Batch +#### List Policies -This action is used to take action to approve or reject vulnerability sync batch. +This action is used to retrieve Automox policies. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|action|string|None|True|Action to take on batch|['accept', 'reject']|accept| -|batch_id|integer|None|True|Identifier of batch|None|1234| -|org_id|integer|None|True|Identifier of organization|None|1234| +|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| Example input: ``` { - "action": "accept", - "batch_id": 1234, "org_id": 1234 } ``` @@ -377,56 +723,56 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|success|boolean|True|Was operation successful| +|policies|[]policy|False|List of Automox policies| Example output: ``` -{ - "success": true -} ``` -#### Run Device Command +#### List Organizations + +This action is used to retrieve Automox organizations. + +##### Input + +_This action does not contain any inputs._ + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|organizations|[]organization|True|List of Automox organizations| + +Example output: + +``` +``` -This action is used to run a command on the device. +#### List Organization Users + +This action is used to retrieve users of the Automox organization. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|command|string|None|True|Command to run on device|['GetOS', 'InstallUpdate', 'InstallAllUpdates', 'PolicyTest', 'PolicyRemediate', 'Reboot']|GetOS| -|device_id|integer|None|True|Identifier of device|None|1234| -|org_id|integer|None|False|Identifier of organization|None|1234| -|patches|[]string|None|False|List of patches to be installed by name (Note: this only works with the InstallUpdate command)|None|["Security Update (KB4549947)"]| -|policy_id|integer|None|False|Identifier of policy|None|1234| +|org_id|integer|None|True|Identifier of organization|None|1234| Example input: ``` -{ - "command": "GetOS", - "device_id": 1234, - "org_id": 1234, - "patches": [ - "Security Update (KB4549947)" - ], - "policy_id": 1234 -} ``` ##### Output |Name|Type|Required|Description| |----|----|--------|-----------| -|success|boolean|True|Was operation successful| +|users|[]user|False|List of Automox users| Example output: ``` -{ - "success": true -} ``` #### List Groups @@ -456,46 +802,24 @@ Example input: Example output: ``` -{ - "groups": [ - { - "id": 1234, - "organization_id": 1234, - "parent_server_group_id": 1234, - "policies": [ - 1234, - 5678 - ], - "refresh_interval": 360, - "server_count": 6, - "ui_color": "#059F1D", - "wsus_config": { - "created_at": "2020-11-03T00:22:06+0000", - "id": 21606, - "server_group_id": 0, - "updated_at": "2020-11-03T00:22:06+0000" - } - } - ] -} ``` -#### Get Device Software +#### Get Vulnerability Sync Action Set -This action is used to retrieve a list of software installed on the device. +This action is used to retrieve details for a specified vulnerability sync action set. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|device_id|integer|None|True|Identifier of device|None|1234| -|org_id|integer|None|False|Identifier of organization|None|1234| +|action_set_id|integer|None|True|Identifier of the action set|None|1234| +|org_id|integer|None|True|Identifier of organization|None|1234| Example input: ``` { - "device_id": 1234, + "action_set_id": 1234, "org_id": 1234 } ``` @@ -504,51 +828,55 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|software|[]device_software|False|List of software on device| +|action_set|action_set|True|Details of a specified vulnerability sync action_set| Example output: ``` { - "software": [ - { - "display_name": "NetworkManager-libnm.x86_64", - "organization_id": 1234, - "repo": "Linux", - "version": "1.30.2-1.fc34", - "create_time": "2021-04-06T08:11:00+0000", - "id": 1235371145, - "is_managed": true, - "os_name": "Fedora", - "os_version_id": 4416, - "name": "NetworkManager-libnm.x86_64", - "os_version": "34", - "package_id": 1234, - "installed": true, - "package_version_id": 1234, - "server_id": 1234, - "software_id": 1234 + "$success": true, + "action_set": { + "created_at": "2023-10-29T21:25:18+0000", + "created_by_user": { + "email": "engineer@example.com", + "firstname": "Engineer", + "id": 1234, + "lastname": "Example" + }, + "id": 1234, + "organization_id": 1234, + "source": { + "name": "insightconnect-uploaded-report.csv", + "type": "generic" + }, + "status": "building", + "updated_at": "2023-10-29T21:25:18+0000", + "updated_by_user": { + "email": "engineer@example.com", + "firstname": "Engineer", + "id": 1234, + "lastname": "Example" } - ] + } } ``` -#### Delete Group +#### Get Device by IP Address -This action is used to delete an Automox group. +This action is used to find an Automox device by IP address. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|group_id|integer|None|True|Identifier of the Automox group|None|1234| -|org_id|integer|None|False|Identifier of organization|None|1234| +|ip_address|string|None|True|IP address of device|None|https://example.com| +|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| Example input: ``` { - "group_id": 1234, + "ip_address": "192.168.0.1", "org_id": 1234 } ``` @@ -557,16 +885,44 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|success|boolean|True|Was operation successful| +|device|device|False|The matched Automox device| Example output: +``` +``` + +#### Get Device by Hostname + +This action is used to find an Automox device by hostname. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|hostname|string|None|True|Hostname of device|None|hostname-1| +|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| + +Example input: + ``` { - "success": true + "hostname": "hostname-1", + "org_id": 1234 } ``` +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|device|device|False|The matched Automox device| + +Example output: + +``` +``` + #### Create Group This action is used to create an Automox group. @@ -612,14 +968,26 @@ Example output: ``` { + "$success": true, "group": { - "organization_id": 1234, - "parent_server_group_id": 0, - "refresh_interval": 1440, - "ui_color": "#059F1D", "id": 1234, - "name": "InsightConnect Test Group", - "notes": "Hello World" + "name": "InsightConnect", + "organization": { + "bill_overages": true, + "billing_interval": "month", + "billing_interval_count": 1, + "create_time": "2022-06-03 20:22:52.261394", + "id": 1234, + "legacy_billing": true, + "name": "InsightConnect", + "rate_id": 1234, + "sub_plan": "TIER3", + "updated_at": "2022-06-03 20:22:52.261394", + "uuid": "a4f7ceab-4bc2-4588-abe7-25af271f1156" + }, + "organization_id": 1234, + "parent_server_group_id": 1234, + "refresh_interval": 1440 }, "success": true } @@ -627,7 +995,7 @@ Example output: #### Delete Device -This action is used to delete Automox device. +This action is used to delete an Automox device. ##### Input @@ -655,125 +1023,27 @@ Example output: ``` { + "$success": true, "success": true } ``` -#### Get Device by Hostname - -This action is used to find an Automox device by hostname. - -##### Input - -|Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|hostname|string|None|True|Hostname of device|None|hostname-1| -|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| - -Example input: - -``` -{ - "hostname": "hostname-1", - "org_id": 1234 -} -``` - -##### Output - -|Name|Type|Required|Description| -|----|----|--------|-----------| -|device|device|False|The matched Automox device| - -Example output: - -``` -{ - "device": { - "agent_version": "1.0-33", - "compliant": true, - "create_time": "2021-08-03T15:53:59+0000", - "detail": { - "CPU": "Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz", - "FQDNS": [ - "hostname.local" - ], - "IPS": [ - "192.168.0.1" - ] - }, - "display_name": "hostname", - "id": 1234, - "ip_addrs": [ - "192.168.0.1" - ], - "ip_addrs_private": [ - "192.168.0.1" - ], - "is_compatible": true, - "last_disconnect_time": "2021-10-22T13:56:46+0000", - "last_logged_in_user": "jsmith", - "last_refresh_time": "2021-10-22T13:54:10+0000", - "name": "hostname.local", - "organization_id": 1234, - "os_family": "Mac", - "os_name": "OS X", - "os_version": "11.4", - "os_version_id": 4476, - "patches": 4, - "policy_status": [ - { - "create_time": "2021-10-22T13:54:10+0000", - "id": 1234, - "organization_id": 1234, - "policy_id": 1234, - "policy_name": "Manual Patching", - "policy_type_name": "patch", - "result": "{}", - "server_id": 1234, - "status": 1 - } - ], - "refresh_interval": 360, - "serial_number": "abcd", - "server_group_id": 1234, - "status": { - "agent_status": "disconnected", - "device_status": "not-ready", - "policy_status": "compliant", - "policy_statuses": [ - { - "compliant": true, - "id": 1234 - } - ] - }, - "tags": [ - "tag1" - ], - "timezone": "UTC-0700", - "total_count": 5, - "uuid": "abc12345-abc1-2345-abc1-abc123456789" - } -} -``` - -#### Get Device by IP Address +#### Delete Group -This action is used to find an Automox device by IP address. +This action is used to delete an Automox group. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|ip_address|string|None|True|IP address of device|None|192.168.0.1| -|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| +|group_id|integer|None|True|Identifier of the Automox group|None|1234| +|org_id|integer|None|False|Identifier of organization|None|1234| Example input: ``` { - "ip_address": "192.168.0.1", + "group_id": 1234, "org_id": 1234 } ``` @@ -782,97 +1052,33 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|device|device|False|The matched Automox device| +|success|boolean|True|Was operation successful| Example output: ``` { - "device": { - "agent_version": "1.0-33", - "compliant": true, - "create_time": "2021-08-03T15:53:59+0000", - "detail": { - "CPU": "Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz", - "FQDNS": [ - "hostname.local" - ], - "IPS": [ - "192.168.0.1" - ] - }, - "display_name": "hostname", - "id": 1234, - "ip_addrs": [ - "192.168.0.1" - ], - "ip_addrs_private": [ - "192.168.0.1" - ], - "is_compatible": true, - "last_disconnect_time": "2021-10-22T13:56:46+0000", - "last_logged_in_user": "jsmith", - "last_refresh_time": "2021-10-22T13:54:10+0000", - "name": "hostname.local", - "organization_id": 1234, - "os_family": "Mac", - "os_name": "OS X", - "os_version": "11.4", - "os_version_id": 4476, - "patches": 4, - "policy_status": [ - { - "create_time": "2021-10-22T13:54:10+0000", - "id": 1234, - "organization_id": 1234, - "policy_id": 1234, - "policy_name": "Manual Patching", - "policy_type_name": "patch", - "result": "{}", - "server_id": 1234, - "status": 1 - } - ], - "refresh_interval": 360, - "serial_number": "abcd", - "server_group_id": 1234, - "status": { - "agent_status": "disconnected", - "device_status": "not-ready", - "policy_status": "compliant", - "policy_statuses": [ - { - "compliant": true, - "id": 1234 - } - ] - }, - "tags": [ - "tag1" - ], - "timezone": "UTC-0700", - "total_count": 5, - "uuid": "abc12345-abc1-2345-abc1-abc123456789" - } + "$success": true, + "success": true } ``` -#### List Devices +#### Delete Vulnerability Sync Action Set -This action is used to retrieve Automox managed devices. +This action is used to delete a vulnerability sync action set and all associated data. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|group_id|integer|None|False|Identifier of server group|None|1234| -|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| +|action_set_id|integer|None|True|Identifier of the action set|None|1234| +|org_id|integer|None|True|Identifier of organization|None|1234| Example input: ``` { - "group_id": 1234, + "action_set_id": 1234, "org_id": 1234 } ``` @@ -881,203 +1087,47 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|devices|[]device|False|List of Automox managed devices| +|success|boolean|True|Was operation successful| Example output: ``` { - "devices": [ - { - "agent_version": "1.0-33", - "compliant": true, - "create_time": "2021-08-03T15:53:59+0000", - "detail": { - "CPU": "Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz", - "FQDNS": [ - "hostname.local" - ], - "IPS": [ - "192.168.0.1" - ] - }, - "display_name": "hostname", - "id": 1234, - "ip_addrs": [ - "192.168.0.1" - ], - "ip_addrs_private": [ - "192.168.0.1" - ], - "is_compatible": true, - "last_disconnect_time": "2021-10-22T13:56:46+0000", - "last_logged_in_user": "jsmith", - "last_refresh_time": "2021-10-22T13:54:10+0000", - "name": "hostname.local", - "organization_id": 1234, - "os_family": "Mac", - "os_name": "OS X", - "os_version": "11.4", - "os_version_id": 4476, - "patches": 4, - "policy_status": [ - { - "create_time": "2021-10-22T13:54:10+0000", - "id": 1234, - "organization_id": 1234, - "policy_id": 1234, - "policy_name": "Manual Patching", - "policy_type_name": "patch", - "result": "{}", - "server_id": 1234, - "status": 1 - } - ], - "refresh_interval": 360, - "serial_number": "abcd", - "server_group_id": 1234, - "status": { - "agent_status": "disconnected", - "device_status": "not-ready", - "policy_status": "compliant", - "policy_statuses": [ - { - "compliant": true, - "id": 1234 - } - ] - }, - "tags": [ - "tag1" - ], - "timezone": "UTC-0700", - "total_count": 5, - "uuid": "abc12345-abc1-2345-abc1-abc123456789" - } - ] + "$success": true, + "success": true } ``` -#### List Organization Users +#### Execute Vulnerability Sync Actions -This action is used to retrieve users of the Automox organization. +This action is used to launch remediation for patch and worklet remediations. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| +|action_set_id|integer|None|True|Identifier of the action set|None|1234| +|actions|[]action_set_action|None|True|List of remediations to execute|None|[None, None]| |org_id|integer|None|True|Identifier of organization|None|1234| Example input: -``` -{ - "org_id": 1234 -} ``` -##### Output - -|Name|Type|Required|Description| -|----|----|--------|-----------| -|users|[]user|False|List of Automox users| - -Example output: - -``` -{ - "users": [ - { - "email": "user@example.com", - "features": { - "mo": true - }, - "firstname": "John", - "id": 1234, - "lastname": "Smith", - "orgs": [ - { - "id": 1234, - "name": "Organization" - } - ], - "prefs": [ - { - "pref_name": "notify.system.add", - "user_id": 1234, - "value": "true" - } - ], - "rbac_roles": [ - { - "description": "Provides full administrative rights to the entire Automox System.", - "id": 1, - "name": "Full Administrator", - "organization_id": 1234 - } - ], - "tags": [ - "tag1" - ], - "uuid": "abc12345-abc1-2345-abc1-abc123456789" - } - ] -} ``` -#### List Organizations - -This action is used to retrieve Automox organizations. - -##### Input - -_This action does not contain any inputs._ - ##### Output |Name|Type|Required|Description| |----|----|--------|-----------| -|organizations|[]organization|True|List of Automox organizations| +|success|boolean|True|Was operation successful| Example output: ``` { - "organizations": [ - { - "access_key": "abc12345-abc1-2345-abc1-abc123456789", - "bill_overages": true, - "create_time": "2019-08-27T21:59:19+0000", - "device_count": 21, - "metadata": { - "patchServersDone": true - }, - "name": "Automox Org", - "sub_plan": "FULL", - "id": 1234, - "legacy_billing": true, - "parent_id": 1, - "rate_id": 1 - } - ] -} -``` - -#### List Policies - -This action is used to retrieve Automox policies. - -##### Input - -|Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|org_id|integer|None|False|Identifier of organization to restrict results|None|1234| - -Example input: - -``` -{ - "org_id": 1234 + "$success": true, + "success": true } ``` @@ -1085,66 +1135,30 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|policies|[]policy|False|List of Automox policies| +|device|device|False|The matched Automox device| Example output: ``` -{ - "policies": [ - { - "configuration": { - "auto_patch": true, - "auto_reboot": true - }, - "create_time": "2021-03-03T21:29:09+0000", - "id": 1234, - "name": "Patch All", - "next_remediation": "2021-12-15T00:00:00+0000", - "organization_id": 1234, - "policy_type_name": "patch", - "schedule_days": 254, - "schedule_months": 8190, - "schedule_time": "00:00", - "schedule_weeks_of_month": 62, - "server_count": 1, - "server_groups": [ - 1234, - 5678 - ] - } - ] -} ``` -#### Update Device +#### Get Device Software -This action is used to update Automox device. +This action is used to retrieve a list of software installed on a device. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|custom_name|string|None|False|Custom name to set on device|None|custom-name| |device_id|integer|None|True|Identifier of device|None|1234| -|exception|boolean|False|True|Exclude the device from reports and statistics|None|False| |org_id|integer|None|False|Identifier of organization|None|1234| -|server_group_id|integer|None|False|Identifier of server group|None|1234| -|tags|[]string|None|False|List of tags|None|["tag1", "tag2"]| Example input: ``` { - "custom_name": "custom-name", "device_id": 1234, - "exception": false, - "org_id": 1234, - "server_group_id": 1234, - "tags": [ - "tag1", - "tag2" - ] + "org_id": 1234 } ``` @@ -1152,34 +1166,29 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|success|boolean|True|Was operation successful| +|software|[]device_software|False|List of software on device| Example output: ``` -{ - "success": true -} ``` -### Triggers - -#### Get Automox Events +#### List Devices -This trigger is used to retrieve Automox events to trigger workflows. +This action is used to retrieve Automox managed devices. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|event_type|string|None|True|Name of event type to be retrieved (list of event types found at https://developer.automox.com/openapi/axconsole/operation/getEvents/#!in=query&path=eventName&t=request)|None|user.login| +|group_id|integer|None|False|Identifier of server group|None|1234| |org_id|integer|None|False|Identifier of organization to restrict results|None|1234| Example input: ``` { - "event_type": "user.login", + "group_id": 1234, "org_id": 1234 } ``` @@ -1188,50 +1197,30 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|event|event|True|Event with details| +|devices|[]device|False|List of Automox managed devices| Example output: ``` -{ - "event": { - "id": 1234, - "name": "system.delete", - "server_id": 1234, - "organization_id": 1234, - "data": { - "ip": "192.168.0.1", - "os": "Ubuntu", - "systemname": "hostname-1" - }, - "server_name": "hostname-1", - "create_time": "2021-12-16 06:20:38.153713" - } -} ``` -### Custom Output Types - -#### device - -|Name|Type|Required|Description| -|----|----|--------|-----------| -|Device ID|integer|True|The device ID| -|Device Name|string|True|The device name| -|Organization ID|integer|True|The organization ID of the device| -|Server Group ID|integer|True|The server group ID of the device| -|Device UUID|string|True|The device unique identifier| - - ## Troubleshooting _This plugin does not contain any troubleshooting information._ # Version History -* 1.2.0 - Get device by IP and Get device by hostname: fix validation issue when IP or hostname not found | Add unit tests +* 2.0.0 - Fix Vulnerability Sync API Actions | Add Delete Vulnerability Sync Action Set action | Add Execute + Vulnerability Sync Actions action | Add List Vulnerability Sync Action Set Issues + action | Add List Vulnerability Sync Action Set Solutions action | Add List Vulnerability Sync Action Sets action | + | Add Get Vulnerability Sync Action Set action | Update Upload Vulnerability Sync File action + | Update Get Devices action | Remove Action on Vulnerability Sync Batch | Remove Action on Vulnerability Sync Task + | Remove Get Vulnerability Sync Batch | Remove List Vulnerability Sync Batches | Remove List Vulnerability Sync Tasks +* 1.2.0 - Get device by IP and Get device by hostname: fix validation issue when IP or hostname not found | Add unit + tests * 1.1.1 - Fix undefined org ID passed to actions when not required | Record outcome of connection tests -* 1.1.0 - Add `report source` as optional input parameter to Upload Vulnerability Sync File action | Add report source to batch type +* 1.1.0 - Add `report source` as optional input parameter to Upload Vulnerability Sync File action | Add report source + to batch type * 1.0.0 - Initial plugin # Links diff --git a/plugins/automox/icon_automox/actions/__init__.py b/plugins/automox/icon_automox/actions/__init__.py index 3b960c99b1..d894a3ebe9 100755 --- a/plugins/automox/icon_automox/actions/__init__.py +++ b/plugins/automox/icon_automox/actions/__init__.py @@ -1,20 +1,21 @@ # GENERATED BY KOMAND SDK - DO NOT EDIT -from .action_on_vulnerability_sync_batch.action import ActionOnVulnerabilitySyncBatch -from .action_on_vulnerability_sync_task.action import ActionOnVulnerabilitySyncTask from .create_group.action import CreateGroup from .delete_device.action import DeleteDevice from .delete_group.action import DeleteGroup +from .delete_vulnerability_sync_action_set.action import DeleteVulnerabilitySyncActionSet +from .execute_vulnerability_sync_actions.action import ExecuteVulnerabilitySyncActions from .get_device_by_hostname.action import GetDeviceByHostname from .get_device_by_ip.action import GetDeviceByIp from .get_device_software.action import GetDeviceSoftware -from .get_vulnerability_sync_batch.action import GetVulnerabilitySyncBatch +from .get_vulnerability_sync_action_set.action import GetVulnerabilitySyncActionSet from .list_devices.action import ListDevices from .list_groups.action import ListGroups from .list_organization_users.action import ListOrganizationUsers from .list_organizations.action import ListOrganizations from .list_policies.action import ListPolicies -from .list_vulnerability_sync_batches.action import ListVulnerabilitySyncBatches -from .list_vulnerability_sync_tasks.action import ListVulnerabilitySyncTasks +from .list_vulnerability_sync_action_set_issues.action import ListVulnerabilitySyncActionSetIssues +from .list_vulnerability_sync_action_set_solutions.action import ListVulnerabilitySyncActionSetSolutions +from .list_vulnerability_sync_action_sets.action import ListVulnerabilitySyncActionSets from .run_command.action import RunCommand from .update_device.action import UpdateDevice from .update_group.action import UpdateGroup diff --git a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/__init__.py b/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/__init__.py deleted file mode 100755 index e840bae0ad..0000000000 --- a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import ActionOnVulnerabilitySyncBatch diff --git a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/action.py b/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/action.py deleted file mode 100755 index 103e6c9bf4..0000000000 --- a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/action.py +++ /dev/null @@ -1,21 +0,0 @@ -import insightconnect_plugin_runtime -from .schema import ActionOnVulnerabilitySyncBatchInput, ActionOnVulnerabilitySyncBatchOutput, Input, Output, Component - -# Custom imports below - - -class ActionOnVulnerabilitySyncBatch(insightconnect_plugin_runtime.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="action_on_vulnerability_sync_batch", - description=Component.DESCRIPTION, - input=ActionOnVulnerabilitySyncBatchInput(), - output=ActionOnVulnerabilitySyncBatchOutput(), - ) - - def run(self, params={}): - self.connection.automox_api.update_vulnerability_sync_batch( - params.get(Input.ORG_ID), params.get(Input.BATCH_ID), params.get(Input.ACTION) - ) - - return {Output.SUCCESS: True} diff --git a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/__init__.py b/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/__init__.py deleted file mode 100755 index 7e4f2ca0c5..0000000000 --- a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import ActionOnVulnerabilitySyncTask diff --git a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/action.py b/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/action.py deleted file mode 100755 index 844e074dd1..0000000000 --- a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/action.py +++ /dev/null @@ -1,21 +0,0 @@ -import insightconnect_plugin_runtime -from .schema import ActionOnVulnerabilitySyncTaskInput, ActionOnVulnerabilitySyncTaskOutput, Input, Output, Component - -# Custom imports below - - -class ActionOnVulnerabilitySyncTask(insightconnect_plugin_runtime.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="action_on_vulnerability_sync_task", - description=Component.DESCRIPTION, - input=ActionOnVulnerabilitySyncTaskInput(), - output=ActionOnVulnerabilitySyncTaskOutput(), - ) - - def run(self, params={}): - self.connection.automox_api.update_vulnerability_sync_task( - params.get(Input.ORG_ID), params.get(Input.TASK_ID), params.get(Input.ACTION) - ) - - return {Output.SUCCESS: True} diff --git a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/schema.py b/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/schema.py deleted file mode 100755 index 6c8c5bf882..0000000000 --- a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_task/schema.py +++ /dev/null @@ -1,81 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import insightconnect_plugin_runtime -import json - - -class Component: - DESCRIPTION = "Take action to execute or cancel a vulnerability sync task" - - -class Input: - ACTION = "action" - ORG_ID = "org_id" - TASK_ID = "task_id" - - -class Output: - SUCCESS = "success" - - -class ActionOnVulnerabilitySyncTaskInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "action": { - "type": "string", - "title": "Action", - "description": "Action to take on vulnerability sync task", - "enum": [ - "execute", - "cancel" - ], - "order": 3 - }, - "org_id": { - "type": "integer", - "title": "Organization ID", - "description": "Identifier of organization", - "order": 1 - }, - "task_id": { - "type": "integer", - "title": "Task ID", - "description": "Identifier of task", - "order": 2 - } - }, - "required": [ - "action", - "org_id", - "task_id" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class ActionOnVulnerabilitySyncTaskOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "success": { - "type": "boolean", - "title": "Success", - "description": "Was operation successful", - "order": 1 - } - }, - "required": [ - "success" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/__init__.py b/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/__init__.py new file mode 100755 index 0000000000..bd399cf4b6 --- /dev/null +++ b/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import DeleteVulnerabilitySyncActionSet diff --git a/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/action.py b/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/action.py new file mode 100755 index 0000000000..84f75ce3d7 --- /dev/null +++ b/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/action.py @@ -0,0 +1,22 @@ +import insightconnect_plugin_runtime +from .schema import DeleteVulnerabilitySyncActionSetInput, DeleteVulnerabilitySyncActionSetOutput, Input, Output, Component +# Custom imports below + + +class DeleteVulnerabilitySyncActionSet(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='delete_vulnerability_sync_action_set', + description=Component.DESCRIPTION, + input=DeleteVulnerabilitySyncActionSetInput(), + output=DeleteVulnerabilitySyncActionSetOutput()) + + def run(self, params={}): + org_id = params.get(Input.ORG_ID) + action_set_id = params.get(Input.ACTION_SET_ID) + resp = self.connection.automox_api.delete_vulnerability_sync_action_set( + org_id, + action_set_id + ) + return {Output.SUCCESS: resp} diff --git a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/schema.py b/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/schema.py similarity index 62% rename from plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/schema.py rename to plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/schema.py index 78afa0e647..4392cde3ea 100755 --- a/plugins/automox/icon_automox/actions/action_on_vulnerability_sync_batch/schema.py +++ b/plugins/automox/icon_automox/actions/delete_vulnerability_sync_action_set/schema.py @@ -4,12 +4,11 @@ class Component: - DESCRIPTION = "Take action to approve or reject vulnerability sync batch" + DESCRIPTION = "Delete a vulnerability sync action set and all associated data" class Input: - ACTION = "action" - BATCH_ID = "batch_id" + ACTION_SET_ID = "action_set_id" ORG_ID = "org_id" @@ -17,26 +16,16 @@ class Output: SUCCESS = "success" -class ActionOnVulnerabilitySyncBatchInput(insightconnect_plugin_runtime.Input): +class DeleteVulnerabilitySyncActionSetInput(insightconnect_plugin_runtime.Input): schema = json.loads(""" { "type": "object", "title": "Variables", "properties": { - "action": { - "type": "string", - "title": "Action", - "description": "Action to take on batch", - "enum": [ - "accept", - "reject" - ], - "order": 3 - }, - "batch_id": { + "action_set_id": { "type": "integer", - "title": "Batch ID", - "description": "Identifier of batch", + "title": "Action Set ID", + "description": "Identifier of the action set", "order": 2 }, "org_id": { @@ -47,8 +36,7 @@ class ActionOnVulnerabilitySyncBatchInput(insightconnect_plugin_runtime.Input): } }, "required": [ - "action", - "batch_id", + "action_set_id", "org_id" ] } @@ -58,7 +46,7 @@ def __init__(self): super(self.__class__, self).__init__(self.schema) -class ActionOnVulnerabilitySyncBatchOutput(insightconnect_plugin_runtime.Output): +class DeleteVulnerabilitySyncActionSetOutput(insightconnect_plugin_runtime.Output): schema = json.loads(""" { "type": "object", diff --git a/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/__init__.py b/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/__init__.py new file mode 100755 index 0000000000..9b7018f50a --- /dev/null +++ b/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import ExecuteVulnerabilitySyncActions diff --git a/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/action.py b/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/action.py new file mode 100755 index 0000000000..a511201774 --- /dev/null +++ b/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/action.py @@ -0,0 +1,48 @@ +import insightconnect_plugin_runtime +from .schema import ExecuteVulnerabilitySyncActionsInput, ExecuteVulnerabilitySyncActionsOutput, Input, Output, Component + + +# Custom imports below + + +class ExecuteVulnerabilitySyncActions(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='execute_vulnerability_sync_actions', + description=Component.DESCRIPTION, + input=ExecuteVulnerabilitySyncActionsInput(), + output=ExecuteVulnerabilitySyncActionsOutput()) + + def run(self, params={}): + org_id = params.get(Input.ORG_ID) + action_set_id = params.get(Input.ACTION_SET_ID) + actions = params.get(Input.ACTIONS) + if actions is None or len(actions) == 0: + raise insightconnect_plugin_runtime.exceptions.PluginException( + cause="Invalid input", + assistance="Actions cannot be empty." + ) + formatted_actions = [] + for action in actions: + fa = { + "action": action.get("action"), + "solutionId": action.get("solution_id"), + "devices": action.get("device_ids"), + } + if action.get("action") == "patch-with-worklet": + if action.get("worklet_id"): + fa["workletId"] = action.get("worklet_id") + else: + raise insightconnect_plugin_runtime.exceptions.PluginException( + cause="Invalid input", + assistance="'worklet_id' cannot be empty when the action is set to 'patch-with-worklet'" + ) + formatted_actions.append(fa) + + resp = self.connection.automox_api.execute_vulnerability_sync_actions( + org_id, + action_set_id, + formatted_actions + ) + return {Output.SUCCESS: resp is None} diff --git a/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/schema.py b/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/schema.py new file mode 100755 index 0000000000..3e5490c100 --- /dev/null +++ b/plugins/automox/icon_automox/actions/execute_vulnerability_sync_actions/schema.py @@ -0,0 +1,109 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Launch remediation for patch and worklet remediations" + + +class Input: + ACTION_SET_ID = "action_set_id" + ACTIONS = "actions" + ORG_ID = "org_id" + + +class Output: + SUCCESS = "success" + + +class ExecuteVulnerabilitySyncActionsInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "action_set_id": { + "type": "integer", + "title": "Action Set ID", + "description": "Identifier of the action set", + "order": 2 + }, + "actions": { + "type": "array", + "title": "Actions", + "description": "List of remediations to execute", + "items": { + "$ref": "#/definitions/action_set_action" + }, + "order": 3 + }, + "org_id": { + "type": "integer", + "title": "Organization ID", + "description": "Identifier of organization", + "order": 1 + } + }, + "required": [ + "action_set_id", + "actions", + "org_id" + ], + "definitions": { + "action_set_action": { + "type": "object", + "title": "action_set_action", + "properties": { + "action": { + "type": "string", + "title": "Action", + "description": "The action to execute for the associated remediation", + "default": "patch-now", + "enum": [ + "patch-now", + "patch-with-worklet" + ], + "order": 1 + }, + "solution_id": { + "type": "integer", + "title": "Solution ID", + "description": "The solution ID associated with the action", + "order": 2 + } + }, + "required": [ + "action", + "solution_id" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class ExecuteVulnerabilitySyncActionsOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "success": { + "type": "boolean", + "title": "Success", + "description": "Was operation successful", + "order": 1 + } + }, + "required": [ + "success" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/__init__.py b/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/__init__.py new file mode 100755 index 0000000000..3408b6bb09 --- /dev/null +++ b/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import GetVulnerabilitySyncActionSet diff --git a/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/action.py b/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/action.py new file mode 100755 index 0000000000..fcf657396b --- /dev/null +++ b/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/action.py @@ -0,0 +1,27 @@ +import insightconnect_plugin_runtime +from .schema import GetVulnerabilitySyncActionSetInput, GetVulnerabilitySyncActionSetOutput, Input, Output, Component + + +# Custom imports below +from icon_automox.util.cleaner import clean_ax_response + + +class GetVulnerabilitySyncActionSet(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='get_vulnerability_sync_action_set', + description=Component.DESCRIPTION, + input=GetVulnerabilitySyncActionSetInput(), + output=GetVulnerabilitySyncActionSetOutput()) + + def run(self, params={}): + org_id = params.get(Input.ORG_ID) + action_set_id = params.get(Input.ACTION_SET_ID) + resp = self.connection.automox_api.get_vulnerability_sync_action_set( + org_id, + action_set_id + ) + resp = clean_ax_response(resp) + + return {Output.ACTION_SET: resp} diff --git a/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/schema.py b/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/schema.py new file mode 100755 index 0000000000..f25046b93c --- /dev/null +++ b/plugins/automox/icon_automox/actions/get_vulnerability_sync_action_set/schema.py @@ -0,0 +1,456 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Retrieve details for a specified vulnerability sync action set" + + +class Input: + ACTION_SET_ID = "action_set_id" + ORG_ID = "org_id" + + +class Output: + ACTION_SET = "action_set" + + +class GetVulnerabilitySyncActionSetInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "action_set_id": { + "type": "integer", + "title": "Action Set ID", + "description": "Identifier of the action set", + "order": 2 + }, + "org_id": { + "type": "integer", + "title": "Organization ID", + "description": "Identifier of organization", + "order": 1 + } + }, + "required": [ + "action_set_id", + "org_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class GetVulnerabilitySyncActionSetOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "action_set": { + "$ref": "#/definitions/action_set", + "title": "Vulnerability Sync action set", + "description": "Details of a specified vulnerability sync action_set", + "order": 1 + } + }, + "required": [ + "action_set" + ], + "definitions": { + "action_set": { + "type": "object", + "title": "action_set", + "properties": { + "configuration_id": { + "type": "string", + "title": "Configuration ID", + "description": "Identifier of the configuration, only applicable for Automated Vulnerability Remediation (AVR) action sets", + "order": 4 + }, + "created_at": { + "type": "string", + "title": "Created At", + "description": "Datetime the action set was created", + "order": 9 + }, + "created_by": { + "$ref": "#/definitions/action_set_user", + "title": "Created By", + "description": "action set creation details", + "order": 8 + }, + "id": { + "type": "integer", + "title": "Action Set ID", + "description": "Identifier of the action set", + "order": 1 + }, + "organization_id": { + "type": "integer", + "title": "Organization ID", + "description": "Identifier of the organization", + "order": 5 + }, + "solutions": { + "$ref": "#/definitions/action_set_solution_summary", + "title": "Solutions", + "description": "Solutions associated with the action set", + "order": 3 + }, + "source": { + "$ref": "#/definitions/action_set_source", + "title": "Action Set Source", + "description": "Source of the action set", + "order": 7 + }, + "statistics": { + "$ref": "#/definitions/action_set_statistics", + "title": "Action Set Statistics", + "description": "Statistics of the action set", + "order": 2 + }, + "status": { + "type": "string", + "title": "Action Set Status", + "description": "Status of the action set", + "order": 6 + }, + "updated_at": { + "type": "string", + "title": "Uploaded At", + "description": "Datetime the action set was uploaded", + "order": 10 + } + }, + "required": [ + "id" + ], + "definitions": { + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + }, + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + }, + "action_set_solution_summary": { + "type": "object", + "title": "action_set_solution_summary", + "properties": { + "patch_now": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch Now", + "description": "Number of devices that will be patched immediately", + "order": 1 + }, + "patch_with_worklet": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch with Worklet", + "description": "Number of devices that will be patched with a worklet", + "order": 2 + } + }, + "definitions": { + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + } + } + }, + "action_set_source": { + "type": "object", + "title": "action_set_source", + "properties": { + "name": { + "type": "string", + "title": "Source Name", + "description": "Name of the source", + "order": 1 + }, + "type": { + "type": "string", + "title": "Source Type", + "description": "Type of the source", + "order": 2 + } + } + }, + "action_set_statistics": { + "type": "object", + "title": "action_set_statistics", + "properties": { + "issues": { + "$ref": "#/definitions/action_set_issues", + "title": "Issues", + "description": "Issues associated with the action set", + "order": 1 + } + }, + "definitions": { + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + } + } + }, + "action_set_user": { + "type": "object", + "title": "action_set_user", + "properties": { + "email": { + "type": "string", + "title": "Email", + "description": "The email of the user", + "order": 4 + }, + "firstname": { + "type": "string", + "title": "First Name", + "description": "The first name of the user", + "order": 2 + }, + "id": { + "type": "integer", + "title": "User ID", + "description": "The user identifier", + "order": 1 + }, + "lastname": { + "type": "string", + "title": "Last Name", + "description": "The last name of the user", + "order": 3 + } + }, + "required": [ + "id" + ] + } + } + }, + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + }, + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + }, + "action_set_solution_summary": { + "type": "object", + "title": "action_set_solution_summary", + "properties": { + "patch_now": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch Now", + "description": "Number of devices that will be patched immediately", + "order": 1 + }, + "patch_with_worklet": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch with Worklet", + "description": "Number of devices that will be patched with a worklet", + "order": 2 + } + }, + "definitions": { + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + } + } + }, + "action_set_source": { + "type": "object", + "title": "action_set_source", + "properties": { + "name": { + "type": "string", + "title": "Source Name", + "description": "Name of the source", + "order": 1 + }, + "type": { + "type": "string", + "title": "Source Type", + "description": "Type of the source", + "order": 2 + } + } + }, + "action_set_statistics": { + "type": "object", + "title": "action_set_statistics", + "properties": { + "issues": { + "$ref": "#/definitions/action_set_issues", + "title": "Issues", + "description": "Issues associated with the action set", + "order": 1 + } + }, + "definitions": { + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + } + } + }, + "action_set_user": { + "type": "object", + "title": "action_set_user", + "properties": { + "email": { + "type": "string", + "title": "Email", + "description": "The email of the user", + "order": 4 + }, + "firstname": { + "type": "string", + "title": "First Name", + "description": "The first name of the user", + "order": 2 + }, + "id": { + "type": "integer", + "title": "User ID", + "description": "The user identifier", + "order": 1 + }, + "lastname": { + "type": "string", + "title": "Last Name", + "description": "The last name of the user", + "order": 3 + } + }, + "required": [ + "id" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/__init__.py b/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/__init__.py deleted file mode 100755 index 86405ea442..0000000000 --- a/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import GetVulnerabilitySyncBatch diff --git a/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/action.py b/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/action.py deleted file mode 100755 index 45f9a53005..0000000000 --- a/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/action.py +++ /dev/null @@ -1,21 +0,0 @@ -import insightconnect_plugin_runtime -from .schema import GetVulnerabilitySyncBatchInput, GetVulnerabilitySyncBatchOutput, Input, Output, Component - -# Custom imports below - - -class GetVulnerabilitySyncBatch(insightconnect_plugin_runtime.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="get_vulnerability_sync_batch", - description=Component.DESCRIPTION, - input=GetVulnerabilitySyncBatchInput(), - output=GetVulnerabilitySyncBatchOutput(), - ) - - def run(self, params={}): - batch = self.connection.automox_api.get_vulnerability_sync_batch( - params.get(Input.ORG_ID), params.get(Input.BATCH_ID) - ) - - return {Output.BATCH: batch} diff --git a/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/schema.py b/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/schema.py deleted file mode 100755 index 9272ea7e02..0000000000 --- a/plugins/automox/icon_automox/actions/get_vulnerability_sync_batch/schema.py +++ /dev/null @@ -1,220 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import insightconnect_plugin_runtime -import json - - -class Component: - DESCRIPTION = "Retrieve details for a specified vulnerability sync batch" - - -class Input: - BATCH_ID = "batch_id" - ORG_ID = "org_id" - - -class Output: - BATCH = "batch" - - -class GetVulnerabilitySyncBatchInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "batch_id": { - "type": "integer", - "title": "Batch ID", - "description": "Identifier of batch", - "order": 2 - }, - "org_id": { - "type": "integer", - "title": "Organization ID", - "description": "Identifier of organization", - "order": 1 - } - }, - "required": [ - "batch_id", - "org_id" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class GetVulnerabilitySyncBatchOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "batch": { - "$ref": "#/definitions/batch", - "title": "Vulnerability Sync Batch", - "description": "Details of a specified vulnerability sync batch", - "order": 1 - } - }, - "required": [ - "batch" - ], - "definitions": { - "batch": { - "type": "object", - "title": "batch", - "properties": { - "created_by": { - "$ref": "#/definitions/batch_user", - "title": "Created By", - "description": "Batch creation details", - "order": 5 - }, - "cve_count": { - "type": "integer", - "title": "CVE Count", - "description": "Number of CVEs that are impacted by batch", - "order": 12 - }, - "id": { - "type": "integer", - "title": "Batch ID", - "description": "Identifier of batch", - "order": 1 - }, - "impacted_device_count": { - "type": "integer", - "title": "Impacted Device Count", - "description": "Number of devices that are impacted by batch", - "order": 10 - }, - "issue_count": { - "type": "integer", - "title": "Issue Count", - "description": "Number of issues identified with batch", - "order": 11 - }, - "organization_id": { - "type": "integer", - "title": "Organization ID", - "description": "Identifier of organization", - "order": 2 - }, - "source": { - "type": "string", - "title": "Batch Source", - "description": "Source of batch", - "order": 4 - }, - "status": { - "type": "string", - "title": "Batch Status", - "description": "Status of batch", - "order": 3 - }, - "task_count": { - "type": "integer", - "title": "Task Count", - "description": "Number of tasks related to batch", - "order": 8 - }, - "unknown_host_count": { - "type": "integer", - "title": "Unknown Host Count", - "description": "Number of hosts that are unknown within batch", - "order": 9 - }, - "updated_by": { - "$ref": "#/definitions/batch_user", - "title": "Updated By", - "description": "Batch update details", - "order": 6 - }, - "uploaded_at": { - "type": "string", - "title": "Uploaded At", - "description": "Datetime the batch was uploaded", - "order": 7 - } - }, - "required": [ - "id" - ], - "definitions": { - "batch_user": { - "type": "object", - "title": "batch_user", - "properties": { - "email": { - "type": "string", - "title": "Email", - "description": "The email of the user", - "order": 4 - }, - "firstname": { - "type": "string", - "title": "First Name", - "description": "The first name of the user", - "order": 2 - }, - "id": { - "type": "integer", - "title": "User ID", - "description": "The user identifier", - "order": 1 - }, - "lastname": { - "type": "string", - "title": "Last Name", - "description": "The last name of the user", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } - }, - "batch_user": { - "type": "object", - "title": "batch_user", - "properties": { - "email": { - "type": "string", - "title": "Email", - "description": "The email of the user", - "order": 4 - }, - "firstname": { - "type": "string", - "title": "First Name", - "description": "The first name of the user", - "order": 2 - }, - "id": { - "type": "integer", - "title": "User ID", - "description": "The user identifier", - "order": 1 - }, - "lastname": { - "type": "string", - "title": "Last Name", - "description": "The last name of the user", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/__init__.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/__init__.py new file mode 100755 index 0000000000..3652a6f113 --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import ListVulnerabilitySyncActionSetIssues diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/action.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/action.py new file mode 100755 index 0000000000..9fb538dec5 --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/action.py @@ -0,0 +1,29 @@ +import insightconnect_plugin_runtime +from .schema import ListVulnerabilitySyncActionSetIssuesInput, ListVulnerabilitySyncActionSetIssuesOutput, Input, Output, Component +# Custom imports below +from icon_automox.util.param_parser import inputs_to_query_params +from icon_automox.util.cleaner import clean_ax_response + + +class ListVulnerabilitySyncActionSetIssues(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='list_vulnerability_sync_action_set_issues', + description=Component.DESCRIPTION, + input=ListVulnerabilitySyncActionSetIssuesInput(), + output=ListVulnerabilitySyncActionSetIssuesOutput()) + + def run(self, params={}): + org_id = params.get(Input.ORG_ID) + action_set_id = params.get(Input.ACTION_SET_ID) + params = inputs_to_query_params({ + "issue_type:in[]": params.get(Input.ISSUE_TYPE_IN) + }) + resp = self.connection.automox_api.list_vulnerability_sync_action_set_issues( + org_id, + action_set_id, + params + ) + resp = [clean_ax_response(i) for i in resp] + return {Output.ISSUES: resp} diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/schema.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/schema.py new file mode 100755 index 0000000000..aa16132b7f --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_issues/schema.py @@ -0,0 +1,113 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Retrieve the issues identified for a specified vulnerability sync action set" + + +class Input: + ACTION_SET_ID = "action_set_id" + ISSUE_TYPE_IN = "issue_type_in" + ORG_ID = "org_id" + + +class Output: + ISSUES = "issues" + + +class ListVulnerabilitySyncActionSetIssuesInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "action_set_id": { + "type": "integer", + "title": "Action Set ID", + "description": "Identifier of the action set", + "order": 2 + }, + "issue_type_in": { + "type": "array", + "title": "Issue Type In", + "description": "Filter by issue type", + "items": { + "type": "string" + }, + "order": 3 + }, + "org_id": { + "type": "integer", + "title": "Organization ID", + "description": "Identifier of organization", + "order": 1 + } + }, + "required": [ + "action_set_id", + "org_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class ListVulnerabilitySyncActionSetIssuesOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "issues": { + "type": "array", + "title": "Vulnerability Sync Action Set Issues", + "description": "Issues associated with the specified vulnerability sync action_set", + "items": { + "$ref": "#/definitions/action_set_issue" + }, + "order": 1 + } + }, + "required": [ + "issues" + ], + "definitions": { + "action_set_issue": { + "type": "object", + "title": "action_set_issue", + "properties": { + "id": { + "type": "integer", + "title": "Issue ID", + "description": "Identifier of the issue", + "order": 1 + }, + "issue_details": { + "type": "object", + "title": "Issue Details", + "description": "Details of the issue", + "order": 3 + }, + "issue_type": { + "type": "string", + "title": "Issue Type", + "description": "Type of issue", + "order": 2 + } + }, + "required": [ + "id", + "issue_details", + "issue_type" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/__init__.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/__init__.py new file mode 100755 index 0000000000..34b3dcb18e --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import ListVulnerabilitySyncActionSetSolutions diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/action.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/action.py new file mode 100755 index 0000000000..642359a2cf --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/action.py @@ -0,0 +1,33 @@ +import insightconnect_plugin_runtime +from .schema import ListVulnerabilitySyncActionSetSolutionsInput, ListVulnerabilitySyncActionSetSolutionsOutput, Input, Output, Component +# Custom imports below +from icon_automox.util.param_parser import inputs_to_query_params +from icon_automox.util.cleaner import clean_ax_response + + +class ListVulnerabilitySyncActionSetSolutions(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='list_vulnerability_sync_action_set_solutions', + description=Component.DESCRIPTION, + input=ListVulnerabilitySyncActionSetSolutionsInput(), + output=ListVulnerabilitySyncActionSetSolutionsOutput()) + + def run(self, params={}): + org_id = params.get(Input.ORG_ID) + action_set_id = params.get(Input.ACTION_SET_ID) + params = inputs_to_query_params({ + "remediation_type:in[]": params.get(Input.REMEDIATION_TYPE_IN), + "solution_details_severity:in[]": params.get(Input.SEVERITY_IN), + "vulnerability_id:in[]": params.get(Input.VULNERABILITY_IN), + }) + resp = self.connection.automox_api.list_vulnerability_sync_action_set_solutions( + org_id, + action_set_id, + params + ) + # Clean the response and set the device_ids field for each solution as a helper in workflows + resp = [dict(clean_ax_response(s), device_ids=[d["id"] for d in s["devices"]]) for s in resp] + + return {Output.SOLUTIONS: resp} diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/schema.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/schema.py new file mode 100755 index 0000000000..c2b27c2f1c --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_set_solutions/schema.py @@ -0,0 +1,325 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Retrieve a list of vulnerability sync remediations" + + +class Input: + ACTION_SET_ID = "action_set_id" + ORG_ID = "org_id" + REMEDIATION_TYPE_IN = "remediation_type_in" + SEVERITY_IN = "severity_in" + VULNERABILITY_IN = "vulnerability_in" + + +class Output: + SOLUTIONS = "solutions" + + +class ListVulnerabilitySyncActionSetSolutionsInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "action_set_id": { + "type": "integer", + "title": "Action Set ID", + "description": "Filter by action set identifier", + "order": 2 + }, + "org_id": { + "type": "integer", + "title": "Organization ID", + "description": "Identifier of organization", + "order": 1 + }, + "remediation_type_in": { + "type": "array", + "title": "Remediation Type In", + "description": "Filter by remediation type", + "items": { + "type": "string" + }, + "order": 3 + }, + "severity_in": { + "type": "array", + "title": "Severity In", + "description": "Filter by severity", + "items": { + "type": "string" + }, + "order": 4 + }, + "vulnerability_in": { + "type": "array", + "title": "Vulnerability In", + "description": "Filter by vulnerability", + "items": { + "type": "string" + }, + "order": 5 + } + }, + "required": [ + "action_set_id", + "org_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class ListVulnerabilitySyncActionSetSolutionsOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "solutions": { + "type": "array", + "title": "Vulnerability Sync Solutions", + "description": "List of vulnerability sync Solutions", + "items": { + "$ref": "#/definitions/solution" + }, + "order": 1 + } + }, + "definitions": { + "solution": { + "type": "object", + "title": "solution", + "properties": { + "device_ids": { + "type": "array", + "title": "Device IDs", + "description": "List of device identifiers associated with the solution. This is a helper field to make executing actions easier. It does not exist on the Automox API.", + "items": { + "type": "integer" + }, + "order": 5 + }, + "devices": { + "type": "array", + "title": "Devices", + "description": "List of devices associated with the solution", + "items": { + "$ref": "#/definitions/solution_device" + }, + "order": 6 + }, + "id": { + "type": "integer", + "title": "Solution ID", + "description": "Identifier of solution", + "order": 1 + }, + "remediation_type": { + "type": "string", + "title": "Remediation Type", + "description": "Type of remediation", + "order": 3 + }, + "solution_details": { + "type": "object", + "title": "Solution Details", + "description": "Details of the solution. This can include package information and other details depending on the solution type", + "order": 4 + }, + "solution_type": { + "type": "string", + "title": "Solution Type", + "description": "Type of solution", + "order": 2 + }, + "vulnerabilities": { + "type": "array", + "title": "Vulnerabilities", + "description": "List of vulnerabilities associated with the solution", + "items": { + "$ref": "#/definitions/solution_vulnerability" + }, + "order": 7 + } + }, + "required": [ + "id" + ], + "definitions": { + "solution_device": { + "type": "object", + "title": "solution_device", + "properties": { + "custom_name": { + "type": "string", + "title": "Custom Name", + "description": "Custom name of the device", + "order": 3 + }, + "deleted": { + "type": "boolean", + "title": "Deleted", + "description": "Whether the device is deleted from Automox", + "order": 5 + }, + "id": { + "type": "integer", + "title": "Device ID", + "description": "Identifier of device", + "order": 1 + }, + "ip_addrs_private": { + "type": "array", + "title": "Private IP Addresses", + "description": "List of private IP addresses for the device", + "items": { + "type": "string" + }, + "order": 6 + }, + "name": { + "type": "string", + "title": "Device Name", + "description": "Name of the device", + "order": 2 + }, + "status": { + "type": "string", + "title": "Device Status", + "description": "Status of remediation for the device", + "order": 4 + } + }, + "required": [ + "id" + ] + }, + "solution_vulnerability": { + "type": "object", + "title": "solution_vulnerability", + "properties": { + "id": { + "type": "string", + "title": "Vulneability ID", + "description": "Identifier of the vulnerability, typically a CVE", + "order": 1 + }, + "severity": { + "type": "string", + "title": "Severity", + "description": "Severity of the vulnerability", + "order": 4 + }, + "summary": { + "type": "string", + "title": "Summary", + "description": "Summary of the vulnerability", + "order": 3 + }, + "title": { + "type": "string", + "title": "Title", + "description": "Title of the vulnerability", + "order": 2 + } + }, + "required": [ + "id" + ] + } + } + }, + "solution_device": { + "type": "object", + "title": "solution_device", + "properties": { + "custom_name": { + "type": "string", + "title": "Custom Name", + "description": "Custom name of the device", + "order": 3 + }, + "deleted": { + "type": "boolean", + "title": "Deleted", + "description": "Whether the device is deleted from Automox", + "order": 5 + }, + "id": { + "type": "integer", + "title": "Device ID", + "description": "Identifier of device", + "order": 1 + }, + "ip_addrs_private": { + "type": "array", + "title": "Private IP Addresses", + "description": "List of private IP addresses for the device", + "items": { + "type": "string" + }, + "order": 6 + }, + "name": { + "type": "string", + "title": "Device Name", + "description": "Name of the device", + "order": 2 + }, + "status": { + "type": "string", + "title": "Device Status", + "description": "Status of remediation for the device", + "order": 4 + } + }, + "required": [ + "id" + ] + }, + "solution_vulnerability": { + "type": "object", + "title": "solution_vulnerability", + "properties": { + "id": { + "type": "string", + "title": "Vulneability ID", + "description": "Identifier of the vulnerability, typically a CVE", + "order": 1 + }, + "severity": { + "type": "string", + "title": "Severity", + "description": "Severity of the vulnerability", + "order": 4 + }, + "summary": { + "type": "string", + "title": "Summary", + "description": "Summary of the vulnerability", + "order": 3 + }, + "title": { + "type": "string", + "title": "Title", + "description": "Title of the vulnerability", + "order": 2 + } + }, + "required": [ + "id" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/__init__.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/__init__.py new file mode 100755 index 0000000000..e118f099af --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import ListVulnerabilitySyncActionSets diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/action.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/action.py new file mode 100755 index 0000000000..3fb22179c3 --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/action.py @@ -0,0 +1,39 @@ +import insightconnect_plugin_runtime +from .schema import ListVulnerabilitySyncActionSetsInput, ListVulnerabilitySyncActionSetsOutput, Input, Output, Component +# Custom imports below +from icon_automox.util.param_parser import inputs_to_query_params +from icon_automox.util.cleaner import clean_ax_response + + +class ListVulnerabilitySyncActionSets(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='list_vulnerability_sync_action_sets', + description=Component.DESCRIPTION, + input=ListVulnerabilitySyncActionSetsInput(), + output=ListVulnerabilitySyncActionSetsOutput()) + + def run(self, params={}): + org_id = params.get(Input.ORG_ID) + # Hidden parameter, but there's only one option so we'll just set it here + group_by = params.get(Input.GROUP_SORT) + params = inputs_to_query_params({ + "sort": params.get(Input.SORT), + "groupSort": params.get(Input.GROUP_SORT), + "source_type:in[]": params.get(Input.SOURCE_TYPE_IN), + "status:in[]": params.get(Input.STATUS_IN), + "status:not_in[]": params.get(Input.STATUS_NOT_IN), + "configuration_id:equals": params.get(Input.CONFIGURATION_ID_EQUALS), + "configuration_id:is_set": params.get(Input.CONFIGURATION_ID_IS_SET), + "include_all_runs:equals": params.get(Input.INCLUDE_ALL_RUNS_EQUALS), + }) + if group_by is not None: + params["groupBy"] = "configuration_id" + resp = self.connection.automox_api.list_vulnerability_sync_action_sets( + org_id, + params + ) + resp = [clean_ax_response(a) for a in resp] + + return {Output.ACTION_SETS: resp} diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/schema.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/schema.py new file mode 100755 index 0000000000..34a0103a3d --- /dev/null +++ b/plugins/automox/icon_automox/actions/list_vulnerability_sync_action_sets/schema.py @@ -0,0 +1,531 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Retrieve list of vulnerability sync batches" + + +class Input: + CONFIGURATION_ID_EQUALS = "configuration_id_equals" + CONFIGURATION_ID_IS_SET = "configuration_id_is_set" + GROUP_SORT = "group_sort" + INCLUDE_ALL_RUNS_EQUALS = "include_all_runs_equals" + ORG_ID = "org_id" + SORT = "sort" + SOURCE_TYPE_IN = "source_type_in" + STATUS_IN = "status_in" + STATUS_NOT_IN = "status_not_in" + + +class Output: + ACTION_SETS = "action_sets" + + +class ListVulnerabilitySyncActionSetsInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "configuration_id_equals": { + "type": "string", + "title": "Configuration ID Equals", + "description": "Filter by configuration ID", + "order": 7 + }, + "configuration_id_is_set": { + "type": "boolean", + "title": "Configuration ID Is Set", + "description": "Filter based on whether the configuration ID is set", + "order": 8 + }, + "group_sort": { + "type": "string", + "title": "Group Sort", + "description": "Sort results by field", + "enum": [ + "asc", + "desc", + "latest_updated_at:asc", + "latest_updated_at:desc", + "source:asc", + "source:desc", + "" + ], + "order": 3 + }, + "include_all_runs_equals": { + "type": "boolean", + "title": "Include All Runs Equals", + "description": "Whether to include all runs in the response", + "order": 9 + }, + "org_id": { + "type": "integer", + "title": "Organization ID", + "description": "Identifier of organization", + "order": 1 + }, + "sort": { + "type": "string", + "title": "Sort", + "description": "Sort results by field", + "enum": [ + "created_at", + "updated_at", + "status", + "source_type", + "source_name", + "configuration_id", + "" + ], + "order": 2 + }, + "source_type_in": { + "type": "array", + "title": "Source Type In", + "description": "Filter by source type", + "items": { + "type": "string" + }, + "order": 4 + }, + "status_in": { + "type": "array", + "title": "Status In", + "description": "Filter by status", + "items": { + "type": "string" + }, + "order": 5 + }, + "status_not_in": { + "type": "array", + "title": "Status Not In", + "description": "Filter by status", + "items": { + "type": "string" + }, + "order": 6 + } + }, + "required": [ + "org_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class ListVulnerabilitySyncActionSetsOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "action_sets": { + "type": "array", + "title": "Vulnerability Sync Action Sets", + "description": "List of vulnerability sync action sets", + "items": { + "$ref": "#/definitions/action_set" + }, + "order": 1 + } + }, + "definitions": { + "action_set": { + "type": "object", + "title": "action_set", + "properties": { + "configuration_id": { + "type": "string", + "title": "Configuration ID", + "description": "Identifier of the configuration, only applicable for Automated Vulnerability Remediation (AVR) action sets", + "order": 4 + }, + "created_at": { + "type": "string", + "title": "Created At", + "description": "Datetime the action set was created", + "order": 9 + }, + "created_by": { + "$ref": "#/definitions/action_set_user", + "title": "Created By", + "description": "action set creation details", + "order": 8 + }, + "id": { + "type": "integer", + "title": "Action Set ID", + "description": "Identifier of the action set", + "order": 1 + }, + "organization_id": { + "type": "integer", + "title": "Organization ID", + "description": "Identifier of the organization", + "order": 5 + }, + "solutions": { + "$ref": "#/definitions/action_set_solution_summary", + "title": "Solutions", + "description": "Solutions associated with the action set", + "order": 3 + }, + "source": { + "$ref": "#/definitions/action_set_source", + "title": "Action Set Source", + "description": "Source of the action set", + "order": 7 + }, + "statistics": { + "$ref": "#/definitions/action_set_statistics", + "title": "Action Set Statistics", + "description": "Statistics of the action set", + "order": 2 + }, + "status": { + "type": "string", + "title": "Action Set Status", + "description": "Status of the action set", + "order": 6 + }, + "updated_at": { + "type": "string", + "title": "Uploaded At", + "description": "Datetime the action set was uploaded", + "order": 10 + } + }, + "required": [ + "id" + ], + "definitions": { + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + }, + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + }, + "action_set_solution_summary": { + "type": "object", + "title": "action_set_solution_summary", + "properties": { + "patch_now": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch Now", + "description": "Number of devices that will be patched immediately", + "order": 1 + }, + "patch_with_worklet": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch with Worklet", + "description": "Number of devices that will be patched with a worklet", + "order": 2 + } + }, + "definitions": { + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + } + } + }, + "action_set_source": { + "type": "object", + "title": "action_set_source", + "properties": { + "name": { + "type": "string", + "title": "Source Name", + "description": "Name of the source", + "order": 1 + }, + "type": { + "type": "string", + "title": "Source Type", + "description": "Type of the source", + "order": 2 + } + } + }, + "action_set_statistics": { + "type": "object", + "title": "action_set_statistics", + "properties": { + "issues": { + "$ref": "#/definitions/action_set_issues", + "title": "Issues", + "description": "Issues associated with the action set", + "order": 1 + } + }, + "definitions": { + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + } + } + }, + "action_set_user": { + "type": "object", + "title": "action_set_user", + "properties": { + "email": { + "type": "string", + "title": "Email", + "description": "The email of the user", + "order": 4 + }, + "firstname": { + "type": "string", + "title": "First Name", + "description": "The first name of the user", + "order": 2 + }, + "id": { + "type": "integer", + "title": "User ID", + "description": "The user identifier", + "order": 1 + }, + "lastname": { + "type": "string", + "title": "Last Name", + "description": "The last name of the user", + "order": 3 + } + }, + "required": [ + "id" + ] + } + } + }, + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + }, + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + }, + "action_set_solution_summary": { + "type": "object", + "title": "action_set_solution_summary", + "properties": { + "patch_now": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch Now", + "description": "Number of devices that will be patched immediately", + "order": 1 + }, + "patch_with_worklet": { + "$ref": "#/definitions/action_set_solution_counts", + "title": "Patch with Worklet", + "description": "Number of devices that will be patched with a worklet", + "order": 2 + } + }, + "definitions": { + "action_set_solution_counts": { + "type": "object", + "title": "action_set_solution_counts", + "properties": { + "count": { + "type": "integer", + "title": "Solution Count", + "description": "Number of solutions associated with the action set", + "order": 1 + }, + "device_count": { + "type": "integer", + "title": "Device Count", + "description": "Number of devices associated with the action set", + "order": 2 + }, + "vulnerability_count": { + "type": "integer", + "title": "Vulnerability Count", + "description": "Number of vulnerabilities associated with the action set", + "order": 3 + } + } + } + } + }, + "action_set_source": { + "type": "object", + "title": "action_set_source", + "properties": { + "name": { + "type": "string", + "title": "Source Name", + "description": "Name of the source", + "order": 1 + }, + "type": { + "type": "string", + "title": "Source Type", + "description": "Type of the source", + "order": 2 + } + } + }, + "action_set_statistics": { + "type": "object", + "title": "action_set_statistics", + "properties": { + "issues": { + "$ref": "#/definitions/action_set_issues", + "title": "Issues", + "description": "Issues associated with the action set", + "order": 1 + } + }, + "definitions": { + "action_set_issues": { + "type": "object", + "title": "action_set_issues", + "properties": { + "unknown_host_count": { + "type": "integer", + "title": "Unknown Host Count", + "description": "Number of hosts that are unknown within the action set", + "order": 1 + } + } + } + } + }, + "action_set_user": { + "type": "object", + "title": "action_set_user", + "properties": { + "email": { + "type": "string", + "title": "Email", + "description": "The email of the user", + "order": 4 + }, + "firstname": { + "type": "string", + "title": "First Name", + "description": "The first name of the user", + "order": 2 + }, + "id": { + "type": "integer", + "title": "User ID", + "description": "The user identifier", + "order": 1 + }, + "lastname": { + "type": "string", + "title": "Last Name", + "description": "The last name of the user", + "order": 3 + } + }, + "required": [ + "id" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/__init__.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/__init__.py deleted file mode 100755 index 180e4f1da3..0000000000 --- a/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import ListVulnerabilitySyncBatches diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/action.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/action.py deleted file mode 100755 index dfa42f6c1a..0000000000 --- a/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/action.py +++ /dev/null @@ -1,20 +0,0 @@ -import insightconnect_plugin_runtime -from .schema import ListVulnerabilitySyncBatchesInput, ListVulnerabilitySyncBatchesOutput, Input, Output, Component - -# Custom imports below - - -class ListVulnerabilitySyncBatches(insightconnect_plugin_runtime.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="list_vulnerability_sync_batches", - description=Component.DESCRIPTION, - input=ListVulnerabilitySyncBatchesInput(), - output=ListVulnerabilitySyncBatchesOutput(), - ) - - def run(self, params={}): - batches = self.connection.automox_api.get_vulnerability_sync_batches(params.get(Input.ORG_ID)) - self.logger.info(f"Returned {len(batches)} batches") - - return {Output.BATCHES: batches} diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/schema.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/schema.py deleted file mode 100755 index edd80999a7..0000000000 --- a/plugins/automox/icon_automox/actions/list_vulnerability_sync_batches/schema.py +++ /dev/null @@ -1,212 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import insightconnect_plugin_runtime -import json - - -class Component: - DESCRIPTION = "Retrieve list of vulnerability sync batches" - - -class Input: - ORG_ID = "org_id" - - -class Output: - BATCHES = "batches" - - -class ListVulnerabilitySyncBatchesInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "org_id": { - "type": "integer", - "title": "Organization ID", - "description": "Identifier of organization", - "order": 1 - } - }, - "required": [ - "org_id" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class ListVulnerabilitySyncBatchesOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "batches": { - "type": "array", - "title": "Vulnerability Sync Batches", - "description": "List of vulnerability sync batches", - "items": { - "$ref": "#/definitions/batch" - }, - "order": 1 - } - }, - "definitions": { - "batch": { - "type": "object", - "title": "batch", - "properties": { - "created_by": { - "$ref": "#/definitions/batch_user", - "title": "Created By", - "description": "Batch creation details", - "order": 5 - }, - "cve_count": { - "type": "integer", - "title": "CVE Count", - "description": "Number of CVEs that are impacted by batch", - "order": 12 - }, - "id": { - "type": "integer", - "title": "Batch ID", - "description": "Identifier of batch", - "order": 1 - }, - "impacted_device_count": { - "type": "integer", - "title": "Impacted Device Count", - "description": "Number of devices that are impacted by batch", - "order": 10 - }, - "issue_count": { - "type": "integer", - "title": "Issue Count", - "description": "Number of issues identified with batch", - "order": 11 - }, - "organization_id": { - "type": "integer", - "title": "Organization ID", - "description": "Identifier of organization", - "order": 2 - }, - "source": { - "type": "string", - "title": "Batch Source", - "description": "Source of batch", - "order": 4 - }, - "status": { - "type": "string", - "title": "Batch Status", - "description": "Status of batch", - "order": 3 - }, - "task_count": { - "type": "integer", - "title": "Task Count", - "description": "Number of tasks related to batch", - "order": 8 - }, - "unknown_host_count": { - "type": "integer", - "title": "Unknown Host Count", - "description": "Number of hosts that are unknown within batch", - "order": 9 - }, - "updated_by": { - "$ref": "#/definitions/batch_user", - "title": "Updated By", - "description": "Batch update details", - "order": 6 - }, - "uploaded_at": { - "type": "string", - "title": "Uploaded At", - "description": "Datetime the batch was uploaded", - "order": 7 - } - }, - "required": [ - "id" - ], - "definitions": { - "batch_user": { - "type": "object", - "title": "batch_user", - "properties": { - "email": { - "type": "string", - "title": "Email", - "description": "The email of the user", - "order": 4 - }, - "firstname": { - "type": "string", - "title": "First Name", - "description": "The first name of the user", - "order": 2 - }, - "id": { - "type": "integer", - "title": "User ID", - "description": "The user identifier", - "order": 1 - }, - "lastname": { - "type": "string", - "title": "Last Name", - "description": "The last name of the user", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } - }, - "batch_user": { - "type": "object", - "title": "batch_user", - "properties": { - "email": { - "type": "string", - "title": "Email", - "description": "The email of the user", - "order": 4 - }, - "firstname": { - "type": "string", - "title": "First Name", - "description": "The first name of the user", - "order": 2 - }, - "id": { - "type": "integer", - "title": "User ID", - "description": "The user identifier", - "order": 1 - }, - "lastname": { - "type": "string", - "title": "Last Name", - "description": "The last name of the user", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/__init__.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/__init__.py deleted file mode 100755 index 89faf17fd6..0000000000 --- a/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import ListVulnerabilitySyncTasks diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/action.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/action.py deleted file mode 100755 index ad5cbf06a4..0000000000 --- a/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/action.py +++ /dev/null @@ -1,22 +0,0 @@ -import insightconnect_plugin_runtime -from .schema import ListVulnerabilitySyncTasksInput, ListVulnerabilitySyncTasksOutput, Input, Output, Component - -# Custom imports below - - -class ListVulnerabilitySyncTasks(insightconnect_plugin_runtime.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="list_vulnerability_sync_tasks", - description=Component.DESCRIPTION, - input=ListVulnerabilitySyncTasksInput(), - output=ListVulnerabilitySyncTasksOutput(), - ) - - def run(self, params={}): - parameters = {"batch_id:equals": params.get(Input.BATCH_ID), "status:equals": params.get(Input.STATUS)} - - tasks = self.connection.automox_api.get_vulnerability_sync_tasks(params.get(Input.ORG_ID), parameters) - self.logger.info(f"Returned {len(tasks)} tasks") - - return {Output.TASKS: tasks} diff --git a/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/schema.py b/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/schema.py deleted file mode 100755 index cf5409b1c2..0000000000 --- a/plugins/automox/icon_automox/actions/list_vulnerability_sync_tasks/schema.py +++ /dev/null @@ -1,455 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import insightconnect_plugin_runtime -import json - - -class Component: - DESCRIPTION = "Retrieve list of vulnerability sync tasks" - - -class Input: - BATCH_ID = "batch_id" - ORG_ID = "org_id" - STATUS = "status" - - -class Output: - TASKS = "tasks" - - -class ListVulnerabilitySyncTasksInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "batch_id": { - "type": "integer", - "title": "Batch ID", - "description": "Filter by batch identifier", - "order": 3 - }, - "org_id": { - "type": "integer", - "title": "Organization ID", - "description": "Identifier of organization", - "order": 1 - }, - "status": { - "type": "string", - "title": "Status", - "description": "Filter by status of tasks", - "order": 2 - } - }, - "required": [ - "org_id" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class ListVulnerabilitySyncTasksOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "tasks": { - "type": "array", - "title": "Vulnerability Sync Tasks", - "description": "List of vulnerability sync tasks", - "items": { - "$ref": "#/definitions/task" - }, - "order": 1 - } - }, - "definitions": { - "batch_user": { - "type": "object", - "title": "batch_user", - "properties": { - "email": { - "type": "string", - "title": "Email", - "description": "The email of the user", - "order": 4 - }, - "firstname": { - "type": "string", - "title": "First Name", - "description": "The first name of the user", - "order": 2 - }, - "id": { - "type": "integer", - "title": "User ID", - "description": "The user identifier", - "order": 1 - }, - "lastname": { - "type": "string", - "title": "Last Name", - "description": "The last name of the user", - "order": 3 - } - }, - "required": [ - "id" - ] - }, - "task": { - "type": "object", - "title": "task", - "properties": { - "completed_at": { - "type": "string", - "title": "Completed At", - "description": "The datetime the task was completed", - "order": 12 - }, - "created_at": { - "type": "string", - "title": "Created At", - "description": "The datetime the task was created", - "order": 10 - }, - "created_by_user": { - "$ref": "#/definitions/batch_user", - "title": "Created by User", - "description": "Task creation details", - "order": 8 - }, - "cves": { - "type": "array", - "title": "CVEs", - "description": "List of CVEs associated with task", - "items": { - "type": "string" - }, - "order": 13 - }, - "id": { - "type": "integer", - "title": "Task ID", - "description": "Identifier of task", - "order": 1 - }, - "last_updated_by_user": { - "$ref": "#/definitions/batch_user", - "title": "Updated by User", - "description": "Task update details", - "order": 9 - }, - "notes": { - "type": "string", - "title": "Task Notes", - "description": "Notes associated with task", - "order": 6 - }, - "organization_id": { - "type": "integer", - "title": "Organization ID", - "description": "Identifier of organization", - "order": 2 - }, - "payload": { - "$ref": "#/definitions/task_payload", - "title": "Payload", - "description": "Payload associated with task", - "order": 4 - }, - "report_source": { - "type": "string", - "title": "Report Source", - "description": "The source of the vulnerability report", - "order": 14 - }, - "source": { - "type": "string", - "title": "Task Source", - "description": "Source of task", - "order": 5 - }, - "status": { - "type": "string", - "title": "Task Status", - "description": "Status of task", - "order": 7 - }, - "task_type": { - "type": "string", - "title": "Task Type", - "description": "Type of task", - "order": 3 - }, - "updated_at": { - "type": "string", - "title": "Updated At", - "description": "The datetime the task was updated", - "order": 11 - } - }, - "required": [ - "id" - ], - "definitions": { - "batch_user": { - "type": "object", - "title": "batch_user", - "properties": { - "email": { - "type": "string", - "title": "Email", - "description": "The email of the user", - "order": 4 - }, - "firstname": { - "type": "string", - "title": "First Name", - "description": "The first name of the user", - "order": 2 - }, - "id": { - "type": "integer", - "title": "User ID", - "description": "The user identifier", - "order": 1 - }, - "lastname": { - "type": "string", - "title": "Last Name", - "description": "The last name of the user", - "order": 3 - } - }, - "required": [ - "id" - ] - }, - "task_payload": { - "type": "object", - "title": "task_payload", - "properties": { - "package_versions": { - "type": "array", - "title": "Package Versions", - "description": "The version of the packages within scope of the task", - "items": { - "$ref": "#/definitions/task_payload_package_versions" - }, - "order": 3 - }, - "patch_id": { - "type": "string", - "title": "Patch ID", - "description": "The patch identifier associated with the task", - "order": 1 - }, - "severity": { - "type": "string", - "title": "Severity", - "description": "The severity of the patch associated with the task", - "order": 2 - } - }, - "definitions": { - "task_payload_package_versions": { - "type": "object", - "title": "task_payload_package_versions", - "properties": { - "display_name": { - "type": "string", - "title": "Display Name", - "description": "The display name of the package associated with the task", - "order": 4 - }, - "id": { - "type": "string", - "title": "Package ID", - "description": "The package identifier associated with the task", - "order": 1 - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the package associated with the task", - "order": 2 - }, - "requires_reboot": { - "type": "boolean", - "title": "Requires Reboot", - "description": "Whether the package installed by the task will require reboot", - "order": 5 - }, - "version": { - "type": "string", - "title": "Version", - "description": "The version of the package associated with the task", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } - }, - "task_payload_package_versions": { - "type": "object", - "title": "task_payload_package_versions", - "properties": { - "display_name": { - "type": "string", - "title": "Display Name", - "description": "The display name of the package associated with the task", - "order": 4 - }, - "id": { - "type": "string", - "title": "Package ID", - "description": "The package identifier associated with the task", - "order": 1 - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the package associated with the task", - "order": 2 - }, - "requires_reboot": { - "type": "boolean", - "title": "Requires Reboot", - "description": "Whether the package installed by the task will require reboot", - "order": 5 - }, - "version": { - "type": "string", - "title": "Version", - "description": "The version of the package associated with the task", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } - }, - "task_payload": { - "type": "object", - "title": "task_payload", - "properties": { - "package_versions": { - "type": "array", - "title": "Package Versions", - "description": "The version of the packages within scope of the task", - "items": { - "$ref": "#/definitions/task_payload_package_versions" - }, - "order": 3 - }, - "patch_id": { - "type": "string", - "title": "Patch ID", - "description": "The patch identifier associated with the task", - "order": 1 - }, - "severity": { - "type": "string", - "title": "Severity", - "description": "The severity of the patch associated with the task", - "order": 2 - } - }, - "definitions": { - "task_payload_package_versions": { - "type": "object", - "title": "task_payload_package_versions", - "properties": { - "display_name": { - "type": "string", - "title": "Display Name", - "description": "The display name of the package associated with the task", - "order": 4 - }, - "id": { - "type": "string", - "title": "Package ID", - "description": "The package identifier associated with the task", - "order": 1 - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the package associated with the task", - "order": 2 - }, - "requires_reboot": { - "type": "boolean", - "title": "Requires Reboot", - "description": "Whether the package installed by the task will require reboot", - "order": 5 - }, - "version": { - "type": "string", - "title": "Version", - "description": "The version of the package associated with the task", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } - }, - "task_payload_package_versions": { - "type": "object", - "title": "task_payload_package_versions", - "properties": { - "display_name": { - "type": "string", - "title": "Display Name", - "description": "The display name of the package associated with the task", - "order": 4 - }, - "id": { - "type": "string", - "title": "Package ID", - "description": "The package identifier associated with the task", - "order": 1 - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the package associated with the task", - "order": 2 - }, - "requires_reboot": { - "type": "boolean", - "title": "Requires Reboot", - "description": "Whether the package installed by the task will require reboot", - "order": 5 - }, - "version": { - "type": "string", - "title": "Version", - "description": "The version of the package associated with the task", - "order": 3 - } - }, - "required": [ - "id" - ] - } - } -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/automox/icon_automox/actions/update_device/action.py b/plugins/automox/icon_automox/actions/update_device/action.py index 0fe6c2c20b..3e4060c35d 100755 --- a/plugins/automox/icon_automox/actions/update_device/action.py +++ b/plugins/automox/icon_automox/actions/update_device/action.py @@ -19,8 +19,13 @@ def run(self, params={}): params.get(Input.ORG_ID), params.get(Input.DEVICE_ID) ) + # Set server_group_id to current value if not provided as input + # ICON will set the default value to 0, which causes the params.get() use an invalid group ID + server_group_id = current_device_details["server_group_id"] + if params.get(Input.SERVER_GROUP_ID) != 0: + server_group_id = params.get(Input.SERVER_GROUP_ID) payload = { - "server_group_id": params.get(Input.SERVER_GROUP_ID, current_device_details["server_group_id"]), + "server_group_id": server_group_id, "ip_addrs": current_device_details["ip_addrs"], "exception": params.get(Input.EXCEPTION, current_device_details["exception"]), "tags": params.get(Input.TAGS, current_device_details["tags"]), diff --git a/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/action.py b/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/action.py index 5ba3ebe659..5accf50f9c 100755 --- a/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/action.py +++ b/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/action.py @@ -24,11 +24,11 @@ def run(self, params={}): assistance=f"Review uploaded CSV and ensure it is a base64 encoded input. Error: {str(e)}", ) - batch_id = self.connection.automox_api.upload_vulnerability_sync_file( + resp = self.connection.automox_api.upload_vulnerability_sync_file( params.get(Input.ORG_ID), decoded_data, params.get(Input.CSV_FILE_NAME, "insightconnect-uploaded-report.csv"), - params.get(Input.REPORT_SOURCE, "Generic Report"), + params.get(Input.REPORT_SOURCE, "generic"), ) - return {Output.BATCH_ID: batch_id} + return {Output.ID: resp.get("id"), Output.STATUS: resp.get("status")} diff --git a/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/schema.py b/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/schema.py index 01512a468f..9d23c74178 100755 --- a/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/schema.py +++ b/plugins/automox/icon_automox/actions/upload_vulnerability_sync_file/schema.py @@ -15,7 +15,8 @@ class Input: class Output: - BATCH_ID = "batch_id" + ID = "id" + STATUS = "status" class UploadVulnerabilitySyncFileInput(insightconnect_plugin_runtime.Input): @@ -49,13 +50,13 @@ class UploadVulnerabilitySyncFileInput(insightconnect_plugin_runtime.Input): "type": "string", "title": "Report Source", "description": "The third-party source of the vulnerability report", - "default": "Generic Report", + "default": "generic", "enum": [ - "Generic Report", - "CrowdStrike", - "Rapid7", - "TenableIO", - "Qualys" + "generic", + "crowd-strike", + "rapid7", + "tenable", + "qualys" ], "order": 4 } @@ -77,15 +78,22 @@ class UploadVulnerabilitySyncFileOutput(insightconnect_plugin_runtime.Output): "type": "object", "title": "Variables", "properties": { - "batch_id": { + "id": { "type": "integer", - "title": "Vulnerability Sync Batch ID", - "description": "Identifier of vulnerability sync batch", + "title": "Vulnerability Sync Action Set ID", + "description": "Identifier of the vulnerability sync action set", "order": 1 + }, + "status": { + "type": "string", + "title": "Vulnerability Sync Status", + "description": "Status of the vulnerability sync action set", + "order": 2 } }, "required": [ - "batch_id" + "id", + "status" ] } """) diff --git a/plugins/automox/icon_automox/util/api_client.py b/plugins/automox/icon_automox/util/api_client.py index 5d68909ebd..8efd83f14c 100644 --- a/plugins/automox/icon_automox/util/api_client.py +++ b/plugins/automox/icon_automox/util/api_client.py @@ -7,7 +7,7 @@ class ApiClient: INTEGRATION_NAME = "rapid7-insightconnect-plugin" - VERSION = "1.1.1" + VERSION = "2.0.0" PAGE_SIZE = 500 OUTCOME_FAIL = "failure" @@ -31,10 +31,12 @@ def set_headers(self) -> None: "content-type": "application/json", } - def _call_api(self, method: str, url: str, params: Dict = {}, json_data: object = None) -> Optional[dict]: + def _call_api(self, method: str, url: str, params=None, json_data: object = None) -> Optional[Dict]: + if params is None: + params = {} try: response = self.session.request(method, url, json=json_data, params=params) - + self.logger.info(f"Request URL: {url}, Method: {method}, Response code: {response.status_code}") if response.status_code == 403: raise PluginException(preset=PluginException.Preset.API_KEY) @@ -44,6 +46,9 @@ def _call_api(self, method: str, url: str, params: Dict = {}, json_data: object if response.status_code == 204: return + if response.status_code == 202: + return + if 200 <= response.status_code < 300: return response.json() @@ -59,8 +64,10 @@ def _call_api(self, method: str, url: str, params: Dict = {}, json_data: object self.logger.info(f"Call to Automox Console API failed: {e}") raise PluginException(preset=PluginException.Preset.UNKNOWN) - def _page_results(self, url: str, init_params: Dict = {}, sanitize: bool = True) -> [dict]: - params = self.first_page(init_params) + def _page_results(self, url: str, params=None, sanitize: bool = True) -> List[Dict]: + if params is None: + params = {} + params = self.first_page(params) page_resp = [] @@ -80,8 +87,10 @@ def _page_results(self, url: str, init_params: Dict = {}, sanitize: bool = True) return page_resp - def _page_results_data(self, url: str, init_params: Dict = {}) -> [dict]: - params = self.first_page(init_params) + def _page_results_data(self, url: str, params=None) -> List[Dict]: + if params is None: + params = {} + params = self.first_page(params) page_resp = [] @@ -110,14 +119,16 @@ def remove_null_values(self, d: Collection): return d @staticmethod - def _org_param(org_id: str) -> dict: + def _org_param(org_id: int) -> Dict: if not org_id: return {} return {"o": org_id} @staticmethod - def first_page(params: Dict = {}) -> Dict: + def first_page(params=None) -> Dict: + if params is None: + params = {} params.update({"limit": ApiClient.PAGE_SIZE, "page": 0}) return params @@ -145,7 +156,7 @@ def get_org_users(self, org_id: int) -> Dict: def get_device(self, org_id: int, device_id: int) -> Dict: return self._call_api("GET", f"{self.endpoint}/servers/{device_id}", params=self._org_param(org_id)) - def find_device_by_attribute(self, org_id: int, attributes: List[str], value: str) -> dict: + def find_device_by_attribute(self, org_id: int, attributes: List[str], value: str) -> Dict: params = self.first_page(self._org_param(org_id)) while True: @@ -189,9 +200,10 @@ def run_device_command(self, org_id: int, device_id: int, command: str) -> bool: :param command: Command to be run :return: Boolean of outcome """ - return self._call_api( + resp = self._call_api( "POST", f"{self.endpoint}/servers/{device_id}/queues", params=self._org_param(org_id), json_data=command ) + return resp is not None def update_device(self, org_id: int, device_id: int, payload: Dict) -> bool: """ @@ -201,9 +213,10 @@ def update_device(self, org_id: int, device_id: int, payload: Dict) -> bool: :param payload: Dict of parameters to update on device :return: Boolean of outcome """ - return self._call_api( + resp = self._call_api( "PUT", f"{self.endpoint}/servers/{device_id}", params=self._org_param(org_id), json_data=payload ) + return resp is not None def delete_device(self, org_id: int, device_id: int) -> bool: """ @@ -212,11 +225,12 @@ def delete_device(self, org_id: int, device_id: int) -> bool: :param device_id: Device ID :return: Boolean of outcome """ - return self._call_api("DELETE", f"{self.endpoint}/servers/{device_id}", params=self._org_param(org_id)) + resp = self._call_api("DELETE", f"{self.endpoint}/servers/{device_id}", params=self._org_param(org_id)) + return resp is not None # Policies @staticmethod - def _sanitize_policies(policies: [dict]) -> List[Dict]: + def _sanitize_policies(policies: List[Dict]) -> List[Dict]: for policy in policies: for key, fields in {"configuration": ["evaluation_code", "installation_code", "remediation_code"]}.items(): if key in policy: @@ -268,9 +282,10 @@ def update_group(self, org_id: int, group_id: int, payload: Dict) -> bool: :param payload: Dict of parameters to update on group :return: Boolean of outcome """ - return self._call_api( + resp = self._call_api( "PUT", f"{self.endpoint}/servergroups/{group_id}", params=self._org_param(org_id), json_data=payload ) + return resp is not None def delete_group(self, org_id: int, group_id: int) -> bool: """ @@ -279,24 +294,31 @@ def delete_group(self, org_id: int, group_id: int) -> bool: :param group_id: Group ID :return: Boolean of outcome """ - return self._call_api("DELETE", f"{self.endpoint}/servergroups/{group_id}", params=self._org_param(org_id)) + resp = self._call_api("DELETE", f"{self.endpoint}/servergroups/{group_id}", params=self._org_param(org_id)) + return resp is not None # Vulnerability Sync - def upload_vulnerability_sync_file(self, org_id: int, file_content, filename, report_source) -> int: + def upload_vulnerability_sync_file(self, org_id: int, file_content, filename, report_source) -> Dict: with io.BytesIO(file_content) as file: files = [("file", (filename, file, "text/csv"))] headers = {"Authorization": f"Bearer {self.api_key}"} + params = self._org_param(org_id) + params['source'] = report_source try: response = requests.post( - f"{self.endpoint}/orgs/{org_id}/tasks/patch/batches/upload?source={report_source}", + f"{self.endpoint}/orgs/{org_id}/remediations/action-sets/upload", + params=params, files=files, headers=headers, ) # nosec B113 - if response.status_code == 200: - return response.json().get("id") + if response.status_code == 201: + return { + "id": response.json().get("id"), + "status": response.json().get("status"), + } else: raise PluginException( cause="Failed to upload file to Vulnerability Sync", @@ -308,20 +330,48 @@ def upload_vulnerability_sync_file(self, org_id: int, file_content, filename, re assistance=f"Review encoded CSV file and try again: {e}", ) - def get_vulnerability_sync_batches(self, org_id: int) -> List[Dict]: - return self._page_results_data(f"{self.endpoint}/orgs/{org_id}/tasks/batches") - - def get_vulnerability_sync_batch(self, org_id: int, batch_id: int) -> Dict: - return self._call_api("GET", f"{self.endpoint}/orgs/{org_id}/tasks/batches/{batch_id}") - - def update_vulnerability_sync_batch(self, org_id: int, batch_id: int, action: str) -> bool: - return self._call_api("POST", f"{self.endpoint}/orgs/{org_id}/tasks/batches/{batch_id}/{action}") + def list_vulnerability_sync_action_sets(self, org_id: int, params=None) -> List[Dict]: + if params is None: + params = {} + params.update(self._org_param(org_id)) + return self._page_results_data(f"{self.endpoint}/orgs/{org_id}/remediations/action-sets", + params=params) + + def list_vulnerability_sync_action_set_issues(self, org_id: int, action_set_id: int, params=None) -> List[Dict]: + if params is None: + params = {} + params.update(self._org_param(org_id)) + return self._page_results_data(f"{self.endpoint}/orgs/{org_id}/remediations/action-sets/{action_set_id}/issues", + params=params) + + def list_vulnerability_sync_action_set_solutions(self, org_id: int, action_set_id: int, params=None) -> List[Dict]: + if params is None: + params = {} + params.update(self._org_param(org_id)) + return self._page_results_data( + f"{self.endpoint}/orgs/{org_id}/remediations/action-sets/{action_set_id}/solutions", + params=params) + + def get_vulnerability_sync_action_set(self, org_id: int, action_set_id: int) -> Dict: + params = self._org_param(org_id) + return self._call_api("GET", + f"{self.endpoint}/orgs/{org_id}/remediations/action-sets/{action_set_id}", + params=params) - def get_vulnerability_sync_tasks(self, org_id: int, params: Dict) -> List[Dict]: - return self._page_results_data(f"{self.endpoint}/orgs/{org_id}/tasks", params) + def delete_vulnerability_sync_action_set(self, org_id: int, action_set_id: int) -> bool: + params = self._org_param(org_id) + resp = self._call_api("DELETE", f"{self.endpoint}/orgs/{org_id}/remediations/action-sets/{action_set_id}", + params=params) + # 204 No Content + return resp is None - def update_vulnerability_sync_task(self, org_id: int, task_id: int, action: str) -> bool: - return self._call_api("PATCH", f"{self.endpoint}/orgs/{org_id}/tasks/{task_id}", params={"action": action}) + def execute_vulnerability_sync_actions(self, org_id: int, action_set_id: int, actions: List[Dict]) -> Dict: + params = self._org_param(org_id) + data = { + "actions": actions + } + return self._call_api("POST", f"{self.endpoint}/orgs/{org_id}/remediations/action-sets/{action_set_id}/actions", + json_data=data, params=params) # Events def get_events(self, org_id: int, event_type: str, page: int = 0) -> List[Dict]: diff --git a/plugins/automox/icon_automox/util/cleaner.py b/plugins/automox/icon_automox/util/cleaner.py new file mode 100644 index 0000000000..4bbc3b1305 --- /dev/null +++ b/plugins/automox/icon_automox/util/cleaner.py @@ -0,0 +1,11 @@ +from typing import Dict + + +def clean_ax_response(resp: Dict) -> Dict: + """ + Remove null values from the action set + :param resp: + :return: + """ + return dict(filter(lambda k: k[1] is not None, resp.items())) + diff --git a/plugins/automox/icon_automox/util/param_parser.py b/plugins/automox/icon_automox/util/param_parser.py new file mode 100644 index 0000000000..1cb6f2d5ea --- /dev/null +++ b/plugins/automox/icon_automox/util/param_parser.py @@ -0,0 +1,16 @@ +from typing import Dict + + +def inputs_to_query_params(input_dict: Dict) -> Dict: + """ + Takes a dict of input parameters and returns a dict of query parameters, useful when plugin inputs names do not + match the API query parameters exactly. + :param input_dict: dict of input parameters + :return: dict of query parameters + """ + query_params = {} + for key, value in input_dict.items(): + if value is not None: + query_params[key] = value + + return query_params diff --git a/plugins/automox/plugin.spec.yaml b/plugins/automox/plugin.spec.yaml index e80b2ef015..9850065a84 100644 --- a/plugins/automox/plugin.spec.yaml +++ b/plugins/automox/plugin.spec.yaml @@ -1,25 +1,28 @@ plugin_spec_version: v2 extension: plugin -products: [insightconnect] +products: [ insightconnect ] name: automox title: Automox description: Automox is modernizing IT operations with continuous visibility, insight, and agility for your entire IT environment -version: 1.2.0 -supported_versions: ["All as of 1/21/2022"] +version: 2.0.0 +supported_versions: [ "All as of 10/09/2023" ] vendor: automox support: partner -status: [] -tags: [endpoint, patch] +status: [ ] +tags: [ endpoint, patch ] hub_tags: - use_cases: [threat_detection_and_response, asset_inventory, remediation_management] - keywords: [endpoint] - features: [] + use_cases: [ threat_detection_and_response, asset_inventory, remediation_management ] + keywords: [ endpoint ] + features: [ ] resources: source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/automox license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE vendor_url: https://www.automox.com/ enable_cache: false - +sdk: + type: slim + version: 5 + user: nobody types: organization: id: @@ -577,7 +580,7 @@ types: description: Creation time of event type: string required: false - batch_user: + action_set_user: id: title: User ID description: The user identifier @@ -598,180 +601,252 @@ types: description: The email of the user type: string required: false - batch: - id: - title: Batch ID - description: Identifier of batch - type: integer - required: true - organization_id: - title: Organization ID - description: Identifier of organization + action_set_issues: + unknown_host_count: + title: Unknown Host Count + description: Number of hosts that are unknown within the action set type: integer required: false - status: - title: Batch Status - description: Status of batch - type: string + action_set_statistics: + issues: + title: Issues + description: Issues associated with the action set + type: action_set_issues required: false - source: - title: Batch Source - description: Source of batch + action_set_source: + name: + title: Source Name + description: Name of the source type: string required: false - created_by: - title: Created By - description: Batch creation details - type: batch_user - required: false - updated_by: - title: Updated By - description: Batch update details - type: batch_user - required: false - uploaded_at: - title: Uploaded At - description: Datetime the batch was uploaded + type: + title: Source Type + description: Type of the source type: string required: false - task_count: - title: Task Count - description: Number of tasks related to batch + action_set_solution_counts: + count: + title: Solution Count + description: Number of solutions associated with the action set type: integer required: false - unknown_host_count: - title: Unknown Host Count - description: Number of hosts that are unknown within batch + device_count: + title: Device Count + description: Number of devices associated with the action set type: integer required: false - impacted_device_count: - title: Impacted Device Count - description: Number of devices that are impacted by batch + vulnerability_count: + title: Vulnerability Count + description: Number of vulnerabilities associated with the action set type: integer required: false - issue_count: - title: Issue Count - description: Number of issues identified with batch - type: integer + action_set_solution_summary: + patch_now: + title: Patch Now + description: Number of devices that will be patched immediately + type: action_set_solution_counts required: false - cve_count: - title: CVE Count - description: Number of CVEs that are impacted by batch - type: integer + patch_with_worklet: + title: Patch with Worklet + description: Number of devices that will be patched with a worklet + type: action_set_solution_counts required: false - task_payload_package_versions: + action_set: id: - title: Package ID - description: The package identifier associated with the task - type: string + title: Action Set ID + description: Identifier of the action set + type: integer required: true - name: - title: Name - description: The name of the package associated with the task + statistics: + title: Action Set Statistics + description: Statistics of the action set + type: action_set_statistics + required: false + solutions: + title: Solutions + description: Solutions associated with the action set + type: action_set_solution_summary + required: false + configuration_id: + title: Configuration ID + description: Identifier of the configuration, only applicable for Automated Vulnerability Remediation (AVR) action sets type: string required: false - version: - title: Version - description: The version of the package associated with the task - type: string + organization_id: + title: Organization ID + description: Identifier of the organization + type: integer required: false - display_name: - title: Display Name - description: The display name of the package associated with the task + status: + title: Action Set Status + description: Status of the action set type: string required: false - requires_reboot: - title: Requires Reboot - description: Whether the package installed by the task will require reboot - type: boolean + source: + title: Action Set Source + description: Source of the action set + type: action_set_source required: false - task_payload: - patch_id: - title: Patch ID - description: The patch identifier associated with the task - type: string + created_by: + title: Created By + description: action set creation details + type: action_set_user required: false - severity: - title: Severity - description: The severity of the patch associated with the task + created_at: + title: Created At + description: Datetime the action set was created type: string required: false - package_versions: - title: Package Versions - description: The version of the packages within scope of the task - type: "[]task_payload_package_versions" + updated_at: + title: Uploaded At + description: Datetime the action set was uploaded + type: string required: false - task: - id: - title: Task ID - description: Identifier of task + action_set_action: + action: + title: Action + description: The action to execute for the associated remediation + type: string + required: true + enum: + - "patch-now" + - "patch-with-worklet" + default: "patch-now" + solution_id: + title: Solution ID + description: The solution ID associated with the action type: integer required: true - organization_id: - title: Organization ID - description: Identifier of organization + action_set_issue: + id: + title: Issue ID + description: Identifier of the issue type: integer - required: false - task_type: - title: Task Type - description: Type of task + required: true + issue_type: + title: Issue Type + description: Type of issue type: string - required: false - payload: - title: Payload - description: Payload associated with task - type: task_payload - required: false - source: - title: Task Source - description: Source of task + required: true + issue_details: + title: Issue Details + description: Details of the issue + type: object + required: true + solution_device: + id: + title: Device ID + description: Identifier of device + type: integer + required: true + name: + title: Device Name + description: Name of the device type: string required: false - notes: - title: Task Notes - description: Notes associated with task + custom_name: + title: Custom Name + description: Custom name of the device type: string required: false status: - title: Task Status - description: Status of task + title: Device Status + description: Status of remediation for the device type: string required: false - created_by_user: - title: Created by User - description: Task creation details - type: batch_user + deleted: + title: Deleted + description: Whether the device is deleted from Automox + type: boolean required: false - last_updated_by_user: - title: Updated by User - description: Task update details - type: batch_user + ip_addrs_private: + title: Private IP Addresses + description: List of private IP addresses for the device + type: "[]string" required: false - created_at: - title: Created At - description: The datetime the task was created + solution_vulnerability: + id: + title: Vulneability ID + description: Identifier of the vulnerability, typically a CVE + type: string + required: true + title: + title: Title + description: Title of the vulnerability type: string required: false - updated_at: - title: Updated At - description: The datetime the task was updated + summary: + title: Summary + description: Summary of the vulnerability type: string required: false - completed_at: - title: Completed At - description: The datetime the task was completed + severity: + title: Severity + description: Severity of the vulnerability type: string required: false - cves: - title: CVEs - description: List of CVEs associated with task - type: "[]string" + solution: + id: + title: Solution ID + description: Identifier of solution + type: integer + required: true + example: 1234 + solution_type: + title: Solution Type + description: Type of solution + type: string required: false - report_source: - title: Report Source - description: The source of the vulnerability report + example: "rapid7-solution" + remediation_type: + title: Remediation Type + description: Type of remediation type: string required: false + example: "patch-with-worklet" + solution_details: + title: Solution Details + description: Details of the solution. This can include package information and other details depending on the solution type + type: object + required: false + example: + solution_id: "office-click-to-run-upgrade-latest" + solution_type: "workaround" + solution_summary: "Upgrade to the latest version of Microsoft Office" + solution_fix: "Install Office Click-To-Run updates through any installed Office application. Go to File > Account (or Office Account if you opened Outlook). Under Product Information, choose Update Options > Update Now." + device_ids: + title: Device IDs + description: List of device identifiers associated with the solution. This is a helper field to make executing actions easier. It does not exist on the Automox API. + type: "[]integer" + required: false + example: [ 1234, 5678 ] + devices: + title: Devices + description: List of devices associated with the solution + type: "[]solution_device" + required: false + example: + - id: 1234 + name: "device-1" + custom_name: "custom-name" + status: "in_progress" + deleted: false + ip_addrs_private: + - 10.0.0.1 + vulnerabilities: + title: Vulnerabilities + description: List of vulnerabilities associated with the solution + type: "[]solution_vulnerability" + required: false + example: + - id: "CVE-2019-1297" + title: "Microsoft Excel Remote Code Execution Vulnerability" + summary: "A remote code execution vulnerability exists in Microsoft Excel software when the software fails to properly handle objects in memory. An attacker who successfully exploited the vulnerability could run arbitrary code in the context of the current user. If the current user is logged on with administrative user rights, an attacker could take control of the affected system. An attacker could then install programs; view, change, or delete data; or create new accounts with full user rights. Users whose accounts are configured to have fewer user rights on the system could be less impacted than users who operate with administrative user rights. Exploitation of the vulnerability requires that a user open a specially crafted file with an affected version of Microsoft Excel. In an email attack scenario, an attacker could exploit the vulnerability by sending the specially crafted file to the user and convincing the user to open the file. In a web-based attack scenario, an attacker could host a website (or leverage a compromised website that accepts or hosts user-provided content) containing a specially crafted file designed to exploit the vulnerability. An attacker would have no way to force users to visit the website. Instead, an attacker would have to convince users to click a link, typically by way of an enticement in an email or instant message, and then convince them to open the specially crafted file. The security update addresses the vulnerability by correcting how Microsoft Excel handles objects in memory." + severity: "high" + - id: "CVE-2021-42292" + title: "Microsoft Excel Security Feature Bypass Vulnerability" + summary: "" + severity: "high" connection: api_key: @@ -916,7 +991,7 @@ actions: description: List of tags type: "[]string" required: false - example: ["tag1", "tag2"] + example: [ "tag1", "tag2" ] exception: title: Exception description: Exclude the device from reports and statistics @@ -1001,12 +1076,12 @@ actions: description: Command to run on device type: string enum: - - "GetOS" - - "InstallUpdate" - - "InstallAllUpdates" - - "PolicyTest" - - "PolicyRemediate" - - "Reboot" + - "GetOS" + - "InstallUpdate" + - "InstallAllUpdates" + - "PolicyTest" + - "PolicyRemediate" + - "Reboot" required: true example: "GetOS" patches: @@ -1014,7 +1089,7 @@ actions: description: "List of patches to be installed by name (Note: this only works with the InstallUpdate command)" type: "[]string" required: false - example: ["Security Update (KB4549947)"] + example: [ "Security Update (KB4549947)" ] policy_id: title: Policy ID description: Identifier of policy @@ -1089,7 +1164,7 @@ actions: description: List of policy IDs to assign to group type: "[]integer" required: false - example: [1, 2, 3] + example: [ 1, 2, 3 ] output: success: title: Success @@ -1153,7 +1228,7 @@ actions: description: List of policy IDs to assign to group type: "[]integer" required: false - example: [1, 2, 3] + example: [ 1, 2, 3 ] output: success: title: Success @@ -1210,24 +1285,30 @@ actions: description: The third-party source of the vulnerability report type: string required: false - default: "Generic Report" + default: "generic" enum: - - "Generic Report" - - "CrowdStrike" - - "Rapid7" - - "TenableIO" - - "Qualys" - example: "Rapid7" + - "generic" + - "crowd-strike" + - "rapid7" + - "tenable" + - "qualys" + example: "rapid7" output: - batch_id: - title: Vulnerability Sync Batch ID - description: Identifier of vulnerability sync batch + id: + title: Vulnerability Sync Action Set ID + description: Identifier of the vulnerability sync action set type: integer required: true example: 1234 - get_vulnerability_sync_batch: - title: Get Vulnerability Sync Batch - description: Retrieve details for a specified vulnerability sync batch + status: + title: Vulnerability Sync Status + description: Status of the vulnerability sync action set + type: string + required: true + example: "building" + get_vulnerability_sync_action_set: + title: Get Vulnerability Sync Action Set + description: Retrieve details for a specified vulnerability sync action set input: org_id: title: Organization ID @@ -1235,21 +1316,21 @@ actions: type: integer required: true example: 1234 - batch_id: - title: Batch ID - description: Identifier of batch + action_set_id: + title: Action Set ID + description: Identifier of the action set type: integer required: true example: 1234 output: - batch: - title: Vulnerability Sync Batch - description: Details of a specified vulnerability sync batch - type: batch + action_set: + title: Vulnerability Sync action set + description: Details of a specified vulnerability sync action_set + type: action_set required: true - action_on_vulnerability_sync_batch: - title: Accept or Reject Vulnerability Sync Batch - description: Take action to approve or reject vulnerability sync batch + list_vulnerability_sync_action_sets: + title: List Vulnerability Sync Action Sets + description: Retrieve list of vulnerability sync batches input: org_id: title: Organization ID @@ -1257,30 +1338,147 @@ actions: type: integer required: true example: 1234 - batch_id: - title: Batch ID - description: Identifier of batch + sort: + title: Sort + description: Sort results by field + type: string + required: false + enum: + - "created_at" + - "updated_at" + - "status" + - "source_type" + - "source_name" + - "configuration_id" + - "" + example: "created_at" + group_sort: + title: Group Sort + description: Sort results by field + type: string + required: false + enum: + - "asc" + - "desc" + - "latest_updated_at:asc" + - "latest_updated_at:desc" + - "source:asc" + - "source:desc" + - "" + example: "latest_updated_at:desc" + source_type_in: + title: Source Type In + description: Filter by source type + type: "[]string" + required: false + example: + - "Generic Report" + - "CrowdStrike" + - "Rapid7" + - "TenableIO" + - "Qualys" + status_in: + title: Status In + description: Filter by status + type: "[]string" + required: false + example: + - "building" + - "ready" + - "error" + status_not_in: + title: Status Not In + description: Filter by status + type: "[]string" + required: false + example: + - "building" + - "ready" + - "error" + configuration_id_equals: + title: Configuration ID Equals + description: Filter by configuration ID + type: string + required: false + example: "00000000-0000-0000-0000-000000000000" + configuration_id_is_set: + title: Configuration ID Is Set + description: Filter based on whether the configuration ID is set + type: boolean + required: false + example: true + include_all_runs_equals: + title: Include All Runs Equals + description: Whether to include all runs in the response + type: boolean + required: false + example: true + output: + action_sets: + title: Vulnerability Sync Action Sets + description: List of vulnerability sync action sets + type: "[]action_set" + required: false + example: + - created_at: 2023-10-10T03:45:26+0000 + created_by_user: + email: user.name@example.com + firstname: User + id: 1 + lastname: Name + id: 1234 + organization_id: 1 + source: + name: insightconnect-uploaded-report.csv + type: generic + statistics: + issues: + unknown-host: + count: 4 + solutions: + patch-with-worklet: + count: 1 + device_count: 18 + vulnerability_count: 1 + status: ready + updated_at: 2023-10-10T03:45:30+0000 + updated_by_user: + email: user.name@example.com + firstname: User + id: 1 + lastname: Name + list_vulnerability_sync_action_set_issues: + title: List Vulnerability Sync Action Set Issues + description: Retrieve the issues identified for a specified vulnerability sync action set + input: + org_id: + title: Organization ID + description: Identifier of organization type: integer required: true example: 1234 - action: - title: Action - description: Action to take on batch - type: string - enum: - - "accept" - - "reject" + action_set_id: + title: Action Set ID + description: Identifier of the action set + type: integer required: true - example: "accept" + example: 1234 + issue_type_in: + title: Issue Type In + description: Filter by issue type + type: "[]string" + required: false + example: + - "unknown-host" output: - success: - title: Success - description: Was operation successful - type: boolean + issues: + title: Vulnerability Sync Action Set Issues + description: Issues associated with the specified vulnerability sync action_set + type: "[]action_set_issue" required: true - list_vulnerability_sync_batches: - title: List Vulnerability Sync Batches - description: Retrieve list of vulnerability sync batches + list_vulnerability_sync_action_set_solutions: + title: List Vulnerability Sync Action Set Solutions + description: Retrieve a list of vulnerability sync remediations input: org_id: title: Organization ID @@ -1288,15 +1486,48 @@ actions: type: integer required: true example: 1234 + action_set_id: + title: Action Set ID + description: Filter by action set identifier + type: integer + required: true + example: 1234 + remediation_type_in: + title: Remediation Type In + description: Filter by remediation type + type: "[]string" + required: false + example: + - "patch-now" + - "patch-with-worklet" + severity_in: + title: Severity In + description: Filter by severity + type: "[]string" + required: false + example: + - "critical" + - "high" + - "medium" + - "low" + - "unknown" + vulnerability_in: + title: Vulnerability In + description: Filter by vulnerability + type: "[]string" + required: false + example: + - "CVE-2020-1234" + - "CVE-2020-5678" output: - batches: - title: Vulnerability Sync Batches - description: List of vulnerability sync batches - type: "[]batch" + solutions: + title: Vulnerability Sync Solutions + description: List of vulnerability sync Solutions + type: "[]solution" required: false - list_vulnerability_sync_tasks: - title: List Vulnerability Sync Tasks - description: Retrieve list of vulnerability sync tasks + execute_vulnerability_sync_actions: + title: Execute Vulnerability Sync Actions + description: Launch remediation for patch and worklet remediations input: org_id: title: Organization ID @@ -1304,27 +1535,38 @@ actions: type: integer required: true example: 1234 - status: - title: Status - description: Filter by status of tasks - type: string - required: false - example: "in_progress" - batch_id: - title: Batch ID - description: Filter by batch identifier + action_set_id: + title: Action Set ID + description: Identifier of the action set type: integer - required: false + required: true example: 1234 + actions: + title: Actions + description: List of remediations to execute + type: "[]action_set_action" + required: true + example: + - action: "patch-now" + solution_id: 1234 + device_ids: + - 1234 + - 5678 + - action: "patch-with-worklet" + solution_id: 1234 + worklet_id: 1234 + device_ids: + - 1234 + - 5678 output: - tasks: - title: Vulnerability Sync Tasks - description: List of vulnerability sync tasks - type: "[]task" - required: false - action_on_vulnerability_sync_task: - title: Execute or Cancel Vulnerability Sync Task - description: Take action to execute or cancel a vulnerability sync task + success: + title: Success + description: Was operation successful + type: boolean + required: true + delete_vulnerability_sync_action_set: + title: Delete Vulnerability Sync Action Set + description: Delete a vulnerability sync action set and all associated data input: org_id: title: Organization ID @@ -1332,21 +1574,12 @@ actions: type: integer required: true example: 1234 - task_id: - title: Task ID - description: Identifier of task + action_set_id: + title: Action Set ID + description: Identifier of the action set type: integer required: true example: 1234 - action: - title: Action - description: Action to take on vulnerability sync task - type: string - enum: - - "execute" - - "cancel" - required: true - example: "execute" output: success: title: Success diff --git a/plugins/automox/setup.py b/plugins/automox/setup.py index 6d2d5f0f80..82953664ad 100755 --- a/plugins/automox/setup.py +++ b/plugins/automox/setup.py @@ -3,7 +3,7 @@ setup(name="automox-automox-plugin", - version="1.2.0", + version="2.0.0", description="Automox is modernizing IT operations with continuous visibility, insight, and agility for your entire IT environment", author="automox", author_email="", diff --git a/plugins/automox/unit_test/test_action_on_vulnerability_sync_batch.py b/plugins/automox/unit_test/test_action_on_vulnerability_sync_batch.py deleted file mode 100644 index ede97010c8..0000000000 --- a/plugins/automox/unit_test/test_action_on_vulnerability_sync_batch.py +++ /dev/null @@ -1,49 +0,0 @@ -import os -import sys - -sys.path.append(os.path.abspath("../")) - -from parameterized import parameterized -from unittest.mock import patch, Mock -from unittest import TestCase -from insightconnect_plugin_runtime.exceptions import ConnectionTestException, PluginException - -from unit_test.util import ( - Util, - mock_request_200, - mock_request_403, - mock_request_404, - mocked_request, - mock_request_200_invalid_json, - ORG_ID, - BATCH_ID, - ACTION, -) -from icon_automox.actions.action_on_vulnerability_sync_batch import ActionOnVulnerabilitySyncBatch -from icon_automox.actions.action_on_vulnerability_sync_batch.schema import Input, Output - - -class TestActionOnVulnerabilitySyncBatch(TestCase): - def setUp(self) -> None: - self.action = Util.default_connector(ActionOnVulnerabilitySyncBatch()) - self.params = {Input.ORG_ID: ORG_ID, Input.BATCH_ID: BATCH_ID, Input.ACTION: ACTION} - - @patch("requests.Session.request", side_effect=mock_request_200) - def test_action_on_vulnerability_sync_batch_ok(self, mock: Mock) -> None: - response = self.action.run(self.params) - expected_response = {Output.SUCCESS: True} - self.assertEqual(response, expected_response) - - @parameterized.expand( - [ - (mock_request_403, PluginException.causes[PluginException.Preset.API_KEY]), - (mock_request_403, PluginException.causes[PluginException.Preset.API_KEY]), - (mock_request_404, PluginException.causes[PluginException.Preset.NOT_FOUND]), - (mock_request_200_invalid_json, PluginException.causes[PluginException.Preset.INVALID_JSON]), - ], - ) - def test_action_on_vulnerability_sync_batch_exception(self, mock_request: Mock, exception: str) -> None: - mocked_request(mock_request) - with self.assertRaises(ConnectionTestException) as context: - self.action.run(self.params) - self.assertEqual(context.exception.cause, exception) diff --git a/plugins/automox/unit_test/test_action_on_vulnerability_sync_task.py b/plugins/automox/unit_test/test_action_on_vulnerability_sync_task.py deleted file mode 100644 index 61c63ab8a0..0000000000 --- a/plugins/automox/unit_test/test_action_on_vulnerability_sync_task.py +++ /dev/null @@ -1,49 +0,0 @@ -import os -import sys - -sys.path.append(os.path.abspath("../")) - -from parameterized import parameterized -from unittest.mock import patch, Mock -from unittest import TestCase -from insightconnect_plugin_runtime.exceptions import ConnectionTestException, PluginException - -from unit_test.util import ( - Util, - mock_request_200, - mock_request_403, - mock_request_404, - mocked_request, - mock_request_200_invalid_json, - ORG_ID, - TASK_ID, - ACTION, -) -from icon_automox.actions.action_on_vulnerability_sync_task import ActionOnVulnerabilitySyncTask -from icon_automox.actions.action_on_vulnerability_sync_task.schema import Input, Output - - -class TestActionOnVulnerabilitySyncTask(TestCase): - def setUp(self) -> None: - self.action = Util.default_connector(ActionOnVulnerabilitySyncTask()) - self.params = {Input.ORG_ID: ORG_ID, Input.TASK_ID: TASK_ID, Input.ACTION: ACTION} - - @patch("requests.Session.request", side_effect=mock_request_200) - def test_action_on_vulnerability_sync_task_ok(self, mock: Mock) -> None: - response = self.action.run(self.params) - expected_response = {Output.SUCCESS: True} - self.assertEqual(response, expected_response) - - @parameterized.expand( - [ - (mock_request_403, PluginException.causes[PluginException.Preset.API_KEY]), - (mock_request_403, PluginException.causes[PluginException.Preset.API_KEY]), - (mock_request_404, PluginException.causes[PluginException.Preset.NOT_FOUND]), - (mock_request_200_invalid_json, PluginException.causes[PluginException.Preset.INVALID_JSON]), - ], - ) - def test_action_on_vulnerability_sync_batch_exception(self, mock_request: Mock, exception: str) -> None: - mocked_request(mock_request) - with self.assertRaises(ConnectionTestException) as context: - self.action.run(self.params) - self.assertEqual(context.exception.cause, exception) diff --git a/plugins/automox/unit_test/test_get_vulnerability_sync_batch.py b/plugins/automox/unit_test/test_get_vulnerability_sync_batch.py deleted file mode 100644 index fd394406df..0000000000 --- a/plugins/automox/unit_test/test_get_vulnerability_sync_batch.py +++ /dev/null @@ -1,73 +0,0 @@ -import os -import sys - -sys.path.append(os.path.abspath("../")) - -from parameterized import parameterized -from unittest.mock import patch, Mock -from unittest import TestCase -from insightconnect_plugin_runtime.exceptions import ConnectionTestException, PluginException - -from unit_test.util import ( - Util, - mock_request_200, - mock_request_403, - mock_request_404, - mocked_request, - mock_request_200_invalid_json, - ORG_ID, - BATCH_ID, -) -from icon_automox.actions.get_vulnerability_sync_batch import GetVulnerabilitySyncBatch -from icon_automox.actions.get_vulnerability_sync_batch.schema import Input, Output - - -class TestGetVulnerabilitySyncBatch(TestCase): - def setUp(self) -> None: - self.action = Util.default_connector(GetVulnerabilitySyncBatch()) - self.params = {Input.ORG_ID: ORG_ID, Input.BATCH_ID: BATCH_ID} - - @patch("requests.Session.request", side_effect=mock_request_200) - def test_get_vulnerability_sync_batch_ok(self, mock: Mock) -> None: - response = self.action.run(self.params) - expected_response = { - Output.BATCH: { - "id": 1234, - "organization_id": 1234, - "status": "accepted", - "source": "example", - "created_by": { - "id": 123, - "firstname": "ExampleName", - "lastname": "ExampleLastName", - "email": "user@example.com", - }, - "updated_by": { - "id": 123, - "firstname": "ExampleName", - "lastname": "ExampleLastName", - "email": "user@example.com", - }, - "updated_at": "2023-03-01T12:00:00+0000", - "task_count": 0, - "unknown_host_count": 0, - "impacted_device_count": 0, - "issue_count": 0, - "cve_count": 0, - } - } - self.assertEqual(response, expected_response) - - @parameterized.expand( - [ - (mock_request_403, PluginException.causes[PluginException.Preset.API_KEY]), - (mock_request_403, PluginException.causes[PluginException.Preset.API_KEY]), - (mock_request_404, PluginException.causes[PluginException.Preset.NOT_FOUND]), - (mock_request_200_invalid_json, PluginException.causes[PluginException.Preset.INVALID_JSON]), - ], - ) - def test_get_vulnerability_sync_batch_exception(self, mock_request: Mock, exception: str) -> None: - mocked_request(mock_request) - with self.assertRaises(ConnectionTestException) as context: - self.action.run(self.params) - self.assertEqual(context.exception.cause, exception)