diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py index bb38436876da..e06da4437d01 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py @@ -383,12 +383,6 @@ def list_containers( :param bool include_metadata: Specifies that container metadata to be returned in the response. The default value is `False`. - :keyword bool include_deleted: - Specifies that deleted containers to be returned in the response. This is for container restore enabled - account. The default value is `False`. - - .. versionadded:: 12.4.0 - :keyword int results_per_page: The maximum number of container names to retrieve per API call. If the request does not specify the server will return up to 5,000 items. @@ -407,9 +401,6 @@ def list_containers( :caption: Listing the containers in the blob service. """ include = ['metadata'] if include_metadata else [] - include_deleted = kwargs.pop('include_deleted', None) - if include_deleted: - include.append("deleted") timeout = kwargs.pop('timeout', None) results_per_page = kwargs.pop('results_per_page', None) @@ -436,8 +427,8 @@ def find_blobs_by_tags(self, filter_expression, **kwargs): :param str filter_expression: The expression to find blobs whose tags matches the specified condition. - eg. "yourtagname='firsttag' and yourtagname2='secondtag'" - To specify a container, eg. "@container=’containerName’ and Name = ‘C’" + eg. "\"yourtagname\"='firsttag' and \"yourtagname2\"='secondtag'" + To specify a container, eg. "@container=’containerName’ and \"Name\"=‘C’" :keyword int results_per_page: The max result per page when paginating. :keyword int timeout: @@ -566,7 +557,7 @@ def delete_container( **kwargs) @distributed_trace - def undelete_container(self, deleted_container_name, deleted_container_version, new_name=None, **kwargs): + def _undelete_container(self, deleted_container_name, deleted_container_version, new_name=None, **kwargs): # type: (str, str, str, **Any) -> ContainerClient """Restores soft-deleted container. diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py index a50c91ac0c97..ad7dd4c4292b 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py @@ -1054,18 +1054,26 @@ class ContainerSasPermissions(object): :param bool delete: Delete any blob in the container. Note: You cannot grant permissions to delete a container with a container SAS. Use an account SAS instead. + :param bool delete_previous_version: + Delete the previous blob version for the versioning enabled storage account. :param bool list: List blobs in the container. + :param bool tag: + Set or get tags on the blobs in the container. """ - def __init__(self, read=False, write=False, delete=False, list=False): # pylint: disable=redefined-builtin + def __init__(self, read=False, write=False, delete=False, list=False, delete_previous_version=False, tag=False): # pylint: disable=redefined-builtin self.read = read self.write = write self.delete = delete self.list = list + self.delete_previous_version = delete_previous_version + self.tag = tag self._str = (('r' if self.read else '') + ('w' if self.write else '') + ('d' if self.delete else '') + - ('l' if self.list else '')) + ('x' if self.delete_previous_version else '') + + ('l' if self.list else '') + + ('t' if self.tag else '')) def __str__(self): return self._str @@ -1087,7 +1095,10 @@ def from_string(cls, permission): p_write = 'w' in permission p_delete = 'd' in permission p_list = 'l' in permission - parsed = cls(p_read, p_write, p_delete, p_list) + p_delete_previous_version = 'x' in permission + p_tag = 't' in permission + parsed = cls(read=p_read, write=p_write, delete=p_delete, list=p_list, + delete_previous_version=p_delete_previous_version, tag=p_tag) parsed._str = permission # pylint: disable = protected-access return parsed @@ -1111,21 +1122,25 @@ class BlobSasPermissions(object): Delete the blob. :param bool delete_previous_version: Delete the previous blob version for the versioning enabled storage account. + :param bool tag: + Set or get tags on the blob. """ def __init__(self, read=False, add=False, create=False, write=False, - delete=False, delete_previous_version=False): + delete=False, delete_previous_version=False, tag=True): self.read = read self.add = add self.create = create self.write = write self.delete = delete self.delete_previous_version = delete_previous_version + self.tag = tag self._str = (('r' if self.read else '') + ('a' if self.add else '') + ('c' if self.create else '') + ('w' if self.write else '') + ('d' if self.delete else '') + - ('x' if self.delete_previous_version else '')) + ('x' if self.delete_previous_version else '') + + ('t' if self.tag else '')) def __str__(self): return self._str @@ -1149,8 +1164,10 @@ def from_string(cls, permission): p_write = 'w' in permission p_delete = 'd' in permission p_delete_previous_version = 'x' in permission + p_tag = 't' in permission - parsed = cls(p_read, p_add, p_create, p_write, p_delete, p_delete_previous_version) + parsed = cls(read=p_read, add=p_add, create=p_create, write=p_write, delete=p_delete, + delete_previous_version=p_delete_previous_version, tag=p_tag) parsed._str = permission # pylint: disable = protected-access return parsed diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/models.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/models.py index 731d17058266..41da5226db8d 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/models.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/models.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- - +# pylint: disable=too-many-instance-attributes from enum import Enum @@ -324,10 +324,15 @@ class AccountSasPermissions(object): Valid for the following Object resource types only: queue messages. :param bool process: Valid for the following Object resource type only: queue messages. + :param bool tag: + To enable set or get tags on the blobs in the container. + :param bool filter_by_tags: + To enable get blobs by tags, this should be used together with list permission. """ def __init__(self, read=False, write=False, delete=False, list=False, # pylint: disable=redefined-builtin - add=False, create=False, update=False, process=False, delete_previous_version=False): + add=False, create=False, update=False, process=False, delete_previous_version=False, tag=False, + filter_by_tags=False): self.read = read self.write = write self.delete = delete @@ -337,6 +342,8 @@ def __init__(self, read=False, write=False, delete=False, self.create = create self.update = update self.process = process + self.tag = tag + self.filter_by_tags = filter_by_tags self._str = (('r' if self.read else '') + ('w' if self.write else '') + ('d' if self.delete else '') + @@ -345,7 +352,10 @@ def __init__(self, read=False, write=False, delete=False, ('a' if self.add else '') + ('c' if self.create else '') + ('u' if self.update else '') + - ('p' if self.process else '')) + ('p' if self.process else '') + + ('f' if self.filter_by_tags else '') + + ('t' if self.tag else '') + ) def __str__(self): return self._str @@ -360,7 +370,7 @@ def from_string(cls, permission): :param str permission: Specify permissions in the string with the first letter of the word. - :return: A AccountSasPermissions object + :return: An AccountSasPermissions object :rtype: ~azure.storage.blob.AccountSasPermissions """ p_read = 'r' in permission @@ -372,8 +382,11 @@ def from_string(cls, permission): p_create = 'c' in permission p_update = 'u' in permission p_process = 'p' in permission - - parsed = cls(p_read, p_write, p_delete, p_delete_previous_version, p_list, p_add, p_create, p_update, p_process) + p_tag = 't' in permission + p_filter_by_tags = 'f' in permission + parsed = cls(read=p_read, write=p_write, delete=p_delete, delete_previous_version=p_delete_previous_version, + list=p_list, add=p_add, create=p_create, update=p_update, process=p_process, tag=p_tag, + filter_by_tags=p_filter_by_tags) parsed._str = permission # pylint: disable = protected-access return parsed diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py index 48ef864f11db..b91d91433271 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py @@ -337,12 +337,6 @@ def list_containers( :param bool include_metadata: Specifies that container metadata to be returned in the response. The default value is `False`. - :keyword bool include_deleted: - Specifies that deleted containers to be returned in the response. This is for container restore enabled - account. The default value is `False`. - - .. versionadded:: 12.4.0 - :keyword int results_per_page: The maximum number of container names to retrieve per API call. If the request does not specify the server will return up to 5,000 items. @@ -361,9 +355,6 @@ def list_containers( :caption: Listing the containers in the blob service. """ include = ['metadata'] if include_metadata else [] - include_deleted = kwargs.pop('include_deleted', None) - if include_deleted: - include.append("deleted") timeout = kwargs.pop('timeout', None) results_per_page = kwargs.pop('results_per_page', None) command = functools.partial( @@ -389,8 +380,8 @@ def find_blobs_by_tags(self, filter_expression, **kwargs): :param str filter_expression: The expression to find blobs whose tags matches the specified condition. - eg. "yourtagname='firsttag' and yourtagname2='secondtag'" - To specify a container, eg. "@container=’containerName’ and Name = ‘C’" + eg. "\"yourtagname\"='firsttag' and \"yourtagname2\"='secondtag'" + To specify a container, eg. "@container=’containerName’ and \"Name\"=‘C’" :keyword int results_per_page: The max result per page when paginating. :keyword int timeout: @@ -519,7 +510,7 @@ async def delete_container( **kwargs) @distributed_trace_async - async def undelete_container(self, deleted_container_name, deleted_container_version, new_name=None, **kwargs): + async def _undelete_container(self, deleted_container_name, deleted_container_version, new_name=None, **kwargs): # type: (str, str, str, **Any) -> ContainerClient """Restores soft-deleted container. diff --git a/sdk/storage/azure-storage-blob/tests/test_blob_tags.py b/sdk/storage/azure-storage-blob/tests/test_blob_tags.py index 30ac2751d1da..828ffb3bd6b9 100644 --- a/sdk/storage/azure-storage-blob/tests/test_blob_tags.py +++ b/sdk/storage/azure-storage-blob/tests/test_blob_tags.py @@ -5,8 +5,11 @@ # license information. # -------------------------------------------------------------------------- import os -import uuid +from datetime import datetime, timedelta from enum import Enum + +import pytest + try: from urllib.parse import quote except ImportError: @@ -17,7 +20,8 @@ ResourceExistsError) from azure.storage.blob import ( BlobServiceClient, - BlobBlock) + BlobBlock, generate_account_sas, ResourceTypes, AccountSasPermissions, generate_container_sas, + ContainerSasPermissions, BlobClient, generate_blob_sas, BlobSasPermissions) #------------------------------------------------------------------------------ @@ -279,4 +283,69 @@ def test_filter_blobs(self, resource_group, location, storage_account, storage_a self.assertEqual(2, len(items_on_page1)) self.assertEqual(2, len(items_on_page2)) + + @pytest.mark.live_test_only + @GlobalStorageAccountPreparer() + def test_filter_blobs_using_account_sas(self, resource_group, location, storage_account, storage_account_key): + token = generate_account_sas( + storage_account.name, + storage_account_key, + ResourceTypes(service=True, container=True, object=True), + AccountSasPermissions(write=True, list=True, read=True, delete_previous_version=True, tag=True, + filter_by_tags=True), + datetime.utcnow() + timedelta(hours=1), + ) + self._setup(storage_account, token) + + tags = {"year": '1000', "tag2": "secondtag", "tag3": "thirdtag", "habitat_type": 'Shallow Lowland Billabongs'} + blob_client, _ = self._create_block_blob(tags=tags, container_name=self.container_name) + blob_client.set_blob_tags(tags=tags) + tags_on_blob = blob_client.get_blob_tags() + self.assertEqual(len(tags_on_blob), len(tags)) + + # To filter in a specific container use: + # where = "@container='{}' and tag1='1000' and tag2 = 'secondtag'".format(container_name1) + where = "\"year\"='1000' and tag2 = 'secondtag' and tag3='thirdtag'" + + blob_list = self.bsc.find_blobs_by_tags(filter_expression=where, results_per_page=2).by_page() + first_page = next(blob_list) + items_on_page1 = list(first_page) + self.assertEqual(1, len(items_on_page1)) + + @pytest.mark.live_test_only + @GlobalStorageAccountPreparer() + def test_set_blob_tags_using_blob_sas(self, resource_group, location, storage_account, storage_account_key): + token = generate_account_sas( + storage_account.name, + storage_account_key, + ResourceTypes(service=True, container=True, object=True), + AccountSasPermissions(write=True, list=True, read=True, delete_previous_version=True, tag=True, + filter_by_tags=True), + datetime.utcnow() + timedelta(hours=1), + ) + self._setup(storage_account, token) + + tags = {"year": '1000', "tag2": "secondtag", "tag3": "thirdtag", "habitat_type": 'Shallow Lowland Billabongs'} + blob_client, _ = self._create_block_blob(tags=tags, container_name=self.container_name) + token1 = generate_blob_sas( + storage_account.name, + self.container_name, + blob_client.blob_name, + account_key=storage_account_key, + permission=BlobSasPermissions(delete_previous_version=True, tag=True), + expiry=datetime.utcnow() + timedelta(hours=1), + ) + blob_client=BlobClient.from_blob_url(blob_client.url, token1) + blob_client.set_blob_tags(tags=tags) + tags_on_blob = blob_client.get_blob_tags() + self.assertEqual(len(tags_on_blob), len(tags)) + + # To filter in a specific container use: + # where = "@container='{}' and tag1='1000' and tag2 = 'secondtag'".format(container_name1) + where = "\"year\"='1000' and tag2 = 'secondtag' and tag3='thirdtag'" + + blob_list = self.bsc.find_blobs_by_tags(filter_expression=where, results_per_page=2).by_page() + first_page = next(blob_list) + items_on_page1 = list(first_page) + self.assertEqual(1, len(items_on_page1)) #------------------------------------------------------------------------------ diff --git a/sdk/storage/azure-storage-blob/tests/test_container.py b/sdk/storage/azure-storage-blob/tests/test_container.py index 4be7a1781958..bbb2664b3239 100644 --- a/sdk/storage/azure-storage-blob/tests/test_container.py +++ b/sdk/storage/azure-storage-blob/tests/test_container.py @@ -723,6 +723,7 @@ def test_delete_container_with_lease_id(self, resource_group, location, storage_ @GlobalStorageAccountPreparer() def test_undelete_container(self, resource_group, location, storage_account, storage_account_key): # container soft delete should enabled by SRP call or use armclient, so make this test as playback only. + pytest.skip('This will be added back along with STG74 features') bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key) container_client = self._create_container(bsc) @@ -740,8 +741,8 @@ def test_undelete_container(self, resource_group, location, storage_account, sto for container in container_list: # find the deleted container and restore it if container.deleted and container.name == container_client.container_name: - restored_ctn_client = bsc.undelete_container(container.name, container.version, - new_name="restored" + str(restored_version)) + restored_ctn_client = bsc._undelete_container(container.name, container.version, + new_name="restored" + str(restored_version)) restored_version += 1 # to make sure the deleted container is restored @@ -752,6 +753,7 @@ def test_undelete_container(self, resource_group, location, storage_account, sto @GlobalStorageAccountPreparer() def test_restore_to_existing_container(self, resource_group, location, storage_account, storage_account_key): # container soft delete should enabled by SRP call or use armclient, so make this test as playback only. + pytest.skip('This will be added back along with STG74 features') bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key) # get an existing container @@ -771,14 +773,15 @@ def test_restore_to_existing_container(self, resource_group, location, storage_a # find the deleted container and restore it if container.deleted and container.name == container_client.container_name: with self.assertRaises(HttpResponseError): - bsc.undelete_container(container.name, container.version, - new_name=existing_container_client.container_name) + bsc._undelete_container(container.name, container.version, + new_name=existing_container_client.container_name) @pytest.mark.live_test_only # sas token is dynamically generated @pytest.mark.playback_test_only # we need container soft delete enabled account @GlobalStorageAccountPreparer() def test_restore_with_sas(self, resource_group, location, storage_account, storage_account_key): # container soft delete should enabled by SRP call or use armclient, so make this test as playback only. + pytest.skip('This will be added back along with STG74 features') token = generate_account_sas( storage_account.name, storage_account_key, @@ -800,8 +803,8 @@ def test_restore_with_sas(self, resource_group, location, storage_account, stora for container in container_list: # find the deleted container and restore it if container.deleted and container.name == container_client.container_name: - restored_ctn_client = bsc.undelete_container(container.name, container.version, - new_name="restored" + str(restored_version)) + restored_ctn_client = bsc._undelete_container(container.name, container.version, + new_name="restored" + str(restored_version)) restored_version += 1 # to make sure the deleted container is restored diff --git a/sdk/storage/azure-storage-blob/tests/test_container_async.py b/sdk/storage/azure-storage-blob/tests/test_container_async.py index ecb2a87f37f8..343ff58554e3 100644 --- a/sdk/storage/azure-storage-blob/tests/test_container_async.py +++ b/sdk/storage/azure-storage-blob/tests/test_container_async.py @@ -785,7 +785,7 @@ async def test_delete_container_with_lease_id(self, resource_group, location, st @AsyncStorageTestCase.await_prepared_test async def test_undelete_container(self, resource_group, location, storage_account, storage_account_key): # container soft delete should enabled by SRP call or use armclient, so make this test as playback only. - + pytest.skip('This will be added back along with STG74 features') bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key) container_client = await self._create_container(bsc) @@ -804,8 +804,8 @@ async def test_undelete_container(self, resource_group, location, storage_accoun for container in container_list: # find the deleted container and restore it if container.deleted and container.name == container_client.container_name: - restored_ctn_client = await bsc.undelete_container(container.name, container.version, - new_name="restoredctn" + str(restored_version)) + restored_ctn_client = await bsc._undelete_container(container.name, container.version, + new_name="restoredctn" + str(restored_version)) restored_version += 1 # to make sure the deleted container is restored @@ -816,6 +816,7 @@ async def test_undelete_container(self, resource_group, location, storage_accoun @GlobalStorageAccountPreparer() @AsyncStorageTestCase.await_prepared_test async def test_restore_to_existing_container(self, resource_group, location, storage_account, storage_account_key): + pytest.skip('This will be added back along with STG74 features') # container soft delete should enabled by SRP call or use armclient, so make this test as playback only. bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key) @@ -838,8 +839,8 @@ async def test_restore_to_existing_container(self, resource_group, location, sto # find the deleted container and restore it if container.deleted and container.name == container_client.container_name: with self.assertRaises(HttpResponseError): - await bsc.undelete_container(container.name, container.version, - new_name=existing_container_client.container_name) + await bsc._undelete_container(container.name, container.version, + new_name=existing_container_client.container_name) @GlobalStorageAccountPreparer() @AsyncStorageTestCase.await_prepared_test diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/models.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/models.py index 42365bb13da0..4359045bb8b8 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/models.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/models.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +# pylint: disable=too-many-instance-attributes from enum import Enum @@ -324,10 +325,15 @@ class AccountSasPermissions(object): Valid for the following Object resource types only: queue messages. :param bool process: Valid for the following Object resource type only: queue messages. + :param bool tag: + To enable set or get tags on the blobs in the container. + :param bool filter_by_tags: + To enable get blobs by tags, this should be used together with list permission. """ def __init__(self, read=False, write=False, delete=False, list=False, # pylint: disable=redefined-builtin - add=False, create=False, update=False, process=False, delete_previous_version=False): + add=False, create=False, update=False, process=False, delete_previous_version=False, tag=False, + filter_by_tags=False): self.read = read self.write = write self.delete = delete @@ -337,6 +343,8 @@ def __init__(self, read=False, write=False, delete=False, self.create = create self.update = update self.process = process + self.tag = tag + self.filter_by_tags = filter_by_tags self._str = (('r' if self.read else '') + ('w' if self.write else '') + ('d' if self.delete else '') + @@ -345,7 +353,10 @@ def __init__(self, read=False, write=False, delete=False, ('a' if self.add else '') + ('c' if self.create else '') + ('u' if self.update else '') + - ('p' if self.process else '')) + ('p' if self.process else '') + + ('f' if self.filter_by_tags else '') + + ('t' if self.tag else '') + ) def __str__(self): return self._str @@ -360,7 +371,7 @@ def from_string(cls, permission): :param str permission: Specify permissions in the string with the first letter of the word. - :return: A AccountSasPermissions object + :return: An AccountSasPermissions object :rtype: ~azure.storage.filedatalake.AccountSasPermissions """ p_read = 'r' in permission @@ -372,8 +383,11 @@ def from_string(cls, permission): p_create = 'c' in permission p_update = 'u' in permission p_process = 'p' in permission - - parsed = cls(p_read, p_write, p_delete, p_delete_previous_version, p_list, p_add, p_create, p_update, p_process) + p_tag = 't' in permission + p_filter_by_tags = 'f' in permission + parsed = cls(read=p_read, write=p_write, delete=p_delete, delete_previous_version=p_delete_previous_version, + list=p_list, add=p_add, create=p_create, update=p_update, process=p_process, tag=p_tag, + filter_by_tags=p_filter_by_tags) parsed._str = permission # pylint: disable = protected-access return parsed diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/models.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/models.py index b3265044ff50..9c5161cae823 100644 --- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/models.py +++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/models.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +# pylint: disable=too-many-instance-attributes from enum import Enum @@ -324,10 +325,15 @@ class AccountSasPermissions(object): Valid for the following Object resource types only: queue messages. :param bool process: Valid for the following Object resource type only: queue messages. + :param bool tag: + To enable set or get tags on the blobs in the container. + :param bool filter_by_tags: + To enable get blobs by tags, this should be used together with list permission. """ def __init__(self, read=False, write=False, delete=False, list=False, # pylint: disable=redefined-builtin - add=False, create=False, update=False, process=False, delete_previous_version=False): + add=False, create=False, update=False, process=False, delete_previous_version=False, tag=False, + filter_by_tags=False): self.read = read self.write = write self.delete = delete @@ -337,6 +343,8 @@ def __init__(self, read=False, write=False, delete=False, self.create = create self.update = update self.process = process + self.tag = tag + self.filter_by_tags = filter_by_tags self._str = (('r' if self.read else '') + ('w' if self.write else '') + ('d' if self.delete else '') + @@ -345,7 +353,10 @@ def __init__(self, read=False, write=False, delete=False, ('a' if self.add else '') + ('c' if self.create else '') + ('u' if self.update else '') + - ('p' if self.process else '')) + ('p' if self.process else '') + + ('f' if self.filter_by_tags else '') + + ('t' if self.tag else '') + ) def __str__(self): return self._str @@ -372,8 +383,11 @@ def from_string(cls, permission): p_create = 'c' in permission p_update = 'u' in permission p_process = 'p' in permission - - parsed = cls(p_read, p_write, p_delete, p_delete_previous_version, p_list, p_add, p_create, p_update, p_process) + p_tag = 't' in permission + p_filter_by_tags = 'f' in permission + parsed = cls(read=p_read, write=p_write, delete=p_delete, delete_previous_version=p_delete_previous_version, + list=p_list, add=p_add, create=p_create, update=p_update, process=p_process, tag=p_tag, + filter_by_tags=p_filter_by_tags) parsed._str = permission # pylint: disable = protected-access return parsed diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/models.py b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/models.py index 10ffaec3c569..60a20631ea0d 100644 --- a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/models.py +++ b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/models.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +# pylint: disable=too-many-instance-attributes from enum import Enum @@ -324,10 +325,15 @@ class AccountSasPermissions(object): Valid for the following Object resource types only: queue messages. :param bool process: Valid for the following Object resource type only: queue messages. + :param bool tag: + To enable set or get tags on the blobs in the container. + :param bool filter_by_tags: + To enable get blobs by tags, this should be used together with list permission. """ def __init__(self, read=False, write=False, delete=False, list=False, # pylint: disable=redefined-builtin - add=False, create=False, update=False, process=False, delete_previous_version=False): + add=False, create=False, update=False, process=False, delete_previous_version=False, tag=False, + filter_by_tags=False): self.read = read self.write = write self.delete = delete @@ -337,6 +343,8 @@ def __init__(self, read=False, write=False, delete=False, self.create = create self.update = update self.process = process + self.tag = tag + self.filter_by_tags = filter_by_tags self._str = (('r' if self.read else '') + ('w' if self.write else '') + ('d' if self.delete else '') + @@ -345,7 +353,10 @@ def __init__(self, read=False, write=False, delete=False, ('a' if self.add else '') + ('c' if self.create else '') + ('u' if self.update else '') + - ('p' if self.process else '')) + ('p' if self.process else '') + + ('f' if self.filter_by_tags else '') + + ('t' if self.tag else '') + ) def __str__(self): return self._str @@ -360,7 +371,7 @@ def from_string(cls, permission): :param str permission: Specify permissions in the string with the first letter of the word. - :return: A AccountSasPermissions object + :return: An AccountSasPermissions object :rtype: ~azure.storage.queue.AccountSasPermissions """ p_read = 'r' in permission @@ -372,8 +383,11 @@ def from_string(cls, permission): p_create = 'c' in permission p_update = 'u' in permission p_process = 'p' in permission - - parsed = cls(p_read, p_write, p_delete, p_delete_previous_version, p_list, p_add, p_create, p_update, p_process) + p_tag = 't' in permission + p_filter_by_tags = 'f' in permission + parsed = cls(read=p_read, write=p_write, delete=p_delete, delete_previous_version=p_delete_previous_version, + list=p_list, add=p_add, create=p_create, update=p_update, process=p_process, tag=p_tag, + filter_by_tags=p_filter_by_tags) parsed._str = permission # pylint: disable = protected-access return parsed