-
Notifications
You must be signed in to change notification settings - Fork 56
NetApp Ransomware Resilience Integration for Google SecOps #577
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
base: main
Are you sure you want to change the base?
Changes from all commits
bfd5da5
af78479
5f01f89
abea56d
af53f9b
90e2805
1eaacf3
4339dbe
9a12405
1d87adf
a4a30b5
6577bae
a64ed7e
2d166e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 3.11 |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,42 @@ | ||||||
| from __future__ import annotations | ||||||
| from soar_sdk.SiemplifyAction import SiemplifyAction | ||||||
| from soar_sdk.SiemplifyUtils import output_handler | ||||||
| from soar_sdk.ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED | ||||||
| from ..core.ApiManager import ApiManager | ||||||
|
|
||||||
|
|
||||||
| @output_handler | ||||||
| def main(): | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||
| siemplify = SiemplifyAction() | ||||||
| siemplify.LOGGER.info("----------------- RRS - Check Job Status: Init -----------------") | ||||||
| rrsManager = ApiManager(siemplify) | ||||||
| siemplify.LOGGER.info("----------------- RRS - Check Job Status: Started -----------------") | ||||||
|
|
||||||
| job_status_result = None | ||||||
| try: | ||||||
|
|
||||||
| # call check job status api | ||||||
| job_status_result = rrsManager.check_job_status() | ||||||
|
|
||||||
| status = EXECUTION_STATE_COMPLETED # used to flag back to siemplify system, the action final status | ||||||
| output_message = "Successfully retrieved job status" # human readable message, showed in UI as the action result | ||||||
| result_value = True # Set a simple result value, used for playbook if\else and placeholders. | ||||||
|
|
||||||
| except Exception as e: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The References
|
||||||
| output_message = f"Failed to check job status. Error: {e}" | ||||||
| siemplify.LOGGER.error(f"Check Job Status: Failed to check job status. Error: {e}") | ||||||
| siemplify.LOGGER.exception(e) | ||||||
| status = EXECUTION_STATE_FAILED | ||||||
| result_value = False | ||||||
| job_status_result = {} | ||||||
|
|
||||||
| siemplify.LOGGER.info("----------------- RRS - Check Job Status: End -----------------") | ||||||
| siemplify.LOGGER.info(f"Check Job Status output: \n status: {status}\n result_value: {result_value}\n output_message: {output_message}") | ||||||
|
|
||||||
| # Add result to action output. | ||||||
| siemplify.result.add_result_json(job_status_result) | ||||||
| siemplify.end(output_message, result_value, status) | ||||||
|
|
||||||
|
|
||||||
| if __name__ == "__main__": | ||||||
| main() | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| name: Check Job Status | ||
| description: Check status of asynchronous jobs | ||
| integration_identifier: netapp-ransomware-resilience | ||
| parameters: | ||
| - name: Source | ||
| default_value: '' | ||
| type: string | ||
| description: Source string (eg. rps-agent) | ||
| is_mandatory: true | ||
| - name: Agent ID | ||
| default_value: '' | ||
| type: string | ||
| description: Console Agent ID | ||
| is_mandatory: true | ||
| - name: Job ID | ||
| default_value: '' | ||
| type: string | ||
| description: Job ID for which status to be fetched | ||
| is_mandatory: true | ||
| dynamic_results_metadata: | ||
| - result_example_path: resources/check_job_status_JsonResult_example.json | ||
ronypnetapp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| result_name: JsonResult | ||
| show_result: true | ||
| default_result_value: '' | ||
| creator: 5c86e1e4-dd8c-4181-8fc9-f5e8f008caae | ||
| script_result_name: ScriptResult | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| from __future__ import annotations | ||
| from soar_sdk.SiemplifyAction import SiemplifyAction | ||
| from soar_sdk.SiemplifyUtils import unix_now, convert_unixtime_to_datetime, output_handler | ||
| from soar_sdk.ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED,EXECUTION_STATE_TIMEDOUT | ||
| from ..core.ApiManager import ApiManager | ||
|
|
||
|
|
||
| @output_handler | ||
| def main(): | ||
| siemplify = SiemplifyAction() | ||
| siemplify.LOGGER.info("----------------- RRS - Enrich IP: Init -----------------") | ||
| rrsManager = ApiManager(siemplify) | ||
| ip_address = siemplify.extract_action_param("IP Address", print_value=True) | ||
| siemplify.LOGGER.info("----------------- RRS - Enrich IP: Started -----------------") | ||
|
|
||
| enrich_results = None | ||
| try: | ||
|
|
||
| # call enrich api | ||
| enrich_results = rrsManager.enrich_ip(ip_address) | ||
|
|
||
| status = EXECUTION_STATE_COMPLETED # used to flag back to siemplify system, the action final status | ||
| output_message = f"Successfully enriched IP - {ip_address}" # human readable message, showed in UI as the action result | ||
| result_value = True # Set a simple result value, used for playbook if\else and placeholders. | ||
|
|
||
| except Exception as e: | ||
| output_message = f"Failed to enrich IP - {ip_address}. Error: {e}" | ||
| siemplify.LOGGER.error(f"Enrich IP: Failed to enrich IP - {ip_address}. Error: {e}") | ||
| siemplify.LOGGER.exception(e) | ||
| status = EXECUTION_STATE_FAILED | ||
| result_value = False | ||
| enrich_results = [] | ||
|
|
||
| siemplify.LOGGER.info("----------------- RRS - Enrich IP: End -----------------") | ||
| siemplify.LOGGER.info(f"Enrich IP output: \n status: {status}\n result_value: {result_value}\n output_message: {output_message}") | ||
|
|
||
| # Add result to action output. | ||
| siemplify.result.add_result_json(enrich_results) | ||
| siemplify.end(output_message, result_value, status) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| name: Enrich IP Address | ||
| description: Enrich IP with threat intelligence | ||
| integration_identifier: netapp-ransomware-resilience | ||
| parameters: | ||
| - name: IP Address | ||
| default_value: '' | ||
| type: string | ||
| description: IP Address for enrichment | ||
| is_mandatory: true | ||
| dynamic_results_metadata: | ||
| - result_example_path: resources/enrich_ip_address_JsonResult_example.json | ||
| result_name: JsonResult | ||
| show_result: true | ||
| default_result_value: '' | ||
| creator: 5c86e1e4-dd8c-4181-8fc9-f5e8f008caae | ||
| script_result_name: ScriptResult |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| from __future__ import annotations | ||
| from soar_sdk.SiemplifyAction import SiemplifyAction | ||
| from soar_sdk.SiemplifyUtils import unix_now, convert_unixtime_to_datetime, output_handler | ||
| from soar_sdk.ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED,EXECUTION_STATE_TIMEDOUT | ||
| from ..core.ApiManager import ApiManager | ||
|
|
||
|
|
||
| @output_handler | ||
| def main(): | ||
| siemplify = SiemplifyAction() | ||
| siemplify.LOGGER.info("----------------- RRS - Enrich Storage: Init -----------------") | ||
| rrsManager = ApiManager(siemplify) | ||
| siemplify.LOGGER.info("----------------- RRS - Enrich Storage: Started -----------------") | ||
|
|
||
| enrich_results = None | ||
| try: | ||
|
|
||
| # call enrich storage api | ||
| enrich_results = rrsManager.enrich_storage() | ||
|
|
||
| status = EXECUTION_STATE_COMPLETED # used to flag back to siemplify system, the action final status | ||
| output_message = "Successfully enriched storage information" # human readable message, showed in UI as the action result | ||
| result_value = True # Set a simple result value, used for playbook if\else and placeholders. | ||
|
|
||
| except Exception as e: | ||
| siemplify.LOGGER.error(f"Enrich Storage: Failed to enrich storage. Error: {e}") | ||
| output_message = f"Failed to enrich storage. Error: {e}" | ||
| siemplify.LOGGER.exception(e) | ||
| status = EXECUTION_STATE_FAILED | ||
| result_value = False | ||
| enrich_results = [] | ||
|
|
||
| siemplify.LOGGER.info("----------------- RRS - Enrich Storage: End -----------------") | ||
| siemplify.LOGGER.info(f"Enrich Storage output: \n status: {status}\n result_value: {result_value}\n output_message: {output_message}") | ||
|
|
||
| # Add result to action output. | ||
| siemplify.result.add_result_json(enrich_results) | ||
| siemplify.end(output_message, result_value, status) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| name: Enrich Storage | ||
| description: Get volume information for agent/system | ||
| integration_identifier: netapp-ransomware-resilience | ||
| parameters: | ||
| - name: Agent ID | ||
| default_value: '' | ||
| type: string | ||
| description: Console Agent ID | ||
| is_mandatory: true | ||
| - name: System ID | ||
| default_value: '' | ||
| type: string | ||
| description: Storage System ID | ||
| is_mandatory: true | ||
| dynamic_results_metadata: | ||
| - result_example_path: resources/enrich_storage_JsonResult_example.json | ||
| result_name: JsonResult | ||
| show_result: true | ||
| default_result_value: '' | ||
| creator: 5c86e1e4-dd8c-4181-8fc9-f5e8f008caae | ||
| script_result_name: ScriptResult |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| from __future__ import annotations | ||
| from soar_sdk.SiemplifyAction import SiemplifyAction | ||
| from soar_sdk.SiemplifyUtils import output_handler | ||
| from soar_sdk.ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED | ||
| from ..core.ApiManager import ApiManager | ||
|
|
||
| @output_handler | ||
| def main(): | ||
| siemplify = SiemplifyAction() | ||
|
|
||
| siemplify.LOGGER.info("----------------- RRS - Test connection: Init -----------------") | ||
| rrsManager = ApiManager(siemplify) | ||
| siemplify.LOGGER.info("----------------- RRS - Test connection: Started -----------------") | ||
|
|
||
| try: | ||
| is_token_valid = rrsManager.is_token_valid() | ||
| siemplify.LOGGER.info(f"Ping: {is_token_valid=}") | ||
|
|
||
| status = EXECUTION_STATE_COMPLETED # used to flag back to siemplify system, the action final status | ||
| output_message = "Successfully connected to Ransomware Resilience server!" # human readable message, showed in UI as the action result | ||
| result_value = True # Set a simple result value, used for playbook if\else and placeholders. | ||
|
|
||
| except Exception as e: | ||
| output_message = f"Failed to connect to the Ransomware Resilience server! {e}" | ||
| siemplify.LOGGER.error(f"Connection to API failed, performing action {e}") | ||
| siemplify.LOGGER.exception(e) | ||
| status = EXECUTION_STATE_FAILED | ||
| result_value = False | ||
|
|
||
| siemplify.LOGGER.info("----------------- RRS - Test connection: End -----------------") | ||
|
|
||
| siemplify.LOGGER.info(f"Ping: \n status: {status}\n result_value: {result_value}\n output_message: {output_message}") | ||
| siemplify.end(output_message, result_value, status) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| name: Ping | ||
| description: Ping action to test connection to Ransomware resilience service. | ||
| integration_identifier: netapp-ransomware-resilience | ||
| parameters: [] | ||
| dynamic_results_metadata: | ||
| - result_example_path: null | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the Ping action is intended to return a JSON result (implied by References
|
||
| result_name: JsonResult | ||
| show_result: true | ||
| default_result_value: '' | ||
| creator: 5c86e1e4-dd8c-4181-8fc9-f5e8f008caae | ||
| script_result_name: ScriptResult | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| from __future__ import annotations | ||
| from soar_sdk.SiemplifyAction import SiemplifyAction | ||
| from soar_sdk.SiemplifyUtils import unix_now, convert_unixtime_to_datetime, output_handler | ||
| from soar_sdk.ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED,EXECUTION_STATE_TIMEDOUT | ||
| from ..core.ApiManager import ApiManager | ||
|
|
||
|
|
||
| @output_handler | ||
| def main(): | ||
| siemplify = SiemplifyAction() | ||
| siemplify.LOGGER.info("----------------- RRS - Take Snapshot: Init -----------------") | ||
| rrsManager = ApiManager(siemplify) | ||
| siemplify.LOGGER.info("----------------- RRS - Take Snapshot: Started -----------------") | ||
|
|
||
| snapshot_result = None | ||
| try: | ||
|
|
||
| # call take snapshot api | ||
| snapshot_result = rrsManager.take_snapshot() | ||
|
|
||
| status = EXECUTION_STATE_COMPLETED # used to flag back to siemplify system, the action final status | ||
| output_message = "Successfully triggered snapshot creation" # human readable message, showed in UI as the action result | ||
| result_value = True # Set a simple result value, used for playbook if\else and placeholders. | ||
|
|
||
| except Exception as e: | ||
| output_message = f"Failed to take snapshot. Error: {e}" | ||
| siemplify.LOGGER.error(f"Take Snapshot: Failed to take snapshot. Error: {e}") | ||
| siemplify.LOGGER.exception(e) | ||
| status = EXECUTION_STATE_FAILED | ||
| result_value = False | ||
| snapshot_result = {} | ||
|
|
||
| siemplify.LOGGER.info("----------------- RRS - Take Snapshot: End -----------------") | ||
| siemplify.LOGGER.info(f"Take Snapshot: \n status: {status}\n result_value: {result_value}\n output_message: {output_message}") | ||
|
|
||
| # Add result to action output. | ||
| siemplify.result.add_result_json(snapshot_result) | ||
| siemplify.end(output_message, result_value, status) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| name: Take Snapshot | ||
| description: Create volume snapshot | ||
| integration_identifier: netapp-ransomware-resilience | ||
| parameters: | ||
| - name: Volume ID | ||
| default_value: '' | ||
| type: string | ||
| description: Volume ID | ||
| is_mandatory: true | ||
| - name: Agent ID | ||
| default_value: '' | ||
| type: string | ||
| description: Console agent ID | ||
| is_mandatory: true | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The References
|
||
| - name: System ID | ||
| default_value: '' | ||
| type: string | ||
| description: Storage System ID | ||
| is_mandatory: true | ||
| dynamic_results_metadata: | ||
| - result_example_path: resources/take_snapshot_JsonResult_example.json | ||
| result_name: JsonResult | ||
| show_result: true | ||
| default_result_value: '' | ||
| creator: 5c86e1e4-dd8c-4181-8fc9-f5e8f008caae | ||
| script_result_name: ScriptResult | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| from __future__ import annotations | ||
| from soar_sdk.SiemplifyAction import SiemplifyAction | ||
| from soar_sdk.SiemplifyUtils import unix_now, convert_unixtime_to_datetime, output_handler | ||
| from soar_sdk.ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED,EXECUTION_STATE_TIMEDOUT | ||
| from ..core.ApiManager import ApiManager | ||
|
|
||
|
|
||
| @output_handler | ||
| def main(): | ||
| siemplify = SiemplifyAction() | ||
| siemplify.LOGGER.info("----------------- RRS - Volume Offline: Init -----------------") | ||
| rrsManager = ApiManager(siemplify) | ||
| siemplify.LOGGER.info("----------------- RRS - Volume Offline: Started -----------------") | ||
|
|
||
| volume_offline_result = None | ||
| try: | ||
|
|
||
| # call volume offline api | ||
| volume_offline_result = rrsManager.volume_offline() | ||
|
|
||
| status = EXECUTION_STATE_COMPLETED # used to flag back to siemplify system, the action final status | ||
| output_message = "Successfully took volume offline" # human readable message, showed in UI as the action result | ||
| result_value = True # Set a simple result value, used for playbook if\else and placeholders. | ||
|
|
||
| except Exception as e: | ||
| output_message = f"Failed to take volume offline. Error: {e}" | ||
| siemplify.LOGGER.error(f"Volume Offline: Failed to take volume offline. Error: {e}") | ||
| siemplify.LOGGER.exception(e) | ||
| status = EXECUTION_STATE_FAILED | ||
| result_value = False | ||
| volume_offline_result = {} | ||
|
|
||
| siemplify.LOGGER.info("----------------- RRS - Volume Offline: End -----------------") | ||
| siemplify.LOGGER.info(f"Volume Offline: \n status: {status}\n result_value: {result_value}\n output_message: {output_message}") | ||
|
|
||
| # Add result to action output. | ||
| siemplify.result.add_result_json(volume_offline_result) | ||
| siemplify.end(output_message, result_value, status) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| name: Volume Offline | ||
| description: Take volume offline | ||
| integration_identifier: netapp-ransomware-resilience | ||
| parameters: | ||
| - name: Volume ID | ||
| default_value: '' | ||
| type: string | ||
| description: ID of Volume | ||
| is_mandatory: true | ||
| - name: Agent ID | ||
| default_value: '' | ||
| type: string | ||
| description: Console Agent ID | ||
| is_mandatory: true | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The References
|
||
| - name: System ID | ||
| default_value: '' | ||
| type: string | ||
| description: System ID | ||
| is_mandatory: true | ||
| dynamic_results_metadata: | ||
| - result_example_path: resources/volume_offline_JsonResult_example.json | ||
| result_name: JsonResult | ||
| show_result: true | ||
| default_result_value: '' | ||
| creator: 5c86e1e4-dd8c-4181-8fc9-f5e8f008caae | ||
| script_result_name: ScriptResult | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please change actions file names to snake case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new integration is missing the required unit tests. The repository style guide mandates that all new features in the
content/response_integrations/**directory must include correspondingpytestunit tests to ensure production stability. Please add a test suite that covers the new actions and core logic, ensuring that network calls are mocked as per the guide's reference examples.References
content/response_integrations/**must include corresponding unit tests to ensure production stability. (link)