Skip to content

Commit 440b4eb

Browse files
authored
[Storage] Support Point in Time Restore (#12799)
* [Storage] Support Point in Time Restore * [Storage] Add breaking change warning for remove LastEnabledTime * fix CI failure * Update change log per review comment
1 parent e3c1759 commit 440b4eb

26 files changed

+3870
-10
lines changed

src/Storage/Storage.Management.Test/ScenarioTests/StorageBlobTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,12 @@ public void TestStorageBlobORS()
7272
{
7373
TestController.NewInstance.RunPsTest(_logger, "Test-StorageBlobORS");
7474
}
75+
76+
[Fact]
77+
[Trait(Category.AcceptanceType, Category.CheckIn)]
78+
public void TestStorageBlobRestore()
79+
{
80+
TestController.NewInstance.RunPsTest(_logger, "Test-StorageBlobRestore");
81+
}
7582
}
7683
}

src/Storage/Storage.Management.Test/ScenarioTests/StorageBlobTests.ps1

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,66 @@ function Test-StorageBlobServiceProperties
434434
}
435435
}
436436

437+
<#
438+
.SYNOPSIS
439+
Test StorageAccount Blob Restore
440+
.DESCRIPTION
441+
SmokeTest
442+
#>
443+
function Test-StorageBlobRestore
444+
{
445+
# Setup
446+
$rgname = Get-StorageManagementTestResourceName;
437447

448+
try
449+
{
450+
# Test
451+
$stoname = 'sto' + $rgname;
452+
$stotype = 'Standard_LRS';
453+
$loc = Get-ProviderLocation ResourceManagement;
454+
$kind = 'StorageV2'
455+
456+
Write-Verbose "RGName: $rgname | Loc: $loc"
457+
New-AzResourceGroup -Name $rgname -Location $loc;
458+
459+
$loc = Get-ProviderLocation_Stage ResourceManagement;
460+
New-AzStorageAccount -ResourceGroupName $rgname -Name $stoname -Location $loc -Type $stotype -Kind $kind
461+
$stos = Get-AzStorageAccount -ResourceGroupName $rgname;
462+
463+
# Enable Blob Delete Retension Policy, Enable Changefeed, then enabled blob restore policy, then get blob service proeprties and check the setting
464+
Enable-AzStorageBlobDeleteRetentionPolicy -ResourceGroupName $rgname -StorageAccountName $stoname -RetentionDays 5
465+
Update-AzStorageBlobServiceProperty -ResourceGroupName $rgname -StorageAccountName $stoname -EnableChangeFeed $true
466+
# If record, need sleep before enable the blob restore policy, or will get server error
467+
#sleep 100
468+
Enable-AzStorageBlobRestorePolicy -ResourceGroupName $rgname -StorageAccountName $stoname -RestoreDays 4
469+
$property = Get-AzStorageBlobServiceProperty -ResourceGroupName $rgname -StorageAccountName $stoname
470+
Assert-AreEqual $true $property.ChangeFeed.Enabled
471+
Assert-AreEqual $true $property.DeleteRetentionPolicy.Enabled
472+
Assert-AreEqual 5 $property.DeleteRetentionPolicy.Days
473+
Assert-AreEqual $true $property.RestorePolicy.Enabled
474+
Assert-AreEqual 4 $property.RestorePolicy.Days
475+
476+
# restore blobs by -asjob
477+
$range1 = New-AzStorageBlobRangeToRestore -StartRange container1/blob1 -EndRange container2/blob2
478+
$range2 = New-AzStorageBlobRangeToRestore -StartRange container3/blob3 -EndRange ""
479+
$job = Restore-AzStorageBlobRange -ResourceGroupName $rgname -StorageAccountName $stoname -TimeToRestore (Get-Date).AddSeconds(-1) -BlobRestoreRange $range1,$range2 -asjob
480+
481+
# Get Storage Account with Blob Restore Status
482+
$stos = Get-AzStorageAccount -ResourceGroupName $rgname -StorageAccountName $stoname -IncludeBlobRestoreStatus
483+
484+
# wait for restore job finish, and check Blob Restore Status in Storage Account
485+
$job | Wait-Job
486+
$stos = Get-AzStorageAccount -ResourceGroupName $rgname -StorageAccountName $stoname -IncludeBlobRestoreStatus
487+
Assert-AreEqual "Complete" $stos.BlobRestoreStatus.Status
438488

489+
Remove-AzStorageAccount -Force -ResourceGroupName $rgname -Name $stoname;
490+
}
491+
finally
492+
{
493+
# Cleanup
494+
Clean-ResourceGroup $rgname
495+
}
496+
}
439497

440498
<#
441499
.SYNOPSIS

src/Storage/Storage.Management.Test/SessionRecords/Microsoft.Azure.Commands.Management.Storage.Test.ScenarioTests.StorageBlobTests/TestStorageBlobRestore.json

Lines changed: 2199 additions & 0 deletions
Large diffs are not rendered by default.

src/Storage/Storage.Management.Test/Storage.Management.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<PackageReference Include="Azure.Storage.Files.DataLake" Version="12.3.0-preview.2" />
1616
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.3.0-preview.2" />
1717
<PackageReference Include="Azure.Storage.Queues" Version="12.4.0-preview.6" />
18-
<PackageReference Include="Microsoft.Azure.Management.Storage" Version="17.1.0" />
18+
<PackageReference Include="Microsoft.Azure.Management.Storage" Version="17.2.0" />
1919
</ItemGroup>
2020

2121
</Project>

src/Storage/Storage.Management/Az.Storage.psd1

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ CmdletsToExport = 'Get-AzStorageAccount', 'Get-AzStorageAccountKey',
170170
'New-AzStorageObjectReplicationPolicyRule',
171171
'Set-AzStorageObjectReplicationPolicy',
172172
'Get-AzStorageObjectReplicationPolicy',
173-
'Remove-AzStorageObjectReplicationPolicy'
173+
'Remove-AzStorageObjectReplicationPolicy',
174+
'Enable-AzStorageBlobRestorePolicy','Disable-AzStorageBlobRestorePolicy',
175+
'New-AzStorageBlobRangeToRestore','Restore-AzStorageBlobRange'
174176

175177
# Variables to export from this module
176178
# VariablesToExport = @()
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.Management.Storage
16+
{
17+
using Microsoft.Azure.Commands.Management.Storage.Models;
18+
using Microsoft.Azure.Management.Storage;
19+
using Microsoft.Azure.Management.Storage.Models;
20+
using System;
21+
using System.Collections.Generic;
22+
using System.Management.Automation;
23+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
24+
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
25+
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
26+
27+
/// <summary>
28+
/// Modify Azure Storage service properties
29+
/// </summary>
30+
[CmdletOutputBreakingChange(typeof(PSRestorePolicy), ChangeDescription = "The deprecated proeprty LastEnabledTime will be removed in a future release.")]
31+
[Cmdlet("Disable", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + StorageBlobRestorePolicy, SupportsShouldProcess = true, DefaultParameterSetName = AccountNameParameterSet), OutputType(typeof(PSRestorePolicy))]
32+
public class DisableAzStorageBlobRestorePolicyCommand : StorageBlobBaseCmdlet
33+
{
34+
35+
/// <summary>
36+
/// AccountName Parameter Set
37+
/// </summary>
38+
private const string AccountNameParameterSet = "AccountName";
39+
40+
/// <summary>
41+
/// Account object parameter set
42+
/// </summary>
43+
private const string AccountObjectParameterSet = "AccountObject";
44+
45+
/// <summary>
46+
/// BlobServiceProperties ResourceId parameter set
47+
/// </summary>
48+
private const string PropertiesResourceIdParameterSet = "BlobServicePropertiesResourceId";
49+
50+
[Parameter(
51+
Position = 0,
52+
Mandatory = true,
53+
HelpMessage = "Resource Group Name.",
54+
ParameterSetName = AccountNameParameterSet)]
55+
[ResourceGroupCompleter]
56+
[ValidateNotNullOrEmpty]
57+
public string ResourceGroupName { get; set; }
58+
59+
[Parameter(
60+
Position = 1,
61+
Mandatory = true,
62+
HelpMessage = "Storage Account Name.",
63+
ParameterSetName = AccountNameParameterSet)]
64+
[ResourceNameCompleter("Microsoft.Storage/storageAccounts", nameof(ResourceGroupName))]
65+
[Alias(AccountNameAlias, NameAlias)]
66+
[ValidateNotNullOrEmpty]
67+
public string StorageAccountName { get; set; }
68+
69+
[Parameter(Mandatory = true,
70+
HelpMessage = "Storage account object",
71+
ValueFromPipeline = true,
72+
ParameterSetName = AccountObjectParameterSet)]
73+
[ValidateNotNullOrEmpty]
74+
public PSStorageAccount StorageAccount { get; set; }
75+
76+
[Parameter(
77+
Position = 0,
78+
Mandatory = true,
79+
ValueFromPipelineByPropertyName = true,
80+
HelpMessage = "Input a Storage account Resource Id, or a Blob service properties Resource Id.",
81+
ParameterSetName = PropertiesResourceIdParameterSet)]
82+
[ValidateNotNullOrEmpty]
83+
public string ResourceId { get; set; }
84+
85+
[Parameter(Mandatory = false, HelpMessage = "Display ServiceProperties")]
86+
public SwitchParameter PassThru { get; set; }
87+
88+
public override void ExecuteCmdlet()
89+
{
90+
base.ExecuteCmdlet();
91+
if (ShouldProcess("BlobRestorePolicy", "Disable"))
92+
{
93+
switch (ParameterSetName)
94+
{
95+
case AccountObjectParameterSet:
96+
this.ResourceGroupName = StorageAccount.ResourceGroupName;
97+
this.StorageAccountName = StorageAccount.StorageAccountName;
98+
break;
99+
case PropertiesResourceIdParameterSet:
100+
ResourceIdentifier blobServicePropertiesResource = new ResourceIdentifier(ResourceId);
101+
this.ResourceGroupName = blobServicePropertiesResource.ResourceGroupName;
102+
this.StorageAccountName = PSBlobServiceProperties.GetStorageAccountNameFromResourceId(ResourceId);
103+
break;
104+
default:
105+
// For AccountNameParameterSet, the ResourceGroupName and StorageAccountName can get from input directly
106+
break;
107+
}
108+
BlobServiceProperties serviceProperties = this.StorageClient.BlobServices.GetServiceProperties( this.ResourceGroupName, this.StorageAccountName);
109+
110+
serviceProperties.RestorePolicy = new RestorePolicyProperties();
111+
serviceProperties.RestorePolicy.Enabled = false;
112+
serviceProperties.RestorePolicy.Days = null;
113+
114+
serviceProperties = this.StorageClient.BlobServices.SetServiceProperties(this.ResourceGroupName, this.StorageAccountName, serviceProperties);
115+
116+
if (PassThru)
117+
{
118+
WriteObject(new PSRestorePolicy(serviceProperties.RestorePolicy));
119+
}
120+
121+
}
122+
}
123+
}
124+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.Management.Storage
16+
{
17+
using Microsoft.Azure.Commands.Management.Storage.Models;
18+
using Microsoft.Azure.Management.Storage;
19+
using Microsoft.Azure.Management.Storage.Models;
20+
using System;
21+
using System.Collections.Generic;
22+
using System.Management.Automation;
23+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
24+
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
25+
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
26+
27+
/// <summary>
28+
/// Modify Azure Storage service properties
29+
/// </summary>
30+
[CmdletOutputBreakingChange(typeof(PSRestorePolicy), ChangeDescription = "The deprecated proeprty LastEnabledTime will be removed in a future release.")]
31+
[Cmdlet("Enable", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + StorageBlobRestorePolicy, DefaultParameterSetName = AccountNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSRestorePolicy))]
32+
public class EnableAzStorageBlobRestorePolicyCommand : StorageBlobBaseCmdlet
33+
{
34+
35+
/// <summary>
36+
/// AccountName Parameter Set
37+
/// </summary>
38+
private const string AccountNameParameterSet = "AccountName";
39+
40+
/// <summary>
41+
/// Account object parameter set
42+
/// </summary>
43+
private const string AccountObjectParameterSet = "AccountObject";
44+
45+
/// <summary>
46+
/// BlobServiceProperties ResourceId parameter set
47+
/// </summary>
48+
private const string PropertiesResourceIdParameterSet = "BlobServicePropertiesResourceId";
49+
50+
[Parameter(
51+
Position = 0,
52+
Mandatory = true,
53+
HelpMessage = "Resource Group Name.",
54+
ParameterSetName = AccountNameParameterSet)]
55+
[ResourceGroupCompleter]
56+
[ValidateNotNullOrEmpty]
57+
public string ResourceGroupName { get; set; }
58+
59+
[Parameter(
60+
Position = 1,
61+
Mandatory = true,
62+
HelpMessage = "Storage Account Name.",
63+
ParameterSetName = AccountNameParameterSet)]
64+
[ResourceNameCompleter("Microsoft.Storage/storageAccounts", nameof(ResourceGroupName))]
65+
[Alias(AccountNameAlias, NameAlias)]
66+
[ValidateNotNullOrEmpty]
67+
public string StorageAccountName { get; set; }
68+
69+
[Parameter(Mandatory = true,
70+
HelpMessage = "Storage account object",
71+
ValueFromPipeline = true,
72+
ParameterSetName = AccountObjectParameterSet)]
73+
[ValidateNotNullOrEmpty]
74+
public PSStorageAccount StorageAccount { get; set; }
75+
76+
[Parameter(
77+
Position = 0,
78+
Mandatory = true,
79+
ValueFromPipelineByPropertyName = true,
80+
HelpMessage = "Input a Storage account Resource Id, or a Blob service properties Resource Id.",
81+
ParameterSetName = PropertiesResourceIdParameterSet)]
82+
[ValidateNotNullOrEmpty]
83+
public string ResourceId { get; set; }
84+
85+
[Parameter(Mandatory = true, HelpMessage = "Sets the number of days for the blob can be restored..")]
86+
[Alias("Days")]
87+
public int RestoreDays { get; set; }
88+
89+
[Parameter(Mandatory = false, HelpMessage = "Display ServiceProperties")]
90+
public SwitchParameter PassThru { get; set; }
91+
92+
public override void ExecuteCmdlet()
93+
{
94+
base.ExecuteCmdlet();
95+
if (ShouldProcess("BlobRestorePolicy", "Enable"))
96+
{
97+
switch (ParameterSetName)
98+
{
99+
case AccountObjectParameterSet:
100+
this.ResourceGroupName = StorageAccount.ResourceGroupName;
101+
this.StorageAccountName = StorageAccount.StorageAccountName;
102+
break;
103+
case PropertiesResourceIdParameterSet:
104+
ResourceIdentifier blobServicePropertiesResource = new ResourceIdentifier(ResourceId);
105+
this.ResourceGroupName = blobServicePropertiesResource.ResourceGroupName;
106+
this.StorageAccountName = PSBlobServiceProperties.GetStorageAccountNameFromResourceId(ResourceId);
107+
break;
108+
default:
109+
// For AccountNameParameterSet, the ResourceGroupName and StorageAccountName can get from input directly
110+
break;
111+
}
112+
BlobServiceProperties serviceProperties = this.StorageClient.BlobServices.GetServiceProperties( this.ResourceGroupName, this.StorageAccountName);
113+
114+
serviceProperties.RestorePolicy = new RestorePolicyProperties();
115+
serviceProperties.RestorePolicy.Enabled = true;
116+
serviceProperties.RestorePolicy.Days = RestoreDays;
117+
118+
serviceProperties = this.StorageClient.BlobServices.SetServiceProperties(this.ResourceGroupName, this.StorageAccountName, serviceProperties);
119+
120+
if (PassThru)
121+
{
122+
WriteObject(new PSRestorePolicy(serviceProperties.RestorePolicy));
123+
}
124+
125+
}
126+
}
127+
}
128+
}

src/Storage/Storage.Management/Blob/GetAzureStorageBlobServiceProperties.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ namespace Microsoft.Azure.Commands.Management.Storage
2222
using System.Management.Automation;
2323
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2424
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
25+
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
2526

2627
/// <summary>
2728
/// Modify Azure Storage service properties
2829
/// </summary>
30+
[CmdletOutputBreakingChange(typeof(PSBlobServiceProperties), ChangeDescription = "The deprecated proeprty RestorePolicy.LastEnabledTime will be removed in a future release.")]
2931
[Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + StorageBlobServiceProperty, DefaultParameterSetName = AccountNameParameterSet), OutputType(typeof(PSBlobServiceProperties))]
3032
public class GetAzStorageBlobServicePropertyCommand : StorageBlobBaseCmdlet
3133
{

src/Storage/Storage.Management/Blob/StorageBlobBaseCmdlet.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public abstract class StorageBlobBaseCmdlet : AzureRMCmdlet
3737
protected const string StorageContainerLeaseNounStr = StorageContainerNounStr + "Lease";
3838
protected const string StorageBlobServiceProperty = "StorageBlobServiceProperty";
3939
protected const string StorageBlobDeleteRetentionPolicy = "StorageBlobDeleteRetentionPolicy";
40+
protected const string StorageBlobRestorePolicy = "StorageBlobRestorePolicy";
4041

4142
public const string StorageAccountResourceType = "Microsoft.Storage/storageAccounts";
4243

src/Storage/Storage.Management/Blob/UpdateAzureStorageBlobServiceProperties.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ namespace Microsoft.Azure.Commands.Management.Storage
2222
using System.Management.Automation;
2323
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2424
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
25+
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
2526

2627
/// <summary>
2728
/// Modify Azure Storage service properties
2829
/// </summary>
30+
[CmdletOutputBreakingChange(typeof(PSBlobServiceProperties), ChangeDescription = "The deprecated proeprty RestorePolicy.LastEnabledTime will be removed in a future release.")]
2931
[Cmdlet("Update", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + StorageBlobServiceProperty, SupportsShouldProcess = true, DefaultParameterSetName = AccountNameParameterSet), OutputType(typeof(PSBlobServiceProperties))]
3032
public class UpdateAzStorageBlobServicePropertyCommand : StorageBlobBaseCmdlet
3133
{

0 commit comments

Comments
 (0)