CadoResponse
Automate data collection. Process data at cloud speed. Analyze with purpose.
Forensics & Malware Analysis · Cado Response
Details
| ID | CadoResponse |
|---|---|
| Provider | Darktrace |
| Category | Forensics & Malware Analysis |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Cado Response Integration for Cortex XSOAR
Automate data collection. Process data at cloud speed. Analyze with purpose.
This integration was integrated and tested with version 1.2.0 of CadoResponse
Configure Cado Response in Cortex
| Parameter | Description | Required |
|---|---|---|
| Cado Response Instance | The URL for your Cado Response Instance | True |
| API Key | The API Key to use for connection | True |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False | |
| Default Cado Response Project | Provides a fallback Project ID from Cado Response if you forget to add an ID to a command. If you’re not sure, don’t change! | True |
| Default AWS Region | Provides a default AWS region to fallback to if you forget to add it to a command. | True |
| Default S3 Bucket | Provides a default S3 bucket to fallback to if you forget to add it to a command. | True |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
cado-create-project
Create a project in Cado Response
Base Command
cado-create-project
Input
| Argument Name | Description | Required |
|---|---|---|
| project_name | Name of the project. | Required |
| project_description | Description for the project. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CadoResponse.Project.id | Number | The Project ID of the newly created project |
Command example
!cado-create-project project_name="Project Name" description="Project Description"
Context Example
{
"CadoResponse": {
"Project": {
"id": 1,
"msg": "Created"
}
}
}
Human Readable Output
Results
id msg 1 Created
cado-list-project
Get a list of projects from Cado Response
Base Command
cado-list-project
Input
| Argument Name | Description | Required |
|---|---|---|
| project_id | ID of the project to retrive. | Optional |
| limit | Limit results to retrieve. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CadoResponse.Projects.id | Number | ID of the retrieved project |
| CadoResponse.Projects.caseName | String | Name of the retrieved project |
| CadoResponse.Projects.description | String | Description of the retrieved project |
| CadoResponse.Projects.users | Array | Array of users assigned to the retrieved project |
| CadoResponse.Projects.created | Date | Creation date of the project |
Command example
!cado-list-project limit=100
Context Example
{
"CadoResponse": {
"Projects": {
"caseName": "Project Name_XSOAR",
"created": "2022-01-17T12:21:46.613814",
"deleted": false,
"description": "This is a project in Cado Response created through Cortex XSOAR!",
"id": 1,
"status": "Pending",
"users": [
{
"display_name": "admin",
"id": 1,
"is_admin": true,
"login_type": 0,
"username": "admin"
}
]
}
}
}
Human Readable Output
Results
caseName created deleted description id status users Project Name_XSOAR 2022-01-17T12:21:46.613814 false This is a project in Cado Response created through Cortex XSOAR! 1 Pending {‘display_name’: ‘admin’, ‘id’: 1, ‘is_admin’: True, ‘login_type’: 0, ‘username’: ‘admin’}
Command example
!cado-list-project project_id=1
Context Example
{
"CadoResponse": {
"Projects": {
"caseName": "Project Name_XSOAR",
"created": "2022-01-17T12:21:46.613814",
"deleted": false,
"description": "This is a project in Cado Response created through Cortex XSOAR!",
"id": 1,
"status": "Pending",
"users": [
{
"display_name": "admin",
"id": 1,
"is_admin": true,
"login_type": 0,
"username": "admin"
}
]
}
}
}
Human Readable Output
Results
caseName created deleted description id status users Project Name_XSOAR 2022-01-17T12:21:46.613814 false This is a project in Cado Response created through Cortex XSOAR! 1 Pending {‘display_name’: ‘admin’, ‘id’: 1, ‘is_admin’: True, ‘login_type’: 0, ‘username’: ‘admin’}
cado-get-pipeline
Get pipeline details from Cado Response
Base Command
cado-get-pipeline
Input
| Argument Name | Description | Required |
|---|---|---|
| pipeline_id | The id of the pipeline to retrieve. | Optional |
| project_id | The id of the project the pipeline belongs to. | Optional |
| limit | Limit results to retrieve. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CadoResponse.Pipeline.pipeline_id | Number | The ID of the retrieved pipeline |
| CadoResponse.Pipeline.pipeline_type | String | The type of pipeline that was retrieved |
| CadoResponse.Pipeline.created | Date | The date at which the retrieved pipeline was started |
| CadoResponse.Pipeline.evidence_id | Number | The evidence ID linked to the retrieved pipeline |
| CadoResponse.Pipeline.project_id | Number | The ID of the project the pipeline belongs to |
| CadoResponse.Pipeline.is_terminated | Boolean | A boolean which says if the retrieved pipeline has been finished/terminated |
| CadoResponse.Pipeline.summary | Array | An array of values containing the cancelled, failed, pending, running and successful pipeline subtasks |
| CadoResponse.Pipeline.subtask | Array | An array of tasks in the retrieved pipeline |
Command example
!cado-get-pipeline project_id=1 pipeline_id=1
Context Example
{
"CadoResponse": {
"Pipeline": {
"pipeline_id": 1,
"pipeline_type": "processing",
"created": "2022-01-17T12:22:00.843869",
"evidence_id": 1,
"project_id": 1,
"is_terminated": false,
"subtasks": [
{
"execution_duration": 0,
"finish_time": 0,
"name": "Triage: Attaching disk for local data storage.",
"name_key": "infrastructure.check_ssd",
"notification_level": "Info",
"progress_text": [],
"start_time": 0,
"state": "PENDING",
"task_id": "3699827f-63c4-4408-88a4-0ae899187ed3",
"total_stages": null
}
],
"summary": {
"cancelled": 0,
"failure": 0,
"pending": 14,
"running": 0,
"success": 0,
"total": 14
}
}
}
}
Human Readable Output
Results
pipeline_id pipeline_type created evidence_id project_id is_terminated summary subtask 1 processing 2022-01-17T12:22:00.843869 1 1 false “execution_duration”: 0,
“finish_time”: 0,
“name”: “Triage: attaching disk for local data storage.”,
“name_key”: infrastructure.check_ssd”,
“notification_level”: “Info”,
“progress_text”: [],
“start_time”: 0,
“state”: “PENDING”,
“task_id”: “3699827f-63c4-4408-88a4-0ae899187ed3”,
“total_stages”: null“cancelled”: 0,
“failure”: 0,
“pending”: 14,
“running”: 0,
“success”: 0,
“total”: 14
cado-list-ec2
Get a list of EC2 instances in a region
Base Command
cado-list-ec2
Input
| Argument Name | Description | Required |
|---|---|---|
| region | The AWS region to list instances in. | Required |
| project_id | The ID of the project you wish to attach the acquisition to. | Optional |
| limit | Limit results to retrieve. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CadoResponse.EC2Instances.id | Number | AWS ID of the EC2 Instance |
| CadoResponse.EC2Instances.instance_name | String | Name of the EC2 Instance |
| CadoResponse.EC2Instances.instance_type | String | AWS Type of the EC2 instance |
| CadoResponse.EC2Instances.region | String | AWS region of the EC2 instance |
Command example
!cado-list-ec2 project_id=1 region="us-east-1" limit=100
Context Example
{
"CadoResponse": {
"EC2Instances": [
{
"_placement": "us-east-1c",
"_state": "stopped",
"celery_worker_name": null,
"deployment_id": null,
"evidence_id": null,
"id": "i-00000000000",
"instance_name": "Instance",
"instance_type": "t3a.2xlarge",
"ip_address": null,
"launch_time": "Thu, 25 Mar 2021 18:38:13 GMT",
"processing_type": null,
"project_id": null,
"queue_name": null,
"region": {
"name": "us-east-1"
},
"worker_used": null
}
]
}
}
Human Readable Output
Results
_placement _state celery_worker_name deployment_id evidence_id id instance_name instance_type ip_address launch_time processing_type project_id queue_name region worker_used us-east-1c stopped i-00000000000 Instance t3a.2xlarge Thu, 25 Mar 2021 18:38:13 GMT name: us-east-1
cado-list-s3
Get a list of S3 buckets
Base Command
cado-list-s3
Input
| Argument Name | Description | Required |
|---|---|---|
| project_id | The ID of the project you wish to attach the acquisition to. | Optional |
| limit | Limit results to retrieve. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CadoResponse.S3Buckets.buckets | Array | An array of S3 buckets available to the project |
Command example
!cado-list-s3 project_id=1 limit=100
Context Example
{
"CadoResponse": {
"S3Buckets": {
"buckets": [
"bucket",
]
}
}
}
Human Readable Output
Results
buckets bucket
cado-trigger-ec2
Trigger a disk acquisition and processing pipeline in Cado Response for a given EC2 instance
Base Command
cado-trigger-ec2
Input
| Argument Name | Description | Required |
|---|---|---|
| project_id | The ID of the project you wish to attach the acquisition to. | Optional |
| instance_id | ID of the EC2 instance to acquire. | Required |
| region | AWS region in which the EC2 instance is located. | Optional |
| bucket | S3 bucket where the uploaded disk image resides. | Optional |
| compress | Flag indicating if disk compression is enabled. | Optional |
| include_disks | Flag indicating if we include disk images in the acquisition. | Optional |
| include_hash | Flag indicating if we calculate the hash of the disk. | Optional |
| include_logs | Flag indicating if we include system logs in the acquisition. | Optional |
| include_screenshot | Flag indicating if we include a screenshot of the system in the acquisition. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CadoResponse.EC2Acquisition.pipeline_id | Number | ID of the created pipeline |
Command example
!cado-trigger-ec2 project_id=1 instance_id="i-00000000000" region="us-east-1" bucket="bucket" compress=true include_disks=true include_hash=true include_logs=true include_screenshot=true
Context Example
{
"CadoResponse": {
"EC2Acquistion": {
"created": "2022-01-17T12:21:59.084282",
"evidence_id": 0,
"name": "Acquiring i-00000000000",
"pipeline_id": 1,
"pipeline_type": "acquisition",
"project_id": 1,
"subtasks": [
{
"id": "1587a9c9-c02c-464b-a6f7-d4b7e720bd93"
},
{
"id": "4f798bf8-c7d3-427c-9498-10a85cfe3978"
},
{
"id": "c5fa26f1-e282-47a6-8335-1160766e089b"
},
{
"id": "82ec9a7e-47ac-4539-9623-166a44a59d0f"
},
{
"id": "88151005-a999-422e-b4cb-9e76699d6e42"
}
],
"user_id": 1
}
}
}
Human Readable Output
Results
created evidence_id name pipeline_id pipeline_type project_id subtasks user_id 2022-01-17T12:21:59.084282 0 Acquiring i-00000000000 1 acquisition 1 {‘id’: ‘1587a9c9-c02c-464b-a6f7-d4b7e720bd93’},
{‘id’: ‘4f798bf8-c7d3-427c-9498-10a85cfe3978’},
{‘id’: ‘c5fa26f1-e282-47a6-8335-1160766e089b’},
{‘id’: ‘82ec9a7e-47ac-4539-9623-166a44a59d0f’},
{‘id’: ‘88151005-a999-422e-b4cb-9e76699d6e42’}1
cado-trigger-s3
Trigger a disk acquisition and processing pipeline in Cado Response for a given file in an S3 bucket
Base Command
cado-trigger-s3
Input
| Argument Name | Description | Required |
|---|---|---|
| project_id | The ID of the project you wish to attach the acquisition to. | Optional |
| bucket | The S3 bucket name containing the file. | Required |
| file_name | The name of the file to process. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| CadoResponse.S3Acquisition.pipeline_id | Number | ID of the created pipeline |
Command example
!cado-trigger-s3 project_id=1 bucket="bucket" file_name="file"
Context Example
{
"CadoResponse": {
"S3Acquisition": {
"created": "2022-01-17T12:22:00.843869",
"evidence_id": 1,
"name": "",
"pipeline_id": 2,
"pipeline_type": "processing",
"project_id": 1,
"subtasks": [
{
"id": "3699827f-63c4-4408-88a4-0ae899187ed3"
},
{
"id": "727e2072-8bf7-4847-89ea-9447f5fd8fd0"
},
{
"id": "857d48b8-abaf-4ea6-b159-d25c9784b837"
},
{
"id": "533f7deb-74bc-4ffb-b81f-788ed714bead"
},
{
"id": "3f1defde-3986-4292-a423-1bef62d4c52b"
},
{
"id": "e41a0934-266b-4868-9a7d-5f083b1efcc1"
},
{
"id": "75411e10-46e9-41dd-8bf7-9b5fbdc8df71"
},
{
"id": "0afbf2f4-fbf3-4305-ad9f-b19d30f4b17c"
},
{
"id": "ca063c7b-1135-4922-8542-49f40ce71449"
},
{
"id": "67fdb0ea-dcee-4f65-a003-4f40fcd567fb"
},
{
"id": "1437ec33-6af2-4eb8-9c43-e071dcb7e0ac"
},
{
"id": "06db4dcc-57fd-48bc-bb34-5bd8f2da0a0d"
},
{
"id": "e3cc930e-9a60-46c3-97a1-611824c24437"
},
{
"id": "ad2c8877-39e7-4bff-9756-81278802ee76"
}
],
"user_id": 1
}
}
}
Human Readable Output
Results
created evidence_id name pipeline_id pipeline_type project_id subtasks user_id 2022-01-17T12:22:00.843869 1 2 processing 1 {‘id’: ‘3699827f-63c4-4408-88a4-0ae899187ed3’},
{‘id’: ‘727e2072-8bf7-4847-89ea-9447f5fd8fd0’},
{‘id’: ‘857d48b8-abaf-4ea6-b159-d25c9784b837’},
{‘id’: ‘533f7deb-74bc-4ffb-b81f-788ed714bead’},
{‘id’: ‘3f1defde-3986-4292-a423-1bef62d4c52b’},
{‘id’: ‘e41a0934-266b-4868-9a7d-5f083b1efcc1’},
{‘id’: ‘75411e10-46e9-41dd-8bf7-9b5fbdc8df71’},
{‘id’: ‘0afbf2f4-fbf3-4305-ad9f-b19d30f4b17c’},
{‘id’: ‘ca063c7b-1135-4922-8542-49f40ce71449’},
{‘id’: ‘67fdb0ea-dcee-4f65-a003-4f40fcd567fb’},
{‘id’: ‘1437ec33-6af2-4eb8-9c43-e071dcb7e0ac’},
{‘id’: ‘06db4dcc-57fd-48bc-bb34-5bd8f2da0a0d’},
{‘id’: ‘e3cc930e-9a60-46c3-97a1-611824c24437’},
{‘id’: ‘ad2c8877-39e7-4bff-9756-81278802ee76’}1
Configuration parameters
url— Cado Response Instance (required)apikey— API Key (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsCadoResponse_DefaultProject— Default Cado Response Project (required)CadoResponse_DefaultRegion— Default AWS Region (required)CadoResponse_DefaultBucket— Default S3 Bucket (required)
Commands (7)
-
cado-create-projectCreate a project in Cado Response.
-
cado-get-pipelineGet pipeline details from Cado Response.
-
cado-list-ec2Get a list of EC2 instances in a region.
-
cado-list-projectGet a list of projects from Cado Response.
-
cado-list-s3Get a list of S3 buckets.
-
cado-trigger-ec2Trigger a disk acquisition and processing pipeline in Cado Response for a given EC2 instance.
-
cado-trigger-s3Trigger a disk acquisition and processing pipeline in Cado Response for a given file in an S3 bucket.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 """ Cado Response API Integration for the Cortex XSOAR Platform """ import time import traceback from typing import Any import urllib3 from CommonServerUserPython import * """ Module Level Declarations """ urllib3.disable_warnings() CadoResponseCombinedOutput = Union[dict[str, Any], List[dict[str, Any]]] DATE_FORMAT: str = "%Y-%m-%dT%H:%M:%SZ" """ Cado Response API Client Code """ class Client(BaseClient): """Client that makes HTTP requests to the Cado Response API""" def heartbeat(self) -> dict[str, Any]: """Calls the GET /api/v2/system/status endpoint to verify everything is working :return JSON response from /system/status endpoint :rtype Dict[str, Any] """ return self._http_request(method="GET", url_suffix="/system/status") def create_project(self, project_name: str, project_description: str | None) -> dict[str, Any]: """Calls the POST /api/v2/projects endpoint to create a new project with given parameters :param str project_name: Name of the project :param Optional[str] project_description: Description for the project :return JSON response from /projects endpoint :rtype Dict[str, Any] """ if not project_name.endswith("_XSOAR"): project_name += "_XSOAR" if not project_description: project_description = "This is a project in Cado Response created through Cortex XSOAR!" payload: dict[str, Any] = {"caseName": project_name, "description": project_description} return self._http_request(method="POST", url_suffix="/projects", json_data=payload) def get_project(self, project_id: int | None) -> dict[str, Any]: """Calls the GET /api/v2/projects endpoint to retrieve a project with given parameters :param Optional[int] project_id: ID of the project to retrieve :return JSON response from /projects endpoint :rtype Dict[str, Any] """ if not project_id: project_id = demisto.params().get("CadoResponse_DefaultProject", 1) return self._http_request(method="GET", url_suffix=f"/projects/{project_id}") def list_projects(self, limit: int) -> List[dict[str, Any]]: """Calls the GET /api/v2/projects endpoint to retrieve a list of created projects :return JSON response from /projects endpoint :rtype Dict[str, Any] """ data: List[dict[str, Any]] = self._http_request(method="GET", url_suffix="/projects") return data[:limit] def get_pipeline(self, pipeline_id: int | None, project_id: int | None) -> dict[str, Any]: """Calls the GET /api/v2/tasks/pipelines endpoint to retrieve details about a given pipeline :param Optional[int] pipeline_id: The id of the pipeline to retrieve :param Optional[int] project_id: The id of the project the pipeline belongs to :return JSON response from /tasks/pipelines endpoint :rtype Dict[str, Any] """ if not pipeline_id: return {} if not project_id: project_id = demisto.params().get("CadoResponse_DefaultProject", 1) return self._http_request( method="GET", url_suffix="/tasks/pipelines", params={"project_id": project_id, "pipeline_id": pipeline_id} ) def list_pipelines(self, project_id: int | None, limit: int) -> List[dict[str, Any]]: """Calls the GET /api/v2/tasks/pipelines endpoint to retrieve details about all of a projects pipelines :param Optional[int] project_id: The id of the project the pipeline belongs to :return JSON response from /tasks/pipelines endpoint :rtype Dict[str, Any] """ if not project_id: project_id = demisto.params().get("CadoResponse_DefaultProject", 1) data: dict[str, Any] = self._http_request( method="GET", url_suffix="/tasks/pipelines", params={ "project_id": project_id, }, ) pipelines: List[dict[str, Any]] = data["pipelines"] return pipelines[:limit] def list_instances(self, project_id: int | None, region: str | None, limit: int) -> List[dict[str, Any]]: """Calls the GET /api/v2/projects/{id}/imports/ec2 endpoint to retrieve details about a regions EC2 instances :param Optional[int] project_id: The id of the project to query available instances in :param Optional[str] region: The AWS region to search instances in :return JSON response from /projects/{id}/imports/ec2 endpoint :rtype Dict[str, Any] """ if not project_id: project_id = demisto.params().get("CadoResponse_DefaultProject", 1) if not region: region = demisto.params().get("CadoResponse_DefaultRegion", "us-east-1") data: dict[str, Any] = self._http_request( method="GET", url_suffix=f"/projects/{project_id}/imports/ec2", params={"region": region} ) instances: List[dict[str, Any]] = data["instances"] return instances[:limit] def list_buckets(self, project_id: int | None, limit: int) -> dict[str, Any]: """Calls the GET /api/v2/projects/{id}/imports/s3 endpoint to retrieve details about all the available S3 buckets :param Optional[int] project_id: The id of the project to query available buckets in :return JSON response from /projects/{id}/imports/s3 endpoint :rtype Dict[str, Any] """ if not project_id: project_id = demisto.params().get("CadoResponse_DefaultProject", 1) data: dict[str, Any] = self._http_request(method="GET", url_suffix=f"/projects/{project_id}/imports/s3") data["buckets"] = data["buckets"][:limit] return data def trigger_instance_acquisition( self, project_id: int | None, instance_id: str | None, region: str | None, bucket: str | None, compress: bool = True, include_disks: bool = True, include_hash: bool = False, include_logs: bool = True, include_screenshot: bool = True, ) -> dict[str, Any]: """Calls the POST /api/v2/projects/{id}/imports/ec2 endpoint to trigger an acquisition of a given instance :param Optional[int] project_id: The ID of the project you wish to attach the acquisition to :param str instance_id: ID of the EC2 instance to acquire :param Optional[str] region: AWS region in which the EC2 instance is located :param Optional[str] bucket: S3 bucket where the uploaded disk image resides :param bool compress: Flag indicating if disk compression is enabled :param bool include_disks: Flag indicating if we include disk image in the acquisition :param bool include_hash: Flag indicating if we calculate the hash of the disk :param bool include_logs: Flag indicating if we include system logs in the acquisition :param bool include_screenshot: Flag indicating if we include a screenshot of the system in the acquisition :return JSON response from /projects/{id}/imports/ec2 endpoint :rtype Dict[str, Any] """ if not project_id: project_id = demisto.params().get("CadoResponse_DefaultProject", 1) if not region: region = demisto.params().get("CadoResponse_DefaultRegion", "us-east-1") if not bucket: bucket = demisto.params().get("CadoResponse_DefaultBucket", "cado-default-bucket") payload: dict[str, Any] = { "bucket": bucket, "compress": compress, "include_disks": include_disks, "include_hash": include_hash, "include_logs": include_logs, "include_screenshot": include_screenshot, "instance_id": instance_id, "region": region, } return self._http_request(method="POST", url_suffix=f"/projects/{project_id}/imports/ec2", json_data=payload) def trigger_bucket_acquisition(self, project_id: int | None, bucket: str | None, file_name: str | None) -> dict[str, Any]: """Calls the POST /api/v2/projects/{id}/imports/s3 endpoint to trigger an acquisition of a given bucket or file :param Optional[int] project_id: The ID of the project you wish to attach the acquisition to :param Optional[str] bucket: The S3 bucket name containing the file :param str file_name: The name of the file to process :return JSON response from /projects/{id}/imports/ec2 endpoint :rtype Dict[str, Any] """ if not project_id: project_id = demisto.params().get("CadoResponse_DefaultProject", 1) if not bucket: bucket = demisto.params().get("CadoResponse_DefaultBucket", "cado-default-bucket") payload: dict[str, Any] = {"bucket": bucket, "file_name": file_name} return self._http_request(method="POST", url_suffix=f"/projects/{project_id}/imports/s3", json_data=payload) """ Command Line Handlers """ def test_module(client: Client) -> str: """Command handler for !test-module""" result: dict[str, Any] = client.heartbeat() status: str | None = result["status"] if status is not None and status == "Running": return "ok" return "Cado Response is not running" def create_project_command(client: Client, args: dict[str, Any]) -> CommandResults: """Command handler for cado-create-project""" unix_timestamp: str = str(int(time.time())) project_name: str = args.get("project_name", unix_timestamp) project_description: str | None = args.get("project_description", None) result: dict[str, Any] = client.create_project(project_name, project_description) return CommandResults(outputs_prefix="CadoResponse.Project", outputs_key_field="id", outputs=result) def list_project_command(client: Client, args: dict[str, Any]) -> CommandResults: """Command handler for cado-list-project""" project_id: int | None = args.get("project_id", None) limit: int = int(args.get("limit", 50)) if project_id: result: Any = client.get_project(project_id) else: result = client.list_projects(limit) return CommandResults(outputs_prefix="CadoResponse.Projects", outputs_key_field="id", outputs=result) def get_pipeline_command(client: Client, args: dict[str, Any]) -> CommandResults: """Command handler for cado-get-pipeline""" project_id: int | None = args.get("project_id", None) limit: int = int(args.get("limit", 50)) pipeline_id: int | None = args.get("pipeline_id", None) if pipeline_id: result: CadoResponseCombinedOutput = client.get_pipeline(pipeline_id, project_id) else: result = client.list_pipelines(project_id, limit) return CommandResults(outputs_prefix="CadoResponse.Pipelines", outputs_key_field="pipeline_id", outputs=result) def list_ec2_command(client: Client, args: dict[str, Any]) -> CommandResults: """Command handler for cado-list-ec2""" project_id: int | None = args.get("project_id", None) region: str | None = args.get("region", None) limit: int = int(args.get("limit", 100)) result: List[dict[str, Any]] = client.list_instances(project_id, region, limit) return CommandResults(outputs_prefix="CadoResponse.EC2Instances", outputs_key_field="id", outputs=result) def list_s3_command(client: Client, args: dict[str, Any]) -> CommandResults: """Command handler for cado-list-s3""" project_id: int | None = args.get("project_id", None) limit: int = int(args.get("limit", 100)) result: dict[str, Any] = client.list_buckets(project_id, limit) return CommandResults(outputs_prefix="CadoResponse.S3Buckets", outputs=result) def trigger_ec2_command(client: Client, args: dict[str, Any]) -> CommandResults: """Command handler for cado-trigger-ec2""" project_id: int | None = args.get("project_id", None) instance_id: str | None = args.get("instance_id", None) region: str | None = args.get("region", None) bucket: str | None = args.get("bucket", None) compress: bool = args.get("compress", True) include_disks: bool = args.get("include_disks", True) include_hash: bool = args.get("include_hash", False) include_logs: bool = args.get("include_logs", True) include_screenshot: bool = args.get("include_screenshot", True) if not instance_id: raise DemistoException("region is a required parameter!") result: dict[str, Any] = client.trigger_instance_acquisition( project_id, instance_id, region, bucket, compress, include_disks, include_hash, include_logs, include_screenshot ) return CommandResults(outputs_prefix="CadoResponse.EC2Acquistion", outputs_key_field="pipeline_id", outputs=result) def trigger_s3_command(client: Client, args: dict[str, Any]) -> CommandResults: """Command handler for cado-trigger-s3""" project_id: int | None = args.get("project_id", None) bucket: str | None = args.get("bucket", None) file_name: str | None = args.get("file_name", None) if not bucket: raise DemistoException("bucket is a required parameter!") if not file_name: raise DemistoException("file_name is a required parameter!") result: dict[str, Any] = client.trigger_bucket_acquisition(project_id, bucket, file_name) return CommandResults( outputs_prefix="CadoResponse.S3Acquisition", outputs_key_field="pipeline_id", outputs=result.get("pipelines") ) """ Helper Functions """ def enrich_errors(message: str, command: str) -> str: """Helper function to return better error messages. :param str message: Error message :param str command: Calling command :return: A better error message :rtype str """ if command == "cado-create-project" and "Project name already exists" in message: return f'Project name {demisto.args().get("project_name")} already exists!' else: return f"Failed to execute {demisto.command()} command.\nError:\n{message}" """ Entrypoint """ def main() -> None: api_key: str = demisto.params().get("apikey") base_url: str = urljoin(demisto.params()["url"], "/api/v2") verify_certificate: bool = not demisto.params().get("insecure", False) proxy: bool = demisto.params().get("proxy", False) command: str = demisto.command() args: dict[str, Any] = demisto.args() headers: dict[str, Any] = {"Authorization": f"Bearer {api_key}"} try: client: Client = Client(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy) if command == "test-module": return_results(test_module(client)) elif command == "cado-create-project": return_results(create_project_command(client, args)) elif command == "cado-list-project": return_results(list_project_command(client, args)) elif command == "cado-get-pipeline": return_results(get_pipeline_command(client, args)) elif command == "cado-list-ec2": return_results(list_ec2_command(client, args)) elif command == "cado-list-s3": return_results(list_s3_command(client, args)) elif command == "cado-trigger-ec2": return_results(trigger_ec2_command(client, args)) elif command == "cado-trigger-s3": return_results(trigger_s3_command(client, args)) except Exception as e: message: str = str(e) if "404" in message: return_results(f"Nothing found for {command}") else: demisto.error(traceback.format_exc()) return_error(enrich_errors(message, command), error=e) if __name__ in ("__main__", "__builtin__", "builtins"): main()