Azure Storage Table
Create and Manage Azure Storage Tables and Entities.
IT Services · Azure Storage Table
Details
| ID | Azure Storage Table |
|---|---|
| Provider | Microsoft |
| Category | IT Services |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Azure Storage Table
Create and Manage Azure Storage Tables and Entities.
This integration was integrated and tested with version “2020-10-02” of Azure Storage Table
Configure Azure Storage Table in Cortex
| Parameter | Required |
|---|---|
| Storage account name | True |
| Account SAS Token | False |
| Use Azure Managed Identities | False |
| Azure Managed Identities Client ID | False |
| Use system proxy settings | False |
| Trust any certificate (not secure) | False |
Shared Access Signatures (SAS) Permissions
In order to use the integration use-cases,
please make sure your SAS token contains the following permissions:
- ‘Table’ service.
- ‘Service’ and ‘Object’ resource types.
- ‘Read’, ‘Write’, ‘Delete’, ‘List’, ‘Create’, ‘Add’, ‘Update’ and ‘Immutable storage’ permissions.
- Review and select “Generate”.
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
azure-storage-table-create
Creates a new table in a storage account.
Base Command
azure-storage-table-create
Input
| Argument Name | Description | Required |
|---|---|---|
| table_name | The name of the new table to create. Rules for naming tables can be found here: https://docs.microsoft.com/en-us/rest/api/storageservices/understanding-the-table-service-data-model. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageTable.Table.name | String | Table name. |
Command Example
!azure-storage-table-create table_name="xsoar"
Context Example
{
"AzureStorageTable": {
"Table": {
"name": "xsoar"
}
}
}
Human Readable Output
Table xsoar successfully created.
azure-storage-table-delete
Delete the specified table and any data it contains.
Base Command
azure-storage-table-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| table_name | The name of the table to delete. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-table-delete table_name="xsoar"
Human Readable Output
Table xsoar successfully deleted.
azure-storage-table-query
List tables under the specified account.
Base Command
azure-storage-table-query
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | Number of Tables to retrieve. Default is 50. Default is 50. | Optional |
| filter | Filter Tables Query expression. Information about Query expression structure can be found here: https://docs.microsoft.com/en-us/rest/api/storageservices/querying-tables-and-entities#constructing-filter-strings. |
Optional |
| page | Page Number. Default is 1. Default is 1. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageTable.Table.name | String | Table name. |
Command Example
!azure-storage-table-query filter="TableName%20eq%20'xsoar'"
Context Example
{
"AzureStorageTable": {
"Table": {
"name": "xsoar"
}
}
}
Human Readable Output
Tables List
Current page size: 50
Showing page 1 out others that may exist
Name xsoar
azure-storage-table-entity-insert
Insert a new entity into a table.
Base Command
azure-storage-table-entity-insert
Input
| Argument Name | Description | Required |
|---|---|---|
| table_name | Table name. | Required |
| partition_key | Unique identifier for the partition within a given table. | Required |
| row_key | Unique identifier for an entity within a given partition. | Required |
| entity_fields | Entity fields in JSON format: { “Key1”: Value1, “Key2”: Value2}. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageTable.Table.Entity.PartitionKey | String | Entity partition key. |
| AzureStorageTable.Table.Entity.RowKey | String | Entity row key. |
| AzureStorageTable.Table.Entity.Timestamp | Date | Entity last update UTC time. |
| AzureStorageTable.Table.name | String | Entity table name. |
Command Example
!azure-storage-table-entity-insert table_name="xsoar" partition_key="xsoar-partition" row_key="xsoar-row" entity_fields=`{"Age":20}`
Context Example
{
"AzureStorageTable": {
"Table": {
"Entity": [
{
"Age": 20,
"PartitionKey": "xsoar-partition",
"RowKey": "xsoar-row",
"Timestamp": "2021-11-28T13:23:18"
}
],
"name": "xsoar"
}
}
}
Human Readable Output
Entity Fields for xsoar Table
Age Partition Key Row Key Timestamp 20 xsoar-partition xsoar-row 2021-11-28T13:23:18
azure-storage-table-entity-update
Update an existing entity in a table. The Update Entity command does not replace the existing entity.
Base Command
azure-storage-table-entity-update
Input
| Argument Name | Description | Required |
|---|---|---|
| table_name | Entity table name. | Required |
| partition_key | Unique identifier for the partition within a given table. | Required |
| row_key | Unique identifier for an entity within a given partition. | Required |
| entity_fields | Entity fields in JSON format: { “Key1”: Value1, “Key2”: Value2}. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-table-entity-update table_name="xsoar" partition_key="xsoar-partition" row_key="xsoar-row" entity_fields=`{"Address":"New York"}`
Human Readable Output
Entity in xsoar table successfully updated.
azure-storage-table-entity-replace
Replace an existing entity in a table. The Replace Entity command replace the entire entity and can be used to remove properties.
Base Command
azure-storage-table-entity-replace
Input
| Argument Name | Description | Required |
|---|---|---|
| table_name | Table name. | Required |
| partition_key | Unique identifier for the partition within a given table. | Required |
| row_key | Unique identifier for an entity within a given partition. | Required |
| entity_fields | Entity records in JSON format: { “Key1”: Value1, “Key2”: Value2}. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-table-entity-replace table_name="xsoar" partition_key="xsoar-partition" row_key="xsoar-row" entity_fields=`{"City": "TLV" }`
Human Readable Output
Entity in xsoar table successfully replaced.
azure-storage-table-entity-query
Query Entities in a table.
Base Command
azure-storage-table-entity-query
Input
| Argument Name | Description | Required |
|---|---|---|
| table_name | Entity table name. | Required |
| partition_key | Unique identifier for the partition within a given table. If specified, ‘row_key’ argument must also be specified. | Optional |
| row_key | Unique identifier for an entity within a given partition. If specified, ‘partition_key’ argument must also be specified. | Optional |
| filter | Filter Entities query expression. Information about Query expression structure can be found here: https://docs.microsoft.com/en-us/rest/api/storageservices/querying-tables-and-entities#constructing-filter-strings. |
Optional |
| select | Comma-separated Entity properties to return. If not specified - all fields will be retrieved. | Optional |
| limit | Number of entities to retrieve. Default is 50. This argument is will be ignored when ‘partition_key’ or ‘row_key’ arguments are provided. Default is 50. |
Optional |
| page | Page number. Default is 1. This argument is will be ignored when ‘partition_key’ or ‘row_key’ arguments are provided. Default is 1. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageTable.Table.name | String | Entity table Name. |
Command Example
!azure-storage-table-entity-query table_name="xsoar"
Context Example
{
"AzureStorageTable": {
"Table": {
"Entity": [
{
"Address": "New York",
"City": "TLV",
"PartitionKey": "xsoar-partition",
"RowKey": "xsoar-row",
"Timestamp": "2021-11-28T13:23:27"
}
],
"name": "xsoar"
}
}
}
Human Readable Output
Entity Fields for xsoar table
Current page size: 50
Showing page 1 out others that may exist
Address City Partition Key Row Key Timestamp New York TLV xsoar-partition xsoar-row 2021-11-28T13:23:27
azure-storage-table-entity-delete
Delete an existing entity in a table.
Base Command
azure-storage-table-entity-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| table_name | Entity table name. | Required |
| partition_key | Unique identifier for the partition within a given table. | Required |
| row_key | Unique identifier for an entity within a given partition. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-table-entity-delete table_name="xsoar" partition_key="xsoar-partition" row_key="xsoar-row"
Human Readable Output
Entity in xsoar table successfully deleted.
Configuration parameters
credentials— Storage account nameuse_managed_identities— Use Azure Managed Identitiesmanaged_identities_client_id—proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)
Commands (8)
-
azure-storage-table-createCreates a new table in a storage account.
-
azure-storage-table-deleteDelete the specified table and any data it contains.
-
azure-storage-table-entity-deleteDelete an existing entity in a table.
-
azure-storage-table-entity-insertInsert a new entity into a table.
-
azure-storage-table-entity-queryQuery Entities in a table.
-
azure-storage-table-entity-replaceReplace an existing entity in a table. The Replace Entity command replace the entire entity and can be used to remove properties.
-
azure-storage-table-entity-updateUpdate an existing entity in a table. The Update Entity command does not replace the existing entity.
-
azure-storage-table-queryList tables under the specified account.
import pytest from CommonServerPython import * ACCOUNT_NAME = "test" BASE_URL = f"https://{ACCOUNT_NAME}.table.core.windows.net/" SAS_TOKEN = "XXXX" API_VERSION = "2020-10-02" def load_mock_response(file_name: str) -> str: """ Load mock file that simulates an API response. Args: file_name (str): Name of the mock response JSON file to return. Returns: str: Mock file content. """ with open(f"test_data/{file_name}", encoding="utf-8") as mock_file: return mock_file.read() def test_azure_storage_create_table_command(requests_mock): """ Scenario: Create Table. Given: - User has provided valid credentials. When: - azure-storage-table-create called. Then: - Ensure number of items is correct. - Ensure outputs prefix is correct. - Ensure a sample value from the API matches what is generated in the context. - Ensure validation of the table name. """ from AzureStorageTable import Client, create_table_command mock_response = json.loads(load_mock_response("create_table.json")) url = f"{BASE_URL}Tables?{SAS_TOKEN}" table_name = "test" requests_mock.post(url, json=mock_response) client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) result = create_table_command(client, {"table_name": table_name}) assert len(result.outputs) == 1 assert result.outputs_prefix == "AzureStorageTable.Table" assert result.outputs.get("name") == "xsoar" invalid_table_name = "test--1" with pytest.raises(Exception): create_table_command(client, {"table_name": invalid_table_name}) def test_azure_storage_delete_table_command(requests_mock): """ Scenario: Delete Table. Given: - User has provided valid credentials. When: - azure-storage-table--delete called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageTable import Client, delete_table_command table_name = "test" url = f"{BASE_URL}Tables('{table_name}')?{SAS_TOKEN}" requests_mock.delete(url, text="") client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) result = delete_table_command(client, {"table_name": table_name}) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Table {table_name} successfully deleted." def test_azure_storage_query_tables_command(requests_mock): """ Scenario: Query Tables. Given: - User has provided valid credentials. When: - azure-storage-table-query called. Then: - Ensure number of items is correct. - Ensure outputs prefix is correct. - Ensure a sample value from the API matches what is generated in the context. """ from AzureStorageTable import Client, query_tables_command mock_response = json.loads(load_mock_response("query_table.json")) url = f"{BASE_URL}Tables?{SAS_TOKEN}&$top=50" requests_mock.get(url, json=mock_response) client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) result = query_tables_command(client, {}) assert len(result.outputs) == 2 assert result.outputs_prefix == "AzureStorageTable.Table" assert result.outputs[0].get("name") == "xsoar1" assert result.outputs[1].get("name") == "xsoar2" def test_azure_storage_insert_entity_command(requests_mock): """ Scenario: Insert Entity. Given: - User has provided valid credentials. When: - azure-storage-table-entity-insert called. Then: - Ensure number of items is correct. - Ensure outputs prefix is correct. - Ensure a sample value from the API matches what is generated in the context. """ from AzureStorageTable import Client, insert_entity_command mock_response = json.loads(load_mock_response("insert_entity.json")) table_name = "test" url = f"{BASE_URL}{table_name}?{SAS_TOKEN}" requests_mock.post(url, json=mock_response) client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) command_arguments = { "entity_fields": '{"Age":20}', "partition_key": "xsoar-partition", "row_key": "xsoar-row", "table_name": table_name, } result = insert_entity_command(client, command_arguments) assert len(result.outputs) == 2 assert result.outputs_prefix == "AzureStorageTable.Table" assert len(result.outputs.get("Entity")) == 1 assert len(result.outputs.get("Entity")[0]) == 4 assert result.outputs.get("Entity")[0].get("PartitionKey") == "xsoar-partition" assert result.outputs.get("Entity")[0].get("RowKey") == "xsoar-row" assert result.outputs.get("name") == table_name # def test_azure_storage_update_entity_command(requests_mock): """ Scenario: Update Entity. Given: - User has provided valid credentials. When: - azure-storage-table-entity-update called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageTable import Client, update_entity_command table_name = "test" partition_key = "xsoar-partition" row_key = "xsoar-row" url = f"{BASE_URL}{table_name}(PartitionKey='{partition_key}',RowKey='{row_key}')?{SAS_TOKEN}" requests_mock.register_uri("MERGE", url, text="") client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) command_arguments = { "entity_fields": '{"Address":"New York"}', "partition_key": partition_key, "row_key": row_key, "table_name": table_name, } result = update_entity_command(client, command_arguments) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Entity in {table_name} table successfully updated." def test_azure_storage_replace_entity_command(requests_mock): """ Scenario: Replace Entity. Given: - User has provided valid credentials. When: - azure-storage-table-entity-replace called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageTable import Client, replace_entity_command table_name = "test" partition_key = "xsoar-partition" row_key = "xsoar-row" url = f"{BASE_URL}{table_name}(PartitionKey='{partition_key}',RowKey='{row_key}')?{SAS_TOKEN}" requests_mock.put(url, text="") client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) command_arguments = { "entity_fields": '{"Address":"New York"}', "partition_key": partition_key, "row_key": row_key, "table_name": table_name, } result = replace_entity_command(client, command_arguments) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Entity in {table_name} table successfully replaced." def test_azure_storage_query_entity_command(requests_mock): """ Scenario: Query Entity. Given: - User has provided valid credentials. When: - azure-storage-table-entity-query called. Then: - Ensure number of items is correct. - Ensure outputs prefix is correct. - Ensure a sample value from the API matches what is generated in the context. """ from AzureStorageTable import Client, query_entity_command mock_response = json.loads(load_mock_response("query_entity.json")) table_name = "test" url = f"{BASE_URL}{table_name}()?{SAS_TOKEN}&$top=1" requests_mock.get(url, json=mock_response) client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) result = query_entity_command(client, {"table_name": table_name, "limit": "1"}) assert len(result.outputs) == 2 assert len(result.outputs.get("Entity")) == 1 assert len(result.outputs.get("Entity")[0]) == 4 assert result.outputs_prefix == "AzureStorageTable.Table" assert result.outputs.get("Entity")[0].get("PartitionKey") == "xsoar-partition" assert result.outputs.get("Entity")[0].get("RowKey") == "xsoar-row" assert result.outputs.get("Entity")[0].get("Address") == "New York" assert result.outputs.get("name") == table_name def test_azure_storage_delete_entity_command(requests_mock): """ Scenario: Delete Entity. Given: - User has provided valid credentials. When: - azure-storage-table-entity-delete called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageTable import Client, delete_entity_command table_name = "test" partition_key = "xsoar-partition" row_key = "xsoar-row" url = f"{BASE_URL}{table_name}(PartitionKey='{partition_key}',RowKey='{row_key}')?{SAS_TOKEN}" requests_mock.delete(url, text="") client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) command_arguments = {"partition_key": partition_key, "row_key": row_key, "table_name": table_name} result = delete_entity_command(client, command_arguments) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Entity in {table_name} table successfully deleted." @pytest.mark.parametrize(argnames="client_id", argvalues=["test_client_id", None]) def test_test_module_command_with_managed_identities(mocker, requests_mock, client_id): """ Given: - Managed Identities client id for authentication. When: - Calling test_module. Then: - Ensure the output are as expected. """ import re import AzureStorageTable import demistomock as demisto from AzureStorageTable import MANAGED_IDENTITIES_TOKEN_URL, main mock_token = {"access_token": "test_token", "expires_in": "86400"} get_mock = requests_mock.get(MANAGED_IDENTITIES_TOKEN_URL, json=mock_token) requests_mock.get(re.compile(".table.core.windows.net/.*")) params = { "managed_identities_client_id": {"password": client_id}, "use_managed_identities": "True", "credentials": {"identifier": "test_storage_account_name"}, } mocker.patch.object(demisto, "params", return_value=params) mocker.patch.object(demisto, "command", return_value="test-module") mocker.patch.object(AzureStorageTable, "return_results", return_value=params) main() assert "ok" in AzureStorageTable.return_results.call_args[0][0] qs = get_mock.last_request.qs assert (client_id and qs["client_id"] == [client_id]) or "client_id" not in qs