Azure Storage

Deploy and manage storage accounts and blob services.

IT Services · Azure Storage Management

Details

IDAzure Storage
ProviderMicrosoft
CategoryIT Services
From Version5.0.0
Docker Imagedemisto/crypto:1.0.0.5490413
Supported ModulesAgentix XSIAM

README

This integration enables you to deploy and manage storage accounts and blob services.
This integration was integrated and tested with version 2022-09-01 of Azure Storage

Authorization

In order to connect to the Azure Storage Accounts and the Blob Service use either the Cortex XSOAR Azure App or the Self-Deployed Azure App.
Use one of the following methods:

  1. Authorization Code Flow (Recommended).
  2. Client Credentials Flow.
  3. Device Code Flow.

Self-Deployed Azure App

To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal.

To add the registration, refer to the following Microsoft article steps 1-8.

Required permissions

  • Azure Service Management - permission user_impersonation of type Delegated
  • Microsoft Graph - permission offline_access of type Delegated

To add a permission:

  1. Navigate to Home > App registrations.
  2. Search for your app under ‘all applications’.
  3. Click API permissions > Add permission.
  4. Search for the specific Microsoft API and select the specific permission of type Delegated.

Authentication Using the Authorization Code Flow (recommended)

  1. To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal. To add the registration, refer to the following Microsoft article steps 1-8.
  2. In the Authentication Type field, select the Authorization Code option.
  3. In the Application ID field, enter your Client/Application ID.
  4. In the Client Secret field, enter your Client Secret.
  5. In the Tenant ID field, enter your Tenant ID .
  6. In the Application redirect URI field, enter your Application redirect URI.
  7. Save the instance.
  8. Run the !azure-storage-generate-login-url command in the War Room and follow the instruction.

Authentication Using the Client Credentials Flow

  1. Assign Azure roles using the Azure portal Microsoft article

    Note: At the ‘Select members’ section, assign the application you created before.

  2. To configure a Microsoft integration that uses this authorization flow with a self-deployed Azure application:

    a. In the Authentication Type field, select the Client Credentials option.

    b. In the Application ID field, enter your Client/Application ID.

    c. In the Subscription ID field, enter your Subscription ID.

    d. In the Resource Group Name field, enter you Resource Group Name.

    e. In the Tenant ID field, enter your Tenant ID.

    f. In the Client Secret field, enter your Client Secret.

    g. Click Test to validate the URLs, token, and connection

    h. Save the instance.

Authentication Using the Device Code Flow

Use the device authorization grant flow.

  1. Fill in the required parameters.
  2. Run the !azure-storage-auth-start command.
  3. Follow the instructions that appear.
  4. Run the !azure-storage-auth-complete command.

At end of the process you’ll see a message that you’ve logged in successfully.

Cortex XSOAR Azure App

In order to use the Cortex XSOAR Azure application, use the default application ID (55f9764e-300a-474a-a2bb-549cece85439).

You only need to fill in your subscription ID and resource group name. For more details, follow Azure Integrations Parameters.

Self-Configured Azure App

To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal.

The application must have user_impersonation permission and must allow public client flows (can be found under the Authentication section of the app).

Configure Azure Storage on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for Azure Storage Management.
  3. Click Add instance to create and configure a new integration instance.

    Parameter Description Required
    Application ID   False
    Default Subscription ID There are two options to set the specified value, either in the configuration or directly within the commands. However, setting values in both places will cause an override by the command value. True
    Default Resource Group Name There are two options to set the specified value, either in the configuration or directly within the commands. However, setting values in both places will cause an override by the command value. True
    Trust any certificate (not secure)   False
    Use system proxy settings   False
    Authentication Type Type of authentication - can be Authorization Code flow (recommended), Device Code Flow, or Azure Managed Identities. True
    Tenant ID (for user-auth mode)   False
    Client Secret (for user-auth mode)   False
    Azure Managed Identities Client ID The Managed Identities client ID for authentication - relevant only if the integration is running on Azure VM. False
    Application redirect URI (for user-auth mode)   False
    Authorization code For user-auth mode - received from the authorization step. See Detailed Instructions (?) section. False
  4. Click Test to validate the URLs, token, and connection.

Commands

You can execute these commands from the Cortex XSOAR 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-storage-auth-test


Tests the connectivity to Azure.

Base Command

azure-storage-auth-test

Input

There are no input arguments for this command.

Human Readable Output

✅ Success!

azure-storage-auth-start


Run this command to start the authorization process and follow the instructions in the command results.

Base Command

azure-storage-auth-start

Input

There are no input arguments for this command.

Human Readable Output

Authorization instructions

   1. To sign in, use a web browser to open the page:
       [https://microsoft.com/devicelogin](https://microsoft.com/devicelogin)
      and enter the code **XXXXXXXX** to authenticate.
   2. Run the ***!azure-storage-auth-complete*** command in the War Room.

azure-storage-auth-complete


Run this command to complete the authorization process. Should be used after running the azure-storage-auth-start command.

Base Command

azure-storage-auth-complete

Input

There are no input arguments for this command.

Human Readable Output

✅ Authorization completed successfully.

azure-storage-auth-reset


Run this command if for some reason you need to rerun the authentication process.

Base Command

azure-storage-auth-reset

Input

There are no input arguments for this command.

Human Readable Output

Authorization was reset successfully. You can now run !azure-storage-auth-start and !azure-storage-auth-complete.

azure-storage-account-list


Run this command to get the all or specific account storage details.

Base Command

azure-storage-account-list

Input

Argument Name Description Required
account_name The name of the storage account, optional. Optional
subscription_id The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. Optional
resource_group_name The resource group name. Note: This argument will override the instance parameter ‘Default Resource Group Name’. Optional

Context Output

Path Type Description
AzureStorage.StorageAccount.id String Fully qualified resource ID for the resource.
AzureStorage.StorageAccount.kind String Gets the Kind.
AzureStorage.StorageAccount.location String The geo-location where the resource lives
AzureStorage.StorageAccount.name String The name of the resource
AzureStorage.StorageAccount.properties.isHnsEnabled Boolean Account HierarchicalNamespace enabled if sets to true.
AzureStorage.StorageAccount.properties.allowBlobPublicAccess Boolean Allow or disallow public access to all blobs or containers in the storage account. The default interpretation is true for this property.
AzureStorage.StorageAccount.properties.minimumTlsVersion String Set the minimum TLS version to be permitted on requests to storage. The default interpretation is TLS 1.0 for this property.
AzureStorage.StorageAccount.properties.allowSharedKeyAccess Boolean Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Entra ID (Azure AD).
AzureStorage.StorageAccount.properties.creationTime Date Gets the creation date and time of the storage account in UTC.
AzureStorage.StorageAccount.properties.primaryEndpoints.web String Gets the web endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.dfs String Gets the dfs endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.blob String Gets the blob endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.file String Gets the file endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.queue String Gets the queue endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.table String Gets the table endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.web String Gets the web microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.dfs String Gets the dfs microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.blob String Gets the blob microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.file String Gets the file microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.queue String Gets the queue microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.table String Gets the table microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.web String Gets the web internet endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.dfs String Gets the dfs internet endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.blob String Gets the blob internet endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.file String Gets the file internet endpoint.
AzureStorage.StorageAccount.properties.primaryLocation String Gets the location of the primary data center for the storage account.
AzureStorage.StorageAccount.properties.provisioningState String Gets the status of the storage account at the time the operation was called.
AzureStorage.StorageAccount.properties.routingPreference.routingChoice String Routing Choice defines the kind of network routing opted by the user.
AzureStorage.StorageAccount.properties.routingPreference.publishMicrosoftEndpoints Boolean A boolean flag which indicates whether microsoft routing storage endpoints are to be published.
AzureStorage.StorageAccount.properties.routingPreference.publishInternetEndpoints Boolean A boolean flag which indicates whether internet routing storage endpoints are to be published.
AzureStorage.StorageAccount.properties.encryption.services.file.keyType String Encryption key type to be used for the encryption service. ‘Account’ key type implies that an account-scoped encryption key will be used. ‘Service’ key type implies that a default service key is used.
AzureStorage.StorageAccount.properties.encryption.services.file.enabled Boolean A boolean indicating whether or not the service encrypts the data as it is stored.
AzureStorage.StorageAccount.properties.encryption.services.file.lastEnabledTime Date Gets a rough estimate of the date/time when the encryption was last enabled by the user.
AzureStorage.StorageAccount.properties.encryption.services.blob.keyType String Encryption key type to be used for the encryption service. ‘Account’ key type implies that an account-scoped encryption key will be used. ‘Service’ key type implies that a default service key is used.
AzureStorage.StorageAccount.properties.encryption.services.blob.enabled Boolean A boolean indicating whether or not the service encrypts the data as it is stored.
AzureStorage.StorageAccount.properties.encryption.services.blob.lastEnabledTime Date Gets a rough estimate of the date/time when the encryption was last enabled by the user.
AzureStorage.StorageAccount.properties.encryption.requireInfrastructureEncryption Boolean A boolean indicating whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest.
AzureStorage.StorageAccount.properties.encryption.keySource String The encryption keySource (provider). Possible values (case-insensitive): Microsoft.Storage, Microsoft.Keyvault.
AzureStorage.StorageAccount.properties.secondaryLocation String Gets the location of the geo-replicated secondary for the storage account. Only available if the accountType is Standard_GRS or Standard_RAGRS.
AzureStorage.StorageAccount.properties.statusOfPrimary String Gets the status indicating whether the primary location of the storage account is available or unavailable
AzureStorage.StorageAccount.properties.statusOfSecondary String Gets the status indicating whether the secondary location of the storage account is available or unavailable. Only available if the SKU name is Standard_GRS or Standard_RAGRS.
AzureStorage.StorageAccount.properties.supportsHttpsTrafficOnly Boolean Allows https traffic only to storage service if sets to true.
AzureStorage.StorageAccount.sku.name String The SKU name. Required for account creation; optional for update.
AzureStorage.StorageAccount.sku.tier String The SKU tier. This is based on the SKU name.
AzureStorage.StorageAccount.tags Unknown Resource tags.
AzureStorage.StorageAccount.type String The type of the resource.

Command Example

Human Readable Output

Azure Storage Account List

Account Name Subscription ID Resource Group Kind Status Primary Status Secondary Location
acount_name1 subscription_id1 resource_group_name1 Storage available available eastus
acount_name2 subscription_id2 resource_group_name2 BlobStorage available available eastus
acount_name3 subscription_id3 resource_group_name3 Storage available   westeurope

azure-storage-account-create-update


Run this command to create or update a specific
account storage.

Base Command

azure-storage-account-create-update

Input

Argument Name Description Required
account_name The name of the storage account. Required
sku Gets or sets the SKU name, Required for account creation; optional for update. Possible values are: Premium_LRS, Premium_ZRS, Standard_GRS, Standard_GZRS, Standard_LRS, Standard_RAGRS, Standard_RAGZRS, Standard_ZRS. Required
kind Indicates the type of storage account. Possible values are: Storage, StorageV2, BlobStorage, FileStorage, BlockBlobStorage. Required
location Gets or sets the location of the resource. The geo region of a resource cannot be changed once it is created, but if an identical geo region is specified on update, the request will succeed. Possible values are: eastus, eastus2, westus, westeurope, eastasia, southeastasia, japaneast, japanwest, northcentralus, southcentralus, centralus, northeurope, brazilsouth, australiaeast, australiasoutheast, southindia, centralindia, westindia, canadaeast, canadacentral, westus2, westcentralus, uksouth, ukwest, koreacentral, koreasouth, francecentral, australiacentral, southafricanorth, uaenorth, switzerlandnorth, germanywestcentral, norwayeast. Required
tags Gets or sets a list of tags that describe the resource. Optional
custom_domain_name Gets or sets the custom domain name assigned to the storage account. Optional
use_sub_domain_name Indicates whether indirect CName validation is enabled. Possible values are: true, false. Optional
enc_key_source The encryption keySource. Possible values are: Microsoft.Storage, Microsoft.Keyvault. Optional
enc_requireInfrastructureEncryption Indicating whether the service applies a secondary layer of encryption with platform managed keys for data at rest. Possible values are: true, false. Optional
enc_keyvault_key_name The name of KeyVault key. Optional
enc_keyvault_key_version The version of KeyVault key. Optional
enc_keyvault_uri The Uri of KeyVault. Optional
access_tier The access tier for the account. Required where kind = BlobStorage. Possible values are: Hot, Cool. Optional
supports_https_traffic_only Allows https traffic only to storage service if sets to true. Possible values are: true, false. Optional
is_hns_enabled Account HierarchicalNamespace enabled if sets to true. Possible values are: true, false. Optional
large_file_shares_state Allow large file shares if sets to Enabled. Possible values are: Disabled, Enabled. Optional
allow_blob_public_access Allow or disallow public access to all blobs or containers in the storage account. Possible values are: true, false. Optional
minimum_tls_version Set the minimum TLS version to be permitted on requests to storage. Possible values are: TLS1_0, TLS1_1, TLS1_2. Optional
network_ruleset_bypass Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are: AzureServices, Logging, Metrics, None. Optional
network_ruleset_default_action Specifies the default action of allow or deny when no other rules match. Optional
network_ruleset_ipRules Sets the IP ACL rules. Optional
virtual_network_rules Sets the virtual network rules. Optional
subscription_id The subscription ID. Note: This argument will override the instance parameter Default Subscription ID’. Optional
resource_group_name The resource group name. Note: This argument will override the instance parameter ‘Default Resource Group Name’. Optional

Context Output

Path Type Description
AzureStorage.StorageAccount.id String Fully qualified resource ID for the resource.
AzureStorage.StorageAccount.kind String Gets the Kind.
AzureStorage.StorageAccount.location String The geo-location where the resource lives.
AzureStorage.StorageAccount.name String The name of the resource.
AzureStorage.StorageAccount.properties.isHnsEnabled Boolean Account HierarchicalNamespace enabled if sets to true.
AzureStorage.StorageAccount.properties.allowBlobPublicAccess Boolean Allow or disallow public access to all blobs or containers in the storage account. The default interpretation is true for this property.
AzureStorage.StorageAccount.properties.minimumTlsVersion String Set the minimum TLS version to be permitted on requests to storage. The default interpretation is TLS 1.0 for this property.
AzureStorage.StorageAccount.properties.allowSharedKeyAccess Boolean Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Entra ID (Azure AD).
AzureStorage.StorageAccount.properties.creationTime Date Gets the creation date and time of the storage account in UTC.
AzureStorage.StorageAccount.properties.primaryEndpoints.web String Gets the web endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.dfs String Gets the dfs endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.blob String Gets the blob endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.file String Gets the file endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.queue String Gets the queue endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.table String Gets the table endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.web String Gets the web microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.dfs String Gets the dfs microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.blob String Gets the blob microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.file String Gets the file microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.queue String Gets the queue microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.microsoftEndpoints.table String Gets the table microsoft endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.web String Gets the web internet endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.dfs String Gets the dfs internet endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.blob String Gets the blob internet endpoint.
AzureStorage.StorageAccount.properties.primaryEndpoints.internetEndpoints.file String Gets the file internet endpoint.
AzureStorage.StorageAccount.properties.primaryLocation String Gets the location of the primary data center for the storage account.
AzureStorage.StorageAccount.properties.provisioningState String Gets the status of the storage account at the time the operation was called.
AzureStorage.StorageAccount.properties.routingPreference.routingChoice String Routing Choice defines the kind of network routing opted by the user.
AzureStorage.StorageAccount.properties.routingPreference.publishMicrosoftEndpoints Boolean A boolean flag which indicates whether microsoft routing storage endpoints are to be published.
AzureStorage.StorageAccount.properties.routingPreference.publishInternetEndpoints Boolean A boolean flag which indicates whether internet routing storage endpoints are to be published.
AzureStorage.StorageAccount.properties.encryption.services.file.keyType String Encryption key type to be used for the encryption service. ‘Account’ key type implies that an account-scoped encryption key will be used. ‘Service’ key type implies that a default service key is used.
AzureStorage.StorageAccount.properties.encryption.services.file.enabled Boolean A boolean indicating whether or not the service encrypts the data as it is stored.
AzureStorage.StorageAccount.properties.encryption.services.file.lastEnabledTime Date Gets a rough estimate of the date/time when the encryption was last enabled by the user.
AzureStorage.StorageAccount.properties.encryption.services.blob.keyType String Encryption key type to be used for the encryption service. ‘Account’ key type implies that an account-scoped encryption key will be used. ‘Service’ key type implies that a default service key is used.
AzureStorage.StorageAccount.properties.encryption.services.blob.enabled Boolean A boolean indicating whether or not the service encrypts the data as it is stored.
AzureStorage.StorageAccount.properties.encryption.services.blob.lastEnabledTime Date Gets a rough estimate of the date/time when the encryption was last enabled by the user.
AzureStorage.StorageAccount.properties.encryption.requireInfrastructureEncryption Boolean A boolean indicating whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest.
AzureStorage.StorageAccount.properties.encryption.keySource String The encryption keySource (provider). Possible values (case-insensitive): Microsoft.Storage, Microsoft.Keyvault.
AzureStorage.StorageAccount.properties.secondaryLocation String Gets the location of the geo-replicated secondary for the storage account. Only available if the accountType is Standard_GRS or Standard_RAGRS.
AzureStorage.StorageAccount.properties.statusOfPrimary String Gets the status indicating whether the primary location of the storage account is available or unavailable
AzureStorage.StorageAccount.properties.statusOfSecondary String Gets the status indicating whether the secondary location of the storage account is available or unavailable. Only available if the SKU name is Standard_GRS or Standard_RAGRS.
AzureStorage.StorageAccount.properties.supportsHttpsTrafficOnly Boolean Allows https traffic only to storage service if sets to true.
AzureStorage.StorageAccount.sku.name String The SKU name. Required for account creation; optional for update.
AzureStorage.StorageAccount.sku.tier String The SKU tier. This is based on the SKU name.
AzureStorage.StorageAccount.tags Unknown Resource tags.
AzureStorage.StorageAccount.type String The type of the resource.

Command Example

!azure-storage-account-create-update account_name=account_name1 kind=BlobStorage location=eastus sku=Standard_GRS

Context Example

{
    "AzureStorage": {
        "StorageAccount": {
            "id": "/subscriptions/sub_id/resourceGroups/resource_g_name/providers/Microsoft.Storage/storageAccounts/account_name",
            "kind": "BlobStorage",
            "location": "eastus",
            "name": "account_name",
            "properties": {
                "accessTier": "Cool",
                "creationTime": "2021-02-22T13:15:19.2816113Z",
                "encryption": {
                    "keySource": "Microsoft.Storage",
                    "services": {
                        "blob": {
                            "enabled": true,
                            "keyType": "Account",
                            "lastEnabledTime": "2021-02-22T13:15:19.3910225Z"
                        },
                        "file": {
                            "enabled": true,
                            "keyType": "Account",
                            "lastEnabledTime": "2021-02-22T13:15:19.3910225Z"
                        }
                    }
                },
                "minimumTlsVersion": "TLS1_1",
                "networkAcls": {
                    "bypass": "AzureServices",
                    "defaultAction": "Allow",
                    "ipRules": [],
                    "virtualNetworkRules": []
                },
                "primaryEndpoints": {
                    "blob": "",
                    "dfs": "",
                    "table": ""
                },
                "primaryLocation": "eastus",
                "privateEndpointConnections": [],
                "provisioningState": "Succeeded",
                "secondaryLocation": "westus",
                "statusOfPrimary": "available",
                "statusOfSecondary": "available",
                "supportsHttpsTrafficOnly": false
            },
            "sku": {
                "name": "Standard_GRS",
                "tier": "Standard"
            },
            "tags": {},
            "type": "Microsoft.Storage/storageAccounts"
        }
    }
}

Human Readable Output

Azure Storage Account

Account Name Subscription ID Resource Group Kind Status Primary Status Secondary Location
acount_name1 subscription_id1 resource_group_name1 BlobStorage available available eastus

azure-storage-blob-service-properties-get


Run this command to get the blob service properties of a specific account storage.

Base Command

azure-storage-blob-service-properties-get

Input

Argument Name Description Required
account_name The name of the storage account. Required
subscription_id The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. Optional
resource_group_name The resource group name. Note: This argument will override the instance parameter ‘Default Resource Group Name’. Optional

Context Output

Path Type Description
AzureStorage.BlobServiceProperties.id String Fully qualified resource ID for the resource.
AzureStorage.BlobServiceProperties.name String The name of the resource
AzureStorage.BlobServiceProperties.type String The type of the resource.
AzureStorage.BlobServiceProperties.properties.lastAccessTimeTrackingPolicy.enable Boolean When set to true last access time based tracking is enabled.
AzureStorage.BlobServiceProperties.properties.lastAccessTimeTrackingPolicy.name String Name of the policy. The valid value is AccessTimeTracking.
AzureStorage.BlobServiceProperties.properties.lastAccessTimeTrackingPolicy.trackingGranularityInDays Number The field specifies blob object tracking granularity in days, typically how often the blob object should be tracked.
AzureStorage.BlobServiceProperties.properties.lastAccessTimeTrackingPolicy.blobType String An array of predefined supported blob types. Only blockBlob is the supported value.

Command Example

!azure-storage-blob-service-properties-get account_name=account_name1

Context Example

{
    "AzureStorage": {
        "BlobServiceProperties": {
            "id": "/subscriptions/sub_id/resourceGroups/resource_g_name/providers/Microsoft.Storage/storageAccounts/account_name/blobServices/default",
            "name": "default",
            "properties": {
                "changeFeed": {
                    "enabled": false
                },
                "cors": {
                    "corsRules": []
                },
                "deleteRetentionPolicy": {
                    "enabled": false
                },
                "isVersioningEnabled": false
            },
            "sku": {
                "name": "Standard_GRS",
                "tier": "Standard"
            },
            "type": "Microsoft.Storage/storageAccounts/blobServices"
        }
    }
}

Human Readable Output

Azure Storage Blob Service Properties

Name Account Name Subscription ID Resource Group Change Feed Delete Retention Policy Versioning
default account_name subscription_id resource_group_name change_feed_enabled delete_retention_policy_enabled is_versioning_enabled

azure-storage-blob-service-properties-set


Run this command to set properties for
the blob service in a specific account storage

Base Command

azure-storage-blob-service-properties-set

Input

Argument Name Description Required
account_name The name of the storage account. Required
change_feed_enabled Indicates whether change feed event logging is enabled for the Blob service. Possible values are: true, false. Optional
change_feed_retention_days Indicates the duration of changeFeed retention in days. Optional
container_delete_rentention_policy_enabled Indicates whether DeleteRetentionPolicy is enabled. Possible values are: true, false. Optional
container_delete_rentention_policy_days Indicates the number of days that the deleted item should be retained. Optional
delete_rentention_policy_enabled Indicates whether DeleteRetentionPolicy is enabled. Possible values are: true, false. Optional
delete_rentention_policy_days Indicates the number of days that the deleted item should be retained. Optional
versioning Versioning is enabled if set to true. Possible values are: true, false. Optional
last_access_time_tracking_policy_enabled When set to true last access time based tracking is enabled. Possible values are: true, false. Optional
last_access_time_tracking_policy_blob_types An array of predefined supported blob types. Optional
last_access_time_tracking_policy_days The field specifies blob object tracking granularity in days. Optional
restore_policy_enabled Blob restore is enabled if set to true. Possible values are: true, false. Optional
restore_policy_min_restore_time The minimum date and time that the restore can be started. Optional
restore_policy_days how long this blob can be restored. Optional
subscription_id The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. Optional
resource_group_name The resource group name. Note: This argument will override the instance parameter ‘Default Resource Group Name’. Optional

Context Output

Path Type Description
AzureStorage.BlobServiceProperties.id String Fully qualified resource ID for the resource.
AzureStorage.BlobServiceProperties.name String The name of the resource.
AzureStorage.BlobServiceProperties.type String The type of the resource.
AzureStorage.BlobServiceProperties.properties.cors.corsRules.allowedOrigins String Required if CorsRule element is present. A list of origin domains that will be allowed via CORS, or “*” to allow all domains.
AzureStorage.BlobServiceProperties.properties.cors.corsRules.allowedMethods String Required if CorsRule element is present. A list of HTTP methods that are allowed to be executed by the origin.
AzureStorage.BlobServiceProperties.properties.cors.corsRules.maxAgeInSeconds Number Required if CorsRule element is present. The number of seconds that the client/browser should cache a preflight response.
AzureStorage.BlobServiceProperties.properties.cors.corsRules.exposedHeaders String Required if CorsRule element is present. A list of response headers to expose to CORS clients.
AzureStorage.BlobServiceProperties.properties.cors.corsRules.allowedHeaders String Required if CorsRule element is present. A list of headers allowed to be part of the cross-origin request.
AzureStorage.BlobServiceProperties.properties.defaultServiceVersion Date Indicates the default version to use for requests to the Blob service if an incoming request\u2019s version is not specified. Possible values include version 2008-10-27 and all more recent versions.
AzureStorage.BlobServiceProperties.properties.deleteRetentionPolicy.enabled Boolean Indicates whether DeleteRetentionPolicy is enabled.
AzureStorage.BlobServiceProperties.properties.deleteRetentionPolicy.days Number Indicates the number of days that the deleted item should be retained. The minimum specified value can be 1 and the maximum value can be 365.
AzureStorage.BlobServiceProperties.properties.isVersioningEnabled Boolean Versioning is enabled if set to true.
AzureStorage.BlobServiceProperties.properties.changeFeed.enabled Boolean Indicates whether change feed event logging is enabled for the Blob service.
AzureStorage.BlobServiceProperties.properties.changeFeed.retentionInDays Number Indicates the duration of changeFeed retention in days. Minimum value is 1 day and maximum value is 146000 days.
AzureStorage.BlobServiceProperties.sku.name String The SKU name.
AzureStorage.BlobServiceProperties.sku.tier String The SKU tier.

Command Example

!azure-storage-blob-service-properties-set account_name=account_name1 delete_rentention_policy_enabled=false

Context Example

{
    "AzureStorage": {
        "BlobServiceProperties": {
            "id": "/subscriptions/sub_id/resourceGroups/resource_g_name/providers/Microsoft.Storage/storageAccounts/account_name/blobServices/default",
            "name": "default",
            "properties": {
                "deleteRetentionPolicy": {
                    "enabled": false
                }
            },
            "type": "Microsoft.Storage/storageAccounts/blobServices"
        }
    }
}

Human Readable Output

Azure Storage Blob Service Properties

Name Account Name Subscription ID Resource Group Change Feed Delete Retention Policy Versioning
default account_name subscription_id resource_group_name change_feed_enabled delete_retention_policy_enabled is_versioning_enabled

azure-storage-blob-containers-create


Run this command to create a blob container.

Base Command

azure-storage-blob-containers-create

Input

Argument Name Description Required
account_name The name of the storage account. Required
container_name The name of the container. Required
default_encryption_scope Default the container to use specified encryption scope for all writes. Optional
deny_encryption_scope_override Block override of encryption scope from the container default. Possible values are: true, false. Optional
public_access Specifies the level of access. Possible values are: Blob, Container, None. Optional
subscription_id The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. Optional
resource_group_name The resource group name. Note: This argument will override the instance parameter ‘Default Resource Group Name’. Optional

Context Output

Path Type Description
AzureStorage.BlobContainer.id String Fully qualified resource ID for the resource.
AzureStorage.BlobContainer.name String The name of the resource.
AzureStorage.BlobContainer.type String The type of the resource.

Command Example

!azure-storage-blob-containers-create account_name=account_name container_name=container_name

Context Example

{
    "AzureStorage": {
        "BlobContainer": {
            "id": "/subscriptions/subscription_id/resourceGroups/resource_group/providers/Microsoft.Storage/storageAccounts/account_name/blobServices/default/containers/container_name",
            "name": "container_name",
            "properties": {
                "deleted": false,
                "hasImmutabilityPolicy": false,
                "hasLegalHold": false,
                "remainingRetentionDays": 0
            },
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers"
        }
    }
}

Human Readable Output

Azure Storage Blob Containers Properties

Name Account Name Subscription ID Resource Group Public Access
container_name account_name subscription_id resource_group  

azure-storage-blob-containers-update


Run this command to update a specific
blob container.

Base Command

azure-storage-blob-containers-update

Input

Argument Name Description Required
account_name The name of the storage account. Required
container_name The name of the container. Required
default_encryption_scope Default the container to use specified encryption scope for all writes. Optional
deny_encryption_scope_override Block override of encryption scope from the container default. Possible values are: true, false. Optional
public_access Specifies the level of access. Possible values are: Blob, Container, None. Optional
subscription_id The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. Optional
resource_group_name The resource group name. Note: This argument will override the instance parameter ‘Default Resource Group Name’. Optional

Context Output

Path Type Description
AzureStorage.BlobContainer.id String Fully qualified resource ID for the resource.
AzureStorage.BlobContainer.name String The name of the resource.
AzureStorage.BlobContainer.type String The type of the resource.
AzureStorage.BlobContainer.properties.metadata.metadata String A name-value pair to associate with the container as metadata.
AzureStorage.BlobContainer.properties.publicAccess String Specifies whether data in the container may be accessed publicly and the level of access.
AzureStorage.BlobContainer.properties.hasImmutabilityPolicy Boolean The hasImmutabilityPolicy public property is set to true by SRP if ImmutabilityPolicy has been created for this container. The hasImmutabilityPolicy public property is set to false by SRP if ImmutabilityPolicy has not been created for this container.
AzureStorage.BlobContainer.properties.hasLegalHold Boolean The hasLegalHold public property is set to true by SRP if there are at least one existing tag. The hasLegalHold public property is set to false by SRP if all existing legal hold tags are cleared out.

Command Example

!azure-storage-blob-containers-update account_name=account_name container_name=container_name

Context Example

{
    "AzureStorage": {
        "BlobContainer": {
            "id": "/subscriptions/subscription_id/resourceGroups/resource_group/providers/Microsoft.Storage/storageAccounts/account_name/blobServices/default/containers/container_name",
            "name": "container_name",
            "properties": {
                "deleted": false,
                "hasImmutabilityPolicy": false,
                "hasLegalHold": false,
                "remainingRetentionDays": 0
            },
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers"
        }
    }
}

Human Readable Output

Azure Storage Blob Containers Properties

Name Account Name Subscription ID Resource Group Public Access
container_name account_name subscription_id resource_group  

azure-storage-blob-containers-list


Run this command to get the all or specific blob container details.

Base Command

azure-storage-blob-containers-list

Input

Argument Name Description Required
account_name The name of the storage account. Required
container_name The name of the container. Optional
include_deleted Specifies whether include the properties for soft deleted blob containers. Possible values are: true, false. Optional
maxpagesize Specified maximum number of containers that can be included in the list. Optional
subscription_id The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. Optional
resource_group_name The resource group name. Note: This argument will override the instance parameter ‘Default Resource Group Name’. Optional

Context Output

Path Type Description
AzureStorage.BlobContainer.id String Fully qualified resource ID for the resource.
AzureStorage.BlobContainer.name String The name of the resource.
AzureStorage.BlobContainer.type String The type of the resource.
AzureStorage.BlobContainer.properties.publicAccess String Specifies whether data in the container may be accessed publicly and the level of access.
AzureStorage.BlobContainer.properties.leaseStatus String The lease status of the container.
AzureStorage.BlobContainer.properties.leaseState String Lease state of the container.
AzureStorage.BlobContainer.properties.lastModifiedTime Date Returns the date and time the container was last modified.
AzureStorage.BlobContainer.properties.hasImmutabilityPolicy Boolean The hasImmutabilityPolicy public property is set to true by SRP if ImmutabilityPolicy has been created for this container. The hasImmutabilityPolicy public property is set to false by SRP if ImmutabilityPolicy has not been created for this container.
AzureStorage.BlobContainer.properties.hasLegalHold Boolean The hasLegalHold public property is set to true by SRP if there are at least one existing tag. The hasLegalHold public property is set to false by SRP if all existing legal hold tags are cleared out.

Command Example

!azure-storage-blob-containers-list account_name=account_name

Context Example

{
    "AzureStorage": {
        "BlobContainer": [
            {
                "id": "/subscriptions/subscription_id/resourceGroups/resource_group/providers/Microsoft.Storage/storageAccounts/account_name/blobServices/default/containers/container_name",
                "name": "container_name1",
                "properties": {
                    "defaultEncryptionScope": "$account-encryption-key",
                    "deleted": false,
                    "denyEncryptionScopeOverride": false,
                    "hasImmutabilityPolicy": false,
                    "hasLegalHold": false,
                    "lastModifiedTime": "2021-03-31T06:49:57.0000000Z",
                    "leaseState": "Available",
                    "leaseStatus": "Unlocked",
                    "publicAccess": "None",
                    "remainingRetentionDays": 0
                },
                "type": "Microsoft.Storage/storageAccounts/blobServices/containers"
            },
            {
                "id": "/subscriptions/subscription_id/resourceGroups/resource_group/providers/Microsoft.Storage/storageAccounts/account_name/blobServices/default/containers/container_name",
                "name": "container_name",
                "properties": {
                    "defaultEncryptionScope": "$account-encryption-key",
                    "deleted": false,
                    "denyEncryptionScopeOverride": false,
                    "hasImmutabilityPolicy": false,
                    "hasLegalHold": false,
                    "lastModifiedTime": "2021-03-31T06:45:30.0000000Z",
                    "leaseState": "Available",
                    "leaseStatus": "Unlocked",
                    "publicAccess": "None",
                    "remainingRetentionDays": 0
                },
                "type": "Microsoft.Storage/storageAccounts/blobServices/containers"
            }
        ]
    }
}

Human Readable Output

Azure Storage Blob Containers list

Container Name Account Name Subscription ID Resource Group Public Access Lease State Last Modified Time
container_name1 account_name subscription_id resource_group None Available 2021-03-31T06:49:57.0000000Z
container_name2 account_name subscription_id resource_group None Available 2021-03-31T06:45:30.0000000Z

azure-storage-blob-container-delete


Run this command to delete a specific blob container.

Base Command

azure-storage-blob-container-delete

Input

Argument Name Description Required
account_name The name of the storage account. Required
container_name The name of the container. Required
subscription_id The subscription ID. Note: This argument will override the instance parameter ‘Default Subscription ID’. Optional
resource_group_name The resource group name. 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-storage-blob-container-delete account_name=account_name container_name=container_name

Human Readable Output

The request to delete the blob container was sent successfully.

azure-storage-generate-login-url


Generate the login url used for Authorization code flow.

Base Command

azure-storage-generate-login-url

Input

There are no input arguments for this command.

Context Output

There is no context output for this command.

Command Example

Human Readable Output

Azure Storage Subscriptions list

subscriptionId tenantId displayName state
00000000000000000000 00000000000000000 Access to Azure Active Directory Enabled
000000000000 00000000000000000 Pay-As-You-Go Enabled

azure-storage-resource-group-list


Gets all resource groups for a subscription.

Base Command

azure-storage-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 value is 50. 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
AzureStorage.ResourceGroup.id String The unique identifier of the Azure storage resource group.
AzureStorage.ResourceGroup.name String The name of the Azure storage resource group.
AzureStorage.ResourceGroup.type String The type of the Azure storage resource group.
AzureStorage.ResourceGroup.location String The location of the Azure storage resource group.
AzureStorage.ResourceGroup.properties.provisioningState String The provisioning state of the Azure storage resource group.
AzureStorage.ResourceGroup.tags.Owner String The owner tag of the Azure storage resource group.
AzureStorage.ResourceGroup.tags Unknown The tags associated with the Azure storage resource group.
AzureStorage.ResourceGroup.tags.Name String The name tag of the Azure storage resource group.
AzureStorage.ResourceGroup.managedBy String The entity that manages the Azure storage resource group.
AzureStorage.ResourceGroup.tags.aks-managed-cluster-name String The AKS managed cluster name tag associated with the Azure storage resource group.
AzureStorage.ResourceGroup.tags.aks-managed-cluster-rg String The AKS managed cluster resource group tag associated with the Azure storage resource group.
AzureStorage.ResourceGroup.tags.type String The type tag associated with the Azure storage resource group.

Command example


#### Context Example

```json
{
    "AzureStorage": {
        "ResourceGroup": [
            {
                "id": "/subscriptions/000000000000/resourceGroups/cloud-shell-storage-eastus",
                "location": "eastus",
                "name": "cloud-shell-storage-eastus",
                "properties": {
                    "provisioningState": "Succeeded"
                },
                "type": "Microsoft.Resources/resourceGroups"
            },
            {
                "id": "/subscriptions/000000000000/resourceGroups/demi",
                "location": "centralus",
                "name": "demisto",
                "properties": {
                    "provisioningState": "Succeeded"
                },
                "tags": {
                    "Owner": "Demi"
                },
                "type": "Microsoft.Resources/resourceGroups"
            }
        ]
    }
}

Human Readable Output

Resource Groups List

Name Location Tags
cloud-shell-storage-eastus eastus  
demi centralus Owner: Demi

Configuration parameters

  • app_id — Application ID
  • subscription_id — Default Subscription ID (required)
  • resource_group_name — Default Resource Group Name (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • auth_type — Authentication Type (required)
  • tenant_id — Tenant ID
  • credentials — Client Secret
  • redirect_uri — Application redirect URI
  • auth_code — Authorization code
  • managed_identities_client_id

Commands (15)

  • azure-storage-account-create-update

    Run this command to create or update a specific account storage.

  • azure-storage-account-list

    Run this command to get the all or specific account storage details.

  • azure-storage-auth-complete

    Run this command to complete the authorization process. Should be used after running the azure-storage-auth-start command.

  • azure-storage-auth-reset

    Run this command if for some reason you need to rerun the authentication process.

  • azure-storage-auth-start

    Run this command to start the authorization process and follow the instructions in the command results.

  • azure-storage-auth-test

    Tests the connectivity to Azure.

  • azure-storage-blob-container-delete

    Run this command to delete a specific blob container.

  • azure-storage-blob-containers-create

    Run this command to create a blob container.

  • azure-storage-blob-containers-list

    Run this command to get the all or specific blob container details.

  • azure-storage-blob-containers-update

    Run this command to update an specific blob container.

  • azure-storage-blob-service-properties-get

    Run this command to get the blob service properties of a specific account storage.

  • azure-storage-blob-service-properties-set

    Run this command to set properties for the blob service in a specific account storage.

  • azure-storage-generate-login-url

    Generate the login url used for Authorization code flow.

  • azure-storage-resource-group-list

    Gets all resource groups for a subscription.

  • azure-storage-subscriptions-list

    Gets all subscriptions for a tenant.

import demistomock as demisto
import urllib3
from CommonServerPython import *
from MicrosoftApiModule import *  # noqa: E402

from CommonServerUserPython import *

urllib3.disable_warnings()

API_VERSION = "2022-09-01"
GRANT_BY_CONNECTION = {
    "Device Code": DEVICE_CODE,
    "Authorization Code": AUTHORIZATION_CODE,
    "Client Credentials": CLIENT_CREDENTIALS,
}
SCOPE_BY_CONNECTION = {
    "Device Code": "https://management.azure.com/user_impersonation offline_access user.read",
    "Authorization Code": "https://management.azure.com/.default",
    "Client Credentials": "https://management.azure.com/.default",
}
PREFIX_URL = "https://management.azure.com/subscriptions/"


class ASClient:
    def __init__(
        self,
        app_id: str,
        subscription_id: str,
        resource_group_name: str,
        verify: bool,
        proxy: bool,
        connection_type: str,
        tenant_id: str = None,
        enc_key: str = None,
        auth_code: str = None,
        redirect_uri: str = None,
        managed_identities_client_id: str = None,
    ):
        if "@" in app_id:
            app_id, refresh_token = app_id.split("@")
            integration_context = get_integration_context()
            integration_context.update(current_refresh_token=refresh_token)
            set_integration_context(integration_context)

        client_args = assign_params(
            self_deployed=True,
            auth_id=app_id,
            token_retrieval_url="https://login.microsoftonline.com/organizations/oauth2/v2.0/token"
            if "Device Code" in connection_type
            else None,
            grant_type=GRANT_BY_CONNECTION.get(connection_type),
            base_url=f"{PREFIX_URL}{subscription_id}",
            verify=verify,
            proxy=proxy,
            resource="https://management.core.windows.net" if "Device" in connection_type else None,
            scope=SCOPE_BY_CONNECTION.get(connection_type),
            tenant_id=tenant_id,
            enc_key=enc_key,
            auth_code=auth_code,
            redirect_uri=redirect_uri,
            managed_identities_client_id=managed_identities_client_id,
            managed_identities_resource_uri=Resources.management_azure,
            command_prefix="azure-storage",
        )
        self.ms_client = MicrosoftClient(**client_args)
        self.subscription_id = subscription_id
        self.resource_group_name = resource_group_name
        self.connection_type = connection_type

    @logger
    def storage_account_list_request(self, account_name: str, resource_group_name: str, subscription_id: str) -> Dict:
        """
            Send the get storage account/s request to the API.
        Args:
            account_name: The storage account name, optional.
            resource_group_name: The resource group name.
            subscription_id: The subscription id.

        Returns:
            The json response from the API call.
        """
        return self.ms_client.http_request(
            method="GET",
            full_url=(
                f"{PREFIX_URL}{subscription_id}/resourceGroups/{resource_group_name}"
                f"/providers/Microsoft.Storage/storageAccounts/{account_name}"
            ),
            params={
                "api-version": API_VERSION,
            },
        )

    @logger
    def storage_blob_service_properties_get_request(
        self, account_name: str, resource_group_name: str, subscription_id: str
    ) -> Dict:
        """
            Send the get blob service properties request to the API.
        Args:
            account_name: The storage account name.
            resource_group_name: The resource group name.
            subscription_id: The subscription id.

        Returns:
            The json response from the API call.
        """
        return self.ms_client.http_request(
            method="GET",
            full_url=(
                f"{PREFIX_URL}{subscription_id}/resourceGroups/{resource_group_name}"
                f"/providers/Microsoft.Storage/storageAccounts/{account_name}/blobServices/default"
            ),
            params={
                "api-version": API_VERSION,
            },
        )

    @logger
    def storage_account_create_update_request(self, subscription_id: str, resource_group_name: str, args: Dict) -> Dict:
        """
            Send the user arguments for the create/update account in the request body to the API.
        Args:
            subscription_id: The subscription id.
            resource_group_name: The resource group name.
            args: The user arguments.

        Returns:
            The json response from the API call.
        """
        account_name = args.get("account_name", "")
        json_data_args = {"sku": {"name": args["sku"]}, "kind": args["kind"], "location": args["location"], "properties": {}}

        if "tags" in args:
            args_tags_list = args["tags"].split(",")
            tags_obj = {f"tag{i + 1!s}": args_tags_list[i] for i in range(len(args_tags_list))}
            json_data_args["tags"] = tags_obj

        if "custom_domain_name" in args:
            custom_domain = {"name": args["custom_domain_name"]}

            if args["use_sub_domain_name"]:
                custom_domain["useSubDomainName"] = args.get("use_sub_domain_name") == "true"

            json_data_args["properties"]["customDomain"] = custom_domain

        if (
            "enc_key_source" in args
            or "enc_keyvault_key_name" in args
            or "enc_keyvault_key_version" in args
            or "enc_keyvault_uri" in args
            or "enc_requireInfrastructureEncryption" in args
        ):
            json_data_args["properties"]["Encryption"] = {}

            if "enc_key_source" in args:
                json_data_args["properties"]["Encryption"]["keySource"] = args.get("enc_key_source")

            if "enc_keyvault_key_name" in args or "enc_keyvault_key_version" in args or "enc_keyvault_uri" in args:
                json_data_args["properties"]["Encryption"]["keyvaultproperties"] = {}

                if "enc_keyvault_key_name" in args:
                    json_data_args["properties"]["Encryption"]["keyvaultproperties"]["keyname"] = args.get(
                        "enc_keyvault_key_name"
                    )

                if "enc_keyvault_key_version" in args:
                    json_data_args["properties"]["Encryption"]["keyvaultproperties"]["keyversion"] = args.get(
                        "enc_keyvault_key_version"
                    )

                if "enc_keyvault_uri" in args:
                    json_data_args["properties"]["Encryption"]["keyvaultproperties"]["keyvaulturi"] = args.get("enc_keyvault_uri")

            if "enc_requireInfrastructureEncryption" in args:
                json_data_args["properties"]["Encryption"]["requireInfrastructureEncryption"] = (
                    args.get("enc_requireInfrastructureEncryption") == "true"
                )

        if (
            "network_ruleset_bypass" in args
            or "network_ruleset_default_action" in args
            or "network_ruleset_ipRules" in args
            or "virtual_network_rules" in args
        ):
            json_data_args["properties"]["networkAcls"] = {}

            if "network_ruleset_bypass" in args:
                json_data_args["properties"]["networkAcls"]["bypass"] = args.get("network_ruleset_bypass")

            if "network_ruleset_default_action" in args:
                json_data_args["properties"]["networkAcls"]["defaultAction"] = args.get("network_ruleset_default_action")

            if "network_ruleset_ipRules" in args:
                json_data_args["properties"]["networkAcls"]["ipRules"] = json.loads(args["network_ruleset_ipRules"])

            if "virtual_network_rules" in args:
                json_data_args["properties"]["networkAcls"]["virtualNetworkRules"] = json.loads(args["virtual_network_rules"])

        if "access_tier" in args:
            json_data_args["properties"]["accessTier"] = args.get("access_tier")

        if "supports_https_traffic_only" in args:
            json_data_args["properties"]["supportsHttpsTrafficOnly"] = args.get("supports_https_traffic_only") == "true"

        if "is_hns_enabled" in args:
            json_data_args["properties"]["isHnsEnabled"] = args.get("is_hns_enabled") == "true"

        if "large_file_shares_state" in args:
            json_data_args["properties"]["largeFileSharesState"] = args.get("large_file_shares_state")

        if "allow_blob_public_access" in args:
            json_data_args["properties"]["allowBlobPublicAccess"] = args.get("allow_blob_public_access") == "true"

        if "minimum_tls_version" in args:
            json_data_args["properties"]["minimumTlsVersion"] = args.get("minimum_tls_version")

        return self.ms_client.http_request(
            method="PUT",
            full_url=(
                f"{PREFIX_URL}{subscription_id}/resourceGroups/{resource_group_name}"
                f"/providers/Microsoft.Storage/storageAccounts/{account_name}"
            ),
            params={
                "api-version": API_VERSION,
            },
            json_data=json_data_args,
            resp_type="response",
        )

    def storage_blob_service_properties_set_request(
        self, subscription_id: str | None, resource_group_name: str | None, args: Dict
    ) -> Dict:
        """
            Send the user arguments for the blob service in the request body to the API.
        Args:
            subscription_id: The subscription id.
            resource_group_name: The resource group name.
            args: The user arguments.

        Returns:
            The json response from the API call.
        """
        account_name = args.get("account_name")
        properties = {}

        if "change_feed_enabled" in args:
            properties["changeFeed"] = {"enabled": args["change_feed_enabled"] == "true"}

        if "change_feed_retention_days" in args:
            if "changeFeed" not in properties:
                properties["changeFeed"] = {}
            properties["changeFeed"]["retentionInDays"] = args.get("change_feed_retention_days")

        if "container_delete_rentention_policy_enabled" in args:
            properties["containerDeleteRetentionPolicy"] = {
                "enabled": args["container_delete_rentention_policy_enabled"] == "true"
            }

        if "container_delete_rentention_policy_days" in args:
            if "containerDeleteRetentionPolicy" not in properties:
                properties["containerDeleteRetentionPolicy"] = {}
            properties["containerDeleteRetentionPolicy"]["days"] = args.get("container_delete_rentention_policy_days")

        if "delete_rentention_policy_enabled" in args:
            properties["deleteRetentionPolicy"] = {"enabled": args["delete_rentention_policy_enabled"] == "true"}

        if "delete_rentention_policy_days" in args:
            if "deleteRetentionPolicy" not in properties:
                properties["deleteRetentionPolicy"] = {}
            properties["deleteRetentionPolicy"]["days"] = args.get("delete_rentention_policy_days")

        if "versioning" in args:
            properties["isVersioningEnabled"] = argToBoolean(args.get("versioning"))

        if (
            "last_access_time_tracking_policy_enabled" in args
            or "last_access_time_tracking_policy_blob_types" in args
            or "last_access_time_tracking_policy_days" in args
        ):
            properties["lastAccessTimeTrackingPolicy"] = {}

            if "last_access_time_tracking_policy_enabled" in args:
                properties["lastAccessTimeTrackingPolicy"]["enable"] = (
                    args.get("last_access_time_tracking_policy_enabled") == "true"
                )

            if "last_access_time_tracking_policy_blob_types" in args:
                properties["lastAccessTimeTrackingPolicy"]["blobType"] = args[
                    "last_access_time_tracking_policy_blob_types"
                ].split(",")

            if "last_access_time_tracking_policy_days" in args:
                properties["lastAccessTimeTrackingPolicy"]["trackingGranularityInDays"] = args.get(
                    "last_access_time_tracking_policy_days"
                )

        if "restore_policy_enabled" in args or "restore_policy_min_restore_time" in args or "restore_policy_days" in args:
            properties["restorePolicy"] = {}

            if "restore_policy_enabled" in args:
                properties["restorePolicy"]["enabled"] = args.get("restore_policy_enabled") == "true"

            if "restore_policy_min_restore_time" in args:
                properties["restorePolicy"]["minRestoreTime"] = args.get("restore_policy_min_restore_time")

            if "restore_policy_days" in args:
                properties["restorePolicy"]["days"] = args.get("restore_policy_days")

        return self.ms_client.http_request(
            method="PUT",
            full_url=(
                f"{PREFIX_URL}{subscription_id}/resourceGroups/{resource_group_name}"
                f"/providers/Microsoft.Storage/storageAccounts/{account_name}/blobServices/default"
            ),
            params={
                "api-version": API_VERSION,
            },
            json_data={"properties": properties},
        )

    def storage_blob_containers_create_update_request(
        self, subscription_id: str | None, resource_group_name: str | None, args: Dict, method: str
    ) -> Dict:
        """
            Send the user arguments for the create blob container in the request body to the API.
        Args:
            subscription_id: The subscription id.
            resource_group_name: The resource group name.
            args: The user arguments.
            method: The method for the http request.

        Returns:
            The json response from the API call.
        """
        container_name = args.get("container_name", "")
        account_name = args.get("account_name", "")
        properties = {}

        if "default_encryption_scope" in args:
            properties["defaultEncryptionScope"] = args.get("default_encryption_scope")

        if "deny_encryption_scope_override" in args:
            properties["denyEncryptionScopeOverride"] = argToBoolean(args.get("deny_encryption_scope_override"))

        if "public_access" in args:
            properties["publicAccess"] = args.get("public_access")

        return self.ms_client.http_request(
            method=method,
            full_url=(
                f"{PREFIX_URL}{subscription_id}/resourceGroups/{resource_group_name}"
                f"/providers/Microsoft.Storage/storageAccounts/{account_name}"
                f"/blobServices/default/containers/{container_name}"
            ),
            params={
                "api-version": API_VERSION,
            },
            json_data={"properties": properties},
        )

    def storage_blob_containers_list_request(
        self, subscription_id: str | None, resource_group_name: str | None, args: Dict
    ) -> Dict:
        """
            Send the get blob container/s request to the API.
        Args:
            subscription_id: The subscription id.
            resource_group_name: The resource group name.
            args: The user arguments.

        Returns:
            The json response from the API call.
        """
        account_name = args.get("account_name", "")
        container_name = args.get("container_name", "")
        full_url = (
            f"{PREFIX_URL}{subscription_id}/resourceGroups/{resource_group_name}"
            f"/providers/Microsoft.Storage/storageAccounts/{account_name}"
            f"/blobServices/default/containers/{container_name}?"
        )

        params = {
            "api-version": API_VERSION,
        }

        if "include_deleted" in args and args["include_deleted"] == "true":
            params["$include"] = "deleted"

        if "maxpagesize" in args:
            params["$maxpagesize"] = args["maxpagesize"]

        return self.ms_client.http_request(
            method="GET",
            full_url=full_url,
            params=params,
        )

    def storage_blob_containers_delete_request(
        self, subscription_id: str | None, resource_group_name: str | None, account_name: str | None, container_name: str | None
    ) -> requests.Response:
        return self.ms_client.http_request(
            method="DELETE",
            full_url=(
                f"{PREFIX_URL}{subscription_id}/resourceGroups/{resource_group_name}"
                f"/providers/Microsoft.Storage/storageAccounts/{account_name}"
                f"/blobServices/default/containers/{container_name}"
            ),
            params={
                "api-version": API_VERSION,
            },
            resp_type="response",
        )

    def list_subscriptions_request(self):
        return self.ms_client.http_request(
            method="GET",
            full_url="https://management.azure.com/subscriptions",
            params={
                "api-version": API_VERSION,
            },
        )

    def list_resource_groups_request(self, subscription_id: str | None, filter_by_tag: str | None, limit: int | None) -> Dict:
        full_url = f"{PREFIX_URL}{subscription_id}/resourcegroups?"
        return self.ms_client.http_request(
            "GET", full_url=full_url, params={"$filter": filter_by_tag, "$top": limit, "api-version": API_VERSION}
        )


# Storage Account Commands


def storage_account_list(client: ASClient, params: Dict, args: Dict) -> CommandResults:
    """
        Gets a storage account if an account name is specified, and a list of storage accounts if not.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments, (like account name).

    Returns:
        CommandResults: The command results in MD table and context data.
    """
    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")
    account_name = args.get("account_name", "")
    response = client.storage_account_list_request(
        account_name=account_name, resource_group_name=resource_group_name, subscription_id=subscription_id
    )
    accounts = response.get("value", [response])

    readable_output = []
    for account in accounts:
        if subscription_id := re.search("subscriptions/(.+?)/resourceGroups", account.get("id", "")):
            subscription_id = subscription_id.group(1)  # type: ignore

        if resource_group := re.search("resourceGroups/(.+?)/providers", account.get("id", "")):
            resource_group = resource_group.group(1)  # type: ignore

        readable_output.append(
            {
                "Account Name": account.get("name"),
                "Subscription ID": subscription_id,
                "Resource Group": resource_group,
                "Kind": account.get("kind"),
                "Status Primary": account.get("properties").get("statusOfPrimary"),
                "Status Secondary": account.get("properties").get("statusOfSecondary"),
                "Location": account.get("location"),
            }
        )

    return CommandResults(
        outputs_prefix="AzureStorage.StorageAccount",
        outputs_key_field="id",
        outputs=accounts,
        readable_output=tableToMarkdown(
            "Azure Storage Account List",
            readable_output,
            ["Account Name", "Subscription ID", "Resource Group", "Kind", "Status Primary", "Status Secondary", "Location"],
        ),
        raw_response=response,
    )


def storage_account_create_update(client: ASClient, params: Dict, args: Dict) -> Union[CommandResults, str]:
    """
        Creates or updates a given storage account.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments, (like account name).

    Returns:
        CommandResults: The command results in MD table and context data.
    """
    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")

    response = client.storage_account_create_update_request(
        subscription_id=subscription_id, resource_group_name=resource_group_name, args=args
    )

    if not response.text:
        return f"The request was accepted - the account {args.get('account_name')} will be created shortly"

    response = response.json()
    if subscription_id := re.search("subscriptions/(.+?)/resourceGroups", response.get("id", "")):
        subscription_id = subscription_id.group(1)  # type: ignore

    if resource_group := re.search("resourceGroups/(.+?)/providers", response.get("id", "")):
        resource_group = resource_group.group(1)  # type: ignore

    readable_output = {
        "Account Name": response.get("name"),
        "Subscription ID": subscription_id,
        "Resource Group": resource_group,
        "Kind": response.get("kind"),
        "Status Primary": response.get("properties", "").get("statusOfPrimary"),
        "Status Secondary": response.get("properties", "").get("statusOfSecondary"),
        "Location": response.get("location"),
    }

    return CommandResults(
        outputs_prefix="AzureStorage.StorageAccount",
        outputs_key_field="id",
        outputs=response,
        readable_output=tableToMarkdown(
            "Azure Storage Account",
            readable_output,
            ["Account Name", "Subscription ID", "Resource Group", "Kind", "Status Primary", "Status Secondary", "Location"],
        ),
        raw_response=response,
    )


# Blob Service Commands


def storage_blob_service_properties_get(client: ASClient, params: Dict, args: Dict) -> CommandResults:
    """
        Gets the blob service properties for the storage account.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments, (like account name).

    Returns:
        CommandResults: The command results in MD table and context data.
    """
    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")
    account_name = args.get("account_name")
    response = client.storage_blob_service_properties_get_request(
        account_name=account_name, resource_group_name=resource_group_name, subscription_id=subscription_id
    )

    if subscription_id := re.search("subscriptions/(.+?)/resourceGroups", response.get("id", "")):
        subscription_id = subscription_id.group(1)  # type: ignore

    if resource_group := re.search("resourceGroups/(.+?)/providers", response.get("id", "")):
        resource_group = resource_group.group(1)  # type: ignore

    if account_name := re.search("storageAccounts/(.+?)/blobServices", response.get("id", "")):
        account_name = account_name.group(1)  # type: ignore

    readable_output = {
        "Name": response.get("name"),
        "Account Name": account_name,
        "Subscription ID": subscription_id,
        "Resource Group": resource_group,
        "Change Feed": response.get("properties").get("changeFeed").get("enabled")
        if response.get("properties").get("changeFeed")
        else "",
        "Delete Retention Policy": response.get("properties").get("deleteRetentionPolicy").get("enabled")
        if response.get("properties").get("deleteRetentionPolicy")
        else "",
        "Versioning": response.get("properties").get("isVersioningEnabled"),
    }

    return CommandResults(
        outputs_prefix="AzureStorage.BlobServiceProperties",
        outputs_key_field="id",
        outputs=response,
        readable_output=tableToMarkdown(
            "Azure Storage Blob Service Properties",
            readable_output,
            ["Name", "Account Name", "Subscription ID", "Resource Group", "Change Feed", "Delete Retention Policy", "Versioning"],
        ),
        raw_response=response,
    )


def storage_blob_service_properties_set(client: ASClient, params: Dict, args: Dict):
    """
        Sets the blob service properties for the storage account.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments, (like account name).

    Returns:
        CommandResults: The command results in MD table and context data.
    """
    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")

    response = client.storage_blob_service_properties_set_request(
        subscription_id=subscription_id, resource_group_name=resource_group_name, args=args
    )

    if subscription_id := re.search("subscriptions/(.+?)/resourceGroups", response.get("id", "")):
        subscription_id = subscription_id.group(1)  # type: ignore

    if resource_group := re.search("resourceGroups/(.+?)/providers", response.get("id", "")):
        resource_group = resource_group.group(1)  # type: ignore

    if account_name := re.search("storageAccounts/(.+?)/blobServices", response.get("id", "")):
        account_name = account_name.group(1)  # type: ignore

    readable_output = {
        "Name": response.get("name"),
        "Account Name": account_name,
        "Subscription ID": subscription_id,
        "Resource Group": resource_group,
        "Change Feed": str(response.get("properties", "").get("changeFeed").get("enabled"))
        if response.get("properties", "").get("changeFeed")
        else "",
        "Delete Retention Policy": str(response.get("properties", "").get("deleteRetentionPolicy").get("enabled"))
        if response.get("properties", "").get("deleteRetentionPolicy")
        else "",
        "Versioning": response.get("properties", "").get("isVersioningEnabled"),
    }

    return CommandResults(
        outputs_prefix="AzureStorage.BlobServiceProperties",
        outputs_key_field="id",
        outputs=response,
        readable_output=tableToMarkdown(
            "Azure Storage Blob Service Properties",
            readable_output,
            ["Name", "Account Name", "Subscription ID", "Resource Group", "Change Feed", "Delete Retention Policy", "Versioning"],
        ),
        raw_response=response,
    )


# Blob Containers Commands


def storage_blob_containers_create(client: ASClient, params: Dict, args: Dict):
    """
        Creates a blob container.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments, (like account name, container name).

    Returns:
        CommandResults: The command results in MD table and context data.
    """
    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")

    response = client.storage_blob_containers_create_update_request(
        subscription_id=subscription_id, resource_group_name=resource_group_name, args=args, method="PUT"
    )

    if subscription_id := re.search("subscriptions/(.+?)/resourceGroups", response.get("id", "")):
        subscription_id = subscription_id.group(1)  # type: ignore

    if resource_group := re.search("resourceGroups/(.+?)/providers", response.get("id", "")):
        resource_group = resource_group.group(1)  # type: ignore

    if account_name := re.search("storageAccounts/(.+?)/blobServices", response.get("id", "")):
        account_name = account_name.group(1)  # type: ignore

    readable_output = {
        "Name": response.get("name"),
        "Account Name": account_name,
        "Subscription ID": subscription_id,
        "Resource Group": resource_group,
    }

    return CommandResults(
        outputs_prefix="AzureStorage.BlobContainer",
        outputs_key_field="id",
        outputs=response,
        readable_output=tableToMarkdown(
            "Azure Storage Blob Containers Properties",
            readable_output,
            ["Name", "Account Name", "Subscription ID", "Resource Group"],
        ),
        raw_response=response,
    )


def storage_blob_containers_update(client: ASClient, params: Dict, args: Dict) -> CommandResults:
    """
        Updates a given blob container.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments, (like account name, container name).

    Returns:
        CommandResults: The command results in MD table and context data.
    """
    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")

    response = client.storage_blob_containers_create_update_request(
        subscription_id=subscription_id, resource_group_name=resource_group_name, args=args, method="PATCH"
    )

    if subscription_id := re.search("subscriptions/(.+?)/resourceGroups", response.get("id", "")):
        subscription_id = subscription_id.group(1)  # type: ignore

    if resource_group := re.search("resourceGroups/(.+?)/providers", response.get("id", "")):
        resource_group = resource_group.group(1)  # type: ignore

    if account_name := re.search("storageAccounts/(.+?)/blobServices", response.get("id", "")):
        account_name = account_name.group(1)  # type: ignore

    readable_output = {
        "Name": response.get("name"),
        "Account Name": account_name,
        "Subscription ID": subscription_id,
        "Resource Group": resource_group,
        "Public Access": response.get("properties", {}).get("publicAccess"),
    }

    return CommandResults(
        outputs_prefix="AzureStorage.BlobContainer",
        outputs_key_field="id",
        outputs=response,
        readable_output=tableToMarkdown(
            "Azure Storage Blob Containers Properties",
            readable_output,
            ["Name", "Account Name", "Subscription ID", "Resource Group", "Public Access"],
        ),
        raw_response=response,
    )


def storage_blob_containers_list(client: ASClient, params: Dict, args: Dict) -> CommandResults:
    """
        Gets a blob container if an container name is specified, and a list of blob containers if not.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments, (like account name, container name).

    Returns:
        CommandResults: The command results in MD table and context data.
    """
    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")

    response = client.storage_blob_containers_list_request(
        subscription_id=subscription_id, resource_group_name=resource_group_name, args=args
    )
    containers = response.get("value", [response])

    readable_output = []
    for container in containers:
        if subscription_id := re.search("subscriptions/(.+?)/resourceGroups", container.get("id", "")):
            subscription_id = subscription_id.group(1)  # type: ignore

        if resource_group := re.search("resourceGroups/(.+?)/providers", container.get("id", "")):
            resource_group = resource_group.group(1)  # type: ignore

        if account_name := re.search("storageAccounts/(.+?)/blobServices", container.get("id", "")):
            account_name = account_name.group(1)  # type: ignore

        readable_output.append(
            {
                "Container Name": container.get("name"),
                "Account Name": account_name,
                "Subscription ID": subscription_id,
                "Resource Group": resource_group,
                "Public Access": container.get("properties", {}).get("publicAccess"),
                "Lease State": container.get("properties", {}).get("leaseState"),
                "Last Modified Time": container.get("properties", {}).get("lastModifiedTime"),
            }
        )

    return CommandResults(
        outputs_prefix="AzureStorage.BlobContainer",
        outputs_key_field="id",
        outputs=containers,
        readable_output=tableToMarkdown(
            "Azure Storage Blob Containers list",
            readable_output,
            [
                "Container Name",
                "Account Name",
                "Subscription ID",
                "Resource Group",
                "Public Access",
                "Lease State",
                "Last Modified Time",
            ],
        ),
        raw_response=response,
    )


def storage_blob_containers_delete(client: ASClient, params: Dict, args: Dict) -> str:
    """
    This function deletes a given blob container.
    Args:
        client: The microsoft client.
        params: The configuration parameters.
        args: The users arguments.
    Returns:
        str: A string that represent the status of the request.
    """

    # subscription_id and resource_group_name arguments can be passed as command arguments or as configuration parameters,
    # if both are passed as arguments, the command arguments will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    resource_group_name = get_from_args_or_params(params=params, args=args, key="resource_group_name")
    account_name = args.get("account_name", "")
    container_name = args.get("container_name", "")

    res = client.storage_blob_containers_delete_request(
        subscription_id=subscription_id,
        resource_group_name=resource_group_name,
        account_name=account_name,
        container_name=container_name,
    )
    if res.status_code == 200:
        return "The request to delete the blob container was sent successfully."
    else:
        return f"Failed to delete the blob container.\
Status code: {res.status_code} \nPlease verify that the container and account name are correct."


def storage_subscriptions_list(client: ASClient) -> CommandResults:
    """
        Gets a list of subscriptions.
    Args:
        client: The microsoft client.
    Returns:
        CommandResults: The command results in MD table and context data.
    """
    res = client.list_subscriptions_request()
    subscriptions = res.get("value", [])

    return CommandResults(
        outputs_prefix="AzureStorage.Subscription",
        outputs_key_field="id",
        outputs=subscriptions,
        readable_output=tableToMarkdown(
            "Azure Storage Subscriptions list",
            subscriptions,
            ["subscriptionId", "tenantId", "displayName", "state"],
        ),
        raw_response=res,
    )


def storage_resource_group_list(client: ASClient, params: Dict, args: Dict) -> CommandResults:
    """
    List all resource groups in the subscription.
    Args:
        client (KeyVaultClient): microsoft client.
        args (Dict[str, Any]): command arguments.
        params (Dict[str, Any]): configuration parameters.
    Returns:
        CommandResults: Command results with raw response, outputs and readable outputs.
    """
    tag = args.get("tag")
    limit = arg_to_number(args.get("limit")) or 50
    # subscription_id can be passed as command argument or as configuration parameter,
    # if both are passed as arguments, the command argument will be used.
    subscription_id = get_from_args_or_params(params=params, args=args, key="subscription_id")
    filter_by_tag = azure_tag_formatter(tag) if tag else ""

    response = client.list_resource_groups_request(subscription_id=subscription_id, filter_by_tag=filter_by_tag, limit=limit)
    data_from_response = response.get("value", [])

    readable_output = tableToMarkdown(
        "Resource Groups List",
        data_from_response,
        ["name", "location", "tags", "properties.provisioningState"],
        removeNull=True,
        headerTransform=string_to_table_header,
    )
    return CommandResults(
        outputs_prefix="AzureStorage.ResourceGroup",
        outputs_key_field="id",
        outputs=data_from_response,
        raw_response=response,
        readable_output=readable_output,
    )

    # Authentication Functions


def start_auth(client: ASClient) -> CommandResults:
    result = client.ms_client.start_auth("!azure-storage-auth-complete")
    return CommandResults(readable_output=result)


def complete_auth(client: ASClient) -> str:
    client.ms_client.get_access_token()
    return "✅ Authorization completed successfully."


def test_connection(client: ASClient) -> str:
    client.ms_client.get_access_token()
    return "✅ Success!"


def test_module(client: ASClient) -> str:
    """Tests API connectivity and authentication'
    Returning 'ok' indicates that the integration works like it is supposed to.
    Connection to the service is successful.
    Raises exceptions if something goes wrong.
    :type ASClient: ``Client``
    :param Client: client to use
    :return: 'ok' if test passed.
    :rtype: ``str``
    """
    # This  should validate all the inputs given in the integration configuration panel,
    # either manually or by using an API that uses them.
    if "Device" in client.connection_type:
        raise DemistoException(
            "Please enable the integration and run `!azure-storage-auth-start`"
            "and `!azure-storage-auth-complete` to log in."
            "You can validate the connection by running `!azure-storage-auth-test`\n"
            "For more details press the (?) button."
        )

    elif client.connection_type == "Azure Managed Identities" or client.connection_type == "Client Credentials":
        client.ms_client.get_access_token()
        return "ok"
    else:
        raise Exception(
            "When using user auth flow configuration, "
            "Please enable the integration and run the !azure-storage-auth-test command in order to test it"
        )


def main() -> None:  # pragma: no cover
    params = demisto.params()
    command = demisto.command()
    args = demisto.args()

    demisto.debug(f"Command being called is {command}")
    try:
        client = ASClient(
            app_id=params.get("app_id", ""),
            subscription_id=params.get("subscription_id", ""),
            resource_group_name=params.get("resource_group_name", ""),
            verify=not params.get("insecure", False),
            proxy=params.get("proxy", False),
            connection_type=params.get("auth_type", "Device Code"),
            tenant_id=params.get("tenant_id"),
            enc_key=params.get("credentials", {}).get("password"),
            auth_code=(params.get("auth_code", {})).get("password"),
            redirect_uri=params.get("redirect_uri"),
            managed_identities_client_id=get_azure_managed_identities_client_id(params),
        )
        if command == "test-module":
            return_results(test_module(client))
        elif command == "azure-storage-generate-login-url":
            return_results(generate_login_url(client.ms_client))
        elif command == "azure-storage-auth-start":
            return_results(start_auth(client))
        elif command == "azure-storage-auth-complete":
            return_results(complete_auth(client))
        elif command == "azure-storage-auth-test":
            return_results(test_connection(client))
        elif command == "azure-storage-auth-reset":
            return_results(reset_auth())
        elif command == "azure-storage-account-list":
            return_results(storage_account_list(client, params, args))
        elif command == "azure-storage-account-create-update":
            return_results(storage_account_create_update(client, params, args))
        elif command == "azure-storage-blob-service-properties-get":
            return_results(storage_blob_service_properties_get(client, params, args))
        elif command == "azure-storage-blob-service-properties-set":
            return_results(storage_blob_service_properties_set(client, params, args))
        elif command == "azure-storage-blob-containers-create":
            return_results(storage_blob_containers_create(client, params, args))
        elif command == "azure-storage-blob-containers-update":
            return_results(storage_blob_containers_update(client, params, args))
        elif command == "azure-storage-blob-containers-list":
            return_results(storage_blob_containers_list(client, params, args))
        elif command == "azure-storage-blob-container-delete":
            return_results(storage_blob_containers_delete(client, params, args))
        elif command == "azure-storage-subscriptions-list":
            return_results(storage_subscriptions_list(client))
        elif command == "azure-storage-resource-group-list":
            return_results(storage_resource_group_list(client, params, args))
        else:
            raise NotImplementedError(f'Command "{command}" is not implemented.')
    except Exception as e:
        demisto.debug(traceback.format_exc())
        return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}", e)


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()