Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fileshare] Added support for set share properties including access tier #14355

Merged
merged 11 commits into from
Oct 18, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
ContentSettings,
NTFSAttributes)
from ._generated.models import (
HandleItem
HandleItem,
ShareAccessTier
)

__version__ = VERSION
Expand All @@ -56,6 +57,7 @@
'RetentionPolicy',
'CorsRule',
'ShareSmbSettings',
'ShareAccessTier',
'SmbMultichannel',
'ShareProtocolSettings',
'AccessPolicy',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ class ShareProperties(DictMixin):
conditionally.
:ivar int quota:
The allocated quota.
:ivar str access_tier:
The share's access tier.
:ivar dict metadata: A dict with name_value pairs to associate with the
share as metadata.
:ivar str snapshot:
Expand All @@ -331,6 +333,7 @@ def __init__(self, **kwargs):
self.last_modified = kwargs.get('Last-Modified')
self.etag = kwargs.get('ETag')
self.quota = kwargs.get('x-ms-share-quota')
self.access_tier = kwargs.get('x-ms-access-tier')
self.next_allowed_quota_downgrade_time = kwargs.get('x-ms-share-next-allowed-quota-downgrade-time')
self.metadata = kwargs.get('metadata')
self.snapshot = None
Expand All @@ -350,6 +353,7 @@ def _from_generated(cls, generated):
props.last_modified = generated.properties.last_modified
props.etag = generated.properties.etag
props.quota = generated.properties.quota
props.access_tier = generated.properties.access_tier
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In blob we call it blob_tier, do we want to be consistent and call it's share_tier?

Copy link
Contributor Author

@tasherif-msft tasherif-msft Oct 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think access_tier is more concise. Since this is now a property of shares we shouldn't have a prefix share. For example, we call the property quota not share_quota or etag not share_etag. I believe for future naming access_tier is the better naming convention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's should be blob_access_tier and share_access_tier or access_tier. I know we have convention to prefix things with blob_/share_ somewhere (not sure if this applies here). But we should also make sure that "access_tier" can be easily matched with other SDKs and REST docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at https://github.com/Azure/azure-sdk-for-java/pull/15897/files, it appears access_tier would be consistent with other SDKs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - I think access_tier is a good name. No need for share prefix as it's already on ShareProeprties.

If we wanted, what we can do in a future Blobs release is to add access_tier and stop documenting blob_tier - it will always still be there of course so it will never be a breaking change.

props.next_allowed_quota_downgrade_time = generated.properties.next_allowed_quota_downgrade_time
props.metadata = generated.metadata
props.snapshot = generated.snapshot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,13 @@ def create_share(self, **kwargs):
Name-value pairs associated with the share as metadata.
:keyword int quota:
The quota to be allotted.
:keyword access_tier:
Specifies the access tier of the share.
Possible values: 'TransactionOptimized', 'Hot', 'Cool'
:paramtype access_tier: str or ~azure.storage.fileshare.models.ShareAccessTier

.. versionadded:: 12.6.0

:keyword int timeout:
The timeout parameter is expressed in seconds.
:returns: Share-updated property dict (Etag and last modified).
Expand All @@ -321,6 +328,7 @@ def create_share(self, **kwargs):
"""
metadata = kwargs.pop('metadata', None)
quota = kwargs.pop('quota', None)
access_tier = kwargs.pop('access_tier', None)
timeout = kwargs.pop('timeout', None)
headers = kwargs.pop('headers', {})
headers.update(add_metadata_headers(metadata)) # type: ignore
Expand All @@ -330,6 +338,7 @@ def create_share(self, **kwargs):
timeout=timeout,
metadata=metadata,
quota=quota,
access_tier=access_tier,
cls=return_response_headers,
headers=headers,
**kwargs)
Expand Down Expand Up @@ -504,6 +513,55 @@ def set_share_quota(self, quota, **kwargs):
return self._client.share.set_properties( # type: ignore
timeout=timeout,
quota=quota,
access_tier=None,
lease_access_conditions=access_conditions,
cls=return_response_headers,
**kwargs)
except StorageErrorException as error:
process_storage_error(error)

@distributed_trace
def set_share_properties(self, **kwargs):
# type: (Any) -> Dict[str, Any]
"""Sets the share properties.

.. versionadded:: 12.6.0

:keyword access_tier:
Specifies the access tier of the share.
Possible values: 'TransactionOptimized', 'Hot', and 'Cool'
:paramtype access_tier: str or ~azure.storage.fileshare.models.ShareAccessTier
:keyword int quota:
Specifies the maximum size of the share, in gigabytes.
Must be greater than 0, and less than or equal to 5TB.
:keyword int timeout:
The timeout parameter is expressed in seconds.
:keyword lease:
Required if the share has an active lease. Value can be a ShareLeaseClient object
or the lease ID as a string.
:returns: Share-updated property dict (Etag and last modified).
:rtype: dict(str, Any)

.. admonition:: Example:

.. literalinclude:: ../samples/file_samples_share.py
:start-after: [START set_share_properties]
:end-before: [END set_share_properties]
:language: python
:dedent: 12
:caption: Sets the share properties.
"""
access_conditions = get_access_conditions(kwargs.pop('lease', None))
timeout = kwargs.pop('timeout', None)
access_tier = kwargs.pop('access_tier', None)
quota = kwargs.pop('quota', None)
if all(parameter is None for parameter in [access_tier, quota]):
raise ValueError("set_share_properties should be called with at least one parameter.")
try:
return self._client.share.set_properties( # type: ignore
timeout=timeout,
quota=quota,
access_tier=access_tier,
lease_access_conditions=access_conditions,
cls=return_response_headers,
**kwargs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ async def create_share(self, **kwargs):
Name-value pairs associated with the share as metadata.
:keyword int quota:
The quota to be allotted.
:keyword access_tier:
Specifies the access tier of the share.
Possible values: 'TransactionOptimized', 'Hot', 'Cool'
:paramtype access_tier: str or ~azure.storage.fileshare.models.ShareAccessTier

.. versionadded:: 12.6.0

:keyword int timeout:
The timeout parameter is expressed in seconds.
:returns: Share-updated property dict (Etag and last modified).
Expand All @@ -192,6 +199,7 @@ async def create_share(self, **kwargs):
"""
metadata = kwargs.pop('metadata', None)
quota = kwargs.pop('quota', None)
access_tier = kwargs.pop('access_tier', None)
timeout = kwargs.pop('timeout', None)
headers = kwargs.pop('headers', {})
headers.update(add_metadata_headers(metadata)) # type: ignore
Expand All @@ -201,6 +209,7 @@ async def create_share(self, **kwargs):
timeout=timeout,
metadata=metadata,
quota=quota,
access_tier=access_tier,
cls=return_response_headers,
headers=headers,
**kwargs)
Expand Down Expand Up @@ -374,12 +383,60 @@ async def set_share_quota(self, quota, **kwargs):
return await self._client.share.set_properties( # type: ignore
timeout=timeout,
quota=quota,
access_tier=None,
cls=return_response_headers,
lease_access_conditions=access_conditions,
**kwargs)
except StorageErrorException as error:
process_storage_error(error)

async def set_share_properties(self, **kwargs):
# type: (Any) -> Dict[str, Any]
"""Sets the share properties.

.. versionadded:: 12.6.0

:keyword access_tier:
Specifies the access tier of the share.
Possible values: 'TransactionOptimized', 'Hot', and 'Cool'
:paramtype access_tier: str or ~azure.storage.fileshare.models.ShareAccessTier
:keyword int quota:
Specifies the maximum size of the share, in gigabytes.
Must be greater than 0, and less than or equal to 5TB.
:keyword int timeout:
The timeout parameter is expressed in seconds.
:keyword lease:
Required if the share has an active lease. Value can be a ShareLeaseClient object
or the lease ID as a string.
:returns: Share-updated property dict (Etag and last modified).
:rtype: dict(str, Any)

.. admonition:: Example:

.. literalinclude:: ../samples/file_samples_share_async.py
:start-after: [START set_share_properties]
:end-before: [END set_share_properties]
:language: python
:dedent: 16
:caption: Sets the share properties.
"""
access_conditions = get_access_conditions(kwargs.pop('lease', None))
timeout = kwargs.pop('timeout', None)
access_tier = kwargs.pop('access_tier', None)
quota = kwargs.pop('quota', None)
if all(parameter is None for parameter in [access_tier, quota]):
raise ValueError("set_share_properties should be called with at least one parameter.")
try:
return await self._client.share.set_properties( # type: ignore
timeout=timeout,
quota=quota,
access_tier=access_tier,
lease_access_conditions=access_conditions,
cls=return_response_headers,
**kwargs)
except StorageErrorException as error:
process_storage_error(error)

@distributed_trace_async
async def set_share_metadata(self, metadata, **kwargs):
# type: (Dict[str, Any], Any) -> Dict[str, Any]
Expand Down
39 changes: 36 additions & 3 deletions sdk/storage/azure-storage-file-share/samples/file_samples_share.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"""

import os
from azure.storage.fileshare import ShareAccessTier

SOURCE_FILE = './SampleSource.txt'
DEST_FILE = './SampleDestination.txt'
Expand All @@ -37,7 +38,8 @@ def create_share_snapshot(self):
share = ShareClient.from_connection_string(self.connection_string, "sharesamples1")

# [START create_share]
share.create_share()
# Create share with Access Tier set to Hot
share.create_share(access_tier=ShareAccessTier("Hot"))
# [END create_share]
try:
# [START create_share_snapshot]
Expand Down Expand Up @@ -75,10 +77,40 @@ def set_share_quota_and_metadata(self):
# Delete the share
share.delete_share()

def set_share_properties(self):
tasherif-msft marked this conversation as resolved.
Show resolved Hide resolved
from azure.storage.fileshare import ShareClient
share1 = ShareClient.from_connection_string(self.connection_string, "sharesamples3a")
share2 = ShareClient.from_connection_string(self.connection_string, "sharesamples3b")

# Create the share
share1.create_share()
share2.create_share()

try:
# [START set_share_properties]
# Set the tier for the first share to Hot
share1.set_share_properties(access_tier="Hot")
# Set the quota for the first share to 3
share1.set_share_properties(quota=3)
# Set the tier for the second share to Cool and quota to 2
share2.set_share_properties(access_tier=ShareAccessTier("Cool"), quota=2)

# Get the shares' properties
print(share1.get_share_properties().access_tier)
print(share1.get_share_properties().quota)
print(share2.get_share_properties().access_tier)
print(share2.get_share_properties().quota)
# [END set_share_properties]

finally:
# Delete the shares
share1.delete_share()
share2.delete_share()

def list_directories_and_files(self):
# Instantiate the ShareClient from a connection string
from azure.storage.fileshare import ShareClient
share = ShareClient.from_connection_string(self.connection_string, "sharesamples3")
share = ShareClient.from_connection_string(self.connection_string, "sharesamples4")

# Create the share
share.create_share()
Expand All @@ -103,7 +135,7 @@ def list_directories_and_files(self):
def get_directory_or_file_client(self):
# Instantiate the ShareClient from a connection string
from azure.storage.fileshare import ShareClient
share = ShareClient.from_connection_string(self.connection_string, "sharesamples4")
share = ShareClient.from_connection_string(self.connection_string, "sharesamples5")

# Get the directory client to interact with a specific directory
my_dir = share.get_directory_client("dir1")
Expand Down Expand Up @@ -131,6 +163,7 @@ def acquire_share_lease(self):
sample = ShareSamples()
sample.create_share_snapshot()
sample.set_share_quota_and_metadata()
sample.set_share_properties()
sample.list_directories_and_files()
sample.get_directory_or_file_client()
sample.acquire_share_lease()
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import os
import asyncio
from azure.storage.fileshare import ShareAccessTier

SOURCE_FILE = './SampleSource.txt'
DEST_FILE = './SampleDestination.txt'
Expand All @@ -39,7 +40,8 @@ async def create_share_snapshot_async(self):

async with share:
# [START create_share]
await share.create_share()
# Create share with Access Tier set to Hot
await share.create_share(access_tier=ShareAccessTier("Hot"))
# [END create_share]
try:
# [START create_share_snapshot]
Expand Down Expand Up @@ -78,10 +80,43 @@ async def set_share_quota_and_metadata_async(self):
# Delete the share
await share.delete_share()

async def set_share_properties(self):
from azure.storage.fileshare.aio import ShareClient
share1 = ShareClient.from_connection_string(self.connection_string, "sharesamples3a")
share2 = ShareClient.from_connection_string(self.connection_string, "sharesamples3b")

# Create the share
async with share1 and share2:
await share1.create_share()
await share2.create_share()

try:
# [START set_share_properties]
# Set the tier for the first share to Hot
await share1.set_share_properties(access_tier="Hot")
# Set the quota for the first share to 3
await share1.set_share_properties(quota=3)
# Set the tier for the second share to Cool and quota to 2
await share2.set_share_properties(access_tier=ShareAccessTier("Cool"), quota=2)

# Get the shares' properties
props1 = await share1.get_share_properties()
props2 = await share2.get_share_properties()
print(props1.access_tier)
print(props1.quota)
print(props2.access_tier)
print(props2.quota)
# [END set_share_properties]

finally:
# Delete the shares
await share1.delete_share()
await share2.delete_share()

async def list_directories_and_files_async(self):
# Instantiate the ShareClient from a connection string
from azure.storage.fileshare.aio import ShareClient
share = ShareClient.from_connection_string(self.connection_string, "sharesamples3")
share = ShareClient.from_connection_string(self.connection_string, "sharesamples4")

# Create the share
async with share:
Expand Down Expand Up @@ -109,7 +144,7 @@ async def list_directories_and_files_async(self):
async def get_directory_or_file_client_async(self):
# Instantiate the ShareClient from a connection string
from azure.storage.fileshare.aio import ShareClient
share = ShareClient.from_connection_string(self.connection_string, "sharesamples4")
share = ShareClient.from_connection_string(self.connection_string, "sharesamples5")

# Get the directory client to interact with a specific directory
my_dir = share.get_directory_client("dir1")
Expand All @@ -122,6 +157,7 @@ async def main():
sample = ShareSamplesAsync()
await sample.create_share_snapshot_async()
await sample.set_share_quota_and_metadata_async()
await sample.set_share_properties()
await sample.list_directories_and_files_async()
await sample.get_directory_or_file_client_async()

Expand Down
Loading