From 6b32cf730dd6430deeb8c19932a520346b2e2daa Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Fri, 31 Oct 2025 22:40:55 +0530 Subject: [PATCH 01/22] Initialize Azure Sentinel solution --- .../NetAppRPS_HighSeverity.yaml | 33 + .../NetAppRPS_MediumSeverity.yaml | 33 + .../NetAppRPS_DataConnector.json | 59 + .../azuredeploy_rps_dataconnector.json | 173 + .../NetAppRPS/Data/Solution_NetAppRps.json | 27 + Solutions/NetAppRPS/Package/3.0.0.zip | Bin 0 -> 18653 bytes .../NetAppRPS/Package/createUiDefinition.json | 169 + Solutions/NetAppRPS/Package/mainTemplate.json | 3582 +++++++++++++++++ .../NetAppRPS/Package/testParameters.json | 24 + .../NetApp-RPS-Auth-Playbook/azuredeploy.json | 341 ++ .../azuredeploy.parameters.json | 21 + .../RPS_Async_Poll_Playbook/azuredeploy.json | 481 +++ .../azuredeploy.parameters.json | 12 + .../RPS_Enrich_IP_Playbook/azuredeploy.json | 464 +++ .../azuredeploy.parameters.json | 15 + .../azuredeploy.json | 360 ++ .../azuredeploy.parameters.json | 12 + .../azuredeploy.json | 544 +++ .../azuredeploy.parameters.json | 15 + .../azuredeploy.json | 544 +++ .../azuredeploy.parameters.json | 15 + Solutions/NetAppRPS/SolutionMetadata.json | 27 + 22 files changed, 6951 insertions(+) create mode 100644 Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml create mode 100644 Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml create mode 100644 Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json create mode 100644 Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json create mode 100644 Solutions/NetAppRPS/Data/Solution_NetAppRps.json create mode 100644 Solutions/NetAppRPS/Package/3.0.0.zip create mode 100644 Solutions/NetAppRPS/Package/createUiDefinition.json create mode 100644 Solutions/NetAppRPS/Package/mainTemplate.json create mode 100644 Solutions/NetAppRPS/Package/testParameters.json create mode 100644 Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json create mode 100644 Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.parameters.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.parameters.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.parameters.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json create mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json create mode 100644 Solutions/NetAppRPS/SolutionMetadata.json diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml new file mode 100644 index 00000000000..e45ef6804d4 --- /dev/null +++ b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml @@ -0,0 +1,33 @@ +id: 33b9688b-2afb-442f-a3bb-fe2362717bb7 +name: NetApp RPS High Severity Alert +description: | + 'Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the rps_alerts_CL table for alerts with HIGH severity level.' +severity: High +status: Available +requiredDataConnectors: + - connectorId: NetAppRPSCustomLogsIngestion + dataTypes: + - rps_alerts_CL +suppressionDuration: PT5H +suppressionEnabled: false +query: | + rps_alerts_CL | where TimeGenerated > ago(1d) + | where severity == "HIGH" +alertDetailsOverride: + alertDisplayNameFormat: "{{description}}" + alertDescriptionFormat: "High severity alert detected from NetApp RPS: {{description}}" +customDetails: + Severity: severity + IncidentDetails: incident + ContextInfo: context +incidentConfiguration: + createIncident: true + groupingConfiguration: + enabled: false + reopenClosedIncident: false + lookbackDuration: PT5H + matchingMethod: AllEntities +eventGroupingSettings: + aggregationKind: AlertPerResult +version: 1.0.0 +kind: NRT \ No newline at end of file diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml new file mode 100644 index 00000000000..89f1e6efde5 --- /dev/null +++ b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml @@ -0,0 +1,33 @@ +id: be774c6e-7613-41db-b6e4-25975b680d24 +name: NetApp RPS Medium Severity Alert +description: | + 'Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the rps_alerts_CL table for alerts with MEDIUM severity level.' +severity: Medium +status: Available +requiredDataConnectors: + - connectorId: NetAppRPSCustomLogsIngestion + dataTypes: + - rps_alerts_CL +suppressionDuration: PT5H +suppressionEnabled: false +query: | + rps_alerts_CL | where TimeGenerated > ago(1d) + | where severity == "MEDIUM" +alertDetailsOverride: + alertDisplayNameFormat: "{{description}}" + alertDescriptionFormat: "Medium severity alert detected from NetApp RPS: {{description}}" +customDetails: + Severity: severity + IncidentDetails: incident + ContextInfo: context +incidentConfiguration: + createIncident: true + groupingConfiguration: + enabled: false + reopenClosedIncident: false + lookbackDuration: PT5H + matchingMethod: AllEntities +eventGroupingSettings: + aggregationKind: AlertPerResult +version: 1.0.0 +kind: NRT \ No newline at end of file diff --git a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json new file mode 100644 index 00000000000..7d8db44c9d4 --- /dev/null +++ b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json @@ -0,0 +1,59 @@ +{ + "id": "NetAppRPS", + "title": "NetAppRPS", + "publisher": "NetAppRPS", + "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", + "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "NetAppRPS", + "baseQuery": "rps_alerts_CL" + } + ], + "dataTypes": [ + { + "name": "rps_alerts_CL", + "lastDataReceivedQuery": "rps_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "sampleQueries": [ + { + "description": "Default Query", + "query": "rps_alerts_CL" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "rps_alerts_CL" + ] + } + ], + "availability": { + "status": 1, + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + } + ] + }, + "instructionSteps": [ + { + "title": "Azure Resource Manager (ARM) Template", + "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-netskope-azuredeploy)" + } + ] +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json b/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json new file mode 100644 index 00000000000..216231fdabc --- /dev/null +++ b/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json @@ -0,0 +1,173 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "workspaceResourceId": { + "type": "string", + "metadata": { + "description": "Specifies the Azure resource ID of the Log Analytics workspace to use." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Specifies the Object ID of the App registration to be used." + } + } + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2022-10-01", + "name": "[concat(parameters('workspaceResourceId'), '/rps_alerts_CL')]", + "properties": { + "description": "Custom log table for storing custom logs", + "retentionInDays": 30, + "schema": { + "name": "rps_alerts_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "severity", + "type": "string" + }, + { + "name": "incident", + "type": "dynamic" + }, + { + "name": "context", + "type": "dynamic" + } + ] + } + } + }, + { + "type": "Microsoft.Insights/dataCollectionEndpoints", + "name": "rps-alerts-dce", + "location": "[resourceGroup().location]", + "apiVersion": "2021-04-01", + "properties": { + "networkAcls": { + "publicNetworkAccess": "Enabled" + } + } + }, + { + "type": "Microsoft.Insights/dataCollectionRules", + "name": "rps-alerts-dcr", + "location": "[resourceGroup().location]", + "apiVersion": "2023-03-11", + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'rps_alerts_CL')]", + "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]" + ], + "properties": { + "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]", + "streamDeclarations": { + "Custom-MyTableRawData": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "severity", + "type": "string" + }, + { + "name": "incident", + "type": "dynamic" + }, + { + "name": "context", + "type": "dynamic" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceResourceId'))]", + "name": "[parameters('workspaceResourceId')]" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-rps_alerts_CL" + ], + "destinations": [ + "[parameters('workspaceResourceId')]" + ], + "transformKql": "source", + "outputStream": "Custom-rps_alerts_CL" + } + ] + } + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(resourceGroup().id, 'rps-alerts-dce', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", + "scope": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "principalId": "[parameters('principalId')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]" + ] + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(resourceGroup().id, 'rps-alerts-dcr', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", + "scope": "[resourceId('Microsoft.Insights/dataCollectionRules', 'rps-alerts-dcr')]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "principalId": "[parameters('principalId')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Insights/dataCollectionRules', 'rps-alerts-dcr')]" + ] + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(resourceGroup().id, 'rps_alerts_CL', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", + "scope": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'rps_alerts_CL')]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "principalId": "[parameters('principalId')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'rps_alerts_CL')]" + ] + } + ], + "outputs": { + "dataCollectionEndpointIngestion": { + "type": "string", + "value": "[reference('Microsoft.Insights/dataCollectionEndpoints/rps-alerts-dce', '2021-04-01').logsIngestion.endpoint]" + }, + "dataCollectionRuleImmutableId": { + "type": "string", + "value": "[reference('Microsoft.Insights/dataCollectionRules/rps-alerts-dcr', '2023-03-11').immutableId]" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Data/Solution_NetAppRps.json b/Solutions/NetAppRPS/Data/Solution_NetAppRps.json new file mode 100644 index 00000000000..e10bb5c726a --- /dev/null +++ b/Solutions/NetAppRPS/Data/Solution_NetAppRps.json @@ -0,0 +1,27 @@ +{ + "Name": "NetAppRPS", + "Author": "NetApp - support@netapp.com", + "title": "NetApp RPS", + "Description": "NetApp RPS (Ransomware Protection Service) - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.", + "logo": "", + "Data Connectors": [ + "Data Connectors/NetAppRPS_DataConnector.json" + ], + "Analytic Rules": [ + "Analytic Rules/NetAppRPS_HighSeverity.yaml", + "Analytic Rules/NetAppRPS_MediumSeverity.yaml" + ], + "Playbooks": [ + "Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json", + "Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json", + "Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json", + "Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json", + "Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json", + "Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json" + ], + "Version": "3.0.0", + "BasePath": "./Solutions/NetAppRPS/", + "Metadata": "SolutionMetadata.json", + "TemplateSpec": true, + "StaticDataConnectorIds": [] +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Package/3.0.0.zip b/Solutions/NetAppRPS/Package/3.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..f1297836cf135c11f6b80b976909dbdce6a2c521 GIT binary patch literal 18653 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 literal 0 HcmV?d00001 diff --git a/Solutions/NetAppRPS/Package/createUiDefinition.json b/Solutions/NetAppRPS/Package/createUiDefinition.json new file mode 100644 index 00000000000..2085688bf80 --- /dev/null +++ b/Solutions/NetAppRPS/Package/createUiDefinition.json @@ -0,0 +1,169 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "config": { + "isWizard": false, + "basics": { + "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/NetAppRPS/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nNetApp RPS (Ransomware Protection Service) - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.\n\n**Data Connectors:** 1, **Analytic Rules:** 2, **Playbooks:** 6\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "subscription": { + "resourceProviders": [ + "Microsoft.OperationsManagement/solutions", + "Microsoft.OperationalInsights/workspaces/providers/alertRules", + "Microsoft.Insights/workbooks", + "Microsoft.Logic/workflows" + ] + }, + "location": { + "metadata": { + "hidden": "Hiding location, we get it from the log analytics workspace" + }, + "visible": false + }, + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "getLAWorkspace", + "type": "Microsoft.Solutions.ArmApiControl", + "toolTip": "This filters by workspaces that exist in the Resource Group selected", + "condition": "[greater(length(resourceGroup().name),0)]", + "request": { + "method": "GET", + "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]" + } + }, + { + "name": "workspace", + "type": "Microsoft.Common.DropDown", + "label": "Workspace", + "placeholder": "Select a workspace", + "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected", + "constraints": { + "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", + "required": true + }, + "visible": true + } + ], + "steps": [ + { + "name": "dataconnectors", + "label": "Data Connectors", + "bladeTitle": "Data Connectors", + "elements": [ + { + "name": "dataconnectors1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This Solution installs the data connector for NetAppRPS. You can get NetAppRPS custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." + } + }, + { + "name": "dataconnectors-link1", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more about connecting data sources", + "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources" + } + } + } + ] + }, + { + "name": "analytics", + "label": "Analytics", + "subLabel": { + "preValidation": "Configure the analytics", + "postValidation": "Done" + }, + "bladeTitle": "Analytics", + "elements": [ + { + "name": "analytics-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view." + } + }, + { + "name": "analytics-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-detect-threats-custom?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef" + } + } + }, + { + "name": "analytic1", + "type": "Microsoft.Common.Section", + "label": "NetApp RPS High Severity Alert", + "elements": [ + { + "name": "analytic1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the rps_alerts_CL table for alerts with HIGH severity level." + } + } + ] + }, + { + "name": "analytic2", + "type": "Microsoft.Common.Section", + "label": "NetApp RPS Medium Severity Alert", + "elements": [ + { + "name": "analytic2-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the rps_alerts_CL table for alerts with MEDIUM severity level." + } + } + ] + } + ] + }, + { + "name": "playbooks", + "label": "Playbooks", + "subLabel": { + "preValidation": "Configure the playbooks", + "postValidation": "Done" + }, + "bladeTitle": "Playbooks", + "elements": [ + { + "name": "playbooks-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs the Playbook templates to help implement your Security Orchestration, Automation and Response (SOAR) operations. After installing the solution, these will be deployed under Playbook Templates in the Automation blade in Microsoft Sentinel. They can be configured and managed from the Manage solution view in Content Hub." + } + }, + { + "name": "playbooks-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-respond-threats-playbook?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef" + } + } + } + ] + } + ], + "outputs": { + "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", + "location": "[location()]", + "workspace": "[basics('workspace')]" + } + } +} diff --git a/Solutions/NetAppRPS/Package/mainTemplate.json b/Solutions/NetAppRPS/Package/mainTemplate.json new file mode 100644 index 00000000000..3778643e97c --- /dev/null +++ b/Solutions/NetAppRPS/Package/mainTemplate.json @@ -0,0 +1,3582 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "author": "NetApp - support@netapp.com", + "comments": "Solution template for NetAppRPS" + }, + "parameters": { + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + } + }, + "variables": { + "email": "support@netapp.com", + "_email": "[variables('email')]", + "_solutionName": "NetAppRPS", + "_solutionVersion": "3.0.0", + "solutionId": "netapp1234567890.netapp-rps-sentinel-solution", + "_solutionId": "[variables('solutionId')]", + "uiConfigId1": "NetAppRPS", + "_uiConfigId1": "[variables('uiConfigId1')]", + "dataConnectorContentId1": "NetAppRPS", + "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", + "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "_dataConnectorId1": "[variables('dataConnectorId1')]", + "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]", + "dataConnectorVersion1": "1.0.0", + "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]", + "analyticRuleObject1": { + "analyticRuleVersion1": "1.0.0", + "_analyticRulecontentId1": "33b9688b-2afb-442f-a3bb-fe2362717bb7", + "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '33b9688b-2afb-442f-a3bb-fe2362717bb7')]", + "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('33b9688b-2afb-442f-a3bb-fe2362717bb7')))]", + "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','33b9688b-2afb-442f-a3bb-fe2362717bb7','-', '1.0.0')))]" + }, + "analyticRuleObject2": { + "analyticRuleVersion2": "1.0.0", + "_analyticRulecontentId2": "be774c6e-7613-41db-b6e4-25975b680d24", + "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'be774c6e-7613-41db-b6e4-25975b680d24')]", + "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('be774c6e-7613-41db-b6e4-25975b680d24')))]", + "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','be774c6e-7613-41db-b6e4-25975b680d24','-', '1.0.0')))]" + }, + "NetApp-RPS-Auth-Playbook": "NetApp-RPS-Auth-Playbook", + "_NetApp-RPS-Auth-Playbook": "[variables('NetApp-RPS-Auth-Playbook')]", + "playbookVersion1": "1.0", + "playbookContentId1": "NetApp-RPS-Auth-Playbook", + "_playbookContentId1": "[variables('playbookContentId1')]", + "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]", + "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]", + "blanks": "[replace('b', 'b', '')]", + "RPS_Volume_Offline_Playbook": "RPS_Volume_Offline_Playbook", + "_RPS_Volume_Offline_Playbook": "[variables('RPS_Volume_Offline_Playbook')]", + "TemplateEmptyObject": "[json('{}')]", + "playbookVersion2": "1.0", + "playbookContentId2": "RPS_Volume_Offline_Playbook", + "_playbookContentId2": "[variables('playbookContentId2')]", + "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]", + "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]", + "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]", + "RPS_Async_Poll_Playbook": "RPS_Async_Poll_Playbook", + "_RPS_Async_Poll_Playbook": "[variables('RPS_Async_Poll_Playbook')]", + "playbookVersion3": "1.0", + "playbookContentId3": "RPS_Async_Poll_Playbook", + "_playbookContentId3": "[variables('playbookContentId3')]", + "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]", + "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]", + "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]", + "RPS_Volume_Snapshot_Playbook": "RPS_Volume_Snapshot_Playbook", + "_RPS_Volume_Snapshot_Playbook": "[variables('RPS_Volume_Snapshot_Playbook')]", + "playbookVersion4": "1.0", + "playbookContentId4": "RPS_Volume_Snapshot_Playbook", + "_playbookContentId4": "[variables('playbookContentId4')]", + "playbookId4": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId4'))]", + "playbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId4'))))]", + "_playbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId4'),'-', variables('playbookVersion4'))))]", + "RPS_Enrich_StorageVM_Playbook": "RPS_Enrich_StorageVM_Playbook", + "_RPS_Enrich_StorageVM_Playbook": "[variables('RPS_Enrich_StorageVM_Playbook')]", + "playbookVersion5": "1.0", + "playbookContentId5": "RPS_Enrich_StorageVM_Playbook", + "_playbookContentId5": "[variables('playbookContentId5')]", + "playbookId5": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId5'))]", + "playbookTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId5'))))]", + "_playbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId5'),'-', variables('playbookVersion5'))))]", + "RPS_Enrich_IP_Playbook": "RPS_Enrich_IP_Playbook", + "_RPS_Enrich_IP_Playbook": "[variables('RPS_Enrich_IP_Playbook')]", + "playbookVersion6": "1.0", + "playbookContentId6": "RPS_Enrich_IP_Playbook", + "_playbookContentId6": "[variables('playbookContentId6')]", + "playbookId6": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId6'))]", + "playbookTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId6'))))]", + "_playbookcontentProductId6": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId6'),'-', variables('playbookVersion6'))))]", + "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('dataConnectorTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS data connector with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorVersion1')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "GenericUI", + "properties": { + "connectorUiConfig": { + "id": "[variables('_uiConfigId1')]", + "title": "NetAppRPS", + "publisher": "NetAppRPS", + "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", + "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "NetAppRPS", + "baseQuery": "rps_alerts_CL" + } + ], + "dataTypes": [ + { + "name": "rps_alerts_CL", + "lastDataReceivedQuery": "rps_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "sampleQueries": [ + { + "description": "Default Query", + "query": "rps_alerts_CL" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "rps_alerts_CL" + ] + } + ], + "availability": { + "status": 1, + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + } + ] + }, + "instructionSteps": [ + { + "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-netskope-azuredeploy)", + "title": "Azure Resource Manager (ARM) Template" + } + ] + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "contentId": "[variables('_dataConnectorContentId1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion1')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_dataConnectorContentId1')]", + "contentKind": "DataConnector", + "displayName": "NetAppRPS", + "contentProductId": "[variables('_dataConnectorcontentProductId1')]", + "id": "[variables('_dataConnectorcontentProductId1')]", + "version": "[variables('dataConnectorVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "dependsOn": [ + "[variables('_dataConnectorId1')]" + ], + "location": "[parameters('workspace-location')]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "contentId": "[variables('_dataConnectorContentId1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion1')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "GenericUI", + "properties": { + "connectorUiConfig": { + "title": "NetAppRPS", + "publisher": "NetAppRPS", + "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "NetAppRPS", + "baseQuery": "rps_alerts_CL" + } + ], + "dataTypes": [ + { + "name": "rps_alerts_CL", + "lastDataReceivedQuery": "rps_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "rps_alerts_CL" + ] + } + ], + "sampleQueries": [ + { + "description": "Default Query", + "query": "rps_alerts_CL" + } + ], + "availability": { + "status": 1, + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + } + ] + }, + "instructionSteps": [ + { + "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-netskope-azuredeploy)", + "title": "Azure Resource Manager (ARM) Template" + } + ], + "id": "[variables('_uiConfigId1')]", + "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data." + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS_HighSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "apiVersion": "2023-02-01-preview", + "kind": "NRT", + "location": "[parameters('workspace-location')]", + "properties": { + "description": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the rps_alerts_CL table for alerts with HIGH severity level.", + "displayName": "NetApp RPS High Severity Alert", + "enabled": false, + "query": "rps_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"HIGH\"\n", + "severity": "High", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "status": "Available", + "requiredDataConnectors": [ + { + "connectorId": "NetAppRPSCustomLogsIngestion", + "dataTypes": [ + "rps_alerts_CL" + ] + } + ], + "eventGroupingSettings": { + "aggregationKind": "AlertPerResult" + }, + "customDetails": { + "ContextInfo": "context", + "IncidentDetails": "incident", + "Severity": "severity" + }, + "alertDetailsOverride": { + "alertDisplayNameFormat": "{{description}}", + "alertDescriptionFormat": "High severity alert detected from NetApp RPS: {{description}}" + }, + "incidentConfiguration": { + "groupingConfiguration": { + "lookbackDuration": "PT5H", + "matchingMethod": "AllEntities", + "enabled": false, + "reopenClosedIncident": false + }, + "createIncident": true + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]", + "properties": { + "description": "NetAppRPS Analytics Rule 1", + "parentId": "[variables('analyticRuleObject1').analyticRuleId1]", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "contentKind": "AnalyticsRule", + "displayName": "NetApp RPS High Severity Alert", + "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", + "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS_MediumSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "apiVersion": "2023-02-01-preview", + "kind": "NRT", + "location": "[parameters('workspace-location')]", + "properties": { + "description": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the rps_alerts_CL table for alerts with MEDIUM severity level.", + "displayName": "NetApp RPS Medium Severity Alert", + "enabled": false, + "query": "rps_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"MEDIUM\"\n", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "status": "Available", + "requiredDataConnectors": [ + { + "connectorId": "NetAppRPSCustomLogsIngestion", + "dataTypes": [ + "rps_alerts_CL" + ] + } + ], + "eventGroupingSettings": { + "aggregationKind": "AlertPerResult" + }, + "customDetails": { + "ContextInfo": "context", + "IncidentDetails": "incident", + "Severity": "severity" + }, + "alertDetailsOverride": { + "alertDisplayNameFormat": "{{description}}", + "alertDescriptionFormat": "Medium severity alert detected from NetApp RPS: {{description}}" + }, + "incidentConfiguration": { + "groupingConfiguration": { + "lookbackDuration": "PT5H", + "matchingMethod": "AllEntities", + "enabled": false, + "reopenClosedIncident": false + }, + "createIncident": true + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]", + "properties": { + "description": "NetAppRPS Analytics Rule 2", + "parentId": "[variables('analyticRuleObject2').analyticRuleId2]", + "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleObject2').analyticRuleVersion2]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "contentKind": "AnalyticsRule", + "displayName": "NetApp RPS Medium Severity Alert", + "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", + "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", + "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS-Auth-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion1')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the Logic App playbook to be created" + } + }, + "KeyVaultName": { + "type": "String", + "defaultValue": "[concat('rpskv', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "Name of the shared Key Vault to store NetApp RPS credentials" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + }, + "ClientId": { + "type": "securestring", + "metadata": { + "description": "Client ID for NetApp RPS API authentication" + } + }, + "ClientSecret": { + "type": "securestring", + "metadata": { + "description": "Client Secret for NetApp RPS API authentication" + } + }, + "AccountId": { + "type": "securestring", + "metadata": { + "description": "Account ID for NetApp RPS API authentication" + } + } + }, + "variables": { + "KeyVaultConnectionName": "[[concat('keyvault-', parameters('PlaybookName'))]", + "connection-5": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]", + "_connection-5": "[[variables('connection-5')]", + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2019-09-01", + "name": "[[parameters('KeyVaultName')]", + "location": "[[parameters('location')]", + "properties": { + "sku": { + "family": "A", + "name": "standard" + }, + "tenantId": "[[subscription().tenantId]", + "enabledForDeployment": false, + "enabledForDiskEncryption": false, + "enabledForTemplateDeployment": true, + "enableSoftDelete": true, + "softDeleteRetentionInDays": 90, + "enableRbacAuthorization": false + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/client-id')]", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[[parameters('ClientId')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/client-secret')]", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[[parameters('ClientSecret')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/account-id')]", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[[parameters('AccountId')]" + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[[variables('KeyVaultConnectionName')]", + "location": "[[parameters('location')]", + "kind": "V1", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "displayName": "[[variables('KeyVaultConnectionName')]", + "parameterValueSet": { + "name": "oauthMI", + "values": { + "vaultName": { + "value": "[[parameters('KeyVaultName')]" + } + } + }, + "api": { + "id": "[[variables('_connection-5')]" + } + } + }, + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "dependsOn": [ + "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "$connections": { + "type": "Object" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "properties": { + "account_id": { + "type": "string" + }, + "api_hostname": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "actions": { + "Get_Client_ID": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('client-id')}/value" + } + }, + "Get_Client_Secret": { + "runAfter": { + "Get_Client_ID": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('client-secret')}/value" + } + }, + "Get_Account_ID": { + "runAfter": { + "Get_Client_Secret": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('account-id')}/value" + } + }, + "HTTP_Token_Request": { + "runAfter": { + "Get_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://netapp-cloud-account.auth0.com/oauth/token", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{body('Get_Client_ID')?['value']}&client_secret=@{body('Get_Client_Secret')?['value']}&audience=https://api.cloud.netapp.com" + } + }, + "Response": { + "runAfter": { + "HTTP_Token_Request": [ + "Succeeded" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "access_token": "@{body('HTTP_Token_Request')?['access_token']}", + "token_type": "@{body('HTTP_Token_Request')?['token_type']}", + "expires_in": "@{body('HTTP_Token_Request')?['expires_in']}", + "account_id": "@{body('Get_Account_ID')?['value']}" + } + } + } + } + }, + "parameters": { + "$connections": { + "value": { + "keyvault": { + "connectionId": "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", + "connectionName": "[[variables('KeyVaultConnectionName')]", + "connectionProperties": { + "authentication": { + "type": "ManagedServiceIdentity" + } + }, + "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]" + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/add')]", + "dependsOn": [ + "[[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]", + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "accessPolicies": [ + { + "tenantId": "[[subscription().tenantId]", + "objectId": "[[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'Full').identity.principalId]", + "permissions": { + "secrets": [ + "get" + ] + } + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId1'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId1')]", + "contentId": "[variables('_playbookContentId1')]", + "kind": "Playbook", + "version": "[variables('playbookVersion1')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp RPS Authentication Playbook", + "description": "This playbook creates a shared Key Vault for NetApp RPS credentials and provides authentication services to all NetApp RPS playbooks in the solution.", + "prerequisites": [ + "1. Valid client_id, client_secret, and account_id for NetApp RPS API authentication", + "2. API endpoint that accepts OAuth2 client credentials flow" + ], + "postDeployment": [ + "1. Update the client_id, client_secret, and account_id values in the Key Vault", + "2. Test the Logic App to ensure proper token retrieval", + "3. The Key Vault created by this playbook will be shared across all NetApp RPS playbooks", + "4. Other playbooks will call this Auth playbook to obtain authentication tokens" + ], + "lastUpdateTime": "2025-09-17T00:00:00Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Authentication" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId1')]", + "contentKind": "Playbook", + "displayName": "NetAppRPS-Auth-Playbook", + "contentProductId": "[variables('_playbookcontentProductId1')]", + "id": "[variables('_playbookcontentProductId1')]", + "version": "[variables('playbookVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName2')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS-Volume-Offline-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion2')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Volume-Offline-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "NetAppRPSAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp RPS async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "volume_id": { + "type": "string" + }, + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + }, + "poll": { + "type": "boolean" + } + }, + "required": [ + "volume_id", + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "VolumeId", + "type": "string", + "value": "@triggerBody()?['volume_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "DoPoll", + "type": "boolean", + "value": "@coalesce(triggerBody()?['poll'], true)" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobId", + "type": "string" + }, + { + "name": "JobAgentId", + "type": "string" + }, + { + "name": "PollResponse", + "type": "object", + "value": "[variables('TemplateEmptyObject')]" + }, + { + "name": "SubmissionStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Submit_Volume_Offline": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-volume-offline", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "Content-Type": "application/json", + "accept": "application/json" + }, + "body": { + "volume_id": "@variables('VolumeId')", + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Submission_Status_Code": { + "runAfter": { + "Submit_Volume_Offline": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SubmissionStatusCode", + "value": "@outputs('Submit_Volume_Offline')['statusCode']" + } + }, + "Parse_Submission_Response": { + "runAfter": { + "Capture_Submission_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Submit_Volume_Offline')", + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + }, + "Store_JobId": { + "runAfter": { + "Parse_Submission_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobId", + "value": "@body('Parse_Submission_Response')?['job_id']" + } + }, + "Store_Job_AgentId": { + "runAfter": { + "Store_JobId": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobAgentId", + "value": "@body('Parse_Submission_Response')?['agent_id']" + } + }, + "Check_If_Should_Poll": { + "runAfter": { + "Store_Job_AgentId": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@variables('DoPoll')", + true + ] + }, + { + "or": [ + { + "equals": [ + "@variables('SubmissionStatusCode')", + 200 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 201 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 202 + ] + } + ] + }, + { + "not": { + "equals": [ + "@variables('JobId')", + "" + ] + } + } + ] + }, + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@variables('JobId')", + "agent_id": "@variables('JobAgentId')", + "system_id": "@variables('SystemId')", + "source": "ontap", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_volume_id": "@variables('VolumeId')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + } + } + }, + "Parse_Poll_Response": { + "runAfter": { + "Check_If_Should_Poll": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Async_Poll_Playbook')", + "schema": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "jobId": { + "type": "string" + }, + "success": { + "type": "boolean" + } + } + } + } + }, + "Store_Poll_Response": { + "runAfter": { + "Parse_Poll_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PollResponse", + "value": "@body('Parse_Poll_Response')" + } + }, + "Return_Response": { + "runAfter": { + "Store_Poll_Response": [ + "Succeeded", + "Skipped" + ], + "Check_If_Should_Poll": [ + "Succeeded" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Submit_Volume_Offline": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'Failed submitting volume offline request', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'submit', 'success'))", + "submission": { + "statusCode": "@variables('SubmissionStatusCode')", + "jobId": "@variables('JobId')", + "raw": "@body('Submit_Volume_Offline')", + "details": "@if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), body('Submit_Volume_Offline'), null)" + }, + "polling": { + "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", + "playbook": "@parameters('asyncPollPlaybookName')", + "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", + "jobResponse": "@variables('PollResponse')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId2'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId2')]", + "contentId": "[variables('_playbookContentId2')]", + "kind": "Playbook", + "version": "[variables('playbookVersion2')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp RPS Volume Offline Playbook", + "description": "This playbook takes a NetApp volume offline using the updated NetApp RPS take-volume-offline API endpoint and optionally polls for completion.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. NetApp RPS Async Poll Playbook must be deployed first", + "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "4. Caller must provide volume_id, agent_id, and system_id parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Ensure the Async Poll Playbook is working correctly", + "3. Test the volume offline functionality with valid volume_id, agent_id, and system_id", + "4. Verify the new take-volume-offline API endpoint is accessible" + ], + "lastUpdateTime": "2025-09-17T00:00:00Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Volume", + "Offline" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId2')]", + "contentKind": "Playbook", + "displayName": "NetAppRPS-Volume-Offline-Playbook", + "contentProductId": "[variables('_playbookcontentProductId2')]", + "id": "[variables('_playbookcontentProductId2')]", + "version": "[variables('playbookVersion2')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName3')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS-Async-Poll-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion3')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "description": "The NetApp RPS job ID to poll" + }, + "agent_id": { + "type": "string", + "description": "NetApp agent ID" + }, + "system_id": { + "type": "string", + "description": "System ID for the working environment" + }, + "source": { + "type": "string", + "description": "Job source type" + }, + "caller_info": { + "type": "object", + "description": "Optional caller information for tracking" + } + }, + "required": [ + "job_id", + "agent_id", + "system_id", + "source" + ] + } + } + } + }, + "actions": { + "Initialize_variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "JobId", + "type": "string", + "value": "@triggerBody()?['job_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "Source", + "type": "string", + "value": "@triggerBody()?['source']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "PollCount", + "type": "integer", + "value": 0 + }, + { + "name": "MaxPollAttempts", + "type": "integer", + "value": 10 + }, + { + "name": "PollIntervalSeconds", + "type": "integer", + "value": 30 + }, + { + "name": "JobStatus", + "type": "string", + "value": "pending" + }, + { + "name": "JobResponse", + "type": "object", + "value": "[variables('TemplateEmptyObject')]" + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + } + } + }, + "Set_Account_ID": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Call_Auth_Playbook')?['account_id']" + } + }, + "Initial_Status_Check": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 2, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT10S" + }, + "timeout": "PT30S" + } + }, + "Update_Initial_Status": { + "runAfter": { + "Initial_Status_Check": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "@body('Initial_Status_Check')?['status']" + } + }, + "Update_Initial_Response": { + "runAfter": { + "Update_Initial_Status": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobResponse", + "value": "@body('Initial_Status_Check')" + } + }, + "Polling_Loop": { + "runAfter": { + "Update_Initial_Response": [ + "Succeeded" + ] + }, + "type": "Until", + "expression": "@or(or(equals(variables('JobStatus'), 'SUCCESS'), equals(variables('JobStatus'), 'success')), or(equals(variables('JobStatus'), 'FAILED'), equals(variables('JobStatus'), 'failed')), greater(variables('PollCount'), variables('MaxPollAttempts')))", + "limit": { + "count": 10, + "timeout": "PT6M" + }, + "actions": { + "Increment_Poll_Count": { + "type": "IncrementVariable", + "inputs": { + "name": "PollCount", + "value": 1 + } + }, + "Check_Job_Status": { + "runAfter": { + "Increment_Poll_Count": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 2, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT10S" + }, + "timeout": "PT30S" + } + }, + "Update_Job_Status": { + "runAfter": { + "Check_Job_Status": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "@body('Check_Job_Status')?['status']" + } + }, + "Handle_Status_Check_Failure": { + "runAfter": { + "Check_Job_Status": [ + "Failed", + "TimedOut" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "failed" + } + }, + "Update_Job_Response": { + "runAfter": { + "Update_Job_Status": [ + "Succeeded" + ], + "Handle_Status_Check_Failure": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobResponse", + "value": "@body('Check_Job_Status')" + } + }, + "Wait_If_Needed": { + "runAfter": { + "Update_Job_Response": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "not": { + "or": [ + { + "equals": [ + "@variables('JobStatus')", + "SUCCESS" + ] + }, + { + "equals": [ + "@variables('JobStatus')", + "success" + ] + } + ] + } + }, + "actions": { + "Wait_Before_Retry": { + "type": "Wait", + "inputs": { + "interval": { + "count": "@variables('PollIntervalSeconds')", + "unit": "Second" + } + } + } + } + } + } + }, + "Check_Final_Status": { + "runAfter": { + "Polling_Loop": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "or": [ + { + "equals": [ + "@variables('JobStatus')", + "SUCCESS" + ] + }, + { + "equals": [ + "@variables('JobStatus')", + "success" + ] + } + ] + } + ] + }, + "actions": { + "Success_Response": { + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": true, + "job_id": "@variables('JobId')", + "status": "@variables('JobStatus')", + "poll_count": "@variables('PollCount')", + "data": "@variables('JobResponse')", + "caller_info": "@triggerBody()?['caller_info']" + } + } + } + }, + "else": { + "actions": { + "Error_Response": { + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 408, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": false, + "error": "Job polling timeout or failed", + "job_id": "@variables('JobId')", + "status": "@variables('JobStatus')", + "poll_count": "@variables('PollCount')", + "max_attempts": "@variables('MaxPollAttempts')", + "data": "@variables('JobResponse')", + "caller_info": "@triggerBody()?['caller_info']" + } + } + } + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId3'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId3')]", + "contentId": "[variables('_playbookContentId3')]", + "kind": "Playbook", + "version": "[variables('playbookVersion3')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp RPS Async Poll Playbook", + "description": "This playbook polls NetApp RPS job status asynchronously until completion or timeout using the updated job status API endpoint.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "3. Caller must provide job_id, agent_id, system_id, and source parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Test the polling functionality with a valid job ID" + ], + "lastUpdateTime": "2025-09-17T00:00:00Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Async", + "Polling" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId3')]", + "contentKind": "Playbook", + "displayName": "NetAppRPS-Async-Poll-Playbook", + "contentProductId": "[variables('_playbookcontentProductId3')]", + "id": "[variables('_playbookcontentProductId3')]", + "version": "[variables('playbookVersion3')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName4')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS-Volume-Snapshot-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion4')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Volume-Snapshot-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "NetAppRPSAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp RPS async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "volume_id": { + "type": "string" + }, + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + }, + "poll": { + "type": "boolean" + } + }, + "required": [ + "volume_id", + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "VolumeId", + "type": "string", + "value": "@triggerBody()?['volume_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "DoPoll", + "type": "boolean", + "value": "@coalesce(triggerBody()?['poll'], true)" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobId", + "type": "string" + }, + { + "name": "JobAgentId", + "type": "string" + }, + { + "name": "PollResponse", + "type": "object", + "value": "[variables('TemplateEmptyObject')]" + }, + { + "name": "SubmissionStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Submit_Volume_Snapshot": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-snapshot", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "Content-Type": "application/json", + "accept": "application/json" + }, + "body": { + "volume_id": "@variables('VolumeId')", + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Submission_Status_Code": { + "runAfter": { + "Submit_Volume_Snapshot": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SubmissionStatusCode", + "value": "@outputs('Submit_Volume_Snapshot')['statusCode']" + } + }, + "Parse_Submission_Response": { + "runAfter": { + "Capture_Submission_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Submit_Volume_Snapshot')", + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + }, + "Store_JobId": { + "runAfter": { + "Parse_Submission_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobId", + "value": "@body('Parse_Submission_Response')?['job_id']" + } + }, + "Store_Job_AgentId": { + "runAfter": { + "Store_JobId": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobAgentId", + "value": "@body('Parse_Submission_Response')?['agent_id']" + } + }, + "Check_If_Should_Poll": { + "runAfter": { + "Store_Job_AgentId": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@variables('DoPoll')", + true + ] + }, + { + "or": [ + { + "equals": [ + "@variables('SubmissionStatusCode')", + 200 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 201 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 202 + ] + } + ] + }, + { + "not": { + "equals": [ + "@variables('JobId')", + "" + ] + } + } + ] + }, + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@variables('JobId')", + "agent_id": "@variables('JobAgentId')", + "system_id": "@variables('SystemId')", + "source": "ontap", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_volume_id": "@variables('VolumeId')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + } + } + }, + "Parse_Poll_Response": { + "runAfter": { + "Check_If_Should_Poll": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Async_Poll_Playbook')", + "schema": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "jobId": { + "type": "string" + }, + "success": { + "type": "boolean" + } + } + } + } + }, + "Store_Poll_Response": { + "runAfter": { + "Parse_Poll_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PollResponse", + "value": "@body('Parse_Poll_Response')" + } + }, + "Return_Response": { + "runAfter": { + "Store_Poll_Response": [ + "Succeeded", + "Skipped" + ], + "Check_If_Should_Poll": [ + "Succeeded" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Submit_Volume_Snapshot": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'Failed submitting volume snapshot request', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'submit', 'success'))", + "submission": { + "statusCode": "@variables('SubmissionStatusCode')", + "jobId": "@variables('JobId')", + "raw": "@body('Submit_Volume_Snapshot')", + "details": "@if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), body('Submit_Volume_Snapshot'), null)" + }, + "polling": { + "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", + "playbook": "@parameters('asyncPollPlaybookName')", + "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", + "jobResponse": "@variables('PollResponse')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId4'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId4')]", + "contentId": "[variables('_playbookContentId4')]", + "kind": "Playbook", + "version": "[variables('playbookVersion4')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp RPS Volume Snapshot Playbook", + "description": "This playbook creates a NetApp volume snapshot using the updated NetApp RPS take-snapshot API endpoint and optionally polls for completion.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. NetApp RPS Async Poll Playbook must be deployed first", + "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "4. Caller must provide volume_id, agent_id, and system_id parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Ensure the Async Poll Playbook is working correctly", + "3. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id", + "4. Verify the new take-snapshot API endpoint is accessible" + ], + "lastUpdateTime": "2025-09-22T00:00:00Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Volume", + "Snapshot" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId4')]", + "contentKind": "Playbook", + "displayName": "NetAppRPS-Volume-Snapshot-Playbook", + "contentProductId": "[variables('_playbookcontentProductId4')]", + "id": "[variables('_playbookcontentProductId4')]", + "version": "[variables('playbookVersion4')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName5')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS-Enrich-StorageVM-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion5')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Enrich-StorageVM-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + } + }, + "required": [ + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "StorageVMData", + "type": "array" + }, + { + "name": "EnrichmentStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Get_StorageVM_Data": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Enrichment_Status_Code": { + "runAfter": { + "Get_StorageVM_Data": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "EnrichmentStatusCode", + "value": "@outputs('Get_StorageVM_Data')['statusCode']" + } + }, + "Parse_StorageVM_Response": { + "runAfter": { + "Capture_Enrichment_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Get_StorageVM_Data')", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "volume_uuid": { + "type": "string" + }, + "volume_name": { + "type": "string" + }, + "svm_name": { + "type": "string" + } + } + } + } + } + }, + "Store_StorageVM_Data": { + "runAfter": { + "Parse_StorageVM_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "StorageVMData", + "value": "@body('Parse_StorageVM_Response')" + } + }, + "Return_Response": { + "runAfter": { + "Store_StorageVM_Data": [ + "Succeeded", + "Skipped" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Get_StorageVM_Data": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'Failed retrieving storage VM data', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'enrichment', 'success'))", + "account_id": "@variables('AccountId')", + "enrichment": { + "statusCode": "@variables('EnrichmentStatusCode')", + "storage_vms": "@variables('StorageVMData')", + "count": "@length(variables('StorageVMData'))", + "raw": "@body('Get_StorageVM_Data')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId5'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId5')]", + "contentId": "[variables('_playbookContentId5')]", + "kind": "Playbook", + "version": "[variables('playbookVersion5')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp RPS Enrich StorageVM Playbook", + "description": "This playbook enriches storage data by calling the updated NetApp RPS enrich storage API endpoint.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "3. Caller must provide agent_id and system_id parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Test the storage enrichment functionality with valid agent_id and system_id" + ], + "lastUpdateTime": "2025-09-23T00:00:00Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "StorageVM", + "Enrich" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId5')]", + "contentKind": "Playbook", + "displayName": "NetAppRPS-Enrich-StorageVM-Playbook", + "contentProductId": "[variables('_playbookcontentProductId5')]", + "id": "[variables('_playbookcontentProductId5')]", + "version": "[variables('playbookVersion5')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName6')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetAppRPS-Enrich-IP-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion6')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Enrich-IP-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "NetAppRPSAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp RPS async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[[parameters('NetAppRPSAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "ip_address": { + "type": "string" + }, + "callbackData": { + "type": "object" + } + }, + "required": [ + "ip_address" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "IpAddress", + "type": "string", + "value": "@triggerBody()?['ip_address']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobIds", + "type": "array" + }, + { + "name": "PollingResults", + "type": "array" + }, + { + "name": "EnrichmentStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT30S" + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Get_IP_NetworkInterfaces": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/ip-address", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "accept": "application/json", + "Content-Type": "application/json" + }, + "body": { + "ip_address": "@{variables('IpAddress')}" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT45S" + } + }, + "Capture_Enrichment_Status_Code": { + "runAfter": { + "Get_IP_NetworkInterfaces": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "EnrichmentStatusCode", + "value": "@outputs('Get_IP_NetworkInterfaces')['statusCode']" + } + }, + "Parse_JobIds_Response": { + "runAfter": { + "Capture_Enrichment_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Get_IP_NetworkInterfaces')", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + } + }, + "Extract_Job_IDs": { + "runAfter": { + "Parse_JobIds_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobIds", + "value": "@body('Parse_JobIds_Response')" + } + }, + "Poll_All_Jobs": { + "runAfter": { + "Extract_Job_IDs": [ + "Succeeded" + ] + }, + "type": "Foreach", + "foreach": "@variables('JobIds')", + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@item()?['job_id']", + "agent_id": "@item()?['agent_id']", + "system_id": "default", + "source": "@item()?['source']", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_ip": "@variables('IpAddress')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT90S" + } + }, + "Add_Poll_Result": { + "runAfter": { + "Call_Async_Poll_Playbook": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "PollingResults", + "value": { + "job_id": "@item()?['job_id']", + "poll_response": "@body('Call_Async_Poll_Playbook')", + "original_job_info": "@item()" + } + } + }, + "Add_Failed_Poll_Result": { + "runAfter": { + "Call_Async_Poll_Playbook": [ + "Failed", + "TimedOut" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "PollingResults", + "value": { + "job_id": "@item()?['job_id']", + "poll_response": { + "success": false, + "error": "Failed to poll job or timeout occurred" + }, + "original_job_info": "@item()" + } + } + } + }, + "runtimeConfiguration": { + "concurrency": { + "repetitions": 1 + } + } + }, + "Return_Response": { + "runAfter": { + "Poll_All_Jobs": [ + "Succeeded", + "Skipped" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Get_IP_NetworkInterfaces": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'Failed retrieving IP network interfaces data', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'enrichment', 'success'))", + "account_id": "@variables('AccountId')", + "ip_address": "@variables('IpAddress')", + "enrichment": { + "statusCode": "@variables('EnrichmentStatusCode')", + "job_ids_count": "@length(variables('JobIds'))", + "polling_results_count": "@length(variables('PollingResults'))", + "original_jobs": "@variables('JobIds')", + "polling_results": "@variables('PollingResults')", + "raw_initial_response": "@body('Get_IP_NetworkInterfaces')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId6'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId6')]", + "contentId": "[variables('_playbookContentId6')]", + "kind": "Playbook", + "version": "[variables('playbookVersion6')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp RPS Enrich IP Playbook", + "description": "This playbook enriches IP data by calling the updated NetApp RPS enrich IP address API endpoint and asynchronously polls multiple job results.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. NetApp RPS Async Poll Playbook must be deployed", + "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "4. Caller must provide ip_address parameter" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Ensure the Async Poll Playbook is deployed and functional", + "3. Test the IP enrichment functionality with valid IP address", + "4. Verify the new POST API endpoint is accessible and returns job information with agent_id" + ], + "lastUpdateTime": "2025-09-26T00:00:00Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "IP", + "Enrich", + "NetworkInterface" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId6')]", + "contentKind": "Playbook", + "displayName": "NetAppRPS-Enrich-IP-Playbook", + "contentProductId": "[variables('_playbookcontentProductId6')]", + "id": "[variables('_playbookcontentProductId6')]", + "version": "[variables('playbookVersion6')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "apiVersion": "2023-04-01-preview", + "location": "[parameters('workspace-location')]", + "properties": { + "version": "3.0.0", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "displayName": "NetAppRPS", + "publisherDisplayName": "NetApp", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

NetApp RPS (Ransomware Protection Service) - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.

\n

Data Connectors: 1, Analytic Rules: 2, Playbooks: 6

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "contentKind": "Solution", + "contentProductId": "[variables('_solutioncontentProductId')]", + "id": "[variables('_solutioncontentProductId')]", + "icon": "", + "contentId": "[variables('_solutionId')]", + "parentId": "[variables('_solutionId')]", + "source": { + "kind": "Solution", + "name": "NetAppRPS", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId1')]", + "version": "[variables('dataConnectorVersion1')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_NetApp-RPS-Auth-Playbook')]", + "version": "[variables('playbookVersion1')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_RPS_Volume_Offline_Playbook')]", + "version": "[variables('playbookVersion2')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_RPS_Async_Poll_Playbook')]", + "version": "[variables('playbookVersion3')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_RPS_Volume_Snapshot_Playbook')]", + "version": "[variables('playbookVersion4')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_RPS_Enrich_StorageVM_Playbook')]", + "version": "[variables('playbookVersion5')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_RPS_Enrich_IP_Playbook')]", + "version": "[variables('playbookVersion6')]" + } + ] + }, + "firstPublishDate": "2025-08-28", + "lastPublishDate": "2025-08-28", + "providers": [ + "NetApp" + ], + "categories": { + "domains": [ + "Security - Ransomware Protection", + "Storage" + ] + } + }, + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + } + ], + "outputs": {} +} diff --git a/Solutions/NetAppRPS/Package/testParameters.json b/Solutions/NetAppRPS/Package/testParameters.json new file mode 100644 index 00000000000..e55ec41a9ac --- /dev/null +++ b/Solutions/NetAppRPS/Package/testParameters.json @@ -0,0 +1,24 @@ +{ + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + } +} diff --git a/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json b/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json new file mode 100644 index 00000000000..f47fea8fe37 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json @@ -0,0 +1,341 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "NetApp RPS Authentication Playbook", + "description": "This playbook creates a shared Key Vault for NetApp RPS credentials and provides authentication services to all NetApp RPS playbooks in the solution.", + "prerequisites": [ + "1. Valid client_id, client_secret, and account_id for NetApp RPS API authentication", + "2. API endpoint that accepts OAuth2 client credentials flow" + ], + "postDeployment": [ + "1. Update the client_id, client_secret, and account_id values in the Key Vault", + "2. Test the Logic App to ensure proper token retrieval", + "3. The Key Vault created by this playbook will be shared across all NetApp RPS playbooks", + "4. Other playbooks will call this Auth playbook to obtain authentication tokens" + ], + "lastUpdateTime": "2025-09-17T00:00:00.000Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Authentication" + ], + "support": { + "tier": "Community" + }, + "author": { + "name": "NetApp" + } + }, + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the Logic App playbook to be created" + } + }, + "KeyVaultName": { + "type": "String", + "defaultValue": "[concat('rpskv', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "Name of the shared Key Vault to store NetApp RPS credentials" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + }, + "ClientId": { + "type": "securestring", + "metadata": { + "description": "Client ID for NetApp RPS API authentication" + } + }, + "ClientSecret": { + "type": "securestring", + "metadata": { + "description": "Client Secret for NetApp RPS API authentication" + } + }, + "AccountId": { + "type": "securestring", + "metadata": { + "description": "Account ID for NetApp RPS API authentication" + } + } + }, + "variables": { + "KeyVaultConnectionName": "[concat('keyvault-', parameters('PlaybookName'))]" + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2019-09-01", + "name": "[parameters('KeyVaultName')]", + "location": "[parameters('location')]", + "properties": { + "sku": { + "family": "A", + "name": "standard" + }, + "tenantId": "[subscription().tenantId]", + "enabledForDeployment": false, + "enabledForDiskEncryption": false, + "enabledForTemplateDeployment": true, + "enableSoftDelete": true, + "softDeleteRetentionInDays": 90, + "enableRbacAuthorization": false + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[concat(parameters('KeyVaultName'), '/client-id')]", + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[parameters('ClientId')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[concat(parameters('KeyVaultName'), '/client-secret')]", + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[parameters('ClientSecret')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[concat(parameters('KeyVaultName'), '/account-id')]", + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[parameters('AccountId')]" + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[variables('KeyVaultConnectionName')]", + "location": "[parameters('location')]", + "kind": "V1", + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "displayName": "[variables('KeyVaultConnectionName')]", + "parameterValueSet": { + "name": "oauthMI", + "values": { + "vaultName": { + "value": "[parameters('KeyVaultName')]" + } + } + }, + "api": { + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]" + } + } + }, + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('PlaybookName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", + "[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "$connections": { + "defaultValue": {}, + "type": "Object" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "properties": { + "account_id": { + "type": "string" + }, + "api_hostname": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "actions": { + "Get_Client_ID": { + "runAfter": {}, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('client-id')}/value" + } + }, + "Get_Client_Secret": { + "runAfter": { + "Get_Client_ID": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('client-secret')}/value" + } + }, + "Get_Account_ID": { + "runAfter": { + "Get_Client_Secret": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('account-id')}/value" + } + }, + "HTTP_Token_Request": { + "runAfter": { + "Get_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://netapp-cloud-account.auth0.com/oauth/token", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{body('Get_Client_ID')?['value']}&client_secret=@{body('Get_Client_Secret')?['value']}&audience=https://api.cloud.netapp.com" + } + }, + "Response": { + "runAfter": { + "HTTP_Token_Request": [ + "Succeeded" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "access_token": "@{body('HTTP_Token_Request')?['access_token']}", + "token_type": "@{body('HTTP_Token_Request')?['token_type']}", + "expires_in": "@{body('HTTP_Token_Request')?['expires_in']}", + "account_id": "@{body('Get_Account_ID')?['value']}" + } + } + } + }, + "outputs": {} + }, + "parameters": { + "$connections": { + "value": { + "keyvault": { + "connectionId": "[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", + "connectionName": "[variables('KeyVaultConnectionName')]", + "connectionProperties": { + "authentication": { + "type": "ManagedServiceIdentity" + } + }, + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]" + } + } + } + } + } + }, + { + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2019-09-01", + "name": "[concat(parameters('KeyVaultName'), '/add')]", + "dependsOn": [ + "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]", + "[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "accessPolicies": [ + { + "tenantId": "[subscription().tenantId]", + "objectId": "[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'Full').identity.principalId]", + "permissions": { + "secrets": [ + "get" + ] + } + } + ] + } + } + ], + "outputs": { + "PlaybookName": { + "type": "string", + "value": "[parameters('PlaybookName')]" + }, + "PlaybookResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]" + }, + "KeyVaultName": { + "type": "string", + "value": "[parameters('KeyVaultName')]" + }, + "KeyVaultResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..90ee242aad8 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetAppRPS-Auth-Playbook" + }, + "KeyVaultName": { + "value": "[concat('rpskv', uniqueString(resourceGroup().id))]" + }, + "ClientId": { + "value": "YOUR_CLIENT_ID_HERE" + }, + "ClientSecret": { + "value": "YOUR_CLIENT_SECRET_HERE" + }, + "AccountId": { + "value": "YOUR_ACCOUNT_ID_HERE" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json b/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json new file mode 100644 index 00000000000..1646a508eaa --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json @@ -0,0 +1,481 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "NetApp RPS Async Poll Playbook", + "description": "This playbook polls NetApp RPS job status asynchronously until completion or timeout using the updated job status API endpoint.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "3. Caller must provide job_id, agent_id, system_id, and source parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Test the polling functionality with a valid job ID" + ], + "lastUpdateTime": "2025-09-17T00:00:00.000Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Async", + "Polling" + ], + "support": { + "tier": "Community" + }, + "author": { + "name": "NetApp" + } + }, + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('PlaybookName')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "description": "The NetApp RPS job ID to poll" + }, + "agent_id": { + "type": "string", + "description": "NetApp agent ID" + }, + "system_id": { + "type": "string", + "description": "System ID for the working environment" + }, + "source": { + "type": "string", + "description": "Job source type" + }, + "caller_info": { + "type": "object", + "description": "Optional caller information for tracking" + } + }, + "required": [ + "job_id", + "agent_id", + "system_id", + "source" + ] + } + } + } + }, + "actions": { + "Initialize_variables": { + "runAfter": {}, + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "JobId", + "type": "string", + "value": "@triggerBody()?['job_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "Source", + "type": "string", + "value": "@triggerBody()?['source']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "PollCount", + "type": "integer", + "value": 0 + }, + { + "name": "MaxPollAttempts", + "type": "integer", + "value": 10 + }, + { + "name": "PollIntervalSeconds", + "type": "integer", + "value": 30 + }, + { + "name": "JobStatus", + "type": "string", + "value": "pending" + }, + { + "name": "JobResponse", + "type": "object", + "value": {} + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + } + } + }, + "Set_Account_ID": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Call_Auth_Playbook')?['account_id']" + } + }, + "Initial_Status_Check": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 2, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT10S" + }, + "timeout": "PT30S" + } + }, + "Update_Initial_Status": { + "runAfter": { + "Initial_Status_Check": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "@body('Initial_Status_Check')?['status']" + } + }, + "Update_Initial_Response": { + "runAfter": { + "Update_Initial_Status": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobResponse", + "value": "@body('Initial_Status_Check')" + } + }, + "Polling_Loop": { + "runAfter": { + "Update_Initial_Response": [ + "Succeeded" + ] + }, + "type": "Until", + "expression": "@or(or(equals(variables('JobStatus'), 'SUCCESS'), equals(variables('JobStatus'), 'success')), or(equals(variables('JobStatus'), 'FAILED'), equals(variables('JobStatus'), 'failed')), greater(variables('PollCount'), variables('MaxPollAttempts')))", + "limit": { + "count": 10, + "timeout": "PT6M" + }, + "actions": { + "Increment_Poll_Count": { + "runAfter": {}, + "type": "IncrementVariable", + "inputs": { + "name": "PollCount", + "value": 1 + } + }, + "Check_Job_Status": { + "runAfter": { + "Increment_Poll_Count": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 2, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT10S" + }, + "timeout": "PT30S" + } + }, + "Update_Job_Status": { + "runAfter": { + "Check_Job_Status": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "@body('Check_Job_Status')?['status']" + } + }, + "Handle_Status_Check_Failure": { + "runAfter": { + "Check_Job_Status": [ + "Failed", + "TimedOut" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "failed" + } + }, + "Update_Job_Response": { + "runAfter": { + "Update_Job_Status": [ + "Succeeded" + ], + "Handle_Status_Check_Failure": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobResponse", + "value": "@body('Check_Job_Status')" + } + }, + "Wait_If_Needed": { + "runAfter": { + "Update_Job_Response": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "not": { + "or": [ + { + "equals": [ + "@variables('JobStatus')", + "SUCCESS" + ] + }, + { + "equals": [ + "@variables('JobStatus')", + "success" + ] + } + ] + } + }, + "actions": { + "Wait_Before_Retry": { + "runAfter": {}, + "type": "Wait", + "inputs": { + "interval": { + "count": "@variables('PollIntervalSeconds')", + "unit": "Second" + } + } + } + }, + "else": { + "actions": {} + } + } + } + }, + "Check_Final_Status": { + "runAfter": { + "Polling_Loop": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "or": [ + { + "equals": [ + "@variables('JobStatus')", + "SUCCESS" + ] + }, + { + "equals": [ + "@variables('JobStatus')", + "success" + ] + } + ] + } + ] + }, + "actions": { + "Success_Response": { + "runAfter": {}, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": true, + "job_id": "@variables('JobId')", + "status": "@variables('JobStatus')", + "poll_count": "@variables('PollCount')", + "data": "@variables('JobResponse')", + "caller_info": "@triggerBody()?['caller_info']" + } + } + } + }, + "else": { + "actions": { + "Error_Response": { + "runAfter": {}, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 408, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": false, + "error": "Job polling timeout or failed", + "job_id": "@variables('JobId')", + "status": "@variables('JobStatus')", + "poll_count": "@variables('PollCount')", + "max_attempts": "@variables('MaxPollAttempts')", + "data": "@variables('JobResponse')", + "caller_info": "@triggerBody()?['caller_info']" + } + } + } + } + } + } + }, + "outputs": {} + }, + "parameters": {} + } + } + ], + "outputs": { + "PlaybookName": { + "type": "string", + "value": "[parameters('PlaybookName')]" + }, + "PlaybookResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]" + }, + "PlaybookUrl": { + "type": "string", + "value": "[concat('https://portal.azure.com/#resource', resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')))]" + }, + "TriggerUrl": { + "type": "string", + "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..9b4b9ab47cc --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.parameters.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetAppRPS-Async-Poll-Playbook" + }, + "NetAppRPSAuthPlaybookName": { + "value": "NetAppRPS-Auth-Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json new file mode 100644 index 00000000000..0477762561b --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json @@ -0,0 +1,464 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "NetApp RPS Enrich IP Playbook", + "description": "This playbook enriches IP data by calling the updated NetApp RPS enrich IP address API endpoint and asynchronously polls multiple job results.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. NetApp RPS Async Poll Playbook must be deployed", + "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "4. Caller must provide ip_address parameter" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Ensure the Async Poll Playbook is deployed and functional", + "3. Test the IP enrichment functionality with valid IP address", + "4. Verify the new POST API endpoint is accessible and returns job information with agent_id" + ], + "lastUpdateTime": "2025-09-26T00:00:00.000Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "IP", + "Enrich", + "NetworkInterface" + ], + "support": { + "tier": "Community" + }, + "author": { + "name": "NetApp" + } + }, + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Enrich-IP-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "NetAppRPSAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp RPS async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('PlaybookName')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "ip_address": { + "type": "string" + }, + "callbackData": { + "type": "object" + } + }, + "required": [ + "ip_address" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "runAfter": {}, + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "IpAddress", + "type": "string", + "value": "@triggerBody()?['ip_address']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobIds", + "type": "array" + }, + { + "name": "PollingResults", + "type": "array" + }, + { + "name": "EnrichmentStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT30S" + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Get_IP_NetworkInterfaces": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/ip-address", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "accept": "application/json", + "Content-Type": "application/json" + }, + "body": { + "ip_address": "@{variables('IpAddress')}" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT45S" + } + }, + "Capture_Enrichment_Status_Code": { + "runAfter": { + "Get_IP_NetworkInterfaces": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "EnrichmentStatusCode", + "value": "@outputs('Get_IP_NetworkInterfaces')['statusCode']" + } + }, + "Parse_JobIds_Response": { + "runAfter": { + "Capture_Enrichment_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Get_IP_NetworkInterfaces')", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + } + }, + "Extract_Job_IDs": { + "runAfter": { + "Parse_JobIds_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobIds", + "value": "@body('Parse_JobIds_Response')" + } + }, + "Poll_All_Jobs": { + "runAfter": { + "Extract_Job_IDs": [ + "Succeeded" + ] + }, + "type": "Foreach", + "foreach": "@variables('JobIds')", + "actions": { + "Call_Async_Poll_Playbook": { + "runAfter": {}, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@item()?['job_id']", + "agent_id": "@item()?['agent_id']", + "system_id": "default", + "source": "@item()?['source']", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_ip": "@variables('IpAddress')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT90S" + } + }, + "Add_Poll_Result": { + "runAfter": { + "Call_Async_Poll_Playbook": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "PollingResults", + "value": { + "job_id": "@item()?['job_id']", + "poll_response": "@body('Call_Async_Poll_Playbook')", + "original_job_info": "@item()" + } + } + }, + "Add_Failed_Poll_Result": { + "runAfter": { + "Call_Async_Poll_Playbook": [ + "Failed", + "TimedOut" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "PollingResults", + "value": { + "job_id": "@item()?['job_id']", + "poll_response": { + "success": false, + "error": "Failed to poll job or timeout occurred" + }, + "original_job_info": "@item()" + } + } + } + }, + "runtimeConfiguration": { + "concurrency": { + "repetitions": 1 + } + } + }, + "Return_Response": { + "runAfter": { + "Poll_All_Jobs": [ + "Succeeded", + "Skipped" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Get_IP_NetworkInterfaces": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'Failed retrieving IP network interfaces data', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'enrichment', 'success'))", + "account_id": "@variables('AccountId')", + "ip_address": "@variables('IpAddress')", + "enrichment": { + "statusCode": "@variables('EnrichmentStatusCode')", + "job_ids_count": "@length(variables('JobIds'))", + "polling_results_count": "@length(variables('PollingResults'))", + "original_jobs": "@variables('JobIds')", + "polling_results": "@variables('PollingResults')", + "raw_initial_response": "@body('Get_IP_NetworkInterfaces')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + }, + "outputs": {} + }, + "parameters": {} + } + } + ], + "outputs": { + "PlaybookName": { + "type": "string", + "value": "[parameters('PlaybookName')]" + }, + "PlaybookResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]" + }, + "PlaybookUrl": { + "type": "string", + "value": "[concat('https://portal.azure.com/#resource', resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')))]" + }, + "TriggerUrl": { + "type": "string", + "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..f97dc4c95d8 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetAppRPS-Enrich-IP-Playbook" + }, + "NetAppRPSAuthPlaybookName": { + "value": "NetAppRPS-Auth-Playbook" + }, + "NetAppRPSAsyncPollPlaybookName": { + "value": "NetAppRPS-Async-Poll-Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json new file mode 100644 index 00000000000..8b9ccf4e946 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json @@ -0,0 +1,360 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "NetApp RPS Enrich StorageVM Playbook", + "description": "This playbook enriches storage data by calling the updated NetApp RPS enrich storage API endpoint.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "3. Caller must provide agent_id and system_id parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Test the storage enrichment functionality with valid agent_id and system_id" + ], + "lastUpdateTime": "2025-09-23T00:00:00.000Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "StorageVM", + "Enrich" + ], + "support": { + "tier": "Community" + }, + "author": { + "name": "NetApp" + } + }, + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Enrich-StorageVM-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('PlaybookName')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + } + }, + "required": [ + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "runAfter": {}, + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "StorageVMData", + "type": "array" + }, + { + "name": "EnrichmentStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Get_StorageVM_Data": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Enrichment_Status_Code": { + "runAfter": { + "Get_StorageVM_Data": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "EnrichmentStatusCode", + "value": "@outputs('Get_StorageVM_Data')['statusCode']" + } + }, + "Parse_StorageVM_Response": { + "runAfter": { + "Capture_Enrichment_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Get_StorageVM_Data')", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "volume_uuid": { + "type": "string" + }, + "volume_name": { + "type": "string" + }, + "svm_name": { + "type": "string" + } + } + } + } + } + }, + "Store_StorageVM_Data": { + "runAfter": { + "Parse_StorageVM_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "StorageVMData", + "value": "@body('Parse_StorageVM_Response')" + } + }, + "Return_Response": { + "runAfter": { + "Store_StorageVM_Data": [ + "Succeeded", + "Skipped" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Get_StorageVM_Data": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'Failed retrieving storage VM data', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'enrichment', 'success'))", + "account_id": "@variables('AccountId')", + "enrichment": { + "statusCode": "@variables('EnrichmentStatusCode')", + "storage_vms": "@variables('StorageVMData')", + "count": "@length(variables('StorageVMData'))", + "raw": "@body('Get_StorageVM_Data')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + }, + "outputs": {} + }, + "parameters": {} + } + } + ], + "outputs": { + "PlaybookName": { + "type": "string", + "value": "[parameters('PlaybookName')]" + }, + "PlaybookResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]" + }, + "PlaybookUrl": { + "type": "string", + "value": "[concat('https://portal.azure.com/#resource', resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')))]" + }, + "TriggerUrl": { + "type": "string", + "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..f3440d06190 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.parameters.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetAppRPS-Enrich-StorageVM-Playbook" + }, + "NetAppRPSAuthPlaybookName": { + "value": "NetAppRPS-Auth-Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json new file mode 100644 index 00000000000..e2087995612 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json @@ -0,0 +1,544 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "NetApp RPS Volume Offline Playbook", + "description": "This playbook takes a NetApp volume offline using the updated NetApp RPS take-volume-offline API endpoint and optionally polls for completion.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. NetApp RPS Async Poll Playbook must be deployed first", + "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "4. Caller must provide volume_id, agent_id, and system_id parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Ensure the Async Poll Playbook is working correctly", + "3. Test the volume offline functionality with valid volume_id, agent_id, and system_id", + "4. Verify the new take-volume-offline API endpoint is accessible" + ], + "lastUpdateTime": "2025-09-17T00:00:00.000Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Volume", + "Offline" + ], + "support": { + "tier": "Community" + }, + "author": { + "name": "NetApp" + } + }, + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Volume-Offline-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "NetAppRPSAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp RPS async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('PlaybookName')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "volume_id": { + "type": "string" + }, + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + }, + "poll": { + "type": "boolean" + } + }, + "required": [ + "volume_id", + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "runAfter": {}, + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "VolumeId", + "type": "string", + "value": "@triggerBody()?['volume_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "DoPoll", + "type": "boolean", + "value": "@coalesce(triggerBody()?['poll'], true)" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobId", + "type": "string" + }, + { + "name": "JobAgentId", + "type": "string" + }, + { + "name": "PollResponse", + "type": "object", + "value": {} + }, + { + "name": "SubmissionStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Submit_Volume_Offline": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-volume-offline", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "Content-Type": "application/json", + "accept": "application/json" + }, + "body": { + "volume_id": "@variables('VolumeId')", + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Submission_Status_Code": { + "runAfter": { + "Submit_Volume_Offline": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SubmissionStatusCode", + "value": "@outputs('Submit_Volume_Offline')['statusCode']" + } + }, + "Parse_Submission_Response": { + "runAfter": { + "Capture_Submission_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Submit_Volume_Offline')", + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + }, + "Store_JobId": { + "runAfter": { + "Parse_Submission_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobId", + "value": "@body('Parse_Submission_Response')?['job_id']" + } + }, + "Store_Job_AgentId": { + "runAfter": { + "Store_JobId": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobAgentId", + "value": "@body('Parse_Submission_Response')?['agent_id']" + } + }, + "Check_If_Should_Poll": { + "runAfter": { + "Store_Job_AgentId": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@variables('DoPoll')", + true + ] + }, + { + "or": [ + { + "equals": [ + "@variables('SubmissionStatusCode')", + 200 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 201 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 202 + ] + } + ] + }, + { + "not": { + "equals": [ + "@variables('JobId')", + "" + ] + } + } + ] + }, + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@variables('JobId')", + "agent_id": "@variables('JobAgentId')", + "system_id": "@variables('SystemId')", + "source": "ontap", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_volume_id": "@variables('VolumeId')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + } + }, + "else": { + "actions": {} + } + }, + "Parse_Poll_Response": { + "runAfter": { + "Check_If_Should_Poll": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Async_Poll_Playbook')", + "schema": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "jobId": { + "type": "string" + }, + "success": { + "type": "boolean" + } + } + } + } + }, + "Store_Poll_Response": { + "runAfter": { + "Parse_Poll_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PollResponse", + "value": "@body('Parse_Poll_Response')" + } + }, + "Return_Response": { + "runAfter": { + "Store_Poll_Response": [ + "Succeeded", + "Skipped" + ], + "Check_If_Should_Poll": [ + "Succeeded" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Submit_Volume_Offline": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'Failed submitting volume offline request', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'submit', 'success'))", + "submission": { + "statusCode": "@variables('SubmissionStatusCode')", + "jobId": "@variables('JobId')", + "raw": "@body('Submit_Volume_Offline')", + "details": "@if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), body('Submit_Volume_Offline'), null)" + }, + "polling": { + "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", + "playbook": "@parameters('asyncPollPlaybookName')", + "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", + "jobResponse": "@variables('PollResponse')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + }, + "outputs": {} + }, + "parameters": {} + } + } + ], + "outputs": { + "PlaybookName": { + "type": "string", + "value": "[parameters('PlaybookName')]" + }, + "PlaybookResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]" + }, + "PlaybookUrl": { + "type": "string", + "value": "[concat('https://portal.azure.com/#resource', resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')))]" + }, + "TriggerUrl": { + "type": "string", + "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..4bdd7715aa9 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetAppRPS-Volume-Offline-Playbook" + }, + "NetAppRPSAuthPlaybookName": { + "value": "NetAppRPS-Auth-Playbook" + }, + "NetAppRPSAsyncPollPlaybookName": { + "value": "NetAppRPS-Async-Poll-Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json new file mode 100644 index 00000000000..0f7c2e01284 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json @@ -0,0 +1,544 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "NetApp RPS Volume Snapshot Playbook", + "description": "This playbook creates a NetApp volume snapshot using the updated NetApp RPS take-snapshot API endpoint and optionally polls for completion.", + "prerequisites": [ + "1. NetApp RPS Auth Playbook must be deployed first", + "2. NetApp RPS Async Poll Playbook must be deployed first", + "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "4. Caller must provide volume_id, agent_id, and system_id parameters" + ], + "postDeployment": [ + "1. Ensure the Auth Playbook is working correctly", + "2. Ensure the Async Poll Playbook is working correctly", + "3. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id", + "4. Verify the new take-snapshot API endpoint is accessible" + ], + "lastUpdateTime": "2025-09-22T00:00:00.000Z", + "tags": [ + "NetApp", + "RPS", + "Playbook", + "Volume", + "Snapshot" + ], + "support": { + "tier": "Community" + }, + "author": { + "name": "NetApp" + } + }, + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Volume-Snapshot-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRPSAuthPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp RPS authentication playbook" + } + }, + "NetAppRPSAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp RPS async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('PlaybookName')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[parameters('NetAppRPSAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "volume_id": { + "type": "string" + }, + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + }, + "poll": { + "type": "boolean" + } + }, + "required": [ + "volume_id", + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "runAfter": {}, + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "VolumeId", + "type": "string", + "value": "@triggerBody()?['volume_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "DoPoll", + "type": "boolean", + "value": "@coalesce(triggerBody()?['poll'], true)" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobId", + "type": "string" + }, + { + "name": "JobAgentId", + "type": "string" + }, + { + "name": "PollResponse", + "type": "object", + "value": {} + }, + { + "name": "SubmissionStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Submit_Volume_Snapshot": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-snapshot", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "Content-Type": "application/json", + "accept": "application/json" + }, + "body": { + "volume_id": "@variables('VolumeId')", + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Submission_Status_Code": { + "runAfter": { + "Submit_Volume_Snapshot": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SubmissionStatusCode", + "value": "@outputs('Submit_Volume_Snapshot')['statusCode']" + } + }, + "Parse_Submission_Response": { + "runAfter": { + "Capture_Submission_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Submit_Volume_Snapshot')", + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + }, + "Store_JobId": { + "runAfter": { + "Parse_Submission_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobId", + "value": "@body('Parse_Submission_Response')?['job_id']" + } + }, + "Store_Job_AgentId": { + "runAfter": { + "Store_JobId": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobAgentId", + "value": "@body('Parse_Submission_Response')?['agent_id']" + } + }, + "Check_If_Should_Poll": { + "runAfter": { + "Store_Job_AgentId": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@variables('DoPoll')", + true + ] + }, + { + "or": [ + { + "equals": [ + "@variables('SubmissionStatusCode')", + 200 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 201 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 202 + ] + } + ] + }, + { + "not": { + "equals": [ + "@variables('JobId')", + "" + ] + } + } + ] + }, + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@variables('JobId')", + "agent_id": "@variables('JobAgentId')", + "system_id": "@variables('SystemId')", + "source": "ontap", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_volume_id": "@variables('VolumeId')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + } + }, + "else": { + "actions": {} + } + }, + "Parse_Poll_Response": { + "runAfter": { + "Check_If_Should_Poll": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Async_Poll_Playbook')", + "schema": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "jobId": { + "type": "string" + }, + "success": { + "type": "boolean" + } + } + } + } + }, + "Store_Poll_Response": { + "runAfter": { + "Parse_Poll_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PollResponse", + "value": "@body('Parse_Poll_Response')" + } + }, + "Return_Response": { + "runAfter": { + "Store_Poll_Response": [ + "Succeeded", + "Skipped" + ], + "Check_If_Should_Poll": [ + "Succeeded" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Submit_Volume_Snapshot": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'Failed submitting volume snapshot request', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'submit', 'success'))", + "submission": { + "statusCode": "@variables('SubmissionStatusCode')", + "jobId": "@variables('JobId')", + "raw": "@body('Submit_Volume_Snapshot')", + "details": "@if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), body('Submit_Volume_Snapshot'), null)" + }, + "polling": { + "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", + "playbook": "@parameters('asyncPollPlaybookName')", + "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", + "jobResponse": "@variables('PollResponse')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + }, + "outputs": {} + }, + "parameters": {} + } + } + ], + "outputs": { + "PlaybookName": { + "type": "string", + "value": "[parameters('PlaybookName')]" + }, + "PlaybookResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]" + }, + "PlaybookUrl": { + "type": "string", + "value": "[concat('https://portal.azure.com/#resource', resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')))]" + }, + "TriggerUrl": { + "type": "string", + "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..fd47f031396 --- /dev/null +++ b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetAppRPS-Volume-Snapshot-Playbook" + }, + "NetAppRPSAuthPlaybookName": { + "value": "NetAppRPS-Auth-Playbook" + }, + "NetAppRPSAsyncPollPlaybookName": { + "value": "NetAppRPS-Async-Poll-Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/SolutionMetadata.json b/Solutions/NetAppRPS/SolutionMetadata.json new file mode 100644 index 00000000000..a803ed0efa6 --- /dev/null +++ b/Solutions/NetAppRPS/SolutionMetadata.json @@ -0,0 +1,27 @@ +{ + "id": "NetAppRPS", + "title": "NetApp RPS (Ransomware Protection Service)", + "publisher": "NetApp", + "publisherId": "netapp1234567890", + "offerId": "netapp-rps-sentinel-solution", + "firstPublishDate": "2025-10-31", + "lastPublishDate": "2025-10-31", + "providers": [ + "NetApp" + ], + "categories": { + "domains": [ + "Security - Ransomware Protection", + "Storage" + ], + "verticals": [] + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + }, + "basePath": "https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/NetAppRPS", + "version": "3.0.0" +} \ No newline at end of file From ad3c70a3f0e245bd139f5d81843ebcce668335c2 Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Tue, 4 Nov 2025 08:54:04 +0530 Subject: [PATCH 02/22] Fix data connector --- .../Data Connectors/NetAppRPS_DataConnector.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json index 7d8db44c9d4..8b003168826 100644 --- a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json +++ b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json @@ -48,12 +48,22 @@ "delete": true } } + ], + "customs": [ + { + "name": "Azure Subscription", + "description": "Azure Subscription with owner role is required to register an application in azure active directory() and assign role of contributor to app in resource group." + }, + { + "name": "NetApp Console Organization", + "description": "NetApp Console Organization with permissions to create a new Service Account" + } ] }, "instructionSteps": [ { "title": "Azure Resource Manager (ARM) Template", - "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-netskope-azuredeploy)" + "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)" } ] } \ No newline at end of file From 55eac147e275e2ac692f7d03b6b93b70e487e2c0 Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Tue, 4 Nov 2025 08:54:38 +0530 Subject: [PATCH 03/22] Fix analytic rules --- Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml | 3 ++- .../NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml index e45ef6804d4..485b358a429 100644 --- a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml +++ b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml @@ -30,4 +30,5 @@ incidentConfiguration: eventGroupingSettings: aggregationKind: AlertPerResult version: 1.0.0 -kind: NRT \ No newline at end of file +kind: NRT +tactics: [] \ No newline at end of file diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml index 89f1e6efde5..5110623c182 100644 --- a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml +++ b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml @@ -30,4 +30,5 @@ incidentConfiguration: eventGroupingSettings: aggregationKind: AlertPerResult version: 1.0.0 -kind: NRT \ No newline at end of file +kind: NRT +tactics: [] From 91f67fec5bc1c2ee22ca47b91157c692a3adb3c8 Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Wed, 12 Nov 2025 09:11:17 +0530 Subject: [PATCH 04/22] Add NetAppRPSCustomLogsIngestion to valid connector IDs --- .../ValidConnectorIds.json | 573 +++++++++--------- 1 file changed, 287 insertions(+), 286 deletions(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json index fd4fe199415..8ed7a699fa2 100644 --- a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json +++ b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json @@ -1,287 +1,288 @@ -[ - "Netclean_ProActive_Incidents", - "42CrunchAPIProtection", - "AIVectraDetect", - "AIVectraStream", - "VectraXDR", - "AWS", - "AWSS3", - "AWSSecurityHub", - "Agari", - "AkamaiSecurityEvents", - "AlcideKAudit", - "AlsidForAD", - "Anvilogic", - "Armorblox", - "ApacheHTTPServer", - "ApacheTomcat", - "ARGOSCloudSecurity", - "AristaAwakeSecurity", - "ASimDnsActivityLogs", - "ArubaClearPass", - "AzureActiveDirectory", - "AzureActiveDirectoryIdentityProtection", - "AzureActivity", - "AzureAdvancedThreatProtection", - "AzureFirewall", - "AzureInformationProtection", - "AzureKeyVault", - "AzureKubernetes", - "AzureMonitor(IIS)", - "AzureMonitor(VMInsights)", - "AzureMonitor(WireData)", - "AzureNSG", - "AzureSecurityCenter", - "AzureSql", - "AzureStorageAccount", - "Barracuda", - "BarracudaCloudFirewall", - "BetterMTD", - "BehaviorAnalytics", - "BeyondSecuritybeSECURE", - "Bitglass", - "BitSight", - "BlackberryCylancePROTECT", - "BloodHoundEnterprise", - "BoschAIShield", - "BoxDataConnector", - "BroadcomSymantecDLP", - "CEF", - "CheckPoint", - "CiscoASA", - "CiscoAsaAma", - "CiscoDuoSecurity", - "CiscoFirepowerEStreamer", - "CiscoISE", - "CiscoMeraki", - "CiscoSDWAN", - "CiscoSecureEndpoint", - "CiscoSEG", - "CiscoUCS", - "CiscoUmbrellaDataConnector", - "CiscoWSA", - "Citrix", - "CitrixWAF", - "Claroty", - "CloudflareDataConnector", - "CognniSentinelDataConnector", - "ContrastProtect", - "Corelight", - "CrowdStrikeFalconEndpointProtection", - "CyberArk", - "CyberArkEPM", - "CyberpionSecurityLogs", - "CynerioSecurityEvents", - "DDOS", - "DNS", - "Darktrace", - "DarktraceRESTConnector", - "DataminrPulseAlerts", - "Dataverse", - "DigitalGuardianDLP", - "DigitalShadows", - "DragosSitestoreCCP", - "Dynamics365", - "Dynamics365Finance", - "EgressDefend", - "ESETEnterpriseInspector", - "ESETPROTECT", - "EsetSMC", - "ESI-ExchangeAdminAuditLogEvents", - "ExtraHopNetworks", - "F5", - "F5BigIp", - "Flare", - "ForcepointCasb", - "ForcepointDlp", - "ForcepointNgfw", - "ForgeRock", - "Fortinet", - "FortiWeb", - "GCPDNSDataConnector", - "GoogleSCCDefinition", - "GWorkspaceRAPI", - "GoogleWorkspaceReportsAPI", - "GreyNoise2SentinelAPI", - "IdentityInfo", - "ImpervaWAFCloudAPI", - "ImpervaWAFGateway", - "ImportedConnector", - "InfobloxCloudDataConnector", - "InfobloxNIOS", - "IoT", - "JamfProtect", - "JiraAuditAPI", - "JuniperSRX", - "KeeperSecurityPush2", - "LastPass", - "LookoutAPI", - "LumenThreatFeedConnector", - "McAfeeePO", - "MicrosoftAzurePurview", - "MicrosoftCloudAppSecurity", - "MicrosoftCopilot", - "MicrosoftDefenderAdvancedThreatProtection", - "MicrosoftSysmonForLinux", - "MicrosoftThreatProtection", - "MimecastSEGAPI", - "MorphisecCCF", - "NasuniEdgeAppliance", - "NXLogDnsLogs", - "NXLogLinuxAudit", - "Netskope", - "Office365", - "OfficeATP", - "OktaSSO", - "OktaSSOv2", - "OnapsisPlatform", - "OneIdentity", - "OCILogs", - "OracleDatabaseAudit", - "OracleCloudInfrastructureLogsConnector", - "OracleWebLogicServer", - "OrcaSecurityAlerts", - "PaloAltoCDL", - "PaloAltoNetworks", - "PaloAltoPrismaCloud", - "Perimeter81ActivityLogs", - "PingFederate", - "PostgreSQL", - "PowerAutomate", - "PowerPlatformAdmin", - "ProofpointPOD", - "ProofpointTAP", - "ProofpointTAPNativePoller", - "ProofpointTAPv2", - "PulseConnectSecure", - "QscoutAppEventsCCFDefinition", - "QualysKB", - "QualysVulnerabilityManagement", - "RedCanaryDataConnector", - "RubrikSecurityCloudAzureFunctions", - "SailPointIdentityNow", - "SalesforceServiceCloud", - "SalesforceServiceCloudCCPDefinition", - "SAP", - "SAPBTPAuditEvents", - "SAPLogServ", - "SAPETDAlerts", - "SecurityEvents", - "SemperisDSP", - "SenservaPro", - "SentinelOne", - "SlackAuditAPI", - "Snowflake", - "SonicWallFirewall", - "SonraiDataConnector", - "SophosCloudOptix", - "SophosXGFirewall", - "SquadraTechnologiesSecRmm", - "SquidProxy", - "Symantec", - "SymantecEndpointProtection", - "SymantecProxySG", - "SymantecVIP", - "Syslog", - "Tenable.ad", - "TenableVM", - "TenableIE", - "ThreatIntelligence", - "ThreatIntelligenceTaxii", - "ThreatIntelligenceUploadIndicatorsAPI", - "DelineaSecretServer_CEF", - "TrendMicro", - "TrendMicroApexOne", - "TrendMicroCAS", - "TrendMicroTippingPoint", - "TrendMicroXDR", - "UbiquitiUnifi", - "vArmourAC", - "VMwareCarbonBlack", - "vCenter", - "VMwareESXi", - "VMwareSDWAN", - "WAF", - "WindowsFirewall", - "WindowsForwardedEvents", - "WireX_Systems_NFP", - "ZimperiumMtdAlerts", - "Zscaler", - "ZscalerPrivateAccess", - "illusiveAttackManagementSystem", - "WindowsSecurityEvents", - "IronNetIronDefense", - "GCPIAMDataConnector", - "Illusive", - "NGINXHTTPServer", - "ZeroNetworksSegmentAuditFunction", - "ZeroNetworksSegmentAuditNativePoller", - "Theom", - "Votiro", - "ISCBind", - "DynatraceRuntimeVulnerabilities", - "DynatraceAttacks", - "DynatraceAuditLogs", - "DynatraceProblems", - "Authomize", - "MicrosoftDefenderThreatIntelligence", - "ZeroFox_Alert_Polling", - "CortexXDR", - "Corelight", - "CorelightConnectorExporter", - "MimecastSIEMAPI", - "MimecastTTPAPI", - "MimecastAuditAPI", - "PingFederateAma", - "vArmourACAma", - "ContrastProtectAma", - "InfobloxCloudDataConnectorAma", - "ClarotyAma", - "illusiveAttackManagementSystemAma", - "TrendMicroApexOneAma", - "PaloAltoCDLAma", - "CiscoSEGAma", - "AtlassianBeaconAlerts", - "GCPAuditLogsDefinition", - "PrancerLogData", - "MicrosoftDefenderForCloudTenantBased", - "RidgeBotDataConnector", - "ValenceSecurity", - "HVPollingIDAzureFunctions", - "CBSPollingIDAzureFunctions", - "AzureCloudNGFWByPaloAltoNetworks", - "PaloAltoNetworksAma", - "FortinetAma", - "CrowdStrikeFalconEndpointProtectionAma", - "AIVectraDetectAma", - "ZscalerAma", - "SyslogAma", - "FortinetFortiWebAma", - "InfobloxSOCInsightsDataConnector_API", - "InfobloxSOCInsightsDataConnector_Legacy", - "InfobloxSOCInsightsDataConnector_AMA", - "NetskopeDataConnector", - "NetskopeWebTransactionsDataConnector", - "CefAma", - "WindowsFirewallAma", - "1Password", - "RadiflowIsid", - "CustomLogsAma", - "SilverfortAma", - "IllumioSaaSDataConnector", - "CTERA", - "Workday", - "SamsungDCDefinition", - "CommvaultSecurityIQ_CL", - "ExtraHop", - "ContrastADR", - "CyfirmaAttackSurfaceAlertsConnector", - "CyfirmaBrandIntelligenceAlertsDC", - "CyfirmaDigitalRiskAlertsConnector", - "CyfirmaVulnerabilitiesIntelDC", - "CyfirmaCyberIntelligenceDC", - "VeeamCustomTablesDataConnector", - "CyfirmaCompromisedAccountsDataConnector", - "RSAIDPlus_AdminLogs_Connector", - "CybleVisionAlerts" +[ + "Netclean_ProActive_Incidents", + "42CrunchAPIProtection", + "AIVectraDetect", + "AIVectraStream", + "VectraXDR", + "AWS", + "AWSS3", + "AWSSecurityHub", + "Agari", + "AkamaiSecurityEvents", + "AlcideKAudit", + "AlsidForAD", + "Anvilogic", + "Armorblox", + "ApacheHTTPServer", + "ApacheTomcat", + "ARGOSCloudSecurity", + "AristaAwakeSecurity", + "ASimDnsActivityLogs", + "ArubaClearPass", + "AzureActiveDirectory", + "AzureActiveDirectoryIdentityProtection", + "AzureActivity", + "AzureAdvancedThreatProtection", + "AzureFirewall", + "AzureInformationProtection", + "AzureKeyVault", + "AzureKubernetes", + "AzureMonitor(IIS)", + "AzureMonitor(VMInsights)", + "AzureMonitor(WireData)", + "AzureNSG", + "AzureSecurityCenter", + "AzureSql", + "AzureStorageAccount", + "Barracuda", + "BarracudaCloudFirewall", + "BetterMTD", + "BehaviorAnalytics", + "BeyondSecuritybeSECURE", + "Bitglass", + "BitSight", + "BlackberryCylancePROTECT", + "BloodHoundEnterprise", + "BoschAIShield", + "BoxDataConnector", + "BroadcomSymantecDLP", + "CEF", + "CheckPoint", + "CiscoASA", + "CiscoAsaAma", + "CiscoDuoSecurity", + "CiscoFirepowerEStreamer", + "CiscoISE", + "CiscoMeraki", + "CiscoSDWAN", + "CiscoSecureEndpoint", + "CiscoSEG", + "CiscoUCS", + "CiscoUmbrellaDataConnector", + "CiscoWSA", + "Citrix", + "CitrixWAF", + "Claroty", + "CloudflareDataConnector", + "CognniSentinelDataConnector", + "ContrastProtect", + "Corelight", + "CrowdStrikeFalconEndpointProtection", + "CyberArk", + "CyberArkEPM", + "CyberpionSecurityLogs", + "CynerioSecurityEvents", + "DDOS", + "DNS", + "Darktrace", + "DarktraceRESTConnector", + "DataminrPulseAlerts", + "Dataverse", + "DigitalGuardianDLP", + "DigitalShadows", + "DragosSitestoreCCP", + "Dynamics365", + "Dynamics365Finance", + "EgressDefend", + "ESETEnterpriseInspector", + "ESETPROTECT", + "EsetSMC", + "ESI-ExchangeAdminAuditLogEvents", + "ExtraHopNetworks", + "F5", + "F5BigIp", + "Flare", + "ForcepointCasb", + "ForcepointDlp", + "ForcepointNgfw", + "ForgeRock", + "Fortinet", + "FortiWeb", + "GCPDNSDataConnector", + "GoogleSCCDefinition", + "GWorkspaceRAPI", + "GoogleWorkspaceReportsAPI", + "GreyNoise2SentinelAPI", + "IdentityInfo", + "ImpervaWAFCloudAPI", + "ImpervaWAFGateway", + "ImportedConnector", + "InfobloxCloudDataConnector", + "InfobloxNIOS", + "IoT", + "JamfProtect", + "JiraAuditAPI", + "JuniperSRX", + "KeeperSecurityPush2", + "LastPass", + "LookoutAPI", + "LumenThreatFeedConnector", + "McAfeeePO", + "MicrosoftAzurePurview", + "MicrosoftCloudAppSecurity", + "MicrosoftCopilot", + "MicrosoftDefenderAdvancedThreatProtection", + "MicrosoftSysmonForLinux", + "MicrosoftThreatProtection", + "MimecastSEGAPI", + "MorphisecCCF", + "NasuniEdgeAppliance", + "NXLogDnsLogs", + "NXLogLinuxAudit", + "Netskope", + "Office365", + "OfficeATP", + "OktaSSO", + "OktaSSOv2", + "OnapsisPlatform", + "OneIdentity", + "OCILogs", + "OracleDatabaseAudit", + "OracleCloudInfrastructureLogsConnector", + "OracleWebLogicServer", + "OrcaSecurityAlerts", + "PaloAltoCDL", + "PaloAltoNetworks", + "PaloAltoPrismaCloud", + "Perimeter81ActivityLogs", + "PingFederate", + "PostgreSQL", + "PowerAutomate", + "PowerPlatformAdmin", + "ProofpointPOD", + "ProofpointTAP", + "ProofpointTAPNativePoller", + "ProofpointTAPv2", + "PulseConnectSecure", + "QscoutAppEventsCCFDefinition", + "QualysKB", + "QualysVulnerabilityManagement", + "RedCanaryDataConnector", + "RubrikSecurityCloudAzureFunctions", + "SailPointIdentityNow", + "SalesforceServiceCloud", + "SalesforceServiceCloudCCPDefinition", + "SAP", + "SAPBTPAuditEvents", + "SAPLogServ", + "SAPETDAlerts", + "SecurityEvents", + "SemperisDSP", + "SenservaPro", + "SentinelOne", + "SlackAuditAPI", + "Snowflake", + "SonicWallFirewall", + "SonraiDataConnector", + "SophosCloudOptix", + "SophosXGFirewall", + "SquadraTechnologiesSecRmm", + "SquidProxy", + "Symantec", + "SymantecEndpointProtection", + "SymantecProxySG", + "SymantecVIP", + "Syslog", + "Tenable.ad", + "TenableVM", + "TenableIE", + "ThreatIntelligence", + "ThreatIntelligenceTaxii", + "ThreatIntelligenceUploadIndicatorsAPI", + "DelineaSecretServer_CEF", + "TrendMicro", + "TrendMicroApexOne", + "TrendMicroCAS", + "TrendMicroTippingPoint", + "TrendMicroXDR", + "UbiquitiUnifi", + "vArmourAC", + "VMwareCarbonBlack", + "vCenter", + "VMwareESXi", + "VMwareSDWAN", + "WAF", + "WindowsFirewall", + "WindowsForwardedEvents", + "WireX_Systems_NFP", + "ZimperiumMtdAlerts", + "Zscaler", + "ZscalerPrivateAccess", + "illusiveAttackManagementSystem", + "WindowsSecurityEvents", + "IronNetIronDefense", + "GCPIAMDataConnector", + "Illusive", + "NGINXHTTPServer", + "ZeroNetworksSegmentAuditFunction", + "ZeroNetworksSegmentAuditNativePoller", + "Theom", + "Votiro", + "ISCBind", + "DynatraceRuntimeVulnerabilities", + "DynatraceAttacks", + "DynatraceAuditLogs", + "DynatraceProblems", + "Authomize", + "MicrosoftDefenderThreatIntelligence", + "ZeroFox_Alert_Polling", + "CortexXDR", + "Corelight", + "CorelightConnectorExporter", + "MimecastSIEMAPI", + "MimecastTTPAPI", + "MimecastAuditAPI", + "PingFederateAma", + "vArmourACAma", + "ContrastProtectAma", + "InfobloxCloudDataConnectorAma", + "ClarotyAma", + "illusiveAttackManagementSystemAma", + "TrendMicroApexOneAma", + "PaloAltoCDLAma", + "CiscoSEGAma", + "AtlassianBeaconAlerts", + "GCPAuditLogsDefinition", + "PrancerLogData", + "MicrosoftDefenderForCloudTenantBased", + "RidgeBotDataConnector", + "ValenceSecurity", + "HVPollingIDAzureFunctions", + "CBSPollingIDAzureFunctions", + "AzureCloudNGFWByPaloAltoNetworks", + "PaloAltoNetworksAma", + "FortinetAma", + "CrowdStrikeFalconEndpointProtectionAma", + "AIVectraDetectAma", + "ZscalerAma", + "SyslogAma", + "FortinetFortiWebAma", + "InfobloxSOCInsightsDataConnector_API", + "InfobloxSOCInsightsDataConnector_Legacy", + "InfobloxSOCInsightsDataConnector_AMA", + "NetskopeDataConnector", + "NetskopeWebTransactionsDataConnector", + "CefAma", + "WindowsFirewallAma", + "1Password", + "RadiflowIsid", + "CustomLogsAma", + "SilverfortAma", + "IllumioSaaSDataConnector", + "CTERA", + "Workday", + "SamsungDCDefinition", + "CommvaultSecurityIQ_CL", + "ExtraHop", + "ContrastADR", + "CyfirmaAttackSurfaceAlertsConnector", + "CyfirmaBrandIntelligenceAlertsDC", + "CyfirmaDigitalRiskAlertsConnector", + "CyfirmaVulnerabilitiesIntelDC", + "CyfirmaCyberIntelligenceDC", + "VeeamCustomTablesDataConnector", + "CyfirmaCompromisedAccountsDataConnector", + "RSAIDPlus_AdminLogs_Connector", + "CybleVisionAlerts", + "NetAppRPSCustomLogsIngestion" ] \ No newline at end of file From 6ce13931601d9dcbed0ef6834bf73012c82d43af Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Wed, 12 Nov 2025 09:13:18 +0530 Subject: [PATCH 05/22] Add NetAppRPS_alerts_CL.json custom table definition --- .../CustomTables/NetAppRPS_alerts_CL.json | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .script/tests/KqlvalidationsTests/CustomTables/NetAppRPS_alerts_CL.json diff --git a/.script/tests/KqlvalidationsTests/CustomTables/NetAppRPS_alerts_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/NetAppRPS_alerts_CL.json new file mode 100644 index 00000000000..b8a357c5718 --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/NetAppRPS_alerts_CL.json @@ -0,0 +1,25 @@ +{ + "name": "NetAppRPS_alerts_CL", + "properties": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "severity", + "type": "string" + }, + { + "name": "incident", + "type": "dynamic" + }, + { + "name": "context", + "type": "dynamic" + } + ] +} \ No newline at end of file From d60e09907b919633db528db05cc34419dcbff7fc Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Wed, 12 Nov 2025 09:13:33 +0530 Subject: [PATCH 06/22] Update NetApp RPS analytic rules and data connector configurations to use NetAppRPS_alerts_CL table --- .../NetAppRPS_HighSeverity.yaml | 9 +- .../NetAppRPS_MediumSeverity.yaml | 7 +- .../NetAppRPS_DataConnector.json | 37 +++-- .../azuredeploy_rps_dataconnector.json | 16 +-- Solutions/NetAppRPS/Package/3.0.0.zip | Bin 18653 -> 19112 bytes .../NetAppRPS/Package/createUiDefinition.json | 4 +- Solutions/NetAppRPS/Package/mainTemplate.json | 132 ++++++++++++------ 7 files changed, 133 insertions(+), 72 deletions(-) diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml index 485b358a429..d932137ef55 100644 --- a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml +++ b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml @@ -1,17 +1,17 @@ id: 33b9688b-2afb-442f-a3bb-fe2362717bb7 name: NetApp RPS High Severity Alert description: | - 'Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the rps_alerts_CL table for alerts with HIGH severity level.' + 'Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the NetAppRPS_alerts_CL table for alerts with HIGH severity level.' severity: High status: Available requiredDataConnectors: - connectorId: NetAppRPSCustomLogsIngestion dataTypes: - - rps_alerts_CL + - NetAppRPS_alerts_CL suppressionDuration: PT5H suppressionEnabled: false query: | - rps_alerts_CL | where TimeGenerated > ago(1d) + NetAppRPS_alerts_CL | where TimeGenerated > ago(1d) | where severity == "HIGH" alertDetailsOverride: alertDisplayNameFormat: "{{description}}" @@ -31,4 +31,5 @@ eventGroupingSettings: aggregationKind: AlertPerResult version: 1.0.0 kind: NRT -tactics: [] \ No newline at end of file +tactics: [] +relevantTechniques: [] diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml index 5110623c182..f65a2e0c8cb 100644 --- a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml +++ b/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml @@ -1,17 +1,17 @@ id: be774c6e-7613-41db-b6e4-25975b680d24 name: NetApp RPS Medium Severity Alert description: | - 'Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the rps_alerts_CL table for alerts with MEDIUM severity level.' + 'Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the NetAppRPS_alerts_CL table for alerts with MEDIUM severity level.' severity: Medium status: Available requiredDataConnectors: - connectorId: NetAppRPSCustomLogsIngestion dataTypes: - - rps_alerts_CL + - NetAppRPS_alerts_CL suppressionDuration: PT5H suppressionEnabled: false query: | - rps_alerts_CL | where TimeGenerated > ago(1d) + NetAppRPS_alerts_CL | where TimeGenerated > ago(1d) | where severity == "MEDIUM" alertDetailsOverride: alertDisplayNameFormat: "{{description}}" @@ -32,3 +32,4 @@ eventGroupingSettings: version: 1.0.0 kind: NRT tactics: [] +relevantTechniques: [] diff --git a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json index 8b003168826..abf8fcff387 100644 --- a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json +++ b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json @@ -1,45 +1,45 @@ { - "id": "NetAppRPS", - "title": "NetAppRPS", + "id": "NetAppRPSCustomLogsIngestion", + "title": "NetAppRPS Data Connector", "publisher": "NetAppRPS", "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", "graphQueries": [ { "metricName": "Total data received", - "legend": "NetAppRPS", - "baseQuery": "rps_alerts_CL" + "legend": "NetAppRPS_alerts_CL", + "baseQuery": "NetAppRPS_alerts_CL" } ], "dataTypes": [ { - "name": "rps_alerts_CL", - "lastDataReceivedQuery": "rps_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + "name": "NetAppRPS_alerts_CL", + "lastDataReceivedQuery": "NetAppRPS_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "sampleQueries": [ { "description": "Default Query", - "query": "rps_alerts_CL" + "query": "NetAppRPS_alerts_CL" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ - "rps_alerts_CL" + "NetAppRPS_alerts_CL" ] } ], "availability": { "status": 1, - "isPreview": false + "isPreview": true }, "permissions": { "resourceProvider": [ { "provider": "Microsoft.OperationalInsights/workspaces", - "permissionsDisplayText": "read and write permissions on the workspace are required.", + "permissionsDisplayText": "read and write permissions are required.", "providerDisplayName": "Workspace", "scope": "Workspace", "requiredPermissions": { @@ -47,6 +47,15 @@ "read": true, "delete": true } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } } ], "customs": [ @@ -62,8 +71,12 @@ }, "instructionSteps": [ { - "title": "Azure Resource Manager (ARM) Template", - "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)" + "title": "1. Configuration", + "description": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data." + }, + { + "title": "2. Deploy the ARM Template", + "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)" } ] } \ No newline at end of file diff --git a/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json b/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json index 216231fdabc..fd735685fa8 100644 --- a/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json +++ b/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json @@ -19,12 +19,12 @@ { "type": "Microsoft.OperationalInsights/workspaces/tables", "apiVersion": "2022-10-01", - "name": "[concat(parameters('workspaceResourceId'), '/rps_alerts_CL')]", + "name": "[concat(parameters('workspaceResourceId'), '/NetAppRPS_alerts_CL')]", "properties": { "description": "Custom log table for storing custom logs", "retentionInDays": 30, "schema": { - "name": "rps_alerts_CL", + "name": "NetAppRPS_alerts_CL", "columns": [ { "name": "TimeGenerated", @@ -67,7 +67,7 @@ "location": "[resourceGroup().location]", "apiVersion": "2023-03-11", "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'rps_alerts_CL')]", + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRPS_alerts_CL')]", "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]" ], "properties": { @@ -109,13 +109,13 @@ "dataFlows": [ { "streams": [ - "Custom-rps_alerts_CL" + "Custom-NetAppRPS_alerts_CL" ], "destinations": [ "[parameters('workspaceResourceId')]" ], "transformKql": "source", - "outputStream": "Custom-rps_alerts_CL" + "outputStream": "Custom-NetAppRPS_alerts_CL" } ] } @@ -149,14 +149,14 @@ { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2020-04-01-preview", - "name": "[guid(resourceGroup().id, 'rps_alerts_CL', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", - "scope": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'rps_alerts_CL')]", + "name": "[guid(resourceGroup().id, 'NetAppRPS_alerts_CL', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", + "scope": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRPS_alerts_CL')]", "properties": { "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", "principalId": "[parameters('principalId')]" }, "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'rps_alerts_CL')]" + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRPS_alerts_CL')]" ] } ], diff --git a/Solutions/NetAppRPS/Package/3.0.0.zip b/Solutions/NetAppRPS/Package/3.0.0.zip index f1297836cf135c11f6b80b976909dbdce6a2c521..b70f359c564977ffc54d63faabc6c4bd952be2a8 100644 GIT binary patch delta 18455 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 diff --git a/Solutions/NetAppRPS/Package/createUiDefinition.json b/Solutions/NetAppRPS/Package/createUiDefinition.json index 2085688bf80..d1713c0b97d 100644 --- a/Solutions/NetAppRPS/Package/createUiDefinition.json +++ b/Solutions/NetAppRPS/Package/createUiDefinition.json @@ -110,7 +110,7 @@ "name": "analytic1-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the rps_alerts_CL table for alerts with HIGH severity level." + "text": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the NetAppRPS_alerts_CL table for alerts with HIGH severity level." } } ] @@ -124,7 +124,7 @@ "name": "analytic2-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the rps_alerts_CL table for alerts with MEDIUM severity level." + "text": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the NetAppRPS_alerts_CL table for alerts with MEDIUM severity level." } } ] diff --git a/Solutions/NetAppRPS/Package/mainTemplate.json b/Solutions/NetAppRPS/Package/mainTemplate.json index 3778643e97c..55f085a2716 100644 --- a/Solutions/NetAppRPS/Package/mainTemplate.json +++ b/Solutions/NetAppRPS/Package/mainTemplate.json @@ -36,9 +36,9 @@ "_solutionVersion": "3.0.0", "solutionId": "netapp1234567890.netapp-rps-sentinel-solution", "_solutionId": "[variables('solutionId')]", - "uiConfigId1": "NetAppRPS", + "uiConfigId1": "NetAppRPSCustomLogsIngestion", "_uiConfigId1": "[variables('uiConfigId1')]", - "dataConnectorContentId1": "NetAppRPS", + "dataConnectorContentId1": "NetAppRPSCustomLogsIngestion", "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", "_dataConnectorId1": "[variables('dataConnectorId1')]", @@ -138,34 +138,34 @@ "properties": { "connectorUiConfig": { "id": "[variables('_uiConfigId1')]", - "title": "NetAppRPS", + "title": "NetAppRPS Data Connector", "publisher": "NetAppRPS", "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", "graphQueries": [ { "metricName": "Total data received", - "legend": "NetAppRPS", - "baseQuery": "rps_alerts_CL" + "legend": "NetAppRPS_alerts_CL", + "baseQuery": "NetAppRPS_alerts_CL" } ], "dataTypes": [ { - "name": "rps_alerts_CL", - "lastDataReceivedQuery": "rps_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + "name": "NetAppRPS_alerts_CL", + "lastDataReceivedQuery": "NetAppRPS_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "sampleQueries": [ { "description": "Default Query", - "query": "rps_alerts_CL" + "query": "NetAppRPS_alerts_CL" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ - "rps_alerts_CL" + "NetAppRPS_alerts_CL" ] } ], @@ -177,7 +177,7 @@ "resourceProvider": [ { "provider": "Microsoft.OperationalInsights/workspaces", - "permissionsDisplayText": "read and write permissions on the workspace are required.", + "permissionsDisplayText": "read and write permissions are required.", "providerDisplayName": "Workspace", "scope": "Workspace", "requiredPermissions": { @@ -185,13 +185,36 @@ "read": true, "delete": true } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Azure Subscription", + "description": "Azure Subscription with owner role is required to register an application in azure active directory() and assign role of contributor to app in resource group." + }, + { + "name": "NetApp Console Organization", + "description": "NetApp Console Organization with permissions to create a new Service Account" } ] }, "instructionSteps": [ { - "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-netskope-azuredeploy)", - "title": "Azure Resource Manager (ARM) Template" + "description": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "title": "1. Configuration" + }, + { + "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)", + "title": "2. Deploy the ARM Template" } ] } @@ -232,7 +255,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_dataConnectorContentId1')]", "contentKind": "DataConnector", - "displayName": "NetAppRPS", + "displayName": "NetAppRPS Data Connector", "contentProductId": "[variables('_dataConnectorcontentProductId1')]", "id": "[variables('_dataConnectorcontentProductId1')]", "version": "[variables('dataConnectorVersion1')]" @@ -276,34 +299,34 @@ "kind": "GenericUI", "properties": { "connectorUiConfig": { - "title": "NetAppRPS", + "title": "NetAppRPS Data Connector", "publisher": "NetAppRPS", "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", "graphQueries": [ { "metricName": "Total data received", - "legend": "NetAppRPS", - "baseQuery": "rps_alerts_CL" + "legend": "NetAppRPS_alerts_CL", + "baseQuery": "NetAppRPS_alerts_CL" } ], "dataTypes": [ { - "name": "rps_alerts_CL", - "lastDataReceivedQuery": "rps_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + "name": "NetAppRPS_alerts_CL", + "lastDataReceivedQuery": "NetAppRPS_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ - "rps_alerts_CL" + "NetAppRPS_alerts_CL" ] } ], "sampleQueries": [ { "description": "Default Query", - "query": "rps_alerts_CL" + "query": "NetAppRPS_alerts_CL" } ], "availability": { @@ -314,7 +337,7 @@ "resourceProvider": [ { "provider": "Microsoft.OperationalInsights/workspaces", - "permissionsDisplayText": "read and write permissions on the workspace are required.", + "permissionsDisplayText": "read and write permissions are required.", "providerDisplayName": "Workspace", "scope": "Workspace", "requiredPermissions": { @@ -322,13 +345,36 @@ "read": true, "delete": true } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Azure Subscription", + "description": "Azure Subscription with owner role is required to register an application in azure active directory() and assign role of contributor to app in resource group." + }, + { + "name": "NetApp Console Organization", + "description": "NetApp Console Organization with permissions to create a new Service Account" } ] }, "instructionSteps": [ { - "description": "[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-netskope-azuredeploy)", - "title": "Azure Resource Manager (ARM) Template" + "description": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "title": "1. Configuration" + }, + { + "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)", + "title": "2. Deploy the ARM Template" } ], "id": "[variables('_uiConfigId1')]", @@ -359,10 +405,10 @@ "kind": "NRT", "location": "[parameters('workspace-location')]", "properties": { - "description": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the rps_alerts_CL table for alerts with HIGH severity level.", + "description": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the NetAppRPS_alerts_CL table for alerts with HIGH severity level.", "displayName": "NetApp RPS High Severity Alert", "enabled": false, - "query": "rps_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"HIGH\"\n", + "query": "NetAppRPS_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"HIGH\"\n", "severity": "High", "suppressionDuration": "PT1H", "suppressionEnabled": false, @@ -371,7 +417,7 @@ { "connectorId": "NetAppRPSCustomLogsIngestion", "dataTypes": [ - "rps_alerts_CL" + "NetAppRPS_alerts_CL" ] } ], @@ -384,17 +430,17 @@ "Severity": "severity" }, "alertDetailsOverride": { - "alertDisplayNameFormat": "{{description}}", - "alertDescriptionFormat": "High severity alert detected from NetApp RPS: {{description}}" + "alertDescriptionFormat": "High severity alert detected from NetApp RPS: {{description}}", + "alertDisplayNameFormat": "{{description}}" }, "incidentConfiguration": { + "createIncident": true, "groupingConfiguration": { "lookbackDuration": "PT5H", - "matchingMethod": "AllEntities", + "reopenClosedIncident": false, "enabled": false, - "reopenClosedIncident": false - }, - "createIncident": true + "matchingMethod": "AllEntities" + } } } }, @@ -463,10 +509,10 @@ "kind": "NRT", "location": "[parameters('workspace-location')]", "properties": { - "description": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the rps_alerts_CL table for alerts with MEDIUM severity level.", + "description": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the NetAppRPS_alerts_CL table for alerts with MEDIUM severity level.", "displayName": "NetApp RPS Medium Severity Alert", "enabled": false, - "query": "rps_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"MEDIUM\"\n", + "query": "NetAppRPS_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"MEDIUM\"\n", "severity": "Medium", "suppressionDuration": "PT1H", "suppressionEnabled": false, @@ -475,7 +521,7 @@ { "connectorId": "NetAppRPSCustomLogsIngestion", "dataTypes": [ - "rps_alerts_CL" + "NetAppRPS_alerts_CL" ] } ], @@ -488,17 +534,17 @@ "Severity": "severity" }, "alertDetailsOverride": { - "alertDisplayNameFormat": "{{description}}", - "alertDescriptionFormat": "Medium severity alert detected from NetApp RPS: {{description}}" + "alertDescriptionFormat": "Medium severity alert detected from NetApp RPS: {{description}}", + "alertDisplayNameFormat": "{{description}}" }, "incidentConfiguration": { + "createIncident": true, "groupingConfiguration": { "lookbackDuration": "PT5H", - "matchingMethod": "AllEntities", + "reopenClosedIncident": false, "enabled": false, - "reopenClosedIncident": false - }, - "createIncident": true + "matchingMethod": "AllEntities" + } } } }, @@ -3563,8 +3609,8 @@ } ] }, - "firstPublishDate": "2025-08-28", - "lastPublishDate": "2025-08-28", + "firstPublishDate": "2025-10-31", + "lastPublishDate": "2025-10-31", "providers": [ "NetApp" ], From b97d032ea624bc1963c03850e5fa1a858435aad4 Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Wed, 12 Nov 2025 09:17:44 +0530 Subject: [PATCH 07/22] Update BasePath in NetApp RPS solution configuration to use absolute path --- Solutions/NetAppRPS/Data/Solution_NetAppRps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/NetAppRPS/Data/Solution_NetAppRps.json b/Solutions/NetAppRPS/Data/Solution_NetAppRps.json index e10bb5c726a..a8ba1a36306 100644 --- a/Solutions/NetAppRPS/Data/Solution_NetAppRps.json +++ b/Solutions/NetAppRPS/Data/Solution_NetAppRps.json @@ -20,7 +20,7 @@ "Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json" ], "Version": "3.0.0", - "BasePath": "./Solutions/NetAppRPS/", + "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\NetAppRPS", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "StaticDataConnectorIds": [] From a13dc3ae88583f3241f925cf9a62c444ad56d047 Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Wed, 12 Nov 2025 09:17:51 +0530 Subject: [PATCH 08/22] Update offerId in SolutionMetadata.json to match the correct format --- Solutions/NetAppRPS/SolutionMetadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/NetAppRPS/SolutionMetadata.json b/Solutions/NetAppRPS/SolutionMetadata.json index a803ed0efa6..d7f6c83ff2f 100644 --- a/Solutions/NetAppRPS/SolutionMetadata.json +++ b/Solutions/NetAppRPS/SolutionMetadata.json @@ -3,7 +3,7 @@ "title": "NetApp RPS (Ransomware Protection Service)", "publisher": "NetApp", "publisherId": "netapp1234567890", - "offerId": "netapp-rps-sentinel-solution", + "offerId": "azure-sentinel-solution-NetAppRPS", "firstPublishDate": "2025-10-31", "lastPublishDate": "2025-10-31", "providers": [ From 6d4173f9e8f06f32507893da99b0111188c7f04d Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Wed, 12 Nov 2025 09:38:45 +0530 Subject: [PATCH 09/22] Update category domain from "Security - Ransomware Protection" to "Security - Threat Protection" in SolutionMetadata.json --- Solutions/NetAppRPS/SolutionMetadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/NetAppRPS/SolutionMetadata.json b/Solutions/NetAppRPS/SolutionMetadata.json index d7f6c83ff2f..68f699b35d9 100644 --- a/Solutions/NetAppRPS/SolutionMetadata.json +++ b/Solutions/NetAppRPS/SolutionMetadata.json @@ -11,7 +11,7 @@ ], "categories": { "domains": [ - "Security - Ransomware Protection", + "Security - Threat Protection", "Storage" ], "verticals": [] From 11d208d95ad5f2ac4ff73646b30ec57a40ffadf1 Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Fri, 14 Nov 2025 10:28:19 +0530 Subject: [PATCH 10/22] Update solutionId and deployment button links in mainTemplate.json for NetApp RPS --- .../NetAppRPS_DataConnector.json | 2 +- Solutions/NetAppRPS/Package/3.0.0.zip | Bin 19112 -> 19164 bytes Solutions/NetAppRPS/Package/mainTemplate.json | 48 +++++++++--------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json index abf8fcff387..5d8d7e2fa1d 100644 --- a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json +++ b/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json @@ -76,7 +76,7 @@ }, { "title": "2. Deploy the ARM Template", - "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)" + "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRPS%2FData%2520Connectors%2Fazuredeploy_rps_dataconnector.json)" } ] } \ No newline at end of file diff --git a/Solutions/NetAppRPS/Package/3.0.0.zip b/Solutions/NetAppRPS/Package/3.0.0.zip index b70f359c564977ffc54d63faabc6c4bd952be2a8..3bb71d3de54d06f77d5f4a50eae64accef6f460b 100644 GIT binary patch delta 15517 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 HBZK@Oxs^Gd delta 15474 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 T|6c=fzAPsclI*_@W03y=S6}`d diff --git a/Solutions/NetAppRPS/Package/mainTemplate.json b/Solutions/NetAppRPS/Package/mainTemplate.json index 55f085a2716..1b94b21db19 100644 --- a/Solutions/NetAppRPS/Package/mainTemplate.json +++ b/Solutions/NetAppRPS/Package/mainTemplate.json @@ -34,7 +34,7 @@ "_email": "[variables('email')]", "_solutionName": "NetAppRPS", "_solutionVersion": "3.0.0", - "solutionId": "netapp1234567890.netapp-rps-sentinel-solution", + "solutionId": "netapp1234567890.azure-sentinel-solution-NetAppRPS", "_solutionId": "[variables('solutionId')]", "uiConfigId1": "NetAppRPSCustomLogsIngestion", "_uiConfigId1": "[variables('uiConfigId1')]", @@ -213,7 +213,7 @@ "title": "1. Configuration" }, { - "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)", + "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRPS%2FData%2520Connectors%2Fazuredeploy_rps_dataconnector.json)", "title": "2. Deploy the ARM Template" } ] @@ -373,7 +373,7 @@ "title": "1. Configuration" }, { - "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://raw.githubusercontent.com/NetApp/Azure-Sentinel/refs/heads/netapp-rps/Solutions/NetAppRPS/Data%20Connectors/azuredeploy_rps_dataconnector.json)", + "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRPS%2FData%2520Connectors%2Fazuredeploy_rps_dataconnector.json)", "title": "2. Deploy the ARM Template" } ], @@ -415,32 +415,32 @@ "status": "Available", "requiredDataConnectors": [ { - "connectorId": "NetAppRPSCustomLogsIngestion", "dataTypes": [ "NetAppRPS_alerts_CL" - ] + ], + "connectorId": "NetAppRPSCustomLogsIngestion" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { - "ContextInfo": "context", "IncidentDetails": "incident", - "Severity": "severity" + "Severity": "severity", + "ContextInfo": "context" }, "alertDetailsOverride": { - "alertDescriptionFormat": "High severity alert detected from NetApp RPS: {{description}}", - "alertDisplayNameFormat": "{{description}}" + "alertDisplayNameFormat": "{{description}}", + "alertDescriptionFormat": "High severity alert detected from NetApp RPS: {{description}}" }, "incidentConfiguration": { - "createIncident": true, "groupingConfiguration": { "lookbackDuration": "PT5H", + "matchingMethod": "AllEntities", "reopenClosedIncident": false, - "enabled": false, - "matchingMethod": "AllEntities" - } + "enabled": false + }, + "createIncident": true } } }, @@ -519,32 +519,32 @@ "status": "Available", "requiredDataConnectors": [ { - "connectorId": "NetAppRPSCustomLogsIngestion", "dataTypes": [ "NetAppRPS_alerts_CL" - ] + ], + "connectorId": "NetAppRPSCustomLogsIngestion" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { - "ContextInfo": "context", "IncidentDetails": "incident", - "Severity": "severity" + "Severity": "severity", + "ContextInfo": "context" }, "alertDetailsOverride": { - "alertDescriptionFormat": "Medium severity alert detected from NetApp RPS: {{description}}", - "alertDisplayNameFormat": "{{description}}" + "alertDisplayNameFormat": "{{description}}", + "alertDescriptionFormat": "Medium severity alert detected from NetApp RPS: {{description}}" }, "incidentConfiguration": { - "createIncident": true, "groupingConfiguration": { "lookbackDuration": "PT5H", + "matchingMethod": "AllEntities", "reopenClosedIncident": false, - "enabled": false, - "matchingMethod": "AllEntities" - } + "enabled": false + }, + "createIncident": true } } }, @@ -3616,7 +3616,7 @@ ], "categories": { "domains": [ - "Security - Ransomware Protection", + "Security - Threat Protection", "Storage" ] } From a7c6e7ab33987d3ce0b30bf456e8ea327a4ad328 Mon Sep 17 00:00:00 2001 From: SoumyaRanjanNaik Date: Mon, 17 Nov 2025 08:43:19 +0530 Subject: [PATCH 11/22] Update offerId in SolutionMetadata.json to use correct casing --- Solutions/NetAppRPS/Package/3.0.0.zip | Bin 19164 -> 19166 bytes Solutions/NetAppRPS/Package/mainTemplate.json | 2 +- Solutions/NetAppRPS/SolutionMetadata.json | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Solutions/NetAppRPS/Package/3.0.0.zip b/Solutions/NetAppRPS/Package/3.0.0.zip index 3bb71d3de54d06f77d5f4a50eae64accef6f460b..5da4b331911951cd292db8dca2e8d0de07a82b95 100644 GIT binary patch delta 13472 zcmZu&RZyKllf{F(I|O$K!69gH3lQAhH8^~@26qqc?sjnv?(Xgm7v20@wYx9-&@~U; zH4igYXU;j(y_N*IkpzjNBnu6L4FLfG55X$oSc`Itg79zE-jCC@B&$b2t$>2dhkcWX zJ*{s>--3a8@K6>@$ikTc#E_GluWZq?kgy8HV`u$_z3i%9}k}=s{Xn{R>76Ea1iIVcX@AXSy@74 zLw?LHp=qX!8k7B?rqwL-!GC)R9pH<^_`9if>sUb!vA=D&OhZ|N9IjSW6Q}XBXL%IG zQ}P`4-#aB3!c3xl%tO%*K_o_-O$(_S-XL9=IJxM@W``ec$_|WOpMQwEx54{tI1p6u z|8*@f2ueDbtj7uhezqVlL0rf|^0)lv^vjuQ+=oe3VJf_*`byCAa}B7V)crmxGIE1+ zjx9L8yVCnCwJlT>`o4y`CHh1PP>`yU?F@(nZ9sUOl}Kg;T@aagXVMB{6|1z+>w3Mv&ZQf2pRKQ6%(bJv??j3Hb@gJz zSrjlaJUD1tljw&L9jU~~(+2COWgySrio@3#>Zy%*H zREro)>Z}yFp)mL!t?p9Of&X-|;7*A$Elwlry-8&OaLfFaWj#^!ez_g@=E>F{LuIXY z)Rj}PV^?=DEZF#(!vl}krtn$vG#fK0{Pz~pPgKEfGVk%Rw`yT{8P=9wolOOoT@f(W zfbC?mDj%K&Kua|KxK>NsEZ!EKVtCYQ@tfo_+k*i18~c|@jrL?n9X|Tdfd`?x5RKB; ze#8f0mi95><+{tqJ6of0inX9V$*;+d*^*S;wS4Nc&i79)9Skt6kxZer-fzM2#KuqI z zP%gpr1g)gjyV)xlNnkHV03{4b@0k>}--sIAs1=vX#_c2?E{jltuZeo*+A$q)yR#nX zG(HgPdKylPfvBijC%$~8B&1d9P_E2Mfo?I>d_$^e#2 zY2;bPwUiNiceD8Z811W3>Cqk~AhAQ4JMyy8635mDKE90heYLL3M8ZlFb;&0FW=66bXzt%y|}N-q#~QAC%gSBDNT`|}WT ze~QSkF?&PfJ>6RGPC|CKoz)o}eR31RQ?>m|a9@IDU(#*Ke(Y8)^aU=I?}Lr?TR$V} zC*+5 zy@J1z+)ze8EkJhpLxa|uv)VHkA59nU3>WWoi(U3Pm9d{okc`Ve&eOQ* z1`N7&)KwZ7cxUE4mWk~X&VAMU4At9|tfU5|Xf0EZ+9$X2k}XMKcM0!yfnB99ptbWS zhsEpl2#+=^_Z9}91~t$!fS6-5f$UJ1rOWu(+5}o?^r;wE(P?FET(e8OPD_50;dN2_ z%l&NoA}+CHBe;3U;**`$$tu9h;FGR4bhzQ2ng{yJ5c=aZ|24!r@!lt4KufbT_Bs$j z1h>J2c#EF`^^fkO27|;e>m1at_bwK9quJ{^+x*DJ_ybFt$#X7I$?HTZL&l)sT0w4(b#OQOv;-8xz>R<@f-nV>VC%JbB^Ivd zuj|wDd30j$P?C#IAmH>Tl`(9U1p6wbD0&B6iJBuJ5h4%u=ox-E1-+?_sAAmL+i2_> zz5&?yRsoLyp&9BW@j>)1_(k*Y3zv^Dt-n zckX7Y>k)4R)-`K1M68h~35PQi)_nHP&OVU6B9fT9#WGHD*WGKY1TsDFJ`z?_t&f!5 zJzW*=RDL23e5cAJIF1m9A7leF`rlxUy3%k?x>wFVRs@8{do`Xv?+v<|+dH`LN~j)oIEd{$(Ut8P+xxFO4W%~=uMEQJUlN{cOo)YkzG6fxrw!8X_?ajF_GZ9fQ*=!Ndo{EQ{s_Xg#; z$e%$zVp&>-B`Vrty2c@G-0oJahn1x)k}m8**SlQvJrzip`T|-iBug8~w=%}-Yn~be zXKVZbo2$~T7<5q^H*2>3>$}+(W0L)~z^{wb^bz=HN8(xuy4H2p@~+zK%M$TidZ(H_hEd?!v1PS&N+=^+@y^}MoCxcFv44UsM@EO# z`xskO{_}mxl_I5u-E|*HqJM_KU)2f|;IP|{+CE&c*}Onoz?4kTZ=d`gapy?G=$oFL zqEgCq($B;9Z&y#82R1W^Is3VMf-J@6Nc=oehY5IaS<1d+W4y!f!=;&v$(~I}1R5$v zFUCK`C4(v4DqmU~mc{!Rry?TC&1TT5Gk{dh$h#5^2?j-g2t03uC`j!!c%5qsd^J(> z2@&Kai)fsQRY4jiom#u4C?t&}V^ljR-E!4*IqqsYXcGIqVZOf*Pu{Rry017OheF|6 zxmN^c?{m72(Lqu)5%W0)mw&RNwj(NPAz1@C(7uZ?U6qyhds>yzz6TzcEF`&+2$_>9 zINPc^rn&J%9CSJ4XrtBeinZ1N$8N^fP@YAHLoqyHvpxB75COwCl;Q0K^hW23Hp{$E z2)q=95U6OBa@clKX@vChbf>@+OxgrWE2~@gd^t+j^Yl{Jz8)@yS`d*$5?sA zI6*U)K?x}=$le_@+mIXqj9GFff5)`8w#^QR;keZ({ zTYL2#s}o8)Z?;_TXmUhtB%-O0gz~B zc2cR>on=8Rz`%Bx9>jONNr~ZG8%RH9j7Zz>zBRgP{mn*)Ry&bs?dBCW=CGoVPsTrh|wBcNm+$dKoi_tuf|zHr9bY@=XDvPu?DzV~1BXY6cl>SlV~1|J%6 z3!HG!1XUNSx|K-++_XvJN=Ft_h%d5_XM9xG%+y{Ph2=YAe(1q%nR0B|2QkBCnSRuN zH!;t)(QRz_EHf?g|Jny1mC4s4U^S?|2>xKUX0=K*(eDHRUeC*QBR6bokEmGN2$ToO z`V7W`@~jSTuOxtRAW`R;%gaBU?V2XKIrAa!Euq_+B7q-3t~JRFskt$Yg6h>v!zIIs zMBn$iN{5B(={C*wJzn43e1v#vXuczn(WQ>m{k~vqFQcRSWz(q-gXso~K~Ylfbx1$I z`s_Ht91xAlw>vpHC;eC)Vxic+IIMOwlzHz!ti?&KG+{30a;1HehDvOyp{|=L%q=@* z8*Yc!@Nov3w(3^iH9n^;vDp3ElV5C=+*m5%7gl`p{rt>wo(9DcO?TLvh81Vy z>xD30H_)B~Rt$=7lBVxfhhnZqRBwvxVzMFo^jX`azq~i;yy#*(T%Yuzq+on80P(c|VGrJTb5E z!p3u=PMvBY->)dsntC{raJQ!z+%;BOYl~IRXxMtB@s;J4JCyR&5@%3fJ5+J?J);G; zJGs~L+TB)4a=3S+O7ZgDl(PHBqUSt2J6$cXO6A9M7<0X%e5UAP2sN&;=5%?x$pex^i+9?#D=SF<%?b?nL+jBu|Rs?LG!8LTphq8Z2grac@Y*H}%K+7DqlZNb-6v zrhVmKa$jK_XgoN?$&g@&N4wHSV4lAmV8#Ow#DzR(wcgSPhBYA?6|A1gIb8-ZjKt5tx6+rC$|2L77ubup_pLTkE0<*`=8DA?wGz z_3N=l;BIgiJoFuIvVIhwd?jjTbJh$t7ZNMHiho}R_zjfW8!4bcyDdHAp6Bk7&*@z?UwEn`3?I4QuP8f^uwVJUE(Fq7c^MI^J49DEw7Tj|DW6a4*)^<; z!`5lALQy-f6$n*dJ-k8@3jNsP{mXmN*$E06vfrHUd%`9-zc%#lfwS2Se+4XO+_PRj ztSZP6x&(tDaDQ`DLNRmcL~r$E>3Bxh4}A4!@thiJQitOcMVfS6&`BEl4cEoOJpc+q#4OZL#KHy5jf$CJH+C=-O#YtNVrxIK4! zf}+G40A}W_!};?hFLrBT_JF+&u`WoAWUnK9Ia?V1W~pn9+w~Bs%|E&G$IfRSs7-4T z3X8t+n8qIJ{e6YQDv6mv&0Pg+hkagDSj&*-A6wI*qW5w23FV%SjpGG4wd#G7>v)_1{lG?W4a2K3z-FJla|2a5iPeY{9?rc-*%dQ`Ub{Fn04R4{6 z(4iHbPuEbc2H&-10@!l**9QorPuT3&mCgYlN~eg(PQEaB7s^It>rbtc{vi*#ox#sf z)3t$YLJ|P*=vjF+ikScpvpD$Z4WFQ=rNE5^cralgGNNdIdy=I6gKYqq%&KzZj1gsQ zNRHGGyPL*DQ{U*$&(GcZoW*(!DDtP`z7{ghA+DV`#0sDSY0T%x%HXuNg&Prpap-XJ zDxHB;tSh|ds+j|r?E(h$^^#kx85vpsKerTrLe09iB?)K>51XtfQ*I+YlPXxjGU?v) zOJ3%l2=rQU_1m2Afeq#wKbs4GNng`-jVdED547jjyH~jpqwb z&4Ry^N$?ASAB?m@v%2`1h)d6ip?BMx2V-L?=r6kmjKo~V%b1;o?29s^51BaI9Wdvd zO>y#+3N=C3VGm0Eqsr!FpK(iJ~#kRB}5#R>GDPffCo$vfT z+#OC>17`WDL(Bwy9%!9k%*f@tvPEx@tV0yVPH`WB64=&5iHs&N^=Bl(bug^9(1Ws- zK#*kn5YA*h<0WHZqovKe-6e0uOYQCNG>0>My7@mdcKxbv!$GQQS@&>7Cqv&a>_$+E zIt$N^lb!6CdkbSE8Lj8T(#yYN?DZD~GzbeJjn2+|^|D-^;C6~w;DqD&RMw1~n~~4r zMh%$>SO%ld%;n0&*oRQ1cXa=pTK(KHhI_WQy>{jkBCRvN;==_UZ;&Y7k=W^Z3 zuWt2xsD(vUZh^GT`H`p7^HI$%MV~Qgr`D1=0M)v#sLmFa4aHZ}ZR5I${V#P=0w-`3 znopauQU@BQZ{o*Zm?&!{EoMDr;u?v#;123VE)nyRbd`CJpXNSN$8);z`I1N#_^+i- zX&D`!+c44hV%Z%xf{J?U-Zx%`Jd5SM&z0?ErC+HJYo;h&N9QNX?zI(}D*;5+f%kY( zV6GXSm1!7(4zrokE*3|P_=Lc$nE<~Ru$qx`kwV!$4^gJ1Oksg!w0eGS$F0X+QC4Tj zlVYSim^=Bt^VfFBSxX?la_<*NPP;uYIO;jauvSj}41rmeWm zdW+2l)wTnAv+I3T>W8W9!%aUaqDj1!(dz@}={P z#;jCAq5};OzPmUVLr={M6r-AzVT9sj8$DES;bs94u1Fy7PE>7oK9J{9tmq05W^xiR z5Q0@?)gcXzitJOiJ&m>g60J?ufI4l^vdkau;||HDPv4YXTK7K<4cZyF`_C5wjBt;Q zD{8yJRCJnc6`ADk_zWG>IDP1)S%l#ff79Yr(?b-xcbZSMOFDkkcOV+8~FAu((-{+@e^9hO3&#K+4;2$OB&q4&baq zre)DcaLbf9WiNzz-f;R|qCLSL-`7dpGhVH6wxcjrrr!DgYeDf(D$Pmf<{d_&?FO$RiLI^*(`EJ&ZM~Rw;bsvE0o5o z+PyE+E8a9H2Vb@U6FK+SR=FQk4MRFKtMcm82ke%dG13{epF2ry2crYNT7PlfLuedd znl?MLaMty9hKEer-sMHoJ6U_{Bg&6Fj8#e6GhA9EdTpx@GZXd{$D4diam~NzE_Df} z{saq=_-831c%6UsQO8JS6%9gcz4djR=<^BzC9^H(i6@#VaFVNW82Zjt$CN!RtNc?V`hLV0EqN`J!>J(zTI_oAE@fzxV1)FNq95J4e z0o(N}`^>6ahAWJX!r`9a4yh9{C)+#s0$ysbCj7z(+tLhEqOBtI0s6Pjj$W+EEIVt4 zm8RkwZhPWjpusjYut%pWgNi9M>vV5b0iCj}Lx3-KgG)r}ZjlClnMq_=B(IcABQLVg zPwh}}Y6-E-lS&`U;-`D(N7kdCih(6)?27Zq&I$V^w<3h7#vy7cu;6+I6Z&6 z7$A879PhABvgmcWv&^vhn9HwZftL_#b9{8A#sH;cu#oZ3z(v&o>)j>icH%1zUUVGI zJ9qX?>>n3qJn{dmKw5udY`YM`Z?HIi1$NYZi%^Lbw!h`i;!kx+7%}W2aNBN(am}CV zepUBt;ch)g)#x-MqHFn%kO!|u4ibjt^S3wv6+Xv2oT<|HTZS~UtW=bL={?ys^;y0% z{N;lAEV)M-t%R*?x5#%Iv@XtTt!364#KL-N|H}9`i;t&JH3mZ1_;~j%-VXwlPCmGj zpO0O3Yo`VeuVZ071EJW^xqd}ZhOjICElAh@eFH;2L!=QO|3`IEpuR8gZeTAk>&{oIMfenq&Zj{?nKg*h#+-_8=18xNV8Zktn? z%S5=)>x{7AkfFA{!q^y^p1hj1B3uz8u>PcwY2M`G7;qGT`Inul@~F@TSAL7te3cCT z3-es?`6WGLMdMW4Zgv69=qI!%N~r`+ff-V-Qp3!sk(*QN|Q)yVIf*H1orsS z_0rRRc__6G?3{J5iy>v|<;i6kom&4zU;wAXu7$WoV)!vfoXrm3eqOWo5405{m<~&{ zkW*0l`!O7mV`-8;+L|FjxTbT*$>@!`1L_7h4K(|xJ~gc*U)wsTO5I;CHdOAe;@(f~ ztTsJ0O~d>hkP~}qA|9L4T57^}0Js7ZMJ8><9ro?LC-0N}Z~cwoxne^|TKa>5*K9mrFK0q9*PSu+O^ zvA#xk>!`RiNU|;FkqkFaQ?`-9<(*pbx|e2xs7v%+O^4@U=0dgz4l@ z)*kXMl_6R$LzrOWy5~2 z9mP;NUOysY$bPYijHVaL4q6nD_RP}t=E0{J{|ci@`cHsdZc9HIR=)80t*w&Hc;-3( z-8D)`C8N=@#;Wt-&0gI*?weM^J z`&F4>Nh}Y>Hw*VarOFH*Y~7(E*QAVH+joPA5Qc`!ICo zxi@Z6fBz^=!pb>jK~{jZLAe^ed#D8?=~V@}iw~!&H8&9Rd@`5d5jMyQ?EhhouuSw9J1eoSRN2m1*(h%!%CkK^h`W{EnuXUb%`bj=uACcJ_P&^4;NDl zp!=SKXwM)TDPI4Fj#;+>Ug1)kN5q;CDy?r$J7j7cP)_MeT;Ii)#z?n05id077Q>d` z&|{>#z}PT}Y`So;ueUbO+BhQ3=a?~yqI;mQtHLO-*mJZsY0Pgtu=^>QTM;PY<|x?KcAY$t*!|4i zQiz-ccpoac^eS1EmSdu@oKSi8xwU7$*lPV_Qif5_pbI^jD{py>i_x^Ik2t1FJ zXDIrzBGbbA>lmvo1{a;!plP}-O8uUzhreXBFe36VNvbT)Dy z#YK7Jsx#h6B2_&gsms1+PEfWlOgYvUA`g}=4dz?97uyV@6*6pr8N6TZoVfoEx)in` z_&A%~?U+YR8zX4pjC>-DrQ!*anN!zL_%Z@UvDt|pE4m~N*WCG&gcG$+-`vu5<;!^Q zZz)Cy}oM@+x(Ks3za9o&~g^4#1Al`SY zk@>>`r#gdRoqI?ri-3VW!jVFiW=wi!?&Mz(fRfs&(bin$c8PdDpi}46`n`-ba^5Qm z@>%-62TD#AmJa&L6J5($Dsj=H=^s&EN+v?8+4o*GyLMOA6u4tHzaIAAUXTPf7MimM z@=HRwA|*2hKBpVBrdrZPews&6s=%s988zN97M7L#iQJo^Hhe41mr7BP&06@wHMRhU z^mxuGGnCF09%7@)$^VSGQqqF~dpo(omI{6vj3A1s&XVythzc%TcP})VD9F~oe%R>T zLM}Rv$<)ayYD(_&y!C+Y1KJYMTummW&H`f1x8)bUqpw1-3;+5hz2szrBVB1E?n9_n zB1NHe-15fffODE?%#t$J*5Iw5=J`2XzD~{BA}EHsHhh|f%aW~j1ZlCEmRs;@IAF>B zmc*1x8e@j^O9r-`2q=!Lam28I%QC^eU@>2QN4dt#7Bfa5w@F%Hg^CogeU9w(-)hvP zBODX0MLO%`n(S*%Jo)*{?rYBDl)WI2a+!^MezZwc z*khb(_dny-zVkx_*4sBQ-WD7Y_A?n!@fsHH3bO*7#sVl^h{)P&E{I z1x=p-KDGKao^mYx?10%DFi=!OdrZh)Ho4eEgInklj$<~t*eBX%Pgo9`pKya%1l7%O zA}vlN$!-#;ddVZDE{nie)RP?kWE$ob)BHccZYPKF<-zd3n(s2lOXK}DEKO`=3 z{H$Y&p~(`=V)nJ#3<@Ie8iLYntq&rg9sJ;_|8dZE{z3sc4p?eYGsh{$992=AjM4YL zPcTpVi!s_th%6y%A4B*@pOpV#9-f8_AWkZE!Z9wX7=`5??Q6Wkp1~pht<_G7<{qZs z1WUStaWxfP@;eev^}F6C68_XgivS!X6k~YQ%qYk2BjA&lv&A;1UO++y$iJ8~5MAg=vEbPm5^-EzVSnfPJGP3Ql}a z&%C`^&YSRStXz!f)g}E;4=w7M%sSk;%2(i9pIhttO`sm+Tq3pp8H>j3o6& zLDIrc%r_dE?x9P23L8{{-a)0O%@D!Vw9z>0f7O^{wkZU=9dmNF1>w(T9H@1^y`!z4e+eY zy|R&4PD}Pu|D?sva)+tLvP>i#7WYbCPr)eAWWjc<_wUGXQNHhiX7hT8-${L;E!gl< z@;4pe83>f&t9p3njCyTc)t33_es>-X;7;1Z&hGEAv5L``d(nQ~@BfW3Ygdis)uM3p zU2HL2w|fyAeg?PSj0Bx%!^jS6G(^iun>ZuN(dLQhu`_r1bvtU{B5}1lj>4p=81xs& z*0*iFB&0VW#qgboWc{c7M9~fY$x0N93yGU6jP+55byryRy0JXY;ACi)_UW`;;TIGe zgKWx&=3lIWWZDTCJGSl7h$f_}vq>zx+ziHyQWRG3!3HH5nkJB;nNRb|iDxIe6wSxi zJCea)cOS|ex7V%)X^j?fTEK;q#}mMpDMG0l*taU}ugiDgeRJkcxN12ma?dq9E!CfW zM>#rYF2$cKcHgc0VV5$AV*m3-j=3_Mo2bCUzDN1=VRg=s(0kVEpE|Mn_EZBS`Y(B1 z2d4TayecX0h91_Zysnc)DxNS?-Kk~J!bb&_d`6?4+(wf2ttv&MN!YXN%K((#aOdO1 z){SbZ>^$GnLL`60eK|9dg*)n(8+AUL6_NDK2AKxJpRcioN)&`>cF-wXE2{FgVxf|2 zP=5jfx&y8jZ-i9@$Q`z-yHBf_X}h7!odSk%bAJbu`b0d0a(~Z`p#(>FjF=n;T6^vO zeV=HpdB7RgZ(}>Zg+I?bvIR&~pf?hGZd&FypvYJqr1Vz1S?IN!*f~)T(>t%5c&bpI zv9&lCp(UJ|A1&eiFcCSYDBGKctGx1CaQE+HTXF)QJRQSzR$%H9xJc=rPA?X{?1gL6 z@ROkemwJpwX4>W07{mgiNT8CUdK&v&%^i0AWi>4Gk6+S-ch4$6mjLJWTQO{_a;{2A zte-1hFg!f$9py==g}{x~bIjN*Z-v3V>tC>|T21NJh}%?s==hyam0BbO8*qI4-W8H&6&-hJ?0GO*T6$x zS|cLA8Zf26bhvn_m{>7_ZPw^XLi~xP(c_Ihc`p(${x5)fHS3ZfZ8(HzW!uFbcs;!1 zW_ZlUs-Q#}Y+XlBro2?_Z%jkcBx?pAywwh6jY*_;44GIY*M|eMIe}A;Ys)IJ2H)Pi z34KIU#49Ms^o_}0%N!zfyrOs4`$~BR(M7^-xZw$O>CL)xe1&uc-uB)*+@C+*CqE=E zhgk{`|KtG7F1x#@v^ki;PXB4*WA{jMg^TsO>l&ecKybpctLVOBWPp$nx}TDlOx#xokI6C9g_pspbTCJV zFK!PoWcj3gj|WI(n-Dj5B;Q3`rgbZM3{n)>OOGb<>PaiOW-Th-%L1t)wTcHN>OEPq9}05;{@nvnCl!r+Ed|v$kPO|-P8R0{h86h z&>5jurX-FS@DT{I>9Mk8)p8acn4aueM_yl@y*d~vj?OE|;X8s04D!7x%^%I-gMWI) zyZoD=NJ20orK~Cr0yU8w{;N7|eNy@41ElfWp;w+L78gH0KF)N~c)XvfCYgdcTQYo3 z$i1HTREDn2Hi}UZdp~{p2A)gPejju7GG;~Y1S<|F;_1H+6;I6Om|N^DMQ-#`?rJ?x zOzUqUd6?YY$IYaCdNZbj>q^MId!@ES+caFvQ26%C;%%*&Er>fpAQpREJc4p01SkXi zKGZnx1>Sw>=${=*C?vQFK^($9mL(+z==60IBW;9$kh+Qdj9egCH!j2{X^xC7C;vhE zTL|i#_-6Tx(lJq3(-+|g7W%=OoI5NZq2gV()Xn_se;FdSoMZ2Iuo+LRi~P@6isJ}& zHhua!hLN(HT-K5FwZ)0;dOKtwj{Z2rQW!d&>Qu}`s;_5Cb@&jpAQ@uvkOcCm8g45n zhvT3cp9;BZr=VBTAs~#95ki$mA&6%{lMk%eRbt)$+` z5vJ)QloC^sh@eOLZ8(GS=8j6H)~YD<@C!eYKKx_fFp$TKa2}kS>)P82zJyaYp!(hzwhW<9_=pi7WOwM995zk?%jJ-sta-4C@XvIM1zS>vxyS z$@W|16|6%hl|J&imeP>R8+39r#kO6acl3SjwY;Pq08M`#A@9$Xx|zaPqMVu7wpIyU zPnyfMBiBuMt_ul?&qcw8K5nD>o9+)cBTP~@+FB)>UcqQVPG1I8JZwLL=%GtbeB{;R z?4;7|=!O$Rtn|q;PeV9WL!nJ%rZW9qR5-qRKxF1WjvW13h8g^VqDGyd0vDlxKXmqJ zcvB~eFQ0@G=uL`G!FJdwmxxJPJPYGg#*F$WajEX#D6l5@^g?rT90U@dIgIHT z`|C#i?f-{1Qyn8cT&=}B|} z|E~QqW0VoV3JT(t^5ytHI+~ktk7@*XX~bA@zUX<7A`^0_A#WCSl{4$nYW zQb6%OM2L`KW(wa*mG#Klf=>2CIOZ-4;5_H+B4l+q z@+fZ4hSBgD?Q^3+tjj+j2sKP~5FYFr>Wi5R8FTrE0}$=i{w^~(#!rZCUm7*6kHj8* zG}(dDg+Fl@^SMyH);#!S4Bn&xzP=hq(X+m5=;t^S zx|^+EIq+s0t)N`O=Ti_R3IbWrW%>i3?rV`D2Zf%Gu&hznIY8`+#G;^}QTqG7O0A zihY}j*y>I&&Aace9z{5JQ%5ozrp*s`C!iWp;StH^8} zdf;jHS0}eOTcZgNbf{L5fv9L*8VWQfnz^cYVmqPY%Ic8KOQkEe8R&PZav&jsr8!W=imOcIRAMxv&X%_EK9@=e5V%(%lS^~JFqls!wS^@T^GTx7opos*(*eMFo)LT*4f zBd4>&P}>MvCVKEhKjQV+tqd<;?_6L-23RRTftV`X^GNU-hMlz7X6d^)&DjatDMot$ zmZX&!dqxsiF4w#cF$;bjh34ZvwEEjCpd3q=3RJ$bdtjfq;NOgP1GZ)x+Pz!~FMZ6EB8w;5Wh`RD*%hTs3we?La`9?SZNH z@h0V=&jH%7`2yRJyKTK+8wmdQU=~A}zYSay4~Y_64IEguwKhJc$)0Ru!y~>uRAj8C z9Z%K|%7ZgHpM@t1jJ8Hl;Sypuoi7(JiykV@9aMI0vd5mTJ40%zO1_645wRN zQN9P>2o?x1U7)(J9%fL#o+AFWYjCO1c$zGc^;*u~ z3+v|73rs|OJ2wKQ8+5{-+F6WSums|}<|}bF(!sFCwE?rXC!jj>Ty5^BZZDj?{El!y zLWqtJp?>Jhs>vSR<{#y_)L?lfkFo;>7%u$~kNURMmSt<1x34P6KTpd~Hc}d#MMZfzKg^QFWiA(PgheEp^_f+JPJHw~jsSQE?olw(Yxc`F;P?GKmAO4kyX z7ZQ($ac45y?P+Fi9*uYm;CKRB{$_qE`g1T}<=vz#r$g$lIL0W2yUrjQ*=Jd$Cv=j@E?LkvQv(2_Du70W}BRu#5`~F)rgndZiGe z*ql!`FAjCIHGCb!c%{r$E-_2(L?6ZeK|`43NS9u5xr^Sp-dl~&1_-6Kk9K3nkz#=R z$f*4D>1Rldl%u~>C%uYPy6y2I{4{^`e<|ASUMyzd43R+Q`(bN>6*4W&f-ao3WlK*d z0Kr4r8gJauO11sdR>ugZj)n->fl)V8jNbU@mv~653Y-BXC!x znuxDVwzp5S=R)lf1gt|0j68np^m4ZhxrBWV^Xj|)wRb4LN4&oi>D;@i^|ffE0DF$7 z=RpraG;P8B`bE1WJ5-?UwX(!*(vvFP#P|9=^!cTI^IS(~1w?+nhbWbg=jqS?V%Q6} z$G^el+?nuQZ=3M+)pwI6bd%k7l~$KS6)T8qXC#-j@PRssqSu39!n7@bDV-zJ-it(c z?DNCO7H>P}<@nI5y~Clu+XGE~^N02ADdFFC3D(YtQy*-dU_oHppV*8=bjRPWNiVAk z4Xc`y&_2wn0dB^QCP66HSDT&ktk11=*GJZPhf>~^CN9OX^DHCkl10>;eTueQ@?|y9XFU6{B-Zx&B;$0znHu^9ZLq3at{O;Q#UfR>|fH zpcie4g2CgOm_$O6ox*co4O%z|$XQ^3_jC8FyQr!oTpKLk$_bc@@wA-+k|HlnFiDiI zhjB>#QpCk8o_qvai?9aPx--dq4k8?~E@{3J?X+?#2wMMK60ZCLw_$-gW>2>kd|#jY z%I+2o@Yha^S#3uPt&xrxqR-l23%#tqz+bs=GByD#QE8a`0Zo(TS`xHMS%)ZNB8lQe z8LITT;y$A4e3-02CLN-6(y9K2iR(6Zq#bwVWt*msIy}h+~;568%9`}Lx4KFP9679)#SMGw!Z9ug?7T1L56YYiMsxSjO2Ar_-W*a{C8BS*dGr+rWYqqW3$y<#yvjfS!D3f_#AKyywQD`dQCp=a zQPc7(&UUmYp4G&bljdCl_im+HV^mxSLn@@XjwYo(eosXI2d7%Fgx!V-c;WRr$3g{q zD0eg40-IU6cTm}r(^lr0lPKmss(_s`{$xAR?NAZhV!)*>R~_rpR83e)-@h(!z!-{6 zfYqSV`+o0r=-Qs0Wl8ZLpN2DjPGNXotXwhMYBPDql1VFik}fHgR*|lC)4N@ao95${ zQRP*yMVXyh(>|P+a*-}wh&_!s50e;=RWsXKvv`L^V9l&ulsJ!2{fz%??b%vG=xVLS zO%%5kw%ip974@F zv@&h&x%%<&VE@Ypz8IP3t-Kq%HioNo)&StnG; z(!e7Ofej(-zhjNRhos#AgbTI1)D>rM@%AC*r&(|f1f@En*jTcs{h%1eNpqPF^j4g62K=Jq>5D4@V}mgD&E-$31N;%sb)(*vMK0%*0$&u$-3L z^JKDQSv$dM%KuuCf8MmehGjHM#zm?Y-#xS@=+l+XC^wkn5o)OcB9M#bD@peS8Z_`+ z&HfjlQ+$L zn{Pzf7t(Tjyze{8N%SyfW1kz)zbUl}Mou77Dm&MW3Jj04C zzF?o*9zn8Ll3}v|KaLjid~+|qkMJaW@vVi6tb)6Fe>^*QMV^t$EOM{-cvPp#r;F%c zMGuu}AK9stA@k$mCl5q-kd4#Lp48%Lqc@h-HjdFwac27#BXMr`M)hN)q9|B!tQKZrdz?_yHScJR5NW%?J83cg7kG zqMd~O9o3-PfkxuiLG2)Ul3lTuF`9Vy7xht^)(Se;loEaTMGfh;#DGoOSOGOTRSXV} z=bO;P!p+10cF?B_`wTOu!o;Gk`kxc)Eh@;eC8h>M*~a- z6$JftdLdbWvhX&O-9FdQUy0HfKJLIzxT#9fp?a50&GAR{Gu3@pI=T-V*Hb5T0`Dz` zVweg%%)s;W+mnqNcWv7tJ)MM!D2QtSxL>E**>7+3(5OA7mJW^3!we&Cm|w|eNfr6y zDyx!UgmyKMY)Mb%J@PF+f&O>Q~GTpw?Bzd}!Qi$-7_vcn^=esS&xv36KvjT^+|ocikGT z(J8Q0Qs$d{_bK3uZB02aiJ*>QYzfxCIJvxC$Y02HQhj}H4z+RUd(gWL6wwo(De}@^bMCL z4M(uIf2f7muAyZy3duBYlPoqo6^cteExtde6+Lg!xk=QgE<>-Dt{4EU9c{wxYhx3w z>aVRzzsE}K8!^+NQSJ9UCM+4&1YjmHncD^cB$;7LXd3+`N}`Jt%Ui{IXvJ=*I!yy4 zIGv-@w5`uiUqpX-Z<+0a1=WTXQxm?Y(m^q{dpZuhK4O7_JD0&h;DhaLJeS||iDH5C ztTcA(>K5?5KtZ|k`@+F2J(#XS(hgXaUUITBb`Q)W6^ww@CZ^HFscc6G>WuPV8mc|*b*Zy_tYe|Tyne*Vq&PBee7jXcy+Eh3a{sKsfhN&o#?ZW$arzT*z)G1wq+_L-L#Lx#(D<7+W=`nG4 z5E&9JacPw;kr8SF!%A{+y}5_%z)-V;k%y9}V9B(^s4jb_WlV2Nj#p5(ya(voy~|?W zJXyBVy_me94y7h9Bx{z}t;5(8))qe6P}-MQpknUI1JDJ8HdDaij6U?}@yh_%fK?Sy zDOf^+LwedW6Ccwt-gG0!6X6VUsjGZ}g;~NO6R{S%cLX=FpF{En`%sWEN0)R~J!X0v ze`_72H~P!4hV1Jq^-@Kf*P%);!RIXk4~J|K}Ke94@=L;Cq|AGNPh*vR83cnQvQ?xT-dL38D_w;_bn=2uESHMB4&R_ zF$&rnzAl!}FP!yyu2abxHr@m>qH|7WZC^)Gb&dwPqU4gsP(-G2tjYja3tRg{lbxin ze8HO_O8yFpv7;gQukrYZ+nRFS`0z;4>A8E$<`!_TbQ;nft@u#6WnwO7ePd{7N|N0a zy2ADYxECxcqM6x(sKqoZ@e9VBndDS5`6hBguaJFQlFNkok%d94Ad6b3J!yw|qu<{w zGR?DmB&``ggsTQnuZMtRWs0fmL)4r4pc;_xBgL<=3g$_vG6!NYwYyOCQ{xdQd+@7f zkh_;#)%Jfsg8yj9eKe`?YHpovU+%xNHRoNBcq2HXmqIf5v}xsF^AarKNcD+TEh#J# zOgMWq`yy=bIKLp~HfHZ{t)E+ad_3XvMaw755)ck!+VryLj^+X6G0Sb=b;CasZ`MVi z4f-hOsb`D^4xtG)#!8MkwRKQW3ZZ;$yiM~-nr`sSr&K*BEkLT7$=}pEeDynHo`<$C ztV7v{zXgpyb|uT>w}+glo4-RwOfrtyyxA8b9qJ(v^Vd*!nmb-;Ik)}77>Jk^KPY6o zQvZ^89q<##2+9Fhd=I!thHYW7eGB4$oTJd<*tTuMAK-Dca`;Dbj}0bjPFyZ2sF+gS z#dvihdBw)0Jl;+_q3i z3ELxDZ+;)eAjY759mOo8=4caOB3YQieVR1{H1mvLoMYaLy$I%orv>}7vyD|9az+Yw zXocLs$}ItIBD^%v5WACV^jXrM&xp;ny+p?n4!ZosPzwIc{do)mT)?D3pCs62U6uPf>rZ`?d84A$ zpH4K0w^emz`L;(8GSoksf-L*=+l6a-YY?Eu_Tz!oxm<#jyb5bN!ohjoc<8-x)o3nI zpx~O?Rt`z75^OexTi{ns6B;x(A()rN6Ruyfp^}$f$CD3NPr3ToTVh@Dn0icC85L4= zS}LIdHFlOa^hip}ds381ECBwrDak3WW-5ICfUn}0ySdLy)ucb6f26x^7Xz#hSgZyp zQUlFSdn}tFeHH#Sbqnf()R*GF7vp|QsxE5U8&vw)99*St7_4cJ=h{&n zFA?j!c{DYs#gw;Mp$W;^P)oudH0JZt={BaNUiy%fS;!g_Ip=##AhmOyIjN)cW&mo? zzhv<%A70EP3&&t>esuBmPuTSR!@u%DJi# zx+I_6O)=XW6KRd{ArvfTnJ}&GWQ*z&TFIrFWA3^XmMphP#^u%28`+mfoz^y1g(_KWO4i)4Yx@86Y`Y0ox5)E5m+_J+WBX&AP`BPY0*JI5jQ-JSULLAvdY$R7> zN7}vN#>>%!v50;KF~N$$IIlAUXE}C%nQ^K0PjV2aJ7KhrnBB4JQ7hHj@!ZuH_GwM+ zf{kwVon2=}8;c7Tht=hdK^ush>C|+|C1?n77HAn3ptdpAK4k?d{292}t+^giQEwP~ z7!@F4QiKB6!SF|^1f%rjp*oA0Nas!VE$tE(~}HL zESVUG*^4Xa$JJ$mOIWK&z-q|GmMXD4fuQxP>JAyFVVkI8WM{+4@(|<7RW#Lnc`w!1 zuWpL_$1;&a(5ClSB9Wh8=m+=;6(3<<{s75AkgVya~!p z^;LjmZ8@E!3sdXBj2mDczDBNq_8eX~!oP`n@E;La5eCj=;t%f5gdFmxtCmi{mg^=A zo~qHC^urY{4;^T1Ezl+CKrAydy7`>@6|E4@jiQC6%IZLhxisy=)8@zyVq5pDkmb`k zB-CzLtashpjSZlC={RmQK0x=~q`px0c&j=kGi4;oX=L$Y$^z2i>3V@vNhk(y3H&UA zPfrs4u<11#?X9)$*FPVJbgGmNvh0A*u5thO;x_{!vdX;#5%1WbnM?*rk_m^sKsL`2 z%_ah6>HKTDk?{6IJQA*t^*74(vnA(fw8xnvEKBETQB+z?7WhM~0&37mmB2@*=-wid zQAQNDEX9E|P~haqf4qYf2D6lwo8h=iiJJ`Spyx)iCv~3}32)oKcSEl8wZG4r0&}cb zQ?np&I!y@Ll9rN@Be&3c9q|Q*eT5x*oDpyFQG0Grg(BmE%w{|x;#hCJk&JXH+zBWa z&#_lYL&7^-DH{k!NU*S%EKFF*k#mkFwR0rTEC|4(02nM<5;pu3@QFCh{8_`(yim9i zH^j`ecW4_lcyN;7$wYFOWzr~@Q;owA(NMo)FT@{}9MwO;pDwLOV*(SRuB%`+5G02) zi2n2u-d>W?6@Za```QH4=O|_k9lTE(6|$!f6?0GZzP2wbXC1fjlNeRVuh7LdgfF1J2_CC3>;wzRs2lLCk!Ok|D5 zN>`)rG#PvICkW$0&ct>nQ(?}pxjFHo+GmAQfFRP<@5G*Df?0|=+81K;?LNf}<8A5S zi3kLrq>pIatG}3DTy)!pIMJx)WnD(J0Ric2jf$`miD9QsR_M;Rl&Gyx*iapnq|3L} zQlj_BMQ)4a>eq-6_ l8$gvEVvqwDL^mb8`owC0a63Oi!+X1N+EQ9*>rD;Z4=YLn z>u#J_laC!z{Z1=wa^05@zY51Eioj28QG-PR+raoKlwds4%(notc1}1A*Ddgvn*2(M zJGKC`kmV}6a<72Sug4)jrp51@;WF0L@1F7xAdyH&9RF=ja>o%3_vDShnYYk6H6uFtV)>jwmI;f`+UT9)I&7){J zx7ET25fQBA(4C_RUkGXKAItQyF%BuMRIQGBPhMWn-*zKCEes4@K7h`{Bp0Cny1UqW zj5;QUpLbs>-pq)rL3&?Z4jKG_GR?SVF=O+PRqbSt>7Oc0C1yqEoTXctQ2 zxhv;`GAgudR(`9j04jN=#_U5UIJP#tGDzRHwOEgG3u#b5Gi~S?%Aox$U2O_lyA3_z zS_M*YmH;{ zh7%rB5=}H)kj+Yvzl)!lkI;A=-B9=uPoKykLS#E?SStjlvoeWe!{99*QdP7TTb~Hq zvttc1?F*$I$(;sMu2aJgEj?FmQ@98_EAAsQ2C8H#TmaG9)94a`Unx@M%D%N7sRDK$ z@hW~%KZ`8uM9zB1I0meE^xT^myvt{*s=q}{d=JQBt9ozsGXqhpg*YbQzi8MEdx?;` z!=Q_dqI%q`N-WCqIYGT%6UYd)K*>cidy?pmsip4>s;4+1w4GHvKqUBo1z^hK{gpUk zCYuxGj%Oe&nEueS+p+wRq~{OG{uzs^vdhf?lB<~)BgL1 z%hJ?)N;bYg)zaOPou62z*=y_3iUqn-ILaTxE70GC!MVboj2t5wF?;~g{1I3Ek|ADN zk=>zL+&3jA-`IalbOoDjukEug5n^9ui@nVr7NJ52$gXpD+bSZ`b=yYSc&Op!GZJNATxOIEdjXpPM^U5e#4RpFh^}7svzs4N}3a!K0%wUy>-8Kpj#&Yf#Hc z`rf{j$5c}B^6F4n5b~Ukh~VLW4ah4&ZZP3edmZ>_*XOSq3hq{3diID{!@_3vU+Zc6 zZL+!iIyHL?&;Dy4w&2qZIBWYL%r*h$=VCCeKyPCf==2q~vLcV7c2II{{_xY0w!O(}7cBr9y> z+?-g{&O>(yYE$X2c&^`FrqG*sfa|NwDqm~@TESSUoQjtli|FjZWpm&j!LDqJ#W}(= zdxzW7Y0Opq*!lD3Q@fqk!2sNf=CtriG%*2KCAMoIn+wa)M81SeYo!x5#zqzA`5gM# zT*pyptP$bf5spx#IKi^G8jqIsm6%TJ>7X_*r$qJ|O&pD4Q7p|H@wQi(}A>mbs)>MfBI8 zBxsbCE6MF)%YIvd>JLf{fJLP=!6D;F*i2F;*M1s$xFKA~ha>@zgb8X2lE+d>*fZ}5 zh4q3ZF&7F-mHRS1M_%KI`Zq7q;&3&x^db>rYeSP$i=^oOVq{BEIvmQC$^c1_5F^ca z(%mbaqLp4cx6nPXJ7+)FH&_-;{t=_z`edZoK2Omh056vbhlVZ*D3HfzSKItP=L*Kf zSze3Q7-Ny;H!x3V=b65+CbxBT={Ou2u2nh{YT2a>b4aw+=(OsLhai_pOF5n9w5uQhfe5jSYaiK|L-VM*RbYyo|AXV>Y`yGS7-M&pb8Q#P^RA7pFErd*U z>4P{yfp$BxR_6`__`~W{(QvH0U3Y5Vg@@$o;F;6$$r8Z~4=DOURY6c23zFsh!SJGQ zNJbJ$pmml?{D zGC~_X6mmd@xcj^+c**%8n_NtWh&nYxc=L*bu!YZFm8eajq_lPu=6=Pd~2ixKdhI?Z%0wBvIdJ}_hy08o)uhZy{wSJK3cSn-Yx5UUY{sW zf;AIpTV{xa)8;WG1QvNgC;U1QxYTQH#B~DfW=wyAHR2_T679h^jQVb|YJ24K9&o`? zjQU(OTjcYoky+xU*6>F;gW_%w$b5Ir|ls}sCl`` z|2BW^e&Vlc`crY)k>VOG%q8;HmPg0Z#$}9_{lpLT@MEy&7O#H+I2`?|7zu|;Cq`=b zR^%W=IEX|>!+dZ=f3xiCo*(UN*SiT(X0m}&)j5>chwv+$!hhMs7uOqic$`ghYG}bz ze^L;TPRhHf7X$I|iAEJOsMVQ5$18Olig77;DaJwhL8WX z5Hvk_?D7Y_jGiz?BKniK@`6C%FP=*FunQmf@;>t8tFa?w2nKr@^h@fsV9pXzUA!0g zNiNB~1;GXqez27eNn+GIca~~2uXUUew5jRgtg@jZt3rI$+W<2f~oJhq6 ziIN3@=HG$`ij+Y>hc3xj)mvbDi+BQ-1X*JH#*KprvjfA%QVuG6vRan5LkiR%6*cgl zg_rPmq`Ofc^2yFxlSvr&#Y(^m^t~uVn1SyMs(vgrnJ$(;J zQxe*bOTx=w&3BBW0|i65@q0w}PVyNs#J82Fail*2z1}u``dT+>7#}4+08JppqEG(` z{!0moVqj?1-U!U+;|rtzDE^nt#n5P`+-K%1iZ*S=!gvarjgXPs4;1Hm&Zrh+2?J^x zFpF6g_B_L=Qetk>L@NqTN-T8FM_czN1SlB_-s*y8Xol=Lx_+6cn>pgnCTNDR&(J25 zF{0cl?a-8(CJRQ#B08Mkl{P>WWYSfMSditcf#?;_e@WfF-sSLzbav!=gAdD3L=M@( z$rhm_pEOfXsR`;|iPE#V{ZM1nl|#5^PHt#-S5lUnOlQ1&;;s)n54K}<$yxc~BO5?u zD`c|-TE9zo#9m-iPS!e9zlt>y+T*y5n>j_erEwwG29Jj=Z03E|aRIz8roPuEfE^+4 z9(TT=ye*MJfU>uHZ22GQks=b#)>O~gsymQP&`K*?aP2hU=5Qf2ZTCVRQ5gZ+&vW|UWb-(G`;wb0K6;K7BSrrJ&C2VxSkTG zwzlLNKihDZNPxgcS8#&_%dJ(Clx}#FxILuum{#gYF>U710XrcZ-q&#S@+s{qH9@vr ze~UDF)*Adnj~PjTl7UkE;#b)!(JI3sL~Ka(!rL8o2bfyf#RYa3k3l*RYD#EYXn+op zbqE{`>g#9c)tVC+tphoQhYj+$#>s4%1>j+P@Jg9@J(~49mH%%GNB6~bHmtRNz()z} zJb&B_edN{>z{IvAi%lD+eMxt73l?_J41bZ>V2UfU?@+snYag}0mM>o*=FF$Sy6lt} z3PM>R2u{~v9d*&p5oxWchZynB6<&v#Hd-P}#ACUi5ZH6&*YykukriP`#TbrHn@Za? z0a3(Ey0Y?1VHHb<$HpC!gWzv)3VUXE9SrNgE$+ZIfFJe?x^c<`O7)ewznw54?HOZv zL2)lh|6O`hcy~@;i*kccWH(bgw128VW-+XRr4=DWdqD&?WLV z|CaawxNGc;?ymetSJLx3Ay{}2ll1Fg=IECO&FF#{GzYp@UgY^*m}$ZuT{J%rY7d|; z)|U~Bg)p~C!a<~zEAffmBu5B%(&1(($d~;UDAQX%xwtGOr z9(PZlRnw_CM4{_c7_bGPPfFbC5R$I^7o5Oq8onnj%$Kn6p`b#v}A?o zEPB}pairAkfYZfFAN*6^{m(Kj?Ngz;ey&+$K#%v63)*)&hwlf>)BJSVEQO2IAkN(_ z+f!fN&$7|xW6mwU>_}rcM5BMZuC9e<4$CeN9 z#QL8;R(!HCXP@v-Oqtq<`G*H##+zDmyqxfbSNj1_{~O<}3H=%DEBmK>2QwQt0}jSq zZ<9s~U7dlS@9~GiB0+!7(~qpg1W1oIa((#c1a9wV|B9virWYO|>|gr_Fqgk!IxBFt z@4mT(Cz9VbL=(l_T#N*FJ4H*1yrShk@3Ufw89uAyhPL;y3CYKO(L)-1+oVqD&AIfZ zw;=Dcs%AnD`23OMT^mJFa0~?}L`6YK?{cK|PsBogrlTZimHDjlH!aL+9x$cqE`}?< zL%Of~zTo+W^S`swKZ8qHMxZETK}K`LxX(RNmPCst!qCe0|80MMO`-RtWTTMv7iesZ zh>T)Xr#=<3QK;a3;%!XLbn(I4=lYycM!r=9*)d9q}epCec*8#WPysrxh3DIa` zVh88e>yH2Z`kNai;5w5AwCzLAR(`p7c>w^!rgh@+w4ADDs(et#Y8gU9nLNKMp8b*U zSw4}E!%dQWPTS$MO)JM!|4i0*@NduCL%`>Z_tP_!JhtnEj+VK$4%w)C`q;?oVjTi5A>a@f+eFRX}1(I~jo?C)aAM4NKp4eCW-OnG|$IxMje zF$_n^MEQ&cd?76~(h4Dg7&o!H>h{=KY>9M=HGLc1az$P06ZD?TD(}JgWJdm>iyA(q zJHUbmy!a&12<}}qKftBie1w6bc*^!ZmK^U*~QZ^B$1z{;vx zoIcl!MZP%`cYLFm@_t~fA0~8~h|v7IqHc^kM>G#@xw!z4bCV%}+ifgF+;LZ(+im>y zn8MF0j{(C^1Frg-Kb}ZCaa3i&Bp@2~I*ooChi~l!YvS?KELG9iM#C3uDXNzig8?IZl6sIQdr;up~? zpA~=Y_R9?buga{V!LF$Urz*gqBBgx5k0a@;ii;4fjIgDpvi`Gk%HQ=3BP-W&a%|8itob)3kXP^n5Ras>m zJq|DgGp=yz5#Z%;ks>I!`oP96C8hDz_$`)#PWM_(nMjTscukygqGT5-7L}L_fn61wW zp%XC<6>x4`EMJrIKfT5F11e#oGo-R?V>8J>L17O&oYXmDgbm(kDJ0DjhoA{|qMS)A zIlQb06n$EAH$t8%s%R?JX#-dnm9MK{FvR4Ff?#OEp2!qwk|HZHOK1Z#?{Wb~br}_W zs0copXqilCDRUk+F&<9PQHBjs#qbOS_l&8gr)j#9KH-TddB)q0>ccyfD)U2kMJF>L zB$*y`;I5noSy|u{em>HZglbZrBavsABCA25oT7rADwSs9$|+h(KE{j${pn+8l~~cw zeVSM;d`Zy@Sgj#fTW*f>^O7%CAQY60tzr>})agkfDkNg89su0f| zqY^Bn6vux;fE5Y@W%A+8`ypvN`ujf}fc*20BT1pl6k3_8%Jp&&#+o-%C~f)X5za7NtZg){hc<`t;&-TGl%y zNfH;!Qo3S3P9J8g_WRh^zTH;4K8vzPRd>f#wOrdqhz3jvN=v}ip;E+R!CW+ni7%M0 zIoLIQoj4({IoC*0>+*6ujnzUg-a^iFz&o?k<*oJmS`f{$76gah${^`Oj(p%7v4qst z9J!g{g*66dnk?M*Bw}8S?q2Rc(wn2i_M=>hu_j5pVB%+1_A0E1G$iWuzrrj~?$ucz zy)cR=zpIg^dGn-;NPhE;wr3!coeT;kmWOSj$|LPNj)&Tcn)KHqG!oR)a5@&Vqcv(~ zOrv>`SItDsY#Q9@121m_-%tuNpkQd=|JQJoq%1A`{~3;wa;3Q;g{A* Date: Wed, 14 Jan 2026 09:14:42 +0530 Subject: [PATCH 12/22] added updated logo --- Logos/NetApp.svg | 4 ++++ Solutions/NetAppRPS/Data/Solution_NetAppRps.json | 2 +- Solutions/NetAppRPS/ReleaseNotes.md | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 Logos/NetApp.svg create mode 100644 Solutions/NetAppRPS/ReleaseNotes.md diff --git a/Logos/NetApp.svg b/Logos/NetApp.svg new file mode 100644 index 00000000000..f9f49b9771c --- /dev/null +++ b/Logos/NetApp.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Solutions/NetAppRPS/Data/Solution_NetAppRps.json b/Solutions/NetAppRPS/Data/Solution_NetAppRps.json index a8ba1a36306..608925fcfa4 100644 --- a/Solutions/NetAppRPS/Data/Solution_NetAppRps.json +++ b/Solutions/NetAppRPS/Data/Solution_NetAppRps.json @@ -3,7 +3,7 @@ "Author": "NetApp - support@netapp.com", "title": "NetApp RPS", "Description": "NetApp RPS (Ransomware Protection Service) - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.", - "logo": "", + "logo": "\"NetApp", "Data Connectors": [ "Data Connectors/NetAppRPS_DataConnector.json" ], diff --git a/Solutions/NetAppRPS/ReleaseNotes.md b/Solutions/NetAppRPS/ReleaseNotes.md new file mode 100644 index 00000000000..5bcd8bf4bf1 --- /dev/null +++ b/Solutions/NetAppRPS/ReleaseNotes.md @@ -0,0 +1,3 @@ +**Version** | **Date Modified (DD-MM-YYYY)**| **ChangeHistory** | +|------------|-------------------------------|-------------------------------------------------------------------------------------------| +| 3.0.0 | 16-12-2025 | Added Initial changes for Playbooks, Data Connectors and Analytics Rules. | \ No newline at end of file From c8349bd5d54fbd5e390d2f31515d744504a2237d Mon Sep 17 00:00:00 2001 From: Avinash Bharti Date: Fri, 30 Jan 2026 09:39:46 +0530 Subject: [PATCH 13/22] added updated names and flow --- ...NetAppRansomwareResilience_alerts_CL.json} | 2 +- .../ValidConnectorIds.json | 2 +- .../NetAppRPS/Data/Solution_NetAppRps.json | 27 -- Solutions/NetAppRPS/Package/3.0.0.zip | Bin 19166 -> 0 bytes .../azuredeploy.parameters.json | 15 - .../azuredeploy.parameters.json | 15 - .../azuredeploy.parameters.json | 15 - ...AppRansomwareResilience_HighSeverity.yaml} | 12 +- ...pRansomwareResilience_MediumSeverity.yaml} | 12 +- ...ppRansomwareResilience_DataConnector.json} | 26 +- .../azuredeploy_rrs_dataconnector.json} | 40 +- .../Solution_NetAppRansomwareResilience.json | 27 ++ .../Package/3.0.0.zip | Bin 0 -> 15964 bytes .../Package/createUiDefinition.json | 12 +- .../Package/mainTemplate.json | 434 +++++++++--------- .../Package/testParameters.json | 0 .../azuredeploy.json | 24 +- .../azuredeploy.parameters.json | 4 +- .../azuredeploy.json | 34 +- .../azuredeploy.parameters.json | 6 +- .../azuredeploy.json | 41 +- .../azuredeploy.parameters.json | 15 + .../azuredeploy.json | 27 +- .../azuredeploy.parameters.json | 6 +- .../azuredeploy.json | 41 +- .../azuredeploy.parameters.json | 15 + .../azuredeploy.json | 41 +- .../azuredeploy.parameters.json | 15 + .../ReleaseNotes.md | 0 .../SolutionMetadata.json | 8 +- 30 files changed, 448 insertions(+), 468 deletions(-) rename .script/tests/KqlvalidationsTests/CustomTables/{NetAppRPS_alerts_CL.json => NetAppRansomwareResilience_alerts_CL.json} (89%) delete mode 100644 Solutions/NetAppRPS/Data/Solution_NetAppRps.json delete mode 100644 Solutions/NetAppRPS/Package/3.0.0.zip delete mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json delete mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json delete mode 100644 Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json rename Solutions/{NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml => NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml} (60%) rename Solutions/{NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml => NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml} (60%) rename Solutions/{NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json => NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json} (60%) rename Solutions/{NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json => NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json} (71%) create mode 100644 Solutions/NetAppRansomwareResilience/Data/Solution_NetAppRansomwareResilience.json create mode 100644 Solutions/NetAppRansomwareResilience/Package/3.0.0.zip rename Solutions/{NetAppRPS => NetAppRansomwareResilience}/Package/createUiDefinition.json (53%) rename Solutions/{NetAppRPS => NetAppRansomwareResilience}/Package/mainTemplate.json (87%) rename Solutions/{NetAppRPS => NetAppRansomwareResilience}/Package/testParameters.json (100%) rename Solutions/{NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook}/azuredeploy.json (93%) rename Solutions/{NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook}/azuredeploy.parameters.json (77%) rename Solutions/{NetAppRPS/Playbooks/RPS_Async_Poll_Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook}/azuredeploy.json (88%) rename Solutions/{NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook}/azuredeploy.parameters.json (51%) rename Solutions/{NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook}/azuredeploy.json (89%) create mode 100644 Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json rename Solutions/{NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook}/azuredeploy.json (90%) rename Solutions/{NetAppRPS/Playbooks/RPS_Async_Poll_Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook}/azuredeploy.parameters.json (50%) rename Solutions/{NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook}/azuredeploy.json (91%) create mode 100644 Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json rename Solutions/{NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook => NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook}/azuredeploy.json (91%) create mode 100644 Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json rename Solutions/{NetAppRPS => NetAppRansomwareResilience}/ReleaseNotes.md (100%) rename Solutions/{NetAppRPS => NetAppRansomwareResilience}/SolutionMetadata.json (75%) diff --git a/.script/tests/KqlvalidationsTests/CustomTables/NetAppRPS_alerts_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/NetAppRansomwareResilience_alerts_CL.json similarity index 89% rename from .script/tests/KqlvalidationsTests/CustomTables/NetAppRPS_alerts_CL.json rename to .script/tests/KqlvalidationsTests/CustomTables/NetAppRansomwareResilience_alerts_CL.json index b8a357c5718..a3aa7879ff7 100644 --- a/.script/tests/KqlvalidationsTests/CustomTables/NetAppRPS_alerts_CL.json +++ b/.script/tests/KqlvalidationsTests/CustomTables/NetAppRansomwareResilience_alerts_CL.json @@ -1,5 +1,5 @@ { - "name": "NetAppRPS_alerts_CL", + "name": "NetAppRansomwareResilience_alerts_CL", "properties": [ { "name": "TimeGenerated", diff --git a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json index 8ed7a699fa2..10a012a427e 100644 --- a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json +++ b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json @@ -284,5 +284,5 @@ "CyfirmaCompromisedAccountsDataConnector", "RSAIDPlus_AdminLogs_Connector", "CybleVisionAlerts", - "NetAppRPSCustomLogsIngestion" + "NetAppRansomwareResilienceCustomLogsIngestion" ] \ No newline at end of file diff --git a/Solutions/NetAppRPS/Data/Solution_NetAppRps.json b/Solutions/NetAppRPS/Data/Solution_NetAppRps.json deleted file mode 100644 index 608925fcfa4..00000000000 --- a/Solutions/NetAppRPS/Data/Solution_NetAppRps.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "Name": "NetAppRPS", - "Author": "NetApp - support@netapp.com", - "title": "NetApp RPS", - "Description": "NetApp RPS (Ransomware Protection Service) - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.", - "logo": "\"NetApp", - "Data Connectors": [ - "Data Connectors/NetAppRPS_DataConnector.json" - ], - "Analytic Rules": [ - "Analytic Rules/NetAppRPS_HighSeverity.yaml", - "Analytic Rules/NetAppRPS_MediumSeverity.yaml" - ], - "Playbooks": [ - "Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json", - "Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json", - "Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json", - "Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json", - "Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json", - "Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json" - ], - "Version": "3.0.0", - "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\NetAppRPS", - "Metadata": "SolutionMetadata.json", - "TemplateSpec": true, - "StaticDataConnectorIds": [] -} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Package/3.0.0.zip b/Solutions/NetAppRPS/Package/3.0.0.zip deleted file mode 100644 index 5da4b331911951cd292db8dca2e8d0de07a82b95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19166 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 diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json deleted file mode 100644 index f97dc4c95d8..00000000000 --- a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.parameters.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "PlaybookName": { - "value": "NetAppRPS-Enrich-IP-Playbook" - }, - "NetAppRPSAuthPlaybookName": { - "value": "NetAppRPS-Auth-Playbook" - }, - "NetAppRPSAsyncPollPlaybookName": { - "value": "NetAppRPS-Async-Poll-Playbook" - } - } -} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json deleted file mode 100644 index 4bdd7715aa9..00000000000 --- a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.parameters.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "PlaybookName": { - "value": "NetAppRPS-Volume-Offline-Playbook" - }, - "NetAppRPSAuthPlaybookName": { - "value": "NetAppRPS-Auth-Playbook" - }, - "NetAppRPSAsyncPollPlaybookName": { - "value": "NetAppRPS-Async-Poll-Playbook" - } - } -} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json deleted file mode 100644 index fd47f031396..00000000000 --- a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.parameters.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "PlaybookName": { - "value": "NetAppRPS-Volume-Snapshot-Playbook" - }, - "NetAppRPSAuthPlaybookName": { - "value": "NetAppRPS-Auth-Playbook" - }, - "NetAppRPSAsyncPollPlaybookName": { - "value": "NetAppRPS-Async-Poll-Playbook" - } - } -} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml b/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml similarity index 60% rename from Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml rename to Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml index d932137ef55..293891058ea 100644 --- a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_HighSeverity.yaml +++ b/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml @@ -1,21 +1,21 @@ id: 33b9688b-2afb-442f-a3bb-fe2362717bb7 -name: NetApp RPS High Severity Alert +name: NetApp Ransomware Resilience High Severity Alert description: | - 'Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the NetAppRPS_alerts_CL table for alerts with HIGH severity level.' + 'Detects high severity NetApp Ransomware Resilience alerts that require immediate attention. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with HIGH severity level.' severity: High status: Available requiredDataConnectors: - - connectorId: NetAppRPSCustomLogsIngestion + - connectorId: NetAppRansomwareResilienceCustomLogsIngestion dataTypes: - - NetAppRPS_alerts_CL + - NetAppRansomwareResilience_alerts_CL suppressionDuration: PT5H suppressionEnabled: false query: | - NetAppRPS_alerts_CL | where TimeGenerated > ago(1d) + NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d) | where severity == "HIGH" alertDetailsOverride: alertDisplayNameFormat: "{{description}}" - alertDescriptionFormat: "High severity alert detected from NetApp RPS: {{description}}" + alertDescriptionFormat: "High severity alert detected from NetApp Ransomware Resilience Service: {{description}}" customDetails: Severity: severity IncidentDetails: incident diff --git a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml b/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml similarity index 60% rename from Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml rename to Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml index f65a2e0c8cb..17eec70e8d4 100644 --- a/Solutions/NetAppRPS/Analytic Rules/NetAppRPS_MediumSeverity.yaml +++ b/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml @@ -1,21 +1,21 @@ id: be774c6e-7613-41db-b6e4-25975b680d24 -name: NetApp RPS Medium Severity Alert +name: NetApp Ransomware Resilience Medium Severity Alert description: | - 'Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the NetAppRPS_alerts_CL table for alerts with MEDIUM severity level.' + 'Detects medium severity NetApp Ransomware Resilience alerts that may require investigation. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with MEDIUM severity level.' severity: Medium status: Available requiredDataConnectors: - - connectorId: NetAppRPSCustomLogsIngestion + - connectorId: NetAppRansomwareResilienceCustomLogsIngestion dataTypes: - - NetAppRPS_alerts_CL + - NetAppRansomwareResilience_alerts_CL suppressionDuration: PT5H suppressionEnabled: false query: | - NetAppRPS_alerts_CL | where TimeGenerated > ago(1d) + NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d) | where severity == "MEDIUM" alertDetailsOverride: alertDisplayNameFormat: "{{description}}" - alertDescriptionFormat: "Medium severity alert detected from NetApp RPS: {{description}}" + alertDescriptionFormat: "Medium severity alert detected from NetApp Ransomware Resilience Service: {{description}}" customDetails: Severity: severity IncidentDetails: incident diff --git a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json b/Solutions/NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json similarity index 60% rename from Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json rename to Solutions/NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json index 5d8d7e2fa1d..601c20b40e9 100644 --- a/Solutions/NetAppRPS/Data Connectors/NetAppRPS_DataConnector.json +++ b/Solutions/NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json @@ -1,33 +1,33 @@ { - "id": "NetAppRPSCustomLogsIngestion", - "title": "NetAppRPS Data Connector", - "publisher": "NetAppRPS", - "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", - "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "id": "NetAppRansomwareResilienceCustomLogsIngestion", + "title": "NetAppRansomwareResilience Data Connector", + "publisher": "NetAppRansomwareResilience", + "descriptionMarkdown": "Data connector for ingesting NetApp Ransomware Resilience alerts into Microsoft Sentinel. This connector enables seamless integration of Ransomware Resilience alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", + "additionalRequirementBanner": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", "graphQueries": [ { "metricName": "Total data received", - "legend": "NetAppRPS_alerts_CL", - "baseQuery": "NetAppRPS_alerts_CL" + "legend": "NetAppRansomwareResilience_alerts_CL", + "baseQuery": "NetAppRansomwareResilience_alerts_CL" } ], "dataTypes": [ { - "name": "NetAppRPS_alerts_CL", - "lastDataReceivedQuery": "NetAppRPS_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + "name": "NetAppRansomwareResilience_alerts_CL", + "lastDataReceivedQuery": "NetAppRansomwareResilience_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "sampleQueries": [ { "description": "Default Query", - "query": "NetAppRPS_alerts_CL" + "query": "NetAppRansomwareResilience_alerts_CL" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ - "NetAppRPS_alerts_CL" + "NetAppRansomwareResilience_alerts_CL" ] } ], @@ -72,11 +72,11 @@ "instructionSteps": [ { "title": "1. Configuration", - "description": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data." + "description": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data." }, { "title": "2. Deploy the ARM Template", - "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRPS%2FData%2520Connectors%2Fazuredeploy_rps_dataconnector.json)" + "description": "Click the button below to deploy the NetApp Ransomware Resilience data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRansomwareResilience%2FData%2520Connectors%2Fazuredeploy_rrs_dataconnector.json)" } ] } \ No newline at end of file diff --git a/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json b/Solutions/NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json similarity index 71% rename from Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json rename to Solutions/NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json index fd735685fa8..2696ca7472c 100644 --- a/Solutions/NetAppRPS/Data Connectors/azuredeploy_rps_dataconnector.json +++ b/Solutions/NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json @@ -19,12 +19,12 @@ { "type": "Microsoft.OperationalInsights/workspaces/tables", "apiVersion": "2022-10-01", - "name": "[concat(parameters('workspaceResourceId'), '/NetAppRPS_alerts_CL')]", + "name": "[concat(parameters('workspaceResourceId'), '/NetAppRansomwareResilience_alerts_CL')]", "properties": { "description": "Custom log table for storing custom logs", "retentionInDays": 30, "schema": { - "name": "NetAppRPS_alerts_CL", + "name": "NetAppRansomwareResilience_alerts_CL", "columns": [ { "name": "TimeGenerated", @@ -52,7 +52,7 @@ }, { "type": "Microsoft.Insights/dataCollectionEndpoints", - "name": "rps-alerts-dce", + "name": "ransomware-resilience-alerts-dce", "location": "[resourceGroup().location]", "apiVersion": "2021-04-01", "properties": { @@ -63,15 +63,15 @@ }, { "type": "Microsoft.Insights/dataCollectionRules", - "name": "rps-alerts-dcr", + "name": "ransomware-resilience-alerts-dcr", "location": "[resourceGroup().location]", "apiVersion": "2023-03-11", "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRPS_alerts_CL')]", - "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]" + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRansomwareResilience_alerts_CL')]", + "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]" ], "properties": { - "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]", + "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]", "streamDeclarations": { "Custom-MyTableRawData": { "columns": [ @@ -109,13 +109,13 @@ "dataFlows": [ { "streams": [ - "Custom-NetAppRPS_alerts_CL" + "Custom-NetAppRansomwareResilience_alerts_CL" ], "destinations": [ "[parameters('workspaceResourceId')]" ], "transformKql": "source", - "outputStream": "Custom-NetAppRPS_alerts_CL" + "outputStream": "Custom-NetAppRansomwareResilience_alerts_CL" } ] } @@ -123,51 +123,51 @@ { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2020-04-01-preview", - "name": "[guid(resourceGroup().id, 'rps-alerts-dce', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", - "scope": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]", + "name": "[guid(resourceGroup().id, 'ransomware-resilience-alerts-dce', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", + "scope": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]", "properties": { "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", "principalId": "[parameters('principalId')]" }, "dependsOn": [ - "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'rps-alerts-dce')]" + "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]" ] }, { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2020-04-01-preview", - "name": "[guid(resourceGroup().id, 'rps-alerts-dcr', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", - "scope": "[resourceId('Microsoft.Insights/dataCollectionRules', 'rps-alerts-dcr')]", + "name": "[guid(resourceGroup().id, 'ransomware-resilience-alerts-dcr', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", + "scope": "[resourceId('Microsoft.Insights/dataCollectionRules', 'ransomware-resilience-alerts-dcr')]", "properties": { "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", "principalId": "[parameters('principalId')]" }, "dependsOn": [ - "[resourceId('Microsoft.Insights/dataCollectionRules', 'rps-alerts-dcr')]" + "[resourceId('Microsoft.Insights/dataCollectionRules', 'ransomware-resilience-alerts-dcr')]" ] }, { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2020-04-01-preview", - "name": "[guid(resourceGroup().id, 'NetAppRPS_alerts_CL', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", - "scope": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRPS_alerts_CL')]", + "name": "[guid(resourceGroup().id, 'NetAppRansomwareResilience_alerts_CL', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", + "scope": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRansomwareResilience_alerts_CL')]", "properties": { "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", "principalId": "[parameters('principalId')]" }, "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRPS_alerts_CL')]" + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRansomwareResilience_alerts_CL')]" ] } ], "outputs": { "dataCollectionEndpointIngestion": { "type": "string", - "value": "[reference('Microsoft.Insights/dataCollectionEndpoints/rps-alerts-dce', '2021-04-01').logsIngestion.endpoint]" + "value": "[reference('Microsoft.Insights/dataCollectionEndpoints/ransomware-resilience-alerts-dce', '2021-04-01').logsIngestion.endpoint]" }, "dataCollectionRuleImmutableId": { "type": "string", - "value": "[reference('Microsoft.Insights/dataCollectionRules/rps-alerts-dcr', '2023-03-11').immutableId]" + "value": "[reference('Microsoft.Insights/dataCollectionRules/ransomware-resilience-alerts-dcr', '2023-03-11').immutableId]" } } } \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Data/Solution_NetAppRansomwareResilience.json b/Solutions/NetAppRansomwareResilience/Data/Solution_NetAppRansomwareResilience.json new file mode 100644 index 00000000000..7d9280bf744 --- /dev/null +++ b/Solutions/NetAppRansomwareResilience/Data/Solution_NetAppRansomwareResilience.json @@ -0,0 +1,27 @@ +{ + "Name": "NetAppRansomwareResilience", + "Author": "NetApp - support@netapp.com", + "title": "NetApp Ransomware Resilience", + "Description": "NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.", + "logo": "\"NetApp", + "Data Connectors": [ + "Data Connectors/NetAppRansomwareResilience_DataConnector.json" + ], + "Analytic Rules": [ + "Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml", + "Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml" + ], + "Playbooks": [ + "Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json", + "Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json", + "Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json", + "Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json", + "Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json", + "Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json" + ], + "Version": "3.0.0", + "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\NetAppRansomwareResilience", + "Metadata": "SolutionMetadata.json", + "TemplateSpec": true, + "StaticDataConnectorIds": [] +} \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Package/3.0.0.zip b/Solutions/NetAppRansomwareResilience/Package/3.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..b685f4385857bcfab25578234a5b368e3127a368 GIT binary patch literal 15964 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 WDM*8Y{ih4izY_AV9_0Pc*Z%@}D(VUV literal 0 HcmV?d00001 diff --git a/Solutions/NetAppRPS/Package/createUiDefinition.json b/Solutions/NetAppRansomwareResilience/Package/createUiDefinition.json similarity index 53% rename from Solutions/NetAppRPS/Package/createUiDefinition.json rename to Solutions/NetAppRansomwareResilience/Package/createUiDefinition.json index d1713c0b97d..895ed550a21 100644 --- a/Solutions/NetAppRPS/Package/createUiDefinition.json +++ b/Solutions/NetAppRansomwareResilience/Package/createUiDefinition.json @@ -6,7 +6,7 @@ "config": { "isWizard": false, "basics": { - "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/NetAppRPS/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nNetApp RPS (Ransomware Protection Service) - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.\n\n**Data Connectors:** 1, **Analytic Rules:** 2, **Playbooks:** 6\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "description": "\"NetApp\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/NetAppRansomwareResilience/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nNetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.\n\n**Data Connectors:** 1, **Analytic Rules:** 2, **Playbooks:** 6\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -60,7 +60,7 @@ "name": "dataconnectors1-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "This Solution installs the data connector for NetAppRPS. You can get NetAppRPS custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." + "text": "This Solution installs the data connector for NetAppRansomwareResilience. You can get NetAppRansomwareResilience custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." } }, { @@ -104,13 +104,13 @@ { "name": "analytic1", "type": "Microsoft.Common.Section", - "label": "NetApp RPS High Severity Alert", + "label": "NetApp Ransomware Resilience High Severity Alert", "elements": [ { "name": "analytic1-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the NetAppRPS_alerts_CL table for alerts with HIGH severity level." + "text": "Detects high severity NetApp Ransomware Resilience alerts that require immediate attention. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with HIGH severity level." } } ] @@ -118,13 +118,13 @@ { "name": "analytic2", "type": "Microsoft.Common.Section", - "label": "NetApp RPS Medium Severity Alert", + "label": "NetApp Ransomware Resilience Medium Severity Alert", "elements": [ { "name": "analytic2-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the NetAppRPS_alerts_CL table for alerts with MEDIUM severity level." + "text": "Detects medium severity NetApp Ransomware Resilience alerts that may require investigation. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with MEDIUM severity level." } } ] diff --git a/Solutions/NetAppRPS/Package/mainTemplate.json b/Solutions/NetAppRansomwareResilience/Package/mainTemplate.json similarity index 87% rename from Solutions/NetAppRPS/Package/mainTemplate.json rename to Solutions/NetAppRansomwareResilience/Package/mainTemplate.json index b566bbf40f1..2cc3016325c 100644 --- a/Solutions/NetAppRPS/Package/mainTemplate.json +++ b/Solutions/NetAppRansomwareResilience/Package/mainTemplate.json @@ -3,7 +3,7 @@ "contentVersion": "1.0.0.0", "metadata": { "author": "NetApp - support@netapp.com", - "comments": "Solution template for NetAppRPS" + "comments": "Solution template for NetAppRansomwareResilience" }, "parameters": { "location": { @@ -32,13 +32,13 @@ "variables": { "email": "support@netapp.com", "_email": "[variables('email')]", - "_solutionName": "NetAppRPS", + "_solutionName": "NetAppRansomwareResilience", "_solutionVersion": "3.0.0", - "solutionId": "netapp1234567890.azure-sentinel-solution-netapprps", + "solutionId": "netapp1234567890.azure-sentinel-solution-netapprrs", "_solutionId": "[variables('solutionId')]", - "uiConfigId1": "NetAppRPSCustomLogsIngestion", + "uiConfigId1": "NetAppRansomwareResilienceCustomLogsIngestion", "_uiConfigId1": "[variables('uiConfigId1')]", - "dataConnectorContentId1": "NetAppRPSCustomLogsIngestion", + "dataConnectorContentId1": "NetAppRansomwareResilienceCustomLogsIngestion", "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", "_dataConnectorId1": "[variables('dataConnectorId1')]", @@ -59,53 +59,53 @@ "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('be774c6e-7613-41db-b6e4-25975b680d24')))]", "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','be774c6e-7613-41db-b6e4-25975b680d24','-', '1.0.0')))]" }, - "NetApp-RPS-Auth-Playbook": "NetApp-RPS-Auth-Playbook", - "_NetApp-RPS-Auth-Playbook": "[variables('NetApp-RPS-Auth-Playbook')]", + "NetApp-RansomwareResilience-Auth-Playbook": "NetApp-RansomwareResilience-Auth-Playbook", + "_NetApp-RansomwareResilience-Auth-Playbook": "[variables('NetApp-RansomwareResilience-Auth-Playbook')]", "playbookVersion1": "1.0", - "playbookContentId1": "NetApp-RPS-Auth-Playbook", + "playbookContentId1": "NetApp-RansomwareResilience-Auth-Playbook", "_playbookContentId1": "[variables('playbookContentId1')]", "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]", "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]", "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]", "blanks": "[replace('b', 'b', '')]", - "RPS_Volume_Offline_Playbook": "RPS_Volume_Offline_Playbook", - "_RPS_Volume_Offline_Playbook": "[variables('RPS_Volume_Offline_Playbook')]", + "NetApp-RansomwareResilience_Volume_Offline_Playbook": "NetApp-RansomwareResilience_Volume_Offline_Playbook", + "_NetApp-RansomwareResilience_Volume_Offline_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Offline_Playbook')]", "TemplateEmptyObject": "[json('{}')]", "playbookVersion2": "1.0", - "playbookContentId2": "RPS_Volume_Offline_Playbook", + "playbookContentId2": "NetApp-RansomwareResilience_Volume_Offline_Playbook", "_playbookContentId2": "[variables('playbookContentId2')]", "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]", "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]", "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]", - "RPS_Async_Poll_Playbook": "RPS_Async_Poll_Playbook", - "_RPS_Async_Poll_Playbook": "[variables('RPS_Async_Poll_Playbook')]", + "NetApp-RansomwareResilience_Async_Poll_Playbook": "NetApp-RansomwareResilience_Async_Poll_Playbook", + "_NetApp-RansomwareResilience_Async_Poll_Playbook": "[variables('NetApp-RansomwareResilience_Async_Poll_Playbook')]", "playbookVersion3": "1.0", - "playbookContentId3": "RPS_Async_Poll_Playbook", + "playbookContentId3": "NetApp-RansomwareResilience_Async_Poll_Playbook", "_playbookContentId3": "[variables('playbookContentId3')]", "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]", "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]", "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]", - "RPS_Volume_Snapshot_Playbook": "RPS_Volume_Snapshot_Playbook", - "_RPS_Volume_Snapshot_Playbook": "[variables('RPS_Volume_Snapshot_Playbook')]", + "NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook", + "_NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Snapshot_Playbook')]", "playbookVersion4": "1.0", - "playbookContentId4": "RPS_Volume_Snapshot_Playbook", + "playbookContentId4": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook", "_playbookContentId4": "[variables('playbookContentId4')]", "playbookId4": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId4'))]", "playbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId4'))))]", "_playbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId4'),'-', variables('playbookVersion4'))))]", - "RPS_Enrich_StorageVM_Playbook": "RPS_Enrich_StorageVM_Playbook", - "_RPS_Enrich_StorageVM_Playbook": "[variables('RPS_Enrich_StorageVM_Playbook')]", + "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "_NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_StorageVM_Playbook')]", "playbookVersion5": "1.0", - "playbookContentId5": "RPS_Enrich_StorageVM_Playbook", + "playbookContentId5": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", "_playbookContentId5": "[variables('playbookContentId5')]", "playbookId5": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId5'))]", "playbookTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId5'))))]", "_playbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId5'),'-', variables('playbookVersion5'))))]", - "RPS_Enrich_IP_Playbook": "RPS_Enrich_IP_Playbook", - "_RPS_Enrich_IP_Playbook": "[variables('RPS_Enrich_IP_Playbook')]", + "NetApp-RansomwareResilience_Enrich_IP_Playbook": "NetApp-RansomwareResilience_Enrich_IP_Playbook", + "_NetApp-RansomwareResilience_Enrich_IP_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_IP_Playbook')]", "playbookVersion6": "1.0", - "playbookContentId6": "RPS_Enrich_IP_Playbook", + "playbookContentId6": "NetApp-RansomwareResilience_Enrich_IP_Playbook", "_playbookContentId6": "[variables('playbookContentId6')]", "playbookId6": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId6'))]", "playbookTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId6'))))]", @@ -122,7 +122,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS data connector with template version 3.0.0", + "description": "NetAppRansomwareResilience data connector with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion1')]", @@ -138,34 +138,34 @@ "properties": { "connectorUiConfig": { "id": "[variables('_uiConfigId1')]", - "title": "NetAppRPS Data Connector", - "publisher": "NetAppRPS", - "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", - "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "title": "NetAppRansomwareResilience Data Connector", + "publisher": "NetAppRansomwareResilience", + "descriptionMarkdown": "Data connector for ingesting NetApp Ransomware Resilience alerts into Microsoft Sentinel. This connector enables seamless integration of Ransomware Resilience alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", + "additionalRequirementBanner": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", "graphQueries": [ { "metricName": "Total data received", - "legend": "NetAppRPS_alerts_CL", - "baseQuery": "NetAppRPS_alerts_CL" + "legend": "NetAppRansomwareResilience_alerts_CL", + "baseQuery": "NetAppRansomwareResilience_alerts_CL" } ], "dataTypes": [ { - "name": "NetAppRPS_alerts_CL", - "lastDataReceivedQuery": "NetAppRPS_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + "name": "NetAppRansomwareResilience_alerts_CL", + "lastDataReceivedQuery": "NetAppRansomwareResilience_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "sampleQueries": [ { "description": "Default Query", - "query": "NetAppRPS_alerts_CL" + "query": "NetAppRansomwareResilience_alerts_CL" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ - "NetAppRPS_alerts_CL" + "NetAppRansomwareResilience_alerts_CL" ] } ], @@ -209,11 +209,11 @@ }, "instructionSteps": [ { - "description": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "description": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", "title": "1. Configuration" }, { - "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRPS%2FData%2520Connectors%2Fazuredeploy_rps_dataconnector.json)", + "description": "Click the button below to deploy the NetApp Ransomware Resilience data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRansomwareResilience%2FData%2520Connectors%2Fazuredeploy_rrs_dataconnector.json)", "title": "2. Deploy the ARM Template" } ] @@ -231,7 +231,7 @@ "version": "[variables('dataConnectorVersion1')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -255,7 +255,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_dataConnectorContentId1')]", "contentKind": "DataConnector", - "displayName": "NetAppRPS Data Connector", + "displayName": "NetAppRansomwareResilience Data Connector", "contentProductId": "[variables('_dataConnectorcontentProductId1')]", "id": "[variables('_dataConnectorcontentProductId1')]", "version": "[variables('dataConnectorVersion1')]" @@ -276,7 +276,7 @@ "version": "[variables('dataConnectorVersion1')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -299,34 +299,34 @@ "kind": "GenericUI", "properties": { "connectorUiConfig": { - "title": "NetAppRPS Data Connector", - "publisher": "NetAppRPS", - "descriptionMarkdown": "Data connector for ingesting NetApp RPS (Ransomware Protection Service) alerts into Microsoft Sentinel. This connector enables seamless integration of RPS alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", + "title": "NetAppRansomwareResilience Data Connector", + "publisher": "NetAppRansomwareResilience", + "descriptionMarkdown": "Data connector for ingesting NetApp Ransomware Resilience alerts into Microsoft Sentinel. This connector enables seamless integration of Ransomware Resilience alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", "graphQueries": [ { "metricName": "Total data received", - "legend": "NetAppRPS_alerts_CL", - "baseQuery": "NetAppRPS_alerts_CL" + "legend": "NetAppRansomwareResilience_alerts_CL", + "baseQuery": "NetAppRansomwareResilience_alerts_CL" } ], "dataTypes": [ { - "name": "NetAppRPS_alerts_CL", - "lastDataReceivedQuery": "NetAppRPS_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + "name": "NetAppRansomwareResilience_alerts_CL", + "lastDataReceivedQuery": "NetAppRansomwareResilience_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ - "NetAppRPS_alerts_CL" + "NetAppRansomwareResilience_alerts_CL" ] } ], "sampleQueries": [ { "description": "Default Query", - "query": "NetAppRPS_alerts_CL" + "query": "NetAppRansomwareResilience_alerts_CL" } ], "availability": { @@ -369,16 +369,16 @@ }, "instructionSteps": [ { - "description": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data.", + "description": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", "title": "1. Configuration" }, { - "description": "Click the button below to deploy the NetApp RPS data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRPS%2FData%2520Connectors%2Fazuredeploy_rps_dataconnector.json)", + "description": "Click the button below to deploy the NetApp Ransomware Resilience data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRansomwareResilience%2FData%2520Connectors%2Fazuredeploy_rrs_dataconnector.json)", "title": "2. Deploy the ARM Template" } ], "id": "[variables('_uiConfigId1')]", - "additionalRequirementBanner": "You need to have an active NetApp RPS subscription and appropriate permissions to access RPS alert data." + "additionalRequirementBanner": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data." } } }, @@ -391,7 +391,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS_HighSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", + "description": "NetAppRansomwareResilience_HighSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", @@ -405,10 +405,10 @@ "kind": "NRT", "location": "[parameters('workspace-location')]", "properties": { - "description": "Detects high severity NetApp RPS alerts that require immediate attention. This rule monitors the NetAppRPS_alerts_CL table for alerts with HIGH severity level.", - "displayName": "NetApp RPS High Severity Alert", + "description": "Detects high severity NetApp Ransomware Resilience alerts that require immediate attention. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with HIGH severity level.", + "displayName": "NetApp Ransomware Resilience High Severity Alert", "enabled": false, - "query": "NetAppRPS_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"HIGH\"\n", + "query": "NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"HIGH\"\n", "severity": "High", "suppressionDuration": "PT1H", "suppressionEnabled": false, @@ -416,31 +416,31 @@ "requiredDataConnectors": [ { "dataTypes": [ - "NetAppRPS_alerts_CL" + "NetAppRansomwareResilience_alerts_CL" ], - "connectorId": "NetAppRPSCustomLogsIngestion" + "connectorId": "NetAppRansomwareResilienceCustomLogsIngestion" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { - "IncidentDetails": "incident", "Severity": "severity", - "ContextInfo": "context" + "ContextInfo": "context", + "IncidentDetails": "incident" }, "alertDetailsOverride": { - "alertDisplayNameFormat": "{{description}}", - "alertDescriptionFormat": "High severity alert detected from NetApp RPS: {{description}}" + "alertDescriptionFormat": "High severity alert detected from NetApp Ransomware Resilience Service: {{description}}", + "alertDisplayNameFormat": "{{description}}" }, "incidentConfiguration": { + "createIncident": true, "groupingConfiguration": { - "lookbackDuration": "PT5H", + "enabled": false, "matchingMethod": "AllEntities", "reopenClosedIncident": false, - "enabled": false - }, - "createIncident": true + "lookbackDuration": "PT5H" + } } } }, @@ -449,14 +449,14 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]", "properties": { - "description": "NetAppRPS Analytics Rule 1", + "description": "NetAppRansomwareResilience Analytics Rule 1", "parentId": "[variables('analyticRuleObject1').analyticRuleId1]", "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", "kind": "AnalyticsRule", "version": "[variables('analyticRuleObject1').analyticRuleVersion1]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -480,7 +480,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", "contentKind": "AnalyticsRule", - "displayName": "NetApp RPS High Severity Alert", + "displayName": "NetApp Ransomware Resilience High Severity Alert", "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" @@ -495,7 +495,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS_MediumSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", + "description": "NetAppRansomwareResilience_MediumSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", @@ -509,10 +509,10 @@ "kind": "NRT", "location": "[parameters('workspace-location')]", "properties": { - "description": "Detects medium severity NetApp RPS alerts that may require investigation. This rule monitors the NetAppRPS_alerts_CL table for alerts with MEDIUM severity level.", - "displayName": "NetApp RPS Medium Severity Alert", + "description": "Detects medium severity NetApp Ransomware Resilience alerts that may require investigation. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with MEDIUM severity level.", + "displayName": "NetApp Ransomware Resilience Medium Severity Alert", "enabled": false, - "query": "NetAppRPS_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"MEDIUM\"\n", + "query": "NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"MEDIUM\"\n", "severity": "Medium", "suppressionDuration": "PT1H", "suppressionEnabled": false, @@ -520,31 +520,31 @@ "requiredDataConnectors": [ { "dataTypes": [ - "NetAppRPS_alerts_CL" + "NetAppRansomwareResilience_alerts_CL" ], - "connectorId": "NetAppRPSCustomLogsIngestion" + "connectorId": "NetAppRansomwareResilienceCustomLogsIngestion" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { - "IncidentDetails": "incident", "Severity": "severity", - "ContextInfo": "context" + "ContextInfo": "context", + "IncidentDetails": "incident" }, "alertDetailsOverride": { - "alertDisplayNameFormat": "{{description}}", - "alertDescriptionFormat": "Medium severity alert detected from NetApp RPS: {{description}}" + "alertDescriptionFormat": "Medium severity alert detected from NetApp Ransomware Resilience Service: {{description}}", + "alertDisplayNameFormat": "{{description}}" }, "incidentConfiguration": { + "createIncident": true, "groupingConfiguration": { - "lookbackDuration": "PT5H", + "enabled": false, "matchingMethod": "AllEntities", "reopenClosedIncident": false, - "enabled": false - }, - "createIncident": true + "lookbackDuration": "PT5H" + } } } }, @@ -553,14 +553,14 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]", "properties": { - "description": "NetAppRPS Analytics Rule 2", + "description": "NetAppRansomwareResilience Analytics Rule 2", "parentId": "[variables('analyticRuleObject2').analyticRuleId2]", "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", "kind": "AnalyticsRule", "version": "[variables('analyticRuleObject2').analyticRuleVersion2]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -584,7 +584,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", "contentKind": "AnalyticsRule", - "displayName": "NetApp RPS Medium Severity Alert", + "displayName": "NetApp Ransomware Resilience Medium Severity Alert", "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" @@ -599,23 +599,23 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS-Auth-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Auth-Playbook Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion1')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { "description": "Name of the Logic App playbook to be created" } }, "KeyVaultName": { "type": "String", - "defaultValue": "[concat('rpskv', uniqueString(resourceGroup().id))]", + "defaultValue": "[concat('RRSkv', uniqueString(resourceGroup().id))]", "metadata": { - "description": "Name of the shared Key Vault to store NetApp RPS credentials" + "description": "Name of the shared Key Vault to store NetApp Ransomware Resilience credentials" } }, "location": { @@ -628,19 +628,19 @@ "ClientId": { "type": "securestring", "metadata": { - "description": "Client ID for NetApp RPS API authentication" + "description": "Client ID for NetApp Ransomware Resilience API authentication" } }, "ClientSecret": { "type": "securestring", "metadata": { - "description": "Client Secret for NetApp RPS API authentication" + "description": "Client Secret for NetApp Ransomware Resilience API authentication" } }, "AccountId": { "type": "securestring", "metadata": { - "description": "Account ID for NetApp RPS API authentication" + "description": "Account ID for NetApp Ransomware Resilience API authentication" } } }, @@ -826,7 +826,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://netapp-cloud-account.auth0.com/oauth/token", + "uri": "https://staging-netapp-cloud-account.auth0.com/oauth/token", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, @@ -910,7 +910,7 @@ "version": "[variables('playbookVersion1')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -927,22 +927,22 @@ } ], "metadata": { - "title": "NetApp RPS Authentication Playbook", - "description": "This playbook creates a shared Key Vault for NetApp RPS credentials and provides authentication services to all NetApp RPS playbooks in the solution.", + "title": "NetApp Ransomware Resilience Authentication Playbook", + "description": "This playbook creates a shared Key Vault for NetApp Ransomware Resilience credentials and provides authentication services to all NetApp Ransomware Resilience playbooks in the solution.", "prerequisites": [ - "1. Valid client_id, client_secret, and account_id for NetApp RPS API authentication", + "1. Valid client_id, client_secret, and account_id for NetApp Ransomware Resilience API authentication", "2. API endpoint that accepts OAuth2 client credentials flow" ], "postDeployment": [ "1. Update the client_id, client_secret, and account_id values in the Key Vault", "2. Test the Logic App to ensure proper token retrieval", - "3. The Key Vault created by this playbook will be shared across all NetApp RPS playbooks", + "3. The Key Vault created by this playbook will be shared across all NetApp Ransomware Resilience playbooks", "4. Other playbooks will call this Auth playbook to obtain authentication tokens" ], "lastUpdateTime": "2025-09-17T00:00:00Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Authentication" ], @@ -962,7 +962,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId1')]", "contentKind": "Playbook", - "displayName": "NetAppRPS-Auth-Playbook", + "displayName": "NetApp-RansomwareResilience-Auth-Playbook", "contentProductId": "[variables('_playbookcontentProductId1')]", "id": "[variables('_playbookcontentProductId1')]", "version": "[variables('playbookVersion1')]" @@ -977,30 +977,30 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS-Volume-Offline-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Volume-Offline-Playbook Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion2')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Volume-Offline-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Offline-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, - "NetAppRPSAsyncPollPlaybookName": { + "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { - "description": "Name of the NetApp RPS async poll playbook" + "description": "Name of the NetApp Ransomware Resilience async poll playbook" } }, "location": { @@ -1032,11 +1032,11 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" }, "asyncPollPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAsyncPollPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", "type": "String" } }, @@ -1141,7 +1141,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -1220,7 +1220,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-volume-offline", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-volume-offline", "headers": { "Authorization": "Bearer @{variables('Token')}", "Content-Type": "application/json", @@ -1357,7 +1357,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -1484,7 +1484,7 @@ "version": "[variables('playbookVersion2')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -1501,24 +1501,21 @@ } ], "metadata": { - "title": "NetApp RPS Volume Offline Playbook", - "description": "This playbook takes a NetApp volume offline using the updated NetApp RPS take-volume-offline API endpoint and optionally polls for completion.", + "title": "NetApp Ransomware Resilience Volume Offline Playbook", + "description": "This playbook takes a NetApp volume offline using the updated NetApp Ransomware Resilience take-volume-offline API endpoint and optionally polls for completion.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. NetApp RPS Async Poll Playbook must be deployed first", - "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "4. Caller must provide volume_id, agent_id, and system_id parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Ensure the Async Poll Playbook is working correctly", - "3. Test the volume offline functionality with valid volume_id, agent_id, and system_id", - "4. Verify the new take-volume-offline API endpoint is accessible" + "1. Test the volume offline functionality with valid volume_id, agent_id, and system_id" ], "lastUpdateTime": "2025-09-17T00:00:00Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Volume", "Offline" @@ -1539,7 +1536,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId2')]", "contentKind": "Playbook", - "displayName": "NetAppRPS-Volume-Offline-Playbook", + "displayName": "NetApp-RansomwareResilience-Volume-Offline-Playbook", "contentProductId": "[variables('_playbookcontentProductId2')]", "id": "[variables('_playbookcontentProductId2')]", "version": "[variables('playbookVersion2')]" @@ -1554,23 +1551,23 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS-Async-Poll-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Async-Poll-Playbook Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion3')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "location": { @@ -1602,7 +1599,7 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" } }, @@ -1616,11 +1613,11 @@ "properties": { "job_id": { "type": "string", - "description": "The NetApp RPS job ID to poll" + "description": "The NetApp Ransomware Resilience job ID to poll" }, "agent_id": { "type": "string", - "description": "NetApp agent ID" + "description": "NetApp Ransomware Resilience agent ID" }, "system_id": { "type": "string", @@ -1711,7 +1708,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -1745,7 +1742,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", "accept": "application/json" @@ -1813,7 +1810,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", "accept": "application/json" @@ -1997,7 +1994,7 @@ "version": "[variables('playbookVersion3')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -2014,21 +2011,21 @@ } ], "metadata": { - "title": "NetApp RPS Async Poll Playbook", - "description": "This playbook polls NetApp RPS job status asynchronously until completion or timeout using the updated job status API endpoint.", + "title": "NetApp Ransomware Resilience Async Poll Playbook", + "description": "This playbook polls NetApp Ransomware Resilience job status asynchronously until completion or timeout using the updated job status API endpoint.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "3. Caller must provide job_id, agent_id, system_id, and source parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Test the polling functionality with a valid job ID" + "1. Test the playbook by triggering it with a valid job_id, agent_id, system_id, and source", + "2. Monitor the playbook run history to verify successful polling and completion" ], "lastUpdateTime": "2025-09-17T00:00:00Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Async", "Polling" @@ -2049,7 +2046,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId3')]", "contentKind": "Playbook", - "displayName": "NetAppRPS-Async-Poll-Playbook", + "displayName": "NetApp-RansomwareResilience-Async-Poll-Playbook", "contentProductId": "[variables('_playbookcontentProductId3')]", "id": "[variables('_playbookcontentProductId3')]", "version": "[variables('playbookVersion3')]" @@ -2064,30 +2061,30 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS-Volume-Snapshot-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion4')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Volume-Snapshot-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, - "NetAppRPSAsyncPollPlaybookName": { + "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { - "description": "Name of the NetApp RPS async poll playbook" + "description": "Name of the NetApp Ransomware Resilience async poll playbook" } }, "location": { @@ -2119,11 +2116,11 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" }, "asyncPollPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAsyncPollPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", "type": "String" } }, @@ -2228,7 +2225,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -2307,7 +2304,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-snapshot", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-snapshot", "headers": { "Authorization": "Bearer @{variables('Token')}", "Content-Type": "application/json", @@ -2444,7 +2441,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -2571,7 +2568,7 @@ "version": "[variables('playbookVersion4')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -2588,24 +2585,21 @@ } ], "metadata": { - "title": "NetApp RPS Volume Snapshot Playbook", - "description": "This playbook creates a NetApp volume snapshot using the updated NetApp RPS take-snapshot API endpoint and optionally polls for completion.", + "title": "NetApp Ransomware Resilience Volume Snapshot Playbook", + "description": "This playbook creates a NetApp volume snapshot using the updated NetApp Ransomware Resilience take-snapshot API endpoint and optionally polls for completion.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. NetApp RPS Async Poll Playbook must be deployed first", - "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "4. Caller must provide volume_id, agent_id, and system_id parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Ensure the Async Poll Playbook is working correctly", - "3. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id", - "4. Verify the new take-snapshot API endpoint is accessible" + "1. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id" ], "lastUpdateTime": "2025-09-22T00:00:00Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Volume", "Snapshot" @@ -2626,7 +2620,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId4')]", "contentKind": "Playbook", - "displayName": "NetAppRPS-Volume-Snapshot-Playbook", + "displayName": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", "contentProductId": "[variables('_playbookcontentProductId4')]", "id": "[variables('_playbookcontentProductId4')]", "version": "[variables('playbookVersion4')]" @@ -2641,23 +2635,23 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS-Enrich-StorageVM-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion5')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Enrich-StorageVM-Playbook", + "defaultValue": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "location": { @@ -2689,7 +2683,7 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" } }, @@ -2768,7 +2762,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -2847,7 +2841,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{variables('Token')}", "accept": "application/json" @@ -2970,7 +2964,7 @@ "version": "[variables('playbookVersion5')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -2987,21 +2981,20 @@ } ], "metadata": { - "title": "NetApp RPS Enrich StorageVM Playbook", - "description": "This playbook enriches storage data by calling the updated NetApp RPS enrich storage API endpoint.", + "title": "NetApp Ransomware Resilience Enrich StorageVM Playbook", + "description": "This playbook enriches storage data by calling the updated NetApp Ransomware Resilience enrich storage API endpoint.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "3. Caller must provide agent_id and system_id parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Test the storage enrichment functionality with valid agent_id and system_id" + "1. Test the storage enrichment functionality with valid agent_id and system_id" ], "lastUpdateTime": "2025-09-23T00:00:00Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "StorageVM", "Enrich" @@ -3022,7 +3015,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId5')]", "contentKind": "Playbook", - "displayName": "NetAppRPS-Enrich-StorageVM-Playbook", + "displayName": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", "contentProductId": "[variables('_playbookcontentProductId5')]", "id": "[variables('_playbookcontentProductId5')]", "version": "[variables('playbookVersion5')]" @@ -3037,30 +3030,30 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetAppRPS-Enrich-IP-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Enrich-IP-Playbook Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion6')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Enrich-IP-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Enrich-IP-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, - "NetAppRPSAsyncPollPlaybookName": { + "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { - "description": "Name of the NetApp RPS async poll playbook" + "description": "Name of the NetApp Ransomware Resilience async poll playbook" } }, "location": { @@ -3092,11 +3085,11 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" }, "asyncPollPlaybookName": { - "defaultValue": "[[parameters('NetAppRPSAsyncPollPlaybookName')]", + "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", "type": "String" } }, @@ -3170,7 +3163,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -3250,7 +3243,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/ip-address", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/ip-address", "headers": { "Authorization": "Bearer @{variables('Token')}", "accept": "application/json", @@ -3338,7 +3331,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -3465,7 +3458,7 @@ "version": "[variables('playbookVersion6')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -3482,24 +3475,21 @@ } ], "metadata": { - "title": "NetApp RPS Enrich IP Playbook", - "description": "This playbook enriches IP data by calling the updated NetApp RPS enrich IP address API endpoint and asynchronously polls multiple job results.", + "title": "NetApp Ransomware Resilience Enrich IP Playbook", + "description": "This playbook enriches IP data by calling the updated NetApp Ransomware Resilience enrich IP address API endpoint and asynchronously polls multiple job results.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. NetApp RPS Async Poll Playbook must be deployed", - "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "4. Caller must provide ip_address parameter" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Ensure the Async Poll Playbook is deployed and functional", - "3. Test the IP enrichment functionality with valid IP address", - "4. Verify the new POST API endpoint is accessible and returns job information with agent_id" + "1. Test the IP enrichment functionality with valid IP address" ], "lastUpdateTime": "2025-09-26T00:00:00Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "IP", "Enrich", @@ -3521,7 +3511,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId6')]", "contentKind": "Playbook", - "displayName": "NetAppRPS-Enrich-IP-Playbook", + "displayName": "NetApp-RansomwareResilience-Enrich-IP-Playbook", "contentProductId": "[variables('_playbookcontentProductId6')]", "id": "[variables('_playbookcontentProductId6')]", "version": "[variables('playbookVersion6')]" @@ -3535,18 +3525,18 @@ "version": "3.0.0", "kind": "Solution", "contentSchemaVersion": "3.0.0", - "displayName": "NetAppRPS", + "displayName": "NetAppRansomwareResilience", "publisherDisplayName": "NetApp", - "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n
\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

NetApp RPS (Ransomware Protection Service) - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.

\n

Data Connectors: 1, Analytic Rules: 2, Playbooks: 6

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.

\n

Data Connectors: 1, Analytic Rules: 2, Playbooks: 6

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", - "icon": "", + "icon": "\"NetApp", "contentId": "[variables('_solutionId')]", "parentId": "[variables('_solutionId')]", "source": { "kind": "Solution", - "name": "NetAppRPS", + "name": "NetAppRansomwareResilience", "sourceId": "[variables('_solutionId')]" }, "author": { @@ -3579,32 +3569,32 @@ }, { "kind": "Playbook", - "contentId": "[variables('_NetApp-RPS-Auth-Playbook')]", + "contentId": "[variables('_NetApp-RansomwareResilience-Auth-Playbook')]", "version": "[variables('playbookVersion1')]" }, { "kind": "Playbook", - "contentId": "[variables('_RPS_Volume_Offline_Playbook')]", + "contentId": "[variables('_NetApp-RansomwareResilience_Volume_Offline_Playbook')]", "version": "[variables('playbookVersion2')]" }, { "kind": "Playbook", - "contentId": "[variables('_RPS_Async_Poll_Playbook')]", + "contentId": "[variables('_NetApp-RansomwareResilience_Async_Poll_Playbook')]", "version": "[variables('playbookVersion3')]" }, { "kind": "Playbook", - "contentId": "[variables('_RPS_Volume_Snapshot_Playbook')]", + "contentId": "[variables('_NetApp-RansomwareResilience_Volume_Snapshot_Playbook')]", "version": "[variables('playbookVersion4')]" }, { "kind": "Playbook", - "contentId": "[variables('_RPS_Enrich_StorageVM_Playbook')]", + "contentId": "[variables('_NetApp-RansomwareResilience_Enrich_StorageVM_Playbook')]", "version": "[variables('playbookVersion5')]" }, { "kind": "Playbook", - "contentId": "[variables('_RPS_Enrich_IP_Playbook')]", + "contentId": "[variables('_NetApp-RansomwareResilience_Enrich_IP_Playbook')]", "version": "[variables('playbookVersion6')]" } ] diff --git a/Solutions/NetAppRPS/Package/testParameters.json b/Solutions/NetAppRansomwareResilience/Package/testParameters.json similarity index 100% rename from Solutions/NetAppRPS/Package/testParameters.json rename to Solutions/NetAppRansomwareResilience/Package/testParameters.json diff --git a/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json similarity index 93% rename from Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json index f47fea8fe37..1e3af130cd4 100644 --- a/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json @@ -2,22 +2,22 @@ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { - "title": "NetApp RPS Authentication Playbook", - "description": "This playbook creates a shared Key Vault for NetApp RPS credentials and provides authentication services to all NetApp RPS playbooks in the solution.", + "title": "NetApp Ransomware Resilience Authentication Playbook", + "description": "This playbook creates a shared Key Vault for NetApp Ransomware Resilience credentials and provides authentication services to all NetApp Ransomware Resilience playbooks in the solution.", "prerequisites": [ - "1. Valid client_id, client_secret, and account_id for NetApp RPS API authentication", + "1. Valid client_id, client_secret, and account_id for NetApp Ransomware Resilience API authentication", "2. API endpoint that accepts OAuth2 client credentials flow" ], "postDeployment": [ "1. Update the client_id, client_secret, and account_id values in the Key Vault", "2. Test the Logic App to ensure proper token retrieval", - "3. The Key Vault created by this playbook will be shared across all NetApp RPS playbooks", + "3. The Key Vault created by this playbook will be shared across all NetApp Ransomware Resilience playbooks", "4. Other playbooks will call this Auth playbook to obtain authentication tokens" ], "lastUpdateTime": "2025-09-17T00:00:00.000Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Authentication" ], @@ -31,16 +31,16 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { "description": "Name of the Logic App playbook to be created" } }, "KeyVaultName": { "type": "String", - "defaultValue": "[concat('rpskv', uniqueString(resourceGroup().id))]", + "defaultValue": "[concat('RRSkv', uniqueString(resourceGroup().id))]", "metadata": { - "description": "Name of the shared Key Vault to store NetApp RPS credentials" + "description": "Name of the shared Key Vault to store NetApp Ransomware Resilience credentials" } }, "location": { @@ -53,19 +53,19 @@ "ClientId": { "type": "securestring", "metadata": { - "description": "Client ID for NetApp RPS API authentication" + "description": "Client ID for NetApp Ransomware Resilience API authentication" } }, "ClientSecret": { "type": "securestring", "metadata": { - "description": "Client Secret for NetApp RPS API authentication" + "description": "Client Secret for NetApp Ransomware Resilience API authentication" } }, "AccountId": { "type": "securestring", "metadata": { - "description": "Account ID for NetApp RPS API authentication" + "description": "Account ID for NetApp Ransomware Resilience API authentication" } } }, @@ -248,7 +248,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://netapp-cloud-account.auth0.com/oauth/token", + "uri": "https://staging-netapp-cloud-account.auth0.com/oauth/token", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, diff --git a/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.parameters.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json similarity index 77% rename from Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.parameters.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json index 90ee242aad8..dc2540234df 100644 --- a/Solutions/NetAppRPS/Playbooks/NetApp-RPS-Auth-Playbook/azuredeploy.parameters.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json @@ -3,10 +3,10 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetAppRPS-Auth-Playbook" + "value": "NetApp-RansomwareResilience-Auth-Playbook" }, "KeyVaultName": { - "value": "[concat('rpskv', uniqueString(resourceGroup().id))]" + "value": "[concat('rrskv', uniqueString(resourceGroup().id))]" }, "ClientId": { "value": "YOUR_CLIENT_ID_HERE" diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json similarity index 88% rename from Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json index 1646a508eaa..b3277fd78da 100644 --- a/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json @@ -2,21 +2,21 @@ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { - "title": "NetApp RPS Async Poll Playbook", - "description": "This playbook polls NetApp RPS job status asynchronously until completion or timeout using the updated job status API endpoint.", + "title": "NetApp Ransomware Resilience Async Poll Playbook", + "description": "This playbook polls NetApp Ransomware Resilience job status asynchronously until completion or timeout using the updated job status API endpoint.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "3. Caller must provide job_id, agent_id, system_id, and source parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Test the polling functionality with a valid job ID" + "1. Test the playbook by triggering it with a valid job_id, agent_id, system_id, and source", + "2. Monitor the playbook run history to verify successful polling and completion" ], "lastUpdateTime": "2025-09-17T00:00:00.000Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Async", "Polling" @@ -31,16 +31,16 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "location": { @@ -68,7 +68,7 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" } }, @@ -82,11 +82,11 @@ "properties": { "job_id": { "type": "string", - "description": "The NetApp RPS job ID to poll" + "description": "The NetApp Ransomware Resilience job ID to poll" }, "agent_id": { "type": "string", - "description": "NetApp agent ID" + "description": "NetApp Ransomware Resilience agent ID" }, "system_id": { "type": "string", @@ -178,7 +178,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -212,7 +212,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", "accept": "application/json" @@ -281,7 +281,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", "accept": "application/json" diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json similarity index 51% rename from Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.parameters.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json index f3440d06190..79d957eda11 100644 --- a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.parameters.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json @@ -3,10 +3,10 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetAppRPS-Enrich-StorageVM-Playbook" + "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" }, - "NetAppRPSAuthPlaybookName": { - "value": "NetAppRPS-Auth-Playbook" + "NetAppRansomwareResilienceAuthPlaybookName": { + "value": "NetApp-RansomwareResilience-Auth-Playbook" } } } \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json similarity index 89% rename from Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json index 0477762561b..1ae259d703d 100644 --- a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_IP_Playbook/azuredeploy.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json @@ -2,24 +2,21 @@ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { - "title": "NetApp RPS Enrich IP Playbook", - "description": "This playbook enriches IP data by calling the updated NetApp RPS enrich IP address API endpoint and asynchronously polls multiple job results.", + "title": "NetApp Ransomware Resilience Enrich IP Playbook", + "description": "This playbook enriches IP data by calling the updated NetApp Ransomware Resilience enrich IP address API endpoint and asynchronously polls multiple job results.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. NetApp RPS Async Poll Playbook must be deployed", - "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "4. Caller must provide ip_address parameter" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Ensure the Async Poll Playbook is deployed and functional", - "3. Test the IP enrichment functionality with valid IP address", - "4. Verify the new POST API endpoint is accessible and returns job information with agent_id" + "1. Test the IP enrichment functionality with valid IP address" ], "lastUpdateTime": "2025-09-26T00:00:00.000Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "IP", "Enrich", @@ -35,23 +32,23 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Enrich-IP-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Enrich-IP-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, - "NetAppRPSAsyncPollPlaybookName": { + "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { - "description": "Name of the NetApp RPS async poll playbook" + "description": "Name of the NetApp Ransomware Resilience async poll playbook" } }, "location": { @@ -79,11 +76,11 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" }, "asyncPollPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAsyncPollPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", "type": "String" } }, @@ -158,7 +155,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -238,7 +235,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/ip-address", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/ip-address", "headers": { "Authorization": "Bearer @{variables('Token')}", "accept": "application/json", @@ -327,7 +324,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..317f473b6ae --- /dev/null +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetApp-RansomwareResilience_Enrich_IP_Playbook" + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "value": "NetApp-RansomwareResilience-Auth-Playbook" + }, + "NetAppRansomwareResilienceAsyncPollPlaybookName": { + "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json similarity index 90% rename from Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json index 8b9ccf4e946..362b0194f1d 100644 --- a/Solutions/NetAppRPS/Playbooks/RPS_Enrich_StorageVM_Playbook/azuredeploy.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json @@ -2,21 +2,20 @@ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { - "title": "NetApp RPS Enrich StorageVM Playbook", - "description": "This playbook enriches storage data by calling the updated NetApp RPS enrich storage API endpoint.", + "title": "NetApp Ransomware Resilience Enrich StorageVM Playbook", + "description": "This playbook enriches storage data by calling the updated NetApp Ransomware Resilience enrich storage API endpoint.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "3. Caller must provide agent_id and system_id parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Test the storage enrichment functionality with valid agent_id and system_id" + "1. Test the storage enrichment functionality with valid agent_id and system_id" ], "lastUpdateTime": "2025-09-23T00:00:00.000Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "StorageVM", "Enrich" @@ -31,16 +30,16 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Enrich-StorageVM-Playbook", + "defaultValue": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "location": { @@ -68,7 +67,7 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" } }, @@ -148,7 +147,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -227,7 +226,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{variables('Token')}", "accept": "application/json" diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json similarity index 50% rename from Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.parameters.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json index 9b4b9ab47cc..dab75f5b6b6 100644 --- a/Solutions/NetAppRPS/Playbooks/RPS_Async_Poll_Playbook/azuredeploy.parameters.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json @@ -3,10 +3,10 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetAppRPS-Async-Poll-Playbook" + "value": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook" }, - "NetAppRPSAuthPlaybookName": { - "value": "NetAppRPS-Auth-Playbook" + "NetAppRansomwareResilienceAuthPlaybookName": { + "value": "NetApp-RansomwareResilience-Auth-Playbook" } } } \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json similarity index 91% rename from Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json index e2087995612..cd23212bf4d 100644 --- a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Offline_Playbook/azuredeploy.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json @@ -2,24 +2,21 @@ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { - "title": "NetApp RPS Volume Offline Playbook", - "description": "This playbook takes a NetApp volume offline using the updated NetApp RPS take-volume-offline API endpoint and optionally polls for completion.", + "title": "NetApp Ransomware Resilience Volume Offline Playbook", + "description": "This playbook takes a NetApp volume offline using the updated NetApp Ransomware Resilience take-volume-offline API endpoint and optionally polls for completion.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. NetApp RPS Async Poll Playbook must be deployed first", - "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "4. Caller must provide volume_id, agent_id, and system_id parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Ensure the Async Poll Playbook is working correctly", - "3. Test the volume offline functionality with valid volume_id, agent_id, and system_id", - "4. Verify the new take-volume-offline API endpoint is accessible" + "1. Test the volume offline functionality with valid volume_id, agent_id, and system_id" ], "lastUpdateTime": "2025-09-17T00:00:00.000Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Volume", "Offline" @@ -34,23 +31,23 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Volume-Offline-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Offline-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, - "NetAppRPSAsyncPollPlaybookName": { + "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { - "description": "Name of the NetApp RPS async poll playbook" + "description": "Name of the NetApp Ransomware Resilience async poll playbook" } }, "location": { @@ -78,11 +75,11 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" }, "asyncPollPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAsyncPollPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", "type": "String" } }, @@ -188,7 +185,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -267,7 +264,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-volume-offline", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-volume-offline", "headers": { "Authorization": "Bearer @{variables('Token')}", "Content-Type": "application/json", @@ -404,7 +401,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..82ba2572cd5 --- /dev/null +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetApp-RansomwareResilience_Volume_Offline_Playbook" + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "value": "NetApp-RansomwareResilience-Auth-Playbook" + }, + "NetAppRansomwareResilienceAsyncPollPlaybookName": { + "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json similarity index 91% rename from Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json rename to Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json index 0f7c2e01284..5e938ab10d3 100644 --- a/Solutions/NetAppRPS/Playbooks/RPS_Volume_Snapshot_Playbook/azuredeploy.json +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json @@ -2,24 +2,21 @@ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { - "title": "NetApp RPS Volume Snapshot Playbook", - "description": "This playbook creates a NetApp volume snapshot using the updated NetApp RPS take-snapshot API endpoint and optionally polls for completion.", + "title": "NetApp Ransomware Resilience Volume Snapshot Playbook", + "description": "This playbook creates a NetApp volume snapshot using the updated NetApp Ransomware Resilience take-snapshot API endpoint and optionally polls for completion.", "prerequisites": [ - "1. NetApp RPS Auth Playbook must be deployed first", - "2. NetApp RPS Async Poll Playbook must be deployed first", - "3. Valid NetApp RPS API credentials configured in the Auth Playbook", + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", "4. Caller must provide volume_id, agent_id, and system_id parameters" ], "postDeployment": [ - "1. Ensure the Auth Playbook is working correctly", - "2. Ensure the Async Poll Playbook is working correctly", - "3. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id", - "4. Verify the new take-snapshot API endpoint is accessible" + "1. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id" ], "lastUpdateTime": "2025-09-22T00:00:00.000Z", "tags": [ "NetApp", - "RPS", + "RansomwareResilience", "Playbook", "Volume", "Snapshot" @@ -34,23 +31,23 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Volume-Snapshot-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", "metadata": { "description": "Name of the Logic App/Playbook" } }, - "NetAppRPSAuthPlaybookName": { + "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", "metadata": { - "description": "Name of the NetApp RPS authentication playbook" + "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, - "NetAppRPSAsyncPollPlaybookName": { + "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetAppRPS-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", "metadata": { - "description": "Name of the NetApp RPS async poll playbook" + "description": "Name of the NetApp Ransomware Resilience async poll playbook" } }, "location": { @@ -78,11 +75,11 @@ "contentVersion": "1.0.0.0", "parameters": { "authPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAuthPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", "type": "String" }, "asyncPollPlaybookName": { - "defaultValue": "[parameters('NetAppRPSAsyncPollPlaybookName')]", + "defaultValue": "[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", "type": "String" } }, @@ -188,7 +185,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -267,7 +264,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://snapcenter.cloudmanager.cloud.netapp.com/rps/v1/account/@{variables('AccountId')}/storage/take-snapshot", + "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-snapshot", "headers": { "Authorization": "Bearer @{variables('Token')}", "Content-Type": "application/json", @@ -404,7 +401,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRPSAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json new file mode 100644 index 00000000000..93118e8ef62 --- /dev/null +++ b/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "value": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook" + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "value": "NetApp-RansomwareResilience-Auth-Playbook" + }, + "NetAppRansomwareResilienceAsyncPollPlaybookName": { + "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" + } + } +} \ No newline at end of file diff --git a/Solutions/NetAppRPS/ReleaseNotes.md b/Solutions/NetAppRansomwareResilience/ReleaseNotes.md similarity index 100% rename from Solutions/NetAppRPS/ReleaseNotes.md rename to Solutions/NetAppRansomwareResilience/ReleaseNotes.md diff --git a/Solutions/NetAppRPS/SolutionMetadata.json b/Solutions/NetAppRansomwareResilience/SolutionMetadata.json similarity index 75% rename from Solutions/NetAppRPS/SolutionMetadata.json rename to Solutions/NetAppRansomwareResilience/SolutionMetadata.json index 627499263b2..f0e6ca23f22 100644 --- a/Solutions/NetAppRPS/SolutionMetadata.json +++ b/Solutions/NetAppRansomwareResilience/SolutionMetadata.json @@ -1,9 +1,9 @@ { - "id": "NetAppRPS", - "title": "NetApp RPS (Ransomware Protection Service)", + "id": "NetAppRansomwareResilience", + "title": "NetApp Ransomware Resilience", "publisher": "NetApp", "publisherId": "netapp1234567890", - "offerId": "azure-sentinel-solution-netapprps", + "offerId": "azure-sentinel-solution-netapprrs", "firstPublishDate": "2025-10-31", "lastPublishDate": "2025-10-31", "providers": [ @@ -22,6 +22,6 @@ "tier": "Partner", "link": "https://support.netapp.com" }, - "basePath": "https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/NetAppRPS", + "basePath": "https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/NetAppRansomwareResilience", "version": "3.0.0" } \ No newline at end of file From 5c19f6f3b3c6d1378d567803ff9608bb70749c89 Mon Sep 17 00:00:00 2001 From: Avinash Bharti Date: Fri, 13 Feb 2026 10:35:52 +0530 Subject: [PATCH 14/22] removed: data connectors and analytics rules and added more readme for the playbooks --- .../Solution_NetAppRansomwareResilience.json | 12 +- .../README.md | 42 + .../azuredeploy.json | 5 +- .../azuredeploy.parameters.json | 0 .../azuredeploy.json | 418 ++ .../README.md | 50 + .../azuredeploy.json | 8 +- .../azuredeploy.parameters.json | 0 .../README.md | 62 + .../azuredeploy.json | 29 +- .../azuredeploy.parameters.json | 0 .../README.md | 65 + .../azuredeploy.json | 27 +- .../azuredeploy.parameters.json | 0 .../README.md | 85 + .../azuredeploy.json | 57 +- .../azuredeploy.parameters.json | 0 .../README.md | 75 + .../azuredeploy.json | 8 +- .../azuredeploy.parameters.json | 0 .../Playbooks/README.md | 171 + .../ReleaseNotes.md | 0 .../SolutionMetadata.json | 1 - ...tAppRansomwareResilience_HighSeverity.yaml | 35 - ...ppRansomwareResilience_MediumSeverity.yaml | 35 - ...AppRansomwareResilience_DataConnector.json | 82 - .../azuredeploy_rrs_dataconnector.json | 173 - .../Package/3.0.0.zip | Bin 15964 -> 0 bytes .../Package/createUiDefinition.json | 169 - .../Package/mainTemplate.json | 3618 ----------------- .../Package/testParameters.json | 24 - 31 files changed, 1058 insertions(+), 4193 deletions(-) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Data/Solution_NetAppRansomwareResilience.json (72%) create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json (99%) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json (100%) create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json (94%) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json (100%) create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json (93%) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json (100%) create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json (92%) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json (100%) create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json (91%) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json (100%) create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json (96%) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json (100%) create mode 100644 Solutions/NetApp Ransomware Resilience/Playbooks/README.md rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/ReleaseNotes.md (100%) rename Solutions/{NetAppRansomwareResilience => NetApp Ransomware Resilience}/SolutionMetadata.json (84%) delete mode 100644 Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml delete mode 100644 Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml delete mode 100644 Solutions/NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json delete mode 100644 Solutions/NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json delete mode 100644 Solutions/NetAppRansomwareResilience/Package/3.0.0.zip delete mode 100644 Solutions/NetAppRansomwareResilience/Package/createUiDefinition.json delete mode 100644 Solutions/NetAppRansomwareResilience/Package/mainTemplate.json delete mode 100644 Solutions/NetAppRansomwareResilience/Package/testParameters.json diff --git a/Solutions/NetAppRansomwareResilience/Data/Solution_NetAppRansomwareResilience.json b/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json similarity index 72% rename from Solutions/NetAppRansomwareResilience/Data/Solution_NetAppRansomwareResilience.json rename to Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json index 7d9280bf744..5e9093863da 100644 --- a/Solutions/NetAppRansomwareResilience/Data/Solution_NetAppRansomwareResilience.json +++ b/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json @@ -1,16 +1,10 @@ { - "Name": "NetAppRansomwareResilience", + "Name": "NetApp Ransomware Resilience", "Author": "NetApp - support@netapp.com", "title": "NetApp Ransomware Resilience", "Description": "NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.", "logo": "\"NetApp", - "Data Connectors": [ - "Data Connectors/NetAppRansomwareResilience_DataConnector.json" - ], - "Analytic Rules": [ - "Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml", - "Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml" - ], + "Playbooks": [ "Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json", "Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json", @@ -20,7 +14,7 @@ "Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json" ], "Version": "3.0.0", - "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\NetAppRansomwareResilience", + "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\NetApp Ransomware Resilience", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "StaticDataConnectorIds": [] diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md new file mode 100644 index 00000000000..5ad7e7103ae --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md @@ -0,0 +1,42 @@ +# NetApp Ransomware Resilience Authentication Playbook + +## Overview +This playbook provides authentication services for all NetApp Ransomware Resilience playbooks. It creates and manages a shared Azure Key Vault that securely stores your NetApp API credentials and handles OAuth2 token generation. + +## Purpose +The Auth Playbook serves as the central authentication hub for the NetApp Ransomware Resilience solution. All other playbooks depend on this playbook to obtain valid authentication tokens when communicating with the NetApp Ransomware Resilience API. + +## Deployment Order +**This playbook MUST be deployed FIRST** before deploying any other NetApp Ransomware Resilience playbooks. + +## What It Does +- Creates a shared Azure Key Vault to store NetApp API credentials securely +- Stores your client ID, client secret, and account ID +- Provides authentication tokens to other playbooks on request +- Uses OAuth2 client credentials flow for secure API authentication + +## Prerequisites +Before deploying this playbook, you need: +1. Valid NetApp Ransomware Resilience API credentials: + - Client ID + - Client Secret + - Account ID +2. Appropriate permissions to create resources in your Azure subscription + +## Post-Deployment Configuration +After deploying this playbook: +1. Verify that the Key Vault was created successfully +2. Confirm that your credentials are stored correctly in the Key Vault +3. Test the Logic App to ensure it can retrieve authentication tokens +4. Grant access permissions to the Key Vault for other playbooks as needed + +## Security Notes +- All credentials are stored securely in Azure Key Vault +- The playbook uses system-assigned managed identity for secure operations +- Credentials are never exposed in plain text outside the Key Vault + +## Need Help? +If you encounter authentication issues, verify: +- Your NetApp API credentials are valid and active +- The Key Vault is accessible and contains all required secrets +- The Logic App has appropriate permissions to access the Key Vault diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json similarity index 99% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json index 1e3af130cd4..6a5a8f59699 100644 --- a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json @@ -75,7 +75,7 @@ "resources": [ { "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2019-09-01", + "apiVersion": "2023-07-01", "name": "[parameters('KeyVaultName')]", "location": "[parameters('location')]", "properties": { @@ -89,7 +89,8 @@ "enabledForTemplateDeployment": true, "enableSoftDelete": true, "softDeleteRetentionInDays": 90, - "enableRbacAuthorization": false + "enableRbacAuthorization": false, + "accessPolicies": [] } }, { diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json similarity index 100% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json new file mode 100644 index 00000000000..33c5b6dcaab --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json @@ -0,0 +1,418 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "NetApp RRS Manual IP to Volume Offline", + "description": "Manually trigger playbook to take a volume offline based on IP address enrichment", + "prerequisites": [ + "1. NetApp RRS Auth Playbook must be deployed", + "2. NetApp RRS Async Poll Playbook must be deployed", + "3. NetApp RRS Enrich IP Playbook must be deployed", + "4. NetApp RRS Enrich StorageVM Playbook must be deployed", + "5. NetApp RRS Volume Offline Playbook must be deployed" + ], + "postDeployment": [ + "1. Assign Managed Identity permissions if needed", + "2. Test with a valid IP address" + ], + "lastUpdateTime": "2026-02-09T00:00:00.000Z", + "entities": [], + "tags": ["NetApp", "Ransomware", "Volume", "Offline", "Manual"], + "support": { + "tier": "community" + }, + "author": { + "name": "NetApp" + } + }, + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "IPEnrichmentPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Enrich-IP-Playbook", + "metadata": { + "description": "Name of the IP Enrichment Playbook" + } + }, + "StorageVMEnrichmentPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Enrich-StorageVM-Playbook", + "metadata": { + "description": "Name of the StorageVM Enrichment Playbook" + } + }, + "VolumeOfflinePlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Volume-Offline-Playbook", + "metadata": { + "description": "Name of the Volume Offline Playbook" + } + } + }, + "variables": { + "IPEnrichmentPlaybookId": "[resourceId('Microsoft.Logic/workflows', parameters('IPEnrichmentPlaybookName'))]", + "StorageVMEnrichmentPlaybookId": "[resourceId('Microsoft.Logic/workflows', parameters('StorageVMEnrichmentPlaybookName'))]", + "VolumeOfflinePlaybookId": "[resourceId('Microsoft.Logic/workflows', parameters('VolumeOfflinePlaybookName'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('PlaybookName')]", + "location": "[resourceGroup().location]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "ip_address": { + "type": "string", + "description": "IP address to enrich and take volume offline" + } + }, + "required": ["ip_address"] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "InputIP", + "type": "string", + "value": "@triggerBody()?['ip_address']" + }, + { + "name": "VolumeId", + "type": "string", + "value": "" + }, + { + "name": "AgentId", + "type": "string", + "value": "" + }, + { + "name": "SystemId", + "type": "string", + "value": "" + }, + { + "name": "IPEnrichmentStatus", + "type": "string", + "value": "" + }, + { + "name": "StorageEnrichmentStatus", + "type": "string", + "value": "" + }, + { + "name": "VolumeOfflineStatus", + "type": "string", + "value": "" + }, + { + "name": "ErrorMessage", + "type": "string", + "value": "" + } + ] + } + }, + "Step_1_Call_IP_Enrichment": { + "runAfter": { + "Initialize_Variables": ["Succeeded"] + }, + "type": "Workflow", + "inputs": { + "host": { + "triggerName": "manual", + "workflow": { + "id": "[variables('IPEnrichmentPlaybookId')]" + } + }, + "body": { + "ip_address": "@variables('InputIP')" + } + } + }, + "Parse_IP_Enrichment_Response": { + "runAfter": { + "Step_1_Call_IP_Enrichment": ["Succeeded", "Failed", "TimedOut"] + }, + "type": "Compose", + "inputs": "@if(equals(actions('Step_1_Call_IP_Enrichment').status, 'Succeeded'), body('Step_1_Call_IP_Enrichment'), json(concat('{\"success\": false, \"message\": \"IP Enrichment workflow failed or timed out: ', actions('Step_1_Call_IP_Enrichment').status, '\"}')))" + }, + "Check_IP_Enrichment_Success": { + "runAfter": { + "Parse_IP_Enrichment_Response": ["Succeeded"] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@outputs('Parse_IP_Enrichment_Response')?['success']", + true + ] + } + ] + }, + "actions": { + "Set_IP_Enrichment_Success": { + "type": "SetVariable", + "inputs": { + "name": "IPEnrichmentStatus", + "value": "Success" + } + }, + "Extract_Volume_Data": { + "runAfter": { + "Set_IP_Enrichment_Success": ["Succeeded"] + }, + "type": "Compose", + "inputs": "@first(first(outputs('Parse_IP_Enrichment_Response')?['enrichment']?['polling_results'])?['poll_response']?['data']?['records'])" + }, + "Set_Agent_ID": { + "runAfter": { + "Extract_Volume_Data": ["Succeeded"] + }, + "type": "SetVariable", + "inputs": { + "name": "AgentId", + "value": "@{outputs('Extract_Volume_Data')?['agent_id']}" + } + }, + "Set_System_ID": { + "runAfter": { + "Set_Agent_ID": ["Succeeded"] + }, + "type": "SetVariable", + "inputs": { + "name": "SystemId", + "value": "@{outputs('Extract_Volume_Data')?['system_id']}" + } + }, + "Step_2_Call_StorageVM_Enrichment": { + "runAfter": { + "Set_System_ID": ["Succeeded"] + }, + "type": "Workflow", + "inputs": { + "host": { + "triggerName": "manual", + "workflow": { + "id": "[variables('StorageVMEnrichmentPlaybookId')]" + } + }, + "body": { + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')" + } + } + }, + "Parse_StorageVM_Response": { + "runAfter": { + "Step_2_Call_StorageVM_Enrichment": ["Succeeded", "Failed", "TimedOut"] + }, + "type": "Compose", + "inputs": "@if(equals(actions('Step_2_Call_StorageVM_Enrichment').status, 'Succeeded'), body('Step_2_Call_StorageVM_Enrichment'), json(concat('{\"success\": false, \"message\": \"StorageVM Enrichment workflow failed or timed out: ', actions('Step_2_Call_StorageVM_Enrichment').status, '\"}')))" + }, + "Check_StorageVM_Success": { + "runAfter": { + "Parse_StorageVM_Response": ["Succeeded"] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@outputs('Parse_StorageVM_Response')?['success']", + true + ] + } + ] + }, + "actions": { + "Set_StorageVM_Success": { + "type": "SetVariable", + "inputs": { + "name": "StorageEnrichmentStatus", + "value": "Success" + } + }, + "Extract_Volume_UUID": { + "runAfter": { + "Set_StorageVM_Success": ["Succeeded"] + }, + "type": "Compose", + "inputs": "@first(outputs('Parse_StorageVM_Response')?['enrichment']?['storage_vms'])?['volume_uuid']" + }, + "Update_Volume_ID": { + "runAfter": { + "Extract_Volume_UUID": ["Succeeded"] + }, + "type": "SetVariable", + "inputs": { + "name": "VolumeId", + "value": "@{outputs('Extract_Volume_UUID')}" + } + }, + "Step_3_Call_Volume_Offline": { + "runAfter": { + "Update_Volume_ID": ["Succeeded"] + }, + "type": "Workflow", + "inputs": { + "host": { + "triggerName": "manual", + "workflow": { + "id": "[variables('VolumeOfflinePlaybookId')]" + } + }, + "body": { + "volume_id": "@variables('VolumeId')", + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')", + "poll": true + } + } + }, + "Parse_Volume_Offline_Response": { + "runAfter": { + "Step_3_Call_Volume_Offline": ["Succeeded", "Failed", "TimedOut"] + }, + "type": "Compose", + "inputs": "@if(equals(actions('Step_3_Call_Volume_Offline').status, 'Succeeded'), body('Step_3_Call_Volume_Offline'), json(concat('{\"success\": false, \"message\": \"Volume Offline workflow failed or timed out: ', actions('Step_3_Call_Volume_Offline').status, '\"}')))" + }, + "Set_Volume_Offline_Status": { + "runAfter": { + "Parse_Volume_Offline_Response": ["Succeeded"] + }, + "type": "SetVariable", + "inputs": { + "name": "VolumeOfflineStatus", + "value": "@{if(equals(outputs('Parse_Volume_Offline_Response')?['success'], true), 'Success - Volume Taken Offline', 'Failed - Volume NOT Offline')}" + } + } + }, + "else": { + "actions": { + "Set_StorageVM_Failed": { + "type": "SetVariable", + "inputs": { + "name": "StorageEnrichmentStatus", + "value": "Failed" + } + }, + "Set_StorageVM_Error": { + "runAfter": { + "Set_StorageVM_Failed": ["Succeeded"] + }, + "type": "SetVariable", + "inputs": { + "name": "ErrorMessage", + "value": "@{outputs('Parse_StorageVM_Response')?['message']}" + } + } + } + } + } + }, + "else": { + "actions": { + "Set_IP_Enrichment_Failed": { + "type": "SetVariable", + "inputs": { + "name": "IPEnrichmentStatus", + "value": "Failed" + } + }, + "Set_IP_Error": { + "runAfter": { + "Set_IP_Enrichment_Failed": ["Succeeded"] + }, + "type": "SetVariable", + "inputs": { + "name": "ErrorMessage", + "value": "@{outputs('Parse_IP_Enrichment_Response')?['message']}" + } + } + } + } + }, + "Response": { + "runAfter": { + "Check_IP_Enrichment_Success": ["Succeeded", "Failed"] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@{if(equals(variables('VolumeOfflineStatus'), 'Success - Volume Taken Offline'), 200, 400)}", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@{equals(variables('VolumeOfflineStatus'), 'Success - Volume Taken Offline')}", + "input": { + "ip_address": "@{variables('InputIP')}" + }, + "enrichment_results": { + "ip_enrichment_status": "@{variables('IPEnrichmentStatus')}", + "storage_enrichment_status": "@{variables('StorageEnrichmentStatus')}", + "volume_offline_status": "@{variables('VolumeOfflineStatus')}" + }, + "volume_details": { + "volume_id": "@{variables('VolumeId')}", + "agent_id": "@{variables('AgentId')}", + "system_id": "@{variables('SystemId')}" + }, + "error_message": "@{variables('ErrorMessage')}", + "timestamp": "@{utcNow()}" + } + } + } + }, + "outputs": {} + }, + "parameters": {} + } + } + ], + "outputs": { + "PlaybookName": { + "type": "string", + "value": "[parameters('PlaybookName')]" + }, + "PlaybookResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]" + }, + "PlaybookUrl": { + "type": "string", + "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" + } + } +} diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md new file mode 100644 index 00000000000..60902235271 --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md @@ -0,0 +1,50 @@ +# NetApp Ransomware Resilience Async Poll Playbook + +## Overview +This playbook monitors the status of asynchronous NetApp operations by polling job status until completion or timeout. It acts as a helper playbook for operations that take time to complete. + +## Purpose +When you perform actions like taking snapshots or taking volumes offline, these operations run asynchronously in the NetApp system. This playbook continuously checks the job status and notifies you when the operation completes, fails, or times out. + +## Deployment Order +**This playbook MUST be deployed SECOND**, after: +1. āœ… Auth Playbook (required) + +## What It Does +- Polls NetApp job status at regular intervals +- Monitors asynchronous operations until completion +- Handles timeout scenarios for long-running jobs +- Returns final job status to the calling playbook +- Provides operation results back to parent workflows + +## Prerequisites +Before deploying this playbook: +1. The Auth Playbook must be successfully deployed and functioning +2. Valid NetApp API credentials configured in the Auth Playbook + +## How It Works +1. Receives a job ID, agent ID, system ID, and source from a calling playbook +2. Requests an authentication token from the Auth Playbook +3. Polls the NetApp API for job status at regular intervals +4. Continues polling until the job completes, fails, or times out +5. Returns the final status to the calling playbook + +## When Is This Used? +This playbook is automatically called by other action playbooks such as: +- Volume Snapshot Playbook +- Volume Offline Playbook +- Any other playbook that initiates asynchronous NetApp operations + +You typically won't call this playbook directly—it's invoked automatically by other playbooks that need to wait for operation completion. + +## Post-Deployment Configuration +After deploying this playbook: +1. Test it by triggering with a valid job ID from a NetApp operation +2. Monitor the run history to verify successful polling behavior +3. Adjust timeout settings if needed based on your environment + +## Need Help? +If polling isn't working correctly, verify: +- The Auth Playbook is functioning and returning valid tokens +- The job ID being polled is valid and active +- Your NetApp API endpoint is accessible diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json similarity index 94% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json index b3277fd78da..8aa162bfd29 100644 --- a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json @@ -178,7 +178,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -212,7 +212,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", "accept": "application/json" @@ -281,7 +281,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", "accept": "application/json" @@ -475,7 +475,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json similarity index 100% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md new file mode 100644 index 00000000000..76fa0394497 --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md @@ -0,0 +1,62 @@ +# NetApp Ransomware Resilience Enrich IP Playbook + +## Overview +This playbook enriches IP address information by retrieving detailed network interface data from the NetApp Ransomware Resilience API. It helps you investigate network-related security incidents by providing context about storage network interfaces. + +## Purpose +When investigating a security incident involving a suspicious IP address, this playbook retrieves detailed information about the network interface from your NetApp storage systems, including associated volumes, storage VMs, and access patterns. + +## Deployment Order +**This playbook should be deployed THIRD**, after: +1. āœ… Auth Playbook (required) +2. āœ… Async Poll Playbook (required) + +## What It Does +- Accepts an IP address as input +- Retrieves authentication from the Auth Playbook +- Queries the NetApp API for network interface details associated with that IP +- Polls asynchronously for the enrichment results +- Returns detailed network interface information including: + - Network interface configuration + - Associated storage VMs + - Connected volumes + - Access policies and protocols + +## Prerequisites +Before deploying this playbook: +1. Auth Playbook must be deployed and functioning correctly +2. Async Poll Playbook must be deployed and functioning correctly +3. Valid NetApp API credentials configured + +## How to Use +This playbook can be: +- Called manually with an IP address to investigate +- Integrated into automation rules triggered by Microsoft Sentinel alerts +- Chained with other playbooks in your incident response workflow +- Combined with Volume Snapshot or Volume Offline playbooks for remediation + +**Input Required:** +- `ip_address`: The IP address you want to investigate + +## Use Case Example +When you receive an alert about suspicious activity from an IP address: +1. This playbook enriches the IP with NetApp storage context +2. You identify which storage VM and volumes are exposed +3. Based on the findings, you can take protective actions using other playbooks + +## Post-Deployment Configuration +After deploying this playbook: +1. Test with a known valid IP address from your NetApp environment +2. Verify the enrichment data is returned correctly +3. Consider integrating it into your incident response automation rules + +## Building Custom Workflows +This enrichment playbook is a building block. You can combine it with other playbooks to create complete incident response workflows. For example: +- Enrich IP → Identify volume → Take snapshot → Take volume offline + +## Need Help? +If enrichment isn't working, verify: +- The Auth Playbook is returning valid tokens +- The Async Poll Playbook is functioning correctly +- The IP address exists in your NetApp environment +- Your NetApp API endpoint is accessible diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json similarity index 93% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json index 1ae259d703d..357620be3d9 100644 --- a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json @@ -155,7 +155,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -235,7 +235,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/ip-address", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/enrich/ip-address", "headers": { "Authorization": "Bearer @{variables('Token')}", "accept": "application/json", @@ -324,7 +324,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -392,11 +392,13 @@ } } }, - "Return_Response": { + "Finalize_Execution": { "runAfter": { "Poll_All_Jobs": [ "Succeeded", - "Skipped" + "Skipped", + "Failed", + "TimedOut" ], "Call_Auth_Playbook": [ "Failed", @@ -407,6 +409,21 @@ "TimedOut" ] }, + "type": "Compose", + "inputs": { + "execution_completed": true, + "timestamp": "@utcNow()" + } + }, + "Return_Response": { + "runAfter": { + "Finalize_Execution": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ] + }, "type": "Response", "kind": "Http", "inputs": { @@ -455,7 +472,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json similarity index 100% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md new file mode 100644 index 00000000000..c02fb746779 --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md @@ -0,0 +1,65 @@ +# NetApp Ransomware Resilience Enrich StorageVM Playbook + +## Overview +This playbook enriches storage information by retrieving detailed configuration and status data for NetApp Storage Virtual Machines (SVMs). It provides valuable context when investigating incidents involving your NetApp storage infrastructure. + +## Purpose +When investigating a security incident, this playbook helps you understand the storage environment by retrieving detailed information about Storage VMs, including their volumes, security settings, and current operational status. + +## Deployment Order +**This playbook should be deployed FOURTH**, after: +1. āœ… Auth Playbook (required) +2. āœ… Async Poll Playbook (required) +3. āœ… Enrich IP Playbook (optional, recommended) + +## What It Does +- Accepts agent ID and system ID as input +- Retrieves authentication from the Auth Playbook +- Queries the NetApp API for Storage VM details +- Returns comprehensive storage configuration information including: + - Storage VM configuration and status + - Associated volumes and their states + - Security and protocol settings + - Network interface configurations + - Access policies + +## Prerequisites +Before deploying this playbook: +1. Auth Playbook must be deployed and functioning correctly +2. Valid NetApp API credentials configured + +## How to Use +This playbook can be: +- Called manually with agent ID and system ID to investigate storage configurations +- Triggered automatically as part of incident response workflows +- Combined with other playbooks to create comprehensive response actions +- Used to gather context before taking protective actions + +**Input Required:** +- `agent_id`: The NetApp agent identifier +- `system_id`: The NetApp system identifier + +## Use Case Example +When investigating a potential ransomware incident: +1. Use this playbook to retrieve Storage VM details +2. Identify all volumes and their current states +3. Assess which volumes may be at risk +4. Use Volume Snapshot playbook to protect critical data +5. Use Volume Offline playbook to isolate compromised volumes + +## Post-Deployment Configuration +After deploying this playbook: +1. Test with valid agent ID and system ID from your NetApp environment +2. Verify the storage enrichment data is returned correctly +3. Consider integrating it into your security automation workflows + +## Building Custom Workflows +This enrichment playbook is designed as a building block. Combine it with action playbooks to create complete incident response solutions: +- Enrich StorageVM → Identify critical volumes → Take snapshots → Take volumes offline if needed + +## Need Help? +If enrichment isn't working, verify: +- The Auth Playbook is returning valid tokens +- The agent ID and system ID are correct and active +- Your NetApp API endpoint is accessible +- The Storage VM exists in your NetApp environment diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json similarity index 92% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json index 362b0194f1d..2c8fc685b17 100644 --- a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json @@ -147,7 +147,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -226,7 +226,7 @@ "type": "Http", "inputs": { "method": "GET", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", "headers": { "Authorization": "Bearer @{variables('Token')}", "accept": "application/json" @@ -293,11 +293,13 @@ "value": "@body('Parse_StorageVM_Response')" } }, - "Return_Response": { + "Finalize_Execution": { "runAfter": { "Store_StorageVM_Data": [ "Succeeded", - "Skipped" + "Skipped", + "Failed", + "TimedOut" ], "Call_Auth_Playbook": [ "Failed", @@ -308,6 +310,21 @@ "TimedOut" ] }, + "type": "Compose", + "inputs": { + "execution_completed": true, + "timestamp": "@utcNow()" + } + }, + "Return_Response": { + "runAfter": { + "Finalize_Execution": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ] + }, "type": "Response", "kind": "Http", "inputs": { @@ -353,7 +370,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json similarity index 100% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md new file mode 100644 index 00000000000..c1c228066bd --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md @@ -0,0 +1,85 @@ +# NetApp Ransomware Resilience Volume Offline Playbook + +## Overview +This playbook takes NetApp volumes offline to immediately stop access and prevent further damage during a security incident. Taking a volume offline is a protective action that isolates compromised or at-risk storage. + +## Purpose +When you identify a volume that is compromised by ransomware or under active attack, taking it offline immediately stops all access, preventing the spread of malware and protecting other parts of your infrastructure. + +## Deployment Order +**This playbook should be deployed SIXTH**, after: +1. āœ… Auth Playbook (required) +2. āœ… Async Poll Playbook (required) +3. āœ… Enrich IP Playbook (optional) +4. āœ… Enrich StorageVM Playbook (optional) +5. āœ… Volume Snapshot Playbook (optional, but **strongly recommended**) + +## What It Does +- Accepts volume ID, agent ID, and system ID as input +- Retrieves authentication from the Auth Playbook +- Initiates a volume offline operation via the NetApp API +- Uses the Async Poll Playbook to monitor operation completion +- Confirms when the volume is successfully taken offline +- Returns operation status + +## Prerequisites +Before deploying this playbook: +1. Auth Playbook must be deployed and functioning correctly +2. Async Poll Playbook must be deployed and functioning correctly +3. Valid NetApp API credentials configured + +## How to Use +This playbook can be: +- Called manually when you need to isolate a compromised volume +- Triggered automatically by Microsoft Sentinel automation rules during high-severity incidents +- Used as the final step in incident response workflows +- Combined with snapshot playbooks for data protection before isolation + +**Input Required:** +- `volume_id`: The ID of the volume to take offline +- `agent_id`: The NetApp agent identifier +- `system_id`: The NetApp system identifier + +## āš ļø Critical Considerations +**Before taking a volume offline:** +- **Create a snapshot first** using the Volume Snapshot Playbook—this ensures you have a recovery point +- Understand the business impact—offline volumes are completely inaccessible +- Verify you're targeting the correct volume +- Have a recovery plan in place +- Document the reason for taking the volume offline + +## Use Case Example +**Ransomware Containment:** +1. Receive alert about active file encryption on a volume +2. Use Enrich IP or Enrich StorageVM playbooks to confirm the affected volume +3. **Use Volume Snapshot playbook to create a clean recovery point** +4. **Use this playbook to take the compromised volume offline** +5. Investigation and remediation can proceed safely +6. Restore from snapshot when ready + +## Post-Deployment Configuration +After deploying this playbook: +1. Test with a non-production volume using valid IDs +2. Verify the volume is taken offline successfully +3. Test bringing the volume back online to ensure recoverability +4. Configure automation rules with appropriate severity thresholds +5. Document your volume offline procedures and approval workflows + +## Building Custom Workflows +This playbook is typically the **final protective action** in an incident response workflow: +- Enrich IP → Identify volume → Take snapshot → **Take volume offline** +- Critical alert → Enrich StorageVM → Snapshot critical volumes → **Offline compromised volume** + +## Need Help? +If the volume offline operation isn't working, verify: +- The Auth Playbook is returning valid tokens +- The Async Poll Playbook is functioning correctly +- Volume ID, agent ID, and system ID are correct +- You have appropriate permissions to modify volume states +- The volume is currently online and accessible + +## Recovery +To bring a volume back online after remediation: +- Use NetApp management tools or APIs +- Verify the threat has been fully remediated before bringing volumes online +- Restore from snapshots if data was compromised diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json similarity index 91% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json index cd23212bf4d..a514788e8bc 100644 --- a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json @@ -185,7 +185,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -264,7 +264,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-volume-offline", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/storage/take-volume-offline", "headers": { "Authorization": "Bearer @{variables('Token')}", "Content-Type": "application/json", @@ -398,10 +398,11 @@ }, "actions": { "Call_Async_Poll_Playbook": { + "runAfter": {}, "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -436,24 +437,8 @@ "Succeeded" ] }, - "type": "ParseJson", - "inputs": { - "content": "@body('Call_Async_Poll_Playbook')", - "schema": { - "type": "object", - "properties": { - "status": { - "type": "string" - }, - "jobId": { - "type": "string" - }, - "success": { - "type": "boolean" - } - } - } - } + "type": "Compose", + "inputs": "@if(equals(actions('Call_Async_Poll_Playbook')['status'], 'Succeeded'), body('Call_Async_Poll_Playbook'), json('{\"success\": false, \"status\": \"FAILED\", \"error\": \"Poll playbook failed or timed out\"}'))" }, "Store_Poll_Response": { "runAfter": { @@ -464,17 +449,22 @@ "type": "SetVariable", "inputs": { "name": "PollResponse", - "value": "@body('Parse_Poll_Response')" + "value": "@outputs('Parse_Poll_Response')" } }, - "Return_Response": { + "Finalize_Execution": { "runAfter": { "Store_Poll_Response": [ "Succeeded", - "Skipped" + "Skipped", + "Failed", + "TimedOut" ], "Check_If_Should_Poll": [ - "Succeeded" + "Succeeded", + "Skipped", + "Failed", + "TimedOut" ], "Call_Auth_Playbook": [ "Failed", @@ -485,6 +475,21 @@ "TimedOut" ] }, + "type": "Compose", + "inputs": { + "execution_completed": true, + "timestamp": "@utcNow()" + } + }, + "Return_Response": { + "runAfter": { + "Finalize_Execution": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ] + }, "type": "Response", "kind": "Http", "inputs": { @@ -535,7 +540,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json similarity index 100% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md new file mode 100644 index 00000000000..a922da87cbc --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md @@ -0,0 +1,75 @@ +# NetApp Ransomware Resilience Volume Snapshot Playbook + +## Overview +This playbook creates point-in-time snapshots of NetApp volumes to protect your data. When responding to a security incident, snapshots provide a clean recovery point and preserve evidence for investigation. + +## Purpose +During a ransomware or security incident, taking immediate snapshots of critical volumes ensures you have a clean copy of data before any potential corruption or encryption occurs. These snapshots can be used for recovery or forensic analysis. + +## Deployment Order +**This playbook should be deployed FIFTH**, after: +1. āœ… Auth Playbook (required) +2. āœ… Async Poll Playbook (required) +3. āœ… Enrich IP Playbook (optional) +4. āœ… Enrich StorageVM Playbook (optional) + +## What It Does +- Accepts volume ID, agent ID, and system ID as input +- Retrieves authentication from the Auth Playbook +- Initiates a snapshot creation operation via the NetApp API +- Uses the Async Poll Playbook to monitor snapshot completion +- Confirms when the snapshot is successfully created +- Returns snapshot details and status + +## Prerequisites +Before deploying this playbook: +1. Auth Playbook must be deployed and functioning correctly +2. Async Poll Playbook must be deployed and functioning correctly +3. Valid NetApp API credentials configured +4. Sufficient storage capacity for snapshots + +## How to Use +This playbook can be: +- Called manually when you identify a volume that needs protection +- Triggered automatically by Microsoft Sentinel automation rules +- Integrated into multi-step incident response workflows +- Combined with enrichment playbooks to identify which volumes to snapshot + +**Input Required:** +- `volume_id`: The ID of the volume to snapshot +- `agent_id`: The NetApp agent identifier +- `system_id`: The NetApp system identifier + +## Use Case Example +**Ransomware Incident Response:** +1. Receive alert about suspicious file encryption activity +2. Use Enrich IP or Enrich StorageVM playbooks to identify affected volumes +3. **Use this playbook to immediately snapshot clean volumes** +4. Use Volume Offline playbook to isolate compromised volumes +5. Restore from snapshots if needed + +## Important Notes +- Snapshots preserve the current state of the volume +- Snapshots consume storage space—monitor your capacity +- Take snapshots BEFORE taking volumes offline for maximum data protection +- Regular snapshots are recommended as part of your backup strategy + +## Post-Deployment Configuration +After deploying this playbook: +1. Test with a non-production volume using valid IDs +2. Verify the snapshot is created successfully +3. Configure automation rules to trigger snapshots during security incidents +4. Document your snapshot retention policies + +## Building Custom Workflows +Combine this playbook with others to create comprehensive incident response: +- Enrich IP → Identify volumes → **Take snapshots** → Take volumes offline +- Alert triggers → Enrich StorageVM → **Take snapshots of all critical volumes** + +## Need Help? +If snapshot creation isn't working, verify: +- The Auth Playbook is returning valid tokens +- The Async Poll Playbook is functioning correctly +- Volume ID, agent ID, and system ID are correct +- You have sufficient storage capacity for snapshots +- Your NetApp system supports snapshot operations diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json similarity index 96% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json index 5e938ab10d3..3dbbe4c39d1 100644 --- a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json @@ -185,7 +185,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -264,7 +264,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-snapshot", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/storage/take-snapshot", "headers": { "Authorization": "Bearer @{variables('Token')}", "Content-Type": "application/json", @@ -401,7 +401,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -535,7 +535,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json similarity index 100% rename from Solutions/NetAppRansomwareResilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json rename to Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/README.md new file mode 100644 index 00000000000..95b1b86e579 --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/README.md @@ -0,0 +1,171 @@ +# NetApp Ransomware Resilience Playbooks + +## Overview +The NetApp Ransomware Resilience solution provides a set of modular playbooks that work together to help you respond to ransomware and security incidents affecting your NetApp storage infrastructure. These playbooks integrate with Microsoft Sentinel to provide automated investigation and response capabilities. + +## Architecture +The playbooks are designed as **building blocks** that you can combine to create custom incident response workflows. Each playbook serves a specific purpose, and they work together to provide comprehensive ransomware protection. + +### Playbook Categories + +**Foundation Playbooks** (Required Infrastructure): +- **Authentication Playbook** - Manages credentials and provides authentication tokens +- **Async Poll Playbook** - Monitors asynchronous operations until completion + +**Investigation Playbooks** (Data Enrichment): +- **Enrich IP Playbook** - Retrieves network interface details for IP addresses +- **Enrich StorageVM Playbook** - Retrieves Storage VM configuration and volume information + +**Response Playbooks** (Protective Actions): +- **Volume Snapshot Playbook** - Creates point-in-time snapshots for data protection +- **Volume Offline Playbook** - Takes volumes offline to isolate compromised storage + +## šŸš€ Deployment Order + +**You MUST deploy the playbooks in this specific order:** + +### 1. Authentication Playbook (FIRST) +Deploy the **NetApp-RansomwareResilience-Auth-Playbook** first. This creates the shared Key Vault and provides authentication services that all other playbooks depend on. + +šŸ“– [Auth Playbook Documentation](./NetApp-RansomwareResilience-Auth-Playbook/README.md) + +### 2. Async Poll Playbook (SECOND) +Deploy the **NetApp-RansomwareResilience-Async-Poll-Playbook** next. This monitors asynchronous operations and is used by most other playbooks. + +šŸ“– [Async Poll Playbook Documentation](./NetApp-RansomwareResilience_Async_Poll_Playbook/README.md) + +### 3. Enrich IP Playbook (THIRD) +Deploy the **NetApp-RansomwareResilience-Enrich-IP-Playbook** to enable IP address investigation capabilities. + +šŸ“– [Enrich IP Playbook Documentation](./NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md) + +### 4. Enrich StorageVM Playbook (FOURTH) +Deploy the **NetApp-RansomwareResilience-Enrich-StorageVM-Playbook** to enable storage configuration investigation. + +šŸ“– [Enrich StorageVM Playbook Documentation](./NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md) + +### 5. Volume Snapshot Playbook (FIFTH) +Deploy the **NetApp-RansomwareResilience-Volume-Snapshot-Playbook** to enable data protection through snapshots. + +šŸ“– [Volume Snapshot Playbook Documentation](./NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md) + +### 6. Volume Offline Playbook (SIXTH) +Deploy the **NetApp-RansomwareResilience-Volume-Offline-Playbook** to enable volume isolation capabilities. + +šŸ“– [Volume Offline Playbook Documentation](./NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md) + +## Building Custom Incident Response Workflows + +These playbooks are designed to work together as building blocks. You can create powerful automated response workflows by combining them in different ways. + +### Example Workflow Pattern + +Here's a typical ransomware incident response pattern: + +``` +Incident Detected + ↓ +Investigate (Enrich IP or Enrich StorageVM) + ↓ +Identify Affected Volumes + ↓ +Protect Data (Volume Snapshot) + ↓ +Contain Threat (Volume Offline) +``` + +### Sample Use Cases + +**Use Case 1: Suspicious IP Investigation** +1. Alert triggers on suspicious IP activity +2. **Enrich IP Playbook** - Gather network interface details +3. **Enrich StorageVM Playbook** - Get full storage context +4. **Volume Snapshot Playbook** - Protect volumes before taking action +5. **Volume Offline Playbook** - Isolate if threat is confirmed + +**Use Case 2: Ransomware Alert Response** +1. Ransomware detection alert triggers +2. **Enrich StorageVM Playbook** - Identify all volumes on affected storage +3. **Volume Snapshot Playbook** - Immediately snapshot all critical volumes +4. **Volume Offline Playbook** - Take compromised volumes offline +5. Restore from snapshots after remediation + +**Use Case 3: Manual Investigation** +1. SOC analyst receives threat intelligence +2. Manually trigger **Enrich IP Playbook** with suspicious IP +3. Review enrichment data to assess risk +4. If needed, manually trigger **Volume Snapshot** and **Volume Offline** playbooks + +## Getting Started + +### Prerequisites +Before deploying any playbooks: +- Access to an Azure subscription with Microsoft Sentinel enabled +- Valid NetApp Ransomware Resilience API credentials (client ID, client secret, account ID) +- Appropriate permissions to create Azure resources +- Understanding of your NetApp storage infrastructure + +### Deployment Steps +1. **Deploy Foundation Playbooks** (Auth, then Async Poll) +2. **Configure Authentication** - Add your NetApp API credentials to the Key Vault +3. **Test Foundation Playbooks** - Verify authentication is working +4. **Deploy Investigation Playbooks** - Add enrichment capabilities as needed +5. **Deploy Response Playbooks** - Add protective action capabilities +6. **Test Each Playbook** - Verify functionality with non-production resources +7. **Create Automation Rules** - Connect playbooks to Microsoft Sentinel alerts +8. **Document Procedures** - Define when and how each playbook should be used + +### Testing Recommendations +- Always test with non-production volumes first +- Verify authentication before deploying action playbooks +- Create test automation rules before enabling production triggers +- Document volume offline/online procedures +- Establish snapshot retention policies + +## Best Practices for SOC Analysts + +### Investigation Phase +- Use **Enrich IP** and **Enrich StorageVM** playbooks to gather context +- Review enrichment data before taking protective actions +- Document findings for incident reports + +### Response Phase +- **Always take snapshots BEFORE taking volumes offline** +- Verify you're targeting the correct volumes +- Understand the business impact of taking volumes offline +- Follow your organization's approval process for disruptive actions + +### Recovery Phase +- Use snapshots to restore clean data +- Verify threats are fully remediated before bringing volumes online +- Update security controls to prevent recurrence + +## Security Considerations +- All NetApp API credentials are stored securely in Azure Key Vault +- Playbooks use managed identities for Azure resource access +- Review and approve automation rules before enabling auto-response +- Maintain audit logs of all playbook executions +- Regularly review and update API credentials + +## Support and Troubleshooting + +### Common Issues +- **Authentication failures**: Verify credentials in Key Vault and Auth Playbook functionality +- **Polling timeouts**: Check network connectivity to NetApp API endpoints +- **Invalid volume IDs**: Confirm IDs from enrichment playbooks before using action playbooks +- **Permission errors**: Verify playbook managed identities have required access + +### Getting Help +- Review individual playbook README files for specific troubleshooting +- Check Logic App run history for detailed error messages +- Verify prerequisites are met for each playbook +- Test with known-good values from your NetApp environment + +## Additional Resources +- Microsoft Sentinel Documentation: [https://docs.microsoft.com/azure/sentinel/](https://docs.microsoft.com/azure/sentinel/) +- Azure Logic Apps Documentation: [https://docs.microsoft.com/azure/logic-apps/](https://docs.microsoft.com/azure/logic-apps/) +- NetApp Ransomware Resilience Documentation: Contact NetApp Support + +--- + +**Remember:** These playbooks are powerful tools for incident response. Always test thoroughly, understand the impact of actions, and follow your organization's security procedures. diff --git a/Solutions/NetAppRansomwareResilience/ReleaseNotes.md b/Solutions/NetApp Ransomware Resilience/ReleaseNotes.md similarity index 100% rename from Solutions/NetAppRansomwareResilience/ReleaseNotes.md rename to Solutions/NetApp Ransomware Resilience/ReleaseNotes.md diff --git a/Solutions/NetAppRansomwareResilience/SolutionMetadata.json b/Solutions/NetApp Ransomware Resilience/SolutionMetadata.json similarity index 84% rename from Solutions/NetAppRansomwareResilience/SolutionMetadata.json rename to Solutions/NetApp Ransomware Resilience/SolutionMetadata.json index f0e6ca23f22..40f11fb1ab1 100644 --- a/Solutions/NetAppRansomwareResilience/SolutionMetadata.json +++ b/Solutions/NetApp Ransomware Resilience/SolutionMetadata.json @@ -22,6 +22,5 @@ "tier": "Partner", "link": "https://support.netapp.com" }, - "basePath": "https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/NetAppRansomwareResilience", "version": "3.0.0" } \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml b/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml deleted file mode 100644 index 293891058ea..00000000000 --- a/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_HighSeverity.yaml +++ /dev/null @@ -1,35 +0,0 @@ -id: 33b9688b-2afb-442f-a3bb-fe2362717bb7 -name: NetApp Ransomware Resilience High Severity Alert -description: | - 'Detects high severity NetApp Ransomware Resilience alerts that require immediate attention. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with HIGH severity level.' -severity: High -status: Available -requiredDataConnectors: - - connectorId: NetAppRansomwareResilienceCustomLogsIngestion - dataTypes: - - NetAppRansomwareResilience_alerts_CL -suppressionDuration: PT5H -suppressionEnabled: false -query: | - NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d) - | where severity == "HIGH" -alertDetailsOverride: - alertDisplayNameFormat: "{{description}}" - alertDescriptionFormat: "High severity alert detected from NetApp Ransomware Resilience Service: {{description}}" -customDetails: - Severity: severity - IncidentDetails: incident - ContextInfo: context -incidentConfiguration: - createIncident: true - groupingConfiguration: - enabled: false - reopenClosedIncident: false - lookbackDuration: PT5H - matchingMethod: AllEntities -eventGroupingSettings: - aggregationKind: AlertPerResult -version: 1.0.0 -kind: NRT -tactics: [] -relevantTechniques: [] diff --git a/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml b/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml deleted file mode 100644 index 17eec70e8d4..00000000000 --- a/Solutions/NetAppRansomwareResilience/Analytic Rules/NetAppRansomwareResilience_MediumSeverity.yaml +++ /dev/null @@ -1,35 +0,0 @@ -id: be774c6e-7613-41db-b6e4-25975b680d24 -name: NetApp Ransomware Resilience Medium Severity Alert -description: | - 'Detects medium severity NetApp Ransomware Resilience alerts that may require investigation. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with MEDIUM severity level.' -severity: Medium -status: Available -requiredDataConnectors: - - connectorId: NetAppRansomwareResilienceCustomLogsIngestion - dataTypes: - - NetAppRansomwareResilience_alerts_CL -suppressionDuration: PT5H -suppressionEnabled: false -query: | - NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d) - | where severity == "MEDIUM" -alertDetailsOverride: - alertDisplayNameFormat: "{{description}}" - alertDescriptionFormat: "Medium severity alert detected from NetApp Ransomware Resilience Service: {{description}}" -customDetails: - Severity: severity - IncidentDetails: incident - ContextInfo: context -incidentConfiguration: - createIncident: true - groupingConfiguration: - enabled: false - reopenClosedIncident: false - lookbackDuration: PT5H - matchingMethod: AllEntities -eventGroupingSettings: - aggregationKind: AlertPerResult -version: 1.0.0 -kind: NRT -tactics: [] -relevantTechniques: [] diff --git a/Solutions/NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json b/Solutions/NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json deleted file mode 100644 index 601c20b40e9..00000000000 --- a/Solutions/NetAppRansomwareResilience/Data Connectors/NetAppRansomwareResilience_DataConnector.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "id": "NetAppRansomwareResilienceCustomLogsIngestion", - "title": "NetAppRansomwareResilience Data Connector", - "publisher": "NetAppRansomwareResilience", - "descriptionMarkdown": "Data connector for ingesting NetApp Ransomware Resilience alerts into Microsoft Sentinel. This connector enables seamless integration of Ransomware Resilience alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", - "additionalRequirementBanner": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", - "graphQueries": [ - { - "metricName": "Total data received", - "legend": "NetAppRansomwareResilience_alerts_CL", - "baseQuery": "NetAppRansomwareResilience_alerts_CL" - } - ], - "dataTypes": [ - { - "name": "NetAppRansomwareResilience_alerts_CL", - "lastDataReceivedQuery": "NetAppRansomwareResilience_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - } - ], - "sampleQueries": [ - { - "description": "Default Query", - "query": "NetAppRansomwareResilience_alerts_CL" - } - ], - "connectivityCriterias": [ - { - "type": "IsConnectedQuery", - "value": [ - "NetAppRansomwareResilience_alerts_CL" - ] - } - ], - "availability": { - "status": 1, - "isPreview": true - }, - "permissions": { - "resourceProvider": [ - { - "provider": "Microsoft.OperationalInsights/workspaces", - "permissionsDisplayText": "read and write permissions are required.", - "providerDisplayName": "Workspace", - "scope": "Workspace", - "requiredPermissions": { - "write": true, - "read": true, - "delete": true - } - }, - { - "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", - "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", - "providerDisplayName": "Keys", - "scope": "Workspace", - "requiredPermissions": { - "action": true - } - } - ], - "customs": [ - { - "name": "Azure Subscription", - "description": "Azure Subscription with owner role is required to register an application in azure active directory() and assign role of contributor to app in resource group." - }, - { - "name": "NetApp Console Organization", - "description": "NetApp Console Organization with permissions to create a new Service Account" - } - ] - }, - "instructionSteps": [ - { - "title": "1. Configuration", - "description": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data." - }, - { - "title": "2. Deploy the ARM Template", - "description": "Click the button below to deploy the NetApp Ransomware Resilience data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRansomwareResilience%2FData%2520Connectors%2Fazuredeploy_rrs_dataconnector.json)" - } - ] -} \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json b/Solutions/NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json deleted file mode 100644 index 2696ca7472c..00000000000 --- a/Solutions/NetAppRansomwareResilience/Data Connectors/azuredeploy_rrs_dataconnector.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "workspaceResourceId": { - "type": "string", - "metadata": { - "description": "Specifies the Azure resource ID of the Log Analytics workspace to use." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Specifies the Object ID of the App registration to be used." - } - } - }, - "resources": [ - { - "type": "Microsoft.OperationalInsights/workspaces/tables", - "apiVersion": "2022-10-01", - "name": "[concat(parameters('workspaceResourceId'), '/NetAppRansomwareResilience_alerts_CL')]", - "properties": { - "description": "Custom log table for storing custom logs", - "retentionInDays": 30, - "schema": { - "name": "NetAppRansomwareResilience_alerts_CL", - "columns": [ - { - "name": "TimeGenerated", - "type": "datetime" - }, - { - "name": "description", - "type": "string" - }, - { - "name": "severity", - "type": "string" - }, - { - "name": "incident", - "type": "dynamic" - }, - { - "name": "context", - "type": "dynamic" - } - ] - } - } - }, - { - "type": "Microsoft.Insights/dataCollectionEndpoints", - "name": "ransomware-resilience-alerts-dce", - "location": "[resourceGroup().location]", - "apiVersion": "2021-04-01", - "properties": { - "networkAcls": { - "publicNetworkAccess": "Enabled" - } - } - }, - { - "type": "Microsoft.Insights/dataCollectionRules", - "name": "ransomware-resilience-alerts-dcr", - "location": "[resourceGroup().location]", - "apiVersion": "2023-03-11", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRansomwareResilience_alerts_CL')]", - "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]" - ], - "properties": { - "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]", - "streamDeclarations": { - "Custom-MyTableRawData": { - "columns": [ - { - "name": "TimeGenerated", - "type": "datetime" - }, - { - "name": "description", - "type": "string" - }, - { - "name": "severity", - "type": "string" - }, - { - "name": "incident", - "type": "dynamic" - }, - { - "name": "context", - "type": "dynamic" - } - ] - } - }, - "destinations": { - "logAnalytics": [ - { - "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceResourceId'))]", - "name": "[parameters('workspaceResourceId')]" - } - ] - }, - "dataFlows": [ - { - "streams": [ - "Custom-NetAppRansomwareResilience_alerts_CL" - ], - "destinations": [ - "[parameters('workspaceResourceId')]" - ], - "transformKql": "source", - "outputStream": "Custom-NetAppRansomwareResilience_alerts_CL" - } - ] - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(resourceGroup().id, 'ransomware-resilience-alerts-dce', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", - "scope": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "principalId": "[parameters('principalId')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Insights/dataCollectionEndpoints', 'ransomware-resilience-alerts-dce')]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(resourceGroup().id, 'ransomware-resilience-alerts-dcr', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", - "scope": "[resourceId('Microsoft.Insights/dataCollectionRules', 'ransomware-resilience-alerts-dcr')]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "principalId": "[parameters('principalId')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Insights/dataCollectionRules', 'ransomware-resilience-alerts-dcr')]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(resourceGroup().id, 'NetAppRansomwareResilience_alerts_CL', parameters('principalId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb'))]", - "scope": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRansomwareResilience_alerts_CL')]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "principalId": "[parameters('principalId')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceResourceId'), 'NetAppRansomwareResilience_alerts_CL')]" - ] - } - ], - "outputs": { - "dataCollectionEndpointIngestion": { - "type": "string", - "value": "[reference('Microsoft.Insights/dataCollectionEndpoints/ransomware-resilience-alerts-dce', '2021-04-01').logsIngestion.endpoint]" - }, - "dataCollectionRuleImmutableId": { - "type": "string", - "value": "[reference('Microsoft.Insights/dataCollectionRules/ransomware-resilience-alerts-dcr', '2023-03-11').immutableId]" - } - } -} \ No newline at end of file diff --git a/Solutions/NetAppRansomwareResilience/Package/3.0.0.zip b/Solutions/NetAppRansomwareResilience/Package/3.0.0.zip deleted file mode 100644 index b685f4385857bcfab25578234a5b368e3127a368..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15964 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 WDM*8Y{ih4izY_AV9_0Pc*Z%@}D(VUV diff --git a/Solutions/NetAppRansomwareResilience/Package/createUiDefinition.json b/Solutions/NetAppRansomwareResilience/Package/createUiDefinition.json deleted file mode 100644 index 895ed550a21..00000000000 --- a/Solutions/NetAppRansomwareResilience/Package/createUiDefinition.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", - "handler": "Microsoft.Azure.CreateUIDef", - "version": "0.1.2-preview", - "parameters": { - "config": { - "isWizard": false, - "basics": { - "description": "\"NetApp\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/NetAppRansomwareResilience/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nNetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.\n\n**Data Connectors:** 1, **Analytic Rules:** 2, **Playbooks:** 6\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", - "subscription": { - "resourceProviders": [ - "Microsoft.OperationsManagement/solutions", - "Microsoft.OperationalInsights/workspaces/providers/alertRules", - "Microsoft.Insights/workbooks", - "Microsoft.Logic/workflows" - ] - }, - "location": { - "metadata": { - "hidden": "Hiding location, we get it from the log analytics workspace" - }, - "visible": false - }, - "resourceGroup": { - "allowExisting": true - } - } - }, - "basics": [ - { - "name": "getLAWorkspace", - "type": "Microsoft.Solutions.ArmApiControl", - "toolTip": "This filters by workspaces that exist in the Resource Group selected", - "condition": "[greater(length(resourceGroup().name),0)]", - "request": { - "method": "GET", - "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]" - } - }, - { - "name": "workspace", - "type": "Microsoft.Common.DropDown", - "label": "Workspace", - "placeholder": "Select a workspace", - "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected", - "constraints": { - "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", - "required": true - }, - "visible": true - } - ], - "steps": [ - { - "name": "dataconnectors", - "label": "Data Connectors", - "bladeTitle": "Data Connectors", - "elements": [ - { - "name": "dataconnectors1-text", - "type": "Microsoft.Common.TextBlock", - "options": { - "text": "This Solution installs the data connector for NetAppRansomwareResilience. You can get NetAppRansomwareResilience custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." - } - }, - { - "name": "dataconnectors-link1", - "type": "Microsoft.Common.TextBlock", - "options": { - "link": { - "label": "Learn more about connecting data sources", - "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources" - } - } - } - ] - }, - { - "name": "analytics", - "label": "Analytics", - "subLabel": { - "preValidation": "Configure the analytics", - "postValidation": "Done" - }, - "bladeTitle": "Analytics", - "elements": [ - { - "name": "analytics-text", - "type": "Microsoft.Common.TextBlock", - "options": { - "text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view." - } - }, - { - "name": "analytics-link", - "type": "Microsoft.Common.TextBlock", - "options": { - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-detect-threats-custom?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef" - } - } - }, - { - "name": "analytic1", - "type": "Microsoft.Common.Section", - "label": "NetApp Ransomware Resilience High Severity Alert", - "elements": [ - { - "name": "analytic1-text", - "type": "Microsoft.Common.TextBlock", - "options": { - "text": "Detects high severity NetApp Ransomware Resilience alerts that require immediate attention. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with HIGH severity level." - } - } - ] - }, - { - "name": "analytic2", - "type": "Microsoft.Common.Section", - "label": "NetApp Ransomware Resilience Medium Severity Alert", - "elements": [ - { - "name": "analytic2-text", - "type": "Microsoft.Common.TextBlock", - "options": { - "text": "Detects medium severity NetApp Ransomware Resilience alerts that may require investigation. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with MEDIUM severity level." - } - } - ] - } - ] - }, - { - "name": "playbooks", - "label": "Playbooks", - "subLabel": { - "preValidation": "Configure the playbooks", - "postValidation": "Done" - }, - "bladeTitle": "Playbooks", - "elements": [ - { - "name": "playbooks-text", - "type": "Microsoft.Common.TextBlock", - "options": { - "text": "This solution installs the Playbook templates to help implement your Security Orchestration, Automation and Response (SOAR) operations. After installing the solution, these will be deployed under Playbook Templates in the Automation blade in Microsoft Sentinel. They can be configured and managed from the Manage solution view in Content Hub." - } - }, - { - "name": "playbooks-link", - "type": "Microsoft.Common.TextBlock", - "options": { - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-respond-threats-playbook?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef" - } - } - } - ] - } - ], - "outputs": { - "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", - "location": "[location()]", - "workspace": "[basics('workspace')]" - } - } -} diff --git a/Solutions/NetAppRansomwareResilience/Package/mainTemplate.json b/Solutions/NetAppRansomwareResilience/Package/mainTemplate.json deleted file mode 100644 index 2cc3016325c..00000000000 --- a/Solutions/NetAppRansomwareResilience/Package/mainTemplate.json +++ /dev/null @@ -1,3618 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "author": "NetApp - support@netapp.com", - "comments": "Solution template for NetAppRansomwareResilience" - }, - "parameters": { - "location": { - "type": "string", - "minLength": 1, - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" - } - }, - "workspace-location": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" - } - }, - "workspace": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" - } - } - }, - "variables": { - "email": "support@netapp.com", - "_email": "[variables('email')]", - "_solutionName": "NetAppRansomwareResilience", - "_solutionVersion": "3.0.0", - "solutionId": "netapp1234567890.azure-sentinel-solution-netapprrs", - "_solutionId": "[variables('solutionId')]", - "uiConfigId1": "NetAppRansomwareResilienceCustomLogsIngestion", - "_uiConfigId1": "[variables('uiConfigId1')]", - "dataConnectorContentId1": "NetAppRansomwareResilienceCustomLogsIngestion", - "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", - "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", - "_dataConnectorId1": "[variables('dataConnectorId1')]", - "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]", - "dataConnectorVersion1": "1.0.0", - "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]", - "analyticRuleObject1": { - "analyticRuleVersion1": "1.0.0", - "_analyticRulecontentId1": "33b9688b-2afb-442f-a3bb-fe2362717bb7", - "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '33b9688b-2afb-442f-a3bb-fe2362717bb7')]", - "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('33b9688b-2afb-442f-a3bb-fe2362717bb7')))]", - "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','33b9688b-2afb-442f-a3bb-fe2362717bb7','-', '1.0.0')))]" - }, - "analyticRuleObject2": { - "analyticRuleVersion2": "1.0.0", - "_analyticRulecontentId2": "be774c6e-7613-41db-b6e4-25975b680d24", - "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'be774c6e-7613-41db-b6e4-25975b680d24')]", - "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('be774c6e-7613-41db-b6e4-25975b680d24')))]", - "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','be774c6e-7613-41db-b6e4-25975b680d24','-', '1.0.0')))]" - }, - "NetApp-RansomwareResilience-Auth-Playbook": "NetApp-RansomwareResilience-Auth-Playbook", - "_NetApp-RansomwareResilience-Auth-Playbook": "[variables('NetApp-RansomwareResilience-Auth-Playbook')]", - "playbookVersion1": "1.0", - "playbookContentId1": "NetApp-RansomwareResilience-Auth-Playbook", - "_playbookContentId1": "[variables('playbookContentId1')]", - "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]", - "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]", - "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", - "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]", - "blanks": "[replace('b', 'b', '')]", - "NetApp-RansomwareResilience_Volume_Offline_Playbook": "NetApp-RansomwareResilience_Volume_Offline_Playbook", - "_NetApp-RansomwareResilience_Volume_Offline_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Offline_Playbook')]", - "TemplateEmptyObject": "[json('{}')]", - "playbookVersion2": "1.0", - "playbookContentId2": "NetApp-RansomwareResilience_Volume_Offline_Playbook", - "_playbookContentId2": "[variables('playbookContentId2')]", - "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]", - "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]", - "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]", - "NetApp-RansomwareResilience_Async_Poll_Playbook": "NetApp-RansomwareResilience_Async_Poll_Playbook", - "_NetApp-RansomwareResilience_Async_Poll_Playbook": "[variables('NetApp-RansomwareResilience_Async_Poll_Playbook')]", - "playbookVersion3": "1.0", - "playbookContentId3": "NetApp-RansomwareResilience_Async_Poll_Playbook", - "_playbookContentId3": "[variables('playbookContentId3')]", - "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]", - "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]", - "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]", - "NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook", - "_NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Snapshot_Playbook')]", - "playbookVersion4": "1.0", - "playbookContentId4": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook", - "_playbookContentId4": "[variables('playbookContentId4')]", - "playbookId4": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId4'))]", - "playbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId4'))))]", - "_playbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId4'),'-', variables('playbookVersion4'))))]", - "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", - "_NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_StorageVM_Playbook')]", - "playbookVersion5": "1.0", - "playbookContentId5": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", - "_playbookContentId5": "[variables('playbookContentId5')]", - "playbookId5": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId5'))]", - "playbookTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId5'))))]", - "_playbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId5'),'-', variables('playbookVersion5'))))]", - "NetApp-RansomwareResilience_Enrich_IP_Playbook": "NetApp-RansomwareResilience_Enrich_IP_Playbook", - "_NetApp-RansomwareResilience_Enrich_IP_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_IP_Playbook')]", - "playbookVersion6": "1.0", - "playbookContentId6": "NetApp-RansomwareResilience_Enrich_IP_Playbook", - "_playbookContentId6": "[variables('playbookContentId6')]", - "playbookId6": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId6'))]", - "playbookTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId6'))))]", - "_playbookcontentProductId6": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId6'),'-', variables('playbookVersion6'))))]", - "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" - }, - "resources": [ - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('dataConnectorTemplateSpecName1')]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetAppRansomwareResilience data connector with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('dataConnectorVersion1')]", - "parameters": {}, - "variables": {}, - "resources": [ - { - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", - "apiVersion": "2021-03-01-preview", - "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", - "location": "[parameters('workspace-location')]", - "kind": "GenericUI", - "properties": { - "connectorUiConfig": { - "id": "[variables('_uiConfigId1')]", - "title": "NetAppRansomwareResilience Data Connector", - "publisher": "NetAppRansomwareResilience", - "descriptionMarkdown": "Data connector for ingesting NetApp Ransomware Resilience alerts into Microsoft Sentinel. This connector enables seamless integration of Ransomware Resilience alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", - "additionalRequirementBanner": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", - "graphQueries": [ - { - "metricName": "Total data received", - "legend": "NetAppRansomwareResilience_alerts_CL", - "baseQuery": "NetAppRansomwareResilience_alerts_CL" - } - ], - "dataTypes": [ - { - "name": "NetAppRansomwareResilience_alerts_CL", - "lastDataReceivedQuery": "NetAppRansomwareResilience_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - } - ], - "sampleQueries": [ - { - "description": "Default Query", - "query": "NetAppRansomwareResilience_alerts_CL" - } - ], - "connectivityCriterias": [ - { - "type": "IsConnectedQuery", - "value": [ - "NetAppRansomwareResilience_alerts_CL" - ] - } - ], - "availability": { - "status": 1, - "isPreview": false - }, - "permissions": { - "resourceProvider": [ - { - "provider": "Microsoft.OperationalInsights/workspaces", - "permissionsDisplayText": "read and write permissions are required.", - "providerDisplayName": "Workspace", - "scope": "Workspace", - "requiredPermissions": { - "write": true, - "read": true, - "delete": true - } - }, - { - "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", - "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", - "providerDisplayName": "Keys", - "scope": "Workspace", - "requiredPermissions": { - "action": true - } - } - ], - "customs": [ - { - "name": "Azure Subscription", - "description": "Azure Subscription with owner role is required to register an application in azure active directory() and assign role of contributor to app in resource group." - }, - { - "name": "NetApp Console Organization", - "description": "NetApp Console Organization with permissions to create a new Service Account" - } - ] - }, - "instructionSteps": [ - { - "description": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", - "title": "1. Configuration" - }, - { - "description": "Click the button below to deploy the NetApp Ransomware Resilience data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRansomwareResilience%2FData%2520Connectors%2Fazuredeploy_rrs_dataconnector.json)", - "title": "2. Deploy the ARM Template" - } - ] - } - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2023-04-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", - "properties": { - "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", - "contentId": "[variables('_dataConnectorContentId1')]", - "kind": "DataConnector", - "version": "[variables('dataConnectorVersion1')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ] - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_dataConnectorContentId1')]", - "contentKind": "DataConnector", - "displayName": "NetAppRansomwareResilience Data Connector", - "contentProductId": "[variables('_dataConnectorcontentProductId1')]", - "id": "[variables('_dataConnectorcontentProductId1')]", - "version": "[variables('dataConnectorVersion1')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2023-04-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", - "dependsOn": [ - "[variables('_dataConnectorId1')]" - ], - "location": "[parameters('workspace-location')]", - "properties": { - "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", - "contentId": "[variables('_dataConnectorContentId1')]", - "kind": "DataConnector", - "version": "[variables('dataConnectorVersion1')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - }, - { - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", - "apiVersion": "2021-03-01-preview", - "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", - "location": "[parameters('workspace-location')]", - "kind": "GenericUI", - "properties": { - "connectorUiConfig": { - "title": "NetAppRansomwareResilience Data Connector", - "publisher": "NetAppRansomwareResilience", - "descriptionMarkdown": "Data connector for ingesting NetApp Ransomware Resilience alerts into Microsoft Sentinel. This connector enables seamless integration of Ransomware Resilience alerts, facilitating enhanced monitoring and response capabilities for ransomware threats within NetApp storage environments.", - "graphQueries": [ - { - "metricName": "Total data received", - "legend": "NetAppRansomwareResilience_alerts_CL", - "baseQuery": "NetAppRansomwareResilience_alerts_CL" - } - ], - "dataTypes": [ - { - "name": "NetAppRansomwareResilience_alerts_CL", - "lastDataReceivedQuery": "NetAppRansomwareResilience_alerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - } - ], - "connectivityCriterias": [ - { - "type": "IsConnectedQuery", - "value": [ - "NetAppRansomwareResilience_alerts_CL" - ] - } - ], - "sampleQueries": [ - { - "description": "Default Query", - "query": "NetAppRansomwareResilience_alerts_CL" - } - ], - "availability": { - "status": 1, - "isPreview": false - }, - "permissions": { - "resourceProvider": [ - { - "provider": "Microsoft.OperationalInsights/workspaces", - "permissionsDisplayText": "read and write permissions are required.", - "providerDisplayName": "Workspace", - "scope": "Workspace", - "requiredPermissions": { - "write": true, - "read": true, - "delete": true - } - }, - { - "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", - "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", - "providerDisplayName": "Keys", - "scope": "Workspace", - "requiredPermissions": { - "action": true - } - } - ], - "customs": [ - { - "name": "Azure Subscription", - "description": "Azure Subscription with owner role is required to register an application in azure active directory() and assign role of contributor to app in resource group." - }, - { - "name": "NetApp Console Organization", - "description": "NetApp Console Organization with permissions to create a new Service Account" - } - ] - }, - "instructionSteps": [ - { - "description": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data.", - "title": "1. Configuration" - }, - { - "description": "Click the button below to deploy the NetApp Ransomware Resilience data connector using Azure Resource Manager template:\n\n[![Deployment Button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FNetApp%2FAzure-Sentinel%2Frefs%2Fheads%2Fnetapp-rps%2FSolutions%2FNetAppRansomwareResilience%2FData%2520Connectors%2Fazuredeploy_rrs_dataconnector.json)", - "title": "2. Deploy the ARM Template" - } - ], - "id": "[variables('_uiConfigId1')]", - "additionalRequirementBanner": "You need to have an active NetApp Ransomware Resilience subscription and appropriate permissions to access Ransomware Resilience alert data." - } - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetAppRansomwareResilience_HighSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", - "parameters": {}, - "variables": {}, - "resources": [ - { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]", - "apiVersion": "2023-02-01-preview", - "kind": "NRT", - "location": "[parameters('workspace-location')]", - "properties": { - "description": "Detects high severity NetApp Ransomware Resilience alerts that require immediate attention. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with HIGH severity level.", - "displayName": "NetApp Ransomware Resilience High Severity Alert", - "enabled": false, - "query": "NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"HIGH\"\n", - "severity": "High", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "status": "Available", - "requiredDataConnectors": [ - { - "dataTypes": [ - "NetAppRansomwareResilience_alerts_CL" - ], - "connectorId": "NetAppRansomwareResilienceCustomLogsIngestion" - } - ], - "eventGroupingSettings": { - "aggregationKind": "AlertPerResult" - }, - "customDetails": { - "Severity": "severity", - "ContextInfo": "context", - "IncidentDetails": "incident" - }, - "alertDetailsOverride": { - "alertDescriptionFormat": "High severity alert detected from NetApp Ransomware Resilience Service: {{description}}", - "alertDisplayNameFormat": "{{description}}" - }, - "incidentConfiguration": { - "createIncident": true, - "groupingConfiguration": { - "enabled": false, - "matchingMethod": "AllEntities", - "reopenClosedIncident": false, - "lookbackDuration": "PT5H" - } - } - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]", - "properties": { - "description": "NetAppRansomwareResilience Analytics Rule 1", - "parentId": "[variables('analyticRuleObject1').analyticRuleId1]", - "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleObject1').analyticRuleVersion1]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ] - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", - "contentKind": "AnalyticsRule", - "displayName": "NetApp Ransomware Resilience High Severity Alert", - "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", - "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", - "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetAppRansomwareResilience_MediumSeverity_AnalyticalRules Analytics Rule with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", - "parameters": {}, - "variables": {}, - "resources": [ - { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]", - "apiVersion": "2023-02-01-preview", - "kind": "NRT", - "location": "[parameters('workspace-location')]", - "properties": { - "description": "Detects medium severity NetApp Ransomware Resilience alerts that may require investigation. This rule monitors the NetAppRansomwareResilience_alerts_CL table for alerts with MEDIUM severity level.", - "displayName": "NetApp Ransomware Resilience Medium Severity Alert", - "enabled": false, - "query": "NetAppRansomwareResilience_alerts_CL | where TimeGenerated > ago(1d)\n| where severity == \"MEDIUM\"\n", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "status": "Available", - "requiredDataConnectors": [ - { - "dataTypes": [ - "NetAppRansomwareResilience_alerts_CL" - ], - "connectorId": "NetAppRansomwareResilienceCustomLogsIngestion" - } - ], - "eventGroupingSettings": { - "aggregationKind": "AlertPerResult" - }, - "customDetails": { - "Severity": "severity", - "ContextInfo": "context", - "IncidentDetails": "incident" - }, - "alertDetailsOverride": { - "alertDescriptionFormat": "Medium severity alert detected from NetApp Ransomware Resilience Service: {{description}}", - "alertDisplayNameFormat": "{{description}}" - }, - "incidentConfiguration": { - "createIncident": true, - "groupingConfiguration": { - "enabled": false, - "matchingMethod": "AllEntities", - "reopenClosedIncident": false, - "lookbackDuration": "PT5H" - } - } - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]", - "properties": { - "description": "NetAppRansomwareResilience Analytics Rule 2", - "parentId": "[variables('analyticRuleObject2').analyticRuleId2]", - "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleObject2').analyticRuleVersion2]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ] - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", - "contentKind": "AnalyticsRule", - "displayName": "NetApp Ransomware Resilience Medium Severity Alert", - "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", - "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", - "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('playbookTemplateSpecName1')]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetApp-RansomwareResilience-Auth-Playbook Playbook with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('playbookVersion1')]", - "parameters": { - "PlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", - "metadata": { - "description": "Name of the Logic App playbook to be created" - } - }, - "KeyVaultName": { - "type": "String", - "defaultValue": "[concat('RRSkv', uniqueString(resourceGroup().id))]", - "metadata": { - "description": "Name of the shared Key Vault to store NetApp Ransomware Resilience credentials" - } - }, - "location": { - "type": "string", - "defaultValue": "[parameters('location')]", - "metadata": { - "description": "Location for all resources" - } - }, - "ClientId": { - "type": "securestring", - "metadata": { - "description": "Client ID for NetApp Ransomware Resilience API authentication" - } - }, - "ClientSecret": { - "type": "securestring", - "metadata": { - "description": "Client Secret for NetApp Ransomware Resilience API authentication" - } - }, - "AccountId": { - "type": "securestring", - "metadata": { - "description": "Account ID for NetApp Ransomware Resilience API authentication" - } - } - }, - "variables": { - "KeyVaultConnectionName": "[[concat('keyvault-', parameters('PlaybookName'))]", - "connection-5": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]", - "_connection-5": "[[variables('connection-5')]", - "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", - "workspace-name": "[parameters('workspace')]", - "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2019-09-01", - "name": "[[parameters('KeyVaultName')]", - "location": "[[parameters('location')]", - "properties": { - "sku": { - "family": "A", - "name": "standard" - }, - "tenantId": "[[subscription().tenantId]", - "enabledForDeployment": false, - "enabledForDiskEncryption": false, - "enabledForTemplateDeployment": true, - "enableSoftDelete": true, - "softDeleteRetentionInDays": 90, - "enableRbacAuthorization": false - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2019-09-01", - "name": "[[concat(parameters('KeyVaultName'), '/client-id')]", - "dependsOn": [ - "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" - ], - "properties": { - "value": "[[parameters('ClientId')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2019-09-01", - "name": "[[concat(parameters('KeyVaultName'), '/client-secret')]", - "dependsOn": [ - "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" - ], - "properties": { - "value": "[[parameters('ClientSecret')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2019-09-01", - "name": "[[concat(parameters('KeyVaultName'), '/account-id')]", - "dependsOn": [ - "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" - ], - "properties": { - "value": "[[parameters('AccountId')]" - } - }, - { - "type": "Microsoft.Web/connections", - "apiVersion": "2016-06-01", - "name": "[[variables('KeyVaultConnectionName')]", - "location": "[[parameters('location')]", - "kind": "V1", - "dependsOn": [ - "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" - ], - "properties": { - "displayName": "[[variables('KeyVaultConnectionName')]", - "parameterValueSet": { - "name": "oauthMI", - "values": { - "vaultName": { - "value": "[[parameters('KeyVaultName')]" - } - } - }, - "api": { - "id": "[[variables('_connection-5')]" - } - } - }, - { - "type": "Microsoft.Logic/workflows", - "apiVersion": "2019-05-01", - "name": "[[parameters('PlaybookName')]", - "location": "[[parameters('location')]", - "dependsOn": [ - "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", - "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" - ], - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "state": "Enabled", - "definition": { - "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "$connections": { - "type": "Object" - } - }, - "triggers": { - "manual": { - "type": "Request", - "kind": "Http", - "inputs": { - "schema": { - "properties": { - "account_id": { - "type": "string" - }, - "api_hostname": { - "type": "string" - } - }, - "type": "object" - } - } - } - }, - "actions": { - "Get_Client_ID": { - "type": "ApiConnection", - "inputs": { - "host": { - "connection": { - "name": "@parameters('$connections')['keyvault']['connectionId']" - } - }, - "method": "get", - "path": "/secrets/@{encodeURIComponent('client-id')}/value" - } - }, - "Get_Client_Secret": { - "runAfter": { - "Get_Client_ID": [ - "Succeeded" - ] - }, - "type": "ApiConnection", - "inputs": { - "host": { - "connection": { - "name": "@parameters('$connections')['keyvault']['connectionId']" - } - }, - "method": "get", - "path": "/secrets/@{encodeURIComponent('client-secret')}/value" - } - }, - "Get_Account_ID": { - "runAfter": { - "Get_Client_Secret": [ - "Succeeded" - ] - }, - "type": "ApiConnection", - "inputs": { - "host": { - "connection": { - "name": "@parameters('$connections')['keyvault']['connectionId']" - } - }, - "method": "get", - "path": "/secrets/@{encodeURIComponent('account-id')}/value" - } - }, - "HTTP_Token_Request": { - "runAfter": { - "Get_Account_ID": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "https://staging-netapp-cloud-account.auth0.com/oauth/token", - "headers": { - "Content-Type": "application/x-www-form-urlencoded" - }, - "body": "grant_type=client_credentials&client_id=@{body('Get_Client_ID')?['value']}&client_secret=@{body('Get_Client_Secret')?['value']}&audience=https://api.cloud.netapp.com" - } - }, - "Response": { - "runAfter": { - "HTTP_Token_Request": [ - "Succeeded" - ] - }, - "type": "Response", - "kind": "Http", - "inputs": { - "statusCode": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "access_token": "@{body('HTTP_Token_Request')?['access_token']}", - "token_type": "@{body('HTTP_Token_Request')?['token_type']}", - "expires_in": "@{body('HTTP_Token_Request')?['expires_in']}", - "account_id": "@{body('Get_Account_ID')?['value']}" - } - } - } - } - }, - "parameters": { - "$connections": { - "value": { - "keyvault": { - "connectionId": "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", - "connectionName": "[[variables('KeyVaultConnectionName')]", - "connectionProperties": { - "authentication": { - "type": "ManagedServiceIdentity" - } - }, - "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]" - } - } - } - } - }, - "tags": { - "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/accessPolicies", - "apiVersion": "2019-09-01", - "name": "[[concat(parameters('KeyVaultName'), '/add')]", - "dependsOn": [ - "[[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]", - "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" - ], - "properties": { - "accessPolicies": [ - { - "tenantId": "[[subscription().tenantId]", - "objectId": "[[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'Full').identity.principalId]", - "permissions": { - "secrets": [ - "get" - ] - } - } - ] - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId1'),'/'))))]", - "properties": { - "parentId": "[variables('playbookId1')]", - "contentId": "[variables('_playbookContentId1')]", - "kind": "Playbook", - "version": "[variables('playbookVersion1')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ], - "metadata": { - "title": "NetApp Ransomware Resilience Authentication Playbook", - "description": "This playbook creates a shared Key Vault for NetApp Ransomware Resilience credentials and provides authentication services to all NetApp Ransomware Resilience playbooks in the solution.", - "prerequisites": [ - "1. Valid client_id, client_secret, and account_id for NetApp Ransomware Resilience API authentication", - "2. API endpoint that accepts OAuth2 client credentials flow" - ], - "postDeployment": [ - "1. Update the client_id, client_secret, and account_id values in the Key Vault", - "2. Test the Logic App to ensure proper token retrieval", - "3. The Key Vault created by this playbook will be shared across all NetApp Ransomware Resilience playbooks", - "4. Other playbooks will call this Auth playbook to obtain authentication tokens" - ], - "lastUpdateTime": "2025-09-17T00:00:00Z", - "tags": [ - "NetApp", - "RansomwareResilience", - "Playbook", - "Authentication" - ], - "releaseNotes": { - "version": "1.0", - "title": "[variables('blanks')]", - "notes": [ - "Initial version" - ] - } - } - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_playbookContentId1')]", - "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Auth-Playbook", - "contentProductId": "[variables('_playbookcontentProductId1')]", - "id": "[variables('_playbookcontentProductId1')]", - "version": "[variables('playbookVersion1')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('playbookTemplateSpecName2')]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetApp-RansomwareResilience-Volume-Offline-Playbook Playbook with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('playbookVersion2')]", - "parameters": { - "PlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Volume-Offline-Playbook", - "metadata": { - "description": "Name of the Logic App/Playbook" - } - }, - "NetAppRansomwareResilienceAuthPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience authentication playbook" - } - }, - "NetAppRansomwareResilienceAsyncPollPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience async poll playbook" - } - }, - "location": { - "type": "string", - "defaultValue": "[parameters('location')]", - "metadata": { - "description": "Location for all resources" - } - } - }, - "variables": { - "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", - "workspace-name": "[parameters('workspace')]", - "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" - }, - "resources": [ - { - "type": "Microsoft.Logic/workflows", - "apiVersion": "2019-05-01", - "name": "[[parameters('PlaybookName')]", - "location": "[[parameters('location')]", - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "state": "Enabled", - "definition": { - "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", - "type": "String" - }, - "asyncPollPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", - "type": "String" - } - }, - "triggers": { - "manual": { - "type": "Request", - "kind": "Http", - "inputs": { - "schema": { - "type": "object", - "properties": { - "volume_id": { - "type": "string" - }, - "agent_id": { - "type": "string" - }, - "system_id": { - "type": "string" - }, - "callbackData": { - "type": "object" - }, - "poll": { - "type": "boolean" - } - }, - "required": [ - "volume_id", - "agent_id", - "system_id" - ] - } - } - } - }, - "actions": { - "Initialize_Variables": { - "type": "InitializeVariable", - "inputs": { - "variables": [ - { - "name": "VolumeId", - "type": "string", - "value": "@triggerBody()?['volume_id']" - }, - { - "name": "AgentId", - "type": "string", - "value": "@triggerBody()?['agent_id']" - }, - { - "name": "SystemId", - "type": "string", - "value": "@triggerBody()?['system_id']" - }, - { - "name": "CallbackData", - "type": "object", - "value": "@triggerBody()?['callbackData']" - }, - { - "name": "AccountId", - "type": "string" - }, - { - "name": "DoPoll", - "type": "boolean", - "value": "@coalesce(triggerBody()?['poll'], true)" - }, - { - "name": "Token", - "type": "string" - }, - { - "name": "JobId", - "type": "string" - }, - { - "name": "JobAgentId", - "type": "string" - }, - { - "name": "PollResponse", - "type": "object", - "value": "[variables('TemplateEmptyObject')]" - }, - { - "name": "SubmissionStatusCode", - "type": "integer", - "value": 0 - } - ] - } - }, - "Call_Auth_Playbook": { - "runAfter": { - "Initialize_Variables": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "request_id": "@guid()" - } - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - }, - "Parse_Auth_Response": { - "runAfter": { - "Call_Auth_Playbook": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Call_Auth_Playbook')", - "schema": { - "type": "object", - "properties": { - "access_token": { - "type": "string" - }, - "account_id": { - "type": "string" - } - }, - "required": [ - "access_token", - "account_id" - ] - } - } - }, - "Set_Token": { - "runAfter": { - "Parse_Auth_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "Token", - "value": "@body('Parse_Auth_Response')?['access_token']" - } - }, - "Set_Account_ID": { - "runAfter": { - "Set_Token": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "AccountId", - "value": "@body('Parse_Auth_Response')?['account_id']" - } - }, - "Submit_Volume_Offline": { - "runAfter": { - "Set_Account_ID": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-volume-offline", - "headers": { - "Authorization": "Bearer @{variables('Token')}", - "Content-Type": "application/json", - "accept": "application/json" - }, - "body": { - "volume_id": "@variables('VolumeId')", - "agent_id": "@variables('AgentId')", - "system_id": "@variables('SystemId')" - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - }, - "Capture_Submission_Status_Code": { - "runAfter": { - "Submit_Volume_Offline": [ - "Succeeded", - "Failed" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "SubmissionStatusCode", - "value": "@outputs('Submit_Volume_Offline')['statusCode']" - } - }, - "Parse_Submission_Response": { - "runAfter": { - "Capture_Submission_Status_Code": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Submit_Volume_Offline')", - "schema": { - "type": "object", - "properties": { - "job_id": { - "type": "string" - }, - "status": { - "type": "string" - }, - "source": { - "type": "string" - }, - "agent_id": { - "type": "string" - } - } - } - } - }, - "Store_JobId": { - "runAfter": { - "Parse_Submission_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobId", - "value": "@body('Parse_Submission_Response')?['job_id']" - } - }, - "Store_Job_AgentId": { - "runAfter": { - "Store_JobId": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobAgentId", - "value": "@body('Parse_Submission_Response')?['agent_id']" - } - }, - "Check_If_Should_Poll": { - "runAfter": { - "Store_Job_AgentId": [ - "Succeeded" - ] - }, - "type": "If", - "expression": { - "and": [ - { - "equals": [ - "@variables('DoPoll')", - true - ] - }, - { - "or": [ - { - "equals": [ - "@variables('SubmissionStatusCode')", - 200 - ] - }, - { - "equals": [ - "@variables('SubmissionStatusCode')", - 201 - ] - }, - { - "equals": [ - "@variables('SubmissionStatusCode')", - 202 - ] - } - ] - }, - { - "not": { - "equals": [ - "@variables('JobId')", - "" - ] - } - } - ] - }, - "actions": { - "Call_Async_Poll_Playbook": { - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "job_id": "@variables('JobId')", - "agent_id": "@variables('JobAgentId')", - "system_id": "@variables('SystemId')", - "source": "ontap", - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "original_volume_id": "@variables('VolumeId')" - } - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - } - } - }, - "Parse_Poll_Response": { - "runAfter": { - "Check_If_Should_Poll": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Call_Async_Poll_Playbook')", - "schema": { - "type": "object", - "properties": { - "status": { - "type": "string" - }, - "jobId": { - "type": "string" - }, - "success": { - "type": "boolean" - } - } - } - } - }, - "Store_Poll_Response": { - "runAfter": { - "Parse_Poll_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "PollResponse", - "value": "@body('Parse_Poll_Response')" - } - }, - "Return_Response": { - "runAfter": { - "Store_Poll_Response": [ - "Succeeded", - "Skipped" - ], - "Check_If_Should_Poll": [ - "Succeeded" - ], - "Call_Auth_Playbook": [ - "Failed", - "TimedOut" - ], - "Submit_Volume_Offline": [ - "Failed", - "TimedOut" - ] - }, - "type": "Response", - "kind": "Http", - "inputs": { - "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", - "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'Failed submitting volume offline request', null))", - "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'submit', 'success'))", - "submission": { - "statusCode": "@variables('SubmissionStatusCode')", - "jobId": "@variables('JobId')", - "raw": "@body('Submit_Volume_Offline')", - "details": "@if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), body('Submit_Volume_Offline'), null)" - }, - "polling": { - "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", - "playbook": "@parameters('asyncPollPlaybookName')", - "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", - "jobResponse": "@variables('PollResponse')" - }, - "callbackData": "@variables('CallbackData')", - "timestamp": "@utcnow()" - } - } - } - } - } - }, - "tags": { - "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId2'),'/'))))]", - "properties": { - "parentId": "[variables('playbookId2')]", - "contentId": "[variables('_playbookContentId2')]", - "kind": "Playbook", - "version": "[variables('playbookVersion2')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ], - "metadata": { - "title": "NetApp Ransomware Resilience Volume Offline Playbook", - "description": "This playbook takes a NetApp volume offline using the updated NetApp Ransomware Resilience take-volume-offline API endpoint and optionally polls for completion.", - "prerequisites": [ - "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", - "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", - "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", - "4. Caller must provide volume_id, agent_id, and system_id parameters" - ], - "postDeployment": [ - "1. Test the volume offline functionality with valid volume_id, agent_id, and system_id" - ], - "lastUpdateTime": "2025-09-17T00:00:00Z", - "tags": [ - "NetApp", - "RansomwareResilience", - "Playbook", - "Volume", - "Offline" - ], - "releaseNotes": { - "version": "1.0", - "title": "[variables('blanks')]", - "notes": [ - "Initial version" - ] - } - } - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_playbookContentId2')]", - "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Volume-Offline-Playbook", - "contentProductId": "[variables('_playbookcontentProductId2')]", - "id": "[variables('_playbookcontentProductId2')]", - "version": "[variables('playbookVersion2')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('playbookTemplateSpecName3')]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetApp-RansomwareResilience-Async-Poll-Playbook Playbook with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('playbookVersion3')]", - "parameters": { - "PlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", - "metadata": { - "description": "Name of the Logic App/Playbook" - } - }, - "NetAppRansomwareResilienceAuthPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience authentication playbook" - } - }, - "location": { - "type": "string", - "defaultValue": "[parameters('location')]", - "metadata": { - "description": "Location for all resources" - } - } - }, - "variables": { - "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", - "workspace-name": "[parameters('workspace')]", - "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" - }, - "resources": [ - { - "type": "Microsoft.Logic/workflows", - "apiVersion": "2019-05-01", - "name": "[[parameters('PlaybookName')]", - "location": "[[parameters('location')]", - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "state": "Enabled", - "definition": { - "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", - "type": "String" - } - }, - "triggers": { - "manual": { - "type": "Request", - "kind": "Http", - "inputs": { - "schema": { - "type": "object", - "properties": { - "job_id": { - "type": "string", - "description": "The NetApp Ransomware Resilience job ID to poll" - }, - "agent_id": { - "type": "string", - "description": "NetApp Ransomware Resilience agent ID" - }, - "system_id": { - "type": "string", - "description": "System ID for the working environment" - }, - "source": { - "type": "string", - "description": "Job source type" - }, - "caller_info": { - "type": "object", - "description": "Optional caller information for tracking" - } - }, - "required": [ - "job_id", - "agent_id", - "system_id", - "source" - ] - } - } - } - }, - "actions": { - "Initialize_variables": { - "type": "InitializeVariable", - "inputs": { - "variables": [ - { - "name": "JobId", - "type": "string", - "value": "@triggerBody()?['job_id']" - }, - { - "name": "AgentId", - "type": "string", - "value": "@triggerBody()?['agent_id']" - }, - { - "name": "SystemId", - "type": "string", - "value": "@triggerBody()?['system_id']" - }, - { - "name": "Source", - "type": "string", - "value": "@triggerBody()?['source']" - }, - { - "name": "AccountId", - "type": "string" - }, - { - "name": "PollCount", - "type": "integer", - "value": 0 - }, - { - "name": "MaxPollAttempts", - "type": "integer", - "value": 10 - }, - { - "name": "PollIntervalSeconds", - "type": "integer", - "value": 30 - }, - { - "name": "JobStatus", - "type": "string", - "value": "pending" - }, - { - "name": "JobResponse", - "type": "object", - "value": "[variables('TemplateEmptyObject')]" - } - ] - } - }, - "Call_Auth_Playbook": { - "runAfter": { - "Initialize_variables": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "request_id": "@guid()" - } - } - } - }, - "Set_Account_ID": { - "runAfter": { - "Call_Auth_Playbook": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "AccountId", - "value": "@body('Call_Auth_Playbook')?['account_id']" - } - }, - "Initial_Status_Check": { - "runAfter": { - "Set_Account_ID": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "GET", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", - "headers": { - "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", - "accept": "application/json" - }, - "retryPolicy": { - "type": "exponential", - "count": 2, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT10S" - }, - "timeout": "PT30S" - } - }, - "Update_Initial_Status": { - "runAfter": { - "Initial_Status_Check": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobStatus", - "value": "@body('Initial_Status_Check')?['status']" - } - }, - "Update_Initial_Response": { - "runAfter": { - "Update_Initial_Status": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobResponse", - "value": "@body('Initial_Status_Check')" - } - }, - "Polling_Loop": { - "runAfter": { - "Update_Initial_Response": [ - "Succeeded" - ] - }, - "type": "Until", - "expression": "@or(or(equals(variables('JobStatus'), 'SUCCESS'), equals(variables('JobStatus'), 'success')), or(equals(variables('JobStatus'), 'FAILED'), equals(variables('JobStatus'), 'failed')), greater(variables('PollCount'), variables('MaxPollAttempts')))", - "limit": { - "count": 10, - "timeout": "PT6M" - }, - "actions": { - "Increment_Poll_Count": { - "type": "IncrementVariable", - "inputs": { - "name": "PollCount", - "value": 1 - } - }, - "Check_Job_Status": { - "runAfter": { - "Increment_Poll_Count": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "GET", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", - "headers": { - "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", - "accept": "application/json" - }, - "retryPolicy": { - "type": "exponential", - "count": 2, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT10S" - }, - "timeout": "PT30S" - } - }, - "Update_Job_Status": { - "runAfter": { - "Check_Job_Status": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobStatus", - "value": "@body('Check_Job_Status')?['status']" - } - }, - "Handle_Status_Check_Failure": { - "runAfter": { - "Check_Job_Status": [ - "Failed", - "TimedOut" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobStatus", - "value": "failed" - } - }, - "Update_Job_Response": { - "runAfter": { - "Update_Job_Status": [ - "Succeeded" - ], - "Handle_Status_Check_Failure": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobResponse", - "value": "@body('Check_Job_Status')" - } - }, - "Wait_If_Needed": { - "runAfter": { - "Update_Job_Response": [ - "Succeeded" - ] - }, - "type": "If", - "expression": { - "not": { - "or": [ - { - "equals": [ - "@variables('JobStatus')", - "SUCCESS" - ] - }, - { - "equals": [ - "@variables('JobStatus')", - "success" - ] - } - ] - } - }, - "actions": { - "Wait_Before_Retry": { - "type": "Wait", - "inputs": { - "interval": { - "count": "@variables('PollIntervalSeconds')", - "unit": "Second" - } - } - } - } - } - } - }, - "Check_Final_Status": { - "runAfter": { - "Polling_Loop": [ - "Succeeded" - ] - }, - "type": "If", - "expression": { - "and": [ - { - "or": [ - { - "equals": [ - "@variables('JobStatus')", - "SUCCESS" - ] - }, - { - "equals": [ - "@variables('JobStatus')", - "success" - ] - } - ] - } - ] - }, - "actions": { - "Success_Response": { - "type": "Response", - "kind": "Http", - "inputs": { - "statusCode": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "success": true, - "job_id": "@variables('JobId')", - "status": "@variables('JobStatus')", - "poll_count": "@variables('PollCount')", - "data": "@variables('JobResponse')", - "caller_info": "@triggerBody()?['caller_info']" - } - } - } - }, - "else": { - "actions": { - "Error_Response": { - "type": "Response", - "kind": "Http", - "inputs": { - "statusCode": 408, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "success": false, - "error": "Job polling timeout or failed", - "job_id": "@variables('JobId')", - "status": "@variables('JobStatus')", - "poll_count": "@variables('PollCount')", - "max_attempts": "@variables('MaxPollAttempts')", - "data": "@variables('JobResponse')", - "caller_info": "@triggerBody()?['caller_info']" - } - } - } - } - } - } - } - } - }, - "tags": { - "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId3'),'/'))))]", - "properties": { - "parentId": "[variables('playbookId3')]", - "contentId": "[variables('_playbookContentId3')]", - "kind": "Playbook", - "version": "[variables('playbookVersion3')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ], - "metadata": { - "title": "NetApp Ransomware Resilience Async Poll Playbook", - "description": "This playbook polls NetApp Ransomware Resilience job status asynchronously until completion or timeout using the updated job status API endpoint.", - "prerequisites": [ - "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", - "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", - "3. Caller must provide job_id, agent_id, system_id, and source parameters" - ], - "postDeployment": [ - "1. Test the playbook by triggering it with a valid job_id, agent_id, system_id, and source", - "2. Monitor the playbook run history to verify successful polling and completion" - ], - "lastUpdateTime": "2025-09-17T00:00:00Z", - "tags": [ - "NetApp", - "RansomwareResilience", - "Playbook", - "Async", - "Polling" - ], - "releaseNotes": { - "version": "1.0", - "title": "[variables('blanks')]", - "notes": [ - "Initial version" - ] - } - } - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_playbookContentId3')]", - "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Async-Poll-Playbook", - "contentProductId": "[variables('_playbookcontentProductId3')]", - "id": "[variables('_playbookcontentProductId3')]", - "version": "[variables('playbookVersion3')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('playbookTemplateSpecName4')]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook Playbook with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('playbookVersion4')]", - "parameters": { - "PlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", - "metadata": { - "description": "Name of the Logic App/Playbook" - } - }, - "NetAppRansomwareResilienceAuthPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience authentication playbook" - } - }, - "NetAppRansomwareResilienceAsyncPollPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience async poll playbook" - } - }, - "location": { - "type": "string", - "defaultValue": "[parameters('location')]", - "metadata": { - "description": "Location for all resources" - } - } - }, - "variables": { - "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", - "workspace-name": "[parameters('workspace')]", - "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" - }, - "resources": [ - { - "type": "Microsoft.Logic/workflows", - "apiVersion": "2019-05-01", - "name": "[[parameters('PlaybookName')]", - "location": "[[parameters('location')]", - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "state": "Enabled", - "definition": { - "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", - "type": "String" - }, - "asyncPollPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", - "type": "String" - } - }, - "triggers": { - "manual": { - "type": "Request", - "kind": "Http", - "inputs": { - "schema": { - "type": "object", - "properties": { - "volume_id": { - "type": "string" - }, - "agent_id": { - "type": "string" - }, - "system_id": { - "type": "string" - }, - "callbackData": { - "type": "object" - }, - "poll": { - "type": "boolean" - } - }, - "required": [ - "volume_id", - "agent_id", - "system_id" - ] - } - } - } - }, - "actions": { - "Initialize_Variables": { - "type": "InitializeVariable", - "inputs": { - "variables": [ - { - "name": "VolumeId", - "type": "string", - "value": "@triggerBody()?['volume_id']" - }, - { - "name": "AgentId", - "type": "string", - "value": "@triggerBody()?['agent_id']" - }, - { - "name": "SystemId", - "type": "string", - "value": "@triggerBody()?['system_id']" - }, - { - "name": "CallbackData", - "type": "object", - "value": "@triggerBody()?['callbackData']" - }, - { - "name": "AccountId", - "type": "string" - }, - { - "name": "DoPoll", - "type": "boolean", - "value": "@coalesce(triggerBody()?['poll'], true)" - }, - { - "name": "Token", - "type": "string" - }, - { - "name": "JobId", - "type": "string" - }, - { - "name": "JobAgentId", - "type": "string" - }, - { - "name": "PollResponse", - "type": "object", - "value": "[variables('TemplateEmptyObject')]" - }, - { - "name": "SubmissionStatusCode", - "type": "integer", - "value": 0 - } - ] - } - }, - "Call_Auth_Playbook": { - "runAfter": { - "Initialize_Variables": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "request_id": "@guid()" - } - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - }, - "Parse_Auth_Response": { - "runAfter": { - "Call_Auth_Playbook": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Call_Auth_Playbook')", - "schema": { - "type": "object", - "properties": { - "access_token": { - "type": "string" - }, - "account_id": { - "type": "string" - } - }, - "required": [ - "access_token", - "account_id" - ] - } - } - }, - "Set_Token": { - "runAfter": { - "Parse_Auth_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "Token", - "value": "@body('Parse_Auth_Response')?['access_token']" - } - }, - "Set_Account_ID": { - "runAfter": { - "Set_Token": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "AccountId", - "value": "@body('Parse_Auth_Response')?['account_id']" - } - }, - "Submit_Volume_Snapshot": { - "runAfter": { - "Set_Account_ID": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/storage/take-snapshot", - "headers": { - "Authorization": "Bearer @{variables('Token')}", - "Content-Type": "application/json", - "accept": "application/json" - }, - "body": { - "volume_id": "@variables('VolumeId')", - "agent_id": "@variables('AgentId')", - "system_id": "@variables('SystemId')" - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - }, - "Capture_Submission_Status_Code": { - "runAfter": { - "Submit_Volume_Snapshot": [ - "Succeeded", - "Failed" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "SubmissionStatusCode", - "value": "@outputs('Submit_Volume_Snapshot')['statusCode']" - } - }, - "Parse_Submission_Response": { - "runAfter": { - "Capture_Submission_Status_Code": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Submit_Volume_Snapshot')", - "schema": { - "type": "object", - "properties": { - "job_id": { - "type": "string" - }, - "status": { - "type": "string" - }, - "source": { - "type": "string" - }, - "agent_id": { - "type": "string" - } - } - } - } - }, - "Store_JobId": { - "runAfter": { - "Parse_Submission_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobId", - "value": "@body('Parse_Submission_Response')?['job_id']" - } - }, - "Store_Job_AgentId": { - "runAfter": { - "Store_JobId": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobAgentId", - "value": "@body('Parse_Submission_Response')?['agent_id']" - } - }, - "Check_If_Should_Poll": { - "runAfter": { - "Store_Job_AgentId": [ - "Succeeded" - ] - }, - "type": "If", - "expression": { - "and": [ - { - "equals": [ - "@variables('DoPoll')", - true - ] - }, - { - "or": [ - { - "equals": [ - "@variables('SubmissionStatusCode')", - 200 - ] - }, - { - "equals": [ - "@variables('SubmissionStatusCode')", - 201 - ] - }, - { - "equals": [ - "@variables('SubmissionStatusCode')", - 202 - ] - } - ] - }, - { - "not": { - "equals": [ - "@variables('JobId')", - "" - ] - } - } - ] - }, - "actions": { - "Call_Async_Poll_Playbook": { - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "job_id": "@variables('JobId')", - "agent_id": "@variables('JobAgentId')", - "system_id": "@variables('SystemId')", - "source": "ontap", - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "original_volume_id": "@variables('VolumeId')" - } - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - } - } - }, - "Parse_Poll_Response": { - "runAfter": { - "Check_If_Should_Poll": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Call_Async_Poll_Playbook')", - "schema": { - "type": "object", - "properties": { - "status": { - "type": "string" - }, - "jobId": { - "type": "string" - }, - "success": { - "type": "boolean" - } - } - } - } - }, - "Store_Poll_Response": { - "runAfter": { - "Parse_Poll_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "PollResponse", - "value": "@body('Parse_Poll_Response')" - } - }, - "Return_Response": { - "runAfter": { - "Store_Poll_Response": [ - "Succeeded", - "Skipped" - ], - "Check_If_Should_Poll": [ - "Succeeded" - ], - "Call_Auth_Playbook": [ - "Failed", - "TimedOut" - ], - "Submit_Volume_Snapshot": [ - "Failed", - "TimedOut" - ] - }, - "type": "Response", - "kind": "Http", - "inputs": { - "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", - "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'Failed submitting volume snapshot request', null))", - "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'submit', 'success'))", - "submission": { - "statusCode": "@variables('SubmissionStatusCode')", - "jobId": "@variables('JobId')", - "raw": "@body('Submit_Volume_Snapshot')", - "details": "@if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), body('Submit_Volume_Snapshot'), null)" - }, - "polling": { - "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", - "playbook": "@parameters('asyncPollPlaybookName')", - "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", - "jobResponse": "@variables('PollResponse')" - }, - "callbackData": "@variables('CallbackData')", - "timestamp": "@utcnow()" - } - } - } - } - } - }, - "tags": { - "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId4'),'/'))))]", - "properties": { - "parentId": "[variables('playbookId4')]", - "contentId": "[variables('_playbookContentId4')]", - "kind": "Playbook", - "version": "[variables('playbookVersion4')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ], - "metadata": { - "title": "NetApp Ransomware Resilience Volume Snapshot Playbook", - "description": "This playbook creates a NetApp volume snapshot using the updated NetApp Ransomware Resilience take-snapshot API endpoint and optionally polls for completion.", - "prerequisites": [ - "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", - "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", - "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", - "4. Caller must provide volume_id, agent_id, and system_id parameters" - ], - "postDeployment": [ - "1. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id" - ], - "lastUpdateTime": "2025-09-22T00:00:00Z", - "tags": [ - "NetApp", - "RansomwareResilience", - "Playbook", - "Volume", - "Snapshot" - ], - "releaseNotes": { - "version": "1.0", - "title": "[variables('blanks')]", - "notes": [ - "Initial version" - ] - } - } - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_playbookContentId4')]", - "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", - "contentProductId": "[variables('_playbookcontentProductId4')]", - "id": "[variables('_playbookcontentProductId4')]", - "version": "[variables('playbookVersion4')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('playbookTemplateSpecName5')]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook Playbook with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('playbookVersion5')]", - "parameters": { - "PlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", - "metadata": { - "description": "Name of the Logic App/Playbook" - } - }, - "NetAppRansomwareResilienceAuthPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience authentication playbook" - } - }, - "location": { - "type": "string", - "defaultValue": "[parameters('location')]", - "metadata": { - "description": "Location for all resources" - } - } - }, - "variables": { - "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", - "workspace-name": "[parameters('workspace')]", - "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" - }, - "resources": [ - { - "type": "Microsoft.Logic/workflows", - "apiVersion": "2019-05-01", - "name": "[[parameters('PlaybookName')]", - "location": "[[parameters('location')]", - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "state": "Enabled", - "definition": { - "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", - "type": "String" - } - }, - "triggers": { - "manual": { - "type": "Request", - "kind": "Http", - "inputs": { - "schema": { - "type": "object", - "properties": { - "agent_id": { - "type": "string" - }, - "system_id": { - "type": "string" - }, - "callbackData": { - "type": "object" - } - }, - "required": [ - "agent_id", - "system_id" - ] - } - } - } - }, - "actions": { - "Initialize_Variables": { - "type": "InitializeVariable", - "inputs": { - "variables": [ - { - "name": "AgentId", - "type": "string", - "value": "@triggerBody()?['agent_id']" - }, - { - "name": "SystemId", - "type": "string", - "value": "@triggerBody()?['system_id']" - }, - { - "name": "CallbackData", - "type": "object", - "value": "@triggerBody()?['callbackData']" - }, - { - "name": "AccountId", - "type": "string" - }, - { - "name": "Token", - "type": "string" - }, - { - "name": "StorageVMData", - "type": "array" - }, - { - "name": "EnrichmentStatusCode", - "type": "integer", - "value": 0 - } - ] - } - }, - "Call_Auth_Playbook": { - "runAfter": { - "Initialize_Variables": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "request_id": "@guid()" - } - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - }, - "Parse_Auth_Response": { - "runAfter": { - "Call_Auth_Playbook": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Call_Auth_Playbook')", - "schema": { - "type": "object", - "properties": { - "access_token": { - "type": "string" - }, - "account_id": { - "type": "string" - } - }, - "required": [ - "access_token", - "account_id" - ] - } - } - }, - "Set_Token": { - "runAfter": { - "Parse_Auth_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "Token", - "value": "@body('Parse_Auth_Response')?['access_token']" - } - }, - "Set_Account_ID": { - "runAfter": { - "Set_Token": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "AccountId", - "value": "@body('Parse_Auth_Response')?['account_id']" - } - }, - "Get_StorageVM_Data": { - "runAfter": { - "Set_Account_ID": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "GET", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", - "headers": { - "Authorization": "Bearer @{variables('Token')}", - "accept": "application/json" - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - } - } - }, - "Capture_Enrichment_Status_Code": { - "runAfter": { - "Get_StorageVM_Data": [ - "Succeeded", - "Failed" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "EnrichmentStatusCode", - "value": "@outputs('Get_StorageVM_Data')['statusCode']" - } - }, - "Parse_StorageVM_Response": { - "runAfter": { - "Capture_Enrichment_Status_Code": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Get_StorageVM_Data')", - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "volume_uuid": { - "type": "string" - }, - "volume_name": { - "type": "string" - }, - "svm_name": { - "type": "string" - } - } - } - } - } - }, - "Store_StorageVM_Data": { - "runAfter": { - "Parse_StorageVM_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "StorageVMData", - "value": "@body('Parse_StorageVM_Response')" - } - }, - "Return_Response": { - "runAfter": { - "Store_StorageVM_Data": [ - "Succeeded", - "Skipped" - ], - "Call_Auth_Playbook": [ - "Failed", - "TimedOut" - ], - "Get_StorageVM_Data": [ - "Failed", - "TimedOut" - ] - }, - "type": "Response", - "kind": "Http", - "inputs": { - "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", - "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'Failed retrieving storage VM data', null))", - "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'enrichment', 'success'))", - "account_id": "@variables('AccountId')", - "enrichment": { - "statusCode": "@variables('EnrichmentStatusCode')", - "storage_vms": "@variables('StorageVMData')", - "count": "@length(variables('StorageVMData'))", - "raw": "@body('Get_StorageVM_Data')" - }, - "callbackData": "@variables('CallbackData')", - "timestamp": "@utcnow()" - } - } - } - } - } - }, - "tags": { - "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId5'),'/'))))]", - "properties": { - "parentId": "[variables('playbookId5')]", - "contentId": "[variables('_playbookContentId5')]", - "kind": "Playbook", - "version": "[variables('playbookVersion5')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ], - "metadata": { - "title": "NetApp Ransomware Resilience Enrich StorageVM Playbook", - "description": "This playbook enriches storage data by calling the updated NetApp Ransomware Resilience enrich storage API endpoint.", - "prerequisites": [ - "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", - "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", - "3. Caller must provide agent_id and system_id parameters" - ], - "postDeployment": [ - "1. Test the storage enrichment functionality with valid agent_id and system_id" - ], - "lastUpdateTime": "2025-09-23T00:00:00Z", - "tags": [ - "NetApp", - "RansomwareResilience", - "Playbook", - "StorageVM", - "Enrich" - ], - "releaseNotes": { - "version": "1.0", - "title": "[variables('blanks')]", - "notes": [ - "Initial version" - ] - } - } - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_playbookContentId5')]", - "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", - "contentProductId": "[variables('_playbookcontentProductId5')]", - "id": "[variables('_playbookcontentProductId5')]", - "version": "[variables('playbookVersion5')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", - "apiVersion": "2023-04-01-preview", - "name": "[variables('playbookTemplateSpecName6')]", - "location": "[parameters('workspace-location')]", - "dependsOn": [ - "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" - ], - "properties": { - "description": "NetApp-RansomwareResilience-Enrich-IP-Playbook Playbook with template version 3.0.0", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('playbookVersion6')]", - "parameters": { - "PlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Enrich-IP-Playbook", - "metadata": { - "description": "Name of the Logic App/Playbook" - } - }, - "NetAppRansomwareResilienceAuthPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience authentication playbook" - } - }, - "NetAppRansomwareResilienceAsyncPollPlaybookName": { - "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", - "metadata": { - "description": "Name of the NetApp Ransomware Resilience async poll playbook" - } - }, - "location": { - "type": "string", - "defaultValue": "[parameters('location')]", - "metadata": { - "description": "Location for all resources" - } - } - }, - "variables": { - "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", - "workspace-name": "[parameters('workspace')]", - "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" - }, - "resources": [ - { - "type": "Microsoft.Logic/workflows", - "apiVersion": "2019-05-01", - "name": "[[parameters('PlaybookName')]", - "location": "[[parameters('location')]", - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "state": "Enabled", - "definition": { - "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "authPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", - "type": "String" - }, - "asyncPollPlaybookName": { - "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", - "type": "String" - } - }, - "triggers": { - "manual": { - "type": "Request", - "kind": "Http", - "inputs": { - "schema": { - "type": "object", - "properties": { - "ip_address": { - "type": "string" - }, - "callbackData": { - "type": "object" - } - }, - "required": [ - "ip_address" - ] - } - } - } - }, - "actions": { - "Initialize_Variables": { - "type": "InitializeVariable", - "inputs": { - "variables": [ - { - "name": "IpAddress", - "type": "string", - "value": "@triggerBody()?['ip_address']" - }, - { - "name": "CallbackData", - "type": "object", - "value": "@triggerBody()?['callbackData']" - }, - { - "name": "AccountId", - "type": "string" - }, - { - "name": "Token", - "type": "string" - }, - { - "name": "JobIds", - "type": "array" - }, - { - "name": "PollingResults", - "type": "array" - }, - { - "name": "EnrichmentStatusCode", - "type": "integer", - "value": 0 - } - ] - } - }, - "Call_Auth_Playbook": { - "runAfter": { - "Initialize_Variables": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "request_id": "@guid()" - } - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - }, - "timeout": "PT30S" - } - }, - "Parse_Auth_Response": { - "runAfter": { - "Call_Auth_Playbook": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Call_Auth_Playbook')", - "schema": { - "type": "object", - "properties": { - "access_token": { - "type": "string" - }, - "account_id": { - "type": "string" - } - }, - "required": [ - "access_token", - "account_id" - ] - } - } - }, - "Set_Token": { - "runAfter": { - "Parse_Auth_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "Token", - "value": "@body('Parse_Auth_Response')?['access_token']" - } - }, - "Set_Account_ID": { - "runAfter": { - "Set_Token": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "AccountId", - "value": "@body('Parse_Auth_Response')?['account_id']" - } - }, - "Get_IP_NetworkInterfaces": { - "runAfter": { - "Set_Account_ID": [ - "Succeeded" - ] - }, - "type": "Http", - "inputs": { - "method": "POST", - "uri": "http://k8s-istioing-istioing-4ff0b93b67-74a65bde8c3bb0e5.elb.us-east-1.amazonaws.com/bavinash/v1/account/@{variables('AccountId')}/enrich/ip-address", - "headers": { - "Authorization": "Bearer @{variables('Token')}", - "accept": "application/json", - "Content-Type": "application/json" - }, - "body": { - "ip_address": "@{variables('IpAddress')}" - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - }, - "timeout": "PT45S" - } - }, - "Capture_Enrichment_Status_Code": { - "runAfter": { - "Get_IP_NetworkInterfaces": [ - "Succeeded", - "Failed" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "EnrichmentStatusCode", - "value": "@outputs('Get_IP_NetworkInterfaces')['statusCode']" - } - }, - "Parse_JobIds_Response": { - "runAfter": { - "Capture_Enrichment_Status_Code": [ - "Succeeded" - ] - }, - "type": "ParseJson", - "inputs": { - "content": "@body('Get_IP_NetworkInterfaces')", - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "job_id": { - "type": "string" - }, - "status": { - "type": "string" - }, - "source": { - "type": "string" - }, - "agent_id": { - "type": "string" - } - } - } - } - } - }, - "Extract_Job_IDs": { - "runAfter": { - "Parse_JobIds_Response": [ - "Succeeded" - ] - }, - "type": "SetVariable", - "inputs": { - "name": "JobIds", - "value": "@body('Parse_JobIds_Response')" - } - }, - "Poll_All_Jobs": { - "runAfter": { - "Extract_Job_IDs": [ - "Succeeded" - ] - }, - "type": "Foreach", - "foreach": "@variables('JobIds')", - "actions": { - "Call_Async_Poll_Playbook": { - "type": "Http", - "inputs": { - "method": "POST", - "uri": "[[listCallbackURL(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), '/triggers/manual'), '2019-05-01').value]", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "job_id": "@item()?['job_id']", - "agent_id": "@item()?['agent_id']", - "system_id": "default", - "source": "@item()?['source']", - "caller_info": { - "playbook_name": "@workflow().name", - "correlation_id": "@workflow().run.name", - "original_ip": "@variables('IpAddress')" - } - }, - "retryPolicy": { - "type": "exponential", - "count": 3, - "interval": "PT5S", - "minimumInterval": "PT5S", - "maximumInterval": "PT30S" - }, - "timeout": "PT90S" - } - }, - "Add_Poll_Result": { - "runAfter": { - "Call_Async_Poll_Playbook": [ - "Succeeded" - ] - }, - "type": "AppendToArrayVariable", - "inputs": { - "name": "PollingResults", - "value": { - "job_id": "@item()?['job_id']", - "poll_response": "@body('Call_Async_Poll_Playbook')", - "original_job_info": "@item()" - } - } - }, - "Add_Failed_Poll_Result": { - "runAfter": { - "Call_Async_Poll_Playbook": [ - "Failed", - "TimedOut" - ] - }, - "type": "AppendToArrayVariable", - "inputs": { - "name": "PollingResults", - "value": { - "job_id": "@item()?['job_id']", - "poll_response": { - "success": false, - "error": "Failed to poll job or timeout occurred" - }, - "original_job_info": "@item()" - } - } - } - }, - "runtimeConfiguration": { - "concurrency": { - "repetitions": 1 - } - } - }, - "Return_Response": { - "runAfter": { - "Poll_All_Jobs": [ - "Succeeded", - "Skipped" - ], - "Call_Auth_Playbook": [ - "Failed", - "TimedOut" - ], - "Get_IP_NetworkInterfaces": [ - "Failed", - "TimedOut" - ] - }, - "type": "Response", - "kind": "Http", - "inputs": { - "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", - "headers": { - "Content-Type": "application/json" - }, - "body": { - "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", - "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'Failed retrieving IP network interfaces data', null))", - "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'enrichment', 'success'))", - "account_id": "@variables('AccountId')", - "ip_address": "@variables('IpAddress')", - "enrichment": { - "statusCode": "@variables('EnrichmentStatusCode')", - "job_ids_count": "@length(variables('JobIds'))", - "polling_results_count": "@length(variables('PollingResults'))", - "original_jobs": "@variables('JobIds')", - "polling_results": "@variables('PollingResults')", - "raw_initial_response": "@body('Get_IP_NetworkInterfaces')" - }, - "callbackData": "@variables('CallbackData')", - "timestamp": "@utcnow()" - } - } - } - } - } - }, - "tags": { - "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId6'),'/'))))]", - "properties": { - "parentId": "[variables('playbookId6')]", - "contentId": "[variables('_playbookContentId6')]", - "kind": "Playbook", - "version": "[variables('playbookVersion6')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - } - } - } - ], - "metadata": { - "title": "NetApp Ransomware Resilience Enrich IP Playbook", - "description": "This playbook enriches IP data by calling the updated NetApp Ransomware Resilience enrich IP address API endpoint and asynchronously polls multiple job results.", - "prerequisites": [ - "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", - "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed and ensure that it is functioning correctly", - "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", - "4. Caller must provide ip_address parameter" - ], - "postDeployment": [ - "1. Test the IP enrichment functionality with valid IP address" - ], - "lastUpdateTime": "2025-09-26T00:00:00Z", - "tags": [ - "NetApp", - "RansomwareResilience", - "Playbook", - "IP", - "Enrich", - "NetworkInterface" - ], - "releaseNotes": { - "version": "1.0", - "title": "[variables('blanks')]", - "notes": [ - "Initial version" - ] - } - } - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_playbookContentId6')]", - "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Enrich-IP-Playbook", - "contentProductId": "[variables('_playbookcontentProductId6')]", - "id": "[variables('_playbookcontentProductId6')]", - "version": "[variables('playbookVersion6')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", - "apiVersion": "2023-04-01-preview", - "location": "[parameters('workspace-location')]", - "properties": { - "version": "3.0.0", - "kind": "Solution", - "contentSchemaVersion": "3.0.0", - "displayName": "NetAppRansomwareResilience", - "publisherDisplayName": "NetApp", - "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.

\n

Data Connectors: 1, Analytic Rules: 2, Playbooks: 6

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", - "contentKind": "Solution", - "contentProductId": "[variables('_solutioncontentProductId')]", - "id": "[variables('_solutioncontentProductId')]", - "icon": "\"NetApp", - "contentId": "[variables('_solutionId')]", - "parentId": "[variables('_solutionId')]", - "source": { - "kind": "Solution", - "name": "NetAppRansomwareResilience", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "NetApp", - "email": "[variables('_email')]" - }, - "support": { - "name": "NetApp", - "email": "support@netapp.com", - "tier": "Partner", - "link": "https://support.netapp.com" - }, - "dependencies": { - "operator": "AND", - "criteria": [ - { - "kind": "DataConnector", - "contentId": "[variables('_dataConnectorContentId1')]", - "version": "[variables('dataConnectorVersion1')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", - "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", - "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" - }, - { - "kind": "Playbook", - "contentId": "[variables('_NetApp-RansomwareResilience-Auth-Playbook')]", - "version": "[variables('playbookVersion1')]" - }, - { - "kind": "Playbook", - "contentId": "[variables('_NetApp-RansomwareResilience_Volume_Offline_Playbook')]", - "version": "[variables('playbookVersion2')]" - }, - { - "kind": "Playbook", - "contentId": "[variables('_NetApp-RansomwareResilience_Async_Poll_Playbook')]", - "version": "[variables('playbookVersion3')]" - }, - { - "kind": "Playbook", - "contentId": "[variables('_NetApp-RansomwareResilience_Volume_Snapshot_Playbook')]", - "version": "[variables('playbookVersion4')]" - }, - { - "kind": "Playbook", - "contentId": "[variables('_NetApp-RansomwareResilience_Enrich_StorageVM_Playbook')]", - "version": "[variables('playbookVersion5')]" - }, - { - "kind": "Playbook", - "contentId": "[variables('_NetApp-RansomwareResilience_Enrich_IP_Playbook')]", - "version": "[variables('playbookVersion6')]" - } - ] - }, - "firstPublishDate": "2025-10-31", - "lastPublishDate": "2025-10-31", - "providers": [ - "NetApp" - ], - "categories": { - "domains": [ - "Security - Threat Protection", - "Storage" - ] - } - }, - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" - } - ], - "outputs": {} -} diff --git a/Solutions/NetAppRansomwareResilience/Package/testParameters.json b/Solutions/NetAppRansomwareResilience/Package/testParameters.json deleted file mode 100644 index e55ec41a9ac..00000000000 --- a/Solutions/NetAppRansomwareResilience/Package/testParameters.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "location": { - "type": "string", - "minLength": 1, - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" - } - }, - "workspace-location": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" - } - }, - "workspace": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" - } - } -} From b59a2a5e16bcac05bc273fb85c03dd696c3260da Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Naik <44408204+SoumyaRanjanNaik@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:12:54 +0530 Subject: [PATCH 15/22] update validation schemas --- .../NetAppRansomwareResilience_alerts_CL.json | 25 ------------------- .../ValidConnectorIds.json | 3 +-- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 .script/tests/KqlvalidationsTests/CustomTables/NetAppRansomwareResilience_alerts_CL.json diff --git a/.script/tests/KqlvalidationsTests/CustomTables/NetAppRansomwareResilience_alerts_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/NetAppRansomwareResilience_alerts_CL.json deleted file mode 100644 index a3aa7879ff7..00000000000 --- a/.script/tests/KqlvalidationsTests/CustomTables/NetAppRansomwareResilience_alerts_CL.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "NetAppRansomwareResilience_alerts_CL", - "properties": [ - { - "name": "TimeGenerated", - "type": "datetime" - }, - { - "name": "description", - "type": "string" - }, - { - "name": "severity", - "type": "string" - }, - { - "name": "incident", - "type": "dynamic" - }, - { - "name": "context", - "type": "dynamic" - } - ] -} \ No newline at end of file diff --git a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json index 9c15ccc0468..db4453cbbd4 100644 --- a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json +++ b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json @@ -286,6 +286,5 @@ "CyrenThreatIntel", "CybleVisionAlerts", "VersasecCms", - "VisaThreatIntelligence", - "NetAppRansomwareResilienceCustomLogsIngestion" + "VisaThreatIntelligence" ] \ No newline at end of file From 49712e0852eec96f182b5d583b1400a828533f59 Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Naik <44408204+SoumyaRanjanNaik@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:18:50 +0530 Subject: [PATCH 16/22] fix line endings --- .../ValidConnectorIds.json | 578 +++++++++--------- 1 file changed, 289 insertions(+), 289 deletions(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json index db4453cbbd4..52bc600da01 100644 --- a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json +++ b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json @@ -1,290 +1,290 @@ -[ - "Netclean_ProActive_Incidents", - "42CrunchAPIProtection", - "AIVectraDetect", - "AIVectraStream", - "VectraXDR", - "AWS", - "AWSS3", - "AWSSecurityHub", - "Agari", - "AkamaiSecurityEvents", - "AlcideKAudit", - "AlsidForAD", - "Anvilogic", - "Armorblox", - "ApacheHTTPServer", - "ApacheTomcat", - "ARGOSCloudSecurity", - "AristaAwakeSecurity", - "ASimDnsActivityLogs", - "ArubaClearPass", - "AzureActiveDirectory", - "AzureActiveDirectoryIdentityProtection", - "AzureActivity", - "AzureAdvancedThreatProtection", - "AzureFirewall", - "AzureInformationProtection", - "AzureKeyVault", - "AzureKubernetes", - "AzureMonitor(IIS)", - "AzureMonitor(VMInsights)", - "AzureMonitor(WireData)", - "AzureNSG", - "AzureSecurityCenter", - "AzureSql", - "AzureStorageAccount", - "Barracuda", - "BarracudaCloudFirewall", - "BetterMTD", - "BehaviorAnalytics", - "BeyondSecuritybeSECURE", - "Bitglass", - "BitSight", - "BlackberryCylancePROTECT", - "BloodHoundEnterprise", - "BoschAIShield", - "BoxDataConnector", - "BroadcomSymantecDLP", - "CEF", - "CheckPoint", - "CiscoASA", - "CiscoAsaAma", - "CiscoDuoSecurity", - "CiscoFirepowerEStreamer", - "CiscoISE", - "CiscoMeraki", - "CiscoSDWAN", - "CiscoSecureEndpoint", - "CiscoSEG", - "CiscoUCS", - "CiscoUmbrellaDataConnector", - "CiscoWSA", - "Citrix", - "CitrixWAF", - "Claroty", - "CloudflareDataConnector", - "CognniSentinelDataConnector", - "ContrastProtect", - "Corelight", - "CrowdStrikeFalconEndpointProtection", - "CyberArk", - "CyberArkEPM", - "CyberpionSecurityLogs", - "CynerioSecurityEvents", - "DDOS", - "DNS", - "Darktrace", - "DarktraceRESTConnector", - "DataminrPulseAlerts", - "Dataverse", - "DigitalGuardianDLP", - "DigitalShadows", - "DragosSitestoreCCP", - "Dynamics365", - "Dynamics365Finance", - "EgressDefend", - "ESETEnterpriseInspector", - "ESETPROTECT", - "EsetSMC", - "ESI-ExchangeAdminAuditLogEvents", - "ExtraHopNetworks", - "F5", - "F5BigIp", - "Flare", - "ForcepointCasb", - "ForcepointDlp", - "ForcepointNgfw", - "ForgeRock", - "Fortinet", - "FortiWeb", - "GCPDNSDataConnector", - "GoogleSCCDefinition", - "GWorkspaceRAPI", - "GoogleWorkspaceReportsAPI", - "GreyNoise2SentinelAPI", - "IdentityInfo", - "ImpervaWAFCloudAPI", - "ImpervaWAFGateway", - "ImportedConnector", - "InfobloxCloudDataConnector", - "InfobloxNIOS", - "IoT", - "JamfProtect", - "JiraAuditAPI", - "JuniperSRX", - "KeeperSecurityPush2", - "LastPass", - "LookoutAPI", - "LumenThreatFeedConnector", - "McAfeeePO", - "MicrosoftAzurePurview", - "MicrosoftCloudAppSecurity", - "MicrosoftCopilot", - "MicrosoftDefenderAdvancedThreatProtection", - "MicrosoftSysmonForLinux", - "MicrosoftThreatProtection", - "MimecastSEGAPI", - "MorphisecCCF", - "NasuniEdgeAppliance", - "NXLogDnsLogs", - "NXLogLinuxAudit", - "Netskope", - "Office365", - "OfficeATP", - "OktaSSO", - "OktaSSOv2", - "OnapsisPlatform", - "OneIdentity", - "OCILogs", - "OracleDatabaseAudit", - "OracleCloudInfrastructureLogsConnector", - "OracleWebLogicServer", - "OrcaSecurityAlerts", - "PaloAltoCDL", - "PaloAltoNetworks", - "PaloAltoPrismaCloud", - "Perimeter81ActivityLogs", - "PingFederate", - "PostgreSQL", - "PowerAutomate", - "PowerPlatformAdmin", - "ProofpointPOD", - "ProofpointTAP", - "ProofpointTAPNativePoller", - "ProofpointTAPv2", - "PulseConnectSecure", - "QscoutAppEventsCCFDefinition", - "QualysKB", - "QualysVulnerabilityManagement", - "RedCanaryDataConnector", - "RubrikSecurityCloudAzureFunctions", - "SailPointIdentityNow", - "SalesforceServiceCloud", - "SalesforceServiceCloudCCPDefinition", - "SAP", - "SAPBTPAuditEvents", - "SAPLogServ", - "SAPETDAlerts", - "SecurityEvents", - "SemperisDSP", - "SenservaPro", - "SentinelOne", - "SlackAuditAPI", - "Snowflake", - "SonicWallFirewall", - "SonraiDataConnector", - "SophosCloudOptix", - "SophosXGFirewall", - "SquadraTechnologiesSecRmm", - "SquidProxy", - "Symantec", - "SymantecEndpointProtection", - "SymantecProxySG", - "SymantecVIP", - "Syslog", - "Tenable.ad", - "TenableVM", - "TenableIE", - "ThreatIntelligence", - "ThreatIntelligenceTaxii", - "ThreatIntelligenceUploadIndicatorsAPI", - "DelineaSecretServer_CEF", - "TrendMicro", - "TrendMicroApexOne", - "TrendMicroCAS", - "TrendMicroTippingPoint", - "TrendMicroXDR", - "UbiquitiUnifi", - "vArmourAC", - "VMwareCarbonBlack", - "vCenter", - "VMwareESXi", - "VMwareSDWAN", - "WAF", - "WindowsFirewall", - "WindowsForwardedEvents", - "WireX_Systems_NFP", - "ZimperiumMtdAlerts", - "Zscaler", - "ZscalerPrivateAccess", - "illusiveAttackManagementSystem", - "WindowsSecurityEvents", - "IronNetIronDefense", - "GCPIAMDataConnector", - "Illusive", - "NGINXHTTPServer", - "ZeroNetworksSegmentAuditFunction", - "ZeroNetworksSegmentAuditNativePoller", - "Theom", - "Votiro", - "ISCBind", - "DynatraceRuntimeVulnerabilities", - "DynatraceAttacks", - "DynatraceAuditLogs", - "DynatraceProblems", - "Authomize", - "MicrosoftDefenderThreatIntelligence", - "ZeroFox_Alert_Polling", - "CortexXDR", - "CorelightConnectorExporter", - "MimecastSIEMAPI", - "MimecastTTPAPI", - "MimecastAuditAPI", - "PingFederateAma", - "vArmourACAma", - "ContrastProtectAma", - "InfobloxCloudDataConnectorAma", - "ClarotyAma", - "illusiveAttackManagementSystemAma", - "TrendMicroApexOneAma", - "PaloAltoCDLAma", - "CiscoSEGAma", - "AtlassianBeaconAlerts", - "GCPAuditLogsDefinition", - "PrancerLogData", - "MicrosoftDefenderForCloudTenantBased", - "RidgeBotDataConnector", - "ValenceSecurity", - "HVPollingIDAzureFunctions", - "CBSPollingIDAzureFunctions", - "AzureCloudNGFWByPaloAltoNetworks", - "PaloAltoNetworksAma", - "FortinetAma", - "CrowdStrikeFalconEndpointProtectionAma", - "AIVectraDetectAma", - "ZscalerAma", - "SyslogAma", - "FortinetFortiWebAma", - "InfobloxSOCInsightsDataConnector_API", - "InfobloxSOCInsightsDataConnector_Legacy", - "InfobloxSOCInsightsDataConnector_AMA", - "NetskopeDataConnector", - "NetskopeWebTransactionsDataConnector", - "CefAma", - "WindowsFirewallAma", - "1Password", - "RadiflowIsid", - "CustomLogsAma", - "SilverfortAma", - "IllumioSaaSDataConnector", - "CTERA", - "Workday", - "SamsungDCDefinition", - "CommvaultSecurityIQ_CL", - "ExtraHop", - "ContrastADR", - "CyfirmaAttackSurfaceAlertsConnector", - "CyfirmaBrandIntelligenceAlertsDC", - "CyfirmaDigitalRiskAlertsConnector", - "CyfirmaVulnerabilitiesIntelDC", - "CyfirmaCyberIntelligenceDC", - "VeeamCustomTablesDataConnector", - "CyfirmaCompromisedAccountsDataConnector", - "RSAIDPlus_AdminLogs_Connector", - "TacitRedThreatIntel", - "CyrenThreatIntel", - "CybleVisionAlerts", - "VersasecCms", - "VisaThreatIntelligence" +[ + "Netclean_ProActive_Incidents", + "42CrunchAPIProtection", + "AIVectraDetect", + "AIVectraStream", + "VectraXDR", + "AWS", + "AWSS3", + "AWSSecurityHub", + "Agari", + "AkamaiSecurityEvents", + "AlcideKAudit", + "AlsidForAD", + "Anvilogic", + "Armorblox", + "ApacheHTTPServer", + "ApacheTomcat", + "ARGOSCloudSecurity", + "AristaAwakeSecurity", + "ASimDnsActivityLogs", + "ArubaClearPass", + "AzureActiveDirectory", + "AzureActiveDirectoryIdentityProtection", + "AzureActivity", + "AzureAdvancedThreatProtection", + "AzureFirewall", + "AzureInformationProtection", + "AzureKeyVault", + "AzureKubernetes", + "AzureMonitor(IIS)", + "AzureMonitor(VMInsights)", + "AzureMonitor(WireData)", + "AzureNSG", + "AzureSecurityCenter", + "AzureSql", + "AzureStorageAccount", + "Barracuda", + "BarracudaCloudFirewall", + "BetterMTD", + "BehaviorAnalytics", + "BeyondSecuritybeSECURE", + "Bitglass", + "BitSight", + "BlackberryCylancePROTECT", + "BloodHoundEnterprise", + "BoschAIShield", + "BoxDataConnector", + "BroadcomSymantecDLP", + "CEF", + "CheckPoint", + "CiscoASA", + "CiscoAsaAma", + "CiscoDuoSecurity", + "CiscoFirepowerEStreamer", + "CiscoISE", + "CiscoMeraki", + "CiscoSDWAN", + "CiscoSecureEndpoint", + "CiscoSEG", + "CiscoUCS", + "CiscoUmbrellaDataConnector", + "CiscoWSA", + "Citrix", + "CitrixWAF", + "Claroty", + "CloudflareDataConnector", + "CognniSentinelDataConnector", + "ContrastProtect", + "Corelight", + "CrowdStrikeFalconEndpointProtection", + "CyberArk", + "CyberArkEPM", + "CyberpionSecurityLogs", + "CynerioSecurityEvents", + "DDOS", + "DNS", + "Darktrace", + "DarktraceRESTConnector", + "DataminrPulseAlerts", + "Dataverse", + "DigitalGuardianDLP", + "DigitalShadows", + "DragosSitestoreCCP", + "Dynamics365", + "Dynamics365Finance", + "EgressDefend", + "ESETEnterpriseInspector", + "ESETPROTECT", + "EsetSMC", + "ESI-ExchangeAdminAuditLogEvents", + "ExtraHopNetworks", + "F5", + "F5BigIp", + "Flare", + "ForcepointCasb", + "ForcepointDlp", + "ForcepointNgfw", + "ForgeRock", + "Fortinet", + "FortiWeb", + "GCPDNSDataConnector", + "GoogleSCCDefinition", + "GWorkspaceRAPI", + "GoogleWorkspaceReportsAPI", + "GreyNoise2SentinelAPI", + "IdentityInfo", + "ImpervaWAFCloudAPI", + "ImpervaWAFGateway", + "ImportedConnector", + "InfobloxCloudDataConnector", + "InfobloxNIOS", + "IoT", + "JamfProtect", + "JiraAuditAPI", + "JuniperSRX", + "KeeperSecurityPush2", + "LastPass", + "LookoutAPI", + "LumenThreatFeedConnector", + "McAfeeePO", + "MicrosoftAzurePurview", + "MicrosoftCloudAppSecurity", + "MicrosoftCopilot", + "MicrosoftDefenderAdvancedThreatProtection", + "MicrosoftSysmonForLinux", + "MicrosoftThreatProtection", + "MimecastSEGAPI", + "MorphisecCCF", + "NasuniEdgeAppliance", + "NXLogDnsLogs", + "NXLogLinuxAudit", + "Netskope", + "Office365", + "OfficeATP", + "OktaSSO", + "OktaSSOv2", + "OnapsisPlatform", + "OneIdentity", + "OCILogs", + "OracleDatabaseAudit", + "OracleCloudInfrastructureLogsConnector", + "OracleWebLogicServer", + "OrcaSecurityAlerts", + "PaloAltoCDL", + "PaloAltoNetworks", + "PaloAltoPrismaCloud", + "Perimeter81ActivityLogs", + "PingFederate", + "PostgreSQL", + "PowerAutomate", + "PowerPlatformAdmin", + "ProofpointPOD", + "ProofpointTAP", + "ProofpointTAPNativePoller", + "ProofpointTAPv2", + "PulseConnectSecure", + "QscoutAppEventsCCFDefinition", + "QualysKB", + "QualysVulnerabilityManagement", + "RedCanaryDataConnector", + "RubrikSecurityCloudAzureFunctions", + "SailPointIdentityNow", + "SalesforceServiceCloud", + "SalesforceServiceCloudCCPDefinition", + "SAP", + "SAPBTPAuditEvents", + "SAPLogServ", + "SAPETDAlerts", + "SecurityEvents", + "SemperisDSP", + "SenservaPro", + "SentinelOne", + "SlackAuditAPI", + "Snowflake", + "SonicWallFirewall", + "SonraiDataConnector", + "SophosCloudOptix", + "SophosXGFirewall", + "SquadraTechnologiesSecRmm", + "SquidProxy", + "Symantec", + "SymantecEndpointProtection", + "SymantecProxySG", + "SymantecVIP", + "Syslog", + "Tenable.ad", + "TenableVM", + "TenableIE", + "ThreatIntelligence", + "ThreatIntelligenceTaxii", + "ThreatIntelligenceUploadIndicatorsAPI", + "DelineaSecretServer_CEF", + "TrendMicro", + "TrendMicroApexOne", + "TrendMicroCAS", + "TrendMicroTippingPoint", + "TrendMicroXDR", + "UbiquitiUnifi", + "vArmourAC", + "VMwareCarbonBlack", + "vCenter", + "VMwareESXi", + "VMwareSDWAN", + "WAF", + "WindowsFirewall", + "WindowsForwardedEvents", + "WireX_Systems_NFP", + "ZimperiumMtdAlerts", + "Zscaler", + "ZscalerPrivateAccess", + "illusiveAttackManagementSystem", + "WindowsSecurityEvents", + "IronNetIronDefense", + "GCPIAMDataConnector", + "Illusive", + "NGINXHTTPServer", + "ZeroNetworksSegmentAuditFunction", + "ZeroNetworksSegmentAuditNativePoller", + "Theom", + "Votiro", + "ISCBind", + "DynatraceRuntimeVulnerabilities", + "DynatraceAttacks", + "DynatraceAuditLogs", + "DynatraceProblems", + "Authomize", + "MicrosoftDefenderThreatIntelligence", + "ZeroFox_Alert_Polling", + "CortexXDR", + "CorelightConnectorExporter", + "MimecastSIEMAPI", + "MimecastTTPAPI", + "MimecastAuditAPI", + "PingFederateAma", + "vArmourACAma", + "ContrastProtectAma", + "InfobloxCloudDataConnectorAma", + "ClarotyAma", + "illusiveAttackManagementSystemAma", + "TrendMicroApexOneAma", + "PaloAltoCDLAma", + "CiscoSEGAma", + "AtlassianBeaconAlerts", + "GCPAuditLogsDefinition", + "PrancerLogData", + "MicrosoftDefenderForCloudTenantBased", + "RidgeBotDataConnector", + "ValenceSecurity", + "HVPollingIDAzureFunctions", + "CBSPollingIDAzureFunctions", + "AzureCloudNGFWByPaloAltoNetworks", + "PaloAltoNetworksAma", + "FortinetAma", + "CrowdStrikeFalconEndpointProtectionAma", + "AIVectraDetectAma", + "ZscalerAma", + "SyslogAma", + "FortinetFortiWebAma", + "InfobloxSOCInsightsDataConnector_API", + "InfobloxSOCInsightsDataConnector_Legacy", + "InfobloxSOCInsightsDataConnector_AMA", + "NetskopeDataConnector", + "NetskopeWebTransactionsDataConnector", + "CefAma", + "WindowsFirewallAma", + "1Password", + "RadiflowIsid", + "CustomLogsAma", + "SilverfortAma", + "IllumioSaaSDataConnector", + "CTERA", + "Workday", + "SamsungDCDefinition", + "CommvaultSecurityIQ_CL", + "ExtraHop", + "ContrastADR", + "CyfirmaAttackSurfaceAlertsConnector", + "CyfirmaBrandIntelligenceAlertsDC", + "CyfirmaDigitalRiskAlertsConnector", + "CyfirmaVulnerabilitiesIntelDC", + "CyfirmaCyberIntelligenceDC", + "VeeamCustomTablesDataConnector", + "CyfirmaCompromisedAccountsDataConnector", + "RSAIDPlus_AdminLogs_Connector", + "TacitRedThreatIntel", + "CyrenThreatIntel", + "CybleVisionAlerts", + "VersasecCms", + "VisaThreatIntelligence" ] \ No newline at end of file From a6b3b03045622de6222fcccb379d241f75072b90 Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Naik <44408204+SoumyaRanjanNaik@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:19:22 +0530 Subject: [PATCH 17/22] fix line endings --- .../detectionTemplateSchemaValidation/ValidConnectorIds.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json index 52bc600da01..92536c69939 100644 --- a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json +++ b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json @@ -287,4 +287,4 @@ "CybleVisionAlerts", "VersasecCms", "VisaThreatIntelligence" -] \ No newline at end of file +] From 263f5d47d0d236cdaf26c87d24c6946c2e052265 Mon Sep 17 00:00:00 2001 From: Avinash Bharti Date: Mon, 16 Feb 2026 11:15:40 +0530 Subject: [PATCH 18/22] added build packages --- .../Solution_NetAppRansomwareResilience.json | 5 +- .../Package/3.0.0.zip | Bin 0 -> 12876 bytes .../Package/createUiDefinition.json | 89 + .../Package/mainTemplate.json | 3143 +++++++++++++++++ .../Package/testParameters.json | 24 + .../SolutionMetadata.json | 5 +- 6 files changed, 3261 insertions(+), 5 deletions(-) create mode 100644 Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip create mode 100644 Solutions/NetApp Ransomware Resilience/Package/createUiDefinition.json create mode 100644 Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json create mode 100644 Solutions/NetApp Ransomware Resilience/Package/testParameters.json diff --git a/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json b/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json index 5e9093863da..f7a2190ce85 100644 --- a/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json +++ b/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json @@ -1,10 +1,9 @@ { "Name": "NetApp Ransomware Resilience", "Author": "NetApp - support@netapp.com", - "title": "NetApp Ransomware Resilience", + "Title": "NetApp Ransomware Resilience", + "Logo": "\"NetApp", "Description": "NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.", - "logo": "\"NetApp", - "Playbooks": [ "Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json", "Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json", diff --git a/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip b/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..967e01fec0b5ca429329b81be720996219268ad1 GIT binary patch literal 12876 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\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/NetApp%20Ransomware%20Resilience/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nNetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.\n\n**Playbooks:** 6\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "subscription": { + "resourceProviders": [ + "Microsoft.OperationsManagement/solutions", + "Microsoft.OperationalInsights/workspaces/providers/alertRules", + "Microsoft.Insights/workbooks", + "Microsoft.Logic/workflows" + ] + }, + "location": { + "metadata": { + "hidden": "Hiding location, we get it from the log analytics workspace" + }, + "visible": false + }, + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "getLAWorkspace", + "type": "Microsoft.Solutions.ArmApiControl", + "toolTip": "This filters by workspaces that exist in the Resource Group selected", + "condition": "[greater(length(resourceGroup().name),0)]", + "request": { + "method": "GET", + "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]" + } + }, + { + "name": "workspace", + "type": "Microsoft.Common.DropDown", + "label": "Workspace", + "placeholder": "Select a workspace", + "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected", + "constraints": { + "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", + "required": true + }, + "visible": true + } + ], + "steps": [ + { + "name": "playbooks", + "label": "Playbooks", + "subLabel": { + "preValidation": "Configure the playbooks", + "postValidation": "Done" + }, + "bladeTitle": "Playbooks", + "elements": [ + { + "name": "playbooks-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs the Playbook templates to help implement your Security Orchestration, Automation and Response (SOAR) operations. After installing the solution, these will be deployed under Playbook Templates in the Automation blade in Microsoft Sentinel. They can be configured and managed from the Manage solution view in Content Hub." + } + }, + { + "name": "playbooks-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-respond-threats-playbook?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef" + } + } + } + ] + } + ], + "outputs": { + "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", + "location": "[location()]", + "workspace": "[basics('workspace')]" + } + } +} diff --git a/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json new file mode 100644 index 00000000000..136c7dd8bf6 --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json @@ -0,0 +1,3143 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "author": "NetApp - support@netapp.com", + "comments": "Solution template for NetApp Ransomware Resilience" + }, + "parameters": { + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + } + }, + "variables": { + "email": "support@netapp.com", + "_email": "[variables('email')]", + "_solutionName": "NetApp Ransomware Resilience", + "_solutionVersion": "3.0.0", + "solutionId": "netapp1234567890.azure-sentinel-solution-netapprrs", + "_solutionId": "[variables('solutionId')]", + "NetApp-RansomwareResilience-Auth-Playbook": "NetApp-RansomwareResilience-Auth-Playbook", + "_NetApp-RansomwareResilience-Auth-Playbook": "[variables('NetApp-RansomwareResilience-Auth-Playbook')]", + "TemplateEmptyArray": "[json('[]')]", + "playbookVersion1": "1.0", + "playbookContentId1": "NetApp-RansomwareResilience-Auth-Playbook", + "_playbookContentId1": "[variables('playbookContentId1')]", + "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]", + "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]", + "blanks": "[replace('b', 'b', '')]", + "NetApp-RansomwareResilience_Volume_Offline_Playbook": "NetApp-RansomwareResilience_Volume_Offline_Playbook", + "_NetApp-RansomwareResilience_Volume_Offline_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Offline_Playbook')]", + "TemplateEmptyObject": "[json('{}')]", + "playbookVersion2": "1.0", + "playbookContentId2": "NetApp-RansomwareResilience_Volume_Offline_Playbook", + "_playbookContentId2": "[variables('playbookContentId2')]", + "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]", + "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]", + "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]", + "NetApp-RansomwareResilience_Async_Poll_Playbook": "NetApp-RansomwareResilience_Async_Poll_Playbook", + "_NetApp-RansomwareResilience_Async_Poll_Playbook": "[variables('NetApp-RansomwareResilience_Async_Poll_Playbook')]", + "playbookVersion3": "1.0", + "playbookContentId3": "NetApp-RansomwareResilience_Async_Poll_Playbook", + "_playbookContentId3": "[variables('playbookContentId3')]", + "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]", + "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]", + "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]", + "NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook", + "_NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Snapshot_Playbook')]", + "playbookVersion4": "1.0", + "playbookContentId4": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook", + "_playbookContentId4": "[variables('playbookContentId4')]", + "playbookId4": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId4'))]", + "playbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId4'))))]", + "_playbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId4'),'-', variables('playbookVersion4'))))]", + "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "_NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_StorageVM_Playbook')]", + "playbookVersion5": "1.0", + "playbookContentId5": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "_playbookContentId5": "[variables('playbookContentId5')]", + "playbookId5": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId5'))]", + "playbookTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId5'))))]", + "_playbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId5'),'-', variables('playbookVersion5'))))]", + "NetApp-RansomwareResilience_Enrich_IP_Playbook": "NetApp-RansomwareResilience_Enrich_IP_Playbook", + "_NetApp-RansomwareResilience_Enrich_IP_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_IP_Playbook')]", + "playbookVersion6": "1.0", + "playbookContentId6": "NetApp-RansomwareResilience_Enrich_IP_Playbook", + "_playbookContentId6": "[variables('playbookContentId6')]", + "playbookId6": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId6'))]", + "playbookTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId6'))))]", + "_playbookcontentProductId6": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId6'),'-', variables('playbookVersion6'))))]", + "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetApp-RansomwareResilience-Auth-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion1')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "metadata": { + "description": "Name of the Logic App playbook to be created" + } + }, + "KeyVaultName": { + "type": "String", + "defaultValue": "[concat('RRSkv', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "Name of the shared Key Vault to store NetApp Ransomware Resilience credentials" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + }, + "ClientId": { + "type": "securestring", + "metadata": { + "description": "Client ID for NetApp Ransomware Resilience API authentication" + } + }, + "ClientSecret": { + "type": "securestring", + "metadata": { + "description": "Client Secret for NetApp Ransomware Resilience API authentication" + } + }, + "AccountId": { + "type": "securestring", + "metadata": { + "description": "Account ID for NetApp Ransomware Resilience API authentication" + } + } + }, + "variables": { + "KeyVaultConnectionName": "[[concat('keyvault-', parameters('PlaybookName'))]", + "connection-5": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]", + "_connection-5": "[[variables('connection-5')]", + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-07-01", + "name": "[[parameters('KeyVaultName')]", + "location": "[[parameters('location')]", + "properties": { + "sku": { + "family": "A", + "name": "standard" + }, + "tenantId": "[[subscription().tenantId]", + "enabledForDeployment": false, + "enabledForDiskEncryption": false, + "enabledForTemplateDeployment": true, + "enableSoftDelete": true, + "softDeleteRetentionInDays": 90, + "enableRbacAuthorization": false, + "accessPolicies": "[variables('TemplateEmptyArray')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/client-id')]", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[[parameters('ClientId')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/client-secret')]", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[[parameters('ClientSecret')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/account-id')]", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "value": "[[parameters('AccountId')]" + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[[variables('KeyVaultConnectionName')]", + "location": "[[parameters('location')]", + "kind": "V1", + "dependsOn": [ + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "displayName": "[[variables('KeyVaultConnectionName')]", + "parameterValueSet": { + "name": "oauthMI", + "values": { + "vaultName": { + "value": "[[parameters('KeyVaultName')]" + } + } + }, + "api": { + "id": "[[variables('_connection-5')]" + } + } + }, + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "dependsOn": [ + "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "$connections": { + "type": "Object" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "properties": { + "account_id": { + "type": "string" + }, + "api_hostname": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "actions": { + "Get_Client_ID": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('client-id')}/value" + } + }, + "Get_Client_Secret": { + "runAfter": { + "Get_Client_ID": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('client-secret')}/value" + } + }, + "Get_Account_ID": { + "runAfter": { + "Get_Client_Secret": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['keyvault']['connectionId']" + } + }, + "method": "get", + "path": "/secrets/@{encodeURIComponent('account-id')}/value" + } + }, + "HTTP_Token_Request": { + "runAfter": { + "Get_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://staging-netapp-cloud-account.auth0.com/oauth/token", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{body('Get_Client_ID')?['value']}&client_secret=@{body('Get_Client_Secret')?['value']}&audience=https://api.cloud.netapp.com" + } + }, + "Response": { + "runAfter": { + "HTTP_Token_Request": [ + "Succeeded" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "access_token": "@{body('HTTP_Token_Request')?['access_token']}", + "token_type": "@{body('HTTP_Token_Request')?['token_type']}", + "expires_in": "@{body('HTTP_Token_Request')?['expires_in']}", + "account_id": "@{body('Get_Account_ID')?['value']}" + } + } + } + } + }, + "parameters": { + "$connections": { + "value": { + "keyvault": { + "connectionId": "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]", + "connectionName": "[[variables('KeyVaultConnectionName')]", + "connectionProperties": { + "authentication": { + "type": "ManagedServiceIdentity" + } + }, + "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]" + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2019-09-01", + "name": "[[concat(parameters('KeyVaultName'), '/add')]", + "dependsOn": [ + "[[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]", + "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]" + ], + "properties": { + "accessPolicies": [ + { + "tenantId": "[[subscription().tenantId]", + "objectId": "[[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'Full').identity.principalId]", + "permissions": { + "secrets": [ + "get" + ] + } + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId1'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId1')]", + "contentId": "[variables('_playbookContentId1')]", + "kind": "Playbook", + "version": "[variables('playbookVersion1')]", + "source": { + "kind": "Solution", + "name": "NetApp Ransomware Resilience", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp Ransomware Resilience Authentication Playbook", + "description": "This playbook creates a shared Key Vault for NetApp Ransomware Resilience credentials and provides authentication services to all NetApp Ransomware Resilience playbooks in the solution.", + "prerequisites": [ + "1. Valid client_id, client_secret, and account_id for NetApp Ransomware Resilience API authentication", + "2. API endpoint that accepts OAuth2 client credentials flow" + ], + "postDeployment": [ + "1. Update the client_id, client_secret, and account_id values in the Key Vault", + "2. Test the Logic App to ensure proper token retrieval", + "3. The Key Vault created by this playbook will be shared across all NetApp Ransomware Resilience playbooks", + "4. Other playbooks will call this Auth playbook to obtain authentication tokens" + ], + "lastUpdateTime": "2025-09-17T00:00:00Z", + "tags": [ + "NetApp", + "RansomwareResilience", + "Playbook", + "Authentication" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId1')]", + "contentKind": "Playbook", + "displayName": "NetApp-RansomwareResilience-Auth-Playbook", + "contentProductId": "[variables('_playbookcontentProductId1')]", + "id": "[variables('_playbookcontentProductId1')]", + "version": "[variables('playbookVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName2')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetApp-RansomwareResilience-Volume-Offline-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion2')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Volume-Offline-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience authentication playbook" + } + }, + "NetAppRansomwareResilienceAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "volume_id": { + "type": "string" + }, + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + }, + "poll": { + "type": "boolean" + } + }, + "required": [ + "volume_id", + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "VolumeId", + "type": "string", + "value": "@triggerBody()?['volume_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "DoPoll", + "type": "boolean", + "value": "@coalesce(triggerBody()?['poll'], true)" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobId", + "type": "string" + }, + { + "name": "JobAgentId", + "type": "string" + }, + { + "name": "PollResponse", + "type": "object", + "value": "[variables('TemplateEmptyObject')]" + }, + { + "name": "SubmissionStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Submit_Volume_Offline": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/storage/take-volume-offline", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "Content-Type": "application/json", + "accept": "application/json" + }, + "body": { + "volume_id": "@variables('VolumeId')", + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Submission_Status_Code": { + "runAfter": { + "Submit_Volume_Offline": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SubmissionStatusCode", + "value": "@outputs('Submit_Volume_Offline')['statusCode']" + } + }, + "Parse_Submission_Response": { + "runAfter": { + "Capture_Submission_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Submit_Volume_Offline')", + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + }, + "Store_JobId": { + "runAfter": { + "Parse_Submission_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobId", + "value": "@body('Parse_Submission_Response')?['job_id']" + } + }, + "Store_Job_AgentId": { + "runAfter": { + "Store_JobId": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobAgentId", + "value": "@body('Parse_Submission_Response')?['agent_id']" + } + }, + "Check_If_Should_Poll": { + "runAfter": { + "Store_Job_AgentId": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@variables('DoPoll')", + true + ] + }, + { + "or": [ + { + "equals": [ + "@variables('SubmissionStatusCode')", + 200 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 201 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 202 + ] + } + ] + }, + { + "not": { + "equals": [ + "@variables('JobId')", + "" + ] + } + } + ] + }, + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@variables('JobId')", + "agent_id": "@variables('JobAgentId')", + "system_id": "@variables('SystemId')", + "source": "ontap", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_volume_id": "@variables('VolumeId')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + } + } + }, + "Parse_Poll_Response": { + "runAfter": { + "Check_If_Should_Poll": [ + "Succeeded" + ] + }, + "type": "Compose", + "inputs": "@if(equals(actions('Call_Async_Poll_Playbook')['status'], 'Succeeded'), body('Call_Async_Poll_Playbook'), json('{\"success\": false, \"status\": \"FAILED\", \"error\": \"Poll playbook failed or timed out\"}'))" + }, + "Store_Poll_Response": { + "runAfter": { + "Parse_Poll_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PollResponse", + "value": "@outputs('Parse_Poll_Response')" + } + }, + "Finalize_Execution": { + "runAfter": { + "Store_Poll_Response": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ], + "Check_If_Should_Poll": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Submit_Volume_Offline": [ + "Failed", + "TimedOut" + ] + }, + "type": "Compose", + "inputs": { + "execution_completed": true, + "timestamp": "@utcNow()" + } + }, + "Return_Response": { + "runAfter": { + "Finalize_Execution": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'Failed submitting volume offline request', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'submit', 'success'))", + "submission": { + "statusCode": "@variables('SubmissionStatusCode')", + "jobId": "@variables('JobId')", + "raw": "@body('Submit_Volume_Offline')", + "details": "@if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), body('Submit_Volume_Offline'), null)" + }, + "polling": { + "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", + "playbook": "@parameters('asyncPollPlaybookName')", + "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", + "jobResponse": "@variables('PollResponse')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId2'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId2')]", + "contentId": "[variables('_playbookContentId2')]", + "kind": "Playbook", + "version": "[variables('playbookVersion2')]", + "source": { + "kind": "Solution", + "name": "NetApp Ransomware Resilience", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp Ransomware Resilience Volume Offline Playbook", + "description": "This playbook takes a NetApp volume offline using the updated NetApp Ransomware Resilience take-volume-offline API endpoint and optionally polls for completion.", + "prerequisites": [ + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", + "4. Caller must provide volume_id, agent_id, and system_id parameters" + ], + "postDeployment": [ + "1. Test the volume offline functionality with valid volume_id, agent_id, and system_id" + ], + "lastUpdateTime": "2025-09-17T00:00:00Z", + "tags": [ + "NetApp", + "RansomwareResilience", + "Playbook", + "Volume", + "Offline" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId2')]", + "contentKind": "Playbook", + "displayName": "NetApp-RansomwareResilience-Volume-Offline-Playbook", + "contentProductId": "[variables('_playbookcontentProductId2')]", + "id": "[variables('_playbookcontentProductId2')]", + "version": "[variables('playbookVersion2')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName3')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetApp-RansomwareResilience-Async-Poll-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion3')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience authentication playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "description": "The NetApp Ransomware Resilience job ID to poll" + }, + "agent_id": { + "type": "string", + "description": "NetApp Ransomware Resilience agent ID" + }, + "system_id": { + "type": "string", + "description": "System ID for the working environment" + }, + "source": { + "type": "string", + "description": "Job source type" + }, + "caller_info": { + "type": "object", + "description": "Optional caller information for tracking" + } + }, + "required": [ + "job_id", + "agent_id", + "system_id", + "source" + ] + } + } + } + }, + "actions": { + "Initialize_variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "JobId", + "type": "string", + "value": "@triggerBody()?['job_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "Source", + "type": "string", + "value": "@triggerBody()?['source']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "PollCount", + "type": "integer", + "value": 0 + }, + { + "name": "MaxPollAttempts", + "type": "integer", + "value": 10 + }, + { + "name": "PollIntervalSeconds", + "type": "integer", + "value": 30 + }, + { + "name": "JobStatus", + "type": "string", + "value": "pending" + }, + { + "name": "JobResponse", + "type": "object", + "value": "[variables('TemplateEmptyObject')]" + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + } + } + }, + "Set_Account_ID": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Call_Auth_Playbook')?['account_id']" + } + }, + "Initial_Status_Check": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 2, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT10S" + }, + "timeout": "PT30S" + } + }, + "Update_Initial_Status": { + "runAfter": { + "Initial_Status_Check": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "@body('Initial_Status_Check')?['status']" + } + }, + "Update_Initial_Response": { + "runAfter": { + "Update_Initial_Status": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobResponse", + "value": "@body('Initial_Status_Check')" + } + }, + "Polling_Loop": { + "runAfter": { + "Update_Initial_Response": [ + "Succeeded" + ] + }, + "type": "Until", + "expression": "@or(or(equals(variables('JobStatus'), 'SUCCESS'), equals(variables('JobStatus'), 'success')), or(equals(variables('JobStatus'), 'FAILED'), equals(variables('JobStatus'), 'failed')), greater(variables('PollCount'), variables('MaxPollAttempts')))", + "limit": { + "count": 10, + "timeout": "PT6M" + }, + "actions": { + "Increment_Poll_Count": { + "type": "IncrementVariable", + "inputs": { + "name": "PollCount", + "value": 1 + } + }, + "Check_Job_Status": { + "runAfter": { + "Increment_Poll_Count": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 2, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT10S" + }, + "timeout": "PT30S" + } + }, + "Update_Job_Status": { + "runAfter": { + "Check_Job_Status": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "@body('Check_Job_Status')?['status']" + } + }, + "Handle_Status_Check_Failure": { + "runAfter": { + "Check_Job_Status": [ + "Failed", + "TimedOut" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobStatus", + "value": "failed" + } + }, + "Update_Job_Response": { + "runAfter": { + "Update_Job_Status": [ + "Succeeded" + ], + "Handle_Status_Check_Failure": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobResponse", + "value": "@body('Check_Job_Status')" + } + }, + "Wait_If_Needed": { + "runAfter": { + "Update_Job_Response": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "not": { + "or": [ + { + "equals": [ + "@variables('JobStatus')", + "SUCCESS" + ] + }, + { + "equals": [ + "@variables('JobStatus')", + "success" + ] + } + ] + } + }, + "actions": { + "Wait_Before_Retry": { + "type": "Wait", + "inputs": { + "interval": { + "count": "@variables('PollIntervalSeconds')", + "unit": "Second" + } + } + } + } + } + } + }, + "Check_Final_Status": { + "runAfter": { + "Polling_Loop": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "or": [ + { + "equals": [ + "@variables('JobStatus')", + "SUCCESS" + ] + }, + { + "equals": [ + "@variables('JobStatus')", + "success" + ] + } + ] + } + ] + }, + "actions": { + "Success_Response": { + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": true, + "job_id": "@variables('JobId')", + "status": "@variables('JobStatus')", + "poll_count": "@variables('PollCount')", + "data": "@variables('JobResponse')", + "caller_info": "@triggerBody()?['caller_info']" + } + } + } + }, + "else": { + "actions": { + "Error_Response": { + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 408, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": false, + "error": "Job polling timeout or failed", + "job_id": "@variables('JobId')", + "status": "@variables('JobStatus')", + "poll_count": "@variables('PollCount')", + "max_attempts": "@variables('MaxPollAttempts')", + "data": "@variables('JobResponse')", + "caller_info": "@triggerBody()?['caller_info']" + } + } + } + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId3'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId3')]", + "contentId": "[variables('_playbookContentId3')]", + "kind": "Playbook", + "version": "[variables('playbookVersion3')]", + "source": { + "kind": "Solution", + "name": "NetApp Ransomware Resilience", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp Ransomware Resilience Async Poll Playbook", + "description": "This playbook polls NetApp Ransomware Resilience job status asynchronously until completion or timeout using the updated job status API endpoint.", + "prerequisites": [ + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", + "3. Caller must provide job_id, agent_id, system_id, and source parameters" + ], + "postDeployment": [ + "1. Test the playbook by triggering it with a valid job_id, agent_id, system_id, and source", + "2. Monitor the playbook run history to verify successful polling and completion" + ], + "lastUpdateTime": "2025-09-17T00:00:00Z", + "tags": [ + "NetApp", + "RansomwareResilience", + "Playbook", + "Async", + "Polling" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId3')]", + "contentKind": "Playbook", + "displayName": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "contentProductId": "[variables('_playbookcontentProductId3')]", + "id": "[variables('_playbookcontentProductId3')]", + "version": "[variables('playbookVersion3')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName4')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion4')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience authentication playbook" + } + }, + "NetAppRansomwareResilienceAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "volume_id": { + "type": "string" + }, + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + }, + "poll": { + "type": "boolean" + } + }, + "required": [ + "volume_id", + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "VolumeId", + "type": "string", + "value": "@triggerBody()?['volume_id']" + }, + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "DoPoll", + "type": "boolean", + "value": "@coalesce(triggerBody()?['poll'], true)" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobId", + "type": "string" + }, + { + "name": "JobAgentId", + "type": "string" + }, + { + "name": "PollResponse", + "type": "object", + "value": "[variables('TemplateEmptyObject')]" + }, + { + "name": "SubmissionStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Submit_Volume_Snapshot": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/storage/take-snapshot", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "Content-Type": "application/json", + "accept": "application/json" + }, + "body": { + "volume_id": "@variables('VolumeId')", + "agent_id": "@variables('AgentId')", + "system_id": "@variables('SystemId')" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Submission_Status_Code": { + "runAfter": { + "Submit_Volume_Snapshot": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SubmissionStatusCode", + "value": "@outputs('Submit_Volume_Snapshot')['statusCode']" + } + }, + "Parse_Submission_Response": { + "runAfter": { + "Capture_Submission_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Submit_Volume_Snapshot')", + "schema": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + }, + "Store_JobId": { + "runAfter": { + "Parse_Submission_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobId", + "value": "@body('Parse_Submission_Response')?['job_id']" + } + }, + "Store_Job_AgentId": { + "runAfter": { + "Store_JobId": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobAgentId", + "value": "@body('Parse_Submission_Response')?['agent_id']" + } + }, + "Check_If_Should_Poll": { + "runAfter": { + "Store_Job_AgentId": [ + "Succeeded" + ] + }, + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "@variables('DoPoll')", + true + ] + }, + { + "or": [ + { + "equals": [ + "@variables('SubmissionStatusCode')", + 200 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 201 + ] + }, + { + "equals": [ + "@variables('SubmissionStatusCode')", + 202 + ] + } + ] + }, + { + "not": { + "equals": [ + "@variables('JobId')", + "" + ] + } + } + ] + }, + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@variables('JobId')", + "agent_id": "@variables('JobAgentId')", + "system_id": "@variables('SystemId')", + "source": "ontap", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_volume_id": "@variables('VolumeId')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + } + } + }, + "Parse_Poll_Response": { + "runAfter": { + "Check_If_Should_Poll": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Async_Poll_Playbook')", + "schema": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "jobId": { + "type": "string" + }, + "success": { + "type": "boolean" + } + } + } + } + }, + "Store_Poll_Response": { + "runAfter": { + "Parse_Poll_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PollResponse", + "value": "@body('Parse_Poll_Response')" + } + }, + "Return_Response": { + "runAfter": { + "Store_Poll_Response": [ + "Succeeded", + "Skipped" + ], + "Check_If_Should_Poll": [ + "Succeeded" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Submit_Volume_Snapshot": [ + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'Failed submitting volume snapshot request', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'submit', 'success'))", + "submission": { + "statusCode": "@variables('SubmissionStatusCode')", + "jobId": "@variables('JobId')", + "raw": "@body('Submit_Volume_Snapshot')", + "details": "@if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), body('Submit_Volume_Snapshot'), null)" + }, + "polling": { + "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))", + "playbook": "@parameters('asyncPollPlaybookName')", + "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')", + "jobResponse": "@variables('PollResponse')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId4'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId4')]", + "contentId": "[variables('_playbookContentId4')]", + "kind": "Playbook", + "version": "[variables('playbookVersion4')]", + "source": { + "kind": "Solution", + "name": "NetApp Ransomware Resilience", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp Ransomware Resilience Volume Snapshot Playbook", + "description": "This playbook creates a NetApp volume snapshot using the updated NetApp Ransomware Resilience take-snapshot API endpoint and optionally polls for completion.", + "prerequisites": [ + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", + "4. Caller must provide volume_id, agent_id, and system_id parameters" + ], + "postDeployment": [ + "1. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id" + ], + "lastUpdateTime": "2025-09-22T00:00:00Z", + "tags": [ + "NetApp", + "RansomwareResilience", + "Playbook", + "Volume", + "Snapshot" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId4')]", + "contentKind": "Playbook", + "displayName": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", + "contentProductId": "[variables('_playbookcontentProductId4')]", + "id": "[variables('_playbookcontentProductId4')]", + "version": "[variables('playbookVersion4')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName5')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion5')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience authentication playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "system_id": { + "type": "string" + }, + "callbackData": { + "type": "object" + } + }, + "required": [ + "agent_id", + "system_id" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "AgentId", + "type": "string", + "value": "@triggerBody()?['agent_id']" + }, + { + "name": "SystemId", + "type": "string", + "value": "@triggerBody()?['system_id']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "StorageVMData", + "type": "array" + }, + { + "name": "EnrichmentStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Get_StorageVM_Data": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "GET", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "accept": "application/json" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + } + } + }, + "Capture_Enrichment_Status_Code": { + "runAfter": { + "Get_StorageVM_Data": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "EnrichmentStatusCode", + "value": "@outputs('Get_StorageVM_Data')['statusCode']" + } + }, + "Parse_StorageVM_Response": { + "runAfter": { + "Capture_Enrichment_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Get_StorageVM_Data')", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "volume_uuid": { + "type": "string" + }, + "volume_name": { + "type": "string" + }, + "svm_name": { + "type": "string" + } + } + } + } + } + }, + "Store_StorageVM_Data": { + "runAfter": { + "Parse_StorageVM_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "StorageVMData", + "value": "@body('Parse_StorageVM_Response')" + } + }, + "Finalize_Execution": { + "runAfter": { + "Store_StorageVM_Data": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Get_StorageVM_Data": [ + "Failed", + "TimedOut" + ] + }, + "type": "Compose", + "inputs": { + "execution_completed": true, + "timestamp": "@utcNow()" + } + }, + "Return_Response": { + "runAfter": { + "Finalize_Execution": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'Failed retrieving storage VM data', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'enrichment', 'success'))", + "account_id": "@variables('AccountId')", + "enrichment": { + "statusCode": "@variables('EnrichmentStatusCode')", + "storage_vms": "@variables('StorageVMData')", + "count": "@length(variables('StorageVMData'))", + "raw": "@body('Get_StorageVM_Data')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId5'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId5')]", + "contentId": "[variables('_playbookContentId5')]", + "kind": "Playbook", + "version": "[variables('playbookVersion5')]", + "source": { + "kind": "Solution", + "name": "NetApp Ransomware Resilience", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp Ransomware Resilience Enrich StorageVM Playbook", + "description": "This playbook enriches storage data by calling the updated NetApp Ransomware Resilience enrich storage API endpoint.", + "prerequisites": [ + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", + "3. Caller must provide agent_id and system_id parameters" + ], + "postDeployment": [ + "1. Test the storage enrichment functionality with valid agent_id and system_id" + ], + "lastUpdateTime": "2025-09-23T00:00:00Z", + "tags": [ + "NetApp", + "RansomwareResilience", + "Playbook", + "StorageVM", + "Enrich" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId5')]", + "contentKind": "Playbook", + "displayName": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "contentProductId": "[variables('_playbookcontentProductId5')]", + "id": "[variables('_playbookcontentProductId5')]", + "version": "[variables('playbookVersion5')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName6')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NetApp-RansomwareResilience-Enrich-IP-Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion6')]", + "parameters": { + "PlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Enrich-IP-Playbook", + "metadata": { + "description": "Name of the Logic App/Playbook" + } + }, + "NetAppRansomwareResilienceAuthPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience authentication playbook" + } + }, + "NetAppRansomwareResilienceAsyncPollPlaybookName": { + "type": "String", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "metadata": { + "description": "Name of the NetApp Ransomware Resilience async poll playbook" + } + }, + "location": { + "type": "string", + "defaultValue": "[parameters('location')]", + "metadata": { + "description": "Location for all resources" + } + } + }, + "variables": { + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "state": "Enabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "authPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]", + "type": "String" + }, + "asyncPollPlaybookName": { + "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]", + "type": "String" + } + }, + "triggers": { + "manual": { + "type": "Request", + "kind": "Http", + "inputs": { + "schema": { + "type": "object", + "properties": { + "ip_address": { + "type": "string" + }, + "callbackData": { + "type": "object" + } + }, + "required": [ + "ip_address" + ] + } + } + } + }, + "actions": { + "Initialize_Variables": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "IpAddress", + "type": "string", + "value": "@triggerBody()?['ip_address']" + }, + { + "name": "CallbackData", + "type": "object", + "value": "@triggerBody()?['callbackData']" + }, + { + "name": "AccountId", + "type": "string" + }, + { + "name": "Token", + "type": "string" + }, + { + "name": "JobIds", + "type": "array" + }, + { + "name": "PollingResults", + "type": "array" + }, + { + "name": "EnrichmentStatusCode", + "type": "integer", + "value": 0 + } + ] + } + }, + "Call_Auth_Playbook": { + "runAfter": { + "Initialize_Variables": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "request_id": "@guid()" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT30S" + } + }, + "Parse_Auth_Response": { + "runAfter": { + "Call_Auth_Playbook": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Call_Auth_Playbook')", + "schema": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "account_id": { + "type": "string" + } + }, + "required": [ + "access_token", + "account_id" + ] + } + } + }, + "Set_Token": { + "runAfter": { + "Parse_Auth_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "Token", + "value": "@body('Parse_Auth_Response')?['access_token']" + } + }, + "Set_Account_ID": { + "runAfter": { + "Set_Token": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountId", + "value": "@body('Parse_Auth_Response')?['account_id']" + } + }, + "Get_IP_NetworkInterfaces": { + "runAfter": { + "Set_Account_ID": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "method": "POST", + "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/enrich/ip-address", + "headers": { + "Authorization": "Bearer @{variables('Token')}", + "accept": "application/json", + "Content-Type": "application/json" + }, + "body": { + "ip_address": "@{variables('IpAddress')}" + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT45S" + } + }, + "Capture_Enrichment_Status_Code": { + "runAfter": { + "Get_IP_NetworkInterfaces": [ + "Succeeded", + "Failed" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "EnrichmentStatusCode", + "value": "@outputs('Get_IP_NetworkInterfaces')['statusCode']" + } + }, + "Parse_JobIds_Response": { + "runAfter": { + "Capture_Enrichment_Status_Code": [ + "Succeeded" + ] + }, + "type": "ParseJson", + "inputs": { + "content": "@body('Get_IP_NetworkInterfaces')", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "source": { + "type": "string" + }, + "agent_id": { + "type": "string" + } + } + } + } + } + }, + "Extract_Job_IDs": { + "runAfter": { + "Parse_JobIds_Response": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "JobIds", + "value": "@body('Parse_JobIds_Response')" + } + }, + "Poll_All_Jobs": { + "runAfter": { + "Extract_Job_IDs": [ + "Succeeded" + ] + }, + "type": "Foreach", + "foreach": "@variables('JobIds')", + "actions": { + "Call_Async_Poll_Playbook": { + "type": "Http", + "inputs": { + "method": "POST", + "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "job_id": "@item()?['job_id']", + "agent_id": "@item()?['agent_id']", + "system_id": "default", + "source": "@item()?['source']", + "caller_info": { + "playbook_name": "@workflow().name", + "correlation_id": "@workflow().run.name", + "original_ip": "@variables('IpAddress')" + } + }, + "retryPolicy": { + "type": "exponential", + "count": 3, + "interval": "PT5S", + "minimumInterval": "PT5S", + "maximumInterval": "PT30S" + }, + "timeout": "PT90S" + } + }, + "Add_Poll_Result": { + "runAfter": { + "Call_Async_Poll_Playbook": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "PollingResults", + "value": { + "job_id": "@item()?['job_id']", + "poll_response": "@body('Call_Async_Poll_Playbook')", + "original_job_info": "@item()" + } + } + }, + "Add_Failed_Poll_Result": { + "runAfter": { + "Call_Async_Poll_Playbook": [ + "Failed", + "TimedOut" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "PollingResults", + "value": { + "job_id": "@item()?['job_id']", + "poll_response": { + "success": false, + "error": "Failed to poll job or timeout occurred" + }, + "original_job_info": "@item()" + } + } + } + }, + "runtimeConfiguration": { + "concurrency": { + "repetitions": 1 + } + } + }, + "Finalize_Execution": { + "runAfter": { + "Poll_All_Jobs": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ], + "Call_Auth_Playbook": [ + "Failed", + "TimedOut" + ], + "Get_IP_NetworkInterfaces": [ + "Failed", + "TimedOut" + ] + }, + "type": "Compose", + "inputs": { + "execution_completed": true, + "timestamp": "@utcNow()" + } + }, + "Return_Response": { + "runAfter": { + "Finalize_Execution": [ + "Succeeded", + "Skipped", + "Failed", + "TimedOut" + ] + }, + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))", + "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'Failed retrieving IP network interfaces data', null))", + "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'enrichment', 'success'))", + "account_id": "@variables('AccountId')", + "ip_address": "@variables('IpAddress')", + "enrichment": { + "statusCode": "@variables('EnrichmentStatusCode')", + "job_ids_count": "@length(variables('JobIds'))", + "polling_results_count": "@length(variables('PollingResults'))", + "original_jobs": "@variables('JobIds')", + "polling_results": "@variables('PollingResults')", + "raw_initial_response": "@body('Get_IP_NetworkInterfaces')" + }, + "callbackData": "@variables('CallbackData')", + "timestamp": "@utcnow()" + } + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId6'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId6')]", + "contentId": "[variables('_playbookContentId6')]", + "kind": "Playbook", + "version": "[variables('playbookVersion6')]", + "source": { + "kind": "Solution", + "name": "NetApp Ransomware Resilience", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + } + } + } + ], + "metadata": { + "title": "NetApp Ransomware Resilience Enrich IP Playbook", + "description": "This playbook enriches IP data by calling the updated NetApp Ransomware Resilience enrich IP address API endpoint and asynchronously polls multiple job results.", + "prerequisites": [ + "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly", + "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed and ensure that it is functioning correctly", + "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook", + "4. Caller must provide ip_address parameter" + ], + "postDeployment": [ + "1. Test the IP enrichment functionality with valid IP address" + ], + "lastUpdateTime": "2025-09-26T00:00:00Z", + "tags": [ + "NetApp", + "RansomwareResilience", + "Playbook", + "IP", + "Enrich", + "NetworkInterface" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId6')]", + "contentKind": "Playbook", + "displayName": "NetApp-RansomwareResilience-Enrich-IP-Playbook", + "contentProductId": "[variables('_playbookcontentProductId6')]", + "id": "[variables('_playbookcontentProductId6')]", + "version": "[variables('playbookVersion6')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "apiVersion": "2023-04-01-preview", + "location": "[parameters('workspace-location')]", + "properties": { + "version": "3.0.0", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "displayName": "NetApp Ransomware Resilience", + "publisherDisplayName": "NetApp", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.

\n

Playbooks: 6

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "contentKind": "Solution", + "contentProductId": "[variables('_solutioncontentProductId')]", + "id": "[variables('_solutioncontentProductId')]", + "icon": "\"NetApp", + "contentId": "[variables('_solutionId')]", + "parentId": "[variables('_solutionId')]", + "source": { + "kind": "Solution", + "name": "NetApp Ransomware Resilience", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "NetApp", + "email": "[variables('_email')]" + }, + "support": { + "name": "NetApp", + "email": "support@netapp.com", + "tier": "Partner", + "link": "https://support.netapp.com" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "Playbook", + "contentId": "[variables('_NetApp-RansomwareResilience-Auth-Playbook')]", + "version": "[variables('playbookVersion1')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_NetApp-RansomwareResilience_Volume_Offline_Playbook')]", + "version": "[variables('playbookVersion2')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_NetApp-RansomwareResilience_Async_Poll_Playbook')]", + "version": "[variables('playbookVersion3')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_NetApp-RansomwareResilience_Volume_Snapshot_Playbook')]", + "version": "[variables('playbookVersion4')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_NetApp-RansomwareResilience_Enrich_StorageVM_Playbook')]", + "version": "[variables('playbookVersion5')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_NetApp-RansomwareResilience_Enrich_IP_Playbook')]", + "version": "[variables('playbookVersion6')]" + } + ] + }, + "firstPublishDate": "2025-10-31", + "lastPublishDate": "2025-10-31", + "providers": [ + "NetApp" + ], + "categories": { + "domains": [ + "Security - Threat Protection", + "Storage" + ] + } + }, + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + } + ], + "outputs": {} +} diff --git a/Solutions/NetApp Ransomware Resilience/Package/testParameters.json b/Solutions/NetApp Ransomware Resilience/Package/testParameters.json new file mode 100644 index 00000000000..e55ec41a9ac --- /dev/null +++ b/Solutions/NetApp Ransomware Resilience/Package/testParameters.json @@ -0,0 +1,24 @@ +{ + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + } +} diff --git a/Solutions/NetApp Ransomware Resilience/SolutionMetadata.json b/Solutions/NetApp Ransomware Resilience/SolutionMetadata.json index 40f11fb1ab1..c07a7b46b90 100644 --- a/Solutions/NetApp Ransomware Resilience/SolutionMetadata.json +++ b/Solutions/NetApp Ransomware Resilience/SolutionMetadata.json @@ -1,11 +1,12 @@ { "id": "NetAppRansomwareResilience", "title": "NetApp Ransomware Resilience", + "description": "NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.", "publisher": "NetApp", "publisherId": "netapp1234567890", "offerId": "azure-sentinel-solution-netapprrs", - "firstPublishDate": "2025-10-31", - "lastPublishDate": "2025-10-31", + "firstPublishDate": "2026-02-16", + "lastPublishDate": "2026-02-16", "providers": [ "NetApp" ], From 767a463b159c0ec28c3f30107b4e69817d85ac9f Mon Sep 17 00:00:00 2001 From: Avinash Bharti Date: Mon, 16 Feb 2026 22:34:12 +0530 Subject: [PATCH 19/22] url fix --- .../NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json index 6a5a8f59699..0447e4c5d59 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json @@ -249,7 +249,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "https://staging-netapp-cloud-account.auth0.com/oauth/token", + "uri": "https://netapp-cloud-account.auth0.com/oauth/token", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, From 44264b95b11bc36517f13e4bf92ef83be8fa57d9 Mon Sep 17 00:00:00 2001 From: Avinash Bharti Date: Tue, 17 Feb 2026 09:03:58 +0530 Subject: [PATCH 20/22] updated the package --- .../Package/3.0.0.zip | Bin 12876 -> 12874 bytes .../Package/mainTemplate.json | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip b/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip index 967e01fec0b5ca429329b81be720996219268ad1..7acabd5688aa2f5342255b79a3eabad3189ddfef 100644 GIT binary patch delta 8533 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 P9Fq_-HU_XU00000;XaYh delta 8544 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

wlSTl8MbUU&_Rgr&W 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 Date: Thu, 19 Feb 2026 09:00:45 +0530 Subject: [PATCH 21/22] added arm-ttk fix --- .../Package/3.0.0.zip | Bin 12874 -> 12876 bytes .../Package/mainTemplate.json | 16 ++++++++-------- .../azuredeploy.json | 2 +- .../azuredeploy.json | 4 ++-- .../azuredeploy.json | 6 +++--- .../azuredeploy.json | 4 ++-- .../azuredeploy.json | 6 +++--- .../azuredeploy.json | 6 +++--- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip b/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip index 7acabd5688aa2f5342255b79a3eabad3189ddfef..76e887a5382c42b01988ce8acdd11627fc6f4304 100644 GIT binary patch delta 11208 zcmV;(D>u~2WXxm@P)h>@6aWAK2mohBQ?U(71`=mRQ(TPRwEi|L007i80ss*JlOZw_ zf9-vHbK^F$@Bi~DP&)TUc9mq=@?%e?lI(bACW*82aE&LkRd;4eOG}W%m?F6#Xpc9? zRp+yuk9I!Etp*4_K?0;miI(Z45?jKv(cS270Kfk88A84P<4u=%W%Qn--jY(+dp;WR zPYzawZ7lE#+w{Qrw@>iF)L8}Jd86^+f6@2D!;|6R(P)NU%ejYgAMwhy42lo_@ErR; zdIM;G>ev+9^b;nY>DbWC(ZM17!@pi(YRn7@{r~w4A%uE{PnQmXg6}XrcU?3@p6|L2 zp)YJq4cCQnu*$6U6?E)D@hivjsp;5=2E#yehoGR54~FeIt2={W^Z|ROWnz1Ze|ygm zdSJtF4PvY?#l(vSVmVU-+6zBHs7LQz41IZ&nD!zV1x&-V-(Y(|m%ZocDExGW=Z0_5 zPln~QTAvB_9G^__FU0ZPz5N5x#n)I%X@UeTc~fG#!Ek!-9EyAo&j#q)r^v>5hG&R6 z$Td6<8Dur2^afGvQS{F@K^McTf2HGFv*A034*!OSzZzsVb!K?>&jW=1fstu@6dN;W z711R||Gaa^jprIuJQRccC%Rjj(>l40M3DliGd;ye_MD8zx4+Z zqwMv?_x=6-uZl^>=bAsKT<+4D>pw(a$Tn7-_un`RbZ#5gJvFBux?5s`(OYv$9M73k zbcJnd+Sq~x^)U6_)Eq+LxHX7rTw6FM8+c`y78`1=Xima1pTh?B`s~C0zF_#?L@dNR zW5woPD6i>CF|BeO>J)@}f8zU#8GOaZb~HXdIX(N!e|~?+)!EPs=06mrhrA#mUZx}7 zP<$fMH?i69!4IRsM`ItJ`*b}$GM4Ss#92urd0Fs!D?5G%|$5l*DIIapA%x- zvsOX1@AW@_jg@qR%E4+J1xh~s^-I1JT+EKD&0gM4e45!3l2M9!e?sstW_$fmC=T8@ z3v)UGxt&|io!1{AMf=$f1mUh+JO!>kiff{{{s^^0e}B*)MPs{`YY@Aa?y1H}KMr!^*@9Lrzf$@}@-GHpE3)E~Lk zG&D(3mzp{yuZcYE^8We{Jf$)9^5;XodKs(K%XnSl$XhH_e>7vMq8ZnwXvR8I!RaBl*&Ls*={z_2(^bvrt@5rQ&*8o4B6pi0f$!#r0HE zTu)mouBU2oO-)jR`z|ia%4xht2?0%YR8lfywev;tBTOZdXKPGR-dLe5o=Ii#tTtIZ z(~-rq7Rut8rYxSdRu<3HlamW1e`hw~%-PY~!T@E+Pu|ES&aFAa#2W>q5-cs^{%{KE znz6%$@!|NGpLPyif^SWH7nOw5mOM$#gn}c1O&&1zK1+E&JS$7on_(B*Gw;0}(t>^b z8GobLh9O5$+&#G(C?-%r1b2Y?1%fO%&zRmA3)W8F`bP(5U&Cp+#Bnj9e`f5QNp{Yq zeQS)Q(XRB|vg`>?tSRY%X6}N+ai%lp=ghEwAvhouq<}NsYmBA@8x+q3SBW2f zlo|e&97yl)`2G`2sV<5{f5*)qu5NDA>N9=#Z_Xm^T?cKvr9tov{T<&UHY=cvM;(F- z??3?MW^fW}SYA2mNzU;zl=E~cCqGwTmptO~13L{jEGs(gFE`bfKr6nL=1�VPKuC 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 diff --git a/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json index 23cc20601ac..d4806430fc4 100644 --- a/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json +++ b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json @@ -643,7 +643,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -859,7 +859,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -1214,7 +1214,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -1731,7 +1731,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -1947,7 +1947,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -2268,7 +2268,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -2686,7 +2686,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -2854,7 +2854,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json index 33c5b6dcaab..f5ebed7bc79 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Manual-IP-to-Offline-Playbook/azuredeploy.json @@ -412,7 +412,7 @@ }, "PlaybookUrl": { "type": "string", - "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('PlaybookName'), 'manual'), '2019-05-01').value]" } } } diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json index 8aa162bfd29..b6219cd3d9d 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json @@ -178,7 +178,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -475,7 +475,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('PlaybookName'), 'manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json index 357620be3d9..0902075cbbc 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json @@ -155,7 +155,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -324,7 +324,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -472,7 +472,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('PlaybookName'), 'manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json index 2c8fc685b17..d827c321548 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json @@ -147,7 +147,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -370,7 +370,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('PlaybookName'), 'manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json index a514788e8bc..86cbc4eea20 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json @@ -185,7 +185,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -402,7 +402,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -540,7 +540,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('PlaybookName'), 'manual'), '2019-05-01').value]" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json index 3dbbe4c39d1..73f046f9936 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json @@ -185,7 +185,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAuthPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -401,7 +401,7 @@ "type": "Http", "inputs": { "method": "POST", - "uri": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')), '/triggers/manual'), '2019-05-01').value]", + "uri": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]", "headers": { "Content-Type": "application/json" }, @@ -535,7 +535,7 @@ }, "TriggerUrl": { "type": "string", - "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '/triggers/manual'), '2019-05-01').value]" + "value": "[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('PlaybookName'), 'manual'), '2019-05-01').value]" } } } \ No newline at end of file From 7bbce68f325219e40908798145a573c46f1235c9 Mon Sep 17 00:00:00 2001 From: Avinash Bharti Date: Tue, 3 Mar 2026 21:17:24 +0530 Subject: [PATCH 22/22] set smaller names for the playbooks less than 64 chars. --- .../Package/3.0.0.zip | Bin 12876 -> 12880 bytes .../Package/mainTemplate.json | 52 +++++++++--------- .../README.md | 2 +- .../azuredeploy.json | 2 +- .../azuredeploy.parameters.json | 2 +- .../README.md | 2 +- .../azuredeploy.json | 4 +- .../azuredeploy.parameters.json | 4 +- .../README.md | 2 +- .../azuredeploy.json | 6 +- .../azuredeploy.parameters.json | 6 +- .../README.md | 2 +- .../azuredeploy.json | 4 +- .../azuredeploy.parameters.json | 4 +- .../README.md | 2 +- .../azuredeploy.json | 6 +- .../azuredeploy.parameters.json | 6 +- .../README.md | 2 +- .../azuredeploy.json | 6 +- .../azuredeploy.parameters.json | 6 +- .../Playbooks/README.md | 12 ++-- 21 files changed, 66 insertions(+), 66 deletions(-) diff --git a/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip b/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip index 76e887a5382c42b01988ce8acdd11627fc6f4304..b1ae890f2565545468a2116a39db1ad8af741c5e 100644 GIT binary patch delta 11258 zcmV@6aWAK2msonW3dfN27lV4V_X--VM{tI008PT0ss*J003=a zX>L?yZE$R1bY(7Tb8l|#ef@IdHnQ*k^AsqZdn3C_vTXTdPo|RWcxNVwv-9B^PiCv` z%#@avAc-+Wa!Jr0Z;q?Zvz$jePjagPf&@vB04Y+UWjd+Emhjo=Zge+*U;p_Gq2B-T zr+-VlGJ4NZZ%K&jKOc?QCkHFTHWqk=ZE|4zJMi$q)LDh!`J?gS(f7l{li}gfXog+O zxrcHe@yfLff)D=i9s56e189Hh*aX|;6ZU-5v7wuzgG2a-eZ9iOm>C56|MM9_2=$DB zEFBLDzQg3)bxGs!?R)40gub^WeieEWaKupI*Bpe2sJ01!f`C!<- zv$``pj6PuBv`lPIaqk&I4|Eu=;TbDTu;<4Ev7D&^?M0s;)FbyUhQ55_nf4+a1x&-V z-(Y(|mc8fbDEf4U=SEzN&nMC+G^>#I&&m3+iJMxT!fr!f|VOrg3dyK{oKpFn=vN)LhY= zL}fll4ea&lhy8ud@VyCNhx*>W@e}^!Eq- zQ9On#JPkaP++WzfxmXf^)E}s74_#~69|X4fuK+Xcu_ugMLc0F`zJD(ma@m~MBKS1n1dRk-h z$+3bJp1hyWEz`ymO@IB7TTMfg6m_YoQ}UX~(=P9?|G-lssFyz<^3}^&rC!GC5=Y)* zp`sZ}70tLdMKjh>G~*U38W^~a;E!7?_+z!;rzTm%d*}YWJ)K-SmZdGrvMM@qoYR%A z3`?r#3+1s&D38~frM$I5fjpK9PgT--y8gW7Z5E2_ zsZ?A~YZKQ~9e;5>ZK1fHYKrS=YsK|cEv~6aYH;7hWm!2DYm^YsR7WKxQ>dLUl4mNB zJX>Rm^2Q2f@k}a zZ5VPK#od#ufnov`L~sYFUm(bw^Ni_@v7qhbt$%!A_BEQ8>p3p=h$);i$KfAvg}?6o3=lYmBBIHVB?^9^yaj;4=Cv zIgsAp@%<;5NnM1950^h&-Q1>?W%{V!oW;7j4u9JCOT)u6^mlxZ=&XP;K5;x;c;f*m zH-mFe!}7~fPjYIXp`5QvIr%C2y5!+k9q8G&VOjCnez~c>1X{6;Gk>a}`$Ah}&0(|d z(8Vj|eHC!Nm*vYi9MH<;+uZBO{~b zUVl2a%`UC*n-!lUg>{4PZ=np>V4^6BTZLfyM{Q4|HixIl7Ds+?9nl3WdL(|Zw|^l1 zc`+NHzF>vL7R5jC^@!^O+KOCJKy|kN&dy!aAMyEQRY-4=9kZ~pieE}9XYH_|X~UUe zLjC96>Vi{V`)gsdk?ojcZ{=4_9n@Dnsecz}ksOt1qGkCnYmM`tT$zg(nRDofu32nz zM^$9D_g{vGN7<4Q{SpKeH+t!=k}$mWH=`T_HTvGa38Y^j)SDYC)1nt>&NJ;MX5tgW zo*7=ow8>~XMqF$gp|b0J{+tpy{$+M1aDmH)WuN`*c&{P@wf7v&4a>*H#ZCX_wSPVJ z?zsw7SK)?lq9@`7`L(W`IeCRGObzm!l73X?0|wg}6pQ`JxQE60{xG-c57)*N%v8rS z|7|FyU`(gj_b(mGoU%nvSmoIZQouE3cB}HjGVk)hte(t#Nnn|3-&b~ZdbQ!JUF`QnUv{jU-l$uGpQ+X^d=kZMmtx1D_>%rj17-iPA?SDSp$I zDP9nrk0&SYR|T4fFHv}9T7O@|NJmCIbFnBK*UGR1!_pbi2TTuVr6fq~X}=QU=9e;U zH=ytN@;U^5;*5}AM$MIpvZ1Lpp?b8qY&PCqSX@eYv1iwuEFGVO8n52IpH&=J)QeNV zW<@-XCZ8PG3)1;87dAaSbvCsFC8kY3!E>|RI||+uRZP@jb8kTZFpAt`-h8{&dPOc zY?Hmd5JGquG25ve-wc#Ykb9;P74`!Ad`_@eytZk+%9;a0;j3UerEhQZm*8vOL~}W? zW7yU(EDxR3&a|QPtA9{kr8zbdf{tsSBG-!XqFPz@*N-1BCm)>~Y)`nAR}0%F#9(_o zyS_mhujJ+XtB*xX8F;4Xz_1tR!>Q#2vthV?2N1qEq&^IdWQ+(x+d{)V3!Y(Zn|4)e(aP{!3>DJ&zA1M|gEIJh=C3@poa*?BsC5Bp3Fa zkY%&WOLP59PPyGi|@klaSy zO|3|)GGe0_uZiNsxk`bX8^w|#8Y0>29!&%!C0(x_$d|NvsT-o{rS45BjlC#3&8`Vu zVei%ia)sf~+HE-=fN$T0s3t^484)JNA}1ESG-oqx4}UrMP;?uKbGGb8QheEI1LwS{ zOCK9N?w!?o&YOMeQ{t*$t4u$!d_#)XX5r6R>CUkS7UfmR zWXaCBvQ?$fNYW;_Ymj>Cm?(2w?Zr!2n@M4wjmG=uPtuBSUTOf(Nqd)2D2WZHWpPHR zmw&3qC?Aa!ZjXWRX^$dA^Q&bTxyXR23dE#7aewd9@Q95)c_GWRZxRQ;tnoreUU9wQ zSBrBU*aIgY8QFI}%4Y^blm!{~423Gu zPrW@rKC_8^csT^GWeOYRBlD4Iv-d|Kj~}Gx<$Bn|{|Zdsga?(`EvI*MfIbzFn{WN8rS1iQpX?_tr#;V=>ugsnWuTPXvk z=Q=(~Ty2)k_;+^(j}U=!+S6uNl{mp84vvQVcQQp3>@HM57Afv@-XpC zd}~WyT4E+G^wuW z?Ufwp+BI!2UX@cz!d&T#nI+!y_N34PvhihbJyXLpt5+>yG0HHRA0uplfG*j=283Fq zPS^kjYc>o4L3bZOAi+?Yo2KicOT-J^zrYGa=@Wbul6u%MsOtgAEkj1$!hidb1q&u_ zx?i8F(=Bui0l{lydh;sJG^zNMMW=7D;mY)R?Kl=TY(=M)U+K^|yN73rD}o93)MY2_ z$Yg^H1D)CzxhJBYzl87Gstl3dJ*mk ze}k)g^r{}`C&j(^!TM7>2Y-&-+|0NDG(RzBkZx{fk;pbbwU?rf)|{Tkj$AlBabMT~ zS4KE<q)qdwV_4Xq;=MHSVPoun9Z;;M{iY{LZzH#h?!P(LZDWPs zoa<_;v*B?8gDRgDtfw1tQM%Zx`GQ-qbxrarxDGGoUB#~&G$(7?1b;7bF2YD=dssA; z@=roa`NW{-C*XmL(EDq?fXT7Yp49WO&z~*RCwv$E-Lv#=oQ}Bbo;r#v6FnKAK6CH; zsVl1c2bALqZ}zwTT@Dxt*qfO4+)?}VJXk-8UXF4~@9iJZ&s46e<9XPk^Wv{xgciKO z)@lX3JnTpBXBL4u+kY$GV=Ivl?gib`OV&y%a>>Bo*wa%}a+xSmf!a#F=jgbw6evCq zE+&DXd_27>ZgXYY<|%-sSx{hA_DY)SR-0Q;#@{|}0Jc4XgLl#ON zIyqOq%6k`Sbbs&O->~6f4<*J!g|ok}c)G51R0?ae#|4{paKv-S-V0&E{Dh#;bV{Bl zChCW=Bvp0sSTIqaN4xt4u1n{hY{@-&X}Bct@FWgfO<3G&62ft;t3h)Vv!)^~q}k7g zX+4tdvt(3I*h!s$KsS4RDJ228Dn?JKYd2;4w!ji~dVj78e%nDWHfQD9>&X7$TyNuE z3FU*0_geIj`0?G{sTLfp#|DQSbQ5+SR+CdKS3x`ER;f-8b6hG3U8rNl1h+P)iZAGd zA1AJF4kUPFw-!=;=2~(!)fZAq+ImYoy_sChCs#`+ux1l_VW7Sx6}V)33wtroUr+qa z^)RJ#@qdgAdNFm4yIJ^O0c6=!g*{QyPhvMX6mAy$z*URFB3~OiFI4F0klFVs#CNa(@xo?c5NNzeZW-nn;OY?wZ#{beu4a zsA|$3t|UCUan;yl)M-U0ysB=5JG(u{CWfo7Q0CT5EjMTCyFEi&ay)Zk+J-gJiH@(e z1*n)!KZ;!`lC2-jE+5gZ9M!HE+1_>_gL!3iZ>TZwDR;iM=PA+j0Y&)U(Jt0|Vb1rM zjeoHh?y&r7PIecKBhqjyydO;gb_?-RkF4eZfl}Y=|M{ioLp|UB66NScU%~((eDtOF z^ZCV_*RQ_x;B)MGj>kTR24keCIXxgij)#c3f?opirT5U^&k^AZM~2iil|5 z_Ld!WNNAIAIT7V1;D>>}>WvD0l>! z0q3nvcRh+3mcCHg{Fo{ooz^t04eTlf0)@G3PNvSvg+%YO+-&gi2+S4siLr92E(yr= z9axKXW%(e1SLZRPR1G~gd3t=gMW`j?csa&Q@}6Gx-D%`O8pdWb?7#Q0K1Vp)o+RB3fqFTDl3x^ z(_SDJ-9h0^QWUJN||Se9xXe1BprTCq9wf!wX3G9xcQriB`(uOwt74C>H#YFl3S zpa){K7ZpRaJ$VncWQK`h(nFX$KHBgC7S1M=jLMIpDIN~oMp7=cY2P|G)P85% zmE^#iZ6O$*Y42rMPo+nNpfl}6Jlv2XcWE&bHP9IYCh-r10g4e0dSOFYihsbqv7I|x zt1rQ=NU(3R{pxF#!c9u_A>wtYZg^)rEW60VYA9#hE+wFPY8h?D4QI5;pc|J*RUbE= z(I&5lE~8CcrpsuPo?x-&X)L1+vl~zvAH7sY8+hvl`E0_DQnq^Fg8>gn$^lKwF)Kz? zmOLCwCU=2MDh?fqVOjSSdwtdghvR)e@HBu4Jw`?lRXj znz<%UX0iKOYZAQFs;o7Qq!j5g)@&_fO_y&aNslhyN)FAsd@ET-?eeX3`Br!*U1E~Q zi{hZX(w_|LQW_D1M#ev^eyQY5?9nP{e#cUrgGf$RDN@= z!^?EdNHCldY$mf#yA#+v?yN7m#>>tjEq7U8a(=q3FY9G}X(dE{%d(fW11n$lRHPB8 z{7~OUu)FZKyMIH<&(Yt%yxtN}{vXcuh&?CxE87TuOq6BrP=Ej7JLWVezYSkbJbcGp z&*aw;>d?b?kq4J*KEf1wXcU%T#ri_FkB7}7?r#Ege%wmX`J+P6`2v!`^AIN>N`Rko z>WbZloFuhYZB}Pm3+~V^q~mgBb|D#A5>J~NS=9P)6@T)$Ww+L~9IQ^!%GQ)GfISAB zym1`2_BCt;I@0epF)dAG;ob|!lfx=RB1wI%tKVO~e0_B#Jod~j8o$8JdFP%i&cLyB z8fH(uX}b##8w7jl2aYrj2xW!OQ}H!;(3MXc%UqeoD5lYdcyy?{y_~(x<=pkaK`-p7 zN3Vh~Jbxz^1=TbFqPj|fFNG3XIw~6lD69F5N+2k}`d044`T}1>cO`(fhSaYG(Ay~L zYq57h3qNfSqby$R20V?*-bUL%LdUHK2`%(QbjYdekyKZRp{>${MwIB<_Gm*LtG3c6 zr+rYAiJzs&rRB9$U-(}QduHK;H9Z0Fj=;m)Wq$z;Y&T7Ox1Hk@X6!bq1T;L^k~|>O zFtzCc1?7sF{Ap+--Sb|xKB}Mb{$ZE|U|HWWDmTG%n%?(j*SjFePnkqNWm0TtrM}Tg zfl@XJN;YLj#7_gg>S3Hg1#hpD1w|tXOgm}7K@;ntL36oK6lWaj07k4A{)XoOOZ@>{ zihnZB1XNa=51N`ZEE`$%TD-wMlnfYF>N1q(^7jIp2B3PZT5s+3RV0F_rsiu2#D-fm z&3IAQNl7ZW`@~bbZ9fHCS?#B<|J$7atn|FKb$)}nziJc%t?)G!K;PH)L$ndO^4W2vKJu;ya)`g$@=MH!SU3x5v9^_=8xz~Nz##+xSz)TH1{=`@kNx|hA9 zFMMAd;HiB}&fkSBg~Vx^aJ|<64XrE0WyQFRAeXW9lEQp)_@Bxp))(is1zKbG(iQ52 zShM6r8v7mx`-Yc`A$Ts$O5_9t5)_58DUFua(-F03iQ4o8i~LUv{!k;;ROXynr+>lq zRZqRjrxpH!Es(VBmfa#6dQ2!YNA| zenksyH?Sf*tY6AD9oFxbuzt6UW_jF7G|NKNmwFyuUK*Z{nWn4{$bYb97|C>wzk&F! zr7XiZH0AYtM5ZDwwB1Oc2o$yPU|@s|U zAxu)0*Ooy?kx)c}#MWyie7(pRPaU$3Qt*2fWnXq8!B)Ub^0oSkPj5L5N3D>-h z1s)OO1`qwb+g^2|$bX9w0jf9@n38HAWus8@I=+o~1eti*$PWh;&l<&}#610hET1d1I$nY_2oh2iJ!Y=9r z1iIPl%SqYa=NOjIWL;Y++q4CysMBp#aNG{Muz5?@UN^RKW`FRt9M}kVV6(keO-bF( zn>*D)gY{V81n}h8X;@7zv0Ml3kW-~PJIryYBy{QPWJs>Kpc8(WxV}Y@;E~;0NcD+p z$<YbgqfInHO4(O-3#3PK^kwx)JW|_8glSDrm=&cV=q2 zH&fr;8QPNLnG1?`trH+$YYS*o>Zaq?r*2XtTiR|QgMWEtbZ@9J@+o(|b}-(Vx4*VI z;<=sJ;~$DxStFgs*t8pb%C?cvW6csPR|7i~v(mhcpA)r85T>q7!5=UQygCn@AHn0J=pwiFsSp!s79(djWlsZW2$yQT+_HJ3!+kH>U`NQVy5?Am~$a>bm;BM zFUiKq4SylwbC||CO8Bf_l@pR;d7T^{4Ul{cssn1pIJBxK#&UXim>P>RS~P$lpfu}s ze)*%4<;O6#aX2>piidng%ChkDsNZ4421xIPVbAt#his9l_Xj9v02}7$ywvSmWo5;+ zuPAH5wiQ$VJc(Au(j@>EFW}Hb&|Cf1Xs@s_7;l~3iQ;e09?px*L0;U|sfQ_1V0%cl~T>GG+h zCs?d`8q24`3%h6GHVgEGN~|u%xS&Fb#Jl4S&mN zmxiU$G%T-e&zvrYa99f(+^6>#{GjGciHr!k1wN z!}E;$rbotN3}Bdc5cyH*4kEvU$bYBBI*9xZBL8UtQFajdv}gyBpFfTcBEN&k?;!Fs zuW&nv{1&ZY%OUcA!DJHogcC(D@oB^3|MGfE==hj=#vCO7uRJF9W3mQ^4SM)43N0l| z#GpVA?Sj^?8yvqg%Qt`zABSt|#fO(Fq$h?AUosRX!-mh2u~A(3sHgg2;eT@(Z3o>p z*{ap&wy`j7vEm|lrQxuZJ0&RL3dU(mfwhhVj(pkBVzovv?&VRR)@P!?X$^qJX0j)9*$=?+{B;PU`np8v|n=n;ok`A{^ zGKM1OK`{npRViLq7J*3S0>ubNU$>6D-y|jR737Ef!^8(U(FvV%t6TBfAZTgs$%q>`bMw zjaW-jJ0iHzBLyzn1b<-Au^cdn-vrnQNDyDL*!0WC36c-2GB(h0d$55DAP|_Sb>Ki9 zIFQmRsTmxo0G^{dI?!o#bf9$A5_Z+DpaY$C=s=r52fDc2eORCbE42|8=;E@&1KI^V zppt1n8>b(1I;2^UHbq4WGYX)p9imc)sMH}Ub%;uFi4IYzb$^ITIX7gaNiiCkkv#iG z2Ncz2peWOw7_*sIGTUi~*p#4LLBS4+X;V;47w&nu92ri?nNK9gdQubcdtV;V98!9gb3mqx5JVY!{FWuJSnnQMS@yF7ZY? z%%w!x4s$8lOMi#C)L|~^_&*)yQv28N5nwJ|Tu$C$0wx(X2%%4S>YyXeVT!+n>?xPP=mC{?e&5zm+sP+*gbS2dXI zdHQgN+%e_(U5+o7B1&DDRB(1TIkzlmzlH_Oa>VwQ?q|ot#x#5DI4U>~3#1;AGfEfi z8_G)-v=EDc!mX$YC9=lJoW9Sf%XZ~_$L$<_$uEwrbN*Gr0bSDr)Curvc!J4&yY~XD z2zm>HeSg+hO*Xj$3H61PVe0);$lk}V0rvEFU7=U@nNFW&&H-yV3#{)vkhbJ_<^mwY zCMJWCkbCfJ?(oWUNnJ<3lC!Vx@RxV`D?9!boqrv2CV~Lp7q?dJg!guESPtlk`h)mM<=m&6+@F)W(iNE^nURTZ3Ot-J;3~!L}B`nR(Ct zqzHeRA4w@214q}i7vN)q+h5pdGD4uyxPR#9`lV0JhY{`0P4IRIsodpOb0-no?x-&X&Qi90BWp; zJbiJwHt6)lB?_&k1nx8iDW;%7OV6>Lz_;#c^xQ|Qz#^t=VH!sdckf4vQe8X(ihp|t zc1XcE)*8X_W^l4kAvD#Udj7W8caPZgN5`iv=M9i_qB zbAxNk^q1IsC99w4Ahv6MB`azL{(s>9^n*`4$6ovd+U@xdqwp_uNmU;5@Em(^d=J~o z+_5a@4tCaS3>SBiY5PR5eYkKw|6%0*^u_+c{po-I`+v{}x-f|X=m!HWJv{&MOJp)G zOtK8F>BGo#0Ig*IjXc{C@h~2(44+_c#L4WB*d+h&_%J3D{1Fjq^g&SF2Y;*Cm)=j| zCy0LZ!^rq4G1!kw>|wMr?!nZ^j?%a>4p#oi4@br4c3# zip6YZ;pn`$U9$ABL40I@{D1n~REqO%+?t+agNfnCqvPzvm7_24)LC3AkFpf7l#};M z@25A|@NBdKS{T=GWh7E2h_eQz@P8q_CZiRbIa68l5o^VqQLqCP$a}s9=R-&rR4Z`Z znp37>elS-HS)}m$d``cJZZ$41bIK_=W2z`2I@| z-I+78{P9cgFQ;F6Xo*3+hkyN~w*lvF?s;*N{2J2GLvhHVe5j#xh(R>Hq#=bOA6`3z zAod~;8R&JR2oV&921>c1`b&q@F}ai0Opf_XLMGE1W_Q}Q*GAU%G(;b%*@`Yb zhg!LrlLekLO{9)M5AM@O9$`(#OUjHy&@-h%FN8vX$v-@Mc=rDRP)h*<6ay3h000O8 k+M{EW!7)M(+M{D!7sX*qIx7GG>N1lNGBpOaF#rGn00b)P3;+NC delta 11254 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 diff --git a/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json index d4806430fc4..7071525f549 100644 --- a/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json +++ b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json @@ -100,14 +100,14 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetApp-RansomwareResilience-Auth-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Auth Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion1')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the Logic App playbook to be created" } @@ -464,7 +464,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId1')]", "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Auth-Playbook", + "displayName": "NetApp-RansomwareResilience-Auth", "contentProductId": "[variables('_playbookcontentProductId1')]", "id": "[variables('_playbookcontentProductId1')]", "version": "[variables('playbookVersion1')]" @@ -479,28 +479,28 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetApp-RansomwareResilience-Volume-Offline-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Volume-Offline Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion2')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Volume-Offline-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Offline", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the NetApp Ransomware Resilience async poll playbook" } @@ -1042,7 +1042,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId2')]", "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Volume-Offline-Playbook", + "displayName": "NetApp-RansomwareResilience-Volume-Offline", "contentProductId": "[variables('_playbookcontentProductId2')]", "id": "[variables('_playbookcontentProductId2')]", "version": "[variables('playbookVersion2')]" @@ -1057,21 +1057,21 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetApp-RansomwareResilience-Async-Poll-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Async-Poll Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion3')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } @@ -1552,7 +1552,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId3')]", "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "displayName": "NetApp-RansomwareResilience-Async-Poll", "contentProductId": "[variables('_playbookcontentProductId3')]", "id": "[variables('_playbookcontentProductId3')]", "version": "[variables('playbookVersion3')]" @@ -1567,28 +1567,28 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Volume-Snapshot Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion4')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the NetApp Ransomware Resilience async poll playbook" } @@ -2126,7 +2126,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId4')]", "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", + "displayName": "NetApp-RansomwareResilience-Volume-Snapshot", "contentProductId": "[variables('_playbookcontentProductId4')]", "id": "[variables('_playbookcontentProductId4')]", "version": "[variables('playbookVersion4')]" @@ -2141,21 +2141,21 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Enrich-StorageVM Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion5')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "defaultValue": "NetApp-RansomwareResilience-Enrich-StorageVM", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } @@ -2538,7 +2538,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId5')]", "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "displayName": "NetApp-RansomwareResilience-Enrich-StorageVM", "contentProductId": "[variables('_playbookcontentProductId5')]", "id": "[variables('_playbookcontentProductId5')]", "version": "[variables('playbookVersion5')]" @@ -2553,28 +2553,28 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NetApp-RansomwareResilience-Enrich-IP-Playbook Playbook with template version 3.0.0", + "description": "NetApp-RansomwareResilience-Enrich-IP Playbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion6')]", "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Enrich-IP-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Enrich-IP", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the NetApp Ransomware Resilience async poll playbook" } @@ -3051,7 +3051,7 @@ "contentSchemaVersion": "3.0.0", "contentId": "[variables('_playbookContentId6')]", "contentKind": "Playbook", - "displayName": "NetApp-RansomwareResilience-Enrich-IP-Playbook", + "displayName": "NetApp-RansomwareResilience-Enrich-IP", "contentProductId": "[variables('_playbookcontentProductId6')]", "id": "[variables('_playbookcontentProductId6')]", "version": "[variables('playbookVersion6')]" diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md index 5ad7e7103ae..23b521bab7f 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/README.md @@ -1,4 +1,4 @@ -# NetApp Ransomware Resilience Authentication Playbook +# NetApp-RansomwareResilience-Auth ## Overview This playbook provides authentication services for all NetApp Ransomware Resilience playbooks. It creates and manages a shared Azure Key Vault that securely stores your NetApp API credentials and handles OAuth2 token generation. diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json index 0447e4c5d59..530cc8144c7 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json @@ -31,7 +31,7 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the Logic App playbook to be created" } diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json index dc2540234df..605dc475a26 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.parameters.json @@ -3,7 +3,7 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetApp-RansomwareResilience-Auth-Playbook" + "value": "NetApp-RansomwareResilience-Auth" }, "KeyVaultName": { "value": "[concat('rrskv', uniqueString(resourceGroup().id))]" diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md index 60902235271..4b539fef41e 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/README.md @@ -1,4 +1,4 @@ -# NetApp Ransomware Resilience Async Poll Playbook +# NetApp-RansomwareResilience-Async-Poll ## Overview This playbook monitors the status of asynchronous NetApp operations by polling job status until completion or timeout. It acts as a helper playbook for operations that take time to complete. diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json index b6219cd3d9d..897d1325d86 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json @@ -31,14 +31,14 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json index 79d957eda11..627245456a3 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.parameters.json @@ -3,10 +3,10 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" + "value": "NetApp-RansomwareResilience-Async-Poll" }, "NetAppRansomwareResilienceAuthPlaybookName": { - "value": "NetApp-RansomwareResilience-Auth-Playbook" + "value": "NetApp-RansomwareResilience-Auth" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md index 76fa0394497..196e83f2181 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md @@ -1,4 +1,4 @@ -# NetApp Ransomware Resilience Enrich IP Playbook +# NetApp-RansomwareResilience-Enrich-IP ## Overview This playbook enriches IP address information by retrieving detailed network interface data from the NetApp Ransomware Resilience API. It helps you investigate network-related security incidents by providing context about storage network interfaces. diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json index 0902075cbbc..68e19f91438 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json @@ -32,21 +32,21 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Enrich-IP-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Enrich-IP", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the NetApp Ransomware Resilience async poll playbook" } diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json index 317f473b6ae..0ff758d73aa 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.parameters.json @@ -3,13 +3,13 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetApp-RansomwareResilience_Enrich_IP_Playbook" + "value": "NetApp-RansomwareResilience-Enrich-IP" }, "NetAppRansomwareResilienceAuthPlaybookName": { - "value": "NetApp-RansomwareResilience-Auth-Playbook" + "value": "NetApp-RansomwareResilience-Auth" }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { - "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" + "value": "NetApp-RansomwareResilience-Async-Poll" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md index c02fb746779..48f406844cd 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md @@ -1,4 +1,4 @@ -# NetApp Ransomware Resilience Enrich StorageVM Playbook +# NetApp-RansomwareResilience-Enrich-StorageVM ## Overview This playbook enriches storage information by retrieving detailed configuration and status data for NetApp Storage Virtual Machines (SVMs). It provides valuable context when investigating incidents involving your NetApp storage infrastructure. diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json index d827c321548..db2df9092ba 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json @@ -30,14 +30,14 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook", + "defaultValue": "NetApp-RansomwareResilience-Enrich-StorageVM", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json index dab75f5b6b6..f59f902aa1e 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.parameters.json @@ -3,10 +3,10 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook" + "value": "NetApp-RansomwareResilience-Enrich-StorageVM" }, "NetAppRansomwareResilienceAuthPlaybookName": { - "value": "NetApp-RansomwareResilience-Auth-Playbook" + "value": "NetApp-RansomwareResilience-Auth" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md index c1c228066bd..64a508265e6 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md @@ -1,4 +1,4 @@ -# NetApp Ransomware Resilience Volume Offline Playbook +# NetApp-RansomwareResilience-Volume-Offline ## Overview This playbook takes NetApp volumes offline to immediately stop access and prevent further damage during a security incident. Taking a volume offline is a protective action that isolates compromised or at-risk storage. diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json index 86cbc4eea20..24fa0b277fb 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json @@ -31,21 +31,21 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Volume-Offline-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Offline", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the NetApp Ransomware Resilience async poll playbook" } diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json index 82ba2572cd5..32b8f20bad9 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.parameters.json @@ -3,13 +3,13 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetApp-RansomwareResilience_Volume_Offline_Playbook" + "value": "NetApp-RansomwareResilience-Volume-Offline" }, "NetAppRansomwareResilienceAuthPlaybookName": { - "value": "NetApp-RansomwareResilience-Auth-Playbook" + "value": "NetApp-RansomwareResilience-Auth" }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { - "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" + "value": "NetApp-RansomwareResilience-Async-Poll" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md index a922da87cbc..7a05b9774fd 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md @@ -1,4 +1,4 @@ -# NetApp Ransomware Resilience Volume Snapshot Playbook +# NetApp-RansomwareResilience-Volume-Snapshot ## Overview This playbook creates point-in-time snapshots of NetApp volumes to protect your data. When responding to a security incident, snapshots provide a clean recovery point and preserve evidence for investigation. diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json index 73f046f9936..b19c8c7f3c4 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json @@ -31,21 +31,21 @@ "parameters": { "PlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot", "metadata": { "description": "Name of the Logic App/Playbook" } }, "NetAppRansomwareResilienceAuthPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Auth-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Auth", "metadata": { "description": "Name of the NetApp Ransomware Resilience authentication playbook" } }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { "type": "String", - "defaultValue": "NetApp-RansomwareResilience-Async-Poll-Playbook", + "defaultValue": "NetApp-RansomwareResilience-Async-Poll", "metadata": { "description": "Name of the NetApp Ransomware Resilience async poll playbook" } diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json index 93118e8ef62..92f2c12a165 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.parameters.json @@ -3,13 +3,13 @@ "contentVersion": "1.0.0.0", "parameters": { "PlaybookName": { - "value": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook" + "value": "NetApp-RansomwareResilience-Volume-Snapshot" }, "NetAppRansomwareResilienceAuthPlaybookName": { - "value": "NetApp-RansomwareResilience-Auth-Playbook" + "value": "NetApp-RansomwareResilience-Auth" }, "NetAppRansomwareResilienceAsyncPollPlaybookName": { - "value": "NetApp-RansomwareResilience_Async_Poll_Playbook" + "value": "NetApp-RansomwareResilience-Async-Poll" } } } \ No newline at end of file diff --git a/Solutions/NetApp Ransomware Resilience/Playbooks/README.md b/Solutions/NetApp Ransomware Resilience/Playbooks/README.md index 95b1b86e579..be779537e87 100644 --- a/Solutions/NetApp Ransomware Resilience/Playbooks/README.md +++ b/Solutions/NetApp Ransomware Resilience/Playbooks/README.md @@ -25,32 +25,32 @@ The playbooks are designed as **building blocks** that you can combine to create **You MUST deploy the playbooks in this specific order:** ### 1. Authentication Playbook (FIRST) -Deploy the **NetApp-RansomwareResilience-Auth-Playbook** first. This creates the shared Key Vault and provides authentication services that all other playbooks depend on. +Deploy the **NetApp-RansomwareResilience-Auth** first. This creates the shared Key Vault and provides authentication services that all other playbooks depend on. šŸ“– [Auth Playbook Documentation](./NetApp-RansomwareResilience-Auth-Playbook/README.md) ### 2. Async Poll Playbook (SECOND) -Deploy the **NetApp-RansomwareResilience-Async-Poll-Playbook** next. This monitors asynchronous operations and is used by most other playbooks. +Deploy the **NetApp-RansomwareResilience-Async-Poll** next. This monitors asynchronous operations and is used by most other playbooks. šŸ“– [Async Poll Playbook Documentation](./NetApp-RansomwareResilience_Async_Poll_Playbook/README.md) ### 3. Enrich IP Playbook (THIRD) -Deploy the **NetApp-RansomwareResilience-Enrich-IP-Playbook** to enable IP address investigation capabilities. +Deploy the **NetApp-RansomwareResilience-Enrich-IP** to enable IP address investigation capabilities. šŸ“– [Enrich IP Playbook Documentation](./NetApp-RansomwareResilience_Enrich_IP_Playbook/README.md) ### 4. Enrich StorageVM Playbook (FOURTH) -Deploy the **NetApp-RansomwareResilience-Enrich-StorageVM-Playbook** to enable storage configuration investigation. +Deploy the **NetApp-RansomwareResilience-Enrich-StorageVM** to enable storage configuration investigation. šŸ“– [Enrich StorageVM Playbook Documentation](./NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/README.md) ### 5. Volume Snapshot Playbook (FIFTH) -Deploy the **NetApp-RansomwareResilience-Volume-Snapshot-Playbook** to enable data protection through snapshots. +Deploy the **NetApp-RansomwareResilience-Volume-Snapshot** to enable data protection through snapshots. šŸ“– [Volume Snapshot Playbook Documentation](./NetApp-RansomwareResilience_Volume_Snapshot_Playbook/README.md) ### 6. Volume Offline Playbook (SIXTH) -Deploy the **NetApp-RansomwareResilience-Volume-Offline-Playbook** to enable volume isolation capabilities. +Deploy the **NetApp-RansomwareResilience-Volume-Offline** to enable volume isolation capabilities. šŸ“– [Volume Offline Playbook Documentation](./NetApp-RansomwareResilience_Volume_Offline_Playbook/README.md)

• Review the solution Release Notes