Skip to content

Commit ff4f18d

Browse files
authored
Merge pull request Azure#9105 from mykolian/sqldb-serverless
Support for Serverless specific parameters for CRUD
2 parents 0d6ecc0 + c11bb72 commit ff4f18d

File tree

15 files changed

+5764
-22
lines changed

15 files changed

+5764
-22
lines changed

src/Sql/Sql.Test/ScenarioTests/DatabaseCrudTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ public void TestVcoreDatabaseCreateWithLicenseType()
5454
RunPowerShellTest("Test-CreateVcoreDatabaseWithLicenseType");
5555
}
5656

57+
[Fact]
58+
[Trait(Category.AcceptanceType, Category.CheckIn)]
59+
public void TestCreateServerlessDatabase()
60+
{
61+
RunPowerShellTest("Test-CreateServerlessDatabase");
62+
}
63+
5764
[Fact]
5865
[Trait(Category.AcceptanceType, Category.CheckIn)]
5966
public void TestDatabaseCreateWithSampleName()
@@ -103,6 +110,13 @@ public void TestDatabaseUpdateWithZoneRedundancyNotSpecified()
103110
RunPowerShellTest("Test-UpdateDatabaseWithZoneRedundantNotSpecified");
104111
}
105112

113+
[Fact]
114+
[Trait(Category.AcceptanceType, Category.CheckIn)]
115+
public void TestUpdateServerlessDatabase()
116+
{
117+
RunPowerShellTest("Test-UpdateServerlessDatabase");
118+
}
119+
106120
[Fact]
107121
[Trait(Category.AcceptanceType, Category.CheckIn)]
108122
public void TestDatabaseRename()

src/Sql/Sql.Test/ScenarioTests/DatabaseCrudTests.ps1

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,39 @@ function Test-CreateVcoreDatabaseWithLicenseType
183183
}
184184
}
185185

186+
<#
187+
.SYNOPSIS
188+
Tests creating a Serverless based database
189+
#>
190+
function Test-CreateServerlessDatabase
191+
{
192+
# Setup
193+
$location = Get-Location "Microsoft.Sql" "operations" "Japan East"
194+
$rg = Create-ResourceGroupForTest $location
195+
$server = Create-ServerForTest $rg $location
196+
197+
try
198+
{
199+
# Create with Edition and RequestedServiceObjectiveName
200+
$databaseName = Get-DatabaseName
201+
$job1 = New-AzSqlDatabase -ResourceGroupName $rg.ResourceGroupName -ServerName $server.ServerName -DatabaseName $databaseName -RequestedServiceObjectiveName GP_S_Gen5_2 -AutoPauseDelayInMinutes 360 -MinVCore 0.5 -AsJob
202+
$job1 | Wait-Job
203+
$db = $job1.Output
204+
205+
Assert-AreEqual $databaseName $db.DatabaseName
206+
Assert-NotNull $db.MaxSizeBytes
207+
Assert-AreEqual GP_S_Gen5_2 $db.CurrentServiceObjectiveName
208+
Assert-AreEqual 2 $db.Capacity
209+
Assert-AreEqual 360 $db.AutoPauseDelayInMinutes
210+
Assert-AreEqual 0.5 $db.MinimumCapacity
211+
Assert-AreEqual GeneralPurpose $db.Edition
212+
}
213+
finally
214+
{
215+
Remove-ResourceGroupForTest $rg
216+
}
217+
}
218+
186219
<#
187220
.SYNOPSIS
188221
Tests creating a database with sample name.
@@ -512,6 +545,74 @@ function Test-UpdateDatabaseWithZoneRedundant ()
512545
}
513546
}
514547

548+
<#
549+
.SYNOPSIS
550+
Tests updating a vcore database
551+
#>
552+
function Test-UpdateServerlessDatabase()
553+
{
554+
# Setup
555+
$location = Get-Location "Microsoft.Sql" "operations" "Japan East"
556+
$rg = Create-ResourceGroupForTest $location
557+
$server = Create-ServerForTest $rg $location
558+
559+
$databaseName = Get-DatabaseName
560+
$db = New-AzSqlDatabase -ResourceGroupName $rg.ResourceGroupName -ServerName $server.ServerName -DatabaseName $databaseName `
561+
-VCore 2 -Edition GeneralPurpose -ComputeGeneration Gen5 -MaxSizeBytes 250GB -ComputeModel Serverless
562+
Assert-AreEqual $db.DatabaseName $databaseName
563+
564+
try
565+
{
566+
# Alter with defaults
567+
$job = Set-AzSqlDatabase -ResourceGroupName $db.ResourceGroupName -ServerName $db.ServerName -DatabaseName $db.DatabaseName `
568+
-AsJob
569+
$job | Wait-Job
570+
$db1 = $job.Output
571+
572+
Assert-AreEqual $db1.DatabaseName $db.DatabaseName
573+
Assert-NotNull $db1.MaxSizeBytes
574+
Assert-NotNull $db1.Edition
575+
Assert-NotNull $db1.CurrentServiceObjectiveName
576+
Assert-NotNull $db1.MinimumCapacity
577+
Assert-NotNull $db1.AutoPauseDelayInMinutes
578+
579+
# Alter to dtu database
580+
$job = Set-AzSqlDatabase -ResourceGroupName $db.ResourceGroupName -ServerName $db.ServerName -DatabaseName $db.DatabaseName `
581+
-Edition Premium -AsJob
582+
$job | Wait-Job
583+
$db1 = $job.Output
584+
Assert-AreEqual $db1.DatabaseName $db.DatabaseName
585+
Assert-AreEqual $db1.Edition Premium
586+
Assert-Null $db1.MinimumCapacity
587+
Assert-Null $db1.AutoPauseDelayInMinutes
588+
589+
# Alter back to Serverless
590+
$job = Set-AzSqlDatabase -ResourceGroupName $db.ResourceGroupName -ServerName $db.ServerName -DatabaseName $db.DatabaseName `
591+
-VCore 2 -Edition GeneralPurpose -ComputeModel Serverless -ComputeGeneration Gen5 -AsJob
592+
$job | Wait-Job
593+
$db1 = $job.Output
594+
Assert-AreEqual $db1.DatabaseName $db.DatabaseName
595+
Assert-AreEqual $db1.Edition GeneralPurpose
596+
Assert-AreEqual $db1.CurrentServiceObjectiveName GP_S_Gen5_2
597+
Assert-NotNull $db1.MinimumCapacity
598+
Assert-NotNull $db1.AutoPauseDelayInMinutes
599+
600+
# Alter mincapacity and AutoPauseDelayInMinutes
601+
$job = Set-AzSqlDatabase -ResourceGroupName $db.ResourceGroupName -ServerName $db.ServerName -DatabaseName $db.DatabaseName `
602+
-Vcore 2 -Edition GeneralPurpose -ComputeModel Serverless -ComputeGeneration Gen5 -MinimumCapacity 2 -AutoPauseDelayInMinutes 1440 -AsJob
603+
$job | Wait-Job
604+
$db1 = $job.Output
605+
Assert-AreEqual $db1.DatabaseName $db.DatabaseName
606+
Assert-AreEqual $db1.Edition GeneralPurpose
607+
Assert-AreEqual $db1.CurrentServiceObjectiveName GP_S_Gen5_2
608+
Assert-AreEqual $db1.MinimumCapacity 2
609+
Assert-AreEqual $db1.AutoPauseDelayInMinutes 1440
610+
}
611+
finally
612+
{
613+
Remove-ResourceGroupForTest $rg
614+
}
615+
}
515616
<#
516617
.SYNOPSIS
517618
Tests updating a database with zone redundancy not specified

src/Sql/Sql.Test/SessionRecords/Microsoft.Azure.Commands.Sql.Test.ScenarioTests.DatabaseCrudTests/TestCreateServerlessDatabase.json

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

src/Sql/Sql.Test/SessionRecords/Microsoft.Azure.Commands.Sql.Test.ScenarioTests.DatabaseCrudTests/TestUpdateServerlessDatabase.json

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

src/Sql/Sql.Test/Sql.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<ItemGroup>
1414
<PackageReference Include="Microsoft.Azure.Management.Monitor" Version="0.22.0-preview" />
15-
<PackageReference Include="Microsoft.Azure.Management.Sql" Version="1.29.0-preview" />
15+
<PackageReference Include="Microsoft.Azure.Management.Sql" Version="1.31.0-preview" />
1616
<PackageReference Include="Microsoft.Azure.Management.EventHub" Version="2.5.0" />
1717
<PackageReference Include="Microsoft.Azure.Management.Network" Version="19.11.0-preview" />
1818
<PackageReference Include="Microsoft.Azure.Graph.RBAC" Version="3.2.0-preview" />

src/Sql/Sql/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* Ability to Get-AzSqlServerServiceObjective by location without needing a preexisting server in the region.
2828
* Support for time zone parameter in Managed Instance create.
2929
* Fix documentation for wildcards
30+
* Support of Serverless specific parameters in New-AzSqlDatabase and Set-AzSqlDatabase
3031

3132
## Version 1.8.0
3233
* Support Database Data Classification.

src/Sql/Sql/Database/Cmdlet/NewAzureSqlDatabase.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public class NewAzureSqlDatabase : AzureSqlDatabaseCmdletBase<AzureSqlDatabaseCr
137137
/// </summary>
138138
[Parameter(ParameterSetName = VcoreDatabaseParameterSet, Mandatory = true,
139139
HelpMessage = "The Vcore number for the Azure Sql database")]
140-
[Alias("Capacity")]
140+
[Alias("Capacity", "MaxVCore", "MaxCapacity")]
141141
public int VCore { get; set; }
142142

143143
/// <summary>
@@ -159,6 +159,31 @@ public class NewAzureSqlDatabase : AzureSqlDatabaseCmdletBase<AzureSqlDatabaseCr
159159
Management.Sql.Models.DatabaseLicenseType.BasePrice)]
160160
public string LicenseType { get; set; }
161161

162+
/// <summary>
163+
/// Gets or sets the compute model for Azure Sql database
164+
/// </summary>
165+
[Parameter(ParameterSetName = VcoreDatabaseParameterSet, Mandatory = false,
166+
HelpMessage="The compute model for database. Serverless or Provisioned")]
167+
[PSArgumentCompleter(
168+
DatabaseComputeModel.Provisioned,
169+
DatabaseComputeModel.Serverless)]
170+
public string ComputeModel { get; set; }
171+
172+
/// <summary>
173+
/// Gets or sets the Auto Pause delay for Azure Sql Database
174+
/// </summary>
175+
[Parameter(Mandatory = false,
176+
HelpMessage = "The auto pause delay in minutes for database(serverless only), -1 to opt out from pausing")]
177+
public int AutoPauseDelayInMinutes { get; set; }
178+
179+
/// <summary>
180+
/// Gets or sets the Minimal capacity that database will always have allocated, if not paused
181+
/// </summary>
182+
[Parameter(Mandatory = false,
183+
HelpMessage = "The Minimal capacity that database will always have allocated, if not paused. For serverless database only.")]
184+
[Alias("MinVCore", "MinCapacity")]
185+
public double MinimumCapacity { get; set; }
186+
162187
/// <summary>
163188
/// Overriding to add warning message
164189
/// </summary>
@@ -218,7 +243,9 @@ protected override AzureSqlDatabaseCreateOrUpdateModel ApplyUserInputToModel(Azu
218243
ElasticPoolName = ElasticPoolName,
219244
ReadScale = ReadScale,
220245
ZoneRedundant = MyInvocation.BoundParameters.ContainsKey("ZoneRedundant") ? (bool?)ZoneRedundant.ToBool() : null,
221-
LicenseType = LicenseType // note: default license type will be LicenseIncluded in SQL RP if not specified
246+
LicenseType = LicenseType, // note: default license type will be LicenseIncluded in SQL RP if not specified
247+
AutoPauseDelayInMinutes = MyInvocation.BoundParameters.ContainsKey("AutoPauseDelayInMinutes") ? AutoPauseDelayInMinutes : (int?)null,
248+
MinimumCapacity = MyInvocation.BoundParameters.ContainsKey("AutoPauseDelayInMinutes") ? MinimumCapacity : (double?)null,
222249
};
223250

224251
if(ParameterSetName == DtuDatabaseParameterSet)
@@ -228,7 +255,7 @@ protected override AzureSqlDatabaseCreateOrUpdateModel ApplyUserInputToModel(Azu
228255
}
229256
else
230257
{
231-
newDbModel.SkuName = AzureSqlDatabaseAdapter.GetDatabaseSkuName(Edition);
258+
newDbModel.SkuName = AzureSqlDatabaseAdapter.GetDatabaseSkuName(Edition, ComputeModel == DatabaseComputeModel.Serverless);
232259
newDbModel.Edition = Edition;
233260
newDbModel.Capacity = VCore;
234261
newDbModel.Family = ComputeGeneration;

src/Sql/Sql/Database/Cmdlet/SetAzureSqlDatabase.cs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public class SetAzureSqlDatabase : AzureSqlDatabaseCmdletBase<IEnumerable<AzureS
150150
/// </summary>
151151
[Parameter(ParameterSetName = VcoreDatabaseParameterSet, Mandatory = false,
152152
HelpMessage = "The Vcore number for the Azure Sql database")]
153-
[Alias("Capacity")]
153+
[Alias("Capacity", "MaxVCore", "MaxCapacity")]
154154
public int VCore { get; set; }
155155

156156
/// <summary>
@@ -176,6 +176,43 @@ public class SetAzureSqlDatabase : AzureSqlDatabaseCmdletBase<IEnumerable<AzureS
176176
Management.Sql.Models.DatabaseLicenseType.BasePrice)]
177177
public string LicenseType { get; set; }
178178

179+
/// <summary>
180+
/// Gets or sets the compute model for the Azure Sql Database
181+
/// </summary>
182+
[Parameter(Mandatory = false,
183+
HelpMessage = "The computed model of database. Serverless or Provisioned",
184+
ParameterSetName = UpdateParameterSetName)]
185+
[Parameter(Mandatory = false,
186+
HelpMessage = "The computed model of database. Serverless or Provisioned",
187+
ParameterSetName = VcoreDatabaseParameterSet)]
188+
[PSArgumentCompleter(
189+
DatabaseComputeModel.Provisioned,
190+
DatabaseComputeModel.Serverless)]
191+
public string ComputeModel { get; set; }
192+
193+
/// <summary>
194+
/// Gets or sets the auto pause delay for the Azure Sql Database
195+
/// </summary>
196+
[Parameter(Mandatory = false,
197+
HelpMessage = "The auto pause delay in minutes for database (serverless only), -1 to opt out from pausing",
198+
ParameterSetName = UpdateParameterSetName)]
199+
[Parameter(Mandatory = false,
200+
HelpMessage = "The auto pause delay in minutes for database (serverless only), -1 to opt out from pausing",
201+
ParameterSetName = VcoreDatabaseParameterSet)]
202+
public int AutoPauseDelayInMinutes { get; set; }
203+
204+
/// <summary>
205+
/// Gets or sets the Minimal capacity that database will always have allocated, if not paused
206+
/// </summary>
207+
[Parameter(Mandatory = false,
208+
HelpMessage = "The Minimal capacity that database will always have allocated, if not paused. For serverless database only.",
209+
ParameterSetName = UpdateParameterSetName)]
210+
[Parameter(Mandatory = false,
211+
HelpMessage = "The Minimal capacity that database will always have allocated, if not paused. For serverless database only.",
212+
ParameterSetName = VcoreDatabaseParameterSet)]
213+
[Alias("MinVCore", "MinCapacity")]
214+
public double MinimumCapacity { get; set; }
215+
179216
/// <summary>
180217
/// Overriding to add warning message
181218
/// </summary>
@@ -217,7 +254,9 @@ protected override IEnumerable<AzureSqlDatabaseModel> ApplyUserInputToModel(IEnu
217254
ZoneRedundant != null
218255
? (bool?)ZoneRedundant.ToBool()
219256
: null,
220-
LicenseType = LicenseType ?? model.FirstOrDefault().LicenseType // set to original license type
257+
LicenseType = LicenseType ?? model.FirstOrDefault().LicenseType, // set to original license type
258+
AutoPauseDelayInMinutes = MyInvocation.BoundParameters.ContainsKey("AutoPauseDelayInMinutes") ? AutoPauseDelayInMinutes : (int?)null,
259+
MinimumCapacity = MyInvocation.BoundParameters.ContainsKey("MinimumCapacity") ? MinimumCapacity : (double?)null,
221260
};
222261

223262
var database = ModelAdapter.GetDatabase(ResourceGroupName, ServerName, DatabaseName);
@@ -229,6 +268,9 @@ protected override IEnumerable<AzureSqlDatabaseModel> ApplyUserInputToModel(IEnu
229268
Capacity = database.Capacity
230269
};
231270

271+
// check if current db is serverless
272+
string databaseCurrentComputeModel = database.CurrentServiceObjectiveName.Contains("_S_") ? DatabaseComputeModel.Serverless : DatabaseComputeModel.Provisioned;
273+
232274
if (this.ParameterSetName == UpdateParameterSetName)
233275
{
234276
newDbModel.SkuName = string.IsNullOrWhiteSpace(RequestedServiceObjectiveName) ? AzureSqlDatabaseAdapter.GetDatabaseSkuName(Edition) : RequestedServiceObjectiveName;
@@ -243,7 +285,8 @@ protected override IEnumerable<AzureSqlDatabaseModel> ApplyUserInputToModel(IEnu
243285
MyInvocation.BoundParameters.ContainsKey("VCore"))
244286
{
245287
string skuTier = string.IsNullOrWhiteSpace(Edition) ? databaseCurrentSku.Tier : Edition;
246-
newDbModel.SkuName = AzureSqlDatabaseAdapter.GetDatabaseSkuName(skuTier);
288+
string requestedComputeModel = string.IsNullOrWhiteSpace(ComputeModel) ? databaseCurrentComputeModel : ComputeModel;
289+
newDbModel.SkuName = AzureSqlDatabaseAdapter.GetDatabaseSkuName(skuTier, requestedComputeModel == DatabaseComputeModel.Serverless);
247290
newDbModel.Edition = skuTier;
248291
newDbModel.Family = string.IsNullOrWhiteSpace(ComputeGeneration) ? databaseCurrentSku.Family : ComputeGeneration;
249292
newDbModel.Capacity = MyInvocation.BoundParameters.ContainsKey("VCore") ? VCore : databaseCurrentSku.Capacity;

src/Sql/Sql/Database/Model/AzureSqlDatabaseModel.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@ public class AzureSqlDatabaseModel
165165
/// </summary>
166166
public string LicenseType { get; set; }
167167

168+
/// <summary>
169+
/// Gets or sets the Auto pause delay of the database
170+
/// </summary>
171+
public int? AutoPauseDelayInMinutes { get; set; }
172+
173+
/// <summary>
174+
/// Minimal capacity that database will always have allocated, if not paused
175+
/// </summary>
176+
public double? MinimumCapacity { get; set; }
177+
168178
/// <summary>
169179
/// Construct AzureSqlDatabaseModel
170180
/// </summary>
@@ -213,6 +223,8 @@ public AzureSqlDatabaseModel(string resourceGroup, string serverName, Management
213223
ReadScale = readScale;
214224

215225
ZoneRedundant = false;
226+
AutoPauseDelayInMinutes = null;
227+
MinimumCapacity = null;
216228
}
217229

218230
/// <summary>
@@ -259,6 +271,9 @@ public AzureSqlDatabaseModel(string resourceGroup, string serverName, Management
259271
SkuName = database.Sku == null ? null : database.Sku.Name;
260272

261273
LicenseType = database.LicenseType;
274+
275+
AutoPauseDelayInMinutes = database.AutoPauseDelay;
276+
MinimumCapacity = database.MinCapacity;
262277
}
263278
}
264279
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Microsoft.Azure.Commands.Sql.Database.Model
6+
{
7+
public class DatabaseComputeModel
8+
{
9+
public const string Provisioned = "Provisioned";
10+
11+
public const string Serverless = "Serverless";
12+
}
13+
}

src/Sql/Sql/Database/Services/AzureSqlDatabaseAdapter.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ internal AzureSqlDatabaseModel UpsertDatabaseWithNewSdk(string resourceGroup, st
157157
SampleName = model.SampleName,
158158
ZoneRedundant = model.Database.ZoneRedundant,
159159
ElasticPoolId = elasticPoolId,
160-
LicenseType = model.Database.LicenseType
160+
LicenseType = model.Database.LicenseType,
161+
AutoPauseDelay = model.Database.AutoPauseDelayInMinutes,
162+
MinCapacity = model.Database.MinimumCapacity,
161163
});
162164

163165
return CreateDatabaseModelFromResponse(resourceGroup, serverName, resp);
@@ -338,17 +340,20 @@ public void RenameDatabase(string resourceGroupName, string serverName, string d
338340
/// Standard | Standard
339341
/// Basic | Basic
340342
/// Premium | Premium
343+
///
344+
/// Also adds _S in the end of SkuName in case if it is Serverless
341345
/// </summary>
342346
/// <param name="tier">Azure Sql database edition</param>
347+
/// <param name="isServerless">If sku should be serverless type</param>
343348
/// <returns>The sku name</returns>
344-
public static string GetDatabaseSkuName(string tier)
349+
public static string GetDatabaseSkuName(string tier, bool isServerless = false)
345350
{
346351
if (string.IsNullOrWhiteSpace(tier))
347352
{
348353
return null;
349354
}
350355

351-
return SqlSkuUtils.GetVcoreSkuPrefix(tier) ?? tier;
356+
return (SqlSkuUtils.GetVcoreSkuPrefix(tier) ?? tier) + (isServerless ? "_S" : "");
352357
}
353358

354359
/// <summary>

0 commit comments

Comments
 (0)