Skip to content

Commit b91a4f6

Browse files
hiagadingmeng-xue
andauthored
Adding Cross Tenant DS move (#15185)
updated help text added new CRR regions Co-authored-by: Dingmeng Xue <[email protected]>
1 parent 1299bac commit b91a4f6

File tree

13 files changed

+675
-97
lines changed

13 files changed

+675
-97
lines changed

src/RecoveryServices/RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,6 @@ public List<RecoveryPointBase> ListRecoveryPoints(Dictionary<Enum, object> Provi
379379
string containerUri = HelperUtils.GetContainerUri(uriDict, item.Id);
380380
string protectedItemName = HelperUtils.GetProtectedItemUri(uriDict, item.Id);
381381

382-
TimeSpan duration = endDate - startDate;
383-
if (duration.TotalDays > 30)
384-
{
385-
throw new Exception(Resources.RestoreDiskTimeRangeError);
386-
}
387-
388382
//we need to fetch the list of RPs
389383
var queryFilterString = "null";
390384
if (string.Compare(restorePointQueryType, "All") == 0)
@@ -448,12 +442,6 @@ public List<PointInTimeBase> ListLogChains(Dictionary<Enum, object> ProviderData
448442
string containerUri = HelperUtils.GetContainerUri(uriDict, item.Id);
449443
string protectedItemName = HelperUtils.GetProtectedItemUri(uriDict, item.Id);
450444

451-
TimeSpan duration = endDate - startDate;
452-
if (duration.TotalDays > 30)
453-
{
454-
throw new Exception(Resources.RestoreDiskTimeRangeError);
455-
}
456-
457445
//we need to fetch the list of RPs
458446
var queryFilterString = QueryBuilder.Instance.GetQueryString(new BMSRPQueryObject()
459447
{

src/RecoveryServices/RecoveryServices.Backup.ServiceClientAdapter/BMSAPIs/VaultAPIs.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using System.Collections.Generic;
1616
using System.Linq;
17+
using Microsoft.Azure.Commands.RecoveryServices.Backup.Helpers;
1718
using Microsoft.Azure.Management.RecoveryServices.Backup.Models;
1819
using Microsoft.Azure.Management.RecoveryServices.Models;
1920
using Microsoft.Rest.Azure.OData;
@@ -114,5 +115,55 @@ public AADPropertiesResource GetAADProperties(string azureRegion, string backupM
114115
AADPropertiesResource aadProperties = BmsAdapter.Client.AadProperties.GetWithHttpMessagesAsync(azureRegion, queryParams).Result.Body;
115116
return aadProperties;
116117
}
118+
119+
/// <summary>
120+
/// This method prepares the source vault for Data Move operation.
121+
/// </summary>
122+
/// <param name="vaultName"></param>
123+
/// <param name="resourceGroupName"></param>
124+
/// <param name="prepareMoveRequest"></param>
125+
public string PrepareDataMove(string vaultName, string resourceGroupName, PrepareDataMoveRequest prepareMoveRequest)
126+
{
127+
// prepare move
128+
var prepareMoveOperationResponse = BmsAdapter.Client.BeginBMSPrepareDataMoveWithHttpMessagesAsync(
129+
vaultName, resourceGroupName, prepareMoveRequest).Result;
130+
131+
// track prepare-move operation to success
132+
var operationStatus = TrackingHelpers.GetOperationStatusDataMove(
133+
prepareMoveOperationResponse,
134+
operationId => GetDataMoveOperationStatus(operationId, vaultName, resourceGroupName));
135+
136+
Logger.Instance.WriteDebug("Prepare move operation: " + operationStatus.Body.Status);
137+
138+
// get the correlation Id and return it for trigger data move
139+
var operationResult = TrackingHelpers.GetCorrelationId(
140+
prepareMoveOperationResponse,
141+
operationId => GetPrepareDataMoveOperationResult(operationId, vaultName, resourceGroupName));
142+
143+
Logger.Instance.WriteDebug("Prepare move - correlationId:" + operationResult.CorrelationId);
144+
145+
return operationResult.CorrelationId;
146+
}
147+
148+
/// <summary>
149+
/// This method triggers the Data Move operation on Target vault.
150+
/// </summary>
151+
/// <param name="vaultName"></param>
152+
/// <param name="resourceGroupName"></param>
153+
/// <param name="triggerMoveRequest"></param>
154+
public void TriggerDataMove(string vaultName, string resourceGroupName, TriggerDataMoveRequest triggerMoveRequest)
155+
{
156+
//trigger move
157+
var triggerMoveOperationResponse = BmsAdapter.Client.BeginBMSTriggerDataMoveWithHttpMessagesAsync(
158+
vaultName, resourceGroupName, triggerMoveRequest).Result;
159+
160+
// track trigger-move operation to success
161+
var operationStatus = TrackingHelpers.GetOperationStatusDataMove(
162+
triggerMoveOperationResponse,
163+
operationId => GetDataMoveOperationStatus(operationId, vaultName, resourceGroupName));
164+
165+
Logger.Instance.WriteDebug("Trigger move operation: " + operationStatus.Body.Status);
166+
167+
}
117168
}
118169
}

src/RecoveryServices/RecoveryServices.Backup/Cmdlets/Vault/CopyAzureRmRecoveryServicesVault.cs

Lines changed: 55 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,54 @@ namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets
2626
/// <summary>
2727
/// Used for Data Source Move operation. Currently we only support vault level data move from one region to another.
2828
/// </summary>
29-
[Cmdlet("Copy", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "RecoveryServicesVault", SupportsShouldProcess = true), OutputType(typeof(String))]
29+
[Cmdlet("Copy", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "RecoveryServicesVault",
30+
DefaultParameterSetName = AzureRSVaultDataMoveParameterSet, SupportsShouldProcess = true), OutputType(typeof(String))]
3031
public class CopyAzureRmRecoveryServicesVault : RecoveryServicesBackupCmdletBase
3132
{
3233
#region Parameters
3334

35+
internal const string AzureRSVaultDataMoveParameterSet = "AzureRSVaultDataMoveParameterSet";
36+
internal const string AzureRSVaultTriggerMoveParameterSet = "AzureRSVaultTriggerMoveParameterSet";
37+
3438
/// <summary>
3539
/// Source Vault for Data Move Operation
3640
/// </summary>
37-
[Parameter(Position = 1, Mandatory = true, HelpMessage = ParamHelpMsgs.DSMove.SourceVault,
41+
[Parameter(Position = 1, Mandatory = true, ParameterSetName = AzureRSVaultDataMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.SourceVault,
42+
ValueFromPipeline = true)]
43+
[Parameter(Position = 1, Mandatory = true, ParameterSetName = AzureRSVaultTriggerMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.SourceVault,
3844
ValueFromPipeline = true)]
3945
[ValidateNotNullOrEmpty]
4046
public ARSVault SourceVault;
4147

4248
/// <summary>
4349
/// Target Vault for Data Move Operation
4450
/// </summary>
45-
[Parameter(Position = 2, Mandatory = true, HelpMessage = ParamHelpMsgs.DSMove.TargetVault,
51+
[Parameter(Position = 2, Mandatory = true, ParameterSetName = AzureRSVaultDataMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.TargetVault,
52+
ValueFromPipeline = true)]
53+
[Parameter(Position = 2, Mandatory = true, ParameterSetName = AzureRSVaultTriggerMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.TargetVault,
4654
ValueFromPipeline = true)]
4755
[ValidateNotNullOrEmpty]
4856
public ARSVault TargetVault;
4957

5058
/// <summary>
5159
/// Retries data move only with unmoved containers in the source vault
5260
/// </summary>
53-
[Parameter(Mandatory = false, HelpMessage = ParamHelpMsgs.DSMove.RetryOnlyFailed)]
61+
[Parameter(Mandatory = false, ParameterSetName = AzureRSVaultDataMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.RetryOnlyFailed)]
5462
public SwitchParameter RetryOnlyFailed;
5563

5664
/// <summary>
5765
/// Prevents the confirmation dialog when specified.
5866
/// </summary>
59-
[Parameter(Mandatory = false, HelpMessage = ParamHelpMsgs.DSMove.ForceOption)]
67+
[Parameter(Mandatory = false, ParameterSetName = AzureRSVaultDataMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.ForceOption)]
68+
[Parameter(Mandatory = false, ParameterSetName = AzureRSVaultTriggerMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.ForceOption)]
6069
public SwitchParameter Force { get; set; }
6170

71+
/// <summary>
72+
/// Prevents the confirmation dialog when specified.
73+
/// </summary>
74+
[Parameter(Mandatory = true, ParameterSetName = AzureRSVaultTriggerMoveParameterSet, HelpMessage = ParamHelpMsgs.DSMove.CorrelationId)]
75+
public String CorrelationIdForDataMove { get; set; }
76+
6277
#endregion Parameters
6378

6479
public override void ExecuteCmdlet()
@@ -99,13 +114,14 @@ public override void ExecuteCmdlet()
99114
{
100115
throw new ArgumentException(string.Format(Resources.TargetVaultNotEmptyException));
101116
}
102-
117+
103118
// Confirm the target vault storage type
104119
BackupResourceConfigResource getStorageResponse = ServiceClientAdapter.GetVaultStorageType(
105120
TargetVault.ResourceGroupName, TargetVault.Name);
106121

107-
Logger.Instance.WriteDebug("Storage Type: " + getStorageResponse.Properties.StorageType);
108-
122+
Logger.Instance.WriteDebug("Storage Type: " + getStorageResponse.Properties.StorageType);
123+
124+
string correlationId = "";
109125
ConfirmAction(
110126
Force.IsPresent,
111127
string.Format(Resources.TargetVaultStorageRedundancy, TargetVault.Name, getStorageResponse.Properties.StorageType),
@@ -114,31 +130,38 @@ public override void ExecuteCmdlet()
114130
{
115131
base.ExecuteCmdlet();
116132

117-
// Prepare Data Move
118-
ServiceClientAdapter.BmsAdapter.Client.SubscriptionId = sourceSub; // set source subscription
119-
PrepareDataMoveRequest prepareMoveRequest = new PrepareDataMoveRequest();
120-
prepareMoveRequest.TargetResourceId = TargetVault.ID;
121-
prepareMoveRequest.TargetRegion = TargetVault.Location;
122-
123-
/// currently only allowing vault level data move
124-
prepareMoveRequest.DataMoveLevel = "Vault";
125-
126-
if (RetryOnlyFailed.IsPresent)
133+
if (string.Compare(ParameterSetName, AzureRSVaultDataMoveParameterSet) == 0)
127134
{
128-
prepareMoveRequest.IgnoreMoved = true;
135+
// Prepare Data Move
136+
ServiceClientAdapter.BmsAdapter.Client.SubscriptionId = sourceSub;
137+
PrepareDataMoveRequest prepareMoveRequest = new PrepareDataMoveRequest();
138+
prepareMoveRequest.TargetResourceId = TargetVault.ID;
139+
prepareMoveRequest.TargetRegion = TargetVault.Location;
140+
141+
/// currently only allowing vault level data move
142+
prepareMoveRequest.DataMoveLevel = "Vault";
143+
144+
if (RetryOnlyFailed.IsPresent)
145+
{
146+
prepareMoveRequest.IgnoreMoved = true;
147+
}
148+
else
149+
{
150+
prepareMoveRequest.IgnoreMoved = false;
151+
}
152+
153+
Logger.Instance.WriteDebug("Retry only with failed items : " + prepareMoveRequest.IgnoreMoved);
154+
Logger.Instance.WriteDebug("Location of Target vault: " + TargetVault.Location);
155+
156+
correlationId = ServiceClientAdapter.PrepareDataMove(SourceVault.Name, SourceVault.ResourceGroupName, prepareMoveRequest);
129157
}
130158
else
131159
{
132-
prepareMoveRequest.IgnoreMoved = false;
160+
correlationId = CorrelationIdForDataMove;
133161
}
134162

135-
Logger.Instance.WriteDebug("Retry only with failed items : " + prepareMoveRequest.IgnoreMoved);
136-
Logger.Instance.WriteDebug("Location of Target vault: " + TargetVault.Location);
137-
138-
string correlationId = PrepareDataMove(SourceVault.Name, SourceVault.ResourceGroupName, prepareMoveRequest);
139-
140163
// Trigger Data Move
141-
ServiceClientAdapter.BmsAdapter.Client.SubscriptionId = targetSub; // set target subscription
164+
ServiceClientAdapter.BmsAdapter.Client.SubscriptionId = targetSub;
142165
TriggerDataMoveRequest triggerMoveRequest = new TriggerDataMoveRequest();
143166
triggerMoveRequest.SourceResourceId = SourceVault.ID;
144167
triggerMoveRequest.SourceRegion = SourceVault.Location;
@@ -149,63 +172,15 @@ public override void ExecuteCmdlet()
149172
triggerMoveRequest.PauseGC = false;
150173

151174
Logger.Instance.WriteDebug("Location of Source vault: " + SourceVault.Location);
152-
TriggerDataMove(TargetVault.Name, TargetVault.ResourceGroupName, triggerMoveRequest);
175+
ServiceClientAdapter.TriggerDataMove(TargetVault.Name, TargetVault.ResourceGroupName, triggerMoveRequest);
176+
177+
// set subscription to original
178+
ServiceClientAdapter.BmsAdapter.Client.SubscriptionId = subscriptionContext;
153179

154-
ServiceClientAdapter.BmsAdapter.Client.SubscriptionId = subscriptionContext; // set subscription to original
155-
WriteObject(ParamHelpMsgs.DSMove.CmdletOutput);
180+
WriteObject(ParamHelpMsgs.DSMove.CmdletOutput);
156181
}
157-
);
182+
);
158183
}, ShouldProcess(TargetVault.Name, VerbsCommon.Set));
159184
}
160-
161-
/// <summary>
162-
/// This method prepares the source vault for Data Move operation.
163-
/// </summary>
164-
/// <param name="vaultName"></param>
165-
/// <param name="resourceGroupName"></param>
166-
/// <param name="prepareMoveRequest"></param>
167-
public string PrepareDataMove(string vaultName, string resourceGroupName, PrepareDataMoveRequest prepareMoveRequest)
168-
{
169-
// prepare move
170-
var prepareMoveOperationResponse = ServiceClientAdapter.BmsAdapter.Client.BeginBMSPrepareDataMoveWithHttpMessagesAsync(
171-
vaultName, resourceGroupName, prepareMoveRequest).Result;
172-
173-
// track prepare-move operation to success
174-
var operationStatus = TrackingHelpers.GetOperationStatusDataMove(
175-
prepareMoveOperationResponse,
176-
operationId => ServiceClientAdapter.GetDataMoveOperationStatus(operationId, vaultName, resourceGroupName));
177-
178-
Logger.Instance.WriteDebug("Prepare move operation: " + operationStatus.Body.Status);
179-
180-
// get the correlation Id and return it for trigger data move
181-
var operationResult = TrackingHelpers.GetCorrelationId(
182-
prepareMoveOperationResponse,
183-
operationId => ServiceClientAdapter.GetPrepareDataMoveOperationResult(operationId, vaultName, resourceGroupName));
184-
185-
Logger.Instance.WriteDebug("Prepare move - correlationId:" + operationResult.CorrelationId);
186-
187-
return operationResult.CorrelationId;
188-
}
189-
190-
/// <summary>
191-
/// This method triggers the Data Move operation on Target vault.
192-
/// </summary>
193-
/// <param name="vaultName"></param>
194-
/// <param name="resourceGroupName"></param>
195-
/// <param name="triggerMoveRequest"></param>
196-
public void TriggerDataMove(string vaultName, string resourceGroupName, TriggerDataMoveRequest triggerMoveRequest)
197-
{
198-
//trigger move
199-
var triggerMoveOperationResponse = ServiceClientAdapter.BmsAdapter.Client.BeginBMSTriggerDataMoveWithHttpMessagesAsync(
200-
vaultName, resourceGroupName, triggerMoveRequest).Result;
201-
202-
// track trigger-move operation to success
203-
var operationStatus = TrackingHelpers.GetOperationStatusDataMove(
204-
triggerMoveOperationResponse,
205-
operationId => ServiceClientAdapter.GetDataMoveOperationStatus(operationId, vaultName, resourceGroupName));
206-
207-
Logger.Instance.WriteDebug("Trigger move operation: " + operationStatus.Body.Status);
208-
209-
}
210185
}
211186
}

0 commit comments

Comments
 (0)