Skip to content

Commit 7e5b324

Browse files
author
Nicholas King
committed
Implement and test Get-AzureRmDeletedWebApp and Restore-AzureRmDeletedWebApp
1 parent 6964d17 commit 7e5b324

File tree

13 files changed

+5935
-4
lines changed

13 files changed

+5935
-4
lines changed

src/ResourceManager/Websites/Commands.Websites.Test/Commands.Websites.Test.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
<Compile Include="Properties\AssemblyInfo.cs" />
6666
</ItemGroup>
6767
<ItemGroup>
68-
<None Include="app.config" />
6968
<None Include="MSSharedLibKey.snk" />
7069
<None Include="packages.config">
7170
<SubType>Designer</SubType>
@@ -133,6 +132,7 @@
133132
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestEditAndGetWebAppBackupConfigurationPiping.json">
134133
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
135134
</None>
135+
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestGetDeletedWebApp.json" />
136136
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestGetWebAppBackup.json">
137137
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
138138
</None>
@@ -142,6 +142,8 @@
142142
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestGetWebAppSnapshot.json">
143143
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
144144
</None>
145+
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestRestoreDeletedWebAppToExisting.json" />
146+
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestRestoreDeletedWebAppToNew.json" />
145147
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestRestoreWebAppSnapshot.json">
146148
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
147149
</None>

src/ResourceManager/Websites/Commands.Websites.Test/ScenarioTests/WebAppBackupRestoreTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,26 @@ public void TestRestoreWebAppSnapshot()
115115
{
116116
WebsitesController.NewInstance.RunPsTest(_logger, "Test-RestoreWebAppSnapshot");
117117
}
118+
119+
[Fact]
120+
[Trait(Category.AcceptanceType, Category.CheckIn)]
121+
public void TestGetDeletedWebApp()
122+
{
123+
WebsitesController.NewInstance.RunPsTest(_logger, "Test-GetDeletedWebApp");
124+
}
125+
126+
[Fact]
127+
[Trait(Category.AcceptanceType, Category.CheckIn)]
128+
public void TestRestoreDeletedWebAppToExisting()
129+
{
130+
WebsitesController.NewInstance.RunPsTest(_logger, "Test-RestoreDeletedWebAppToExisting");
131+
}
132+
133+
[Fact]
134+
[Trait(Category.AcceptanceType, Category.CheckIn)]
135+
public void TestRestoreDeletedWebAppToNew()
136+
{
137+
WebsitesController.NewInstance.RunPsTest(_logger, "Test-RestoreDeletedWebAppToNew");
138+
}
118139
}
119140
}

src/ResourceManager/Websites/Commands.Websites.Test/ScenarioTests/WebAppBackupRestoreTests.ps1

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ $snapshotRgName = 'onesdksnapshots'
1818
$snapshotAppName = 'onesdkpremapp2'
1919
$snapshotAppSlot = 'staging'
2020

21+
# Restoring a deleted web app requires an app to have a snapshot available.
22+
# Deploy a web app and wait at least an hour for a snapshot.
23+
# Update these global variables to re-record Test-RestoreDeletedWebApp.
24+
$undeleteRgName = 'ps8425'
25+
$undeleteAppName = 'ps1705'
26+
$undeleteSlot = 'testslot'
27+
2128
function Test-CreateNewWebAppBackup
2229
{
2330
$rgName = Get-ResourceGroupName
@@ -374,6 +381,103 @@ function Test-RestoreWebAppSnapshot
374381
$job | Wait-Job
375382
}
376383

384+
function Test-GetDeletedWebApp
385+
{
386+
# Setup
387+
$rgname = Get-ResourceGroupName
388+
$wname = Get-WebsiteName
389+
$slotName = "staging"
390+
$location = Get-WebLocation
391+
$whpName = Get-WebHostPlanName
392+
$tier = "Standard"
393+
394+
try
395+
{
396+
#Setup
397+
New-AzureRmResourceGroup -Name $rgname -Location $location
398+
New-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Location $location -Tier $tier
399+
New-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Location $location -AppServicePlan $whpName
400+
New-AzureRmWebAppSlot -ResourceGroupName $rgname -Name $wname -Slot $slotName -AppServicePlan $planName
401+
Remove-AzureRmWebAppSlot -ResourceGroupName $rgname -Name $wname -Slot $slotName -Force
402+
Remove-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Force
403+
404+
$deletedApp = Get-AzureRmDeletedWebApp -ResourceGroupName $rgname -Name $wname -Slot "Production"
405+
Assert-NotNull $deletedApp
406+
Assert-AreEqual $rgname $deletedApp.ResourceGroupName
407+
Assert-AreEqual $wname $deletedApp.Name
408+
409+
$deletedSlot = Get-AzureRmDeletedWebApp -ResourceGroupName $rgname -Name $wname -Slot $slotName
410+
Assert-NotNull $deletedSlot
411+
Assert-AreEqual $rgname $deletedSlot.ResourceGroupName
412+
Assert-AreEqual $wname $deletedSlot.Name
413+
Assert-AreEqual $slotName $deletedSlot.Slot
414+
}
415+
finally
416+
{
417+
# Cleanup
418+
Remove-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Force
419+
Remove-AzureRmResourceGroup -Name $rgname -Force
420+
}
421+
}
422+
423+
function Test-RestoreDeletedWebAppToExisting
424+
{
425+
# Setup
426+
$rgname = Get-ResourceGroupName
427+
$wname = Get-WebsiteName
428+
$slotName = "staging"
429+
$location = Get-WebLocation
430+
$whpName = Get-WebHostPlanName
431+
$tier = "Standard"
432+
433+
try
434+
{
435+
#Setup
436+
New-AzureRmResourceGroup -Name $rgname -Location $location
437+
New-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Location $location -Tier $tier
438+
New-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Location $location -AppServicePlan $whpName
439+
New-AzureRmWebAppSlot -ResourceGroupName $rgname -Name $wname -Slot $slotName -AppServicePlan $planName
440+
$deletedApp = Get-AzureRmDeletedWebApp -ResourceGroupName $undeleteRgName -Name $undeleteAppName -Slot "Production"
441+
$deletedSlot = Get-AzureRmDeletedWebApp -ResourceGroupName $undeleteRgName -Name $undeleteAppName -Slot $undeleteSlot
442+
Restore-AzureRmDeletedWebApp $deletedApp -TargetResourceGroupName $rgname -TargetName $wname -Force
443+
Restore-AzureRmDeletedWebApp $deletedSlot -TargetResourceGroupName $rgname -TargetName $wname -TargetSlot $slotName -Force
444+
}
445+
finally
446+
{
447+
# Cleanup
448+
Remove-AzureRmWebAppSlot -ResourceGroupName $rgname -Name $wname -Slot $slotName -Force
449+
Remove-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Force
450+
Remove-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Force
451+
Remove-AzureRmResourceGroup -Name $rgname -Force
452+
}
453+
}
454+
455+
function Test-RestoreDeletedWebAppToNew
456+
{
457+
# Setup
458+
$rgname = Get-ResourceGroupName
459+
$location = Get-WebLocation
460+
$whpName = Get-WebHostPlanName
461+
$tier = "Standard"
462+
463+
try
464+
{
465+
#Setup
466+
New-AzureRmResourceGroup -Name $rgname -Location $location
467+
New-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Location $location -Tier $tier
468+
$deletedApp = Get-AzureRmDeletedWebApp -ResourceGroupName $undeleteRgName -Name $undeleteAppName -Slot "Production"
469+
$job = $deletedApp | Restore-AzureRmDeletedWebApp -TargetResourceGroupName $rgname -TargetAppServicePlanName $whpName -Force -AsJob
470+
$job | Wait-Job
471+
}
472+
finally
473+
{
474+
# Cleanup
475+
Remove-AzureRmWebApp -ResourceGroupName $rgname -Name $undeleteAppName -Force
476+
Remove-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Force
477+
Remove-AzureRmResourceGroup -Name $rgname -Force
478+
}
479+
}
480+
377481
# Utility functions
378482

379483
# Creates a new web app

src/ResourceManager/Websites/Commands.Websites.Test/SessionRecords/Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests/TestGetDeletedWebApp.json

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

src/ResourceManager/Websites/Commands.Websites.Test/SessionRecords/Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests/TestRestoreDeletedWebAppToExisting.json

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

src/ResourceManager/Websites/Commands.Websites.Test/SessionRecords/Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests/TestRestoreDeletedWebAppToNew.json

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

src/ResourceManager/Websites/Commands.Websites/Az.Websites.psd1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ CmdletsToExport = 'Get-AzAppServicePlan', 'Set-AzAppServicePlan',
9595
'New-AzWebApp', 'Remove-AzWebAppBackup',
9696
'Reset-AzWebAppPublishingProfile', 'Restart-AzWebApp',
9797
'Set-AzWebApp', 'Start-AzWebApp', 'Stop-AzWebApp',
98-
'Get-AzWebAppSnapshot', 'Restore-AzWebAppSnapshot'
98+
'Get-AzWebAppSnapshot', 'Restore-AzWebAppSnapshot',
99+
'Get-AzDeletedWebApp'
99100

100101
# Variables to export from this module
101102
# VariablesToExport = @()

src/ResourceManager/Websites/Commands.Websites/AzureRM.Websites.psd1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ CmdletsToExport = 'Get-AzureRmAppServicePlan', 'Set-AzureRmAppServicePlan',
9595
'New-AzureRmWebApp', 'Remove-AzureRmWebAppBackup',
9696
'Reset-AzureRmWebAppPublishingProfile', 'Restart-AzureRmWebApp',
9797
'Set-AzureRmWebApp', 'Start-AzureRmWebApp', 'Stop-AzureRmWebApp',
98-
'Get-AzureRmWebAppSnapshot', 'Restore-AzureRmWebAppSnapshot'
98+
'Get-AzureRmWebAppSnapshot', 'Restore-AzureRmWebAppSnapshot',
99+
'Get-AzureRmDeletedWebApp', 'Restore-AzureRmDeletedWebApp'
99100

100101
# Variables to export from this module
101102
# VariablesToExport = @()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
using System;
16+
17+
namespace Microsoft.Azure.Commands.WebApps.Cmdlets.WebApps
18+
{
19+
public class AzureDeletedWebApp
20+
{
21+
public int DeletedSiteId { get; set; }
22+
23+
public string SubscriptionId { get; set; }
24+
25+
public string ResourceGroupName { get; set; }
26+
27+
public string Name { get; set; }
28+
29+
public string Slot { get; set; }
30+
31+
public DateTime DeletionTime { get; set; }
32+
}
33+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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+
16+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
17+
using Microsoft.Azure.Commands.WebApps.Models;
18+
using Microsoft.Azure.Management.WebSites.Models;
19+
using System;
20+
using System.Collections.Generic;
21+
using System.Linq;
22+
using System.Management.Automation;
23+
24+
namespace Microsoft.Azure.Commands.WebApps.Cmdlets.WebApps
25+
{
26+
/// <summary>
27+
/// Gets the deleted Azure Web Apps in a subscription
28+
/// </summary>
29+
[Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "DeletedWebApp"), OutputType(typeof(AzureDeletedWebApp))]
30+
public class GetAzureDeletedWebApp : WebAppBaseClientCmdLet
31+
{
32+
[Parameter(Position = 0, Mandatory = false, HelpMessage = "The name of the resource group.")]
33+
[ResourceGroupCompleter]
34+
[ValidateNotNullOrEmpty]
35+
public string ResourceGroupName { get; set; }
36+
37+
[Parameter(Position = 1, Mandatory = false, HelpMessage = "The name of the web app.")]
38+
[ValidateNotNullOrEmpty]
39+
public string Name { get; set; }
40+
41+
[Parameter(Position = 2, Mandatory = false, HelpMessage = "The name of the web app slot.")]
42+
[ValidateNotNullOrEmpty]
43+
public string Slot { get; set; }
44+
45+
public override void ExecuteCmdlet()
46+
{
47+
base.ExecuteCmdlet();
48+
IEnumerable<AzureDeletedWebApp> deletedSites = WebsitesClient.GetDeletedSites()
49+
.Where(ds => ds.DeletedSiteId.HasValue)
50+
.Select(ds =>
51+
new AzureDeletedWebApp()
52+
{
53+
DeletedSiteId = ds.DeletedSiteId.Value,
54+
DeletionTime = DateTime.Parse(ds.DeletedTimestamp),
55+
SubscriptionId = DefaultContext.Subscription.Id,
56+
ResourceGroupName = ds.ResourceGroup,
57+
Name = ds.DeletedSiteName,
58+
Slot = ds.Slot
59+
}
60+
);
61+
62+
// Filter out deleted sites older than 30 days.
63+
// They can't be restored and eventually will not be returned by the GetDeletedSites API.
64+
deletedSites = deletedSites.Where(ds => ds.DeletionTime >= DateTime.UtcNow.AddDays(-30)).OrderBy(ds => ds.DeletionTime);
65+
66+
if (!string.IsNullOrEmpty(ResourceGroupName))
67+
{
68+
69+
deletedSites = deletedSites.Where(ds => string.Equals(ResourceGroupName, ds.ResourceGroupName, StringComparison.InvariantCultureIgnoreCase));
70+
}
71+
if (!string.IsNullOrEmpty(Name))
72+
{
73+
deletedSites = deletedSites.Where(ds => string.Equals(Name, ds.Name, StringComparison.InvariantCultureIgnoreCase));
74+
}
75+
if (!string.IsNullOrEmpty(Slot))
76+
{
77+
deletedSites = deletedSites.Where(ds => string.Equals(Slot, ds.Slot, StringComparison.InvariantCultureIgnoreCase));
78+
}
79+
80+
WriteObject(deletedSites, true);
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)