Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RecoveryServices.Backup]Added support for restoring multiple files/folders in AzureFileShare #11373

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ public enum RestoreFSBackupItemParams
SourceFileType,
TargetStorageAccountName,
TargetFileShareName,
TargetFolder
TargetFolder,
MultipleSourceFilePath
}
public enum RestoreWLBackupItemParams
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -598,4 +598,7 @@ Please contact Microsoft for further assistance.</value>
<data name="UnmanagedVMRestoreWarning" xml:space="preserve">
<value>The disks of the managed VM will be restored as unmanaged since TargetResourceGroupName parameter is not provided. This will NOT leverage the instant restore functionality and hence can be significantly slow based on given storage account. To leverage instant restore, provide the TargetResourceGroupName parameter. Otherwise, provide the intent next time by passing the RestoreAsUnmanagedDisks parameter</value>
</data>
<data name="AzureFileSourceFilePathRedundantException" xml:space="preserve">
<value>Both source file path and multiple source file paths provided. Please give only one option</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,14 @@ public RestAzureNS.AzureOperationResponse TriggerRestore()
(string)ProviderData[RestoreFSBackupItemParams.TargetFileShareName] : null;
string targetFolder = ProviderData.ContainsKey(RestoreFSBackupItemParams.TargetFolder) ?
(string)ProviderData[RestoreFSBackupItemParams.TargetFolder] : null;
string[] multipleSourceFilePaths = ProviderData.ContainsKey(RestoreFSBackupItemParams.MultipleSourceFilePath) ?
(string[])ProviderData[RestoreFSBackupItemParams.MultipleSourceFilePath] : null;

//validate file recovery request
ValidateFileRestoreRequest(sourceFilePath, sourceFileType);
ValidateFileRestoreRequest(sourceFilePath, sourceFileType, multipleSourceFilePaths);

//validate alternate location restore request
ValidateLocationRestoreRequest(targetFileShareName, targetStorageAccountName);
ValidateLocationRestoreRequest(targetFileShareName, targetStorageAccountName, targetFolder);

if (targetFileShareName != null && targetStorageAccountName != null && targetFolder == null)
{
Expand Down Expand Up @@ -228,6 +230,31 @@ public RestAzureNS.AzureOperationResponse TriggerRestore()
restoreFileSpecs = new List<RestoreFileSpecs>();
restoreFileSpecs.Add(restoreFileSpec);
}
else if(multipleSourceFilePaths != null)
{
restoreFileSpecs = new List<RestoreFileSpecs>();
foreach (string filepath in multipleSourceFilePaths)
{
RestoreFileSpecs fileSpec = new RestoreFileSpecs();
fileSpec.Path = filepath;
fileSpec.FileSpecType = sourceFileType;
restoreRequest.RestoreRequestType = RestoreRequestType.ItemLevelRestore;
if(targetFolder != null)
{
fileSpec.TargetFolderPath = targetFolder;
targetDetails = new TargetAFSRestoreInfo();
targetDetails.Name = targetFileShareName;
targetDetails.TargetResourceId = targetStorageAccountResource.Id;
restoreRequest.RecoveryType = RecoveryType.AlternateLocation;
}
else
{
fileSpec.TargetFolderPath = null;
restoreRequest.RecoveryType = RecoveryType.OriginalLocation;
}
restoreFileSpecs.Add(fileSpec);
}
}
else
{
restoreRequest.RestoreRequestType = RestoreRequestType.FullShareRestore;
Expand Down Expand Up @@ -884,19 +911,24 @@ private void ValidateAzureFilesModifyProtectionRequest(ItemBase itemBase,
}
}

private void ValidateFileRestoreRequest(string sourceFilePath, string sourceFileType)
private void ValidateFileRestoreRequest(string sourceFilePath, string sourceFileType,
string[] multipleSourceFilePaths)
{
if (sourceFilePath == null && sourceFileType != null)
if (sourceFilePath == null && multipleSourceFilePaths == null && sourceFileType != null)
{
throw new ArgumentException(string.Format(Resources.AzureFileSourceFilePathMissingException));
}
else if (sourceFilePath != null && sourceFileType == null)
{
throw new ArgumentException(string.Format(Resources.AzureFileSourceFileTypeMissingException));
}
else if(sourceFilePath != null && multipleSourceFilePaths != null)
{
throw new ArgumentException(string.Format(Resources.AzureFileSourceFilePathRedundantException));
}
}

private void ValidateLocationRestoreRequest(string targetFileShareName, string targetStorageAccountName)
private void ValidateLocationRestoreRequest(string targetFileShareName, string targetStorageAccountName, string targetFolder)
{
if (targetFileShareName == null && targetStorageAccountName != null)
{
Expand All @@ -906,6 +938,10 @@ private void ValidateLocationRestoreRequest(string targetFileShareName, string t
{
throw new ArgumentException(string.Format(Resources.AzureFileTargetSANameMissingException));
}
else if(targetFolder != null && targetFileShareName == null && targetStorageAccountName == null)
{
throw new ArgumentException(string.Format(Resources.AzureFileTargetSANameMissingException));
}
}

public List<PointInTimeBase> GetLogChains()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ $targetFileShareName = "fs1"
$targetFolder = "pstestfolder3rty7d7s"
$folderPath = "pstestfolder1bca8f8e"
$filePath = "pstestfolder1bca8f8e/pstestfile1bca8f8e.txt"
$file1 = "file1.txt"
$file2 = "file2.txt"
$skuName="Standard_LRS"
$policyName = "afspolicy1"
$newPolicyName = "NewAFSBackupPolicy"
Expand Down Expand Up @@ -314,6 +316,19 @@ function Test-AzureFSFullRestore
-ResolveConflict Overwrite `
-SourceFilePath $filePath } `
"Provide SourceFileType for File restore or remove SourceFilePath for file share restore"

# Multiple Files Restore
$files = ($file1, $file2)
$restoreJob = Restore-AzRecoveryServicesBackupItem `
-VaultId $vault.ID `
-VaultLocation $vault.Location `
-RecoveryPoint $recoveryPoint[0] `
-MultipleSourceFilePath $files `
-SourceFileType File `
-ResolveConflict Overwrite | `
Wait-AzRecoveryServicesBackupJob -VaultId $vault.ID

Assert-True { $restoreJob.Status -eq "Completed" }

# Test without storage account dependancy
# Item level restore at alternate location
Expand Down
Loading