Skip to content

Commit df1e2b4

Browse files
authored
Merge pull request Azure#10895 from alcolic/Cross-subscription-restore-mi
Cross Subscription Restore For Managed Instance.
2 parents ccb14c1 + d547f72 commit df1e2b4

File tree

4 files changed

+96
-26
lines changed

4 files changed

+96
-26
lines changed

src/Sql/Sql.Test/ScenarioTests/ManagedDatabaseCrudScenarioTests.ps1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ function Test-RemoveManagedDatabase
193193
function Test-RestoreManagedDatabase
194194
{
195195
# Setup
196+
$sub = (Get-AzContext).Subscription.Id
196197
$rg = Create-ResourceGroupForTest
197198
$rg2 = Create-ResourceGroupForTest
198199
$vnetName = "cl_initial"
@@ -230,7 +231,7 @@ function Test-RestoreManagedDatabase
230231
Assert-AreEqual $restoredDb.ManagedInstanceName $managedInstance.ManagedInstanceName
231232

232233
# restore managed database to the another instance, different resource group and managed instance
233-
$restoredDb2 = Restore-AzSqlInstanceDatabase -FromPointInTimeBackup -ResourceGroupName $rg.ResourceGroupName -InstanceName $managedInstance.ManagedInstanceName -Name $managedDatabaseName -PointInTime $pointInTime -TargetInstanceDatabaseName $targetManagedDatabaseName -TargetInstanceName $managedInstance2.ManagedInstanceName -TargetResourceGroupName $rg2.ResourceGroupName
234+
$restoredDb2 = Restore-AzSqlInstanceDatabase -FromPointInTimeBackup -SubscriptionId $sub -ResourceGroupName $rg.ResourceGroupName -InstanceName $managedInstance.ManagedInstanceName -Name $managedDatabaseName -PointInTime $pointInTime -TargetInstanceDatabaseName $targetManagedDatabaseName -TargetInstanceName $managedInstance2.ManagedInstanceName -TargetResourceGroupName $rg2.ResourceGroupName
234235
Assert-NotNull $restoredDb2
235236
Assert-AreEqual $restoredDb2.Name $targetManagedDatabaseName
236237
Assert-AreEqual $restoredDb2.ResourceGroupName $rg2.ResourceGroupName
@@ -250,6 +251,7 @@ function Test-RestoreManagedDatabase
250251
function Test-RestoreDeletedManagedDatabase
251252
{
252253
# Setup
254+
$sub = (Get-AzContext).Subscription.Id
253255
$rg = Create-ResourceGroupForTest
254256
$rg2 = Create-ResourceGroupForTest
255257
$vnetName = "cl_initial"
@@ -296,7 +298,7 @@ function Test-RestoreDeletedManagedDatabase
296298
Assert-AreEqual $restoredDb1.ManagedInstanceName $managedInstance.ManagedInstanceName
297299

298300
# restore managed database to the another instance, different resource group and managed instance
299-
$restoredDb2 = Restore-AzSqlInstanceDatabase -FromPointInTimeBackup -ResourceGroupName $rg.ResourceGroupName -InstanceName $managedInstance.ManagedInstanceName -Name $managedDatabaseName -DeletionDate $deletedDatabases[0].DeletionDate -PointInTime $deletedDatabases[0].EarliestRestorePoint -TargetInstanceDatabaseName $targetManagedDatabaseName2 -TargetInstanceName $managedInstance2.ManagedInstanceName -TargetResourceGroupName $rg2.ResourceGroupName
301+
$restoredDb2 = Restore-AzSqlInstanceDatabase -FromPointInTimeBackup -SubscriptionId $sub -ResourceGroupName $rg.ResourceGroupName -InstanceName $managedInstance.ManagedInstanceName -Name $managedDatabaseName -DeletionDate $deletedDatabases[0].DeletionDate -PointInTime $deletedDatabases[0].EarliestRestorePoint -TargetInstanceDatabaseName $targetManagedDatabaseName2 -TargetInstanceName $managedInstance2.ManagedInstanceName -TargetResourceGroupName $rg2.ResourceGroupName
300302
Assert-NotNull $restoredDb2
301303
Assert-AreEqual $restoredDb2.Name $targetManagedDatabaseName2
302304
Assert-AreEqual $restoredDb2.ResourceGroupName $rg2.ResourceGroupName

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+
* Added support for cross subscription point in time restore on Managed Instances.
2122

2223
## Version 2.1.2
2324
* Fix vulnerability assessment set baseline cmdlets functionality to work on master db for azure database and limit it on managed instance system databases.

src/Sql/Sql/ManagedDatabase/Cmdlet/RestoreAzureSqlManagedDatabase.cs

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ public class RestoreAzureRmSqlManagedDatabase
5252
protected const string PointInTimeDeletedDatabasesCrossInstanceRestoreFromNameAndResourceGroupParameterSet =
5353
"PointInTimeDeletedDatabasesCrossInstanceRestoreInstanceDatabaseFromInputParameters";
5454

55-
private const string GeoRestoreFromGeoBackupSetNameFromGeoBackupObjectParameterSet =
55+
private const string GeoRestoreFromGeoBackupSetNameFromGeoBackupObjectParameterSet =
5656
"GeoRestoreFromGeoBackupSetNameFromGeoBackupObjectParameter";
5757

58-
private const string GeoRestoreFromGeoBackupSetNameFromResourceIdParameterSet =
58+
private const string GeoRestoreFromGeoBackupSetNameFromResourceIdParameterSet =
5959
"GeoRestoreFromGeoBackupSetNameFromResourceIdParameter";
6060

61-
private const string GeoRestoreFromGeoBackupSetNameFromNameAndResourceGroupParameterSet =
61+
private const string GeoRestoreFromGeoBackupSetNameFromNameAndResourceGroupParameterSet =
6262
"GeoRestoreFromGeoBackupSetNameFromNameAndResourceGroupParameter";
6363

6464
/// <summary>
@@ -115,6 +115,28 @@ public class RestoreAzureRmSqlManagedDatabase
115115
HelpMessage = "Restore from a geo backup.")]
116116
public SwitchParameter FromGeoBackup { get; set; }
117117

118+
/// <summary>
119+
/// Gets or sets the source subscription id.
120+
/// </summary>
121+
[Parameter(
122+
ParameterSetName = PointInTimeSameInstanceRestoreFromNameAndResourceGroupParameterSet,
123+
Mandatory = false,
124+
HelpMessage = "Source subscription id.")]
125+
[Parameter(
126+
ParameterSetName = PointInTimeCrossInstanceRestoreFromNameAndResourceGroupParameterSet,
127+
Mandatory = false,
128+
HelpMessage = "Source subscription id.")]
129+
[Parameter(
130+
ParameterSetName = PointInTimeDeletedDatabasesSameInstanceRestoreFromNameAndResourceGroupParameterSet,
131+
Mandatory = false,
132+
HelpMessage = "Source subscription id.")]
133+
[Parameter(
134+
ParameterSetName = PointInTimeDeletedDatabasesCrossInstanceRestoreFromNameAndResourceGroupParameterSet,
135+
Mandatory = false,
136+
HelpMessage = "Source subscription id.")]
137+
[Alias("SourceSubscriptionId")]
138+
public string SubscriptionId { get; set; }
139+
118140
/// <summary>
119141
/// Gets or sets the name of the resource group to use.
120142
/// </summary>
@@ -139,6 +161,7 @@ public class RestoreAzureRmSqlManagedDatabase
139161
Position = 0,
140162
HelpMessage = "The name of the resource group.")]
141163
[ResourceGroupCompleter]
164+
[Alias("SourceResourceGroupName")]
142165
[ValidateNotNullOrEmpty]
143166
public override string ResourceGroupName { get; set; }
144167

@@ -166,6 +189,7 @@ public class RestoreAzureRmSqlManagedDatabase
166189
Position = 1,
167190
HelpMessage = "The name of the instance.")]
168191
[ResourceNameCompleter("Microsoft.Sql/managedInstances", "ResourceGroupName")]
192+
[Alias("SourceInstanceName")]
169193
[ValidateNotNullOrEmpty]
170194
public override string InstanceName { get; set; }
171195

@@ -192,7 +216,7 @@ public class RestoreAzureRmSqlManagedDatabase
192216
Mandatory = true,
193217
Position = 2,
194218
HelpMessage = "The instance database name to restore.")]
195-
[Alias("InstanceDatabaseName")]
219+
[Alias("InstanceDatabaseName", "SourceInstanceDatabaseName")]
196220
public string Name { get; set; }
197221

198222
/// <summary>
@@ -376,16 +400,36 @@ protected override AzureSqlManagedDatabaseModel GetEntity()
376400
RestorePointInTime = PointInTime,
377401
};
378402

403+
if (SubscriptionId != null && !Guid.TryParse(SubscriptionId, out Guid _))
404+
{
405+
throw new PSArgumentException(
406+
string.Format("The provided subscription ID {0} is not a valid Guid.", SubscriptionId),
407+
"SubscriptionId");
408+
}
409+
410+
if (SubscriptionId == null)
411+
{
412+
SubscriptionId = ModelAdapter.Context.Subscription.Id;
413+
}
414+
379415
switch (ParameterSetName)
380416
{
381417
case PointInTimeDeletedDatabasesCrossInstanceRestoreFromNameAndResourceGroupParameterSet:
382418
case PointInTimeDeletedDatabasesSameInstanceRestoreFromNameAndResourceGroupParameterSet:
383-
model.RestorableDroppedDatabaseId = ModelAdapter.GetDeletedManagedDatabaseResourceId(this.ResourceGroupName, this.InstanceName, this.Name + "," + this.DeletionDate.ToFileTimeUtc());
419+
model.RestorableDroppedDatabaseId = "/subscriptions/" + SubscriptionId +
420+
"/resourceGroups/" + ResourceGroupName +
421+
"/providers/Microsoft.Sql/managedInstances/" + InstanceName +
422+
"/restorableDroppedDatabases/" + this.Name + "," + this.DeletionDate.ToFileTimeUtc();
384423
break;
424+
385425
case PointInTimeCrossInstanceRestoreFromNameAndResourceGroupParameterSet:
386426
case PointInTimeSameInstanceRestoreFromNameAndResourceGroupParameterSet:
387-
model.SourceDatabaseId = ModelAdapter.GetManagedDatabaseResourceId(this.ResourceGroupName, this.InstanceName, this.Name);
427+
model.SourceDatabaseId = "/subscriptions/" + SubscriptionId +
428+
"/resourceGroups/" + ResourceGroupName +
429+
"/providers/Microsoft.Sql/managedInstances/" + InstanceName +
430+
"/databases/" + Name;
388431
break;
432+
389433
case PointInTimeSameInstanceRestoreFromInputObjectParameterSet:
390434
case PointInTimeCrossInstanceRestoreFromInputObjectParameterSet:
391435
ResourceGroupName = InputObject.ResourceGroupName;
@@ -400,6 +444,7 @@ protected override AzureSqlManagedDatabaseModel GetEntity()
400444
}
401445

402446
break;
447+
403448
case PointInTimeSameInstanceRestoreFromResourceIdParameterSet:
404449
case PointInTimeCrossInstanceRestoreFromResourceIdParameterSet:
405450
var resourceInfo = new ResourceIdentifier(ResourceId);
@@ -415,24 +460,30 @@ protected override AzureSqlManagedDatabaseModel GetEntity()
415460
}
416461

417462
break;
463+
418464
case GeoRestoreFromGeoBackupSetNameFromGeoBackupObjectParameterSet:
419465
ResourceGroupName = GeoBackupObject.ResourceGroupName;
420466
InstanceName = GeoBackupObject.ManagedInstanceName;
421467
model.RecoverableDatabaseId = GeoBackupObject.Id;
422468
model.CreateMode = "Recovery";
423469
model.RestorePointInTime = null;
424470
break;
471+
425472
case GeoRestoreFromGeoBackupSetNameFromNameAndResourceGroupParameterSet:
426-
model.RecoverableDatabaseId = "/subscriptions/" + ModelAdapter.Context.Subscription.Id + "/resourceGroups/" + ResourceGroupName + "/providers/Microsoft.Sql/managedInstances/"
427-
+ InstanceName + "/recoverableDatabases/" + Name;
473+
model.RecoverableDatabaseId = "/subscriptions/" + SubscriptionId +
474+
"/resourceGroups/" + ResourceGroupName +
475+
"/providers/Microsoft.Sql/managedInstances/" + InstanceName +
476+
"/recoverableDatabases/" + Name;
428477
model.CreateMode = "Recovery";
429478
model.RestorePointInTime = null;
430479
break;
480+
431481
case GeoRestoreFromGeoBackupSetNameFromResourceIdParameterSet:
432482
model.CreateMode = "Recovery";
433483
model.RecoverableDatabaseId = ResourceId;
434484
model.RestorePointInTime = null;
435485
break;
486+
436487
default:
437488
throw new ArgumentException("No ParameterSet name");
438489
}

src/Sql/Sql/help/Restore-AzSqlInstanceDatabase.md

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ Restores an Azure SQL Managed Instance database.
1414

1515
### PointInTimeSameInstanceRestoreInstanceDatabaseFromInputParameters (Default)
1616
```
17-
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-ResourceGroupName] <String> [-InstanceName] <String>
18-
[-Name] <String> -PointInTime <DateTime> -TargetInstanceDatabaseName <String> [-AsJob]
19-
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
17+
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-SubscriptionId <String>] [-ResourceGroupName] <String>
18+
[-InstanceName] <String> [-Name] <String> -PointInTime <DateTime> -TargetInstanceDatabaseName <String>
19+
[-AsJob] [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
2020
```
2121

2222
### PointInTimeSameInstanceRestoreInstanceDatabaseFromAzureSqlManagedDatabaseModelInstanceDefinition
@@ -35,10 +35,10 @@ Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-ResourceId] <String> -P
3535

3636
### PointInTimeCrossInstanceRestoreInstanceDatabaseFromInputParameters
3737
```
38-
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-ResourceGroupName] <String> [-InstanceName] <String>
39-
[-Name] <String> -PointInTime <DateTime> -TargetInstanceDatabaseName <String> -TargetInstanceName <String>
40-
-TargetResourceGroupName <String> [-AsJob] [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm]
41-
[<CommonParameters>]
38+
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-SubscriptionId <String>] [-ResourceGroupName] <String>
39+
[-InstanceName] <String> [-Name] <String> -PointInTime <DateTime> -TargetInstanceDatabaseName <String>
40+
-TargetInstanceName <String> -TargetResourceGroupName <String> [-AsJob]
41+
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
4242
```
4343

4444
### PointInTimeCrossInstanceRestoreInstanceDatabaseFromAzureSqlManagedDatabaseModelInstanceDefinition
@@ -58,16 +58,17 @@ Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-ResourceId] <String> -P
5858

5959
### PointInTimeDeletedDatabasesSameInstanceRestoreInstanceDatabaseFromInputParameters
6060
```
61-
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-ResourceGroupName] <String> [-InstanceName] <String>
62-
[-Name] <String> [-DeletionDate] <DateTime> -PointInTime <DateTime> -TargetInstanceDatabaseName <String>
63-
[-AsJob] [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
61+
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-SubscriptionId <String>] [-ResourceGroupName] <String>
62+
[-InstanceName] <String> [-Name] <String> [-DeletionDate] <DateTime> -PointInTime <DateTime>
63+
-TargetInstanceDatabaseName <String> [-AsJob] [-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm]
64+
[<CommonParameters>]
6465
```
6566

6667
### PointInTimeDeletedDatabasesCrossInstanceRestoreInstanceDatabaseFromInputParameters
6768
```
68-
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-ResourceGroupName] <String> [-InstanceName] <String>
69-
[-Name] <String> [-DeletionDate] <DateTime> -PointInTime <DateTime> -TargetInstanceDatabaseName <String>
70-
-TargetInstanceName <String> -TargetResourceGroupName <String> [-AsJob]
69+
Restore-AzSqlInstanceDatabase [-FromPointInTimeBackup] [-SubscriptionId <String>] [-ResourceGroupName] <String>
70+
[-InstanceName] <String> [-Name] <String> [-DeletionDate] <DateTime> -PointInTime <DateTime>
71+
-TargetInstanceDatabaseName <String> -TargetInstanceName <String> -TargetResourceGroupName <String> [-AsJob]
7172
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
7273
```
7374

@@ -253,7 +254,7 @@ The instance name.
253254
```yaml
254255
Type: System.String
255256
Parameter Sets: PointInTimeSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeCrossInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesCrossInstanceRestoreInstanceDatabaseFromInputParameters, GeoRestoreFromGeoBackupSetNameFromNameAndResourceGroupParameter
256-
Aliases:
257+
Aliases: SourceInstanceName
257258

258259
Required: True
259260
Position: 1
@@ -268,7 +269,7 @@ The instance database name to restore.
268269
```yaml
269270
Type: System.String
270271
Parameter Sets: PointInTimeSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeCrossInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesCrossInstanceRestoreInstanceDatabaseFromInputParameters, GeoRestoreFromGeoBackupSetNameFromNameAndResourceGroupParameter
271-
Aliases: InstanceDatabaseName
272+
Aliases: InstanceDatabaseName, SourceInstanceDatabaseName
272273

273274
Required: True
274275
Position: 2
@@ -298,7 +299,7 @@ The name of the resource group.
298299
```yaml
299300
Type: System.String
300301
Parameter Sets: PointInTimeSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeCrossInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesCrossInstanceRestoreInstanceDatabaseFromInputParameters, GeoRestoreFromGeoBackupSetNameFromNameAndResourceGroupParameter
301-
Aliases:
302+
Aliases: SourceResourceGroupName
302303

303304
Required: True
304305
Position: 0
@@ -334,6 +335,21 @@ Accept pipeline input: True (ByPropertyName)
334335
Accept wildcard characters: False
335336
```
336337
338+
### -SubscriptionId
339+
Source subscription id.
340+
341+
```yaml
342+
Type: System.String
343+
Parameter Sets: PointInTimeSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeCrossInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesSameInstanceRestoreInstanceDatabaseFromInputParameters, PointInTimeDeletedDatabasesCrossInstanceRestoreInstanceDatabaseFromInputParameters
344+
Aliases: SourceSubscriptionId
345+
346+
Required: False
347+
Position: Named
348+
Default value: None
349+
Accept pipeline input: False
350+
Accept wildcard characters: False
351+
```
352+
337353
### -TargetInstanceDatabaseName
338354
The name of the target instance database to restore to.
339355

0 commit comments

Comments
 (0)