Skip to content

Commit 8349058

Browse files
authored
Added support for enabling Disk access settings for managed VM restores (#26504)
Updated help Updated changelog Added test case
1 parent 1026dba commit 8349058

File tree

11 files changed

+1636
-9
lines changed

11 files changed

+1636
-9
lines changed

src/RecoveryServices/RecoveryServices.Backup.Helpers/Conversions/RecoveryPointConversions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ public static RecoveryPointBase GetPSAzureVMRecoveryPoint(
367367
Zones = recoveryPoint.Zones,
368368
RehydrationExpiryTime = (DateTime?)null,
369369
ExtendedLocation = recoveryPoint.ExtendedLocation,
370+
IsPrivateAccessEnabledOnAnyDisk = recoveryPoint.IsPrivateAccessEnabledOnAnyDisk
370371
};
371372

372373
if (recoveryPoint.RecoveryPointTierDetails != null)

src/RecoveryServices/RecoveryServices.Backup.Models/AzureVmModels/AzureVmRecoveryPoint.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class AzureVmRecoveryPoint : AzureRecoveryPoint
4242
/// Identifies whether this recovery point represents
4343
/// an encrypted VM at the time of backup.
4444
/// </summary>
45-
public bool EncryptionEnabled { get; set; }
45+
public bool EncryptionEnabled { get; set; }
4646

4747
/// <summary>
4848
/// Identifies whether an ILR session is already active
@@ -93,6 +93,12 @@ public class AzureVmRecoveryPoint : AzureRecoveryPoint
9393
/// </summary>
9494
public ExtendedLocation ExtendedLocation { get; set; }
9595

96+
/// <summary>
97+
/// Identifies whether any of the disks in the VM are using
98+
/// Private access network setting
99+
/// </summary>
100+
public bool? IsPrivateAccessEnabledOnAnyDisk { get; set; }
101+
96102
public AzureVmRecoveryPoint()
97103
{
98104

src/RecoveryServices/RecoveryServices.Backup.Models/CmdletParamEnums.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ public enum RestoreVMBackupItemParams
8585
TargetVNetResourceGroup,
8686
TargetSubnetName,
8787
TargetSubscriptionId,
88-
RestoreToEdgeZone
88+
RestoreToEdgeZone,
89+
DiskAccessOption,
90+
TargetDiskAccessId
8991
}
9092

9193
public enum RestoreFSBackupItemParams

src/RecoveryServices/RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,8 @@ public RestAzureNS.AzureOperationResponse TriggerRestore()
507507
bool restoreToEdgeZone = (bool)ProviderData[RestoreVMBackupItemParams.RestoreToEdgeZone];
508508
string auxiliaryAccessToken = ProviderData.ContainsKey(ResourceGuardParams.Token) ? (string)ProviderData[ResourceGuardParams.Token] : null;
509509
bool isMUAOperation = ProviderData.ContainsKey(ResourceGuardParams.IsMUAOperation) ? (bool)ProviderData[ResourceGuardParams.IsMUAOperation] : false;
510-
510+
ServiceClientModel.TargetDiskNetworkAccessOption? diskAccessOption = ProviderData.ContainsKey(RestoreVMBackupItemParams.DiskAccessOption) ? (ServiceClientModel.TargetDiskNetworkAccessOption?)ProviderData[RestoreVMBackupItemParams.DiskAccessOption] : null;
511+
string targetDiskAccessId = ProviderData.ContainsKey(RestoreVMBackupItemParams.TargetDiskAccessId) ? (string)ProviderData[RestoreVMBackupItemParams.TargetDiskAccessId] : null;
511512

512513
Dictionary<UriEnums, string> uriDict = HelperUtils.ParseUri(rp.Id);
513514
string containerUri = HelperUtils.GetContainerUri(uriDict, rp.Id);
@@ -629,6 +630,17 @@ public RestAzureNS.AzureOperationResponse TriggerRestore()
629630
restoreRequest.ExtendedLocation = rp.ExtendedLocation;
630631
}
631632

633+
if (diskAccessOption != null)
634+
{
635+
restoreRequest.TargetDiskNetworkAccessSettings = new TargetDiskNetworkAccessSettings();
636+
restoreRequest.TargetDiskNetworkAccessSettings.TargetDiskNetworkAccessOption = diskAccessOption;
637+
638+
if(!string.IsNullOrEmpty(targetDiskAccessId))
639+
{
640+
restoreRequest.TargetDiskNetworkAccessSettings.TargetDiskAccessId = targetDiskAccessId;
641+
}
642+
}
643+
632644
if (restoreType == "OriginalLocation") // replace existing
633645
{
634646
restoreRequest.RecoveryType = RecoveryType.OriginalLocation;

src/RecoveryServices/RecoveryServices.Backup.Test/ScenarioTests/IaasVm/ItemTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,5 +315,17 @@ public void TestAzureVaultSoftDelete()
315315
"Test-AzureVaultSoftDelete"
316316
);
317317
}
318+
319+
[Fact]
320+
[Trait(Category.AcceptanceType, Category.CheckIn)]
321+
[Trait(TestConstants.Workload, TestConstants.AzureVM)]
322+
public void TestAzurePERestore()
323+
{
324+
TestRunner.RunTestScript(
325+
$"Import-Module {_IaasVmcommonModule.AsAbsoluteLocation()}",
326+
$"Import-Module {_IaasVmtestModule.AsAbsoluteLocation()}",
327+
"Test-AzurePERestore"
328+
);
329+
}
318330
}
319331
}

src/RecoveryServices/RecoveryServices.Backup.Test/ScenarioTests/IaasVm/ItemTests.ps1

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,41 @@
1212
# limitations under the License.
1313
# ----------------------------------------------------------------------------------
1414

15+
function Test-AzurePERestore
16+
{
17+
$location = "eastus2euap"
18+
$resourceGroupName = "arpja"
19+
$vaultName = "arpja-pe-e2e-validation-vault"
20+
$vmName = "peval-ecy-win44"
21+
$subId = "f2edfd5d-5496-4683-b94f-b3588c579009"
22+
$subName = "sriramsa-IaaSVmBackup Canary Subscription"
23+
$saName = "arpjapevalrestoresa"
24+
$targetVMName = "ps-diskaccess"
25+
$targetVNetName = "arpjavnet238"
26+
$targetVNetRG = "arpja"
27+
$targetSubnetName = "default"
28+
$recoveryPointId = "252905611419763" # latest recovery point
29+
$targetDiskAccessId = "/subscriptions/f2edfd5d-5496-4683-b94f-b3588c579009/resourceGroups/arpja/providers/Microsoft.Compute/diskAccesses/arpja-peval-restore-da"
30+
31+
try
32+
{
33+
# Setup
34+
$vault = Get-AzRecoveryServicesVault -ResourceGroupName $resourceGroupName -Name $vaultName
35+
$item = Get-AzRecoveryServicesBackupItem -BackupManagementType AzureVM -WorkloadType AzureVM `
36+
-VaultId $vault.ID | Where-Object { $_.Name -match $vmName }
37+
38+
$rp = Get-AzRecoveryServicesBackupRecoveryPoint -Item $item[0] -VaultId $vault.ID -RecoveryPointId $recoveryPointId
39+
40+
$diskAccessRestoreJob = Restore-AzRecoveryServicesBackupItem -VaultLocation $vault.Location -RecoveryPoint $rp[0] -StorageAccountName $saName -StorageAccountResourceGroupName $vault.ResourceGroupName -TargetResourceGroupName $vault.ResourceGroupName -TargetVMName $targetVMName -TargetVNetName $targetVNetName -TargetVNetResourceGroup $targetVNetRG -TargetSubnetName $targetSubnetName -VaultId $vault.Id -DiskAccessOption EnablePrivateAccessForAllDisks -TargetDiskAccessId $targetDiskAccessId | Wait-AzRecoveryServicesBackupJob -VaultId $vault.ID
41+
42+
Assert-True { $diskAccessRestoreJob.Status -eq "Completed" }
43+
}
44+
finally
45+
{
46+
Delete-VM $resourceGroupName $targetVMName
47+
}
48+
}
49+
1550
function Test-AzureVaultSoftDelete
1651
{
1752
$resourceGroupName = "hiagarg"

src/RecoveryServices/RecoveryServices.Backup.Test/SessionRecords/Microsoft.Azure.Commands.RecoveryServices.Backup.Test.ScenarioTests.ItemTests/TestAzurePERestore.json

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

src/RecoveryServices/RecoveryServices.Backup/Cmdlets/Restore/RestoreAzureRMRecoveryServicesBackupItem.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,19 @@ public class RestoreAzureRmRecoveryServicesBackupItem : RSBackupVaultCmdletBase
328328
[Parameter(Mandatory = false, HelpMessage = ParamHelpMsgs.ResourceGuard.AuxiliaryAccessToken, ValueFromPipeline = false)]
329329
public string Token;
330330

331+
[Parameter(Mandatory = false, ParameterSetName = AzureManagedVMCreateNewParameterSet,
332+
HelpMessage = ParamHelpMsgs.RestoreVM.DiskAccessOption)]
333+
[Parameter(Mandatory = false, ParameterSetName = AzureManagedVMReplaceExistingParameterSet,
334+
HelpMessage = ParamHelpMsgs.RestoreVM.DiskAccessOption)]
335+
public ServiceClientModel.TargetDiskNetworkAccessOption? DiskAccessOption { get; set; }
336+
337+
[Parameter(Mandatory = false, ParameterSetName = AzureManagedVMCreateNewParameterSet,
338+
HelpMessage = ParamHelpMsgs.RestoreVM.TargetDiskAccessId)]
339+
[Parameter(Mandatory = false, ParameterSetName = AzureManagedVMReplaceExistingParameterSet,
340+
HelpMessage = ParamHelpMsgs.RestoreVM.TargetDiskAccessId)]
341+
[ValidatePattern(@"^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft.Compute/diskAccesses/[^/]+$")]
342+
public string TargetDiskAccessId { get; set; }
343+
331344
public override void ExecuteCmdlet()
332345
{
333346
ExecutionBlock(() =>
@@ -430,6 +443,43 @@ public override void ExecuteCmdlet()
430443
}
431444
}
432445

446+
if (DiskAccessOption != null)
447+
{
448+
AzureVmRecoveryPoint rp = (AzureVmRecoveryPoint)RecoveryPoint;
449+
if (!(bool)rp.IsPrivateAccessEnabledOnAnyDisk)
450+
{
451+
throw new ArgumentException("DiskAccessOption parameter can't be provided since private access is not enabled in given recovery point");
452+
}
453+
454+
if (DiskAccessOption == ServiceClientModel.TargetDiskNetworkAccessOption.EnablePrivateAccessForAllDisks)
455+
{
456+
if (string.IsNullOrEmpty(TargetDiskAccessId))
457+
{
458+
throw new ArgumentException("TargetDiskAccessId must be provided when DiskAccessOption is set to EnablePrivateAccessForAllDisks.");
459+
}
460+
}
461+
else if (RestoreToSecondaryRegion.IsPresent && DiskAccessOption == ServiceClientModel.TargetDiskNetworkAccessOption.SameAsOnSourceDisks)
462+
{
463+
throw new ArgumentException("Given DiskAccessOption isn't applicable to cross region restore");
464+
}
465+
else if (!string.IsNullOrEmpty(TargetDiskAccessId))
466+
{
467+
throw new ArgumentException("TargetDiskAccessId can't be provided for the given DiskAccessOption.");
468+
}
469+
470+
providerParameters.Add(RestoreVMBackupItemParams.DiskAccessOption, DiskAccessOption);
471+
providerParameters.Add(RestoreVMBackupItemParams.TargetDiskAccessId, TargetDiskAccessId);
472+
}
473+
else if (string.Equals(this.ParameterSetName, AzureManagedVMCreateNewParameterSet, StringComparison.Ordinal) ||
474+
string.Equals(this.ParameterSetName, AzureManagedVMReplaceExistingParameterSet, StringComparison.Ordinal))
475+
{
476+
AzureVmRecoveryPoint rp = (AzureVmRecoveryPoint)RecoveryPoint;
477+
if ((bool)rp.IsPrivateAccessEnabledOnAnyDisk)
478+
{
479+
throw new ArgumentException("DiskAccessOption parameter must be provided since private access is enabled in given recovery point");
480+
}
481+
}
482+
433483
if (TargetZoneNumber != null)
434484
{
435485
// get storage type

src/RecoveryServices/RecoveryServices.Backup/ParamHelpMsgs.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ internal static class RestoreVM
181181
public const string TargetVNetResourceGroup = "Name of the resource group which contains the target VNet, in the case of Alternate Location restore to a new VM";
182182
public const string TargetSubnetName = "Name of the subnet in which the target VM should be created, in the case of Alternate Location restore to a new VM";
183183
public const string TargetSubscriptionId = "ID of the target subscription to which the resource should be restored. Use this parameter for Cross subscription restore";
184+
public const string DiskAccessOption = "Specifies the disk access option for target disks";
185+
public const string TargetDiskAccessId = "Specifies the target disk access ID when DiskAccessOption set to EnablePrivateAccessForAllDisks";
184186
}
185187

186188
internal static class RestoreFS

src/RecoveryServices/RecoveryServices/ChangeLog.md

Lines changed: 2 additions & 1 deletion
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 enabling Disk access settings for managed VM restores.
2122

2223
## Version 7.2.0
2324
* Fixed bug for making RecoveryAzureStorageAccountId parameter optional in `New-ASRReplicationProtectedItem` cmdlet of H2A.
@@ -27,7 +28,7 @@
2728
* Added additional properties to the output of Get-AzRecoveryServicesVault cmdlet - MoveDetails, MoveState, RedundancySettings, SecureScore, BcdrSecurityLevel, EncryptionProperty.
2829

2930
## Version 7.0.0
30-
* [Breaking Change] Renamed the property `ResouceType` of `ASRVaultSettings` to `ResourceType`.
31+
* [Breaking Change] Renamed the property `ResouceType` of `ASRVaultSettings` to `ResourceType`.
3132

3233
## Version 6.9.0
3334
* Added support for MUA for disabling vault Immutability, increasing RPO for policy schedule, restore, stop protection with retain data.

0 commit comments

Comments
 (0)