From a32751ada0c2adee8671e387715eef98a5cdf0ea Mon Sep 17 00:00:00 2001 From: Zhiyi Huang <17182306+calvinhzy@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:31:55 +0800 Subject: [PATCH] [Storage-Preview] `az storage account local-user`: Add ACL support, and list paging/filtering (#7795) * copy local-user from main repo for preview features * add new params to `az storage account create/update` --extended-groups --is-nfsv3-enabled --group-id --allow-acl-authorization * remove `--extended-groups` `--is-nfsv3-enabled` from `az storage account create/update` as not fully supported yet * add list --filter and --maxpagesize * lint * move * retrigger ci --- src/storage-preview/HISTORY.rst | 4 + .../azext_storage_preview/_help.py | 75 ++ .../azext_storage_preview/_params.py | 42 +- .../azext_storage_preview/_validators.py | 39 +- .../azext_storage_preview/commands.py | 26 +- .../operations/account.py | 46 + .../test_storage_account_local_user.yaml | 977 ++++++++++++++++++ .../latest/test_storage_account_scenarios.py | 105 ++ 8 files changed, 1297 insertions(+), 17 deletions(-) create mode 100644 src/storage-preview/azext_storage_preview/tests/latest/recordings/test_storage_account_local_user.yaml diff --git a/src/storage-preview/HISTORY.rst b/src/storage-preview/HISTORY.rst index f069bc39812..3355a4b3137 100644 --- a/src/storage-preview/HISTORY.rst +++ b/src/storage-preview/HISTORY.rst @@ -3,6 +3,10 @@ Release History =============== +1.0.0b2(2024-07-15) +++++++++++++++++++ +* `az storage account local-user`: Support `--group-id` and `--allow-acl-authorization`. Support list paging and filtering + 1.0.0b1(2023-08-11) ++++++++++++++++++ * `az storage account migration start/show`: Support start and show storage account migration diff --git a/src/storage-preview/azext_storage_preview/_help.py b/src/storage-preview/azext_storage_preview/_help.py index 371e84d4593..24f2e195bed 100644 --- a/src/storage-preview/azext_storage_preview/_help.py +++ b/src/storage-preview/azext_storage_preview/_help.py @@ -798,3 +798,78 @@ text: | az storage share close-handle --account-name MyAccount --name MyFileShare --path 'dir1/test.txt' --handle-id "id" """ + +helps['storage account local-user'] = """ + type: group + short-summary: Manage storage account local users. +""" + +helps['storage account local-user create'] = """ + type: command + short-summary: Create a local user for a given storage account. + examples: + - name: Create a local-user with two permission scopes and an ssh-authorized-key + text: > + az storage account local-user create --account-name {account-name} -g {resource-group} -n {username} + --home-directory home --permission-scope permissions=r service=blob resource-name=container1 + --permission-scope permissions=rw service=file resource-name=share2 --ssh-authorized-key key="ssh-rsa a2V5" + --has-ssh-key true --has-ssh-password --has-shared-key false --group-id 1 --allow-acl-authorization true +""" + +helps['storage account local-user update'] = """ + type: command + short-summary: Update properties for a local user. + examples: + - name: Update a local-user with one permission scopes and no ssh-key + text: > + az storage account local-user update --account-name {account-name} -g {resource-group} -n {username} + --permission-scope permissions=rw service=file resource-name=share2 + --has-ssh-key false --group-id 2 --allow-acl-authorization false +""" + +helps['storage account local-user delete'] = """ + type: command + short-summary: Delete a local user. + examples: + - name: Delete a local-user + text: > + az storage account local-user delete --account-name {account-name} -g {resource-group} -n {username} +""" + +helps['storage account local-user list'] = """ + type: command + short-summary: List local users for a storage account. + examples: + - name: List local-user for a storage account with name starting with test and only returning 3 results + text: > + az storage account local-user list --account-name {account-name} -g {resource-group} + --filter "startswith(name, test)" --maxpagesize 3 +""" + +helps['storage account local-user show'] = """ + type: command + short-summary: Show info for a local user. + examples: + - name: Show info for a local-user + text: > + az storage account local-user show --account-name {account-name} -g {resource-group} -n {username} +""" + +helps['storage account local-user list-keys'] = """ + type: command + short-summary: List sharedkeys and sshAuthorizedKeys for a local user. + examples: + - name: List sharedkeys and sshAuthorizedKeys for a local-user + text: > + az storage account local-user list-keys --account-name {account-name} -g {resource-group} -n {username} +""" + +helps['storage account local-user regenerate-password'] = """ + type: command + short-summary: Regenerate sshPassword for a local user. + examples: + - name: Regenerate sshPassword for a local-user + text: > + az storage account local-user regenerate-password --account-name {account-name} -g {resource-group} + -n {username} +""" diff --git a/src/storage-preview/azext_storage_preview/_params.py b/src/storage-preview/azext_storage_preview/_params.py index 5f35e89e305..bb176b18943 100644 --- a/src/storage-preview/azext_storage_preview/_params.py +++ b/src/storage-preview/azext_storage_preview/_params.py @@ -15,7 +15,8 @@ validate_storage_data_plane_list, validate_immutability_arguments, process_resource_group, validate_encryption_source, get_permission_help_string, get_permission_validator, - add_progress_callback, validate_share_close_handle) + add_progress_callback, validate_share_close_handle, + PermissionScopeAddAction, SshPublicKeyAddAction) from .profiles import CUSTOM_MGMT_STORAGE, CUSTOM_DATA_STORAGE_FILESHARE @@ -909,3 +910,42 @@ def load_arguments(self, _): # pylint: disable=too-many-locals, too-many-statem c.extra('disallow_source_trailing_dot', arg_type=get_three_state_flag(), default=False, is_preview=True, options_list=["--disallow-source-trailing-dot", "--disallow-src-trailing"], help="If true, the trailing dot will be trimmed from the source URI. Default to False") + + with self.argument_context('storage account local-user') as c: + c.argument('account_name', acct_name_type, options_list='--account-name', id_part=None) + c.argument('username', options_list=['--user-name', '--name', '-n'], + help='The name of local user. The username must contain lowercase letters and numbers ' + 'only. It must be unique only within the storage account.') + + for item in ['create', 'update']: + with self.argument_context(f'storage account local-user {item}') as c: + c.argument('permission_scope', nargs='+', action=PermissionScopeAddAction, + help='The permission scope argument list which includes the permissions, service, ' + 'and resource_name.' + 'The permissions can be a combination of the below possible values: ' + 'Read(r), Write (w), Delete (d), List (l), and Create (c). ' + 'The service has possible values: blob, file. ' + 'The resource-name is the container name or the file share name. ' + 'Example: --permission-scope permissions=r service=blob resource-name=container1' + 'Can specify multiple permission scopes: ' + '--permission-scope permissions=rw service=blob resource-name=container1' + '--permission-scope permissions=rwd service=file resource-name=share2') + c.argument('home_directory', help='The home directory.') + c.argument('ssh_authorized_key', nargs='+', action=SshPublicKeyAddAction, + help='SSH authorized keys for SFTP. Includes an optional description and key. ' + 'The key is the base64 encoded SSH public key , with format: ' + ' e.g. ssh-rsa AAAABBBB.' + 'Example: --ssh_authorized_key description=description key="ssh-rsa AAAABBBB"' + 'or --ssh_authorized_key key="ssh-rsa AAAABBBB"') + c.argument('has_shared_key', arg_type=get_three_state_flag(), + help='Indicates whether shared key exists. Set it to false to remove existing shared key.') + c.argument('has_ssh_key', arg_type=get_three_state_flag(), + help='Indicates whether ssh key exists. Set it to false to remove existing SSH key.') + c.argument('has_ssh_password', arg_type=get_three_state_flag(), + help='Indicates whether ssh password exists. Set it to false to remove existing SSH password.') + c.argument('group_id', + help='An identifier for associating a group of users.') + c.argument('allow_acl_authorization', options_list=['--allow-acl-authorization', '--allow-acl-auth'], + arg_type=get_three_state_flag(), + help='Indicates whether ACL authorization is allowed for this user. ' + 'Set it to false to disallow using ACL authorization.') diff --git a/src/storage-preview/azext_storage_preview/_validators.py b/src/storage-preview/azext_storage_preview/_validators.py index 2a83245aa1f..487c3b313fd 100644 --- a/src/storage-preview/azext_storage_preview/_validators.py +++ b/src/storage-preview/azext_storage_preview/_validators.py @@ -10,6 +10,7 @@ from azure.cli.core.commands.client_factory import get_mgmt_service_client from azure.cli.core.commands.validators import validate_key_value_pairs from azure.cli.core.profiles import get_sdk +from azure.cli.core.azclierror import UnrecognizedArgumentError from knack.util import CLIError from knack.log import get_logger from ._client_factory import get_storage_data_service_client, blob_data_service_factory, cf_blob_service, \ @@ -668,14 +669,18 @@ def __call__(self, parser, namespace, values, option_string=None): try: permissions, service, resource_name = '', '', '' for s in values: - if "permissions" in s: - permissions = s.split('=')[1] - elif "service" in s: - service = s.split('=')[1] - elif "resource-name" in s: - resource_name = s.split('=')[1] - except (ValueError, TypeError): - raise CLIError('usage error: --permission-scope VARIABLE OPERATOR VALUE') + k, v = s.split('=', 1) + if k == "permissions": + permissions = v + elif k == "service": + service = v + elif k == "resource-name": + resource_name = v + else: + raise UnrecognizedArgumentError( + 'key error: key must be one of permissions, service, resource-name for --permission-scope') + except (ValueError, TypeError, IndexError): + raise CLIError('usage error: --permission-scope [Key=Value ...]') namespace.permission_scope.append(PermissionScope( permissions=permissions, service=service, @@ -691,13 +696,17 @@ def __call__(self, parser, namespace, values, option_string=None): SshPublicKey = namespace._cmd.get_models('SshPublicKey') try: description, key = '', '' - for k in values: - if "description" in k: - description = k.split('=')[1] - elif "key" in k: - key = k.split('=')[1] - except (ValueError, TypeError): - raise CLIError('usage error: --ssh-authorized-key VARIABLE OPERATOR VALUE') + for s in values: + k, v = s.split('=', 1) + if k == "description": + description = v + elif k == "key": + key = v + else: + raise UnrecognizedArgumentError( + 'key error: key must be one of description, key for --ssh-authorized-key') + except (ValueError, TypeError, IndexError): + raise CLIError('usage error: --ssh-authorized-key [Key=Value ...]') namespace.ssh_authorized_key.append(SshPublicKey(description=description, key=key)) diff --git a/src/storage-preview/azext_storage_preview/commands.py b/src/storage-preview/azext_storage_preview/commands.py index 125246e5656..e014fd19545 100644 --- a/src/storage-preview/azext_storage_preview/commands.py +++ b/src/storage-preview/azext_storage_preview/commands.py @@ -6,7 +6,7 @@ from azure.cli.core.commands import CliCommandType from azure.cli.core.commands.arm import show_exception_handler from ._client_factory import (cf_sa, blob_data_service_factory, adls_blob_data_service_factory, - cf_share_client, cf_share_file_client, cf_share_directory_client) + cf_share_client, cf_share_file_client, cf_share_directory_client, cf_local_users) from .profiles import (CUSTOM_DATA_STORAGE, CUSTOM_DATA_STORAGE_ADLS, CUSTOM_MGMT_STORAGE, CUSTOM_DATA_STORAGE_FILESHARE) @@ -213,3 +213,27 @@ def _adls_deprecate_message(self): exception_handler=file_related_exception_handler, transform=transform_file_show_result) g.storage_custom_command('download-batch', 'storage_file_download_batch', client_factory=cf_share_client) + + local_users_sdk = CliCommandType( + operations_tmpl='azext_storage_preview.vendored_sdks.azure_mgmt_storage.operations#' + 'LocalUsersOperations.{}', + client_factory=cf_local_users, + resource_type=CUSTOM_MGMT_STORAGE + ) + + local_users_custom_type = CliCommandType( + operations_tmpl='azext_storage_preview.operations.account#{}', + client_factory=cf_local_users, + resource_type=CUSTOM_MGMT_STORAGE + ) + + with self.command_group('storage account local-user', local_users_sdk, + custom_command_type=local_users_custom_type, + resource_type=CUSTOM_MGMT_STORAGE, min_api='2021-08-01', is_preview=True) as g: + g.custom_command('create', 'create_local_user') + g.custom_command('update', 'update_local_user') + g.command('delete', 'delete') + g.command('list', 'list') + g.show_command('show', 'get') + g.command('list-keys', 'list_keys') + g.command('regenerate-password', 'regenerate_password') diff --git a/src/storage-preview/azext_storage_preview/operations/account.py b/src/storage-preview/azext_storage_preview/operations/account.py index c15e166b326..ec6caba0bd0 100644 --- a/src/storage-preview/azext_storage_preview/operations/account.py +++ b/src/storage-preview/azext_storage_preview/operations/account.py @@ -554,3 +554,49 @@ def update_storage_account(cmd, instance, sku=None, tags=None, custom_domain=Non params.is_local_user_enabled = enable_local_user return params + + +def _generate_local_user(local_user, permission_scope=None, ssh_authorized_key=None, + home_directory=None, has_shared_key=None, has_ssh_key=None, has_ssh_password=None, + group_id=None, allow_acl_authorization=None): + if permission_scope is not None: + local_user.permission_scopes = permission_scope + if ssh_authorized_key is not None: + local_user.ssh_authorized_keys = ssh_authorized_key + if home_directory is not None: + local_user.home_directory = home_directory + if has_shared_key is not None: + local_user.has_shared_key = has_shared_key + if has_ssh_key is not None: + local_user.has_ssh_key = has_ssh_key + if has_ssh_password is not None: + local_user.has_ssh_password = has_ssh_password + if group_id is not None: + local_user.group_id = group_id + if allow_acl_authorization is not None: + local_user.allow_acl_authorization = allow_acl_authorization + + +def create_local_user(cmd, client, resource_group_name, account_name, username, permission_scope=None, home_directory=None, + has_shared_key=None, has_ssh_key=None, has_ssh_password=None, ssh_authorized_key=None, + group_id=None, allow_acl_authorization=None): + LocalUser = cmd.get_models('LocalUser') + local_user = LocalUser() + + _generate_local_user(local_user, permission_scope, ssh_authorized_key, + home_directory, has_shared_key, has_ssh_key, has_ssh_password, group_id, + allow_acl_authorization) + return client.create_or_update(resource_group_name=resource_group_name, account_name=account_name, + username=username, properties=local_user) + + +def update_local_user(cmd, client, resource_group_name, account_name, username, permission_scope=None, + home_directory=None, has_shared_key=None, has_ssh_key=None, has_ssh_password=None, + ssh_authorized_key=None, group_id=None, allow_acl_authorization=None): + local_user = client.get(resource_group_name, account_name, username) + + _generate_local_user(local_user, permission_scope, ssh_authorized_key, + home_directory, has_shared_key, has_ssh_key, has_ssh_password, group_id, + allow_acl_authorization) + return client.create_or_update(resource_group_name=resource_group_name, account_name=account_name, + username=username, properties=local_user) diff --git a/src/storage-preview/azext_storage_preview/tests/latest/recordings/test_storage_account_local_user.yaml b/src/storage-preview/azext_storage_preview/tests/latest/recordings/test_storage_account_local_user.yaml new file mode 100644 index 00000000000..b275c7cd5ee --- /dev/null +++ b/src/storage-preview/azext_storage_preview/tests/latest/recordings/test_storage_account_local_user.yaml @@ -0,0 +1,977 @@ +interactions: +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "r", "service": "blob", + "resourceName": "container1"}, {"permissions": "rw", "service": "file", "resourceName": + "share2"}], "homeDirectory": "home", "hasSharedKey": false, "hasSshKey": false, + "groupId": 1, "allowAclAuthorization": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user create + Connection: + - keep-alive + Content-Length: + - '290' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --permission-scope + --has-ssh-key --has-shared-key --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":1,"allowAclAuthorization":true,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '606' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:44 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/a87f6641-199e-45c5-bcb1-4517a8a822f0 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user update + Connection: + - keep-alive + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":1,"allowAclAuthorization":true,"hasSshPassword":false,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '629' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:46 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/bc350454-9aaa-4be0-b81c-d27033b7ea3b + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "rw", "service": "file", + "resourceName": "share2"}], "homeDirectory": "home2", "hasSharedKey": false, + "hasSshKey": false, "hasSshPassword": false, "groupId": 2, "allowAclAuthorization": + false}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user update + Connection: + - keep-alive + Content-Length: + - '246' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":2,"allowAclAuthorization":false,"hasSshPassword":false,"permissionScopes":[{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home2","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '566' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:46 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/34d0b92b-127e-4450-b190-ff804c7158bd + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user list + Connection: + - keep-alive + ParameterSetName: + - --account-name -g + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers?api-version=2023-05-01 + response: + body: + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":2,"allowAclAuthorization":false,"hasSshPassword":false,"permissionScopes":[{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home2","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}]}' + headers: + cache-control: + - no-cache + content-length: + - '578' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:48 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/9eba88ee-102a-4791-b45f-f1252fe2d125 + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "r", "service": "blob", + "resourceName": "container1"}, {"permissions": "rw", "service": "file", "resourceName": + "share2"}], "homeDirectory": "home", "hasSharedKey": false, "hasSshKey": false, + "groupId": 2, "allowAclAuthorization": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user create + Connection: + - keep-alive + Content-Length: + - '290' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --permission-scope + --has-ssh-key --has-shared-key --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/notcli000004?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/notcli000004","name":"notcli000004","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1001,"groupId":2,"allowAclAuthorization":true,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-2655997081-2556675870-3568867302-1001","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '613' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:49 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/5db753d1-300d-492f-8ed3-c04e74611853 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user list + Connection: + - keep-alive + ParameterSetName: + - --account-name -g + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers?api-version=2023-05-01 + response: + body: + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":2,"allowAclAuthorization":false,"hasSshPassword":false,"permissionScopes":[{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home2","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/notcli000004","name":"notcli000004","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1001,"groupId":2,"allowAclAuthorization":true,"hasSshPassword":false,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-2655997081-2556675870-3568867302-1001","hasSharedKey":false,"hasSshKey":false}}]}' + headers: + cache-control: + - no-cache + content-length: + - '1215' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:51 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/7a75c2ed-1290-4c1f-b060-f7dac359ae49 + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user list + Connection: + - keep-alive + ParameterSetName: + - --account-name -g --filter + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers?api-version=2023-05-01&$filter=startswith%28name%2C%20cli%29 + response: + body: + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":2,"allowAclAuthorization":false,"hasSshPassword":false,"permissionScopes":[{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home2","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}]}' + headers: + cache-control: + - no-cache + content-length: + - '578' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:52 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/e33e23a1-e0ff-4e95-9b8b-4d8a56d13b47 + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user show + Connection: + - keep-alive + ParameterSetName: + - --account-name -g -n + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":2,"allowAclAuthorization":false,"hasSshPassword":false,"permissionScopes":[{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home2","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '566' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:54 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/0a6db3a8-8aa9-4657-b3b8-1409361f700d + x-ms-ratelimit-remaining-subscription-global-reads: + - '3748' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user update + Connection: + - keep-alive + ParameterSetName: + - --account-name -g -n --ssh-authorized-key + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":2,"allowAclAuthorization":false,"hasSshPassword":false,"permissionScopes":[{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home2","sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '566' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:56 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/4dba298c-b430-48ba-8b4e-e040e1ac5e4d + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "rw", "service": "file", + "resourceName": "share2"}], "homeDirectory": "home2", "sshAuthorizedKeys": [{"description": + "", "key": "ssh-rsa a2V5"}], "hasSharedKey": false, "hasSshKey": false, "hasSshPassword": + false, "groupId": 2, "allowAclAuthorization": false}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user update + Connection: + - keep-alive + Content-Length: + - '313' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --ssh-authorized-key + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000003","name":"cli000003","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1000,"groupId":2,"allowAclAuthorization":false,"hasSshPassword":false,"permissionScopes":[{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home2","sshAuthorizedKeys":[{"description":"","key":"ssh-rsa + a2V5"}],"sid":"S-1-2-0-259443223-4290653894-1569446496-1000","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '628' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:56 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/bb19b722-629f-4f44-b32c-58bf51fc2509 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user list-keys + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - --account-name -g -n + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003/listKeys?api-version=2023-05-01 + response: + body: + string: '{}' + headers: + cache-control: + - no-cache + content-length: + - '2' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:50:58 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/47b1e8fc-273b-491a-b8d5-209f798d1336 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user regenerate-password + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - --account-name -g -n + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003/regeneratePassword?api-version=2023-05-01 + response: + body: + string: '{"sshPassword":"WI4JD9UlOZ9GfvL/nBgI9lzKlv0n9SGV"}' + headers: + cache-control: + - no-cache + content-length: + - '50' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:51:00 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/89aae28d-0c7c-4a87-81b1-ed010ddacd84 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - --account-name -g -n + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000003?api-version=2023-05-01 + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + content-type: + - text/plain; charset=utf-8 + date: + - Mon, 15 Jul 2024 07:51:01 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/1997e4a6-7c05-417f-a2a0-6f9ef7ed34b7 + x-ms-ratelimit-remaining-subscription-deletes: + - '199' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '2999' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "r", "service": "blob", + "resourceName": "container1"}, {"permissions": "rw", "service": "file", "resourceName": + "share2"}], "homeDirectory": "home", "hasSharedKey": false, "hasSshKey": false, + "groupId": 1, "allowAclAuthorization": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user create + Connection: + - keep-alive + Content-Length: + - '290' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --permission-scope + --has-ssh-key --has-shared-key --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000005?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000005","name":"cli000005","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1002,"groupId":1,"allowAclAuthorization":true,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-3936518271-2781779176-4176656412-1002","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '607' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:51:03 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/887fc38c-c734-4101-b706-032f6e3d1be1 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2998' + x-ms-ratelimit-remaining-subscription-writes: + - '198' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "r", "service": "blob", + "resourceName": "container1"}, {"permissions": "rw", "service": "file", "resourceName": + "share2"}], "homeDirectory": "home", "hasSharedKey": false, "hasSshKey": false, + "groupId": 1, "allowAclAuthorization": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user create + Connection: + - keep-alive + Content-Length: + - '290' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --permission-scope + --has-ssh-key --has-shared-key --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000006?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000006","name":"cli000006","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1003,"groupId":1,"allowAclAuthorization":true,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-1114963197-2923825689-1277316669-1003","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '607' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:51:05 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/3e1e5d28-38bc-4969-b4e7-bfc81db62629 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2998' + x-ms-ratelimit-remaining-subscription-writes: + - '198' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "r", "service": "blob", + "resourceName": "container1"}, {"permissions": "rw", "service": "file", "resourceName": + "share2"}], "homeDirectory": "home", "hasSharedKey": false, "hasSshKey": false, + "groupId": 1, "allowAclAuthorization": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user create + Connection: + - keep-alive + Content-Length: + - '290' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --permission-scope + --has-ssh-key --has-shared-key --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000007?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000007","name":"cli000007","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1004,"groupId":1,"allowAclAuthorization":true,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-2058749126-1151262988-2811272029-1004","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '607' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:51:06 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/8319d791-84c8-40a4-9b0a-f0e2ed6ec508 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "r", "service": "blob", + "resourceName": "container1"}, {"permissions": "rw", "service": "file", "resourceName": + "share2"}], "homeDirectory": "home", "hasSharedKey": false, "hasSshKey": false, + "groupId": 1, "allowAclAuthorization": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user create + Connection: + - keep-alive + Content-Length: + - '290' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --permission-scope + --has-ssh-key --has-shared-key --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000008?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000008","name":"cli000008","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1005,"groupId":1,"allowAclAuthorization":true,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-3020759848-4075199506-2613358959-1005","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '607' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:51:09 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/6bddea7c-0719-4b4b-823b-717e8a4404b9 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"permissionScopes": [{"permissions": "r", "service": "blob", + "resourceName": "container1"}, {"permissions": "rw", "service": "file", "resourceName": + "share2"}], "homeDirectory": "home", "hasSharedKey": false, "hasSshKey": false, + "groupId": 1, "allowAclAuthorization": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user create + Connection: + - keep-alive + Content-Length: + - '290' + Content-Type: + - application/json + ParameterSetName: + - --account-name -g -n --home-directory --permission-scope --permission-scope + --has-ssh-key --has-shared-key --group-id --allow-acl-authorization + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers/cli000009?api-version=2023-05-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000009","name":"cli000009","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1006,"groupId":1,"allowAclAuthorization":true,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-302394010-1513588342-684664950-1006","hasSharedKey":false,"hasSshKey":false}}' + headers: + cache-control: + - no-cache + content-length: + - '605' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:51:10 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/c4a83a4b-c140-4973-a9a7-af2f7cdc1613 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - storage account local-user list + Connection: + - keep-alive + ParameterSetName: + - --account-name -g --maxpagesize + User-Agent: + - AZURECLI/2.62.0 (PIP) azsdk-python-core/1.28.0 Python/3.9.13 (Windows-10-10.0.19045-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localUsers?api-version=2023-05-01&$maxpagesize=3 + response: + body: + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000007","name":"cli000007","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1004,"groupId":1,"allowAclAuthorization":true,"hasSshPassword":false,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-2058749126-1151262988-2811272029-1004","hasSharedKey":false,"hasSshKey":false}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000006","name":"cli000006","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1003,"groupId":1,"allowAclAuthorization":true,"hasSshPassword":false,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-1114963197-2923825689-1277316669-1003","hasSharedKey":false,"hasSshKey":false}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers/cli000008","name":"cli000008","type":"Microsoft.Storage/storageAccounts/localUsers","properties":{"userId":1005,"groupId":1,"allowAclAuthorization":true,"hasSshPassword":false,"permissionScopes":[{"permissions":"r","service":"blob","resourceName":"container1"},{"permissions":"rw","service":"file","resourceName":"share2"}],"homeDirectory":"home","sid":"S-1-2-0-3020759848-4075199506-2613358959-1005","hasSharedKey":false,"hasSshKey":false}}],"nextLink":"https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_storage_account_local_user000001/providers/Microsoft.Storage/storageAccounts/storagelocaluser000002/localusers?api-version=2023-05-01&$maxpagesize=3&$skipToken=2!104!MDAwMDM0IWxvY2FsdXNlci9jbGlsaGl0bmtzaWxicGRrYmRucTZxc2ghMDAwMDI4ITk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OVoh"}' + headers: + cache-control: + - no-cache + content-length: + - '2287' + content-type: + - application/json + date: + - Mon, 15 Jul 2024 07:51:12 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 + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e/eastus2euap/ff71e9de-9843-4864-b64d-8a3c0d841624 + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + status: + code: 200 + message: OK +version: 1 diff --git a/src/storage-preview/azext_storage_preview/tests/latest/test_storage_account_scenarios.py b/src/storage-preview/azext_storage_preview/tests/latest/test_storage_account_scenarios.py index ce95c82055b..16b9832231e 100644 --- a/src/storage-preview/azext_storage_preview/tests/latest/test_storage_account_scenarios.py +++ b/src/storage-preview/azext_storage_preview/tests/latest/test_storage_account_scenarios.py @@ -278,3 +278,108 @@ def test_storage_account_migration(self, resource_group): # other status would take days to months self.cmd('az storage account migration show -n default -g {rg} --account-name {sa}', checks=[JMESPathCheck('migrationStatus', 'SubmittedForConversion')]) + + +class StorageAccountLocalUserTests(StorageScenarioMixin, ScenarioTest): + @AllowLargeResponse() + @ResourceGroupPreparer(name_prefix='cli_storage_account_local_user') + @StorageAccountPreparer(name_prefix='storagelocaluser', kind='StorageV2', location='eastus2euap') + def test_storage_account_local_user(self, resource_group, storage_account): + username = self.create_random_name(prefix='cli', length=24) + self.kwargs.update({ + 'sa': storage_account, + 'rg': resource_group, + 'cmd': 'storage account local-user', + 'username': username, + 'username2': self.create_random_name(prefix='notcli', length=24) + }) + + self.cmd('{cmd} create --account-name {sa} -g {rg} -n {username} --home-directory home ' + '--permission-scope permissions=r service=blob resource-name=container1 ' + '--permission-scope permissions=rw service=file resource-name=share2 ' + '--has-ssh-key false --has-shared-key false --group-id 1 ' + '--allow-acl-authorization true').assert_with_checks( + JMESPathCheck('hasSharedKey', False), + JMESPathCheck('hasSshKey', False), + JMESPathCheck('hasSshPassword', None), + JMESPathCheck('homeDirectory', 'home'), + JMESPathCheck('name', username), + JMESPathCheck('length(permissionScopes)', 2), + JMESPathCheck('permissionScopes[0].permissions', 'r'), + JMESPathCheck('permissionScopes[0].service', 'blob'), + JMESPathCheck('permissionScopes[0].resourceName', 'container1'), + JMESPathCheck('groupId', 1), + JMESPathCheck('allowAclAuthorization', True) + ) + + self.cmd('{cmd} update --account-name {sa} -g {rg} -n {username} --home-directory home2 ' + '--permission-scope permissions=rw service=file resource-name=share2 --group-id 2 ' + '--allow-acl-authorization false').assert_with_checks( + JMESPathCheck('homeDirectory', 'home2'), + JMESPathCheck('length(permissionScopes)', 1), + JMESPathCheck('permissionScopes[0].permissions', 'rw'), + JMESPathCheck('permissionScopes[0].service', 'file'), + JMESPathCheck('permissionScopes[0].resourceName', 'share2'), + JMESPathCheck('groupId', 2), + JMESPathCheck('allowAclAuthorization', False) + ) + + self.cmd('{cmd} list --account-name {sa} -g {rg}').assert_with_checks( + JMESPathCheck('[0].hasSshKey', False), + JMESPathCheck('[0].hasSshPassword', False), + JMESPathCheck('[0].homeDirectory', 'home2'), + JMESPathCheck('[0].length(permissionScopes)', 1), + JMESPathCheck('[0].sshAuthorizedKeys', None) + ) + + self.cmd('{cmd} create --account-name {sa} -g {rg} -n {username2} --home-directory home ' + '--permission-scope permissions=r service=blob resource-name=container1 ' + '--permission-scope permissions=rw service=file resource-name=share2 ' + '--has-ssh-key false --has-shared-key false --group-id 2 ' + '--allow-acl-authorization true') + + self.cmd('{cmd} list --account-name {sa} -g {rg}').assert_with_checks( + JMESPathCheck('length(@)', 2) + ) + self.cmd('{cmd} list --account-name {sa} -g {rg} --filter "startswith(name, cli)"').assert_with_checks( + JMESPathCheck('length(@)', 1) + ) + + self.cmd('{cmd} show --account-name {sa} -g {rg} -n {username}').assert_with_checks( + JMESPathCheck('hasSshKey', False), + JMESPathCheck('hasSshPassword', False), + JMESPathCheck('homeDirectory', 'home2'), + JMESPathCheck('length(permissionScopes)', 1), + JMESPathCheck('permissionScopes[0].permissions', 'rw'), + JMESPathCheck('permissionScopes[0].service', 'file'), + JMESPathCheck('permissionScopes[0].resourceName', 'share2'), + JMESPathCheck('sshAuthorizedKeys', None) + ) + + self.cmd('{cmd} update --account-name {sa} -g {rg} -n {username} ' + '--ssh-authorized-key key="ssh-rsa a2V5" ') + + self.cmd('{cmd} list-keys --account-name {sa} -g {rg} -n {username}').assert_with_checks( + JMESPathCheck('sshAuthorizedKeys', None) + ) + + self.cmd('{cmd} regenerate-password --account-name {sa} -g {rg} -n {username}').assert_with_checks( + JMESPathCheck('sshAuthorizedKeys', None), + JMESPathCheckExists('sshPassword') + ) + + self.cmd('{cmd} delete --account-name {sa} -g {rg} -n {username}') + + for i in range(5): + username = self.create_random_name(prefix='cli', length=24) + self.kwargs.update({ + 'username': username + }) + self.cmd('{cmd} create --account-name {sa} -g {rg} -n {username} --home-directory home ' + '--permission-scope permissions=r service=blob resource-name=container1 ' + '--permission-scope permissions=rw service=file resource-name=share2 ' + '--has-ssh-key false --has-shared-key false --group-id 1 ' + '--allow-acl-authorization true') + self.cmd('{cmd} list --account-name {sa} -g {rg} --maxpagesize 3').assert_with_checks( + JMESPathCheck('length(@)', 3) + )