diff --git a/src/Storage/Storage.Management/ChangeLog.md b/src/Storage/Storage.Management/ChangeLog.md index 6e371b46f654..7ff3cf22975d 100644 --- a/src/Storage/Storage.Management/ChangeLog.md +++ b/src/Storage/Storage.Management/ChangeLog.md @@ -18,11 +18,15 @@ - Additional information about change #1 --> ## Upcoming Release +* Removed the ValidateSet of StandardBlobTier parameter + - `Copy-AzStorageBlob` + - `Set-AzStorageBlobContent` + - `Start-AzStorageBlobCopy` ## Version 5.3.0 -* Return ListBlobProperties in blob list result +* Returned ListBlobProperties in blob list result - `Get-AzStorageBlob` -* Output AllowedCopyScope in get account result +* Returned AllowedCopyScope in get account result - `Get-AzStorageAccount` ## Version 5.2.0 diff --git a/src/Storage/Storage.Management/help/Copy-AzStorageBlob.md b/src/Storage/Storage.Management/help/Copy-AzStorageBlob.md index d560cda17c28..f5d7d688a07d 100644 --- a/src/Storage/Storage.Management/help/Copy-AzStorageBlob.md +++ b/src/Storage/Storage.Management/help/Copy-AzStorageBlob.md @@ -43,38 +43,38 @@ The **Copy-AzStorageBlob** cmdlet copies a blob synchronously, currently only su ### Example 1: Copy a named blob to another ``` -C:\PS> $destBlob = Copy-AzStorageBlob -SrcContainer "sourcecontainername" -SrcBlob "srcblobname" -DestContainer "destcontainername" -DestBlob "destblobname" +$destBlob = Copy-AzStorageBlob -SrcContainer "sourcecontainername" -SrcBlob "srcblobname" -DestContainer "destcontainername" -DestBlob "destblobname" ``` This command copies a blob from source container to the destination container with a new blob name. ### Example 2: Copy blob from a blob object ``` -C:\PS> $srcBlob = Get-AzStorageBlob -Container $containerName -Blob $blobName -Context $ctx -C:\PS> $destBlob = $srcBlob | Copy-AzStorageBlob -DestContainer "destcontainername" -DestBlob "destblobname" +$srcBlob = Get-AzStorageBlob -Container $containerName -Blob $blobName -Context $ctx +$destBlob = $srcBlob | Copy-AzStorageBlob -DestContainer "destcontainername" -DestBlob "destblobname" ``` This command copies a blob from source blob object to the destination container with a new blob name. ### Example 3: Copy blob from a blob Uri ``` -C:\PS> $srcBlobUri = New-AzStorageBlobSASToken -Container $srcContainerName -Blob $srcBlobName -Permission rt -ExpiryTime (Get-Date).AddDays(7) -FullUri -C:\PS> $destBlob = Copy-AzStorageBlob -AbsoluteUri $srcBlobUri -DestContainer "destcontainername" -DestBlob "destblobname" +$srcBlobUri = New-AzStorageBlobSASToken -Container $srcContainerName -Blob $srcBlobName -Permission rt -ExpiryTime (Get-Date).AddDays(7) -FullUri +$destBlob = Copy-AzStorageBlob -AbsoluteUri $srcBlobUri -DestContainer "destcontainername" -DestBlob "destblobname" ``` The first command creates a blob Uri of the source blob, with sas token of permission "rt". The second command copies from source blob Uri to the destination blob. ### Example 4: Update a block blob encryption scope ``` -C:\PS> $blob = Copy-AzStorageBlob -SrcContainer $containerName -SrcBlob $blobname -DestContainer $containername -EncryptionScope $newScopeName -Force +$blob = Copy-AzStorageBlob -SrcContainer $containerName -SrcBlob $blobname -DestContainer $containername -EncryptionScope $newScopeName -Force ``` This command update a block blob encryption scope by copy it to itself with a new encryption scope. -### Example 5: Copy a blob to a new append blob +### Example 5: Copy a blob to a new append blob ``` -C:\PS> $srcBlob = Get-AzStorageBlob -Container $containerName -Blob $blobName -Context $ctx -C:\PS> $destBlob = Copy-AzStorageBlob -SrcContainer "sourcecontainername" -SrcBlob "srcblobname" -DestContainer "destcontainername" -DestBlob "destblobname" -DestBlobType "Append" -DestContext $destCtx +$srcBlob = Get-AzStorageBlob -Container $containerName -Blob $blobName -Context $ctx +$destBlob = Copy-AzStorageBlob -SrcContainer "sourcecontainername" -SrcBlob "srcblobname" -DestContainer "destcontainername" -DestBlob "destblobname" -DestBlobType "Append" -DestContext $destCtx ``` ## PARAMETERS @@ -325,7 +325,6 @@ See detail in https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob- Type: System.String Parameter Sets: (All) Aliases: -Accepted values: Hot, Cool, Archive Required: False Position: Named diff --git a/src/Storage/Storage.Management/help/Set-AzStorageBlobContent.md b/src/Storage/Storage.Management/help/Set-AzStorageBlobContent.md index 61f9e3b81641..cd4199aa9f31 100644 --- a/src/Storage/Storage.Management/help/Set-AzStorageBlobContent.md +++ b/src/Storage/Storage.Management/help/Set-AzStorageBlobContent.md @@ -50,14 +50,14 @@ The **Set-AzStorageBlobContent** cmdlet uploads a local file to an Azure Storage ### Example 1: Upload a named file ``` -PS C:\>Set-AzStorageBlobContent -Container "ContosoUpload" -File ".\PlanningData" -Blob "Planning2015" +Set-AzStorageBlobContent -Container "ContosoUpload" -File ".\PlanningData" -Blob "Planning2015" ``` This command uploads the file that is named PlanningData to a blob named Planning2015. ### Example 2: Upload all files under the current folder ``` -PS C:\>Get-ChildItem -File -Recurse | Set-AzStorageBlobContent -Container "ContosoUploads" +Get-ChildItem -File -Recurse | Set-AzStorageBlobContent -Container "ContosoUploads" ``` This command uses the core Windows PowerShell cmdlet Get-ChildItem to get all the files in the current folder and in subfolders, and then passes them to the current cmdlet by using the pipeline operator. @@ -65,7 +65,7 @@ The **Set-AzStorageBlobContent** cmdlet uploads the files to the container named ### Example 3: Overwrite an existing blob ``` -PS C:\>Get-AzStorageBlob -Container "ContosoUploads" -Blob "Planning2015" | Set-AzStorageBlobContent -File "ContosoPlanning" +Get-AzStorageBlob -Container "ContosoUploads" -Blob "Planning2015" | Set-AzStorageBlobContent -File "ContosoPlanning" ``` This command gets the blob named Planning2015 in the ContosoUploads container by using the Get-AzStorageBlob cmdlet, and then passes that blob to the current cmdlet. @@ -76,7 +76,7 @@ If you confirm the command, the cmdlet overwrites the existing blob. ### Example 4: Upload a file to a container by using the pipeline ``` -PS C:\>Get-AzStorageContainer -Container "ContosoUpload*" | Set-AzStorageBlobContent -File "ContosoPlanning" -Blob "Planning2015" +Get-AzStorageContainer -Container "ContosoUpload*" | Set-AzStorageBlobContent -File "ContosoPlanning" -Blob "Planning2015" ``` This command gets the container that starts with the string ContosoUpload by using the **Get-AzStorageContainer** cmdlet, and then passes that blob to the current cmdlet. @@ -84,8 +84,8 @@ The command uploads the file that is named ContosoPlanning as Planning2015. ### Example 5: Upload a file to page blob with metadata and PremiumPageBlobTier as P10 ``` -PS C:\>$Metadata = @{"key" = "value"; "name" = "test"} -PS C:\> Set-AzStorageBlobContent -File "ContosoPlanning" -Container "ContosoUploads" -Metadata $Metadata -BlobType Page -PremiumPageBlobTier P10 +$Metadata = @{"key" = "value"; "name" = "test"} +Set-AzStorageBlobContent -File "ContosoPlanning" -Container "ContosoUploads" -Metadata $Metadata -BlobType Page -PremiumPageBlobTier P10 ``` The first command creates a hash table that contains metadata for a blob, and stores that hash table in the $Metadata variable. @@ -94,6 +94,8 @@ The blob includes the metadata stored in $Metadata, and has PremiumPageBlobTier ### Example 6: Upload a file to blob with specified blob properties, and set StandardBlobTier as Cool + + ``` PS C:\> $filepath = "c:\temp\index.html" PS C:\> Set-AzStorageBlobContent -File $filepath -Container "contosouploads" -Properties @{"ContentType" = [System.Web.MimeMapping]::GetMimeMapping($filepath); "ContentMD5" = "i727sP7HigloQDsqadNLHw=="} -StandardBlobTier Cool @@ -110,6 +112,8 @@ This command gets ContentType value set to blob properties by [System.Web.MimeMa ### Example 7: Upload a file to a blob with Encryption Scope + + ``` PS C:\> $blob = Set-AzStorageBlobContent -File "mylocalfile" -Container "mycontainer" -Blob "myblob" -EncryptionScope "myencryptscope" @@ -419,7 +423,6 @@ See detail in https://docs.microsoft.com/azure/storage/blobs/storage-blob-storag Type: System.String Parameter Sets: (All) Aliases: -Accepted values: Hot, Cool, Archive Required: False Position: Named @@ -492,7 +495,7 @@ Accept wildcard characters: False ``` ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS diff --git a/src/Storage/Storage.Management/help/Start-AzStorageBlobCopy.md b/src/Storage/Storage.Management/help/Start-AzStorageBlobCopy.md index 6f5b22c608f8..0b0c4a78f3a4 100644 --- a/src/Storage/Storage.Management/help/Start-AzStorageBlobCopy.md +++ b/src/Storage/Storage.Management/help/Start-AzStorageBlobCopy.md @@ -123,14 +123,14 @@ The **Start-AzStorageBlobCopy** cmdlet starts to copy a blob. ### Example 1: Copy a named blob ``` -C:\PS>Start-AzStorageBlobCopy -SrcBlob "ContosoPlanning2015" -DestContainer "ContosoArchives" -SrcContainer "ContosoUploads" +Start-AzStorageBlobCopy -SrcBlob "ContosoPlanning2015" -DestContainer "ContosoArchives" -SrcContainer "ContosoUploads" ``` This command starts the copy operation of the blob named ContosoPlanning2015 from the container named ContosoUploads to the container named ContosoArchives. ### Example 2: Get a container to specify blobs to copy ``` -C:\PS>Get-AzStorageContainer -Name "ContosoUploads" | Start-AzStorageBlobCopy -SrcBlob "ContosoPlanning2015" -DestContainer "ContosoArchives" +Get-AzStorageContainer -Name "ContosoUploads" | Start-AzStorageBlobCopy -SrcBlob "ContosoPlanning2015" -DestContainer "ContosoArchives" ``` This command gets the container named ContosoUploads, by using the **Get-AzStorageContainer** cmdlet, and then passes the container to the current cmdlet by using the pipeline operator. @@ -140,7 +140,7 @@ The *DestContainer* parameter specifies ContosoArchives as the destination conta ### Example 3: Get all blobs in a container and copy them ``` -C:\PS>Get-AzStorageBlob -Container "ContosoUploads" | Start-AzStorageBlobCopy -DestContainer "ContosoArchives" +Get-AzStorageBlob -Container "ContosoUploads" | Start-AzStorageBlobCopy -DestContainer "ContosoArchives" ``` This command gets the blobs in the container named ContosoUploads, by using the **Get-AzStorageBlob** cmdlet, and then passes the results to the current cmdlet by using the pipeline operator. @@ -148,9 +148,9 @@ That cmdlet starts the copy operation of the blobs to the container named Contos ### Example 4: Copy a blob specified as an object ``` -C:\PS>$SrcBlob = Get-AzStorageBlob -Container "ContosoUploads" -Blob "ContosoPlanning2015" -C:\PS> $DestBlob = Get-AzStorageBlob -Container "ContosoArchives" -Blob "ContosoPlanning2015Archived" -C:\PS> Start-AzStorageBlobCopy -ICloudBlob $SrcBlob.ICloudBlob -DestICloudBlob $DestBlob.ICloudBlob +$SrcBlob = Get-AzStorageBlob -Container "ContosoUploads" -Blob "ContosoPlanning2015" +$DestBlob = Get-AzStorageBlob -Container "ContosoArchives" -Blob "ContosoPlanning2015Archived" +Start-AzStorageBlobCopy -ICloudBlob $SrcBlob.ICloudBlob -DestICloudBlob $DestBlob.ICloudBlob ``` The first command gets the blob named ContosoPlanning2015 in the container named ContosoUploads. @@ -162,8 +162,8 @@ The command uses standard dot notation to specify the **ICloudBlob** objects for ### Example 5: Copy a blob from a URI ``` -C:\PS>$Context = New-AzStorageContext -StorageAccountName "ContosoGeneral" -StorageAccountKey "< Storage Key for ContosoGeneral ends with == >" -C:\PS> Start-AzStorageBlobCopy -AbsoluteUri "http://www.contosointernal.com/planning" -DestContainer "ContosoArchive" -DestBlob "ContosoPlanning2015" -DestContext $Context +$Context = New-AzStorageContext -StorageAccountName "ContosoGeneral" -StorageAccountKey "< Storage Key for ContosoGeneral ends with == >" +Start-AzStorageBlobCopy -AbsoluteUri "http://www.contosointernal.com/planning" -DestContainer "ContosoArchive" -DestBlob "ContosoPlanning2015" -DestContext $Context ``` This command creates a context for the account named ContosoGeneral that uses the specified key, and then stores that key in the $Context variable. @@ -173,7 +173,7 @@ There are no source storage context, so the source Uri must have access to the s ### Example 6: Copy a block blob to destination container with a new blob name, and set destination blob StandardBlobTier as Hot, RehydratePriority as High ``` -C:\PS>Start-AzStorageBlobCopy -SrcContainer "ContosoUploads" -SrcBlob "BlockBlobName" -DestContainer "ContosoArchives" -DestBlob "NewBlockBlobName" -StandardBlobTier Hot -RehydratePriority High +Start-AzStorageBlobCopy -SrcContainer "ContosoUploads" -SrcBlob "BlockBlobName" -DestContainer "ContosoArchives" -DestBlob "NewBlockBlobName" -StandardBlobTier Hot -RehydratePriority High ``` This command starts the copy operation of a block blob to destination container with a new blob name, and set destination blob StandardBlobTier as Hot, RehydratePriority as High @@ -614,7 +614,6 @@ See detail in https://docs.microsoft.com/azure/storage/blobs/storage-blob-storag Type: System.String Parameter Sets: (All) Aliases: -Accepted values: Hot, Cool, Archive Required: False Position: Named diff --git a/src/Storage/Storage/Blob/Cmdlet/CopyAzureStorageBlob.cs b/src/Storage/Storage/Blob/Cmdlet/CopyAzureStorageBlob.cs index 006ceff85e8e..c302b8218130 100644 --- a/src/Storage/Storage/Blob/Cmdlet/CopyAzureStorageBlob.cs +++ b/src/Storage/Storage/Blob/Cmdlet/CopyAzureStorageBlob.cs @@ -18,6 +18,7 @@ namespace Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet using Azure.Commands.Common.Authentication.Abstractions; using Commands.Common.Storage.ResourceModel; using global::Azure.Storage.Blobs; + using global::Azure.Storage.Blobs.Models; using global::Azure.Storage.Blobs.Specialized; using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters; using Microsoft.Azure.Storage.Blob; @@ -99,28 +100,30 @@ public string SrcContainer public string DestBlobType { get; set; } [Parameter(HelpMessage = "Block Blob Tier, valid values are Hot/Cool/Archive. See detail in https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers", Mandatory = false)] + [ValidateNotNullOrEmpty] [PSArgumentCompleter("Hot", "Cool", "Archive")] - [ValidateSet("Hot", "Cool", "Archive", IgnoreCase = true)] public string StandardBlobTier { get { - return standardBlobTier is null ? null : standardBlobTier.Value.ToString(); + return accesstier?.ToString(); } set { if (value != null) { - standardBlobTier = ((StandardBlobTier)Enum.Parse(typeof(StandardBlobTier), value, true)); + accesstier = new AccessTier(value); + isBlockBlobAccessTier = true; } else { - standardBlobTier = null; + accesstier = null; } } } - private StandardBlobTier? standardBlobTier = null; + private bool? isBlockBlobAccessTier = null; + private AccessTier? accesstier = null; [Parameter(HelpMessage = "Block Blob RehydratePriority. Indicates the priority with which to rehydrate an archived blob. Valid values are High/Standard.", Mandatory = false)] [ValidateSet("Standard", "High", IgnoreCase = true)] @@ -372,7 +375,11 @@ private async Task CopyFromUri(long taskId, IStorageBlobManagement destChannel, if (destBlobType != null) { - ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(destBlobType), null, standardBlobTier, rehydratePriority); + ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(destBlobType), null, isBlockBlobAccessTier, rehydratePriority); + if (this.rehydratePriority != null && this.accesstier == null) + { + throw new ArgumentException("RehydratePriority should only be specified when StandardBlobTier is specified."); + } } if (!destExist || this.ConfirmOverwrite(srcUri.AbsoluteUri.ToString(), destBlob.Uri.ToString())) @@ -483,9 +490,9 @@ private async Task CopyFromUri(long taskId, IStorageBlobManagement destChannel, Track2Models.BlobCopyFromUriOptions options = new Track2Models.BlobCopyFromUriOptions(); // The Blob Type and Blob Tier must match, since already checked before - if (standardBlobTier != null || rehydratePriority != null) + if (accesstier != null || rehydratePriority != null) { - options.AccessTier = Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier); + options.AccessTier = accesstier; options.RehydratePriority = Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority); } options.SourceConditions = this.BlobRequestConditions; @@ -495,10 +502,10 @@ private async Task CopyFromUri(long taskId, IStorageBlobManagement destChannel, destBlobClient.SyncCopyFromUri(srcUri, options, this.CmdletCancellationToken); // Set rehydrate priority - if (rehydratePriority != null) + if (rehydratePriority != null && accesstier != null) { - destBlobClient.SetAccessTier(Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier) == null ? null : (Track2Models.AccessTier)Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier), - rehydratePriority: Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority), cancellationToken: this.CmdletCancellationToken); + destBlobClient.SetAccessTier(accesstier.Value, + rehydratePriority: Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority), cancellationToken: this.CmdletCancellationToken); } break; } @@ -510,9 +517,9 @@ private async Task CopyFromUri(long taskId, IStorageBlobManagement destChannel, commitBlockListOptions.Metadata = srcProperties.Metadata; commitBlockListOptions.Tags = blobTags ?? null; - if (standardBlobTier != null) + if (accesstier != null) { - commitBlockListOptions.AccessTier = Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier); + commitBlockListOptions.AccessTier = accesstier; } long blockLength = GetBlockLength(srcProperties.ContentLength); @@ -534,10 +541,10 @@ private async Task CopyFromUri(long taskId, IStorageBlobManagement destChannel, destBlockBlob.CommitBlockList(blockIDs, commitBlockListOptions, this.CmdletCancellationToken); // Set rehydrate priority - if (rehydratePriority != null) + if (rehydratePriority != null && accesstier != null) { - destBlockBlob.SetAccessTier(Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier) == null ? null : (Track2Models.AccessTier)Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier), - rehydratePriority: Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority), cancellationToken: this.CmdletCancellationToken); + destBlockBlob.SetAccessTier(accesstier.Value, + rehydratePriority: Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority), cancellationToken: this.CmdletCancellationToken); } break; } diff --git a/src/Storage/Storage/Blob/Cmdlet/SetAzureStorageBlobContent.cs b/src/Storage/Storage/Blob/Cmdlet/SetAzureStorageBlobContent.cs index 322fd92db3b9..8567a38111b4 100644 --- a/src/Storage/Storage/Blob/Cmdlet/SetAzureStorageBlobContent.cs +++ b/src/Storage/Storage/Blob/Cmdlet/SetAzureStorageBlobContent.cs @@ -180,28 +180,30 @@ public PremiumPageBlobTier PremiumPageBlobTier private PremiumPageBlobTier? pageBlobTier = null; [Parameter(HelpMessage = "Block Blob Tier, valid values are Hot/Cool/Archive. See detail in https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers", Mandatory = false)] + [ValidateNotNullOrEmpty] [PSArgumentCompleter("Hot", "Cool", "Archive")] - [ValidateSet("Hot", "Cool", "Archive", IgnoreCase = true)] public string StandardBlobTier { get { - return standardBlobTier is null ? null : standardBlobTier.Value.ToString(); + return accesstier?.ToString(); } set { if (value != null) { - standardBlobTier = ((StandardBlobTier)Enum.Parse(typeof(StandardBlobTier), value, true)); + accesstier = new AccessTier(value); + isBlockBlobAccessTier = true; } else { - standardBlobTier = null; + accesstier = null; } } } - private StandardBlobTier? standardBlobTier = null; + private bool? isBlockBlobAccessTier = null; + private AccessTier? accesstier = null; [Parameter(HelpMessage = "Encryption scope to be used when making requests to the blob.", Mandatory = false)] @@ -220,6 +222,10 @@ protected override bool UseTrack2Sdk() { return true; } + if (accesstier != null && accesstier.Value != AccessTier.Archive && accesstier.Value != AccessTier.Cool && accesstier.Value != AccessTier.Hot) + { + return true; + } return false; } @@ -286,9 +292,9 @@ await DataMovementTransferHelper.DoTransfer(() => data.Record, this.OutputStream).ConfigureAwait(false); - if (this.pageBlobTier != null || this.standardBlobTier != null) + if (this.pageBlobTier != null || this.accesstier != null) { - await this.SetBlobTier(localChannel, blob, pageBlobTier, standardBlobTier).ConfigureAwait(false); + await this.SetBlobTier(localChannel, blob, pageBlobTier, accesstier).ConfigureAwait(false); } try @@ -409,10 +415,10 @@ protected override void DoEndProcessing() /// IStorageBlobManagement channel object /// CloudBlob object /// Page Blob Tier - /// Access condition to source if it's file/blob in azure. - private async Task SetBlobTier(IStorageBlobManagement localChannel, StorageBlob.CloudBlob blob, PremiumPageBlobTier? pageBlobTier = null, StandardBlobTier? standardBlobTier = null) + /// Access condition to source if it's file/blob in azure. + private async Task SetBlobTier(IStorageBlobManagement localChannel, StorageBlob.CloudBlob blob, PremiumPageBlobTier? pageBlobTier = null, AccessTier? accessTier = null) { - if (pageBlobTier == null && standardBlobTier == null) + if (pageBlobTier == null && accessTier == null) { return; } @@ -424,10 +430,9 @@ private async Task SetBlobTier(IStorageBlobManagement localChannel, StorageBlob. { await Channel.SetPageBlobTierAsync((CloudPageBlob)blob, pageBlobTier.Value, requestOptions, OperationContext, CmdletCancellationToken).ConfigureAwait(false); } - if (standardBlobTier != null) + if (accessTier != null) { - AccessCondition accessCondition = null; - await Channel.SetStandardBlobTierAsync((CloudBlockBlob)blob, accessCondition, standardBlobTier.Value, null, requestOptions, OperationContext, CmdletCancellationToken).ConfigureAwait(false); + AzureStorageBlob.GetTrack2BlobClient(blob, localChannel.StorageContext, ClientOptions).SetAccessTier(accesstier.Value, cancellationToken: this.CmdletCancellationToken); } } @@ -450,7 +455,11 @@ internal virtual async Task UploadBlobwithSdk(long taskId, IStorageBlobManagemen BlobHttpHeaders blobHttpHeaders = CreateBlobHttpHeaders(BlobProperties); IDictionary metadata = new Dictionary(); SetBlobMeta_Track2(metadata, this.Metadata); - AccessTier? accesstier = GetAccessTier_Track2(this.standardBlobTier, this.pageBlobTier); + AccessTier? accesstierToSet = this.accesstier; + if (accesstierToSet == null) + { + accesstierToSet = Util.ConvertAccessTier_Track1ToTrack2(this.pageBlobTier); + } //Prepare progress handler long fileSize = new FileInfo(ResolvedFileName).Length; @@ -485,7 +494,7 @@ internal virtual async Task UploadBlobwithSdk(long taskId, IStorageBlobManagemen uploadOptions.Metadata = metadata; uploadOptions.HttpHeaders = blobHttpHeaders; uploadOptions.Conditions = this.BlobRequestConditions; - uploadOptions.AccessTier = accesstier; + uploadOptions.AccessTier = accesstierToSet; uploadOptions.ProgressHandler = progressHandler; uploadOptions.TransferOptions = trasnferOption; @@ -580,9 +589,9 @@ internal virtual async Task UploadBlobwithSdk(long taskId, IStorageBlobManagemen offset += readoutcount; progressHandler.Report(offset); } - if (string.Equals(blobType, PageBlobType, StringComparison.InvariantCultureIgnoreCase) && accesstier != null) + if (string.Equals(blobType, PageBlobType, StringComparison.InvariantCultureIgnoreCase) && accesstierToSet != null) { - await pageblobClient.SetAccessTierAsync(accesstier.Value, cancellationToken: CmdletCancellationToken).ConfigureAwait(false); + await pageblobClient.SetAccessTierAsync(accesstierToSet.Value, cancellationToken: CmdletCancellationToken).ConfigureAwait(false); } } else @@ -613,9 +622,9 @@ protected override void OnTaskSuccessful(DataMovementUserData data) AccessCondition accessCondition = null; StorageBlob.BlobRequestOptions requestOptions = RequestOptions; - if (this.pageBlobTier != null || this.standardBlobTier != null) + if (this.pageBlobTier != null || this.accesstier != null) { - this.SetBlobTier(localChannel, blob, pageBlobTier, standardBlobTier).Wait(); + this.SetBlobTier(localChannel, blob, pageBlobTier, accesstier).Wait(); } try @@ -683,7 +692,7 @@ public override void ExecuteCmdlet() { type = StorageBlob.BlobType.Unspecified; } - ValidateBlobTier(type, pageBlobTier, standardBlobTier); + ValidateBlobTier(type, pageBlobTier, this.isBlockBlobAccessTier); if (BlobProperties != null) { diff --git a/src/Storage/Storage/Blob/Cmdlet/StartAzureStorageBlobCopy.cs b/src/Storage/Storage/Blob/Cmdlet/StartAzureStorageBlobCopy.cs index a7616033d877..786df19b00db 100644 --- a/src/Storage/Storage/Blob/Cmdlet/StartAzureStorageBlobCopy.cs +++ b/src/Storage/Storage/Blob/Cmdlet/StartAzureStorageBlobCopy.cs @@ -211,27 +211,34 @@ public PremiumPageBlobTier PremiumPageBlobTier private PremiumPageBlobTier? pageBlobTier = null; [Parameter(HelpMessage = "Block Blob Tier, valid values are Hot/Cool/Archive. See detail in https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers", Mandatory = false)] + [ValidateNotNullOrEmpty] [PSArgumentCompleter("Hot", "Cool", "Archive")] - [ValidateSet("Hot", "Cool", "Archive", IgnoreCase = true)] public string StandardBlobTier { get { - return standardBlobTier is null ? null : standardBlobTier.Value.ToString(); + return accesstier?.ToString(); } set { if (value != null) { - standardBlobTier = ((StandardBlobTier)Enum.Parse(typeof(StandardBlobTier), value, true)); + accesstier = new Track2Models.AccessTier(value); + isBlockBlobAccessTier = true; + if(accesstier.Value == Track2Models.AccessTier.Hot || accesstier.Value == Track2Models.AccessTier.Cool || accesstier.Value == Track2Models.AccessTier.Archive) + { + standardBlobTier = ((StandardBlobTier)Enum.Parse(typeof(StandardBlobTier), value, true)); + } } else { - standardBlobTier = null; + accesstier = null; } } } + private bool? isBlockBlobAccessTier = null; + private Track2Models.AccessTier? accesstier = null; private StandardBlobTier? standardBlobTier = null; [Parameter(HelpMessage = "Block Blob RehydratePriority. Indicates the priority with which to rehydrate an archived blob. Valid values are High/Standard.", Mandatory = false)] @@ -488,7 +495,7 @@ public override void ExecuteCmdlet() private void StartCopyBlob(IStorageBlobManagement destChannel, CloudBlob srcCloudBlob, CloudBlob destCloudBlob) { ValidateBlobType(srcCloudBlob); - ValidateBlobTier(srcCloudBlob.BlobType, pageBlobTier, standardBlobTier, rehydratePriority); + ValidateBlobTier(srcCloudBlob.BlobType, pageBlobTier, this.isBlockBlobAccessTier, rehydratePriority); Func taskGenerator = (taskId) => StartCopyAsync(taskId, destChannel, srcCloudBlob, destCloudBlob); RunTask(taskGenerator); @@ -505,7 +512,7 @@ private void StartCopyBlob(IStorageBlobManagement destChannel, BlobBaseClient sr { destCloudBlob = Util.GetTrack2BlobClientWithType(destCloudBlob, destChannel.StorageContext, srcBlobType); } - ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(srcBlobType), pageBlobTier, standardBlobTier, rehydratePriority); + ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(srcBlobType), pageBlobTier, this.isBlockBlobAccessTier, rehydratePriority); Func taskGenerator = (taskId) => StartCopyAsync(taskId, destChannel, srcCloudBlob, destCloudBlob); RunTask(taskGenerator); @@ -759,7 +766,7 @@ private async Task StartCopyFromUri(long taskId, IStorageBlobManagement destChan } } - ValidateBlobTier(destBlob.BlobType, pageBlobTier, standardBlobTier, rehydratePriority); + ValidateBlobTier(destBlob.BlobType, pageBlobTier, this.isBlockBlobAccessTier, rehydratePriority); if (!destExist || this.ConfirmOverwrite(srcUri.AbsoluteUri.ToString(), destBlob.Uri.ToString())) { @@ -805,7 +812,7 @@ private async Task StartCopyFromUri(long taskId, IStorageBlobManagement destChan } if (destBlobType != null) { - ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(destBlobType), pageBlobTier, standardBlobTier, rehydratePriority); + ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(destBlobType), pageBlobTier, this.isBlockBlobAccessTier, rehydratePriority); } if (!destExist || this.ConfirmOverwrite(srcUri.AbsoluteUri.ToString(), destBlob.Uri.ToString())) @@ -817,9 +824,9 @@ private async Task StartCopyFromUri(long taskId, IStorageBlobManagement destChan { options.AccessTier = Util.ConvertAccessTier_Track1ToTrack2(pageBlobTier); } - else if (standardBlobTier != null || rehydratePriority != null) + else if (accesstier != null || rehydratePriority != null) { - options.AccessTier = Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier); + options.AccessTier = accesstier; options.RehydratePriority = Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority); } if (this.BlobTag != null) diff --git a/src/Storage/Storage/Blob/StorageCloudBlobCmdletBase.cs b/src/Storage/Storage/Blob/StorageCloudBlobCmdletBase.cs index df119ea1f900..63c9e6e3c16f 100644 --- a/src/Storage/Storage/Blob/StorageCloudBlobCmdletBase.cs +++ b/src/Storage/Storage/Blob/StorageCloudBlobCmdletBase.cs @@ -440,14 +440,14 @@ protected void ValidateBlobType(CloudBlob blob) } } - protected void ValidateBlobTier(BlobType type, PremiumPageBlobTier? pageBlobTier = null, StandardBlobTier? standardBlobTier = null, RehydratePriority? rehydratePriority = null) + protected void ValidateBlobTier(BlobType type, PremiumPageBlobTier? pageBlobTier = null, bool? isBlockBlobAccessTier = null, RehydratePriority? rehydratePriority = null) { if ((pageBlobTier != null) && (type != BlobType.PageBlob)) { throw new ArgumentOutOfRangeException("BlobType, PageBlobTier", String.Format("PremiumPageBlobTier can only be set to Page Blob. The Current BlobType is: {0}", type)); } - if ((standardBlobTier != null || rehydratePriority != null) + if (((isBlockBlobAccessTier != null && isBlockBlobAccessTier.Value) || rehydratePriority != null) && (type != BlobType.BlockBlob)) { throw new ArgumentOutOfRangeException("BlobType, StandardBlobTier/RehydratePriority", String.Format("StandardBlobTier and RehydratePriority can only be set to Block Blob. The Current BlobType is: {0}", type)); @@ -894,56 +894,6 @@ protected static IDictionary SetBlobMeta_Track2(IDictionary diff --git a/tools/StaticAnalysis/Exceptions/Az.Storage/BreakingChangeIssues.csv b/tools/StaticAnalysis/Exceptions/Az.Storage/BreakingChangeIssues.csv new file mode 100644 index 000000000000..db413ff737bd --- /dev/null +++ b/tools/StaticAnalysis/Exceptions/Az.Storage/BreakingChangeIssues.csv @@ -0,0 +1,5 @@ + "Module","ClassName","Target","Severity","ProblemId","Description","Remediation" + "Az.Storage","Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.CopyAzureStorageBlob","Copy-AzStorageBlob","0","2090","The ValidateNotNullOrEmpty attribute has been added to parameter 'StandardBlobTier' for cmdlet 'Copy-AzStorageBlob'.","Remove the ValidateNotNullOrEmpty attribute from parameter 'StandardBlobTier'." + "Az.Storage","Microsoft.WindowsAzure.Commands.Storage.Blob.SetAzureBlobContentCommand","Set-AzStorageBlobContent","0","2090","The ValidateNotNullOrEmpty attribute has been added to parameter 'StandardBlobTier' for cmdlet 'Set-AzStorageBlobContent'.","Remove the ValidateNotNullOrEmpty attribute from parameter 'StandardBlobTier'." + "Az.Storage","Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.StartAzureStorageBlobCopy","Start-AzStorageBlobCopy","0","2090","The ValidateNotNullOrEmpty attribute has been added to parameter 'StandardBlobTier' for cmdlet 'Start-AzStorageBlobCopy'.","Remove the ValidateNotNullOrEmpty attribute from parameter 'StandardBlobTier'." + \ No newline at end of file