Skip to content

Commit 9f6a5f9

Browse files
author
Maddie Clayton
authored
Merge pull request #8376 from dealaus/PortShortTermRetentionToMaster
[SQL] Port SqlDatabaseBackupShortTermRetentionPolicy preview cmdlets to master
2 parents 1eea33b + 688866f commit 9f6a5f9

15 files changed

+3664
-0
lines changed

src/Accounts/Accounts/AzureRmAlias/Mappings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,8 @@
22002200
"New-AzSqlDatabaseImport": "New-AzureRmSqlDatabaseImport",
22012201
"Get-AzSqlDatabaseGeoBackupPolicy": "Get-AzureRmSqlDatabaseGeoBackupPolicy",
22022202
"Set-AzSqlDatabaseGeoBackupPolicy": "Set-AzureRmSqlDatabaseGeoBackupPolicy",
2203+
"Get-AzSqlDatabaseBackupShortTermRetentionPolicy": "Get-AzureRmSqlDatabaseBackupShortTermRetentionPolicy",
2204+
"Set-AzSqlDatabaseBackupShortTermRetentionPolicy": "Set-AzureRmSqlDatabaseBackupShortTermRetentionPolicy",
22032205
"Get-AzSqlDatabaseBackupLongTermRetentionPolicy": "Get-AzureRmSqlDatabaseBackupLongTermRetentionPolicy",
22042206
"Set-AzSqlDatabaseBackupLongTermRetentionPolicy": "Set-AzureRmSqlDatabaseBackupLongTermRetentionPolicy",
22052207
"Get-AzSqlDatabaseLongTermRetentionBackup": "Get-AzureRmSqlDatabaseLongTermRetentionBackup",

src/Sql/Sql.Test/ScenarioTests/DatabaseBackupTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,12 @@ public void TestRemoveDatabaseRestorePoint()
135135
RunPowerShellTest("Test-RemoveDatabaseRestorePoint");
136136
}
137137
}
138+
139+
[Fact]
140+
[Trait(Category.AcceptanceType, Category.CheckIn)]
141+
public void TestShortTermRetentionPolicy()
142+
{
143+
RunPowerShellTest("Test-ShortTermRetentionPolicy");
144+
}
138145
}
139146
}

src/Sql/Sql.Test/ScenarioTests/DatabaseBackupTests.ps1

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,4 +350,72 @@ function Test-RemoveDatabaseRestorePoint
350350
{
351351
Remove-ResourceGroupForTest $rg
352352
}
353+
}
354+
355+
function Test-ShortTermRetentionPolicy
356+
{
357+
# Setup
358+
$location = Get-Location "Microsoft.Sql" "servers" "West US 2"
359+
$rg = Create-ResourceGroupForTest $location
360+
$server = Create-ServerForTest $rg $location
361+
362+
# Not divisible by 7, client should error
363+
$invalidRetention = 20
364+
365+
try
366+
{
367+
# Create db with default values
368+
$databaseName = Get-DatabaseName
369+
$db = New-AzureRmSqlDatabase -ResourceGroupName $rg.ResourceGroupName -ServerName $server.ServerName -DatabaseName $databaseName
370+
371+
# Test default parameter set
372+
$retention = 28
373+
$policy = Set-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -ResourceGroupName $rg.ResourceGroupName -ServerName $server.ServerName -DatabaseName $databaseName -RetentionDays $retention
374+
Assert-AreEqual $policy.Count 1
375+
Assert-AreEqual $retention $policy[0].RetentionDays
376+
$policy = Get-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -ResourceGroupName $rg.ResourceGroupName -ServerName $server.ServerName -DatabaseName $databaseName
377+
Assert-AreEqual $policy.Count 1
378+
Assert-AreEqual $retention $policy[0].RetentionDays
379+
380+
# Test InputObject
381+
$retention = 21
382+
$policy = Set-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -AzureSqlDatabase $db -RetentionDays $retention
383+
Assert-AreEqual 1 $policy.Count
384+
Assert-AreEqual $retention $policy[0].RetentionDays
385+
$policy = Get-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -AzureSqlDatabase $db
386+
Assert-AreEqual 1 $policy.Count
387+
Assert-AreEqual $retention $policy[0].RetentionDays
388+
389+
# Test ResourceId
390+
$retention = 14
391+
$resourceId = $db.ResourceId + "/backupShortTermRetentionPolicies/default"
392+
$policy = Set-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -ResourceId $resourceId -RetentionDays $retention
393+
Assert-AreEqual 1 $policy.Count
394+
Assert-AreEqual $retention $policy[0].RetentionDays
395+
$policy = Get-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -ResourceId $resourceId
396+
Assert-AreEqual 1 $policy.Count
397+
Assert-AreEqual $retention $policy[0].RetentionDays
398+
399+
# Test Piping
400+
$retention = 7
401+
$policy = $db | Set-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -RetentionDays $retention
402+
Assert-AreEqual 1 $policy.Count
403+
Assert-AreEqual $retention $policy[0].RetentionDays
404+
$policy = $db | Get-AzureRmSqlDatabaseBackupShortTermRetentionPolicy
405+
Assert-AreEqual 1 $policy.Count
406+
Assert-AreEqual $retention $policy[0].RetentionDays
407+
408+
# Test client-side error handling
409+
try {
410+
$db | Set-AzureRmSqlDatabaseBackupShortTermRetentionPolicy -RetentionDays $invalidRetention
411+
}
412+
catch [System.Management.Automation.PSArgumentException] {
413+
# We expect an error here
414+
Assert-AreEqual $_.Count 1
415+
}
416+
}
417+
finally
418+
{
419+
Remove-ResourceGroupForTest $rg
420+
}
353421
}

src/Sql/Sql.Test/SessionRecords/Microsoft.Azure.Commands.Sql.Test.ScenarioTests.DatabaseBackupTests/TestShortTermRetentionPolicy.json

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

src/Sql/Sql/Az.Sql.psd1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ CmdletsToExport = 'Get-AzSqlDatabaseTransparentDataEncryption',
122122
'Get-AzSqlDatabaseImportExportStatus', 'New-AzSqlDatabaseExport',
123123
'New-AzSqlDatabaseImport', 'Get-AzSqlDatabaseGeoBackupPolicy',
124124
'Set-AzSqlDatabaseGeoBackupPolicy',
125+
'Get-AzSqlDatabaseBackupShortTermRetentionPolicy',
126+
'Set-AzSqlDatabaseBackupShortTermRetentionPolicy',
125127
'Get-AzSqlDatabaseBackupLongTermRetentionPolicy',
126128
'Set-AzSqlDatabaseBackupLongTermRetentionPolicy',
127129
'Get-AzSqlDatabaseLongTermRetentionBackup',

src/Sql/Sql/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21+
* Add Get/Set AzSqlDatabaseBackupShortTermRetentionPolicy
2122

2223
## Version 1.1.0
2324
* Update incorrect online help URLs
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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+
using System.Collections.Generic;
17+
using Microsoft.Azure.Commands.Sql.Backup.Services;
18+
using Microsoft.Azure.Commands.Sql.Common;
19+
using System.Management.Automation;
20+
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
21+
using Microsoft.Azure.Commands.Sql.Backup.Model;
22+
using Microsoft.Azure.Commands.Sql.Database.Model;
23+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
24+
25+
namespace Microsoft.Azure.Commands.Sql.Backup.Cmdlet
26+
{
27+
public abstract class AzureSqlDatabaseBackupShortTermRetentionPolicyCmdletBase : AzureSqlCmdletBase<IEnumerable<AzureSqlDatabaseBackupShortTermRetentionPolicyModel>, AzureSqlDatabaseBackupAdapter>
28+
{
29+
/// <summary>
30+
/// The expected number of segments in a short term retention policy resource id.
31+
/// </summary>
32+
private const int BackupShortTermRetentionPolicyResourceIdSegmentsLength = 12;
33+
34+
/// <summary>
35+
/// Parameter set with ResourceGroup name, Server name and Database name.
36+
/// </summary>
37+
protected const string PolicyByResourceServerDatabaseSet = "PolicyByResourceServerDatabaseSet";
38+
39+
/// <summary>
40+
/// Parameter set for using a Database Input Object.
41+
/// </summary>
42+
private const string PolicyByInputObjectSet = "PolicyByInputObjectSet";
43+
44+
/// <summary>
45+
/// Parameter set for using a resource Id.
46+
/// </summary>
47+
private const string PolicyByResourceIdSet = "PolicyByResourceIdSet";
48+
49+
/// <summary>
50+
/// Gets or sets the Database object to get the policy for.
51+
/// </summary>
52+
[Parameter(
53+
ParameterSetName = PolicyByInputObjectSet,
54+
Mandatory = true,
55+
ValueFromPipeline = true,
56+
HelpMessage = "The database object to get the policy for.")]
57+
[ValidateNotNullOrEmpty]
58+
[Alias("AzureSqlDatabase")]
59+
public AzureSqlDatabaseModel AzureSqlDatabaseObject { get; set; }
60+
61+
/// <summary>
62+
/// Gets or sets the Database object to get the policy for.
63+
/// </summary>
64+
[Parameter(
65+
ParameterSetName = PolicyByResourceIdSet,
66+
Mandatory = true,
67+
ValueFromPipelineByPropertyName = true,
68+
HelpMessage = "The short term retention policy resource Id.")]
69+
[ValidateNotNullOrEmpty]
70+
public string ResourceId { get; set; }
71+
72+
/// <summary>
73+
/// Gets or sets the name of the resource group to use.
74+
/// </summary>
75+
[Parameter(
76+
ParameterSetName = PolicyByResourceServerDatabaseSet,
77+
Mandatory = true,
78+
ValueFromPipelineByPropertyName = true,
79+
Position = 0,
80+
HelpMessage = "The name of the resource group.")]
81+
[ResourceGroupCompleter]
82+
[ValidateNotNullOrEmpty]
83+
public override string ResourceGroupName { get; set; }
84+
85+
/// <summary>
86+
/// Gets or sets the name of the database server to use.
87+
/// </summary>
88+
[Parameter(ParameterSetName = PolicyByResourceServerDatabaseSet,
89+
Mandatory = true,
90+
ValueFromPipelineByPropertyName = true,
91+
Position = 1,
92+
HelpMessage = "The name of the Azure SQL Server the database is in.")]
93+
[ValidateNotNullOrEmpty]
94+
public string ServerName { get; set; }
95+
96+
/// <summary>
97+
/// Gets or sets the name of the database to use.
98+
/// </summary>
99+
[Parameter(
100+
ParameterSetName = PolicyByResourceServerDatabaseSet,
101+
Mandatory = true,
102+
ValueFromPipelineByPropertyName = true,
103+
Position = 2,
104+
HelpMessage = "The name of the Azure SQL Database to use.")]
105+
[ValidateNotNullOrEmpty]
106+
public string DatabaseName { get; set; }
107+
108+
/// <summary>
109+
/// Initializes the adapter
110+
/// </summary>
111+
/// <param name="subscription">The subscription to operate on</param>
112+
/// <returns></returns>
113+
protected override AzureSqlDatabaseBackupAdapter InitModelAdapter(IAzureSubscription subscription)
114+
{
115+
return new AzureSqlDatabaseBackupAdapter(DefaultProfile.DefaultContext);
116+
}
117+
118+
public override void ExecuteCmdlet()
119+
{
120+
if (AzureSqlDatabaseObject != null)
121+
{
122+
this.ResourceGroupName = AzureSqlDatabaseObject.ResourceGroupName;
123+
this.ServerName = AzureSqlDatabaseObject.ServerName;
124+
this.DatabaseName = AzureSqlDatabaseObject.DatabaseName;
125+
}
126+
else if (!string.IsNullOrEmpty(ResourceId))
127+
{
128+
ParseResourceId();
129+
}
130+
131+
base.ExecuteCmdlet();
132+
}
133+
134+
/// <summary>
135+
/// Helper method to parse resourceGroupName, serverName, databaseName from resourceId
136+
/// Ideally this would utilize Microsoft.Azure.Management.Internal.Resources.Utilities.Models.ResourceIdentifier
137+
/// However, that class is not setup to handle resources that have an ancestry higher than just parent level.
138+
/// That class could recursively create a parent ResourceIdentifier on a __get__ ParentResource,
139+
/// rather than just a string, so a consumer could work all the way to the root resource easily.
140+
/// Leave as a TODO for now, as many other cmdlets consume that class, and I will work on it in separate change.
141+
/// </summary>
142+
private void ParseResourceId()
143+
{
144+
string[] tokens = ResourceId.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
145+
146+
// "/subscriptions/<subId>/resourceGroups/<resourceGroup>/providers/Microsoft.Sql/servers/<server>/databases/<database>/backupShortTermRetentionPolicies/default"
147+
if (tokens.Length != BackupShortTermRetentionPolicyResourceIdSegmentsLength)
148+
{
149+
throw new ArgumentException("Invalid format of the resource identifier.", "ResourceId");
150+
}
151+
152+
// Convert tokens into TYPE:NAME key value pairs, ignoring case
153+
Dictionary<string, string> segments = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
154+
int i = 0;
155+
while (i < tokens.Length)
156+
{
157+
string type = tokens[i++];
158+
string name = tokens[i++];
159+
segments[type] = name;
160+
}
161+
162+
try
163+
{
164+
this.ResourceGroupName = segments["resourceGroups"];
165+
this.ServerName = segments["servers"];
166+
this.DatabaseName = segments["databases"];
167+
}
168+
catch (KeyNotFoundException)
169+
{
170+
throw new ArgumentException(
171+
"Invalid format of the resource identifier. ResourceID should follow format /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Sql/servers/<serverName>/databases/<databaseName>/backupShortTermRetentionPolicies/default");
172+
}
173+
}
174+
}
175+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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.Collections.Generic;
16+
using System.Management.Automation;
17+
using Microsoft.Azure.Commands.Sql.Backup.Model;
18+
19+
namespace Microsoft.Azure.Commands.Sql.Backup.Cmdlet
20+
{
21+
[Cmdlet(VerbsCommon.Get, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "SqlDatabaseBackupShortTermRetentionPolicy",
22+
DefaultParameterSetName = PolicyByResourceServerDatabaseSet),
23+
OutputType(typeof(AzureSqlDatabaseBackupShortTermRetentionPolicyModel))]
24+
public class GetAzureRmSqlDatabaseBackupShortTermRetentionPolicy : AzureSqlDatabaseBackupShortTermRetentionPolicyCmdletBase
25+
{
26+
/// <summary>
27+
/// Get the entities from the service
28+
/// </summary>
29+
/// <returns>The list of entities</returns>
30+
protected override IEnumerable<AzureSqlDatabaseBackupShortTermRetentionPolicyModel> GetEntity()
31+
{
32+
ICollection<AzureSqlDatabaseBackupShortTermRetentionPolicyModel> results = new List<AzureSqlDatabaseBackupShortTermRetentionPolicyModel>();
33+
34+
results.Add(ModelAdapter.GetDatabaseBackupShortTermRetentionPolicy(
35+
ResourceGroupName,
36+
ServerName,
37+
DatabaseName));
38+
39+
return results;
40+
}
41+
42+
/// <summary>
43+
/// No user input to apply to model
44+
/// </summary>
45+
/// <param name="model">Model retrieved from service</param>
46+
/// <returns>The model that was passed in</returns>
47+
protected override IEnumerable<AzureSqlDatabaseBackupShortTermRetentionPolicyModel> ApplyUserInputToModel(
48+
IEnumerable<AzureSqlDatabaseBackupShortTermRetentionPolicyModel> model)
49+
{
50+
return model;
51+
}
52+
53+
/// <summary>
54+
/// No changes to persist to server
55+
/// </summary>
56+
/// <param name="entity">The output of apply user input to model</param>
57+
/// <returns>The input entity</returns>
58+
protected override IEnumerable<AzureSqlDatabaseBackupShortTermRetentionPolicyModel> PersistChanges(
59+
IEnumerable<AzureSqlDatabaseBackupShortTermRetentionPolicyModel> entity)
60+
{
61+
return entity;
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)