Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rubrik Release 1.4.3 #38090

Open
wants to merge 1 commit into
base: contrib/crestdatasystems_Rubrik-Release-143
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions Packs/RubrikPolaris/Integrations/RubrikPolaris/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ Retrieve the download link for the requested scanned file.

### rubrik-radar-anomaly-csv-analysis
***
Request for the analysis and retrieve the download link for the Radar CSV analyzed file.
Request for the analysis and retrieve the download link or directly download file for the Radar CSV analyzed file.


#### Base Command
Expand All @@ -695,6 +695,7 @@ Request for the analysis and retrieve the download link for the Radar CSV analyz
| cluster_id | The unique ID of the cluster.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Required |
| snapshot_id | The CDM snapshot ID.<br/><br/>Note: Users can retrieve the list of snapshot IDs by executing the "rubrik-polaris-vm-object-snapshot-list" command.<br/>Use the "rubrik-radar-suspicious-file-list" command to retrieve the actual CDM ID from the Anomaly ID.<br/>Example format to get the snapshot CDM ID from Anomaly ID: "&lt;Cluster-ID&gt;:::VirtualMachine:::&lt;Snappable-ID&gt;:::&lt;CDM-ID&gt;". | Required |
| object_id | The VM object ID (Snappable ID).<br/><br/>Note: Users can retrieve the list of Snappable IDs by executing the "rubrik-polaris-vm-objects-list" command.<br/>Example format to get the Snappable ID: "VirtualMachine:::&lt;Snappable-ID&gt;". | Required |
| download_file | If set to True, the command downloads the anomaly analysis csv file directly on XSOAR server.<br/><br/>Possible values are: True, False. Default is False. | Optional |


#### Context Output
Expand All @@ -705,16 +706,40 @@ Request for the analysis and retrieve the download link for the Radar CSV analyz
| RubrikPolaris.RadarAnomalyCSV.snapshotId | String | Snapshot ID of the CSV. |
| RubrikPolaris.RadarAnomalyCSV.objectId | String | Object ID of the CSV. |
| RubrikPolaris.RadarAnomalyCSV.investigationCsvDownloadLink.downloadLink | String | The download link of the CSV analysis. |
| File.Size | String | File size in bytes. |
| File.SHA1 | String | SHA1 hash of file. |
| File.SHA256 | String | SHA256 hash of file. |
| File.SHA512 | String | SHA512 hash of file. |
| File.Name | String | File name. |
| File.SSDeep | String | SSDeep hash of the file. |
| File.EntryID | Unknown | The entry ID of the file. |
| File.Info | String | File information. |
| File.Type | String | The file type. |
| File.MD5 | String | MD5 hash of the file. |
| File.Extension | String | The file extension. |


#### Command Example
```!rubrik-radar-anomaly-csv-analysis cluster_id="cc19573c-db6c-418a-9d48-067a256543ba" snapshot_id="7b71d588-911c-4165-b6f3-103a1684d2a3" object_id="868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-4335"```
```!rubrik-radar-anomaly-csv-analysis cluster_id="0000-000-000-000-0000" snapshot_id="0000-000-000-000-0000" object_id="0000-000-000-000-vm-0000" download_file=True```

#### Human Readable Output
### Radar Anomaly CSV Analysis
|CSV Download Link|
|---|
| Download the analyzed [CSV](https://www.example.com/csv_file) file. |
>### Radar Anomaly CSV Analysis
>|CSV Download Link|
>|---|
>| Download the analyzed [CSV](https://www.example.com/snapshot_000-000-000-000.csv) file. |

>Uploaded file: snapshot_000-000-000-000.csv Download
>
>|Property|Value|
>|---|---|
>| Type | text/csv; charset=utf-8 |
>| Size | 10,069 bytes |
>| Info | ASCII text, with very long lines |
>| MD5 | 10000000000000000000000000 |
>| SHA1 | 1000000000000000000000000000000 |
>| SHA256 | 1000000000000000000000000000000000000000000000000000000000 |
>| SHA512 | 10000000000000000000000000000000000000000000000000000000000000000000000 |
>| SSDeep | 1:100000000000000000000000000000000000000000000000000000000: |



Expand Down
25 changes: 21 additions & 4 deletions Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.py
Original file line number Diff line number Diff line change
Expand Up @@ -2820,7 +2820,7 @@ def rubrik_sonar_ondemand_scan_result_command(client: PolarisClient, args: Dict[
raw_response=raw_response)


def rubrik_radar_anomaly_csv_analysis_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
def rubrik_radar_anomaly_csv_analysis_command(client: PolarisClient, args: Dict[str, Any]) -> list[Union[CommandResults, Any]]:
"""
Request for the analysis and retrieve the download link for the Radar CSV analyzed file.

Expand All @@ -2835,13 +2835,14 @@ def rubrik_radar_anomaly_csv_analysis_command(client: PolarisClient, args: Dict[
cluster_id = validate_required_arg("cluster_id", args.get('cluster_id'))
snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
object_id = validate_required_arg("object_id", args.get("object_id"))
download_file = argToBoolean(args.get('download_file', False))

response = client.get_csv_result(cluster_id=cluster_id, snappable_id=object_id, snapshot_id=snapshot_id)

data = response.get("data", {})
download_data = data.get('investigationCsvDownloadLink', {})
if not download_data:
return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])
return [CommandResults(readable_output=MESSAGES["NO_RESPONSE"])]
context = {
"clusterId": cluster_id,
"snapshotId": snapshot_id,
Expand All @@ -2852,13 +2853,29 @@ def rubrik_radar_anomaly_csv_analysis_command(client: PolarisClient, args: Dict[
hr = [f"Download the analyzed [CSV]({download_data.get('downloadLink')}) file."]
readable_output = tableToMarkdown(table_name, hr, ["CSV Download Link"], removeNull=True)

return CommandResults(
result = [CommandResults(
outputs_prefix=OUTPUT_PREFIX["RADAR_ANOMALY_CSV_ANALYSIS"],
outputs_key_field=["clusterId", "snapshotId", "objectId"],
outputs=context,
raw_response=response,
readable_output=readable_output
)
)]

if download_file:
file_content = requests.request("GET", download_data.get('downloadLink')).text
extract_file_name = re.search(r'[^\/]+\.csv', download_data.get('downloadLink'))
file_name = ''
if extract_file_name:
file_name = extract_file_name.group()

file_result = fileResult(
filename=file_name,
data=file_content
)

result.append(file_result)

return result


def rubrik_sonar_csv_download_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
Expand Down
42 changes: 41 additions & 1 deletion Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.yml
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,14 @@ script:
- description: "The VM object ID (Snappable ID).\n\nNote: Users can retrieve the list of Snappable IDs by executing the \"rubrik-polaris-vm-objects-list\" command.\nExample format to get the Snappable ID: \"VirtualMachine:::<Snappable-ID>\"."
name: object_id
required: true
description: Request for the analysis and retrieve the download link for the Radar CSV analyzed file.
- auto: PREDEFINED
defaultValue: "False"
description: "If set to True, the command downloads the anomaly analysis csv file directly on XSOAR server."
name: download_file
predefined:
- "True"
- "False"
description: Request for the analysis and retrieve the download link or directly download file for the Radar CSV analyzed file.
name: rubrik-radar-anomaly-csv-analysis
outputs:
- contextPath: RubrikPolaris.RadarAnomalyCSV.clusterId
Expand All @@ -941,6 +948,39 @@ script:
- contextPath: RubrikPolaris.RadarAnomalyCSV.investigationCsvDownloadLink.downloadLink
description: The download link of the CSV analysis.
type: String
- contextPath: File.Size
description: File size in bytes.
type: String
- contextPath: File.SHA1
description: SHA1 hash of file.
type: String
- contextPath: File.SHA256
description: SHA256 hash of file.
type: String
- contextPath: File.SHA512
description: SHA512 hash of file.
type: String
- contextPath: File.Name
description: File name.
type: String
- contextPath: File.SSDeep
description: SSDeep hash of the file.
type: String
- contextPath: File.EntryID
description: The entry ID of the file.
type: Unknown
- contextPath: File.Info
description: File information.
type: String
- contextPath: File.Type
description: The file type.
type: String
- contextPath: File.MD5
description: MD5 hash of the file.
type: String
- contextPath: File.Extension
description: The file extension.
type: String
- arguments:
- description: "ID of the snapshot.\n\nNote: Users can retrieve the list of snapshot IDs by executing the \"rubrik-polaris-vm-object-snapshot-list\" command."
name: snapshot_id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,13 @@ def test_vm_object_snapshot_get_when_invalid_arguments_are_provided(client, requ
assert str(e.value) == error


@pytest.mark.parametrize("empty_response", [True, False])
def test_radar_anomaly_csv_analysis_success(client, requests_mock, empty_response):
@pytest.mark.parametrize("empty_response, download_file", [
(True, "True"),
(True, "False"),
(False, "True"),
(False, "False")
])
def test_radar_anomaly_csv_analysis_success(client, requests_mock, empty_response, download_file):
"""Tests success for rubrik_radar_anomaly_csv_analysis."""
from RubrikPolaris import rubrik_radar_anomaly_csv_analysis_command

Expand All @@ -913,22 +918,29 @@ def test_radar_anomaly_csv_analysis_success(client, requests_mock, empty_respons
"test_data/radar_anomaly_csv_analysis_hr.md")) as f:
radar_anomaly_hr = f.read()

args = {"object_id": "dummy", "cluster_id": "dummy", "snapshot_id": "dummy"}
args = {"object_id": "dummy", "cluster_id": "dummy", "snapshot_id": "dummy", "download_file": download_file}

with open(os.path.join(os.path.dirname(os.path.realpath(__file__)),
"test_data/radar_anomaly_csv_analysis_file.csv"), 'r') as f:
file_data = f.read()
requests_mock.get('https://dummy_link/snapshot_000-000-000.csv', text=file_data, status_code=200)

if empty_response:
response = radar_anomaly_response.get('empty_response')
requests_mock.post(BASE_URL_GRAPHQL, json=response)
response = rubrik_radar_anomaly_csv_analysis_command(client, args=args)
assert response.readable_output == MESSAGES['NO_RESPONSE']
assert response[0].readable_output == MESSAGES['NO_RESPONSE']

else:
responses = radar_anomaly_response.get('raw_response')
requests_mock.post(BASE_URL_GRAPHQL, json=responses)
response = rubrik_radar_anomaly_csv_analysis_command(client, args=args)

assert response.raw_response == radar_anomaly_response.get('raw_response')
assert response.outputs == remove_empty_elements(radar_anomaly_response.get('outputs'))
assert response.readable_output == radar_anomaly_hr
assert response[0].raw_response == radar_anomaly_response.get('raw_response')
assert response[0].outputs == remove_empty_elements(radar_anomaly_response.get('outputs'))
assert response[0].readable_output == radar_anomaly_hr
if download_file == 'True' and isinstance(response[1], dict):
assert response[1].get('File') == 'snapshot_000-000-000.csv'


@pytest.mark.parametrize("args, error", [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
path,file_name,directory,change,is_suspicious,bytes_changed,size,mtime,object_type
/,/,/,NO_CHANGE,false,0,123456789,1643723900,WindowsVolumeGroup
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### Radar Anomaly CSV Analysis
|CSV Download Link|
|---|
| Download the analyzed [CSV](dummy_link) file. |
| Download the analyzed [CSV](https://dummy_link/snapshot_000-000-000.csv) file. |
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"raw_response": {
"data": {
"investigationCsvDownloadLink": {
"downloadLink": "dummy_link"
"downloadLink": "https://dummy_link/snapshot_000-000-000.csv"
}
}
},
Expand All @@ -14,7 +14,7 @@
"snapshotId": "dummy",
"objectId": "dummy",
"investigationCsvDownloadLink": {
"downloadLink": "dummy_link"
"downloadLink": "https://dummy_link/snapshot_000-000-000.csv"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@
"y": 4
},
{
"h": 2,
"h": 3,
"i": "caseinfoid-f98cd270-a6b1-11eb-bada-87dc9a8c0b9b",
"items": [],
"maxW": 3,
Expand All @@ -356,9 +356,9 @@
"name": "Linked Incidents",
"static": false,
"type": "linkedIncidents",
"w": 2,
"x": 1,
"y": 7
"w": 1,
"x": 0,
"y": 11
},
{
"description": "",
Expand Down Expand Up @@ -408,7 +408,7 @@
"type": "indicators",
"w": 2,
"x": 1,
"y": 9
"y": 11
},
{
"h": 4,
Expand All @@ -423,6 +423,30 @@
"w": 1,
"x": 0,
"y": 7
},
{
"h": 3,
"i": "caseinfoid-b692ce70-c809-11ef-b02b-91540fae8b93",
"items": [],
"maxW": 3,
"minH": 1,
"moved": false,
"name": "Incident Files",
"query": {
"categories": [
"attachments"
],
"lastId": "",
"pageSize": 100,
"tags": [],
"users": []
},
"queryType": "warRoomFilter",
"static": false,
"type": "invTimeline",
"w": 2,
"x": 1,
"y": 8
}
],
"type": "custom"
Expand Down
Loading
Loading