From ded2ebf39f75b6833ccac869533cff6b3bd5c161 Mon Sep 17 00:00:00 2001 From: igorski-r7 <99184344+igorski-r7@users.noreply.github.com> Date: Mon, 2 Oct 2023 11:45:02 +0200 Subject: [PATCH] Carbon Black Cloud - 386 - Updated the SDK version | Cloud enabled (#1988) (#1997) --- plugins/carbon_black_cloud/.CHECKSUM | 12 +- plugins/carbon_black_cloud/Dockerfile | 18 +- .../bin/icon_carbon_black_cloud | 46 ++- plugins/carbon_black_cloud/help.md | 333 ++++++++++------- .../actions/__init__.py | 5 +- .../actions/get_agent_details/__init__.py | 2 +- .../actions/get_agent_details/action.py | 4 +- .../actions/get_agent_details/schema.py | 15 +- .../actions/quarantine/__init__.py | 2 +- .../actions/quarantine/action.py | 6 +- .../actions/quarantine/schema.py | 18 +- .../connection/__init__.py | 2 +- .../connection/connection.py | 46 ++- .../connection/schema.py | 33 +- .../icon_carbon_black_cloud/tasks/__init__.py | 2 + .../triggers/__init__.py | 3 +- .../icon_carbon_black_cloud/util/constants.py | 1 + plugins/carbon_black_cloud/plugin.spec.yaml | 344 +++++++++--------- plugins/carbon_black_cloud/requirements.txt | 3 +- plugins/carbon_black_cloud/setup.py | 4 +- .../carbon_black_cloud/unit_test/__init__.py | 1 + .../responses/get_agent_details.json.resp | 113 ++++++ .../unit_test/responses/quarantine.json.resp | 1 + .../unit_test/test_agent_type.py | 6 + .../unit_test/test_get_agent_details.py | 141 +++++-- .../unit_test/test_quarantine.py | 82 +++-- .../unit_test/test_whitelist_checker.py | 8 +- plugins/carbon_black_cloud/unit_test/util.py | 103 ++++++ 28 files changed, 906 insertions(+), 448 deletions(-) create mode 100644 plugins/carbon_black_cloud/icon_carbon_black_cloud/tasks/__init__.py create mode 100644 plugins/carbon_black_cloud/icon_carbon_black_cloud/util/constants.py create mode 100644 plugins/carbon_black_cloud/unit_test/__init__.py create mode 100644 plugins/carbon_black_cloud/unit_test/responses/get_agent_details.json.resp create mode 100644 plugins/carbon_black_cloud/unit_test/responses/quarantine.json.resp create mode 100644 plugins/carbon_black_cloud/unit_test/util.py diff --git a/plugins/carbon_black_cloud/.CHECKSUM b/plugins/carbon_black_cloud/.CHECKSUM index 2b024ae24e..200e38365a 100644 --- a/plugins/carbon_black_cloud/.CHECKSUM +++ b/plugins/carbon_black_cloud/.CHECKSUM @@ -1,19 +1,19 @@ { - "spec": "e5b6b3d9aa6cbf29b762b7765f740eb0", - "manifest": "3731ceb2c2b1ec3bd60bf42390a63baa", - "setup": "1cd2b92709a21e8fd13f17723054758c", + "spec": "7a5657896c1f07e826c5c384f218ebeb", + "manifest": "d2e7fc2babe82cd2cc3a65d6b30c25a7", + "setup": "cc8128ff5f6d2041b968dbf96d81cd6d", "schemas": [ { "identifier": "get_agent_details/schema.py", - "hash": "82b1b8b683b6666cbca53a6d847bbb23" + "hash": "a4103fd58ab7f8d0437b352fe09f669d" }, { "identifier": "quarantine/schema.py", - "hash": "dfd6d7b199db55b1cd8be36d15e96eba" + "hash": "e595e1f63ac67839d1cc429af097a0c6" }, { "identifier": "connection/schema.py", - "hash": "5bafa80ff66a658d16d6c71a60c4e173" + "hash": "b055776a3ea5e159540fcda6a7d13f6c" } ] } \ No newline at end of file diff --git a/plugins/carbon_black_cloud/Dockerfile b/plugins/carbon_black_cloud/Dockerfile index 81f611b735..0b1cccc7c9 100755 --- a/plugins/carbon_black_cloud/Dockerfile +++ b/plugins/carbon_black_cloud/Dockerfile @@ -1,24 +1,18 @@ -FROM rapid7/insightconnect-python-3-38-plugin:4 -# Refer to the following documentation for available SDK parent images: https://docs.rapid7.com/insightconnect/sdk-guide/#sdk-guide +FROM rapid7/insightconnect-python-3-38-plugin:5 LABEL organization=rapid7 LABEL sdk=python -# Add any custom package dependencies here -# NOTE: Add pip packages to requirements.txt - -# End package dependencies - -# Add source code WORKDIR /python/src + ADD ./plugin.spec.yaml /plugin.spec.yaml -ADD . /python/src +ADD ./requirements.txt /python/src/requirements.txt -# Install pip dependencies RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi -# Install plugin -RUN python setup.py build && python setup.py install +ADD . /python/src + +RUN python setup.py build && python setup.py install # User to run plugin code. The two supported users are: root, nobody USER nobody diff --git a/plugins/carbon_black_cloud/bin/icon_carbon_black_cloud b/plugins/carbon_black_cloud/bin/icon_carbon_black_cloud index 8d8c7a80c5..0ebd680095 100755 --- a/plugins/carbon_black_cloud/bin/icon_carbon_black_cloud +++ b/plugins/carbon_black_cloud/bin/icon_carbon_black_cloud @@ -1,30 +1,44 @@ #!/usr/bin/env python -# GENERATED BY KOMAND SDK - DO NOT EDIT -import insightconnect_plugin_runtime -from icon_carbon_black_cloud import connection, actions, triggers - +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT +import os +import json +from sys import argv Name = "VMware Carbon Black Cloud" Vendor = "rapid7" -Version = "1.0.2" +Version = "2.0.0" Description = "Quarantine endpoints and get device details with the VMware Carbon Black Cloud plugin" -class ICONCarbonBlackCloud(insightconnect_plugin_runtime.Plugin): - def __init__(self): - super(self.__class__, self).__init__( - name=Name, - vendor=Vendor, +def main(): + if 'http' in argv: + if os.environ.get("GUNICORN_CONFIG_FILE"): + with open(os.environ.get("GUNICORN_CONFIG_FILE")) as gf: + gunicorn_cfg = json.load(gf) + if gunicorn_cfg.get("worker_class", "sync") == "gevent": + from gevent import monkey + monkey.patch_all() + elif 'gevent' in argv: + from gevent import monkey + monkey.patch_all() + + import insightconnect_plugin_runtime + from icon_carbon_black_cloud import connection, actions, triggers, tasks + + class ICONCarbonBlackCloud(insightconnect_plugin_runtime.Plugin): + def __init__(self): + super(self.__class__, self).__init__( + name=Name, + vendor=Vendor, version=Version, description=Description, connection=connection.Connection() - ) - self.add_action(actions.GetAgentDetails()) - - self.add_action(actions.Quarantine()) + ) + self.add_action(actions.GetAgentDetails()) + + self.add_action(actions.Quarantine()) + - -def main(): """Run plugin""" cli = insightconnect_plugin_runtime.CLI(ICONCarbonBlackCloud()) cli.run() diff --git a/plugins/carbon_black_cloud/help.md b/plugins/carbon_black_cloud/help.md index 05e0431883..f92ed1b87b 100755 --- a/plugins/carbon_black_cloud/help.md +++ b/plugins/carbon_black_cloud/help.md @@ -4,15 +4,19 @@ The [VMware Carbon Black Cloud](https://www.carbonblack.com/products/vmware-carb Manage and contain threats on your Carbon Black endpoints using this plugin. # Key Features - + * Get device information * Quarantine a device # Requirements - + * API Credentials * Base URL +# Supported Product Versions + +* 2023-09-19 + # Documentation ## Setup @@ -22,12 +26,12 @@ For information on how to get the API credentials and your base URL please see t The connection configuration accepts the following parameters: |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | |api_id|string|None|True|API ID|None|ADFF2QLIIZ| |api_secret_key|credential_secret_key|None|True|API secret key|None|Z1PXFRDZI321LXQVAB9IJKKZ| |org_key|string|None|True|Organization Key|None|1ABZY2FJ| -|url|string|https://defense.conferdeploy.net|True|API URL|None|https://defense.conferdeploy.net| - +|url|string|defense.conferdeploy.net|True|The Carbon Black Cloud URL you use. You can find this by looking at the web address of your Carbon Black Cloud console|['defense-eap01.conferdeploy.net', 'dashboard.confer.net', 'defense.conferdeploy.net', 'defense-prod05.conferdeploy.net', 'defense-eu.conferdeploy.net', 'defense-prodnrt.conferdeploy.net', 'defense-prodsyd.conferdeploy.net', 'ew2.carbonblackcloud.vmware.com', 'gprd1usgw1.carbonblack-us-gov.vmware.com']|defense.conferdeploy.net| + Example input: ``` @@ -35,7 +39,7 @@ Example input: "api_id": "ADFF2QLIIZ", "api_secret_key": "Z1PXFRDZI321LXQVAB9IJKKZ", "org_key": "1ABZY2FJ", - "url": "https://defense.conferdeploy.net" + "url": "defense.conferdeploy.net" } ``` @@ -43,55 +47,17 @@ Example input: ### Actions -#### Quarantine - -This action is used to quarantine an agent. - -##### Input - -|Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|agent|string|None|True|Agent to retrieve device information from. Accepts IP address, hostname, or device ID. Search results are case-sensitive|None|198.51.100.100| -|quarantine_state|boolean|True|True|Set to true to quarantine the agent, set to false to unquarantine an agent|None|True| -|whitelist|[]string|None|False|An array of IPs, hostnames, or device ID that a user can pass in that will not be quarantined|None|["198.51.100.100", "win-test"]| - -Example input: - -``` -{ - "agent": "198.51.100.100", - "quarantine_state": true, - "whitelist": [ - "198.51.100.100", - "win-test" - ] -} -``` - -##### Output - -|Name|Type|Required|Description| -|----|----|--------|-----------| -|quarantined|boolean|True|Is the agent quarantined| - -Example output: - -``` -{ - "quarantined": true -} -``` #### Get Agent Details - -This action is used to get Agent Details. + +This action is used to get agent details. ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | |agent|string|None|True|Agent to retrieve device information from. Accepts IP address, hostname, or device ID. Search results are case-sensitive|None|198.51.100.100| - + Example input: ``` @@ -102,55 +68,83 @@ Example input: ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|agent|agent|False|Details about the agent| - +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|agent|agent|False|Details about the agent|{"adGroupId":0,"policyOverride":false,"currentSensorPolicyName":null,"deviceMetaDataItemList":null,"lastDevicePolicyRequestedTime":null,"lastDevicePolicyChangedTime":null,"lastPolicyUpdatedTime":null,"loginUserName":null,"messages":null,"lastReportedTime":1591962280381,"uninstallCode":null,"organizationId":1105,"deviceId":3466056,"createTime":null,"deviceGuid":null,"email":"user@example.com","deviceSessionId":null,"deviceType":"WINDOWS","assignedToId":null,"assignedToName":null,"lastName":"User","firstName":"Test","middleName":null,"deviceOwnerId":12345,"activationCode":"1A2B3C","targetPriorityType":"HIGH","organizationName":"example.com","sensorVersion":"3.5.0.1680","activationCodeExpiryTime":1234567891011,"sensorKitType":null,"osVersion":"Server 2012 x64","registeredTime":1234567891011,"lastContact":1234567891011,"windowsPlatform":null,"vdiBaseDevice":null,"avStatus":["AV_ACTIVE","ONDEMAND_SCAN_DISABLED"],"deregisteredTime":null,"sensorStates":["ACTIVE","LIVE_RESPONSE_NOT_RUNNING","LIVE_RESPONSE_NOT_KILLED","LIVE_RESPONSE_ENABLED","SECURITY_CENTER_OPTLN_DISABLED"],"rootedBySensor":false,"rootedBySensorTime":null,"quarantined":false,"lastInternalIpAddress":"198.51.100.100","macAddress":"000000000000","lastExternalIpAddress":"198.51.100.100","lastLocation":"OFFSITE","sensorOutOfDate":false,"avUpdateServers":null,"passiveMode":false,"lastResetTime":0,"lastShutdownTime":0,"scanStatus":null,"scanLastActionTime":0,"scanLastCompleteTime":0,"linuxKernelVersion":null,"avEngine":"4.13.0.207-ave.8.3.60.40:avpack.8.5.0.60:vdf.8.18.2.56:apc.2.10.0.149","avProductVersion":"4.13.0.207","avAveVersion":"8.3.60.40","avPackVersion":"8.5.0.60","avVdfVersion":"8.18.2.56","avLastScanTime":0,"virtualMachine":false,"virtualizationProvider":"UNKNOWN","sensorPendingUpdate":false,"rootedByAnalytics":false,"rootedByAnalyticsTime":null,"avMaster":false,"firstVirusActivityTime":0,"lastVirusActivityTime":0,"testId":-1,"uninstalledTime":null,"encodedActivationCode":null,"originEventHash":null,"name":"example-host","status":"REGISTERED","policyId":12345,"policyName":"test"}| + Example output: ``` { "agent": { + "activationCode": "1A2B3C", + "activationCodeExpiryTime": 1234567891011, "adGroupId": 0, - "policyOverride": false, + "assignedToId": null, + "assignedToName": null, + "avAveVersion": "8.3.60.40", + "avEngine": "4.13.0.207-ave.8.3.60.40:avpack.8.5.0.60:vdf.8.18.2.56:apc.2.10.0.149", + "avLastScanTime": 0, + "avMaster": false, + "avPackVersion": "8.5.0.60", + "avProductVersion": "4.13.0.207", + "avStatus": [ + "AV_ACTIVE", + "ONDEMAND_SCAN_DISABLED" + ], + "avUpdateServers": null, + "avVdfVersion": "8.18.2.56", + "createTime": null, "currentSensorPolicyName": null, + "deregisteredTime": null, + "deviceGuid": null, + "deviceId": 3466056, "deviceMetaDataItemList": null, - "lastDevicePolicyRequestedTime": null, + "deviceOwnerId": 12345, + "deviceSessionId": null, + "deviceType": "WINDOWS", + "email": "user@example.com", + "encodedActivationCode": null, + "firstName": "Test", + "firstVirusActivityTime": 0, + "lastContact": 1234567891011, "lastDevicePolicyChangedTime": null, + "lastDevicePolicyRequestedTime": null, + "lastExternalIpAddress": "198.51.100.100", + "lastInternalIpAddress": "198.51.100.100", + "lastLocation": "OFFSITE", + "lastName": "User", "lastPolicyUpdatedTime": null, + "lastReportedTime": 1591962280381, + "lastResetTime": 0, + "lastShutdownTime": 0, + "lastVirusActivityTime": 0, + "linuxKernelVersion": null, "loginUserName": null, + "macAddress": "000000000000", "messages": null, - "lastReportedTime": 1591962280381, - "uninstallCode": null, - "organizationId": 1105, - "deviceId": 3466056, - "createTime": null, - "deviceGuid": null, - "email": "user@example.com", - "deviceSessionId": null, - "deviceType": "WINDOWS", - "assignedToId": null, - "assignedToName": null, - "lastName": "User", - "firstName": "Test", "middleName": null, - "deviceOwnerId": 12345, - "activationCode": "1A2B3C", - "targetPriorityType": "HIGH", + "name": "example-host", + "organizationId": 1105, "organizationName": "example.com", - "sensorVersion": "3.5.0.1680", - "activationCodeExpiryTime": 1234567891011, - "sensorKitType": null, + "originEventHash": null, "osVersion": "Server 2012 x64", + "passiveMode": false, + "policyId": 12345, + "policyName": "test", + "policyOverride": false, + "quarantined": false, "registeredTime": 1234567891011, - "lastContact": 1234567891011, - "windowsPlatform": null, - "vdiBaseDevice": null, - "avStatus": [ - "AV_ACTIVE", - "ONDEMAND_SCAN_DISABLED" - ], - "deregisteredTime": null, + "rootedByAnalytics": false, + "rootedByAnalyticsTime": null, + "rootedBySensor": false, + "rootedBySensorTime": null, + "scanLastActionTime": 0, + "scanLastCompleteTime": 0, + "scanStatus": null, + "sensorKitType": null, + "sensorOutOfDate": false, + "sensorPendingUpdate": false, "sensorStates": [ "ACTIVE", "LIVE_RESPONSE_NOT_RUNNING", @@ -158,68 +152,161 @@ Example output: "LIVE_RESPONSE_ENABLED", "SECURITY_CENTER_OPTLN_DISABLED" ], - "rootedBySensor": false, - "rootedBySensorTime": null, - "quarantined": false, - "lastInternalIpAddress": "198.51.100.100", - "macAddress": "000000000000", - "lastExternalIpAddress": "198.51.100.100", - "lastLocation": "OFFSITE", - "sensorOutOfDate": false, - "avUpdateServers": null, - "passiveMode": false, - "lastResetTime": 0, - "lastShutdownTime": 0, - "scanStatus": null, - "scanLastActionTime": 0, - "scanLastCompleteTime": 0, - "linuxKernelVersion": null, - "avEngine": "4.13.0.207-ave.8.3.60.40:avpack.8.5.0.60:vdf.8.18.2.56:apc.2.10.0.149", - "avProductVersion": "4.13.0.207", - "avAveVersion": "8.3.60.40", - "avPackVersion": "8.5.0.60", - "avVdfVersion": "8.18.2.56", - "avLastScanTime": 0, - "virtualMachine": false, - "virtualizationProvider": "UNKNOWN", - "sensorPendingUpdate": false, - "rootedByAnalytics": false, - "rootedByAnalyticsTime": null, - "avMaster": false, - "firstVirusActivityTime": 0, - "lastVirusActivityTime": 0, + "sensorVersion": "3.5.0.1680", + "status": "REGISTERED", + "targetPriorityType": "HIGH", "testId": -1, + "uninstallCode": null, "uninstalledTime": null, - "encodedActivationCode": null, - "originEventHash": null, - "name": "example-host", - "status": "REGISTERED", - "policyId": 12345, - "policyName": "test" + "vdiBaseDevice": null, + "virtualMachine": false, + "virtualizationProvider": "UNKNOWN", + "windowsPlatform": null } } ``` -### Triggers +#### Quarantine + +This action is used to quarantine an agent. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|agent|string|None|True|Agent to retrieve device information from. Accepts IP address, hostname, or device ID. Search results are case-sensitive|None|198.51.100.100| +|quarantine_state|boolean|True|True|Set to true to quarantine the agent, set to false to unquarantine an agent|None|True| +|whitelist|[]string|None|False|An array of IPs, hostnames, or device ID that a user can pass in that will not be quarantined|None|["198.51.100.100", "win-test"]| + +Example input: + +``` +{ + "agent": "198.51.100.100", + "quarantine_state": true, + "whitelist": "198.51.100.100" +} +``` -_This plugin does not contain any triggers._ +##### Output + +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|quarantined|boolean|True|Indicates whether or not the agent has been quarantined|True| + +Example output: -### Custom Output Types +``` +{ + "quarantined": true +} +``` +### Triggers + +*This plugin does not contain any triggers.* +### Tasks + +*This plugin does not contain any tasks.* + +### Custom Types + +**agent** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|Activation Code|string|None|False|Activation code|None| +|Activation Code Expiry Time|integer|None|False|Activation code expiry time|None| +|AD Group ID|integer|None|False|AD group ID|None| +|Assigned to ID|string|None|False|Assigned to ID|None| +|Assigned to Name|string|None|False|Assigned to name|None| +|AV AVE Version|string|None|False|AV AVE version|None| +|AV Engine|string|None|False|AV engine|None| +|AV Last Scan Time|integer|None|False|AV last scan time|None| +|AV Master|boolean|None|False|AV master|None| +|AV Pack Version|string|None|False|AV pack version|None| +|AV Product Version|string|None|False|AV product version|None| +|AV Status|[]string|None|False|AV status|None| +|AV Update Servers|string|None|False|AV update servers|None| +|AV VDF Version|string|None|False|AV VDF version|None| +|Create Time|string|None|False|Create time|None| +|Current Sensor Policy Name|string|None|False|Current sensor policy name|None| +|Deregistered Time|string|None|False|Deregistered time|None| +|Device GUID|string|None|False|Device GUID|None| +|Device ID|integer|None|False|Device ID|None| +|Device Meta Data Item List|string|None|False|Device meta data item list|None| +|Device Owner ID|integer|None|False|Device owner ID|None| +|Device Session ID|string|None|False|Device session ID|None| +|Device Type|string|None|False|Device type|None| +|Email|string|None|False|Email|None| +|Encoded Activation Code|string|None|False|Encoded activation code|None| +|First Name|string|None|False|First name|None| +|First Virus Activity Time|integer|None|False|First virus activity time|None| +|Last Contact|integer|None|False|Last contact|None| +|Last Device Policy Changed Time|string|None|False|Last device policy changed time|None| +|Last Device Policy Requested time|string|None|False|Last device policy requested time|None| +|Last External IP Address|string|None|False|Last external IP address|None| +|Last Internal IP Address|string|None|False|Last internal IP address|None| +|Last Location|string|None|False|Last location|None| +|Last Name|string|None|False|Last name|None| +|Last Policy Updated Time|string|None|False|Last policy updated time|None| +|Last Reported Time|integer|None|False|Last reported time|None| +|Last Reset Time|integer|None|False|Last reset time|None| +|Last Shutdown Time|integer|None|False|Last shutdown time|None| +|Last Virus Activity Time|integer|None|False|Last virus activity time|None| +|Linux Kernel Version|string|None|False|Linux kernel version|None| +|Login User Name|string|None|False|Login user name|None| +|MAC Address|string|None|False|MAC address|None| +|Messages|string|None|False|Messages|None| +|Middle Name|string|None|False|Middle name|None| +|Name|string|None|False|Name|None| +|Organization ID|integer|None|False|Organization ID|None| +|Organization Name|string|None|False|Organization name|None| +|Origin Event Hash|string|None|False|Origin event hash|None| +|OS Version|string|None|False|OS version|None| +|Passive Mode|boolean|None|False|Passive mode|None| +|Policy ID|integer|None|False|Policy ID|None| +|Policy Name|string|None|False|Policy name|None| +|Policy Override|boolean|None|False|Policy override|None| +|Quarantined|boolean|None|False|Quarantined|None| +|Registered Time|integer|None|False|Registered time|None| +|Rooted by Analytics|boolean|None|False|Rooted by analytics|None| +|Rooted by Analytics Time|string|None|False|Rooted by analytics time|None| +|Rooted by Sensor|boolean|None|False|Rooted by sensor|None| +|Rooted by Sensor Time|string|None|False|Rooted by sensor time|None| +|Scan Last Action Time|integer|None|False|Scan last action time|None| +|Scan Last Complete Time|integer|None|False|Scan last complete time|None| +|Scan Status|string|None|False|Scan status|None| +|Sensor Kit Type|string|None|False|Sensor kit type|None| +|Sensor Out of Date|boolean|None|False|Sensor out of date|None| +|Sensor Pending Update|boolean|None|False|Sensor pending update|None| +|Sensor States|[]string|None|False|Sensor states|None| +|Sensor Version|string|None|False|Sensor version|None| +|Status|string|None|False|Status|None| +|Target Priority Type|string|None|False|Target priority type|None| +|Test ID|integer|None|False|Test ID|None| +|Uninstall Code|string|None|False|Uninstall code|None| +|Uninstalled Time|string|None|False|Uninstalled time|None| +|VDI Base Device|string|None|False|VDI base device|None| +|Virtual Machine|boolean|None|False|Virtual machine|None| +|Virtualization Provider|string|None|False|Virtualization provider|None| +|Windows Platform|string|None|False|Windows platform|None| -_This plugin does not contain any custom output types._ ## Troubleshooting - -_This plugin does not contain any troubleshooting information._ + +*There is no troubleshooting for this plugin.* # Version History +* 2.0.0 - Updated the SDK version | Cloud enabled * 1.0.2 - Updated branding * 1.0.1 - Fix issue where retry on error call could crash plugin * 1.0.0 - Initial plugin # Links +* [Carbon Black Cloud](https://www.carbonblack.com/products/vmware-carbon-black-cloud) + ## References * [Carbon Black Cloud](https://www.carbonblack.com/products/vmware-carbon-black-cloud) diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/__init__.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/__init__.py index 55aabec6f8..caf0cc7f64 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/__init__.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/__init__.py @@ -1,3 +1,6 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT + from .get_agent_details.action import GetAgentDetails + from .quarantine.action import Quarantine + diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/__init__.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/__init__.py index 5c8ec82e32..7d0e20b5d2 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/__init__.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import GetAgentDetails diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/action.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/action.py index 2179ea3463..ddc7fecced 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/action.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/action.py @@ -14,8 +14,6 @@ def __init__(self): ) def run(self, params={}): - agent = params[Input.AGENT] - + agent = params.get(Input.AGENT, "") device = self.connection.get_agent(agent) - return {Output.AGENT: insightconnect_plugin_runtime.helper.clean(device)} diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/schema.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/schema.py index 6bd4575f0c..3f31499744 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/schema.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/get_agent_details/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -9,14 +9,14 @@ class Component: class Input: AGENT = "agent" - + class Output: AGENT = "agent" - + class GetAgentDetailsInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -30,7 +30,8 @@ class GetAgentDetailsInput(insightconnect_plugin_runtime.Input): }, "required": [ "agent" - ] + ], + "definitions": {} } """) @@ -39,7 +40,7 @@ def __init__(self): class GetAgentDetailsOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -182,7 +183,7 @@ class GetAgentDetailsOutput(insightconnect_plugin_runtime.Output): "deviceOwnerId": { "type": "integer", "title": "Device Owner ID", - "description": "Device owner id", + "description": "Device owner ID", "order": 21 }, "deviceSessionId": { diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/__init__.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/__init__.py index ba8405fae2..a06654ea63 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/__init__.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import Quarantine diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/action.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/action.py index 53ec93e8e3..f4fe662932 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/action.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/action.py @@ -2,7 +2,7 @@ from .schema import QuarantineInput, QuarantineOutput, Input, Output, Component # Custom imports below -import icon_carbon_black_cloud.util.whitelist_checker as whitelist_checker +from icon_carbon_black_cloud.util import whitelist_checker class Quarantine(insightconnect_plugin_runtime.Action): @@ -15,8 +15,8 @@ def __init__(self): ) def run(self, params={}): - agent = params.get(Input.AGENT) - whitelist = params.get(Input.WHITELIST) + agent = params.get(Input.AGENT, "") + whitelist = params.get(Input.WHITELIST, []) quarantine_state = params.get(Input.QUARANTINE_STATE) if quarantine_state and whitelist_checker.match_whitelist(agent, whitelist, self.logger): diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/schema.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/schema.py index 3b96f4d956..92946909e7 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/schema.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/actions/quarantine/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -11,14 +11,14 @@ class Input: AGENT = "agent" QUARANTINE_STATE = "quarantine_state" WHITELIST = "whitelist" - + class Output: QUARANTINED = "quarantined" - + class QuarantineInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -49,7 +49,8 @@ class QuarantineInput(insightconnect_plugin_runtime.Input): "required": [ "agent", "quarantine_state" - ] + ], + "definitions": {} } """) @@ -58,7 +59,7 @@ def __init__(self): class QuarantineOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -66,13 +67,14 @@ class QuarantineOutput(insightconnect_plugin_runtime.Output): "quarantined": { "type": "boolean", "title": "Quarantined", - "description": "Is the agent quarantined", + "description": "Indicates whether or not the agent has been quarantined", "order": 1 } }, "required": [ "quarantined" - ] + ], + "definitions": {} } """) diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/__init__.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/__init__.py index a515dcf6b0..c78d3356be 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/__init__.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .connection import Connection diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/connection.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/connection.py index 7ca089d345..3222a3c4d4 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/connection.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/connection.py @@ -5,8 +5,8 @@ import requests from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException import time -import icon_carbon_black_cloud.util.agent_typer as agent_typer -import urllib.parse +from icon_carbon_black_cloud.util import agent_typer +from icon_carbon_black_cloud.util.constants import DEFAULT_TIMEOUT class Connection(insightconnect_plugin_runtime.Connection): @@ -14,15 +14,10 @@ def __init__(self): super(self.__class__, self).__init__(input=ConnectionSchema()) def connect(self, params): - self.api_id = params.get(Input.API_ID) - self.api_secret = params.get(Input.API_SECRET_KEY).get("secretKey") - - base_url = params.get(Input.URL) - self.base_url = urllib.parse.urlparse(base_url).hostname - self.base_url = f"https://{self.base_url}" - - self.org_key = params.get(Input.ORG_KEY) - + self.api_id = params.get(Input.API_ID, "") + self.api_secret = params.get(Input.API_SECRET_KEY, {}).get("secretKey", "") + self.org_key = params.get(Input.ORG_KEY, "") + self.base_url = f"https://{params.get(Input.URL, '')}" self.x_auth_token = f"{self.api_secret}/{self.api_id}" self.headers = {"X-Auth-Token": self.x_auth_token} @@ -38,28 +33,32 @@ def get_agent(self, agent): device = None if agent_type == agent_typer.DEVICE_ID: - device = next((x for x in results if str(x.get("id", "")) == agent), None) + device = next((element for element in results if str(element.get("id", "")) == agent), None) if agent_type == agent_typer.IP_ADDRESS: device = next( - (x for x in results if x.get("last_internal_ip_address") == agent or x.get("last_external_ip_address")), + ( + element + for element in results + if element.get("last_internal_ip_address") == agent or element.get("last_external_ip_address") + ), None, ) if agent_type == agent_typer.HOSTNAME: - device = next((x for x in results if x.get("name", "") == agent), None) + device = next((element for element in results if element.get("name", "") == agent), None) if agent_typer == agent_typer.MAC_ADDRESS: - device = next((x for x in results if x.get("mac_address", "") == agent), None) + device = next((element for element in results if element.get("mac_address", "") == agent), None) if not device: self.logger.error(f"Could not find any device that matched {agent}") return device - def post_to_api(self, url, payload, retry=True): - result = requests.post(url, headers=self.headers, json=payload) + def post_to_api(self, url, payload, retry=True): # noqa: MC0001 + result = requests.post(url, headers=self.headers, json=payload, timeout=DEFAULT_TIMEOUT) try: result.raise_for_status() - except Exception as e: + except Exception as error: if result.status_code == 400: raise PluginException( cause="400 Bad Request", @@ -96,9 +95,9 @@ def post_to_api(self, url, payload, retry=True): return self.post_to_api(url, payload, False) self.logger.error("Retry on 503 failed.") - self.logger.error(str(e)) + self.logger.error(str(error)) self.logger.error(result.text) - raise PluginException(PluginException.Preset.UNKNOWN) + raise PluginException(preset=PluginException.Preset.UNKNOWN) if result.status_code != 204: return result.json() @@ -110,14 +109,13 @@ def test(self): endpoint = self.base_url + device_endpoint self.logger.info(endpoint) - result = requests.get(endpoint, headers=self.headers) + result = requests.get(endpoint, headers=self.headers, timeout=DEFAULT_TIMEOUT) try: result.raise_for_status() - except Exception as e: + except Exception as error: raise ConnectionTestException( cause="Connection test to Carbon Black Cloud failed.\n", assistance=f"{result.text}\n", - data=str(e), + data=str(error), ) - return {"success": True} diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/schema.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/schema.py index 75401f5939..e070a07c48 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/schema.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/connection/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -8,10 +8,10 @@ class Input: API_SECRET_KEY = "api_secret_key" ORG_KEY = "org_key" URL = "url" - + class ConnectionSchema(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -37,8 +37,19 @@ class ConnectionSchema(insightconnect_plugin_runtime.Input): "url": { "type": "string", "title": "URL", - "description": "API URL", - "default": "https://defense.conferdeploy.net", + "description": "The Carbon Black Cloud URL you use. You can find this by looking at the web address of your Carbon Black Cloud console", + "default": "defense.conferdeploy.net", + "enum": [ + "defense-eap01.conferdeploy.net", + "dashboard.confer.net", + "defense.conferdeploy.net", + "defense-prod05.conferdeploy.net", + "defense-eu.conferdeploy.net", + "defense-prodnrt.conferdeploy.net", + "defense-prodsyd.conferdeploy.net", + "ew2.carbonblackcloud.vmware.com", + "gprd1usgw1.carbonblack-us-gov.vmware.com" + ], "order": 4 } }, @@ -54,18 +65,18 @@ class ConnectionSchema(insightconnect_plugin_runtime.Input): "type": "object", "title": "Credential: Secret Key", "description": "A shared secret key", + "required": [ + "secretKey" + ], "properties": { "secretKey": { "type": "string", "title": "Secret Key", - "displayType": "password", "description": "The shared secret key", - "format": "password" + "format": "password", + "displayType": "password" } - }, - "required": [ - "secretKey" - ] + } } } } diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/tasks/__init__.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/tasks/__init__.py new file mode 100644 index 0000000000..7020c9a4ad --- /dev/null +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/tasks/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT + diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/triggers/__init__.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/triggers/__init__.py index bace8db897..7020c9a4ad 100755 --- a/plugins/carbon_black_cloud/icon_carbon_black_cloud/triggers/__init__.py +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/triggers/__init__.py @@ -1 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT + diff --git a/plugins/carbon_black_cloud/icon_carbon_black_cloud/util/constants.py b/plugins/carbon_black_cloud/icon_carbon_black_cloud/util/constants.py new file mode 100644 index 0000000000..f6c9f18a70 --- /dev/null +++ b/plugins/carbon_black_cloud/icon_carbon_black_cloud/util/constants.py @@ -0,0 +1 @@ +DEFAULT_TIMEOUT = 10 diff --git a/plugins/carbon_black_cloud/plugin.spec.yaml b/plugins/carbon_black_cloud/plugin.spec.yaml index c1d635a52a..4b3ffaf499 100644 --- a/plugins/carbon_black_cloud/plugin.spec.yaml +++ b/plugins/carbon_black_cloud/plugin.spec.yaml @@ -4,9 +4,12 @@ products: [insightconnect] name: carbon_black_cloud title: VMware Carbon Black Cloud description: Quarantine endpoints and get device details with the VMware Carbon Black Cloud plugin -version: 1.0.2 +version: 2.0.0 vendor: rapid7 support: rapid7 +cloud_ready: true +connection_version: 2 +supported_versions: ["2023-09-19"] status: [] resources: source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/carbon_black_cloud @@ -20,420 +23,432 @@ tags: - vmware hub_tags: use_cases: [threat_detection_and_response] - keywords: [carbon black, vmware, cloud, antivirus] + keywords: [carbon black, vmware, cloud, antivirus, cloud_enabled] features: [] - +sdk: + type: full + version: 5 + user: nobody types: agent: activationCode: - title: "Activation Code" + title: Activation Code + description: Activation code type: string - description: "Activation code" required: false activationCodeExpiryTime: - title: "Activation Code Expiry Time" + title: Activation Code Expiry Time + description: Activation code expiry time type: integer - description: "Activation code expiry time" required: false adGroupId: - title: "AD Group ID" + title: AD Group ID + description: AD group ID type: integer - description: "AD group ID" required: false assignedToId: - title: "Assigned to ID" + title: Assigned to ID + description: Assigned to ID type: string - description: "Assigned to ID" required: false assignedToName: - title: "Assigned to Name" + title: Assigned to Name + description: Assigned to name type: string - description: "Assigned to name" required: false avAveVersion: - title: "AV AVE Version" + title: AV AVE Version + description: AV AVE version type: string - description: "AV AVE version" required: false avEngine: - title: "AV Engine" + title: AV Engine + description: AV engine type: string - description: "AV engine" required: false avLastScanTime: - title: "AV Last Scan Time" + title: AV Last Scan Time + description: AV last scan time type: integer - description: "AV last scan time" required: false avMaster: - title: "AV Master" + title: AV Master + description: AV master type: boolean - description: "AV master" required: false avPackVersion: - title: "AV Pack Version" + title: AV Pack Version + description: AV pack version type: string - description: "AV pack version" required: false avProductVersion: - title: "AV Product Version" + title: AV Product Version + description: AV product version type: string - description: "AV product version" required: false avStatus: - title: "AV Status" + title: AV Status + description: AV status type: "[]string" - description: "AV status" required: false avUpdateServers: - title: "AV Update Servers" + title: AV Update Servers + description: AV update servers type: string - description: "AV update servers" required: false avVdfVersion: - title: "AV VDF Version" + title: AV VDF Version + description: AV VDF version type: string - description: "AV VDF version" required: false createTime: - title: "Create Time" + title: Create Time + description: Create time type: string - description: "Create time" required: false currentSensorPolicyName: - title: "Current Sensor Policy Name" + title: Current Sensor Policy Name + description: Current sensor policy name type: string - description: "Current sensor policy name" required: false deregisteredTime: - title: "Deregistered Time" + title: Deregistered Time + description: Deregistered time type: string - description: "Deregistered time" required: false deviceGuid: - title: "Device GUID" + title: Device GUID + description: Device GUID type: string - description: "Device GUID" required: false deviceId: - title: "Device ID" + title: Device ID + description: Device ID type: integer - description: "Device ID" required: false deviceMetaDataItemList: - title: "Device Meta Data Item List" + title: Device Meta Data Item List + description: Device meta data item list type: string - description: "Device meta data item list" required: false deviceOwnerId: - title: "Device Owner ID" + title: Device Owner ID + description: Device owner ID type: integer - description: "Device owner id" required: false deviceSessionId: - title: "Device Session ID" + title: Device Session ID + description: Device session ID type: string - description: "Device session ID" required: false deviceType: - title: "Device Type" + title: Device Type + description: Device type type: string - description: "Device type" required: false email: - title: "Email" + title: Email + description: Email type: string - description: "Email" required: false encodedActivationCode: - title: "Encoded Activation Code" + title: Encoded Activation Code + description: Encoded activation code type: string - description: "Encoded activation code" required: false firstName: - title: "First Name" + title: First Name + description: First name type: string - description: "First name" required: false firstVirusActivityTime: - title: "First Virus Activity Time" + title: First Virus Activity Time + description: First virus activity time type: integer - description: "First virus activity time" required: false lastContact: - title: "Last Contact" + title: Last Contact + description: Last contact type: integer - description: "Last contact" required: false lastDevicePolicyChangedTime: - title: "Last Device Policy Changed Time" + title: Last Device Policy Changed Time + description: Last device policy changed time type: string - description: "Last device policy changed time" required: false lastDevicePolicyRequestedTime: - title: "Last Device Policy Requested time" + title: Last Device Policy Requested time + description: Last device policy requested time type: string - description: "Last device policy requested time" required: false lastExternalIpAddress: - title: "Last External IP Address" + title: Last External IP Address + description: Last external IP address type: string - description: "Last external IP address" required: false lastInternalIpAddress: - title: "Last Internal IP Address" + title: Last Internal IP Address + description: Last internal IP address type: string - description: "Last internal IP address" required: false lastLocation: - title: "Last Location" + title: Last Location + description: Last location type: string - description: "Last location" required: false lastName: - title: "Last Name" + title: Last Name + description: Last name type: string - description: "Last name" required: false lastPolicyUpdatedTime: - title: "Last Policy Updated Time" + title: Last Policy Updated Time + description: Last policy updated time type: string - description: "Last policy updated time" required: false lastReportedTime: - title: "Last Reported Time" + title: Last Reported Time + description: Last reported time type: integer - description: "Last reported time" required: false lastResetTime: - title: "Last Reset Time" + title: Last Reset Time + description: Last reset time type: integer - description: "Last reset time" required: false lastShutdownTime: - title: "Last Shutdown Time" + title: Last Shutdown Time + description: Last shutdown time type: integer - description: "Last shutdown time" required: false lastVirusActivityTime: - title: "Last Virus Activity Time" + title: Last Virus Activity Time + description: Last virus activity time type: integer - description: "Last virus activity time" required: false linuxKernelVersion: - title: "Linux Kernel Version" + title: Linux Kernel Version + description: Linux kernel version type: string - description: "Linux kernel version" required: false loginUserName: - title: "Login User Name" + title: Login User Name + description: Login user name type: string - description: "Login user name" required: false macAddress: - title: "MAC Address" + title: MAC Address + description: MAC address type: string - description: "MAC address" required: false messages: - title: "Messages" + title: Messages + description: Messages type: string - description: "Messages" required: false middleName: - title: "Middle Name" + title: Middle Name + description: Middle name type: string - description: "Middle name" required: false name: - title: "Name" + title: Name + description: Name type: string - description: "Name" required: false organizationId: - title: "Organization ID" + title: Organization ID + description: Organization ID type: integer - description: "Organization ID" required: false organizationName: - title: "Organization Name" + title: Organization Name + description: Organization name type: string - description: "Organization name" required: false originEventHash: - title: "Origin Event Hash" + title: Origin Event Hash + description: Origin event hash type: string - description: "Origin event hash" required: false osVersion: - title: "OS Version" + title: OS Version + description: OS version type: string - description: "OS version" required: false passiveMode: - title: "Passive Mode" + title: Passive Mode + description: Passive mode type: boolean - description: "Passive mode" required: false policyId: - title: "Policy ID" + title: Policy ID + description: Policy ID type: integer - description: "Policy ID" required: false policyName: - title: "Policy Name" + title: Policy Name + description: Policy name type: string - description: "Policy name" required: false policyOverride: - title: "Policy Override" + title: Policy Override + description: Policy override type: boolean - description: "Policy override" required: false quarantined: - title: "Quarantined" + title: Quarantined + description: Quarantined type: boolean - description: "Quarantined" required: false registeredTime: - title: "Registered Time" + title: Registered Time + description: Registered time type: integer - description: "Registered time" required: false rootedByAnalytics: - title: "Rooted by Analytics" + title: Rooted by Analytics + description: Rooted by analytics type: boolean - description: "Rooted by analytics" required: false rootedByAnalyticsTime: - title: "Rooted by Analytics Time" + title: Rooted by Analytics Time + description: Rooted by analytics time type: string - description: "Rooted by analytics time" required: false rootedBySensor: - title: "Rooted by Sensor" + title: Rooted by Sensor + description: Rooted by sensor type: boolean - description: "Rooted by sensor" required: false rootedBySensorTime: - title: "Rooted by Sensor Time" + title: Rooted by Sensor Time + description: Rooted by sensor time type: string - description: "Rooted by sensor time" required: false scanLastActionTime: - title: "Scan Last Action Time" + title: Scan Last Action Time + description: Scan last action time type: integer - description: "Scan last action time" required: false scanLastCompleteTime: - title: "Scan Last Complete Time" + title: Scan Last Complete Time + description: Scan last complete time type: integer - description: "Scan last complete time" required: false scanStatus: - title: "Scan Status" + title: Scan Status + description: Scan status type: string - description: "Scan status" required: false sensorKitType: - title: "Sensor Kit Type" + title: Sensor Kit Type + description: Sensor kit type type: string - description: "Sensor kit type" required: false sensorOutOfDate: - title: "Sensor Out of Date" + title: Sensor Out of Date + description: Sensor out of date type: boolean - description: "Sensor out of date" required: false sensorPendingUpdate: - title: "Sensor Pending Update" + title: Sensor Pending Update + description: Sensor pending update type: boolean - description: "Sensor pending update" required: false sensorStates: - title: "Sensor States" + title: Sensor States + description: Sensor states type: "[]string" - description: "Sensor states" required: false sensorVersion: - title: "Sensor Version" + title: Sensor Version + description: Sensor version type: string - description: "Sensor version" required: false status: - title: "Status" + title: Status + description: Status type: string - description: "Status" required: false targetPriorityType: - title: "Target Priority Type" + title: Target Priority Type + description: Target priority type type: string - description: "Target priority type" required: false testId: - title: "Test ID" + title: Test ID + description: Test ID type: integer - description: "Test ID" required: false uninstallCode: - title: "Uninstall Code" + title: Uninstall Code + description: Uninstall code type: string - description: "Uninstall code" required: false uninstalledTime: - title: "Uninstalled Time" + title: Uninstalled Time + description: Uninstalled time type: string - description: "Uninstalled time" required: false vdiBaseDevice: - title: "VDI Base Device" + title: VDI Base Device + description: VDI base device type: string - description: "VDI base device" required: false virtualMachine: - title: "Virtual Machine" + title: Virtual Machine + description: Virtual machine type: boolean - description: "Virtual machine" required: false virtualizationProvider: - title: "Virtualization Provider" + title: Virtualization Provider + description: Virtualization provider type: string - description: "Virtualization provider" required: false windowsPlatform: - title: "Windows Platform" + title: Windows Platform + description: Windows platform type: string - description: "Windows platform" required: false - connection: api_id: title: API ID - type: string description: API ID + type: string example: ADFF2QLIIZ required: true order: 1 api_secret_key: title: API Secret Key - type: credential_secret_key description: API secret key + type: credential_secret_key example: Z1PXFRDZI321LXQVAB9IJKKZ required: true order: 2 org_key: title: Org Key - type: string description: Organization Key + type: string example: 1ABZY2FJ required: true order: 3 url: title: URL + description: The Carbon Black Cloud URL you use. You can find this by looking at the web address of your Carbon Black Cloud console type: string - description: API URL - default: https://defense.conferdeploy.net - example: https://defense.conferdeploy.net + enum: + - defense-eap01.conferdeploy.net + - dashboard.confer.net + - defense.conferdeploy.net + - defense-prod05.conferdeploy.net + - defense-eu.conferdeploy.net + - defense-prodnrt.conferdeploy.net + - defense-prodsyd.conferdeploy.net + - ew2.carbonblackcloud.vmware.com + - gprd1usgw1.carbonblack-us-gov.vmware.com + example: defense.conferdeploy.net + default: defense.conferdeploy.net required: true order: 4 actions: @@ -453,6 +468,7 @@ actions: description: Details about the agent type: agent required: false + example: '{"adGroupId":0,"policyOverride":false,"currentSensorPolicyName":null,"deviceMetaDataItemList":null,"lastDevicePolicyRequestedTime":null,"lastDevicePolicyChangedTime":null,"lastPolicyUpdatedTime":null,"loginUserName":null,"messages":null,"lastReportedTime":1591962280381,"uninstallCode":null,"organizationId":1105,"deviceId":3466056,"createTime":null,"deviceGuid":null,"email":"user@example.com","deviceSessionId":null,"deviceType":"WINDOWS","assignedToId":null,"assignedToName":null,"lastName":"User","firstName":"Test","middleName":null,"deviceOwnerId":12345,"activationCode":"1A2B3C","targetPriorityType":"HIGH","organizationName":"example.com","sensorVersion":"3.5.0.1680","activationCodeExpiryTime":1234567891011,"sensorKitType":null,"osVersion":"Server 2012 x64","registeredTime":1234567891011,"lastContact":1234567891011,"windowsPlatform":null,"vdiBaseDevice":null,"avStatus":["AV_ACTIVE","ONDEMAND_SCAN_DISABLED"],"deregisteredTime":null,"sensorStates":["ACTIVE","LIVE_RESPONSE_NOT_RUNNING","LIVE_RESPONSE_NOT_KILLED","LIVE_RESPONSE_ENABLED","SECURITY_CENTER_OPTLN_DISABLED"],"rootedBySensor":false,"rootedBySensorTime":null,"quarantined":false,"lastInternalIpAddress":"198.51.100.100","macAddress":"000000000000","lastExternalIpAddress":"198.51.100.100","lastLocation":"OFFSITE","sensorOutOfDate":false,"avUpdateServers":null,"passiveMode":false,"lastResetTime":0,"lastShutdownTime":0,"scanStatus":null,"scanLastActionTime":0,"scanLastCompleteTime":0,"linuxKernelVersion":null,"avEngine":"4.13.0.207-ave.8.3.60.40:avpack.8.5.0.60:vdf.8.18.2.56:apc.2.10.0.149","avProductVersion":"4.13.0.207","avAveVersion":"8.3.60.40","avPackVersion":"8.5.0.60","avVdfVersion":"8.18.2.56","avLastScanTime":0,"virtualMachine":false,"virtualizationProvider":"UNKNOWN","sensorPendingUpdate":false,"rootedByAnalytics":false,"rootedByAnalyticsTime":null,"avMaster":false,"firstVirusActivityTime":0,"lastVirusActivityTime":0,"testId":-1,"uninstalledTime":null,"encodedActivationCode":null,"originEventHash":null,"name":"example-host","status":"REGISTERED","policyId":12345,"policyName":"test"}' quarantine: title: Quarantine description: Quarantine an agent @@ -482,7 +498,7 @@ actions: output: quarantined: title: Quarantined - description: Is the agent quarantined + description: Indicates whether or not the agent has been quarantined type: boolean required: true - + example: true diff --git a/plugins/carbon_black_cloud/requirements.txt b/plugins/carbon_black_cloud/requirements.txt index d0674c75e2..d8f5e66f7e 100755 --- a/plugins/carbon_black_cloud/requirements.txt +++ b/plugins/carbon_black_cloud/requirements.txt @@ -1,3 +1,4 @@ # List third-party dependencies here, separated by newlines. # All dependencies must be version-pinned, eg. requests==1.2.0 -# See: https://pip.pypa.io/en/stable/user_guide/#requirements-files \ No newline at end of file +# See: https://pip.pypa.io/en/stable/user_guide/#requirements-files +parameterized==0.9.0 diff --git a/plugins/carbon_black_cloud/setup.py b/plugins/carbon_black_cloud/setup.py index 70c761caa2..388ae0ae50 100755 --- a/plugins/carbon_black_cloud/setup.py +++ b/plugins/carbon_black_cloud/setup.py @@ -1,9 +1,9 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from setuptools import setup, find_packages setup(name="carbon_black_cloud-rapid7-plugin", - version="1.0.2", + version="2.0.0", description="Quarantine endpoints and get device details with the VMware Carbon Black Cloud plugin", author="rapid7", author_email="", diff --git a/plugins/carbon_black_cloud/unit_test/__init__.py b/plugins/carbon_black_cloud/unit_test/__init__.py new file mode 100644 index 0000000000..797e426edf --- /dev/null +++ b/plugins/carbon_black_cloud/unit_test/__init__.py @@ -0,0 +1 @@ +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT diff --git a/plugins/carbon_black_cloud/unit_test/responses/get_agent_details.json.resp b/plugins/carbon_black_cloud/unit_test/responses/get_agent_details.json.resp new file mode 100644 index 0000000000..cf2f2a3c28 --- /dev/null +++ b/plugins/carbon_black_cloud/unit_test/responses/get_agent_details.json.resp @@ -0,0 +1,113 @@ +{ + "results": [ + { + "activation_code": null, + "activation_code_expiry_time": "2022-07-11T06:53:06.190Z", + "ad_group_id": 0, + "appliance_name": null, + "appliance_uuid": null, + "auto_scaling_group_name": null, + "av_ave_version": "8.3.64.172", + "av_engine": "4.15.1.560-ave.8.3.64.172:avpack.8.5.2.64:vdf.8.19.20.4:vdfdate.20220711", + "av_last_scan_time": null, + "av_master": false, + "av_pack_version": "8.5.2.64", + "av_product_version": "4.15.1.560", + "av_status": [ + "AV_ACTIVE", + "ONDEMAND_SCAN_DISABLED" + ], + "av_update_servers": null, + "av_vdf_version": "8.19.20.4", + "base_device": null, + "cloud_provider_account_id": null, + "cloud_provider_resource_id": null, + "cloud_provider_tags": null, + "cluster_name": null, + "current_sensor_policy_name": "CB-policy", + "datacenter_name": null, + "deployment_type": "ENDPOINT", + "deregistered_time": null, + "device_meta_data_item_list": [ + { + "key_name": "OS_MAJOR_VERSION", + "key_value": "Windows 10", + "position": 0 + }, + { + "key_name": "SUBNET", + "key_value": "198.18.127", + "position": 0 + } + ], + "device_owner_id": 854220, + "email": "vagrant", + "esx_host_name": null, + "esx_host_uuid": null, + "first_name": null, + "golden_device": null, + "golden_device_id": null, + "host_based_firewall_failure_reason": null, + "host_based_firewall_status": null, + "id": 5765373, + "last_contact_time": "2022-07-11T22:04:42.993Z", + "last_device_policy_changed_time": "2022-07-04T13:22:15.870Z", + "last_device_policy_requested_time": "2022-07-04T13:46:25.278Z", + "last_external_ip_address": "162.111.555.333", + "last_internal_ip_address": "198.18.127.111", + "last_location": "OFFSITE", + "last_name": null, + "last_policy_updated_time": "2022-05-18T09:33:54.616Z", + "last_reported_time": "2022-07-11T22:04:43.063Z", + "last_reset_time": null, + "last_shutdown_time": "2022-07-04T06:58:55.867Z", + "linux_kernel_version": null, + "login_user_name": "CARBONBLACK\\testuser", + "mac_address": "fa163e92d344", + "middle_name": null, + "name": "carbonblack", + "nsx_distributed_firewall_policy": null, + "nsx_enabled": null, + "organization_id": 1105, + "organization_name": "cb-internal-alliances.com", + "os": "WINDOWS", + "os_version": "Windows 10 x64", + "passive_mode": false, + "policy_id": 87816, + "policy_name": "CB-policy", + "policy_override": true, + "quarantined": false, + "registered_time": "2022-07-04T06:53:06.220Z", + "scan_last_action_time": null, + "scan_last_complete_time": null, + "scan_status": null, + "sensor_kit_type": "WINDOWS", + "sensor_out_of_date": false, + "sensor_pending_update": false, + "sensor_states": [ + "ACTIVE", + "LIVE_RESPONSE_NOT_RUNNING", + "LIVE_RESPONSE_NOT_KILLED", + "LIVE_RESPONSE_ENABLED" + ], + "sensor_version": "3.8.0.627", + "status": "REGISTERED", + "target_priority": "MEDIUM", + "uninstall_code": "R6VERVN2", + "vcenter_host_url": null, + "vcenter_name": null, + "vcenter_uuid": null, + "vdi_base_device": null, + "virtual_machine": false, + "virtual_private_cloud_id": null, + "virtualization_provider": "OTHER", + "vm_ip": null, + "vm_name": null, + "vm_uuid": null, + "vulnerability_score": 0.0, + "vulnerability_severity": null, + "windows_platform": null + } + ], + "num_found": 1 +} diff --git a/plugins/carbon_black_cloud/unit_test/responses/quarantine.json.resp b/plugins/carbon_black_cloud/unit_test/responses/quarantine.json.resp new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/carbon_black_cloud/unit_test/responses/quarantine.json.resp @@ -0,0 +1 @@ +{} diff --git a/plugins/carbon_black_cloud/unit_test/test_agent_type.py b/plugins/carbon_black_cloud/unit_test/test_agent_type.py index 536c1b97fd..3c378f9a3b 100644 --- a/plugins/carbon_black_cloud/unit_test/test_agent_type.py +++ b/plugins/carbon_black_cloud/unit_test/test_agent_type.py @@ -1,4 +1,10 @@ +import os +import sys + +sys.path.append(os.path.abspath("../")) + from unittest import TestCase + import icon_carbon_black_cloud.util.agent_typer as agent_typer diff --git a/plugins/carbon_black_cloud/unit_test/test_get_agent_details.py b/plugins/carbon_black_cloud/unit_test/test_get_agent_details.py index 3dc6e2867d..2a8370935a 100644 --- a/plugins/carbon_black_cloud/unit_test/test_get_agent_details.py +++ b/plugins/carbon_black_cloud/unit_test/test_get_agent_details.py @@ -1,40 +1,119 @@ -import sys import os +import sys sys.path.append(os.path.abspath("../")) from unittest import TestCase -from icon_carbon_black_cloud.connection.connection import Connection +from unittest.mock import MagicMock, patch + from icon_carbon_black_cloud.actions.get_agent_details import GetAgentDetails -import json -import logging +from icon_carbon_black_cloud.actions.get_agent_details.schema import GetAgentDetailsOutput, Input, Output +from insightconnect_plugin_runtime.exceptions import PluginException +from jsonschema import validate +from parameterized import parameterized + +from util import ( + Util, + mock_request_200, + mock_request_400, + mock_request_401, + mock_request_403, + mock_request_404, + mock_request_409, + mock_request_503, + mocked_request, +) + +STUB_AGENT_ID = "192.168.0.1" class TestGetAgentDetails(TestCase): - def test_integration_get_agent_details(self): - log = logging.getLogger("Test") - test_conn = Connection() - test_action = GetAgentDetails() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/get_agent_details.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - self.assertIsNotNone(results.get("agent")) + def setUp(self) -> None: + self.action = Util.default_connector(GetAgentDetails()) + self.payload = {Input.AGENT: STUB_AGENT_ID} + + @patch("requests.post", side_effect=mock_request_200) + def test_get_agent_details(self, mocked_post: MagicMock) -> None: + response = self.action.run(self.payload) + expected = { + Output.AGENT: { + "activation_code_expiry_time": "2022-07-11T06:53:06.190Z", + "ad_group_id": 0, + "av_ave_version": "8.3.64.172", + "av_engine": "4.15.1.560-ave.8.3.64.172:avpack.8.5.2.64:vdf.8.19.20.4:vdfdate.20220711", + "av_master": False, + "av_pack_version": "8.5.2.64", + "av_product_version": "4.15.1.560", + "av_status": ["AV_ACTIVE", "ONDEMAND_SCAN_DISABLED"], + "av_vdf_version": "8.19.20.4", + "current_sensor_policy_name": "CB-policy", + "deployment_type": "ENDPOINT", + "device_meta_data_item_list": [ + {"key_name": "OS_MAJOR_VERSION", "key_value": "Windows 10", "position": 0}, + {"key_name": "SUBNET", "key_value": "198.18.127", "position": 0}, + ], + "device_owner_id": 854220, + "email": "vagrant", + "id": 5765373, + "last_contact_time": "2022-07-11T22:04:42.993Z", + "last_device_policy_changed_time": "2022-07-04T13:22:15.870Z", + "last_device_policy_requested_time": "2022-07-04T13:46:25.278Z", + "last_external_ip_address": "162.111.555.333", + "last_internal_ip_address": "198.18.127.111", + "last_location": "OFFSITE", + "last_policy_updated_time": "2022-05-18T09:33:54.616Z", + "last_reported_time": "2022-07-11T22:04:43.063Z", + "last_shutdown_time": "2022-07-04T06:58:55.867Z", + "login_user_name": "CARBONBLACK\\testuser", + "mac_address": "fa163e92d344", + "name": "carbonblack", + "organization_id": 1105, + "organization_name": "cb-internal-alliances.com", + "os": "WINDOWS", + "os_version": "Windows 10 x64", + "passive_mode": False, + "policy_id": 87816, + "policy_name": "CB-policy", + "policy_override": True, + "quarantined": False, + "registered_time": "2022-07-04T06:53:06.220Z", + "sensor_kit_type": "WINDOWS", + "sensor_out_of_date": False, + "sensor_pending_update": False, + "sensor_states": [ + "ACTIVE", + "LIVE_RESPONSE_NOT_RUNNING", + "LIVE_RESPONSE_NOT_KILLED", + "LIVE_RESPONSE_ENABLED", + ], + "sensor_version": "3.8.0.627", + "status": "REGISTERED", + "target_priority": "MEDIUM", + "uninstall_code": "R6VERVN2", + "virtual_machine": False, + "virtualization_provider": "OTHER", + "vulnerability_score": 0.0, + } + } + validate(response, GetAgentDetailsOutput.schema) + self.assertEqual(response, expected) + mocked_post.assert_called_once() + + @parameterized.expand( + [ + (mock_request_400, "400 Bad Request"), + (mock_request_401, "Authentication Error"), + (mock_request_403, "The specified object cannot be accessed or changed."), + (mock_request_404, "The object referenced in the request cannot be found."), + (mock_request_409, "Either the name you chose already exists, or there is an unacceptable character used."), + (mock_request_503, PluginException.causes[PluginException.Preset.UNKNOWN]), + ], + ) + def test_get_agent_details_exception(self, mock_request: MagicMock, exception: str) -> None: + mocked_request(mock_request) + with self.assertRaises(PluginException) as context: + self.action.run(self.payload) + self.assertEqual( + context.exception.cause, + exception, + ) diff --git a/plugins/carbon_black_cloud/unit_test/test_quarantine.py b/plugins/carbon_black_cloud/unit_test/test_quarantine.py index de6cdb30cb..f2dc64e03c 100644 --- a/plugins/carbon_black_cloud/unit_test/test_quarantine.py +++ b/plugins/carbon_black_cloud/unit_test/test_quarantine.py @@ -1,40 +1,60 @@ -import sys import os +import sys sys.path.append(os.path.abspath("../")) from unittest import TestCase -from icon_carbon_black_cloud.connection.connection import Connection +from unittest.mock import MagicMock, patch + from icon_carbon_black_cloud.actions.quarantine import Quarantine -import json -import logging +from icon_carbon_black_cloud.actions.quarantine.schema import Input, Output, QuarantineOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from jsonschema import validate +from parameterized import parameterized + +from util import ( + Util, + mock_request_200, + mock_request_400, + mock_request_401, + mock_request_403, + mock_request_404, + mock_request_409, + mock_request_503, + mocked_request, +) + +STUB_AGENT_ID = "192.168.0.1" class TestQuarantine(TestCase): - def test_integration_quarantine(self): - log = logging.getLogger("Test") - test_conn = Connection() - test_action = Quarantine() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/quarantine.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - self.assertIn("quarantined", results.keys()) + def setUp(self) -> None: + self.action = Util.default_connector(Quarantine()) + self.payload = {Input.AGENT: STUB_AGENT_ID, Input.WHITELIST: [], Input.QUARANTINE_STATE: False} + + @patch("requests.post", side_effect=mock_request_200) + def test_quarantine(self, mocked_post: MagicMock) -> None: + response = self.action.run(self.payload) + expected = {Output.QUARANTINED: False} + validate(response, QuarantineOutput.schema) + self.assertEqual(response, expected) + mocked_post.assert_called() + + @parameterized.expand( + [ + (mock_request_400, "400 Bad Request"), + (mock_request_401, "Authentication Error"), + (mock_request_403, "The specified object cannot be accessed or changed."), + (mock_request_404, "The object referenced in the request cannot be found."), + (mock_request_409, "Either the name you chose already exists, or there is an unacceptable character used."), + (mock_request_503, PluginException.causes[PluginException.Preset.UNKNOWN]), + ], + ) + def test_quarantine_exception(self, mock_request: MagicMock, exception: str) -> None: + mocked_request(mock_request) + with self.assertRaises(PluginException) as context: + self.action.run(self.payload) + self.assertEqual( + context.exception.cause, + exception, + ) diff --git a/plugins/carbon_black_cloud/unit_test/test_whitelist_checker.py b/plugins/carbon_black_cloud/unit_test/test_whitelist_checker.py index 252c543fcf..808c8288e3 100644 --- a/plugins/carbon_black_cloud/unit_test/test_whitelist_checker.py +++ b/plugins/carbon_black_cloud/unit_test/test_whitelist_checker.py @@ -1,6 +1,12 @@ +import os +import sys + +sys.path.append(os.path.abspath("../")) + +import logging from unittest import TestCase + import icon_carbon_black_cloud.util.whitelist_checker as whitelist_checker -import logging class TestWhitelistChecker(TestCase): diff --git a/plugins/carbon_black_cloud/unit_test/util.py b/plugins/carbon_black_cloud/unit_test/util.py new file mode 100644 index 0000000000..6ceb7563da --- /dev/null +++ b/plugins/carbon_black_cloud/unit_test/util.py @@ -0,0 +1,103 @@ +import json +import logging +import os +import sys +from typing import Callable + +import requests + +sys.path.append(os.path.abspath("../")) + +from typing import Any, Dict +from unittest import mock + +from icon_carbon_black_cloud.connection.connection import Connection +from icon_carbon_black_cloud.connection.schema import Input +from insightconnect_plugin_runtime.action import Action + +STUB_CONNECTION = { + Input.API_ID: "12345", + Input.API_SECRET_KEY: {"secretKey": "12345"}, + Input.ORG_KEY: "123456", + Input.URL: "defense.conferdeploy.net", +} +BASE_URL = f"https://{STUB_CONNECTION.get(Input.URL, '')}" + + +class Util: + @staticmethod + def default_connector(action: Action) -> Action: + default_connection = Connection() + default_connection.logger = logging.getLogger("connection logger") + default_connection.connect(STUB_CONNECTION) + action.connection = default_connection + action.logger = logging.getLogger("action logger") + return action + + @staticmethod + def read_file_to_string(filename: str) -> str: + with open( + os.path.join(os.path.dirname(os.path.realpath(__file__)), filename), "r", encoding="utf-8" + ) as file_reader: + return file_reader.read() + + @staticmethod + def read_file_to_dict(filename: str) -> Dict[str, Any]: + return json.loads(Util.read_file_to_string(filename)) + + +class MockResponse: + def __init__(self, filename: str, status_code: int, text: str = "Example Text") -> None: + self.filename = filename + self.status_code = status_code + self.text = text + + def json(self): + with open( + os.path.join(os.path.dirname(os.path.realpath(__file__)), f"responses/{self.filename}.json.resp") + ) as file: + return json.load(file) + + def raise_for_status(self) -> None: + raise Exception() + + +def mocked_request(side_effect: Callable) -> None: + mock_function = requests + mock_function.post = mock.Mock(side_effect=side_effect) + + +def mock_conditions(url: str, status_code: int, **kwargs: Dict[str, Any]) -> MockResponse: + if url == f"{BASE_URL}/appservices/v6/orgs/{STUB_CONNECTION.get(Input.ORG_KEY, '')}/devices/_search": + return MockResponse("get_agent_details", status_code) + elif url == f"{BASE_URL}/appservices/v6/orgs/{STUB_CONNECTION.get(Input.ORG_KEY, '')}/device_actions": + return MockResponse("quarantine", status_code) + raise Exception("Response has been not implemented") + + +def mock_request_200(*args, **kwargs) -> MockResponse: + return mock_conditions(args[0], 200, **kwargs) + + +def mock_request_400(*args, **kwargs) -> MockResponse: + return mock_conditions(args[0], 400, **kwargs) + + +def mock_request_401(*args, **kwargs) -> MockResponse: + return mock_conditions(args[0], 401, **kwargs) + + +def mock_request_403(*args, **kwargs) -> MockResponse: + return mock_conditions(args[0], 403, **kwargs) + + +def mock_request_404(*args, **kwargs) -> MockResponse: + return mock_conditions(args[0], 404, **kwargs) + + +def mock_request_409(*args, **kwargs) -> MockResponse: + return mock_conditions(args[0], 409, **kwargs) + + +def mock_request_503(*args, **kwargs) -> MockResponse: + return mock_conditions(args[0], 503, **kwargs)