Skip to content

Commit 45ad5d4

Browse files
author
Samuel Anudeep
committed
Merge pull request #233 from MabOneSdk/anudeeb-dev1
Trigger Backup Cmdlet
2 parents b912da7 + de25b84 commit 45ad5d4

File tree

14 files changed

+166
-56
lines changed

14 files changed

+166
-56
lines changed

src/ResourceManager/RecoveryServices.Backup/CmdletParameterHelpMessages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ internal static class Item
7373
public const string Status = "Status of the data source";
7474
public const string Container = "Container where the item resides";
7575
public const string RemoveProtectionOption = "If this option is used, all the backup data for this item will also be deleted and restoring data will not be possible.";
76+
public const string ExpiryDate = "Retention period for the recovery points created by this backup operaiton";
7677
}
7778

7879
internal static class RecoveryPoint

src/ResourceManager/RecoveryServices.Backup/Cmdlets/Item/EnableAzureRmRecoveryServicesProtection.cs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -83,29 +83,7 @@ public override void ExecuteCmdlet()
8383

8484
// Track Response and display job details
8585

86-
WriteDebug(Resources.TrackingOperationStatusURLForCompletion +
87-
itemResponse.AzureAsyncOperation);
88-
89-
var response = WaitForOperationCompletionUsingStatusLink(
90-
itemResponse.AzureAsyncOperation,
91-
HydraAdapter.GetProtectedItemOperationStatusByURL);
92-
93-
WriteDebug(Resources.FinalOperationStatus + response.OperationStatus.Status);
94-
95-
if (response.OperationStatus.Properties != null &&
96-
((HydraModel.OperationStatusJobExtendedInfo)response.OperationStatus.Properties).JobId != null)
97-
{
98-
var jobStatusResponse = (HydraModel.OperationStatusJobExtendedInfo)response.OperationStatus.Properties;
99-
WriteObject(GetJobObject(jobStatusResponse.JobId));
100-
}
101-
102-
if(response.OperationStatus.Status == HydraModel.OperationStatusValues.Failed)
103-
{
104-
var errorMessage = string.Format(Resources.EnableProtectionOperationFailed,
105-
response.OperationStatus.OperationStatusError.Code,
106-
response.OperationStatus.OperationStatusError.Message);
107-
throw new Exception(errorMessage);
108-
}
86+
HandleCreatedJob(itemResponse, Resources.EnableProtectionOperation);
10987
});
11088
}
11189
}

src/ResourceManager/RecoveryServices.Backup/Commands.RecoveryServices.Backup.Cmdlets.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
<Compile Include="Cmdlets\Container\UnregisterAzureRmBackupManagementServer.cs" />
8484
<Compile Include="Cmdlets\Container\UnregisterAzureRmRecoveryServicesBackupContainer.cs" />
8585
<Compile Include="Cmdlets\Item\DisableAzureRmRecoveryServicesProtection.cs" />
86+
<Compile Include="Cmdlets\Backup\BackupAzureRmRecoveryServicesItem.cs" />
8687
<Compile Include="Cmdlets\Item\EnableAzureRmRecoveryServicesProtection.cs" />
8788
<Compile Include="Cmdlets\Item\GetAzureRmRecoveryServicesItem.cs" />
8889
<Compile Include="Cmdlets\Jobs\GetAzureRmRecoveryServicesJob.cs" />
@@ -103,9 +104,7 @@
103104
<Compile Include="RecoveryServicesBackupCmdletBase.cs" />
104105
<Compile Include="CmdletParameterHelpMessages.cs" />
105106
</ItemGroup>
106-
<ItemGroup>
107-
<Folder Include="Cmdlets\Backup\" />
108-
</ItemGroup>
107+
<ItemGroup />
109108
<ItemGroup>
110109
<ProjectReference Include="..\..\Common\Commands.Common.Authentication\Commands.Common.Authentication.csproj">
111110
<Project>{d3804b64-c0d3-48f8-82ec-1f632f833c9e}</Project>

src/ResourceManager/RecoveryServices.Backup/Commands.RecoveryServices.Backup.Helpers/HydraHelpers.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,26 @@ public static string GetHydraProviderType(CmdletModel.WorkloadType workloadType)
5959
return providerType;
6060
}
6161

62-
public static void GetSkipTokenFromNextLink(string url, out string nextLink)
62+
public static void GetSkipTokenFromNextLink(string nextLink, out string skipToken)
6363
{
64-
Uri uriObj = new Uri(url);
65-
// This is sent by service and we don't expect this to be encoded.
66-
// TODO: Need to make sure during testing that this is in fact true.
67-
NameValueCollection queryParams = HttpUtility.ParseQueryString(uriObj.Query);
68-
if (queryParams.Get(HydraConstants.SkipToken) != null)
64+
if (nextLink != null)
6965
{
70-
nextLink = queryParams.Get(HydraConstants.SkipToken);
66+
Uri uriObj = new Uri(nextLink);
67+
// This is sent by service and we don't expect this to be encoded.
68+
// TODO: Need to make sure during testing that this is in fact true.
69+
NameValueCollection queryParams = HttpUtility.ParseQueryString(uriObj.Query);
70+
if (queryParams.Get(HydraConstants.SkipToken) != null)
71+
{
72+
skipToken = queryParams.Get(HydraConstants.SkipToken);
73+
}
74+
else
75+
{
76+
skipToken = null;
77+
}
7178
}
7279
else
7380
{
74-
nextLink = null;
81+
skipToken = null;
7582
}
7683
}
7784

src/ResourceManager/RecoveryServices.Backup/Commands.RecoveryServices.Backup.HydraAdapter/BMSAPIs/ProtectableItemAPI.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,17 @@ public ProtectableObjectListResponse ListProtectableItem(
3838
BmsAdapter.GetCustomRequestHeaders(),
3939
BmsAdapter.CmdletCancellationToken).Result;
4040
}
41+
42+
public BaseRecoveryServicesJobResponse TriggerBackup(string containerName, string itemName)
43+
{
44+
return BmsAdapter.Client.Backup.TriggerBackupAsync(
45+
BmsAdapter.GetResourceGroupName(),
46+
BmsAdapter.GetResourceName(),
47+
BmsAdapter.GetCustomRequestHeaders(),
48+
HydraAdapter.AzureFabricName,
49+
containerName,
50+
itemName,
51+
BmsAdapter.CmdletCancellationToken).Result;
52+
}
4153
}
4254
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public enum ItemParams
7070
Container,
7171
ProtectionStatus,
7272
Status,
73-
DeleteBackupData
73+
DeleteBackupData,
74+
ExpiryDate,
7475
}
7576
}

src/ResourceManager/RecoveryServices.Backup/Commands.RecoveryServices.Backup.Models/CommonModels/Utils.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ public class IdUtils
6262
{
6363
static readonly Regex ResourceGroupRegex = new Regex(@"/Subscriptions/(?<subscriptionsId>.+)/resourceGroups/(?<resourceGroupName>.+)/providers/(?<providersName>.+)/vaults/(?<BackupVaultName>.+)/backupFabrics/(?<BackupFabricName>.+)/protectionContainers/(?<containersName>.+)", RegexOptions.Compiled);
6464
const string NameDelimiter = ";";
65+
const string IdDelimiter = "/";
66+
67+
public class IdNames
68+
{
69+
public const string SubscriptionId = "Subscriptions";
70+
public const string ResourceGroup = "resourceGroups";
71+
public const string Provider = "providers";
72+
public const string Vault = "vaults";
73+
public const string BackupFabric = "backupFabrics";
74+
public const string ProtectionContainerName = "protectionContainers";
75+
public const string ProtectedItemName = "protectedItems";
76+
}
6577

6678
public static string GetResourceGroupName(string id)
6779
{
@@ -89,6 +101,19 @@ public static string GetResourceGroupName(string id)
89101

90102
return null;
91103
}
104+
105+
public static string GetValueByName(string id, string idName)
106+
{
107+
var parts = id.Split(IdDelimiter.ToArray(), StringSplitOptions.RemoveEmptyEntries)
108+
.Select((x, i) => new { Index = i, Value = x })
109+
.GroupBy(x => x.Index % 2)
110+
.ToList();
111+
112+
var dict = parts[0].ToList().Zip(parts[1].ToList(), (k, v) => new { k, v })
113+
.ToDictionary(x => x.k.Value, x => x.v.Value);
114+
115+
return dict[idName];
116+
}
92117
}
93118

94119
public class EnumUtils

src/ResourceManager/RecoveryServices.Backup/Commands.RecoveryServices.Backup.Models/Properties/Resources.Designer.cs

Lines changed: 21 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ResourceManager/RecoveryServices.Backup/Commands.RecoveryServices.Backup.Models/Properties/Resources.resx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,8 @@ Please contact Microsoft for further assistant.</value>
326326
<data name="BothCloudServiceNameAndResourceGroupNameShouldNotEmpty" xml:space="preserve">
327327
<value>For Azure VM, both cloud service name and resource group name can not be empty</value>
328328
</data>
329-
<data name="EnableProtectionOperationFailed" xml:space="preserve">
330-
<value>Enable Protection OperationFailed with error code: {0} , and error Message: {1}</value>
329+
<data name="EnableProtectionOperation" xml:space="preserve">
330+
<value>Enable Protection Operation</value>
331331
</data>
332332
<data name="RemoveProtectionPolicyMessage" xml:space="preserve">
333333
<value>Removing the protection policy</value>
@@ -362,4 +362,10 @@ Please contact Microsoft for further assistant.</value>
362362
<data name="PolicyNameIsEmptyOrNull" xml:space="preserve">
363363
<value>PolicyName is NULL or Empty. Please enter valid PolicyName</value>
364364
</data>
365+
<data name="OperationFailed" xml:space="preserve">
366+
<value>{0} failed. Error Code: {1}. Error Message: {2}</value>
367+
</data>
368+
<data name="TriggerBackupOperation" xml:space="preserve">
369+
<value>Trigger Backup Operation</value>
370+
</data>
365371
</root>

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

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public BaseRecoveryServicesJobResponse EnableProtection()
6464
AzureRmRecoveryServicesIaasVmItem item = (AzureRmRecoveryServicesIaasVmItem)
6565
ProviderData.ProviderParameters[ItemParams.Item];
6666
// do validations
67-
67+
6868
string containerUri = "";
6969
string protectedItemUri = "";
7070
bool isComputeAzureVM = false;
@@ -88,7 +88,7 @@ public BaseRecoveryServicesJobResponse EnableProtection()
8888
ValidateAzureVMWorkloadType(item.WorkloadType, policy.WorkloadType);
8989
ValidateAzureVMModifyProtectionRequest(itemBase, policy);
9090

91-
isComputeAzureVM = IsComputeAzureVM(item.VirtualMachineId);
91+
isComputeAzureVM = IsComputeAzureVM(item.VirtualMachineId);
9292

9393
string containerType = HydraHelpers.GetHydraContainerType(item.ContainerType);
9494
string vmType = HydraHelpers.GetHydraWorkloadType(item.WorkloadType);
@@ -186,7 +186,11 @@ public BaseRecoveryServicesJobResponse DisableProtection()
186186

187187
public BaseRecoveryServicesJobResponse TriggerBackup()
188188
{
189-
throw new NotImplementedException();
189+
AzureRmRecoveryServicesItemBase item = (AzureRmRecoveryServicesItemBase)ProviderData.ProviderParameters[ItemParams.Item];
190+
DateTime expiryDate = (DateTime)ProviderData.ProviderParameters[ItemParams.ExpiryDate];
191+
AzureRmRecoveryServicesIaasVmItem iaasVmItem = item as AzureRmRecoveryServicesIaasVmItem;
192+
return HydraAdapter.TriggerBackup(IdUtils.GetValueByName(iaasVmItem.Id, IdUtils.IdNames.ProtectionContainerName),
193+
IdUtils.GetValueByName(iaasVmItem.Id, IdUtils.IdNames.ProtectedItemName));
190194
}
191195

192196
public BaseRecoveryServicesJobResponse TriggerRestore()
@@ -195,7 +199,7 @@ public BaseRecoveryServicesJobResponse TriggerRestore()
195199
as AzureRmRecoveryServicesIaasVmRecoveryPoint;
196200
string storageId = ProviderData.ProviderParameters[RestoreBackupItemParams.StorageAccountId].ToString();
197201

198-
if(rp == null)
202+
if (rp == null)
199203
{
200204
throw new InvalidCastException("Cant convert input to AzureRmRecoveryServicesIaasVmRecoveryPoint");
201205
}
@@ -430,9 +434,23 @@ public List<AzureRmRecoveryServicesItemBase> ListProtectedItems()
430434
queryParams.DatasourceType = Microsoft.Azure.Management.RecoveryServices.Backup.Models.WorkloadType.VM;
431435
queryParams.ProviderType = ProviderType.AzureIaasVM.ToString();
432436

433-
var listResponse = HydraAdapter.ListProtectedItem(queryParams);
437+
List<ProtectedItemResource> protectedItems = new List<ProtectedItemResource>();
438+
string skipToken = null;
439+
PaginationRequest paginationRequest = null;
440+
do
441+
{
442+
var listResponse = HydraAdapter.ListProtectedItem(queryParams, paginationRequest);
443+
protectedItems.AddRange(listResponse.ItemList.Value);
444+
445+
HydraHelpers.GetSkipTokenFromNextLink(listResponse.ItemList.NextLink, out skipToken);
446+
if (skipToken != null)
447+
{
448+
paginationRequest = new PaginationRequest();
449+
paginationRequest.SkipToken = skipToken;
450+
}
451+
} while (skipToken != null);
434452

435-
List<AzureRmRecoveryServicesItemBase> itemModels = ConversionHelpers.GetItemModelList(listResponse.ItemList.Value, container);
453+
List<AzureRmRecoveryServicesItemBase> itemModels = ConversionHelpers.GetItemModelList(protectedItems, container);
436454

437455
// 1. Filter by container
438456
itemModels = itemModels.Where(itemModel =>
@@ -654,11 +672,12 @@ private void ValidateAzureVMRetentionPolicy(AzureRmRecoveryServicesRetentionPoli
654672
private void ValidateAzureVMEnableProtectionRequest(string vmName, string serviceName, string rgName,
655673
AzureRmRecoveryServicesPolicyBase policy)
656674
{
657-
if(string.IsNullOrEmpty(vmName))
675+
ValidateAzureVMProtectionPolicy(policy);
676+
if (string.IsNullOrEmpty(vmName))
658677
{
659678
throw new ArgumentException(string.Format(Resources.InvalidAzureVMName));
660679
}
661-
if(string.IsNullOrEmpty(rgName) && string.IsNullOrEmpty(serviceName))
680+
if (string.IsNullOrEmpty(rgName) && string.IsNullOrEmpty(serviceName))
662681
{
663682
throw new ArgumentException(string.Format(Resources.BothCloudServiceNameAndResourceGroupNameShouldNotEmpty));
664683
}
@@ -690,7 +709,7 @@ private void ValidateAzureVMDisableProtectionRequest(AzureRmRecoveryServicesItem
690709
private bool IsComputeAzureVM(string virtualMachineId)
691710
{
692711
bool isComputeAzureVM = true;
693-
if(virtualMachineId.IndexOf(classicComputeAzureVMVersion, StringComparison.InvariantCultureIgnoreCase) >=0)
712+
if (virtualMachineId.IndexOf(classicComputeAzureVMVersion, StringComparison.InvariantCultureIgnoreCase) >= 0)
694713
{
695714
isComputeAzureVM = false;
696715
}
@@ -781,9 +800,9 @@ private void RefreshContainer()
781800
{
782801
bool isDiscoverySuccessful = false;
783802
string errorMessage = string.Empty;
784-
var refreshContainerJobResponse = HydraAdapter.RefreshContainers();
803+
var refreshContainerJobResponse = HydraAdapter.RefreshContainers();
785804

786-
//Now wait for the operation to Complete
805+
//Now wait for the operation to Complete
787806
WaitForDiscoveryToComplete(refreshContainerJobResponse.Location, out isDiscoverySuccessful, out errorMessage);
788807

789808
if (!isDiscoverySuccessful)

src/ResourceManager/RecoveryServices.Backup/Commands.RecoveryServices.Backup.Providers/PsBackupProviderManager.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ public IPsBackupProvider GetProviderInstance(ContainerType containerType, Backup
4242
switch (containerType)
4343
{
4444
case ContainerType.AzureVM:
45-
if (backupManagementType.HasValue && backupManagementType != BackupManagementType.AzureVM)
46-
{
47-
throw new ArgumentException("BackupManagementType is not expected for ContainerType: " +
48-
containerType.ToString());
49-
}
5045
providerType = PsBackupProviderTypes.IaasVm;
5146
break;
5247
case ContainerType.Windows:

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,11 @@ public void TestDisableAzureVMProtectionScenario()
4545
{
4646
this.RunPowerShellTest(PsBackupProviderTypes.IaasVm.ToString(), "Test-DisableAzureVMProtectionScenario");
4747
}
48+
49+
[Fact]
50+
public void TestBackupItemScenario()
51+
{
52+
this.RunPowerShellTest(PsBackupProviderTypes.IaasVm.ToString(), "Test-BackupItemScenario");
53+
}
4854
}
4955
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,18 @@ function Test-DisableAzureVMProtectionScenario
4848

4949
$job = Disable-AzureRmRecoveryServicesProtection -Item $item -Force;
5050
Assert-AreEqual $job.Status "Completed";
51+
}
52+
53+
function Test-BackupItemScenario
54+
{
55+
$vault = Get-AzureRmRecoveryServicesVault -ResourceGroupName "pstestrg" -Name "pstestrsvault";
56+
Set-AzureRmRecoveryServicesVaultContext -Vault $vault;
57+
58+
$namedContainer = Get-AzureRmRecoveryServicesContainer -ContainerType "AzureVM" -Status "Registered" -Name "pstestv2vm1";
59+
Assert-AreEqual $namedContainer.FriendlyName "pstestv2vm1";
60+
61+
$item = Get-AzureRmRecoveryServicesItem -Container $namedContainer -WorkloadType "AzureVM";
62+
echo $item.Name;
63+
64+
Backup-AzureRmRecoveryServicesItem -Item $item;
5165
}

0 commit comments

Comments
 (0)