Azure Firewall
Azure Firewall is a cloud-native and intelligent network firewall security service that provides breed threat protection for cloud workloads running in Azure. It's a fully stateful, firewall as a service, with built-in high availability and unrestricted cloud scalability.
IT Services · Azure Firewall
Details
| ID | Azure Firewall |
|---|---|
| Provider | Microsoft |
| Category | IT Services |
| From Version | 6.1.0 |
| Docker Image | demisto/crypto:1.0.0.10120494 |
| Supported Modules | Agentix XSIAM |
README
Azure Firewall is a cloud-native and intelligent network firewall security service that provides breed threat protection for cloud workloads running in Azure. It’s a fully stateful, firewall as a service, with built-in high availability and unrestricted cloud scalability.
This integration was integrated and tested with version 2021-03-01 of Azure Firewall.
Configure Azure Firewall in Cortex
| Parameter | Description | Required |
|---|---|---|
| Resource Group Name. | True | |
| Client ID. | True | |
| Subscription ID. | True | |
| Tenant ID. | False | |
| Client Secret. | False | |
| Certificate Thumbprint | Used for certificate authentication. As appears in the “Certificates & secrets” page of the app. | False |
| Private Key | Used for certificate authentication. The private key of the registered certificate. | False |
| Use Azure Managed Identities | Relevant only if the integration is running on Azure VM. If selected, authenticates based on the value provided for the Azure Managed Identities Client ID field. If no value is provided for the Azure Managed Identities Client ID field, authenticates based on the System Assigned Managed Identity. For additional information, see the Help tab. | False |
| Azure Managed Identities Client ID | The Managed Identities client ID for authentication - relevant only if the integration is running on Azure VM. | False |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
azure-firewall-auth-test
Tests the connectivity to Azure.
Base Command
azure-firewall-auth-test
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
azure-firewall-auth-start
Run this command to start the authorization process and follow the instructions in the command results.
Base Command
azure-firewall-auth-start
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
azure-firewall-auth-complete
Run this command to complete the authorization process. Should be used after running the azure-firewall-auth-start command.
Base Command
azure-firewall-auth-complete
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
azure-firewall-auth-reset
Run this command if for some reason you need to rerun the authentication process.
Base Command
azure-firewall-auth-reset
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
azure-firewall-list
List Azure firewalls in the specified resource group or subscription.
Base Command
azure-firewall-list
Input
| Argument Name | Description | Required |
|---|---|---|
| resource | The resource that contains the firewalls to list. Possible values are: resource_group, subscription. Default is resource_group. | Required |
| limit | The maximum number of results to retrieve. Minimum value is 1. Default is 50. | Optional |
| page | The page number of the results to retrieve. Minimum value is 1. Default is 1. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Firewall.id | String | Firewall resource ID. |
| AzureFirewall.Firewall.name | String | Firewall resource name. |
| AzureFirewall.Firewall.location | String | Firewall resource location. |
Command example
!azure-firewall-list resource=resource_group limit=1 page=1
Context Example
{
"AzureFirewall": {
"Firewall": {
"etag": "W/\"b4fb1688-7055-40e7-8a5e-d17d81b902ed\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip",
"location": "eastus",
"name": "test-ip",
"properties": {
"additionalProperties": {},
"applicationRuleCollections": [],
"ipConfigurations": [
{
"etag": "W/\"b4fb1688-7055-40e7-8a5e-d17d81b902ed\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip/azureFirewallIpConfigurations/test-ip",
"name": "test-ip",
"properties": {
"privateIPAddress": "189.160.40.11",
"privateIPAllocationMethod": "Dynamic",
"provisioningState": "Succeeded",
"publicIPAddress": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/publicIPAddresses/test-ip"
},
"subnet": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet"
}
},
"type": "Microsoft.Network/azureFirewalls/azureFirewallIpConfigurations"
}
],
"natRuleCollections": [],
"networkRuleCollections": [],
"provisioningState": "Succeeded",
"sku": {
"name": "AZFW_VNet",
"tier": "Standard"
},
"threatIntelMode": "Alert"
},
"tags": {},
"type": "Microsoft.Network/azureFirewalls"
}
}
}
Human Readable Output
Firewall List
Current page size: 1
Showing page 1 out others that may exist.
Name Id Location Subnet Threat Intel Mode Private Ip Address Provisioning State test-ip /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip eastus /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet Alert 189.160.40.11 Succeeded
azure-firewall-get
Retrieve Azure firewall information.
Base Command
azure-firewall-get
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_names | Comma-separated list of firewall names to retrieve. | Required |
| polling | Indicates if the command was scheduled. Possible values are: True, False. Default is True. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Firewall.id | String | Firewall resource ID. |
| AzureFirewall.Firewall.name | String | Firewall resource name. |
| AzureFirewall.Firewall.location | String | Firewall resource location. |
Command example
!azure-firewall-get firewall_names=test-ip interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Firewall": {
"etag": "W/\"b4fb1688-7055-40e7-8a5e-d17d81b902ed\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip",
"location": "eastus",
"name": "test-ip",
"properties": {
"additionalProperties": {},
"applicationRuleCollections": [],
"ipConfigurations": [
{
"etag": "W/\"b4fb1688-7055-40e7-8a5e-d17d81b902ed\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip/azureFirewallIpConfigurations/test-ip",
"name": "test-ip",
"properties": {
"privateIPAddress": "189.160.40.11",
"privateIPAllocationMethod": "Dynamic",
"provisioningState": "Succeeded",
"publicIPAddress": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/publicIPAddresses/test-ip"
},
"subnet": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet"
}
},
"type": "Microsoft.Network/azureFirewalls/azureFirewallIpConfigurations"
}
],
"natRuleCollections": [],
"networkRuleCollections": [],
"provisioningState": "Succeeded",
"sku": {
"name": "AZFW_VNet",
"tier": "Standard"
},
"threatIntelMode": "Alert"
},
"tags": {},
"type": "Microsoft.Network/azureFirewalls"
}
}
}
Human Readable Output
Firewall test-ip information
Name Id Location Subnet Threat Intel Mode Private Ip Address Provisioning State test-ip /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip eastus /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet Alert 189.160.40.11 Succeeded
azure-firewall-rule-collection-list
List the collection rules in the firewall or policy. One of the arguments ‘firewall_name’ or ‘policy’ must be provided.
Base Command
azure-firewall-rule-collection-list
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the Azure firewall that contains the collections. | Optional |
| policy | The name of the Azure policy that contains the collections. | Optional |
| rule_type | The names of the rule collection type to retrieve. Possible values are: application_rule, network_rule, nat_rule. | Required |
| limit | The maximum number of results to retrieve. Minimum value is 1. Default is 50. | Optional |
| page | The page number of the results to retrieve. Minimum value is 1. Default is 1. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.RuleCollection.name | String | Rule collection unique name. |
Command example
!azure-firewall-rule-collection-list policy=xsoar-policy rule_type=network_rule limit=1 page=1
Context Example
{
"AzureFirewall": {
"RuleCollection": {
"etag": "e09cf677-e019-43f0-98a6-eeee540a74ae",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy/ruleCollectionGroups/playbook-collection",
"location": "eastus",
"name": "playbook-collection",
"properties": {
"priority": 201,
"provisioningState": "Succeeded",
"ruleCollections": [
{
"action": {
"type": "Deny"
},
"name": "playbook-collection",
"priority": 201,
"ruleCollectionType": "FirewallPolicyFilterRuleCollection",
"rules": [
{
"description": "test-playbook-collection",
"destinationAddresses": [
"189.160.40.11",
"189.160.40.11"
],
"destinationFqdns": [],
"destinationIpGroups": [],
"destinationPorts": [
"8080"
],
"ipProtocols": [
"UDP",
"TCP"
],
"name": "playbook-rule",
"ruleType": "NetworkRule",
"sourceAddresses": [
"189.160.40.11",
"189.160.40.11"
],
"sourceIpGroups": []
}
]
}
]
},
"type": "Microsoft.Network/FirewallPolicies/RuleCollectionGroups"
}
}
}
Human Readable Output
xsoar-policy Rule Collections List
Current page size: 1
Showing page 1 out others that may exist.
Name Action Priority playbook-collection Deny 201
azure-firewall-rule-list
List rules in the firewall or in the policy. One of the arguments ‘firewall_name’ or ‘policy’ must be provided.
Base Command
azure-firewall-rule-list
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the Azure firewall that contains the rules. | Optional |
| policy | The name of the Azure policy that contains the rules. | Optional |
| rule_type | The names of the rule types to retrieve. Required when the “firewall_name” argument is provided. Possible values are: application_rule, network_rule, nat_rule. | Optional |
| collection_name | The name of the rule collection that contains the rules. | Required |
| limit | The maximum number of results to retrieve. Minimum value is 1. Default is 50. | Optional |
| page | The page number of the results to retrieve. Minimum value is 1. Default is 1. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Rule.name | String | Rule name. |
Command example
!azure-firewall-rule-list policy=xsoar-policy collection_name=playbook-collection rule_type=network_rule limit=1 page=1
Context Example
{
"AzureFirewall": {
"Rule": {
"description": "test-playbook-collection",
"destinationAddresses": [
"189.160.40.11",
"189.160.40.11"
],
"destinationFqdns": [],
"destinationIpGroups": [],
"destinationPorts": [
"8080"
],
"ipProtocols": [
"UDP",
"TCP"
],
"name": "playbook-rule",
"ruleType": "NetworkRule",
"sourceAddresses": [
"189.160.40.11",
"189.160.40.11"
],
"sourceIpGroups": []
}
}
}
Human Readable Output
Policy xsoar-policy network_rule Rules List
Current page size: 1
Showing page 1 out others that may exist.
Name playbook-rule
azure-firewall-rule-get
Retrieve rule information. One of the arguments ‘firewall_name’ or ‘policy’ must be provided.
Base Command
azure-firewall-rule-get
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the firewall that contains the rule. | Optional |
| policy | The name of the Azure policy that contains the rules. | Optional |
| rule_type | The name of the rule type collection that contains the rule. Required when the “firewall_name” argument is provided. Possible values are: application_rule, network_rule, nat_rule. | Optional |
| collection_name | The name of the rule collection that contains the rule. | Required |
| rule_name | The name of the rule to retrieve. | Required |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Rule.name | String | Rule name. |
Command example
!azure-firewall-rule-get policy=xsoar-policy collection_name=playbook-collection rule_name=new-playbook-rule
Context Example
{
"AzureFirewall": {
"Rule": {
"description": "test-playbook-collection",
"destinationAddresses": [
"189.160.40.11",
"189.160.40.11"
],
"destinationFqdns": [],
"destinationIpGroups": [],
"destinationPorts": [
"8080"
],
"ipProtocols": [
"UDP"
],
"name": "new-playbook-rule",
"ruleType": "NetworkRule",
"sourceAddresses": [
"189.160.40.11",
"189.160.40.11"
],
"sourceIpGroups": []
}
}
}
Human Readable Output
Rule new-playbook-rule Information
Name new-playbook-rule
azure-firewall-policy-create
Create a firewall policy. This command only creates the policy resource. In order to attach the policy to a firewall, run the ‘azure-firewall-policy-attach’ command.
Base Command
azure-firewall-policy-create
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of the Azure policy to create. | Required |
| threat_intelligence_mode | The operation mode for threat intelligence. Possible values are: Alert, Deny, Turned-off. Default is Turned-off. | Required |
| ips | Comma-separated list of IP addresses for the threat intelligence whitelist. | Optional |
| domains | Comma-separated list of fully qualified domain names for the threat intelligence whitelist. For example : *.microsoft.com,email.college.edu . | Optional |
| location | Policy resource region location. Possible values are: northcentralus, eastus, northeurope, westeurope, eastasia, southeastasia, eastus2, centralus, southcentralus, westus, japaneast, japanwest, australiaeast, australiasoutheast, brazilsouth, centralindia, southindia, westindia, canadacentral, canadaeast, uksouth, ukwest, westcentralus, westus2, koreacentral, francecentral, australiacentral, uaenorth, southafricanorth, switzerlandnorth, germanywestcentral, norwayeast, westus3, jioindiawest. | Required |
| tier | Tier of an Azure policy. Possible values are: Standard, Premium. Default is Standard. | Required |
| base_policy_id | The ID of the parent firewall policy from which rules are inherited. | Optional |
| enable_proxy | Whether to enable the DNS proxy on firewalls attached to the firewall policy. Possible values are: True, False. Default is False. | Optional |
| dns_servers | Comma-separated list of custom DNS servers. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Policy.id | String | Policy resource ID. |
| AzureFirewall.Policy.name | String | Policy resource name. |
Command example
!azure-firewall-policy-create policy_name=xsoar-policy threat_intelligence_mode=Alert location=eastus tier=Standard interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "b5074926-9b59-4ab8-ba44-7fb39a2879a3",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Updating",
"ruleCollectionGroups": [],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Alert"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Created Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Updating
azure-firewall-policy-update
Update the policy resource. The command will update the provided arguments.
Base Command
azure-firewall-policy-update
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of the Azure policy to update. | Required |
| threat_intelligence_mode | The operation mode for threat intelligence. Possible values are: Alert, Deny, Turned-off. | Optional |
| ips | Comma-separated list of IP addresses for the threat intelligence whitelist. | Optional |
| domains | Comma-separated list of fully qualified domain names for the threat intelligence whitelist. For example : *.microsoft.com,email.college.edu . | Optional |
| base_policy_id | The ID of the parent firewall policy from which rules are inherited. | Optional |
| enable_proxy | Whether to enable the DNS Proxy on Firewalls attached to the Firewall Policy. Possible values are: True, False. | Optional |
| dns_servers | Comma-separated list of custom DNS servers. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Policy.id | String | Policy resource ID. |
| AzureFirewall.Policy.name | String | Policy resource name. |
Command example
!azure-firewall-policy-update policy_name=xsoar-policy threat_intelligence_mode=Deny interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "15f105aa-3059-4e9b-97e9-3b85a839ecf3",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Updating",
"ruleCollectionGroups": [],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Deny"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Updated Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Updating
azure-firewall-policy-get
Retrieve policy information.
Base Command
azure-firewall-policy-get
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_names | Comma-separated list of policy names to retrieve. | Required |
| polling | Indicates if the command was scheduled. Possible values are: True, False. Default is True. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Policy.id | String | Policy resource ID. |
| AzureFirewall.Policy.name | String | Policy resource name. |
Command example
!azure-firewall-policy-get policy_names=xsoar-policy interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "b5074926-9b59-4ab8-ba44-7fb39a2879a3",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Succeeded",
"ruleCollectionGroups": [],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Alert"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Policy xsoar-policy information
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Succeeded
azure-firewall-policy-delete
Delete policy resource.
Base Command
azure-firewall-policy-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_names | Comma-separated list of policy names to delete. | Required |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
azure-firewall-policy-list
List the policy in the resource group or subscription.
Base Command
azure-firewall-policy-list
Input
| Argument Name | Description | Required |
|---|---|---|
| resource | The resource that contains the policies to list. Possible values are: resource_group, subscription. Default is resource_group. | Required |
| limit | The maximum number of results to retrieve. Minimum value is 1. Default is 50. | Optional |
| page | The page number of the results to retrieve. Minimum value is 1. Default is 1. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Policy.id | String | Policy resource ID. |
| AzureFirewall.Policy.name | String | Policy resource name. |
Command example
!azure-firewall-policy-list resource=resource_group limit=1 page=1
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "b5074926-9b59-4ab8-ba44-7fb39a2879a3",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Succeeded",
"ruleCollectionGroups": [],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Alert"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Policy List
Current page size: 1
Showing page 1 out others that may exist.
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Succeeded
azure-firewall-policy-attach
Attach a policy to a firewall. The policy and firewall have to belong to the same tier.
Base Command
azure-firewall-policy-attach
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_names | Comma-separated list of firewall names to which the policy will be attached. | Required |
| policy_id | The ID of the policy to attach. | Required |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Firewall.id | String | Firewall resource ID. |
| AzureFirewall.Firewall.name | String | Firewall resource name. |
| AzureFirewall.Firewall.location | String | Firewall resource location. |
Command example
!azure-firewall-policy-attach firewall_names=test-ip policy_id=/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Firewall": {
"etag": "W/\"03a287f1-5106-426c-b181-166258b1fc6a\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip",
"location": "eastus",
"name": "test-ip",
"properties": {
"additionalProperties": {},
"applicationRuleCollections": [],
"firewallPolicy": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy"
},
"ipConfigurations": [
{
"etag": "W/\"03a287f1-5106-426c-b181-166258b1fc6a\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip/azureFirewallIpConfigurations/test-ip",
"name": "test-ip",
"properties": {
"privateIPAddress": "189.160.40.11",
"privateIPAllocationMethod": "Dynamic",
"provisioningState": "Succeeded",
"publicIPAddress": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/publicIPAddresses/test-ip"
},
"subnet": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet"
}
},
"type": "Microsoft.Network/azureFirewalls/azureFirewallIpConfigurations"
}
],
"natRuleCollections": [],
"networkRuleCollections": [],
"provisioningState": "Updating",
"sku": {
"name": "AZFW_VNet",
"tier": "Standard"
},
"threatIntelMode": "Alert"
},
"tags": {},
"type": "Microsoft.Network/azureFirewalls"
}
}
}
Human Readable Output
Successfully Updated Firewall “test-ip”
Name Id Location Subnet Threat Intel Mode Private Ip Address Provisioning State test-ip /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip eastus /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet Alert 189.160.40.11 Updating
azure-firewall-policy-detach
Remove a policy from the firewall. This command will detach the policy and firewall, but will not delete the policy.
Base Command
azure-firewall-policy-detach
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_names | Comma-separated list of firewall names from which the policy will be removed. | Required |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Firewall.id | String | Firewall resource ID. |
| AzureFirewall.Firewall.name | String | Firewall resource name. |
| AzureFirewall.Firewall.location | String | Firewall resource location. |
Command example
!azure-firewall-policy-detach firewall_names=test-ip interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Firewall": {
"etag": "W/\"f4e53250-f431-437b-a86f-7aa6a34d4616\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip",
"location": "eastus",
"name": "test-ip",
"properties": {
"additionalProperties": {},
"applicationRuleCollections": [],
"ipConfigurations": [
{
"etag": "W/\"f4e53250-f431-437b-a86f-7aa6a34d4616\"",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip/azureFirewallIpConfigurations/test-ip",
"name": "test-ip",
"properties": {
"privateIPAddress": "189.160.40.11",
"privateIPAllocationMethod": "Dynamic",
"provisioningState": "Succeeded",
"publicIPAddress": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/publicIPAddresses/test-ip"
},
"subnet": {
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet"
}
},
"type": "Microsoft.Network/azureFirewalls/azureFirewallIpConfigurations"
}
],
"natRuleCollections": [],
"networkRuleCollections": [],
"provisioningState": "Updating",
"sku": {
"name": "AZFW_VNet",
"tier": "Standard"
},
"threatIntelMode": "Alert"
},
"tags": {},
"type": "Microsoft.Network/azureFirewalls"
}
}
}
Human Readable Output
Successfully Updated Firewall “test-ip”
Name Id Location Subnet Threat Intel Mode Private Ip Address Provisioning State test-ip /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/azureFirewalls/test-ip eastus /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/virtualNetworks/test-v-n/subnets/AzureFirewallSubnet Alert 189.160.40.11 Updating
azure-firewall-network-rule-collection-create
Create a network rule collection in a firewall or policy. The command will return firewall or policy rule collection resource information. One of the arguments ‘firewall_name’ or ‘policy’ must be provided.
Base Command
azure-firewall-network-rule-collection-create
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the firewall that contains the collection. | Optional |
| policy | The name of the policy that contains the collection. | Optional |
| collection_name | The name of the network rule collection to create. | Required |
| collection_priority | The priority of the network rule collection resource. Minimum value is 100, maximum value is 65000. | Required |
| action | The action type of a rule collection. Possible values are: Allow, Deny. | Required |
| rule_name | The name of the network rule to create. | Required |
| description | The description of the created rule. | Required |
| protocols | Comma-separated list of protocols for the created rule. Possible values are: TCP, UDP, ICMP, Any. | Required |
| source_type | Rule source type. Possible values are: ip_address, ip_group. | Required |
| source_ips | Comma-separated list of source IP addresses for the created rule. Must be provided when the ‘source_type’ argument is assigned to ‘ip_address’. | Optional |
| source_ip_group_ids | Comma-separated list of source IP group IDs for the created rule. Must be provided when the ‘source_type’ argument is assigned to ‘ip_group’. | Optional |
| destination_type | Rule destination type. Possible values are: ip_address, ip_group, service_tag, fqdn. | Required |
| destinations | Comma-separated list of destinations for the created rule. Must be consistent with the provided ‘destination_type’ argument. Supports IP addresses, service tag names, IP group IDs and FQDN addresses. | Required |
| destination_ports | Comma-separated list of destination ports. | Required |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-network-rule-collection-create policy=xsoar-policy collection_name=playbook-collection collection_priority=105 action=Allow rule_name=playbook-rule description=test-playbook-collection protocols=UDP,TCP source_type=ip_address source_ips=189.160.40.11,189.160.40.11 destination_type=ip_address destinations=189.160.40.11,189.160.40.11 destination_ports=8080 interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "23384541-d2ae-4922-95ed-9c70ffbe336e",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Updating",
"ruleCollectionGroups": [
{
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy/ruleCollectionGroups/playbook-collection"
}
],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Deny"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Updated Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Updating
azure-firewall-network-rule-collection-delete
Delete a network rule collection from the firewall or policy. One of the arguments ‘firewall_name’ or ‘policy’ must be provided.
Base Command
azure-firewall-network-rule-collection-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the firewall that contains the collection. | Optional |
| policy | The name of the policy the contains the collection. | Optional |
| collection_name | The name of the network rule collection to delete. | Required |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-network-rule-collection-delete policy=xsoar-policy collection_name=playbook-collection interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "5984cc1d-8e84-4385-adbe-e1d9293d7e97",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Updating",
"ruleCollectionGroups": [
{
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy/ruleCollectionGroups/playbook-collection"
}
],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Deny"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Updated Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Updating
azure-firewall-network-rule-create
Create a network rule in the firewall or policy rule collection. One of the arguments ‘firewall_name’ or ‘policy’ must be provided.
Base Command
azure-firewall-network-rule-create
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the firewall that contains the collection. | Optional |
| policy | The name of the policy that contains the collection. | Optional |
| collection_name | The name of the network rule collection that contains the rule. | Required |
| rule_name | The name of the network rule to create. | Required |
| description | The description of the created rule. | Required |
| protocols | Comma-separated list of protocols for the created rule. Possible values are: TCP, UDP, ICMP, Any. | Required |
| source_type | Rule source type. Possible values are: ip_address, ip_group. | Required |
| source_ips | Comma-separated list of source IP addresses for the created rule. Must be provided when the ‘source_type’ argument is assigned to ‘ip_address’. | Optional |
| source_ip_group_ids | Comma-separated list of source IP group IDs for the created rule. Must be provided when the ‘source_type’ argument is assigned to ‘ip_group’. | Optional |
| destination_type | Rule destination type. Possible values are: ip_address, ip_group, service_tag, fqdn. | Required |
| destinations | Comma-separated list of destinations for the created rule. Must be consistent with the provided ‘destination_type’ argument. Supports IP addresses, service tag names, IP group IDs and FQDN addresses. | Required |
| destination_ports | Comma-separated list of destination ports. | Required |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-network-rule-create policy=xsoar-policy collection_name=playbook-collection rule_name=new-playbook-rule description=test-playbook-collection protocols=UDP,TCP source_type=ip_address source_ips=189.160.40.11,189.160.40.11 destination_type=ip_address destinations=189.160.40.11,189.160.40.11 destination_ports=8080 interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "e1950ec2-3ab1-43aa-9d84-a3c4053c2f52",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Updating",
"ruleCollectionGroups": [
{
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy/ruleCollectionGroups/playbook-collection"
}
],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Deny"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Updated Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Updating
azure-firewall-network-rule-update
Update the network rule in the firewall. The provided arguments will replace the existing rule configuration. One of the arguments ‘firewall_name’ or ‘policy’ must be provided. The command will not replace the rule source or destination types.
Base Command
azure-firewall-network-rule-update
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the firewall that contains the collection. | Optional |
| policy | The name of the policy that contains the collection. | Optional |
| collection_name | The name of the network rule collection to update. | Required |
| rule_name | The name of the network rule to update. | Required |
| description | The new description of the rule. | Optional |
| protocols | Comma-separated list of protocols for the rule. Possible values are: TCP, UDP, ICMP, Any. | Optional |
| source_type | Rule source type. Possible values are: ip_address, ip_group. | Optional |
| source_ips | Comma-separated list of source IP addresses for the created rule. Must be provided when the ‘source_type’ argument is assigned to ‘ip_address’. | Optional |
| source_ip_group_ids | Comma-separated list of source IP group IDs for the created rule. Must be provided when the ‘source_type’ argument is assigned to ‘ip_group’. | Optional |
| destination_type | Rule destination type. Must be provided when the ‘destinations’ argument is provided. Possible values are: ip_address, ip_group, service_tag, fqdn. | Optional |
| destinations | Comma-separated list of destinations for the created rule. Must be consistent with the provided ‘destination_type’ argument. Supports IP addresses, service tag names, IP group IDs and FQDN addresses. | Optional |
| destination_ports | Comma-separated list of destination ports. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-network-rule-update policy=xsoar-policy collection_name=playbook-collection rule_name=new-playbook-rule protocols=UDP interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "9e0bdc8a-99e9-4337-8778-2ec85d29d445",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Succeeded",
"ruleCollectionGroups": [
{
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy/ruleCollectionGroups/playbook-collection"
}
],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Deny"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Updated Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Succeeded
azure-firewall-network-rule-delete
Delete a network rule from the collection. One of the arguments ‘firewall_name’ or ‘policy’ must be provided.
Base Command
azure-firewall-network-rule-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the firewall that contains the collection. | Optional |
| policy | The name of the policy that contains the collection. | Optional |
| collection_name | The name of the network rule collection to update. | Required |
| rule_names | Comma-separated list of network rule names to delete from the collection. | Required |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-network-rule-delete policy=xsoar-policy collection_name=playbook-collection rule_names=new-playbook-rule interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "6b9e5bf4-3e11-4705-84c6-d5c14e45f13c",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Updating",
"ruleCollectionGroups": [
{
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy/ruleCollectionGroups/playbook-collection"
}
],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Deny"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Updated Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Updating
azure-firewall-network-rule-collection-update
Update a network rule collection in a firewall or policy. The command will update the provided arguments. One of the arguments ‘firewall_name’ or ‘policy’ must be provided. The command will return firewall or policy rule collection resource information.
Base Command
azure-firewall-network-rule-collection-update
Input
| Argument Name | Description | Required |
|---|---|---|
| firewall_name | The name of the firewall that contains the collection. | Optional |
| policy | The name of the policy that contains the collection. | Optional |
| collection_name | The name of the network rule collection to update. | Required |
| priority | The priority of the network rule collection resource. Minimum value is 100, maximum value us 65000. | Optional |
| action | The action type of a rule collection. Possible values are: Allow, Deny. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-network-rule-collection-update policy=xsoar-policy collection_name=playbook-collection priority=201 action=Deny interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"Policy": {
"etag": "a4caa2e4-cc96-460b-9202-4914f74ce5e9",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy",
"location": "eastus",
"name": "xsoar-policy",
"properties": {
"childPolicies": [],
"dnsSettings": {
"servers": []
},
"firewalls": [],
"provisioningState": "Succeeded",
"ruleCollectionGroups": [
{
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy/ruleCollectionGroups/playbook-collection"
}
],
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Deny"
},
"type": "Microsoft.Network/FirewallPolicies"
}
}
}
Human Readable Output
Successfully Updated Policy “xsoar-policy”
Name Id Tier Location Firewalls Base Policy Child Policies Provisioning State xsoar-policy /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/firewallPolicies/xsoar-policy Standard eastus Succeeded
azure-firewall-service-tag-list
Retrieve service tags information.
Base Command
azure-firewall-service-tag-list
Input
| Argument Name | Description | Required |
|---|---|---|
| location | The location that will be used as a reference for a version (not as a filter based on location, the command will retrieve the list of service tags with prefix details across all regions but limited to the cloud that your subscription belongs to). Possible values are: northcentralus, eastus, northeurope, westeurope, eastasia, southeastasia, eastus2, centralus, southcentralus, westus, japaneast, japanwest, australiaeast, australiasoutheast, brazilsouth, centralindia, southindia, westindia, canadacentral, canadaeast, uksouth, ukwest, westcentralus, westus2, koreacentral, francecentral, australiacentral, uaenorth, southafricanorth, switzerlandnorth, germanywestcentral, norwayeast, westus3, jioindiawest. | Required |
| limit | The maximum number of results to retrieve. Minimum value is 1. Default is 50. | Optional |
| page | The page number of the results to retrieve. Minimum value is 1. Default is 1. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-service-tag-list location=eastus limit=1 page=3
Context Example
{
"AzureFirewall": {
"ServiceTag": {
"id": "ApiManagement.AustraliaCentral",
"name": "ApiManagement.AustraliaCentral",
"properties": {
"addressPrefixes": [
"20.36.106.68/31",
"20.36.107.176/28",
"20.37.52.67/32",
"2603:1010:304:402::140/124"
],
"changeNumber": "2",
"networkFeatures": [
"API",
"NSG",
"UDR",
"FW"
],
"region": "australiacentral",
"state": "GA",
"systemService": "AzureApiManagement"
},
"serviceTagChangeNumber": "86"
}
}
}
Human Readable Output
Service Tag List
Current page size: 1
Showing page 3 out others that may exist.
Name Id ApiManagement.AustraliaCentral ApiManagement.AustraliaCentral
azure-firewall-ip-group-create
Create an IP group.
Base Command
azure-firewall-ip-group-create
Input
| Argument Name | Description | Required |
|---|---|---|
| ip_group_name | The name of the IP group resource to create. | Required |
| ips | Comma-separated list of IP addresses or IP address prefixes in the IP group resource. | Optional |
| location | The location of the IP group resource. Possible values are: northcentralus, eastus, northeurope, westeurope, eastasia, southeastasia, eastus2, centralus, southcentralus, westus, japaneast, japanwest, australiaeast, australiasoutheast, brazilsouth, centralindia, southindia, westindia, canadacentral, canadaeast, uksouth, ukwest, westcentralus, westus2, koreacentral, francecentral, australiacentral, uaenorth, southafricanorth, switzerlandnorth, germanywestcentral, norwayeast, westus3, jioindiawest. | Required |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.IPGroup.id | String | IP group resource ID. |
| AzureFirewall.IPGroup.name | String | IP group resource name. |
| AzureFirewall.IPGroup.properties.ipAddresses | String | List of IP addresses or IP address prefixes in the IP groups resource. |
Command example
!azure-firewall-ip-group-create ip_group_name=xsoar-ip-group ips=189.160.40.11 location=eastus interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"IPGroup": {
"etag": "8ea22ba3-4023-4c7f-a887-34f5f349d7c6",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group",
"location": "eastus",
"name": "xsoar-ip-group",
"properties": {
"firewallPolicies": [],
"firewalls": [],
"ipAddresses": [
"189.160.40.11"
],
"provisioningState": "Updating"
},
"type": "Microsoft.Network/IpGroups"
}
}
}
Human Readable Output
Successfully Created IP Group “xsoar-ip-group”
Name Id Ip Addresses Firewalls Firewall Policies Provisioning State xsoar-ip-group /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group 189.160.40.11 Updating
azure-firewall-ip-group-update
Update an IP group. Add or remove IP addresses from the group.
Base Command
azure-firewall-ip-group-update
Input
| Argument Name | Description | Required |
|---|---|---|
| ip_group_name | The name of the IP group resource to update. | Required |
| ips_to_add | Comma-separated list of IP addresses or IP address prefixes to add to the IP group resource. | Optional |
| ips_to_remove | Comma-separated list of IP addresses or IP address prefixes to remove from the IP group resource. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.IPGroup.id | String | IP group resource ID. |
| AzureFirewall.IPGroup.name | String | IP group resource name. |
| AzureFirewall.IPGroup.properties.ipAddresses | String | List of IP addresses or IP address prefixes in the IP groups resource. |
Command example
!azure-firewall-ip-group-update ip_group_name=xsoar-ip-group ips_to_add=189.160.40.11,189.160.40.11 ips_to_remove=189.160.40.11,1.1.1 interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"IPGroup": {
"etag": "8f0e7d5d-6dfd-429c-ad07-e670f57e4dab",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group",
"location": "eastus",
"name": "xsoar-ip-group",
"properties": {
"firewallPolicies": [],
"firewalls": [],
"ipAddresses": [
"189.160.40.11",
"189.160.40.11"
],
"provisioningState": "Updating"
},
"type": "Microsoft.Network/IpGroups"
}
}
}
Human Readable Output
xsoar-ip-group IP Group Information
Name Id Ip Addresses Firewalls Firewall Policies Provisioning State xsoar-ip-group /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group 189.160.40.11,
189.160.40.11Updating
azure-firewall-ip-group-list
List IP groups in a resource group or subscription.
Base Command
azure-firewall-ip-group-list
Input
| Argument Name | Description | Required |
|---|---|---|
| resource | The resource that contains the IP groups to list. Possible values are: resource_group, subscription. Default is resource_group. | Required |
| limit | The maximum number of results to retrieve. Minimum value is 1. Default is 50. | Optional |
| page | The page number of the results to retrieve. Minimum value is 1. Default is 1. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.IPGroup.id | String | IP group resource ID. |
| AzureFirewall.IPGroup.name | String | IP group resource name. |
| AzureFirewall.IPGroup.properties.ipAddresses | String | List of IP addresses or IP address prefixes in the IP groups resource. |
Command example
!azure-firewall-ip-group-list resource=resource_group limit=1 page=1
Context Example
{
"AzureFirewall": {
"IPGroup": {
"etag": "4c626477-c875-4392-9d7c-02464d2a82d9",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group",
"location": "eastus",
"name": "xsoar-ip-group",
"properties": {
"firewallPolicies": [],
"firewalls": [],
"ipAddresses": [
"189.160.40.11"
],
"provisioningState": "Succeeded"
},
"type": "Microsoft.Network/IpGroups"
}
}
}
Human Readable Output
IP Group List
Current page size: 1
Showing page 1 out others that may exist.
Name Id Ip Addresses Firewalls Firewall Policies Provisioning State xsoar-ip-group /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group 189.160.40.11 Succeeded
azure-firewall-ip-group-get
Retrieve IP group information.
Base Command
azure-firewall-ip-group-get
Input
| Argument Name | Description | Required |
|---|---|---|
| ip_group_names | Comma-separated list of IP group names resource to retrieve. | Required |
| polling | Indicates if the command was scheduled. Possible values are: True, False. Default is True. | Optional |
| interval | Indicates how long to wait between command executions (in seconds) when the ‘polling’ argument is true. Minimum value is 10 seconds. Default is 30. | Optional |
| timeout | Indicates the time in seconds until the polling sequence times out. Default is 60. | Optional |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.IPGroup.id | String | IP group resource ID. |
| AzureFirewall.IPGroup.name | String | IP group resource name. |
| AzureFirewall.IPGroup.properties.ipAddresses | String | List of IP addresses or IP address prefixes in the IP groups resource. |
Command example
!azure-firewall-ip-group-get ip_group_names=xsoar-ip-group interval=10 timeout=600
Context Example
{
"AzureFirewall": {
"IPGroup": {
"etag": "4c626477-c875-4392-9d7c-02464d2a82d9",
"id": "/subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group",
"location": "eastus",
"name": "xsoar-ip-group",
"properties": {
"firewallPolicies": [],
"firewalls": [],
"ipAddresses": [
"189.160.40.11"
],
"provisioningState": "Succeeded"
},
"type": "Microsoft.Network/IpGroups"
}
},
"IP": {
"Address": "189.160.40.11"
}
}
Human Readable Output
xsoar-ip-group IP Group Information
Name Id Ip Addresses Firewalls Firewall Policies Provisioning State xsoar-ip-group /subscriptions/xsoar-subscription/resourceGroups/xsoar-resource-group/providers/Microsoft.Network/ipGroups/xsoar-ip-group 189.160.40.11 Succeeded
azure-firewall-ip-group-delete
Delete an IP group resource.
Base Command
azure-firewall-ip-group-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| ip_group_names | Comma-separated list of IP group names resource to delete. | Required |
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| resource_group_name | The name of the resource group. Note: This argument will override the instance parameter ‘Default Resource Group Name’. | Optional |
Context Output
There is no context output for this command.
Command example
!azure-firewall-ip-group-delete ip_group_names=xsoar-ip-group
Human Readable Output
IP Group xsoar-ip-group deleted successfully.
azure-firewall-subscriptions-list
List all subscriptions for a tenant.
Base Command
azure-firewall-subscriptions-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.Subscription.authorizationSource | String | The authorization source of the request. |
| AzureFirewall.Subscription.displayName | String | The subscription display name. |
| AzureFirewall.Subscription.id | String | The fully qualified ID for the subscription. For example, /subscriptions/8d65815f-a5b6-402f-9298-045155da7d74. |
| AzureFirewall.Subscription.managedByTenants | Unknown | An array containing the tenants managing the subscription. |
| AzureFirewall.Subscription.state | Unknown | The subscription state. Possible values are Enabled, Warned, PastDue, Disabled, and Deleted. |
| AzureFirewall.Subscription.subscriptionId | String | The subscription ID. |
| AzureFirewall.Subscription.subscriptionPolicies | Unknown | The subscription policies. |
| AzureFirewall.Subscription.tags | Object | The tags attached to the subscription. |
| AzureFirewall.Subscription.tenantId | String | The subscription tenant ID. |
azure-firewall-resource-group-list
List all resource groups for a subscription.
Base Command
azure-firewall-resource-group-list
Input
| Argument Name | Description | Required |
|---|---|---|
| subscription_id | The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. | Optional |
| limit | Limit on the number of resource groups to return. Default is 50. | Optional |
| tag | A single tag in the form of ‘{“Tag Name”:”Tag Value”}’ to filter the list by. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureFirewall.ResourceGroup.id | String | The ID of the resource group. |
| AzureFirewall.ResourceGroup.location | String | The location of the resource group. |
| AzureFirewall.ResourceGroup.managedBy | String | The ID of the resource that manages this resource group. |
| AzureFirewall.ResourceGroup.name | String | The name of the resource group. |
| AzureFirewall.ResourceGroup.properties.provisioningState | String | The provisioning state. |
| AzureFirewall.ResourceGroup.tags | Object | The tags attached to the resource group. |
| AzureFirewall.ResourceGroup.type | String | The type of the resource group. |
Configuration parameters
resource_group— Default Resource Group Name (required)client_id— Client IDsubscription_id— (required)tenant_id—client_secret—certificate_thumbprint— Certificate Thumbprintprivate_key— Private Keyuse_managed_identities— Use Azure Managed Identitiesmanaged_identities_client_id—proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)
Commands (30)
-
azure-firewall-auth-completeRun this command to complete the authorization process. Should be used after running the azure-firewall-auth-start command.
-
azure-firewall-auth-resetRun this command if for some reason you need to rerun the authentication process.
-
azure-firewall-auth-startRun this command to start the authorization process and follow the instructions in the command results.
-
azure-firewall-auth-testTests the connectivity to Azure.
-
azure-firewall-getRetrieve Azure firewall information.
-
azure-firewall-ip-group-createCreate an IP group.
-
azure-firewall-ip-group-deleteDelete an IP group resource.
-
azure-firewall-ip-group-getRetrieve IP group information.
-
azure-firewall-ip-group-listList IP groups in a resource group or subscription.
-
azure-firewall-ip-group-updateUpdate an IP group. Add or remove IP addresses from the group.
-
azure-firewall-listList Azure firewalls in the specified resource group or subscription.
-
azure-firewall-network-rule-collection-createCreate a network rule collection in a firewall or policy. The command will return firewall or policy rule collection resource information. One of the arguments 'firewall_name' or 'policy' must be provided.
-
azure-firewall-network-rule-collection-deleteDelete a network rule collection from the firewall or policy. One of the arguments 'firewall_name' or 'policy' must be provided.
-
azure-firewall-network-rule-collection-updateUpdate a network rule collection in a firewall or policy. The command will update the provided arguments. One of the arguments 'firewall_name' or 'policy' must be provided. The command will return firewall or policy rule collection resource information.
-
azure-firewall-network-rule-createCreate a network rule in the firewall or policy rule collection. One of the arguments 'firewall_name' or 'policy' must be provided.
-
azure-firewall-network-rule-deleteDelete a network rule from the collection. One of the arguments 'firewall_name' or 'policy' must be provided.
-
azure-firewall-network-rule-updateUpdate the network rule in the firewall. The provided arguments will replace the existing rule configuration. One of the arguments 'firewall_name' or 'policy' must be provided. The command will not replace the rule source or destination types.
-
azure-firewall-policy-attachAttach a policy to a firewall. The policy and firewall have to belong to the same tier.
-
azure-firewall-policy-createCreate a firewall policy. This command only creates the policy resource. In order to attach the policy to a firewall, run the 'azure-firewall-policy-attach' command.
-
azure-firewall-policy-deleteDelete policy resource.
-
azure-firewall-policy-detachRemove a policy from the firewall. This command will detach the policy and firewall, but will not delete the policy.
-
azure-firewall-policy-getRetrieve policy information.
-
azure-firewall-policy-listList the policy in the resource group or subscription.
-
azure-firewall-policy-updateUpdate the policy resource. The command will update the provided arguments.
-
azure-firewall-resource-group-listList all resource groups for a subscription.
-
azure-firewall-rule-collection-listList the collection rules in the firewall or policy. One of the arguments 'firewall_name' or 'policy' must be provided.
-
azure-firewall-rule-getRetrieve rule information. One of the arguments 'firewall_name' or 'policy' must be provided.
-
azure-firewall-rule-listList rules in the firewall or in the policy. One of the arguments 'firewall_name' or 'policy' must be provided.
-
azure-firewall-service-tag-listRetrieve service tags information.
-
azure-firewall-subscriptions-listList all subscriptions for a tenant.
import copy import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 from MicrosoftApiModule import * # noqa: E402 from requests import Response API_VERSION = "2021-03-01" class AzureFirewallClient: def __init__( self, subscription_id: str, resource_group: str, client_id: str, verify: bool, proxy: bool, client_secret: str | None = None, tenant_id: str = "", certificate_thumbprint: str | None = None, private_key: str | None = None, managed_identities_client_id: str | None = None, is_credentials: str | None = None, ): self.resource_group = resource_group self.subscription_id = subscription_id self.default_params = {"api-version": API_VERSION} scope = ( Scopes.management_azure if is_credentials else "https://management.azure.com/user_impersonation offline_access user.read" ) grant_type = CLIENT_CREDENTIALS if is_credentials else DEVICE_CODE token_retrieval_url = ( f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" if tenant_id else "https://login.microsoftonline.com/organizations/oauth2/v2.0/token" ) if not is_credentials: client_secret = None tenant_id = "" certificate_thumbprint = None private_key = None self.ms_client = MicrosoftClient( self_deployed=True, tenant_id=tenant_id, token_retrieval_url=token_retrieval_url, auth_id=client_id, enc_key=client_secret, grant_type=grant_type, base_url=f"https://management.azure.com/subscriptions/{subscription_id}" f"/resourceGroups/{resource_group}/providers/Microsoft.Network", scope=scope, verify=verify, proxy=proxy, certificate_thumbprint=certificate_thumbprint, private_key=private_key, managed_identities_client_id=managed_identities_client_id, managed_identities_resource_uri=Resources.management_azure, command_prefix="azure-firewall", ) def azure_firewall_list_request(self, resource: str, next_link: str = None) -> dict: """ List azure firewalls in resource group or subscription. Args: resource (str): The resource which contains the firewalls to list. next_link (str): URL to retrieve the next set of results. Returns: dict: API response from Azure. """ if next_link: full_url = next_link response = self.ms_client.http_request("GET", full_url=full_url, resp_type="json", timeout=100) return response if resource == "resource_group": full_url = ( f"https://management.azure.com/subscriptions/{self.subscription_id}" f"/resourceGroups/{self.resource_group}/providers/Microsoft.Network/azureFirewalls" ) else: full_url = ( f"https://management.azure.com/subscriptions/{self.subscription_id}" f"/providers/Microsoft.Network/azureFirewalls" ) response = self.ms_client.http_request( "GET", full_url=full_url, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_get_request(self, firewall_name: str) -> dict: """ Retrieve azure firewall information. Args: firewall_name (str): The name of the azure firewall to retrieve. Returns: dict: API response from Azure. """ url_suffix = f"azureFirewalls/{firewall_name}" response = self.ms_client.http_request( "GET", url_suffix=url_suffix, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_update_request(self, firewall_name: str, firewall_data: dict) -> dict: """ Update firewall resource. Args: firewall_name (str): The name of the firewall to update. firewall_data (dict): Firewall resource JSON information. Returns: dict: API response from Azure. """ url_suffix = f"azureFirewalls/{firewall_name}" response = self.ms_client.http_request( "PUT", url_suffix=url_suffix, params=self.default_params, json_data=firewall_data, resp_type="json", timeout=100 ) return response def azure_firewall_policy_create_request( self, policy_name: str, threat_intelligence_mode: str, ip_address: list, domain_address: list, location: str, tier: str, base_policy_id: str, enable_proxy: bool, dns_servers: list, ) -> dict: """ Create firewall policy. Args: policy_name (str): The name of the azure policy to create. threat_intelligence_mode (str): The operation mode for Threat Intelligence. ip_address (list): IP addresses for the threat intelligence whitelist. domain_address (list): Fully qualified domain name for the threat intelligence whitelist. location (str): Policy resource region location. tier (str): Tier of an Azure Policy. base_policy_id (str): The ID of the parent firewall policy from which rules are inherited. enable_proxy (bool): Enable DNS Proxy on Firewalls attached to the Firewall Policy. dns_servers (list): Custom DNS Servers. Returns: dict: API response from Azure. """ data = remove_empty_elements( { "location": location, "properties": { "threatIntelMode": threat_intelligence_mode, "threatIntelWhitelist": {"ipAddresses": ip_address, "fqdns": domain_address}, "snat": {"privateRanges": None}, "dnsSettings": {"servers": dns_servers, "enableProxy": enable_proxy}, "basePolicy": {"id": base_policy_id}, "sku": {"tier": tier}, }, } ) url_suffix = f"firewallPolicies/{policy_name}" response = self.ms_client.http_request( "PUT", url_suffix=url_suffix, params=self.default_params, json_data=data, resp_type="json", timeout=100 ) return response def azure_firewall_policy_update_request(self, policy_name: str, policy_data: dict) -> dict: """ Update policy resource. Args: policy_name (str): The name of the policy resource to update. policy_data (dict): Policy resource JSON information. Returns: dict: API response from Azure. """ url_suffix = f"firewallPolicies/{policy_name}" response = self.ms_client.http_request( "PUT", url_suffix=url_suffix, params=self.default_params, json_data=policy_data, resp_type="json", timeout=100 ) return response def azure_firewall_policy_get_request(self, policy_name: str) -> dict: """ Retrieve policy information. Args: policy_name (str): The name of the policy to retrieve. Returns: dict: API response from Azure. """ url_suffix = f"firewallPolicies/{policy_name}" response = self.ms_client.http_request( "GET", url_suffix=url_suffix, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_policy_delete_request(self, policy_name: str) -> Response: """ Delete policy resource. Args: policy_name (str): The name of the policy to delete. Returns: Response: API response from Azure. """ url_suffix = f"firewallPolicies/{policy_name}" response = self.ms_client.http_request( "DELETE", url_suffix=url_suffix, params=self.default_params, resp_type="response", timeout=100 ) return response def azure_firewall_policy_list_request(self, resource: str, next_link: str = None) -> dict: """ List policies in resource group or subscription. Args: resource (str): The resource which contains the policy to list. next_link (str): URL to retrieve the next set of results. Returns: dict: API response from Azure. """ if next_link: full_url = next_link response = self.ms_client.http_request("GET", full_url=full_url, resp_type="json", timeout=100) return response if resource == "resource_group": full_url = ( f"https://management.azure.com/subscriptions/{self.subscription_id}" f"/resourceGroups/{self.resource_group}/providers/Microsoft.Network/firewallPolicies" ) else: full_url = ( f"https://management.azure.com/subscriptions/{self.subscription_id}" f"/providers/Microsoft.Network/firewallPolicies" ) response = self.ms_client.http_request( "GET", full_url=full_url, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_policy_rule_collection_create_or_update_request( self, policy_name: str, collection_name: str, collection_data: dict ) -> dict: """ Create or update policy rule collection. Args: policy_name (str): The name of the policy which contains the collection. collection_name (str): The name of the rule collection to create or update. collection_data (dict): Rule collection information. Returns: dict: API response from Azure. """ url_suffix = f"firewallPolicies/{policy_name}/ruleCollectionGroups/{collection_name}" response = self.ms_client.http_request( "PUT", url_suffix=url_suffix, params=self.default_params, resp_type="json", json_data=collection_data, timeout=100 ) return response def azure_firewall_policy_rule_collection_list_request(self, policy_name: str, next_link: str = None) -> dict: """ List collection rules in policy. Args: policy_name (str): The resource which contains the policy to list. next_link (str): URL to retrieve the next set of results. Returns: dict: API response from Azure. """ if next_link: full_url = next_link response = self.ms_client.http_request("GET", full_url=full_url, resp_type="json", timeout=100) return response url_suffix = f"firewallPolicies/{policy_name}/ruleCollectionGroups" response = self.ms_client.http_request( "GET", url_suffix=url_suffix, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_policy_rule_collection_get_request(self, policy_name: str, collection_name: str) -> dict: """ Retrieve policy collection group information. Args: policy_name (str): The name of the policy which contains the collection. collection_name (str): he name of the policy rule collection to retrieve. Returns: dict: API response from Azure. """ url_suffix = f"firewallPolicies/{policy_name}/ruleCollectionGroups/{collection_name}" response = self.ms_client.http_request( "GET", url_suffix=url_suffix, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_policy_rule_collection_delete_request(self, policy_name: str, collection_name: str) -> Response: """ Delete policy collection group information. Args: policy_name (str): The name of the policy which contains the collection. collection_name (str): The name of the policy rule collection to delete. Returns: Response: API response from Azure. """ url_suffix = f"firewallPolicies/{policy_name}/ruleCollectionGroups/{collection_name}" response = self.ms_client.http_request( "DELETE", url_suffix=url_suffix, params=self.default_params, resp_type="response", timeout=100 ) return response def azure_firewall_policy_network_rule_collection_create_request( self, policy_name: str, collection_priority: int | None, collection_name: str, action: str, rule_information: dict ) -> dict: """ Create network rule collection in firewall or policy. Args: policy_name (str): The name of the policy which contains the collection. collection_priority (int): The priority of the nat rule collection resource. collection_name (str): The name of the nat rule collection which contains the rule. action (str): The action type of a rule collection. rule_information (dict): Rule information. Returns: dict: API response from Azure. """ payload = remove_empty_elements( { "properties": { "priority": collection_priority, "ruleCollections": [ { "ruleCollectionType": "FirewallPolicyFilterRuleCollection", "name": collection_name, "priority": collection_priority, "action": {"type": action}, "rules": [rule_information], } ], } } ) url_suffix = f"firewallPolicies/{policy_name}/ruleCollectionGroups/{collection_name}" response = self.ms_client.http_request( "PUT", url_suffix=url_suffix, params=self.default_params, json_data=payload, resp_type="json", timeout=100 ) return response def azure_firewall_service_tag_list_request(self, location: str, next_link: str = None) -> dict: """ Retrieve service tag information resources. Args: location (str): The location that will be used as a reference for version next_link (str): URL to retrieve the next set of results. Returns: dict: API response from Azure. """ if next_link: full_url = next_link response = self.ms_client.http_request("GET", full_url=full_url, resp_type="json", timeout=100) return response full_url = ( f"https://management.azure.com/subscriptions/{self.subscription_id}" f"/providers/Microsoft.Network/locations/{location}/serviceTagDetails" ) response = self.ms_client.http_request("GET", full_url=full_url, resp_type="json", params=self.default_params) return response def azure_firewall_ip_group_create_request(self, ip_group_name: str, location: str, ip_address: list = None) -> dict: """ Create IP group resource. Args: ip_group_name (str): The name of the IP group resource to create. location (str): The location of the IP group resource. ip_address (list): IP addresses or IP address prefixes in the IP group resource. Returns: dict: API response from Azure. """ payload = remove_empty_elements({"location": location, "properties": {"ipAddresses": ip_address}}) url_suffix = f"ipGroups/{ip_group_name}" response = self.ms_client.http_request( "PUT", url_suffix=url_suffix, params=self.default_params, json_data=payload, resp_type="json", timeout=100 ) return response def azure_firewall_ip_group_list_request(self, resource: str, next_link: str = None) -> dict: """ List IP Groups in resource group or subscription. Args: resource (str): The resource which contains the IP Groups to list. next_link (str): URL to retrieve the next set of results. Returns: dict: API response from Azure. """ if next_link: full_url = next_link response = self.ms_client.http_request("GET", full_url=full_url, resp_type="json", timeout=100) return response if resource == "resource_group": full_url = ( f"https://management.azure.com/subscriptions/{self.subscription_id}" f"/resourceGroups/{self.resource_group}/providers/Microsoft.Network/ipGroups" ) else: full_url = f"https://management.azure.com/subscriptions/{self.subscription_id}/providers/Microsoft.Network/ipGroups" response = self.ms_client.http_request( "GET", full_url=full_url, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_ip_group_get_request(self, ip_group_name: str) -> dict: """ Retrieve IP group information. Args: ip_group_name (str): The name of the IP group resource to retrieve. Returns: dict: API response from Azure. """ url_suffix = f"ipGroups/{ip_group_name}" response = self.ms_client.http_request( "GET", url_suffix=url_suffix, params=self.default_params, resp_type="json", timeout=100 ) return response def azure_firewall_ip_group_delete_request(self, ip_group_name: str) -> Response: """ Delete IP group resource. Args: ip_group_name (str): The name of the IP group resource to delete. Returns: Response: API response from Azure. """ url_suffix = f"ipGroups/{ip_group_name}" response = self.ms_client.http_request( "DELETE", url_suffix=url_suffix, params=self.default_params, resp_type="response", timeout=100 ) return response def azure_firewall_ip_group_update_request(self, ip_group_name: str, ip_group_data: dict) -> dict: """ Update IP Group resource. Args: ip_group_name (str): The name of the IP Group resource to update. ip_group_data (dict): IP Group resource JSON information. Returns: dict: API response from Azure. """ url_suffix = f"ipGroups/{ip_group_name}" response = self.ms_client.http_request( "PUT", url_suffix=url_suffix, params=self.default_params, json_data=ip_group_data, resp_type="json", timeout=100 ) return response def azure_firewall_subscriptions_list_request(self) -> dict: """ Gets all subscriptions for a tenant. Returns: List[dict]: API response from Azure. """ full_url = "https://management.azure.com/subscriptions" return self.ms_client.http_request("GET", full_url=full_url, params=self.default_params, resp_type="json", timeout=100) def azure_firewall_resource_group_list_request(self, tag: str, limit: int, full_url: Optional[str] = None) -> dict: """ List all resource groups. Args: tag str: Tag to filter by. limit (int): Maximum number of resource groups to retrieve. Default is 50. full_url (str): URL to retrieve the next set of results. Returns: List[dict]: API response from Azure. """ filter_by_tag = azure_tag_formatter(tag) if tag else None params = {"$filter": filter_by_tag, "$top": limit} | self.default_params if not full_url else {} full_url = full_url if full_url else f"https://management.azure.com/subscriptions/{self.subscription_id}/resourcegroups" return self.ms_client.http_request("GET", full_url=full_url, params=params) def generate_polling_readable_message(resource_type_name: str, resource_name: str) -> str: """ Generate appropriate markdown message for polling commands. Args: resource_type_name (str): The name type of the updated resource. For example: Policy, Firewall, IP-Group, etc. resource_name (str): The name of the updated resource. Returns: str: Polling header message. """ return f"## Polling in progress for {resource_type_name} {resource_name}." def create_scheduled_command(command_name: str, interval: int, timeout: int, **kwargs): """ Create scheduled command object. Args: command_name (str): The command that'll run after next_run_in_seconds has passed. interval (int): How long to wait before executing the command. timeout (int): Number of seconds until the polling sequence will timeout. Returns: ScheduledCommand : ScheduledCommand object """ polling_args = {"interval": interval, "polling": True, "timeout": timeout, **kwargs} return ScheduledCommand( command=command_name, next_run_in_seconds=interval, timeout_in_seconds=timeout, args=polling_args, ) def validate_pagination_arguments(limit: int, page: int) -> None: """ Validate pagination arguments values. Args: limit (int): Number of elements to retrieve. page (int): Page number. """ if page < 1 or limit < 1: raise Exception("Page and limit arguments must be greater than 0.") def get_pagination_readable_message(header: str, limit: int, page: int) -> str: """ Generate pagination commands readable message. Args: header (str): Message header limit (int): Number of elements to retrieve. page (int): Page number. Returns: str: Readable message. """ readable_message = f"{header}\n Current page size: {limit}\n Showing page {page} out others that may exist." return readable_message def generate_firewall_command_output(response: dict | list, readable_header: str, output_key: str = None) -> CommandResults: """ Generate command output for firewall commands. Args: response (dict | list): API response from Azure. output_key (str): Used to access to required data in the response. readable_header (str): Readable message header for XSOAR war room. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ outputs = ( copy.deepcopy(response.get(output_key, [])) if output_key and isinstance(response, dict) else copy.deepcopy(response) ) if not isinstance(outputs, list): outputs = [outputs] readable_data = [] for firewall in outputs: properties = firewall.get("properties", {}) ip_configuration = properties.get("ipConfigurations", []) ip_configuration = ip_configuration[0] if ip_configuration else {} data = { "name": firewall.get("name"), "id": firewall.get("id"), "location": firewall.get("location"), "threat_intel_mode": properties.get("threatIntelMode"), "private_ip_address": dict_safe_get(ip_configuration, ["properties", "privateIPAddress"]), "subnet": dict_safe_get(ip_configuration, ["properties", "subnet", "id"]), "provisioning_state": properties.get("provisioningState"), } readable_data.append(data) readable_output = tableToMarkdown( readable_header, readable_data, headers=["name", "id", "location", "subnet", "threat_intel_mode", "private_ip_address", "provisioning_state"], headerTransform=string_to_table_header, ) command_results = CommandResults( readable_output=readable_output, outputs_prefix="AzureFirewall.Firewall", outputs_key_field="id", outputs=outputs, raw_response=response, ) return command_results def azure_firewall_list_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ List azure firewalls in resource group or subscription. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ resource = args.get("resource", "resource_group") limit = arg_to_number(args.get("limit")) or 50 page = arg_to_number(args.get("page")) or 1 validate_pagination_arguments(limit, page) readable_message = get_pagination_readable_message(header="Firewall List:", limit=limit, page=page) start_offset = (page - 1) * limit end_offset = start_offset + limit complete_requests = False total_response: dict[str, list] = {"value": []} response = client.azure_firewall_list_request(resource=resource) while not complete_requests: total_response["value"].extend(response.get("value", [])) if len(total_response["value"]) >= end_offset or not response.get("nextLink"): complete_requests = True else: response = client.azure_firewall_list_request(resource=resource, next_link=response.get("nextLink")) return generate_firewall_command_output(response.get("value", [])[start_offset:end_offset], readable_header=readable_message) def azure_firewall_get_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Retrieve azure firewall information. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() firewall_names = argToList(args.get("firewall_names")) scheduled = argToBoolean(args.get("polling", False)) interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 command_results_list: List[CommandResults] = [] for firewall in firewall_names: try: response = client.azure_firewall_get_request(firewall) state = dict_safe_get(response, ["properties", "provisioningState"], "") if scheduled and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall ) # result with scheduled_command only - no update to the war room command_results_list.append( CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall), ) ) else: command_results = generate_firewall_command_output(response, readable_header=f"Firewall {firewall} information:") command_results_list.append(command_results) except Exception as exception: error = CommandResults(readable_output=f"An error occurred while retrieving {firewall}.\n {exception}") command_results_list.append(error) return command_results_list def get_firewall_rule_collection_name(rule_type: str) -> str: """ Get firewall rule collection API name convention. Args: rule_type (str): Command rule type name convention. Returns: str: Azure collection API name convention. """ rule_types = { "network_rule": "networkRuleCollections", "application_rule": "applicationRuleCollections", "nat_rule": "natRuleCollections", } return rule_types.get(rule_type, "") def get_policy_rule_collection_name(rule_type: str) -> str: """ Get policy rule collection API name convention. Args: rule_type (str): Command rule type name convention. Returns: str: Azure collection API name convention. """ rule_types = { "network_rule": "FirewallPolicyFilterRuleCollection", "application_rule": "FirewallPolicyFilterRuleCollection", "nat_rule": "FirewallPolicyNatRuleCollection", } return rule_types.get(rule_type, "") def get_policy_rule_name(rule_type: str) -> str: """ Get policy rule API name convention. Args: rule_type (str): Command rule type name convention. Returns: str: Azure collection API name convention. """ rule_types = {"network_rule": "NetworkRule", "application_rule": "ApplicationRule", "nat_rule": "NatRule"} return rule_types.get(rule_type, "") def generate_rule_collection_output( rule_collection_response: dict, readable_header: str, outputs: list, is_firewall_collection: bool ) -> CommandResults: """ Generate command output for rule collection commands. Args: rule_collection_response (dict): API response from Azure. readable_header (str): Readable message header for XSOAR war room. outputs (list): Output for XSOAR platform. is_firewall_collection (bool): Indicates if the rule collection belongs to firewall or policy. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ readable_data = [] if is_firewall_collection: for collection in outputs: collection_name = collection.get("name") collection_priority = dict_safe_get(collection, ["properties", "priority"]) collection_action = dict_safe_get(collection, ["properties", "action", "type"]) data = {"priority": collection_priority, "action": collection_action, "name": collection_name} readable_data.append(data) else: # Policy collection for collection in outputs: collection_action, collection_priority, collection_name = None, None, None collection_data = dict_safe_get(collection, ["properties", "ruleCollections"]) if collection_data and isinstance(collection_data, list): collection_action = dict_safe_get(collection_data[0], ["action", "type"]) collection_name = collection_data[0].get("name") collection_priority = collection_data[0].get("priority") data = {"priority": collection_priority, "action": collection_action, "name": collection_name} readable_data.append(data) readable_output = tableToMarkdown( readable_header, readable_data, headers=["name", "action", "priority"], headerTransform=pascalToSpace ) command_results = CommandResults( readable_output=readable_output, outputs_prefix="AzureFirewall.RuleCollection", outputs_key_field="id", outputs=outputs, raw_response=rule_collection_response, ) return command_results def generate_rule_output(response: dict, readable_header: str, outputs: list) -> CommandResults: """ Generate command output for rule commands. Args: response (dict): API response from Azure. readable_header (str): Readable message header for XSOAR war room. outputs (list): Output for XSOAR platform. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ readable_output = tableToMarkdown(readable_header, outputs, headers=["name"], headerTransform=pascalToSpace) command_results = CommandResults( readable_output=readable_output, outputs_prefix="AzureFirewall.Rule", outputs_key_field="name", outputs=outputs, raw_response=response, ) return command_results def filter_policy_rules_collection(rules_collections: list, rule_type: str) -> list: """ Filter policy rules collection by the rule type. Args: rules_collections (list): Rules collection from API response. rule_type (str): Rule type to filter. Returns: list: Filtered rules collection. """ if not rules_collections: return [] collection_key = get_policy_rule_collection_name(rule_type=rule_type) rule_key = get_policy_rule_name(rule_type=rule_type) collections = [] for collection in rules_collections: current_collections = dict_safe_get(collection, ["properties", "ruleCollections"], []) if isinstance(current_collections, list) and len(current_collections) > 0: rule_collection = current_collections[0] if ( rule_collection.get("ruleCollectionType") == collection_key and isinstance(rule_collection.get("rules"), list) and len(rule_collection.get("rules")) > 0 and rule_collection.get("rules")[0].get("ruleType") == rule_key ): collections.append(collection) return collections def get_firewall_rule_collection(client: AzureFirewallClient, firewall_name: str, rule_type: str) -> tuple: """ Retrieve firewall rule collections. Args: client (AzureFirewallClient): Azure Firewall API client. firewall_name (str): The name of the firewall which contains the collection. rule_type (str): The name of the rule collection type to retrieve. Returns: tuple: response, rule_collections """ response = client.azure_firewall_get_request(firewall_name=firewall_name) rule_type_key = get_firewall_rule_collection_name(rule_type) filtered_rules = dict_safe_get(response, ["properties", rule_type_key]) return response, filtered_rules def azure_firewall_rules_collection_list_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ List collection rules in firewall or in policy. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ firewall_name = args.get("firewall_name") policy = args.get("policy") rule_type = args.get("rule_type", "") limit = arg_to_number(args.get("limit")) or 50 page = arg_to_number(args.get("page")) or 1 validate_pagination_arguments(limit, page) start_offset = (page - 1) * limit end_offset = start_offset + limit resource = firewall_name or policy readable_message = get_pagination_readable_message(header=f"{resource} Rule Collections List:", limit=limit, page=page) if firewall_name: response, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type) filtered_rules = filtered_rules[start_offset:end_offset] else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") complete_requests = False total_response: dict[str, list] = {"value": []} response = client.azure_firewall_policy_rule_collection_list_request(policy_name=policy) while not complete_requests: total_response["value"].extend(response.get("value", [])) if not response.get("nextLink"): complete_requests = True else: response = client.azure_firewall_policy_rule_collection_list_request( policy_name=policy, next_link=response.get("nextLink") ) filtered_rules = filter_policy_rules_collection(total_response.get("value", []), rule_type)[start_offset:end_offset] return generate_rule_collection_output( rule_collection_response=response, readable_header=readable_message, outputs=filtered_rules, is_firewall_collection=firewall_name is not None, ) def get_policy_collection_rules(client: AzureFirewallClient, policy: str, collection_name: str) -> tuple: """ Retrieve rules of policy rules collection. Args: client (AzureFirewallClient): Azure Firewall API client. policy (str): The name of the policy which contains the rule collection. collection_name (str): The name of the collection which contains the rules. Returns: tuple: API response , rules list """ rules = [] response = client.azure_firewall_policy_rule_collection_get_request(policy_name=policy, collection_name=collection_name) rules_path = ["properties", "ruleCollections"] rule_collections = dict_safe_get(response, rules_path) if isinstance(rule_collections, list) and len(rule_collections) > 0: rules = rule_collections[0].get("rules") return response, rules def azure_firewall_rules_list_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ List rules in firewall or in policy. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ firewall_name = args.get("firewall_name") policy = args.get("policy") rule_type = args.get("rule_type", "") collection_name = args.get("collection_name", "") limit = arg_to_number(args.get("limit")) or 50 page = arg_to_number(args.get("page")) or 1 validate_pagination_arguments(limit, page) start_offset = (page - 1) * limit end_offset = start_offset + limit rules = [] if firewall_name: if not rule_type: raise Exception("The `rule_type` argument must be provided for firewall rules.") response, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type) readable_message = get_pagination_readable_message( header=f"Firewall {firewall_name} {rule_type} Rules List:", limit=limit, page=page ) rules_path = ["properties", "rules"] for rule_collection in filtered_rules: if rule_collection.get("name") == collection_name: rules = dict_safe_get(rule_collection, rules_path) break if not rules: raise Exception(f"Collection {collection_name} is not exists in {firewall_name} firewall.") else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") readable_message = get_pagination_readable_message( header=f"Policy {policy} {rule_type} Rules List:", limit=limit, page=page ) response, rules = get_policy_collection_rules(client=client, policy=policy, collection_name=collection_name) return generate_rule_output(response=response, readable_header=readable_message, outputs=rules[start_offset:end_offset]) def azure_firewall_rule_get_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Retrieve rule information. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ firewall_name = args.get("firewall_name") policy = args.get("policy") rule_type = args.get("rule_type", "") collection_name = args.get("collection_name", "") rule_name = args.get("rule_name", "") rule_data = None if firewall_name: if not rule_type: raise Exception("The `rule_type` argument must be provided for firewall rules.") response, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type) rules_path = ["properties", "rules"] for rule_collection in filtered_rules: if rule_collection.get("name") == collection_name: rules = dict_safe_get(rule_collection, rules_path) for rule in rules: if rule.get("name") == rule_name: rule_data = rule break if rule_data: break else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") response, rules = get_policy_collection_rules(client=client, policy=policy, collection_name=collection_name) for rule in rules: if rule.get("name") == rule_name: rule_data = rule break if not rule_data: raise Exception(f"Rule {rule_name} is not exists.") return generate_rule_output(response=response, readable_header=f"Rule {rule_name} Information:", outputs=rule_data) def azure_firewall_policy_create_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Create firewall policy. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 policy_name = args.get("policy_name", "") threat_intelligence_mode = args.get("threat_intelligence_mode", "Turned-off") threat_intelligence_mode = "Off" if threat_intelligence_mode == "Turned-off" else threat_intelligence_mode ip_address = argToList(args.get("ips")) domain_address = argToList(args.get("domains")) location = args.get("location", "") tier = args.get("tier", "Standard") base_policy_id = args.get("base_policy_id", "") enable_proxy = argToBoolean(args.get("enable_proxy", "False")) dns_servers = argToList(args.get("dns_servers")) response = client.azure_firewall_policy_create_request( policy_name, threat_intelligence_mode, ip_address, domain_address, location, tier, base_policy_id, enable_proxy, dns_servers, ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy_name), ) return generate_policy_command_output(response, readable_header=f'Successfully Created Policy "{policy_name}"') def dict_nested_set(dictionary: dict, keys: list, value: Any) -> None: """ Set nested dictionary value. Args: dictionary (dict): Dictionary to set. keys (list): Keys for recursive get. value (Any): Required value. """ keys = argToList(keys) for key in keys[:-1]: dictionary = dictionary.setdefault(key, {}) dictionary[keys[-1]] = value def azure_firewall_policy_update_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Update policy resource. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 policy_name = args.get("policy_name", "") threat_intelligence_mode = args.get("threat_intelligence_mode", "") threat_intelligence_mode = "Off" if threat_intelligence_mode == "Turned-off" else threat_intelligence_mode ip_address = argToList(args.get("ips")) domain_address = argToList(args.get("domains")) base_policy_id = args.get("base_policy_id") enable_proxy = argToBoolean(args.get("enable_proxy")) if args.get("enable_proxy") else None dns_servers = argToList(args.get("dns_servers")) policy_data = client.azure_firewall_policy_get_request(policy_name=policy_name) properties = policy_data.get("properties", {}) update_fields = assign_params( threat_intelligence_mode=threat_intelligence_mode, ips=ip_address, domains=domain_address, base_policy_id=base_policy_id, enable_proxy=enable_proxy, dns_servers=dns_servers, ) policy_fields_mapper = { "threat_intelligence_mode": ["threatIntelMode"], "ips": ["threatIntelWhitelist", "ipAddresses"], "domains": ["threatIntelWhitelist", "fqdns"], "base_policy_id": ["basePolicy", "id"], "enable_proxy": ["dnsSettings", "enableProxy"], "dns_servers": ["dnsSettings", "servers"], } for field_key, value in update_fields.items(): key_path = policy_fields_mapper.get(field_key, []) dict_nested_set(properties, key_path, value) response = client.azure_firewall_policy_update_request(policy_name=policy_name, policy_data=policy_data) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy_name), ) return generate_policy_command_output(response, readable_header=f'Successfully Updated Policy "{policy_name}"') def generate_policy_command_output(response: dict | list, readable_header: str, output_key: str = None) -> CommandResults: """ Generate command output for policy commands. Args: response (dict | list): API response from Azure. output_key (str): Used to access to required data in the response. readable_header (str): Readable message header for XSOAR war room. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ outputs = ( copy.deepcopy(response.get(output_key, [])) if output_key and isinstance(response, dict) else copy.deepcopy(response) ) if not isinstance(outputs, list): outputs = [outputs] readable_data = [] for policy in outputs: name = policy.get("name") id = policy.get("id") location = policy.get("location") properties = policy.get("properties", {}) threat_intel_mode = properties.get("threatIntelMode") tier = dict_safe_get(properties, ["sku", "tier"]) child_policies = properties.get("childPolicies", []) child_policies = [child_policy.get("id") for child_policy in child_policies] firewalls = properties.get("firewalls", {}) firewalls = [firewall.get("id") for firewall in firewalls] base_policy = dict_safe_get(properties, ["basePolicy", "id"]) provisioning_state = properties.get("provisioningState") data = { "name": name, "location": location, "threat_intel_mode": threat_intel_mode, "child_policies": child_policies, "firewalls": firewalls, "base_policy": base_policy, "provisioning_state": provisioning_state, "id": id, "tier": tier, } readable_data.append(data) readable_output = tableToMarkdown( readable_header, readable_data, headers=["name", "id", "tier", "location", "firewalls", "base_policy", "child_policies", "provisioning_state"], headerTransform=string_to_table_header, ) command_results = CommandResults( readable_output=readable_output, outputs_prefix="AzureFirewall.Policy", outputs_key_field="id", outputs=outputs, raw_response=response, ) return command_results def azure_firewall_policy_get_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Retrieve policy information. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() policy_names = argToList(args.get("policy_names")) scheduled = argToBoolean(args.get("polling", False)) interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 command_results_list: List[CommandResults] = [] for policy in policy_names: try: response = client.azure_firewall_policy_get_request(policy) state = dict_safe_get(response, ["properties", "provisioningState"], "") if scheduled and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy ) # result with scheduled_command only - no update to the war room command_results_list.append( CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy), ) ) else: command_results_list.append( generate_policy_command_output(response, readable_header=f"Policy {policy} information:") ) except Exception as exception: error = CommandResults(readable_output=f"An error occurred while retrieving {policy}.\n {exception}") command_results_list.append(error) return command_results_list def azure_firewall_policy_delete_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Delete policy resource. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ policy_names = argToList(args.get("policy_names")) command_results_list: List[CommandResults] = [] for policy in policy_names: try: response = client.azure_firewall_policy_delete_request(policy) if response.status_code == 202: readable_output = f"Policy {policy} delete operation accepted and will complete asynchronously." else: readable_output = f"Policy {policy} deleted successfully." command_results_list.append(CommandResults(readable_output=readable_output)) except Exception as exception: error = CommandResults(readable_output=f"An error occurred while deleting {policy}.\n {exception}") command_results_list.append(error) return command_results_list def azure_firewall_policy_list_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ List policy in resource group or subscription. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ resource = args.get("resource", "resource_group") limit = arg_to_number(args.get("limit")) or 50 page = arg_to_number(args.get("page")) or 1 validate_pagination_arguments(limit, page) readable_message = get_pagination_readable_message(header="Policy List:", limit=limit, page=page) start_offset = (page - 1) * limit end_offset = start_offset + limit complete_requests = False total_response: dict[str, list] = {"value": []} response = client.azure_firewall_policy_list_request(resource=resource) while not complete_requests: total_response["value"].extend(response.get("value", [])) if len(total_response["value"]) >= end_offset or not response.get("nextLink"): complete_requests = True else: response = client.azure_firewall_policy_list_request(resource=resource, next_link=response.get("nextLink")) return generate_policy_command_output( total_response.get("value", [])[start_offset:end_offset], readable_header=readable_message ) def azure_firewall_policy_attach_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Attach policy to firewall. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() firewall_names = argToList(args.get("firewall_names")) policy_id = args.get("policy_id") should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 command_results_list: List[CommandResults] = [] for firewall in firewall_names: try: firewall_data = client.azure_firewall_get_request(firewall_name=firewall) firewall_data["properties"]["firewallPolicy"] = {"id": policy_id} response = client.azure_firewall_update_request(firewall_name=firewall, firewall_data=firewall_data) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall ) # result with scheduled_command only - no update to the war room command_results_list.append( CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall), ) ) else: command_results_list.append( generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall}"') ) except Exception as exception: error = CommandResults(readable_output=f"An error occurred while updating {firewall}.\n {exception}") command_results_list.append(error) return command_results_list def azure_firewall_policy_remove_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Remove policy from firewall. This command will detach between policy and firewall, and not delete the policy. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 firewall_names = argToList(args.get("firewall_names")) command_results_list: List[CommandResults] = [] for firewall in firewall_names: try: firewall_data = client.azure_firewall_get_request(firewall_name=firewall) firewall_data["properties"].pop("firewallPolicy", None) response = client.azure_firewall_update_request(firewall_name=firewall, firewall_data=firewall_data) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall ) # result with scheduled_command only - no update to the war room command_results_list.append( CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall), ) ) else: command_results_list.append( generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall}"') ) except Exception as exception: error = CommandResults(readable_output=f"An error occurred while updating {firewall}.\n {exception}") command_results_list.append(error) return command_results_list def delete_rule_collection( client: AzureFirewallClient, collection_name: str, rule_type: str, firewall_name: str = None, policy: str = None, should_poll: bool = False, interval: int = 30, timeout: int = 60, ) -> CommandResults: """ Delete rule collection from firewall or policy. Args: client (AzureFirewallClient): Azure Firewall API client. collection_name (str): The name of the rule collection to delete. rule_type (str): The name of the rule collection type. firewall_name (str): The name of the firewall which contains the collection. policy (str): The name of the policy which contains the collection. should_poll (bool): Use Cortex XSOAR built-in polling to retrieve the resource when it's finished the updating process. interval (int): Indicates how long to wait between command execution. timeout (int): Indicates the time in seconds until the polling sequence timeouts. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ if firewall_name: firewall_data, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type=rule_type) collection_index = -1 for index, collection in enumerate(filtered_rules): if collection.get("name") == collection_name: collection_index = index break if collection_index == -1: raise Exception(f"Collection {collection_name} is not exists in {firewall_name} firewall.") del filtered_rules[collection_index] response: dict = client.azure_firewall_update_request(firewall_name=firewall_name, firewall_data=firewall_data) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall_name), ) else: return generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall_name}"') else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") response_delete = client.azure_firewall_policy_rule_collection_delete_request( policy_name=policy, collection_name=collection_name ) is_resource_deleted = response_delete.status_code == 200 if should_poll and not is_resource_deleted: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy), ) response = client.azure_firewall_policy_get_request(policy) return generate_policy_command_output(response, readable_header=f'Successfully Updated Policy "{policy}"') def add_rule_to_policy_collection( client: AzureFirewallClient, policy: str, collection_name: str, rule_object: dict, rule_name: str ) -> dict: """ Add rule to policy rule collection Args: client (AzureFirewallClient): Azure Firewall API client. policy (str): The name of the policy which contains the collection. collection_name (str): The name of the rule collection which contains the rule. rule_object (dict): Policy rule information. rule_name (str): The name of the rule to create. Returns: dict: API response from Azure. """ collection_information = client.azure_firewall_policy_rule_collection_get_request( policy_name=policy, collection_name=collection_name ) for rule in collection_information["properties"]["ruleCollections"][0]["rules"]: if rule.get("name") == rule_name: raise Exception(f"Rule {rule_name} already exists.") collection_information["properties"]["ruleCollections"][0]["rules"].append(rule_object) return client.azure_firewall_policy_rule_collection_create_or_update_request( policy_name=policy, collection_name=collection_name, collection_data=collection_information ) def remove_rule_from_collection( client: AzureFirewallClient, collection_name: str, rule_type: str, rule_names: list, firewall_name: str = None, policy: str = None, should_poll: bool = False, interval: int = 30, timeout: int = 60, ) -> list: """ Remove rule from collection in firewall or policy. Args: client (AzureFirewallClient): Azure Firewall API client. collection_name (str): The name of the rule collection which contains the rule. rule_type (str): The name of the rule collection type. rule_names (list): The name of the rule to remove. firewall_name (str): The name of the firewall which contains the collection. policy (str): The name of the policy which contains the collection. should_poll (bool): Use Cortex XSOAR built-in polling to retrieve the resource when it's finished the updating process. interval (int): Indicates how long to wait between command execution. timeout (int): Indicates the time in seconds until the polling sequence timeouts. Returns: list[CommandResults]: outputs, readable outputs and raw response for XSOAR. """ command_results_list: List[CommandResults] = [] if firewall_name: firewall_data, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type=rule_type) collection_index = -1 for index, collection in enumerate(filtered_rules): if collection.get("name") == collection_name: collection_index = index break if collection_index == -1: raise Exception(f"Collection {collection_name} is not exists.") for rule_name in rule_names: rule_index = -1 for index, rule in enumerate(dict_safe_get(filtered_rules[collection_index], ["properties", "rules"], [])): if rule.get("name") == rule_name: rule_index = index break if rule_index == -1: error = CommandResults(readable_output=f"Rule {rule_name} is not exists.") command_results_list.append(error) continue del filtered_rules[collection_index]["properties"]["rules"][rule_index] response = client.azure_firewall_update_request(firewall_name=firewall_name, firewall_data=firewall_data) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall_name ) command_results_list.append( CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall_name), ) ) else: command_results_list.append( generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall_name}"') ) else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") collection_information = client.azure_firewall_policy_rule_collection_get_request( policy_name=policy, collection_name=collection_name ) rules = collection_information["properties"]["ruleCollections"][0]["rules"] for rule_name in rule_names: rule_index = -1 for index, rule in enumerate(rules): if rule.get("name") == rule_name: rule_index = index if rule_index == -1: error = CommandResults(readable_output=f"Rule {rule_name} is not exists.") command_results_list.append(error) continue del rules[rule_index] response = client.azure_firewall_policy_rule_collection_create_or_update_request( policy_name=policy, collection_name=collection_name, collection_data=collection_information ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy ) command_results_list.append( CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy), ) ) else: response = client.azure_firewall_policy_get_request(policy) command_results_list.append( generate_policy_command_output(response, readable_header=f'Successfully Updated Policy "{policy}"') ) return command_results_list def create_firewall_collection(client: AzureFirewallClient, firewall_name: str, rule_type: str, collection_object: dict) -> dict: """ Create firewall rules collection. Args: client (AzureFirewallClient): Azure Firewall API client. firewall_name (str): The name of the firewall which contains the collection. rule_type (str): The name of the rule collection type. collection_object (dict): Collection information. Returns: dict: API response from Azure. """ firewall_data = client.azure_firewall_get_request(firewall_name=firewall_name) rule_type_key = get_firewall_rule_collection_name(rule_type=rule_type) firewall_data["properties"][rule_type_key].append(collection_object) return client.azure_firewall_update_request(firewall_name=firewall_name, firewall_data=firewall_data) def validate_predefined_argument(argument_name: str, argument_value: object, argument_options: list) -> bool: """ Validate predefined argument is a valid option. Args: argument_name (str): The name of the argument to validate. argument_value (object): The value of the argument to validate. argument_options (list): Argument predifuend options. Returns: bool: True if the argument is valid, otherwise raise an exception. """ if not isinstance(argument_value, list): argument_value = [argument_value] for value in argument_value: if value not in argument_options: raise Exception(f"Invalid {argument_name} argument. Please provide one of the following options:{argument_options!s}") return True def validate_network_rule_properties( source_type: str, destination_type: str, protocols: list, ip_source_address: list = None, source_ip_group_ids: list = None ) -> bool: """ Validate the provided network rule properties are valid. Args: source_type (str): Rule source type. destination_type (str): protocols (list): Protocols for the created rule ip_source_address (str): Source IP addresses for the created rule source_ip_group_ids (str): Source IP group IDs for the created rule. Returns: bool: True if the properties are valid, otherwise raise an exception. """ validate_predefined_argument( argument_name="protocols", argument_value=protocols, argument_options=["TCP", "UDP", "ICMP", "Any"] ) validate_predefined_argument( argument_name="source_type", argument_value=source_type, argument_options=["ip_address", "ip_group"] ) validate_predefined_argument( argument_name="destination_type", argument_value=destination_type, argument_options=["ip_address", "ip_group", "service_tag", "fqdn"], ) if source_type == "ip_address" and not ip_source_address: raise Exception("`ip_source_address` argument most be provided when `ip_address` argument is provided.") if source_type == "ip_group" and not source_ip_group_ids: raise Exception("`source_ip_group_ids` argument most be provided when `ip_group` argument is provided.") return True def create_firewall_network_rule_object( rule_name: str, description: str, protocol: list, source_type: str, destination_type: str, destinations: list, destination_port: list, ip_source_address: list | None = None, source_ip_group_ids: list | None = None, is_firewall_rule: bool = False, ) -> dict: """ Generate network rule object for firewall resource. Args: rule_name (str): The name of the rule. description (str): The description of the rule. protocol (list): Protocols of the rule. source_type (str): Rule source type. destination_type (str): Rule destination type. destinations (list): Destinations of the rule. destination_port (list): Destination ports ip_source_address (list): Source IP addresses of the rule. source_ip_group_ids (list): Source IP group IDs of the rule. is_firewall_rule (bool): Indicates if the rule belongs to firewall or policy. Returns: dict: Rule object information. """ rule_object = { "name": rule_name, "description": description, "destinationPorts": destination_port, } if source_type == "ip_address": rule_object["sourceAddresses"] = ip_source_address # type: ignore[assignment] else: # source_type == 'ip_group' rule_object["sourceIpGroups"] = source_ip_group_ids # type: ignore[assignment] destination_path = { "ip_address": "destinationAddresses", "ip_group": "destinationIpGroups", "service_tag": "destinationAddresses", "fqdn": "destinationFqdns", } rule_object[destination_path[destination_type]] = destinations if is_firewall_rule: rule_object["protocols"] = protocol else: rule_object["ipProtocols"] = protocol rule_object["ruleType"] = "NetworkRule" return rule_object def azure_firewall_network_rule_collection_create_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Create network rule collection in firewall or policy. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 firewall_name = args.get("firewall_name") policy = args.get("policy") collection_name = args.get("collection_name", "") collection_priority = arg_to_number(args.get("collection_priority")) action = args.get("action", "") rule_name = args.get("rule_name", "") description = args.get("description", "") protocol = argToList(args.get("protocols")) source_type = args.get("source_type", "") # ip_address or ip_group ip_source_address = argToList( args.get("source_ips", []) ) # Must be provided when 'source_type' argument is assigned to 'ip_address'. source_ip_group_ids = argToList( args.get("source_ip_group_ids", []) ) # Must be provided when 'source_type' argument is assigned to 'ip_group'. destination_type = args.get("destination_type", "") # ip_address or ip_group or service_tag or fqdn. destinations = argToList(args.get("destinations")) destination_port = argToList(args.get("destination_ports")) validate_network_rule_properties( source_type=source_type, destination_type=destination_type, protocols=protocol, ip_source_address=ip_source_address, source_ip_group_ids=source_ip_group_ids, ) rule_information = create_firewall_network_rule_object( rule_name=rule_name, description=description, protocol=protocol, source_type=source_type, destination_type=destination_type, destinations=destinations, destination_port=destination_port, ip_source_address=ip_source_address, source_ip_group_ids=source_ip_group_ids, is_firewall_rule=policy is None, ) if firewall_name: collection_object = remove_empty_elements( { "name": collection_name, "properties": {"priority": collection_priority, "action": {"type": action}, "rules": [rule_information]}, } ) response = create_firewall_collection( client=client, firewall_name=firewall_name, rule_type="network_rule", collection_object=collection_object ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall_name), ) else: return generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall_name}"') else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") collection_information = None try: collection_information = client.azure_firewall_policy_rule_collection_get_request( policy_name=policy, collection_name=collection_name ) except NotFoundError: pass if collection_information: raise Exception(f"The collection {collection_name} already exists in policy.") response = client.azure_firewall_policy_network_rule_collection_create_request( policy_name=policy, collection_priority=collection_priority, collection_name=collection_name, action=action, rule_information=rule_information, ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy), ) response = client.azure_firewall_policy_get_request(policy) return generate_policy_command_output(response, readable_header=f'Successfully Updated Policy "{policy}"') def update_policy_rule_collection( client: AzureFirewallClient, policy: str, collection_name: str, priority: int = None, action: str = None ) -> dict: """ Update rule collection in policy Args: client (): policy (str): The name of the policy which contains the collection. collection_name (str): The name of the rule collection to update. priority (int): The priority of the rule collection resource. action (str): The action type of a rule collection. Returns: dict: API response from Azure. """ collection_information = client.azure_firewall_policy_rule_collection_get_request( policy_name=policy, collection_name=collection_name ) rule_collections = dict_safe_get(collection_information, ["properties", "ruleCollections"], []) if action: rule_collections[0]["action"]["type"] = action if priority: rule_collections[0]["priority"] = priority collection_information["properties"]["priority"] = priority return client.azure_firewall_policy_rule_collection_create_or_update_request( policy_name=policy, collection_name=collection_name, collection_data=collection_information ) def azure_firewall_network_rule_collection_update_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Update network rule collection in firewall or policy. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 firewall_name = args.get("firewall_name") policy = args.get("policy") collection_name = args.get("collection_name", "") priority = args.get("priority") if priority: priority = arg_to_number(priority) action = args.get("action") if firewall_name: firewall_data, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type="network_rule") collection_index = -1 for index, collection in enumerate(filtered_rules): if collection.get("name") == collection_name: collection_index = index break if collection_index == -1: raise Exception(f"Collection {collection_name} is not exists in {firewall_name} firewall.") if action: filtered_rules[collection_index]["properties"]["action"]["type"] = action if priority: filtered_rules[collection_index]["properties"]["priority"] = priority response = client.azure_firewall_update_request(firewall_name=firewall_name, firewall_data=firewall_data) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall_name), ) else: return generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall_name}"') else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") response = update_policy_rule_collection( client=client, policy=policy, collection_name=collection_name, priority=priority, action=action ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy), ) response = client.azure_firewall_policy_get_request(policy) return generate_policy_command_output(response, readable_header=f'Successfully Updated Policy "{policy}"') def azure_firewall_network_rule_collection_delete_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Delete network rule collection from firewall or policy. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 firewall_name = args.get("firewall_name") policy = args.get("policy") collection_name = args.get("collection_name", "") return delete_rule_collection( client=client, collection_name=collection_name, rule_type="network_rule", firewall_name=firewall_name, policy=policy, should_poll=should_poll, interval=interval, timeout=timeout, ) def add_rule_to_firewall_collection( client: AzureFirewallClient, firewall_name: str, collection_name: str, rule_type: str, rule_object: dict ) -> dict: """ Add rule to firewall rule collection. Args: client (AzureFirewallClient): Azure Firewall API client. firewall_name (str): The name of the firewall which contains the collection. collection_name (str): The name of the rule collection which contains the rule. rule_type (str) The name of the rule collection type. rule_object (dict): Firewall rule information. Returns: dict: API response from Azure. """ firewall_data, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type=rule_type) collection_index = -1 for index, collection in enumerate(filtered_rules): if collection.get("name") == collection_name: collection_index = index break if collection_index == -1: raise Exception(f"Collection {collection_name} is not exists.") filtered_rules[collection_index]["properties"]["rules"].append(rule_object) return client.azure_firewall_update_request(firewall_name=firewall_name, firewall_data=firewall_data) def azure_firewall_network_rule_create_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Create network rule in firewall or policy rule collection. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 firewall_name = args.get("firewall_name") policy = args.get("policy") collection_name = args.get("collection_name", "") rule_name = args.get("rule_name", "") description = args.get("description", "") protocol = argToList(args.get("protocols")) source_type = args.get("source_type", "") # ip_address or ip_group ip_source_address = argToList( args.get("source_ips", []) ) # Must be provided when 'source_type' argument is assigned to 'ip_address'. source_ip_group_ids = argToList( args.get("source_ip_group_ids", []) ) # Must be provided when 'source_type' argument is assigned to 'ip_group'. destination_type = args.get("destination_type", "") # ip_address or ip_group or service_tag or fqdn. destinations = argToList(args.get("destinations")) destination_port = argToList(args.get("destination_ports")) validate_network_rule_properties( source_type=source_type, destination_type=destination_type, protocols=protocol, ip_source_address=ip_source_address, source_ip_group_ids=source_ip_group_ids, ) rule_information = create_firewall_network_rule_object( rule_name=rule_name, description=description, protocol=protocol, source_type=source_type, destination_type=destination_type, destinations=destinations, destination_port=destination_port, ip_source_address=ip_source_address, source_ip_group_ids=source_ip_group_ids, is_firewall_rule=policy is None, ) if firewall_name: response = add_rule_to_firewall_collection( client=client, firewall_name=firewall_name, collection_name=collection_name, rule_type="network_rule", rule_object=rule_information, ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall_name), ) else: return generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall_name}"') else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") response = add_rule_to_policy_collection( client=client, policy=policy, collection_name=collection_name, rule_object=rule_information, rule_name=rule_name ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy), ) response = client.azure_firewall_policy_get_request(policy) return generate_policy_command_output(response, readable_header=f'Successfully Updated Policy "{policy}"') def update_firewall_collection_rule( client: AzureFirewallClient, firewall_name: str, collection_name: str, rule_name: str, rule_type: str, rule_fields_mapper: dict, update_fields: dict, ) -> dict: """ Update rule in firewall rules collection. Args: client (AzureFirewallClient): Azure Firewall API client. firewall_name (str): The name of the firewall which contains the collection. collection_name (str): The name of the rule collection which contains the rule. rule_name (str): The name of the rule to update rule_type (str): The name of the rule collection type. rule_fields_mapper (dict): Mapper between field name and Azure field name convention. update_fields (dict): New rule information to update. Returns: dict: API response from Azure. """ firewall_data, filtered_rules = get_firewall_rule_collection(client, firewall_name, rule_type=rule_type) collection_index = -1 rule_found = False for index, collection in enumerate(filtered_rules): if collection.get("name") == collection_name: collection_index = index break if collection_index == -1: raise Exception(f"Collection {collection_name} is not exists.") for rule in dict_safe_get(filtered_rules[collection_index], ["properties", "rules"], []): if rule.get("name") == rule_name: rule_found = True for field_key, value in update_fields.items(): key_path = rule_fields_mapper.get(field_key, []) rule[key_path] = value break if not rule_found: raise Exception(f"Rule {rule_name} is not exists.") return client.azure_firewall_update_request(firewall_name=firewall_name, firewall_data=firewall_data) def update_policy_collection_rule( client: AzureFirewallClient, policy: str, collection_name: str, rule_name: str, rule_fields_mapper: dict, update_fields: dict ) -> dict: """ Update rule in policy rules collection. Args: client (AzureFirewallClient): Azure Firewall API client. policy (str): The name of the policy which contains the collection. collection_name (str): The name of the rule collection which contains the rule. rule_name (str): The name of the rule to update rule_fields_mapper (dict): Mapper between field name and Azure field name convention. update_fields (dict): New rule information to update. Returns: dict: API response from Azure. """ collection_information = client.azure_firewall_policy_rule_collection_get_request( policy_name=policy, collection_name=collection_name ) rules = collection_information["properties"]["ruleCollections"][0]["rules"] rule_found = False for rule in rules: if rule.get("name") == rule_name: rule_found = True for field_key, value in update_fields.items(): key_path = rule_fields_mapper.get(field_key, []) rule[key_path] = value break if not rule_found: raise Exception(f"Rule {rule_name} is not exists.") return client.azure_firewall_policy_rule_collection_create_or_update_request( policy_name=policy, collection_name=collection_name, collection_data=collection_information ) def azure_firewall_network_rule_update_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Update network rule in firewall or policy collection. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 firewall_name = args.get("firewall_name") policy = args.get("policy") collection_name = args.get("collection_name", "") rule_name = args.get("rule_name", "") description = args.get("description", "") protocol = argToList(args.get("protocols")) ip_source_address = argToList(args.get("source_ips")) source_ip_group_ids = argToList(args.get("source_ip_group_ids")) destination_port = argToList(args.get("destination_ports")) destination_type = args.get("destination_type", "") source_type = args.get("source_type", "") destinations = argToList(args.get("destinations")) update_fields = assign_params(description=description, destination_port=destination_port, protocol=protocol) rule_fields_mapper = {"description": "description", "destination_port": "destinationPorts"} if source_type: if source_type == "ip_address": rule_fields_mapper["ip_source_address"] = "sourceAddresses" update_fields["ip_source_address"] = ip_source_address else: # source_type == 'ip_group' rule_fields_mapper["ip_source_address"] = "sourceIpGroups" update_fields["ip_source_address"] = source_ip_group_ids if destinations: destination_path = { "ip_address": "destinationAddresses", "ip_group": "destinationIpGroups", "service_tag": "destinationAddresses", "fqdn": "destinationFqdns", } rule_fields_mapper["ip_destination_address"] = destination_path[destination_type] update_fields["ip_destination_address"] = destinations if firewall_name: if protocol: rule_fields_mapper["protocol"] = "protocols" response = update_firewall_collection_rule( client=client, firewall_name=firewall_name, collection_name=collection_name, rule_name=rule_name, rule_type="network_rule", rule_fields_mapper=rule_fields_mapper, update_fields=update_fields, ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-get", interval=interval, timeout=timeout, firewall_names=firewall_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Firewall", resource_name=firewall_name), ) else: return generate_firewall_command_output(response, readable_header=f'Successfully Updated Firewall "{firewall_name}"') else: if not policy: raise Exception("One of the arguments: `firewall_name` or `policy` must be provided.") if protocol: rule_fields_mapper["protocol"] = "ipProtocols" response = update_policy_collection_rule( client=client, policy=policy, collection_name=collection_name, rule_name=rule_name, rule_fields_mapper=rule_fields_mapper, update_fields=update_fields, ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-policy-get", interval=interval, timeout=timeout, policy_names=policy ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="Policy", resource_name=policy), ) response = client.azure_firewall_policy_get_request(policy) return generate_policy_command_output(response, readable_header=f'Successfully Updated Policy "{policy}"') def azure_firewall_network_rule_remove_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Remove network rule from rules collection. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: list[CommandResults]: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 firewall_name = args.get("firewall_name") policy = args.get("policy") collection_name = args.get("collection_name", "") rule_names = argToList(args.get("rule_names")) return remove_rule_from_collection( client=client, collection_name=collection_name, rule_type="network_rule", rule_names=rule_names, firewall_name=firewall_name, policy=policy, should_poll=should_poll, interval=interval, timeout=timeout, ) def azure_firewall_service_tag_list_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Retrieve service tags information. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ location = args.get("location", "") limit = arg_to_number(args.get("limit")) or 50 page = arg_to_number(args.get("page")) or 1 validate_pagination_arguments(limit, page) readable_message = get_pagination_readable_message(header="Service Tag List:", limit=limit, page=page) start_offset = (page - 1) * limit end_offset = start_offset + limit complete_requests = False total_response: dict[str, list] = {"value": []} response = client.azure_firewall_service_tag_list_request(location=location) while not complete_requests: total_response["value"].extend(response.get("value", [])) if len(total_response["value"]) >= end_offset or not response.get("nextLink"): complete_requests = True else: response = client.azure_firewall_service_tag_list_request(location=location, next_link=response.get("nextLink")) readable_output = tableToMarkdown( readable_message, total_response.get("value", [])[start_offset:end_offset], headers=["name", "id"], headerTransform=string_to_table_header, ) command_results = CommandResults( readable_output=readable_output, outputs_prefix="AzureFirewall.ServiceTag", outputs_key_field="id", outputs=total_response.get("value", [])[start_offset:end_offset], raw_response=total_response, ) return command_results def generate_ip_group_command_output(response: dict | list, readable_header: str, output_key: str = None) -> CommandResults: """ Generate command output for IP groups commands. Args: response (dict | list): API response from Azure. output_key (str): Used to access to required data in the response. readable_header (str): Readable message header for XSOAR war room. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ outputs = ( copy.deepcopy(response.get(output_key, [])) if output_key and isinstance(response, dict) else copy.deepcopy(response) ) if not isinstance(outputs, list): outputs = [outputs] readable_data = [] for ip_group in outputs: properties = ip_group.get("properties") data = { "name": ip_group.get("name"), "id": ip_group.get("id"), **properties, } readable_data.append(data) readable_output = tableToMarkdown( readable_header, readable_data, headers=["name", "id", "ipAddresses", "firewalls", "firewallPolicies", "provisioningState"], headerTransform=pascalToSpace, ) command_results = CommandResults( readable_output=readable_output, outputs_prefix="AzureFirewall.IPGroup", outputs_key_field="id", outputs=outputs, raw_response=response, ) return command_results def azure_firewall_ip_group_create_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Create IP group resource. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() ip_group_name = args.get("ip_group_name", "") location = args.get("location", "") ip_address = argToList(args.get("ips")) should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 response = client.azure_firewall_ip_group_create_request( ip_group_name=ip_group_name, location=location, ip_address=ip_address ) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-ip-group-get", interval=interval, timeout=timeout, ip_group_names=ip_group_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="IP-Group", resource_name=ip_group_name), ) return generate_ip_group_command_output(response, readable_header=f'Successfully Created IP Group "{ip_group_name}"') def azure_firewall_ip_group_update_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ Update IP group. Add or remove IPs from the group. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() ip_group_name = args.get("ip_group_name", "") ip_address_to_add = argToList(args.get("ips_to_add")) ip_address_to_remove = argToList(args.get("ips_to_remove")) should_poll = True interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 if not ip_address_to_add and not ip_address_to_remove: raise Exception("One of the arguments: `ip_address_to_add` or `ip_address_to_remove` must be provided.") ip_group_data = client.azure_firewall_ip_group_get_request(ip_group_name=ip_group_name) ip_addresses = dict_safe_get(ip_group_data, ["properties", "ipAddresses"]) ip_addresses.extend(ip_address_to_add) for ip_item in ip_address_to_remove: try: ip_addresses.remove(ip_item) except ValueError: continue response = client.azure_firewall_ip_group_update_request(ip_group_name=ip_group_name, ip_group_data=ip_group_data) state = dict_safe_get(response, ["properties", "provisioningState"], "") if should_poll and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-ip-group-get", interval=interval, timeout=timeout, ip_group_names=ip_group_name ) return CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="IP-Group", resource_name=ip_group_name), ) return generate_ip_group_command_output(response, readable_header=f"{ip_group_name} IP Group Information:") def azure_firewall_ip_group_list_command(client: AzureFirewallClient, args: Dict[str, Any]) -> CommandResults: """ List IP groups in resource group or subscription. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ resource = args.get("resource", "") limit = arg_to_number(args.get("limit")) or 50 page = arg_to_number(args.get("page")) or 1 validate_pagination_arguments(limit, page) readable_message = get_pagination_readable_message(header="IP Group List:", limit=limit, page=page) start_offset = (page - 1) * limit end_offset = start_offset + limit complete_requests = False total_response: dict[str, list] = {"value": []} response = client.azure_firewall_ip_group_list_request(resource=resource) while not complete_requests: total_response["value"].extend(response.get("value", [])) if len(total_response["value"]) >= end_offset or not response.get("nextLink"): complete_requests = True else: response = client.azure_firewall_ip_group_list_request(resource=resource, next_link=response.get("nextLink")) return generate_ip_group_command_output( total_response.get("value", [])[start_offset:end_offset], readable_header=readable_message ) def azure_firewall_ip_group_get_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Retrieve IP group information. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ScheduledCommand.raise_error_if_not_supported() ip_group_names = argToList(args.get("ip_group_names")) scheduled = argToBoolean(args.get("polling", False)) interval = arg_to_number(args.get("interval")) or 30 timeout = arg_to_number(args.get("timeout")) or 60 command_results_list: List[CommandResults] = [] for ip_group in ip_group_names: try: response = client.azure_firewall_ip_group_get_request(ip_group_name=ip_group) state = dict_safe_get(response, ["properties", "provisioningState"], "") if scheduled and state not in ["Succeeded", "Failed"]: # schedule next poll scheduled_command = create_scheduled_command( command_name="azure-firewall-ip-group-get", interval=interval, timeout=timeout, ip_group_names=ip_group ) # result with scheduled_command only - no update to the war room command_results_list.append( CommandResults( scheduled_command=scheduled_command, readable_output=generate_polling_readable_message(resource_type_name="IP-Group", resource_name=ip_group), ) ) else: command_results_list.append( generate_ip_group_command_output(response, readable_header=f"{ip_group} IP Group Information:") ) except Exception as exception: error = CommandResults(readable_output=f"An error occurred while retrieving {ip_group}.\n {exception}") command_results_list.append(error) return command_results_list def azure_firewall_ip_group_delete_command(client: AzureFirewallClient, args: Dict[str, Any]) -> list: """ Delete IP group resource. Args: client (AzureFirewallClient): Azure Firewall API client. args (dict): Command arguments from XSOAR. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ ip_group_names = argToList(args.get("ip_group_names")) command_results_list: List[CommandResults] = [] for ip_group in ip_group_names: try: response = client.azure_firewall_ip_group_delete_request(ip_group_name=ip_group) if response.status_code == 202: readable_output = f"IP Group {ip_group} delete operation accepted and will complete asynchronously." else: readable_output = f"IP Group {ip_group} deleted successfully." command_results_list.append(CommandResults(readable_output=readable_output)) except Exception as exception: error = CommandResults(readable_output=f"An error occurred while deleting {ip_group}.\n {exception}") command_results_list.append(error) return command_results_list def azure_firewall_subscriptions_list_command(client: AzureFirewallClient): response = client.azure_firewall_subscriptions_list_request() value = response.get("value", []) subscriptions = [] for subscription in value: subscription_context = { "Subscription ID": subscription.get("subscriptionId"), "Tenant ID": subscription.get("tenantId"), "State": subscription.get("state"), "Display Name": subscription.get("displayName"), } subscriptions.append(subscription_context) human_readable = tableToMarkdown("List of subscriptions", subscriptions, removeNull=True) return CommandResults( outputs_prefix="AzureFirewall.Subscription", outputs_key_field="id", outputs=value, readable_output=human_readable, raw_response=value, ) def azure_firewall_resource_group_list_command(client: AzureFirewallClient, args: Dict[str, Any]): """ List all resource groups. Args: tag (str): Tag to filter by. limit (int): Maximum number of resource groups to retrieve. Default is 50. Returns: List[dict]: API response from Azure. """ tag = args.get("tag", "") limit = arg_to_number(args.get("limit")) or 50 raw_responses = [] resource_groups: List[dict] = [] next_link: bool | str = True while next_link and len(resource_groups) < limit: full_url = next_link if isinstance(next_link, str) else None response = client.azure_firewall_resource_group_list_request(tag=tag, limit=limit, full_url=full_url) value = response.get("value", []) next_link = response.get("nextLink", "") raw_responses.extend(value) for resource_group in value: resource_group_context = { "Name": resource_group.get("name"), "Location": resource_group.get("location"), "Tags": resource_group.get("tags"), "Provisioning State": resource_group.get("properties", {}).get("provisioningState"), } resource_groups.append(resource_group_context) raw_responses = raw_responses[:limit] resource_groups = resource_groups[:limit] readable_output = tableToMarkdown("Resource Groups List", resource_groups, removeNull=True) return CommandResults( outputs_prefix="AzureFirewall.ResourceGroup", outputs_key_field="id", outputs=raw_responses, raw_response=raw_responses, readable_output=readable_output, ) # --Authorization Commands-- def start_auth(client: AzureFirewallClient) -> CommandResults: """ Start the authorization process. Args: client (AzureFirewallClient): Azure Firewall API client. Returns: CommandResults: Authentication guidelines. """ result = client.ms_client.start_auth("!azure-firewall-auth-complete") return CommandResults(readable_output=result) def complete_auth(client: AzureFirewallClient) -> str: """ Complete authorization process. Args: client (AzureFirewallClient): Azure Firewall API client. Returns: str: Informative message. """ client.ms_client.get_access_token() return "Authorization completed successfully." def test_connection(client: AzureFirewallClient) -> str: """ Test connectivity to Azure. Args: client (AzureFirewallClient): Azure Firewall API client. Returns: str: Informative message. """ try: client.ms_client.get_access_token() except Exception as err: return f"Authorization Error: \n{err}" return "Success!" def main() -> None: params: Dict[str, Any] = demisto.params() args: Dict[str, Any] = demisto.args() verify_certificate: bool = not params.get("insecure", False) proxy = params.get("proxy", False) subscription_id = args.get("subscription_id") or params["subscription_id"]["password"] resource_group = args.get("resource_group_name") or params["resource_group"] client_id = params.get("client_id", "") client_secret = dict_safe_get(params, ["client_secret", "password"]) tenant_id = dict_safe_get(params, ["tenant_id", "password"]) certificate_thumbprint = params.get("certificate_thumbprint") private_key = params.get("private_key") managed_identities_client_id = get_azure_managed_identities_client_id(params) is_credentials = (client_secret and tenant_id) or (certificate_thumbprint and private_key) if ( tenant_id and not client_secret and ((private_key and not certificate_thumbprint) or (certificate_thumbprint and not private_key)) ): raise DemistoException( "When Tenant ID is provided, either Client Secret or Certificate Thumbprint and Private Key must be provided." ) command = demisto.command() demisto.debug(f"Command being called is {command}") try: client: AzureFirewallClient = AzureFirewallClient( subscription_id=subscription_id, resource_group=resource_group, client_id=client_id, verify=verify_certificate, proxy=proxy, client_secret=client_secret, tenant_id=tenant_id, certificate_thumbprint=certificate_thumbprint, private_key=private_key, managed_identities_client_id=managed_identities_client_id, is_credentials=is_credentials, ) commands = { "azure-firewall-list": azure_firewall_list_command, "azure-firewall-get": azure_firewall_get_command, "azure-firewall-rule-collection-list": azure_firewall_rules_collection_list_command, "azure-firewall-rule-list": azure_firewall_rules_list_command, "azure-firewall-rule-get": azure_firewall_rule_get_command, "azure-firewall-policy-create": azure_firewall_policy_create_command, "azure-firewall-policy-update": azure_firewall_policy_update_command, "azure-firewall-policy-get": azure_firewall_policy_get_command, "azure-firewall-policy-delete": azure_firewall_policy_delete_command, "azure-firewall-policy-list": azure_firewall_policy_list_command, "azure-firewall-policy-attach": azure_firewall_policy_attach_command, "azure-firewall-policy-detach": azure_firewall_policy_remove_command, "azure-firewall-network-rule-collection-create": azure_firewall_network_rule_collection_create_command, "azure-firewall-network-rule-collection-update": azure_firewall_network_rule_collection_update_command, "azure-firewall-network-rule-collection-delete": azure_firewall_network_rule_collection_delete_command, "azure-firewall-network-rule-create": azure_firewall_network_rule_create_command, "azure-firewall-network-rule-update": azure_firewall_network_rule_update_command, "azure-firewall-network-rule-delete": azure_firewall_network_rule_remove_command, "azure-firewall-service-tag-list": azure_firewall_service_tag_list_command, "azure-firewall-ip-group-create": azure_firewall_ip_group_create_command, "azure-firewall-ip-group-update": azure_firewall_ip_group_update_command, "azure-firewall-ip-group-list": azure_firewall_ip_group_list_command, "azure-firewall-ip-group-get": azure_firewall_ip_group_get_command, "azure-firewall-ip-group-delete": azure_firewall_ip_group_delete_command, "azure-firewall-resource-group-list": azure_firewall_resource_group_list_command, } if command == "test-module": if managed_identities_client_id or is_credentials: # test-module expected to get 'ok' in case of success test_res = test_connection(client=client) return return_results("ok" if "Success" in test_res else test_res) else: return return_results("The test module is not functional, run the azure-firewall-auth-start command instead.") if command == "azure-firewall-auth-start": return_results(start_auth(client)) elif command == "azure-firewall-auth-complete": return_results(complete_auth(client)) elif command == "azure-firewall-auth-test": return_results(test_connection(client)) elif command == "azure-firewall-auth-reset": return_results(reset_auth()) elif command == "azure-firewall-subscriptions-list": return_results(azure_firewall_subscriptions_list_command(client)) elif command in commands: return_results(commands[command](client, args)) else: raise NotImplementedError(f"{command} command is not implemented.") except Exception as e: return_error(str(e)) if __name__ in ("__main__", "__builtin__", "builtins"): main()