diff --git a/src/azure-cli-core/azure/cli/core/commands/parameters.py b/src/azure-cli-core/azure/cli/core/commands/parameters.py index 075fab99a4e..46fd524637a 100644 --- a/src/azure-cli-core/azure/cli/core/commands/parameters.py +++ b/src/azure-cli-core/azure/cli/core/commands/parameters.py @@ -248,6 +248,8 @@ def _type(value): name_type = CLIArgumentType(options_list=['--name', '-n'], help='the primary resource name') +edge_zone_type = CLIArgumentType(options_list='--edge-zone', help='The name of edge zone.', is_preview=True) + def get_location_type(cli_ctx): location_type = CLIArgumentType( diff --git a/src/azure-cli/azure/cli/command_modules/storage/_params.py b/src/azure-cli/azure/cli/command_modules/storage/_params.py index d6b7aad64e2..d8b949c465b 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/_params.py +++ b/src/azure-cli/azure/cli/command_modules/storage/_params.py @@ -6,7 +6,7 @@ from azure.cli.core.profiles import ResourceType from azure.cli.core.commands.validators import get_default_location_from_resource_group from azure.cli.core.commands.parameters import (tags_type, file_type, get_location_type, get_enum_type, - get_three_state_flag) + get_three_state_flag, edge_zone_type) from azure.cli.core.local_context import LocalContextAttribute, LocalContextAction, ALL from ._validators import (get_datetime_type, validate_metadata, get_permission_validator, get_permission_help_string, @@ -270,6 +270,7 @@ def load_arguments(self, _): # pylint: disable=too-many-locals, too-many-statem help='The minimum TLS version to be permitted on requests to storage. ' 'The default interpretation is TLS 1.0 for this property') c.argument('allow_shared_key_access', allow_shared_key_access_type) + c.argument('edge_zone', edge_zone_type, min_api='2020-08-01-preview') with self.argument_context('storage account private-endpoint-connection', resource_type=ResourceType.MGMT_STORAGE) as c: diff --git a/src/azure-cli/azure/cli/command_modules/storage/operations/account.py b/src/azure-cli/azure/cli/command_modules/storage/operations/account.py index b97b1a024b9..56a0754fa92 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/operations/account.py +++ b/src/azure-cli/azure/cli/command_modules/storage/operations/account.py @@ -54,7 +54,7 @@ def create_storage_account(cmd, resource_group_name, account_name, sku=None, loc encryption_key_type_for_table=None, encryption_key_type_for_queue=None, routing_choice=None, publish_microsoft_endpoints=None, publish_internet_endpoints=None, require_infrastructure_encryption=None, allow_blob_public_access=None, - min_tls_version=None, allow_shared_key_access=None): + min_tls_version=None, allow_shared_key_access=None, edge_zone=None): StorageAccountCreateParameters, Kind, Sku, CustomDomain, AccessTier, Identity, Encryption, NetworkRuleSet = \ cmd.get_models('StorageAccountCreateParameters', 'Kind', 'Sku', 'CustomDomain', 'AccessTier', 'Identity', 'Encryption', 'NetworkRuleSet') @@ -155,6 +155,11 @@ def create_storage_account(cmd, resource_group_name, account_name, sku=None, loc if allow_shared_key_access is not None: params.allow_shared_key_access = allow_shared_key_access + if edge_zone is not None: + ExtendedLocation, ExtendedLocationTypes = cmd.get_models('ExtendedLocation', 'ExtendedLocationTypes') + params.extended_location = ExtendedLocation(name=edge_zone, + type=ExtendedLocationTypes.EDGE_ZONE) + return scf.storage_accounts.begin_create(resource_group_name, account_name, params) diff --git a/src/azure-cli/azure/cli/command_modules/storage/tests/latest/recordings/test_storage_account_extended_location.yaml b/src/azure-cli/azure/cli/command_modules/storage/tests/latest/recordings/test_storage_account_extended_location.yaml new file mode 100644 index 00000000000..cbbdfa13f97 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/storage/tests/latest/recordings/test_storage_account_extended_location.yaml @@ -0,0 +1,243 @@ +interactions: +- request: + body: '{"sku": {"name": "Premium_LRS"}, "kind": "StorageV2", "location": "eastus2euap", + "extendedLocation": {"name": "microsoftrrdclab1", "type": "EdgeZone"}, "properties": + {"encryption": {"services": {"blob": {}}, "keySource": "Microsoft.Storage"}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account create + Connection: + - keep-alive + Content-Length: + - '243' + Content-Type: + - application/json + ParameterSetName: + - -n -g --edge-zone -l --sku + User-Agent: + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-storage/17.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cliedgezone000001/providers/Microsoft.Storage/storageAccounts/edge1000002?api-version=2021-01-01 + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + content-type: + - text/plain; charset=utf-8 + date: + - Wed, 31 Mar 2021 09:21:32 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/eastus2euap/asyncoperations/32693f32-3ca8-42f1-909d-7502a8dc43bd?monitor=true&api-version=2021-01-01 + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-writes: + - '1199' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account create + Connection: + - keep-alive + ParameterSetName: + - -n -g --edge-zone -l --sku + User-Agent: + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-storage/17.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/eastus2euap/asyncoperations/32693f32-3ca8-42f1-909d-7502a8dc43bd?monitor=true&api-version=2021-01-01 + response: + body: + string: '{"extendedLocation":{"type":"EdgeZone","name":"microsoftrrdclab1"},"sku":{"name":"Premium_LRS","tier":"Premium"},"kind":"StorageV2","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cliedgezone000001/providers/Microsoft.Storage/storageAccounts/edge1000002","name":"edge1000002","type":"Microsoft.Storage/storageAccounts","location":"eastus2euap","tags":{},"properties":{"privateEndpointConnections":[],"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-03-31T09:21:32.0697122Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-03-31T09:21:32.0697122Z"}},"keySource":"Microsoft.Storage"},"accessTier":"Hot","provisioningState":"Succeeded","creationTime":"2021-03-31T09:21:31.9634141Z","primaryEndpoints":{"web":"https://edge1000002.web.microsoftrrdclab1.edgestorage.azure.net/","blob":"https://edge1000002.blob.microsoftrrdclab1.edgestorage.azure.net/"},"primaryLocation":"eastus2euap","statusOfPrimary":"available"}}' + headers: + cache-control: + - no-cache + content-length: + - '1197' + content-type: + - application/json + date: + - Wed, 31 Mar 2021 09:21:50 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account create + Connection: + - keep-alive + ParameterSetName: + - -n -g --edge-zone --sku + User-Agent: + - python/3.7.7 (Windows-10-10.0.19041-SP0) msrest/0.6.21 msrest_azure/0.6.3 + azure-mgmt-resource/12.0.0 Azure-SDK-For-Python AZURECLI/2.21.0 + accept-language: + - en-US + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cliedgezone000001?api-version=2020-10-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cliedgezone000001","name":"cliedgezone000001","type":"Microsoft.Resources/resourceGroups","location":"westus","tags":{"product":"azurecli","cause":"automation","date":"2021-03-31T09:21:23Z"},"properties":{"provisioningState":"Succeeded"}}' + headers: + cache-control: + - no-cache + content-length: + - '428' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 31 Mar 2021 09:21:50 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: '{"sku": {"name": "Premium_LRS"}, "kind": "StorageV2", "location": "westus", + "extendedLocation": {"name": "microsoftlosangeles1", "type": "EdgeZone"}, "properties": + {"encryption": {"services": {"blob": {}}, "keySource": "Microsoft.Storage"}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account create + Connection: + - keep-alive + Content-Length: + - '241' + Content-Type: + - application/json + ParameterSetName: + - -n -g --edge-zone --sku + User-Agent: + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-storage/17.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cliedgezone000001/providers/Microsoft.Storage/storageAccounts/edge2000003?api-version=2021-01-01 + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + content-type: + - text/plain; charset=utf-8 + date: + - Wed, 31 Mar 2021 09:21:56 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/westus/asyncoperations/c547edc5-994e-4791-994f-f4a4f1ef0c90?monitor=true&api-version=2021-01-01 + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-writes: + - '1198' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account create + Connection: + - keep-alive + ParameterSetName: + - -n -g --edge-zone --sku + User-Agent: + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-storage/17.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/westus/asyncoperations/c547edc5-994e-4791-994f-f4a4f1ef0c90?monitor=true&api-version=2021-01-01 + response: + body: + string: '{"extendedLocation":{"type":"EdgeZone","name":"microsoftlosangeles1"},"sku":{"name":"Premium_LRS","tier":"Premium"},"kind":"StorageV2","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cliedgezone000001/providers/Microsoft.Storage/storageAccounts/edge2000003","name":"edge2000003","type":"Microsoft.Storage/storageAccounts","location":"westus","tags":{},"properties":{"privateEndpointConnections":[],"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-03-31T09:21:55.9811523Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-03-31T09:21:55.9811523Z"}},"keySource":"Microsoft.Storage"},"accessTier":"Hot","provisioningState":"Succeeded","creationTime":"2021-03-31T09:21:55.9030063Z","primaryEndpoints":{"web":"https://edge2000003.web.microsoftlosangeles1.edgestorage.azure.net/","blob":"https://edge2000003.blob.microsoftlosangeles1.edgestorage.azure.net/"},"primaryLocation":"westus"}}' + headers: + cache-control: + - no-cache + content-length: + - '1166' + content-type: + - application/json + date: + - Wed, 31 Mar 2021 09:22:13 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +version: 1 diff --git a/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_account_scenarios.py b/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_account_scenarios.py index 779e6beaefc..d34e815341b 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_account_scenarios.py +++ b/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_account_scenarios.py @@ -962,6 +962,25 @@ def test_update_storage_account_with_files_adds_true(self, resource_group): self.assertEqual(activeDirectoryProperties['forestName'], self.kwargs['forest_name']) self.assertEqual(activeDirectoryProperties['netBiosDomainName'], self.kwargs['net_bios_domain_name']) + @api_version_constraint(ResourceType.MGMT_STORAGE, min_api='2020-08-01-preview') + @ResourceGroupPreparer(location='westus', name_prefix='cliedgezone') + def test_storage_account_extended_location(self, resource_group): + self.kwargs = { + 'sa1': self.create_random_name(prefix='edge1', length=12), + 'sa2': self.create_random_name(prefix='edge2', length=12), + 'rg': resource_group + } + self.cmd('storage account create -n {sa1} -g {rg} --edge-zone microsoftrrdclab1 -l eastus2euap --sku Premium_LRS', + checks=[ + JMESPathCheck('extendedLocation.name', 'microsoftrrdclab1'), + JMESPathCheck('extendedLocation.type', 'EdgeZone') + ]) + self.cmd('storage account create -n {sa2} -g {rg} --edge-zone microsoftlosangeles1 --sku Premium_LRS', + checks=[ + JMESPathCheck('extendedLocation.name', 'microsoftlosangeles1'), + JMESPathCheck('extendedLocation.type', 'EdgeZone') + ]) + class RoleScenarioTest(LiveScenarioTest): def run_under_service_principal(self):