1+ // ----------------------------------------------------------------------------------
2+ //
3+ // Copyright Microsoft Corporation
4+ // Licensed under the Apache License, Version 2.0 (the "License");
5+ // you may not use this file except in compliance with the License.
6+ // You may obtain a copy of the License at
7+ // http://www.apache.org/licenses/LICENSE-2.0
8+ // Unless required by applicable law or agreed to in writing, software
9+ // distributed under the License is distributed on an "AS IS" BASIS,
10+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+ // See the License for the specific language governing permissions and
12+ // limitations under the License.
13+ // ----------------------------------------------------------------------------------
14+
15+ using Microsoft . Azure . Commands . RecoveryServices . Backup . Cmdlets . Models ;
16+ using Microsoft . Azure . Commands . RecoveryServices . Backup . Cmdlets . ProviderModel ;
17+ using Microsoft . Azure . Commands . RecoveryServices . Backup . Cmdlets . ServiceClientAdapterNS ;
18+ using Microsoft . Azure . Commands . RecoveryServices . Backup . Helpers ;
19+ using Microsoft . Azure . Commands . RecoveryServices . Backup . Properties ;
20+ using Microsoft . Azure . Management . Internal . Resources . Utilities . Models ;
21+ using Microsoft . Rest . Azure . OData ;
22+ using Microsoft . WindowsAzure . Commands . Utilities . Common ;
23+ using Newtonsoft . Json ;
24+ using System ;
25+ using System . Collections . Generic ;
26+ using System . Linq ;
27+ using System . Management . Automation ;
28+ using ServiceClientModel = Microsoft . Azure . Management . RecoveryServices . Backup . Models ;
29+
30+
31+ namespace Microsoft . Azure . Commands . RecoveryServices . Backup . Cmdlets
32+ {
33+ /// <summary>
34+ /// Reconfigure protection for an item protected by the recovery services vault.
35+ /// Combines stop protection, unregister container, and configure backup steps.
36+ /// </summary>
37+ [ Cmdlet ( "Redo" , ResourceManager . Common . AzureRMConstants . AzureRMPrefix + "RecoveryServicesBackupProtection" , SupportsShouldProcess = true ) , OutputType ( typeof ( JobBase ) ) ]
38+ public class RedoAzureRmRecoveryServicesBackupProtection : RSBackupVaultCmdletBase
39+ {
40+ [ Parameter ( Position = 1 , Mandatory = true , HelpMessage = ParamHelpMsgs . Item . ProtectedItem , ValueFromPipeline = true ) ]
41+ [ ValidateNotNullOrEmpty ]
42+ public ItemBase Item { get ; set ; }
43+
44+ [ Parameter ( Position = 2 , Mandatory = true , HelpMessage = "Target Recovery Services vault ID where the item will be reconfigured" ) ]
45+ [ ValidateNotNullOrEmpty ]
46+ public string TargetVaultId { get ; set ; }
47+
48+ [ Parameter ( Position = 3 , Mandatory = true , HelpMessage = "Backup policy to be applied in the target vault" ) ]
49+ [ ValidateNotNullOrEmpty ]
50+ public PolicyBase TargetPolicy { get ; set ; }
51+
52+ [ Parameter ( Position = 4 , Mandatory = false , HelpMessage = ParamHelpMsgs . Item . SuspendBackupOption ) ]
53+ public SwitchParameter RetainRecoveryPointsAsPerPolicy { get ; set ; }
54+
55+ [ Parameter ( Mandatory = false , HelpMessage = ParamHelpMsgs . ResourceGuard . AuxiliaryAccessToken , ValueFromPipeline = false ) ]
56+ [ ValidateNotNullOrEmpty ]
57+ public System . Security . SecureString SecureToken ;
58+
59+ [ Parameter ( Mandatory = false , HelpMessage = ParamHelpMsgs . Item . ForceOption ) ]
60+ public SwitchParameter Force { get ; set ; }
61+
62+ public override void ExecuteCmdlet ( )
63+ {
64+ ExecutionBlock ( ( ) =>
65+ {
66+ base . ExecuteCmdlet ( ) ;
67+ PsBackupProviderManager providerManager ;
68+ JobBase jobObj = null ;
69+
70+ // chck with nandini, source vault is default and can we name targetvault ?
71+ ResourceIdentifier resourceIdentifier = new ResourceIdentifier ( VaultId ) ;
72+ string vaultName = resourceIdentifier . ResourceName ;
73+ string resourceGroupName = resourceIdentifier . ResourceGroupName ;
74+
75+ // Step 1: Stop protection
76+ ConfirmAction (
77+ Force . IsPresent ,
78+ string . Format ( Resources . DisableProtectionWarning , Item . Name ) ,
79+ Resources . DisableProtectionMessage ,
80+ Item . Name , ( ) =>
81+ {
82+ string plainToken = HelperUtils . GetPlainToken ( null , SecureToken ) ;
83+
84+ providerManager =
85+ new PsBackupProviderManager ( new Dictionary < System . Enum , object > ( )
86+ {
87+ { VaultParams . VaultName , vaultName } ,
88+ { VaultParams . ResourceGroupName , resourceGroupName } ,
89+ { ItemParams . Item , Item } ,
90+ { ResourceGuardParams . Token , plainToken } ,
91+ } , ServiceClientAdapter ) ;
92+
93+ IPsBackupProvider psBackupProvider =
94+ providerManager . GetProviderInstance ( Item . WorkloadType , Item . BackupManagementType ) ;
95+
96+ if ( RetainRecoveryPointsAsPerPolicy . IsPresent )
97+ {
98+ var itemResponse = psBackupProvider . SuspendBackup ( ) ;
99+ Logger . Instance . WriteDebug ( "Suspend backup response " + JsonConvert . SerializeObject ( itemResponse ) ) ;
100+ jobObj = HandleCreatedJob (
101+ itemResponse ,
102+ Resources . DisableProtectionOperation ,
103+ vaultName : vaultName ,
104+ resourceGroupName : resourceGroupName ,
105+ returnJobObject : true ) ;
106+ }
107+ else
108+ {
109+ var itemResponse = psBackupProvider . DisableProtection ( ) ;
110+ Logger . Instance . WriteDebug ( "Stop protection with retain data forever response " + JsonConvert . SerializeObject ( itemResponse ) ) ;
111+
112+ jobObj = HandleCreatedJob (
113+ itemResponse ,
114+ Resources . DisableProtectionOperation ,
115+ vaultName : vaultName ,
116+ resourceGroupName : resourceGroupName ,
117+ returnJobObject : true ) ;
118+ }
119+
120+ // Wait for job completion and ensure it succeeded
121+ CmdletHelper . EnsureJobCompletedOrThrow ( jobObj , vaultName , resourceGroupName , "disable protection" , this ) ;
122+ WriteVerbose ( "Disabled protection successfully" ) ;
123+ }
124+ ) ;
125+
126+ // Parse target vault information
127+ ResourceIdentifier targetResourceIdentifier = new ResourceIdentifier ( TargetVaultId ) ;
128+ string targetVaultName = targetResourceIdentifier . ResourceName ;
129+ string targetResourceGroupName = targetResourceIdentifier . ResourceGroupName ;
130+
131+ // Step 2: Unregister/register container (only for supported workloads)
132+ ProtectableItemBase protectableItem = null ;
133+ if ( CmdletHelper . IsContainerUnregistrationRequired ( Item . ContainerType , Item . BackupManagementType ) )
134+ {
135+ var unregisterJobObj = CmdletHelper . UnregisterContainer ( Item , vaultName , resourceGroupName , ServiceClientAdapter , this ) ;
136+ CmdletHelper . EnsureJobCompletedOrThrow ( unregisterJobObj , vaultName , resourceGroupName , "container unregistration" , this ) ;
137+
138+ // After registration, trigger inquiry if needed to discover protectable items
139+ if ( Item . BackupManagementType == BackupManagementType . AzureWorkload )
140+ {
141+ // Register container in target vault using provider pattern
142+ WriteVerbose ( "Registering container in target vault..." ) ;
143+ CmdletHelper . RegisterContainerInTargetVault ( Item , targetVaultName , targetResourceGroupName , ServiceClientAdapter ) ;
144+
145+ WriteVerbose ( $ "Triggering inquiry to discover { Item . WorkloadType } protectable items...") ;
146+ protectableItem = CmdletHelper . TriggerInquiryAndGetProtectableItem ( Item , targetVaultName , targetResourceGroupName , ServiceClientAdapter ) ;
147+ }
148+ }
149+
150+ // Step 3: Configure backup in target vault
151+ WriteVerbose ( "Configuring backup in target vault now" ) ;
152+ // chck : switch context to the target vault's subscription
153+
154+ // Create provider manager for target vault with workload-specific parameters
155+ Dictionary < Enum , object > targetProviderParams = new Dictionary < Enum , object > ( )
156+ {
157+ { VaultParams . VaultName , targetVaultName } ,
158+ { VaultParams . ResourceGroupName , targetResourceGroupName } ,
159+ { ItemParams . Policy , TargetPolicy } ,
160+ { ResourceGuardParams . IsMUAOperation , false }
161+ } ;
162+
163+ // Add workload-specific parameters based on item type
164+ if ( Item . WorkloadType == WorkloadType . AzureVM )
165+ {
166+ // For VM: extract VM name and resource group from VirtualMachineId
167+ AzureVmItem vmItem = ( AzureVmItem ) Item ;
168+ string vmName = BackupUtils . ExtractVmNameFromVmId ( vmItem . VirtualMachineId ) ; // chck if we should use sourceresourceid here
169+
170+ Logger . Instance . WriteDebug ( $ "Reconfiguring Azure VM protection - SourceResourceId: { vmItem . SourceResourceId } , VirtualMachineId: { vmItem . VirtualMachineId } ") ;
171+
172+ string vmResourceGroupName = BackupUtils . ExtractVmResourceGroupFromVmId ( vmItem . VirtualMachineId ) ;
173+
174+ targetProviderParams . Add ( ItemParams . ItemName , vmName ) ;
175+ targetProviderParams . Add ( ItemParams . AzureVMResourceGroupName , vmResourceGroupName ) ;
176+ targetProviderParams . Add ( ItemParams . ParameterSetName , "AzureVMComputeEnableProtection" ) ;
177+ if ( ( bool ) vmItem . IsInclusionList ) {
178+ targetProviderParams . Add ( ItemParams . InclusionDisksList , vmItem . DiskLunList ) ;
179+ }
180+ else targetProviderParams . Add ( ItemParams . ExclusionDisksList , vmItem . DiskLunList ) ;
181+
182+ // chck handling for ItemParams.AzureVMCloudServiceName, { ItemParams.ResetExclusionSettings, ResetExclusionSettings },
183+ //{ ItemParams.ExcludeAllDataDisks, ExcludeAllDataDisks.IsPresent },
184+ //{ ResourceGuardParams.Token, plainToken },
185+ //{ ResourceGuardParams.IsMUAOperation, isMUAOperation },
186+ }
187+ else if ( Item . WorkloadType == WorkloadType . MSSQL )
188+ {
189+ // For AzureWorkload: need to get protectable item
190+ targetProviderParams . Add ( ItemParams . ProtectableItem , protectableItem ) ;
191+ targetProviderParams . Add ( ItemParams . ParameterSetName , "AzureWorkloadParameterSet" ) ;
192+ }
193+ else if ( Item . WorkloadType == WorkloadType . AzureFiles )
194+ {
195+ // For AzureFiles: extract file share name and storage account name
196+ AzureFileShareItem afsItem = ( AzureFileShareItem ) Item ;
197+ string fileShareName = afsItem . FriendlyName ; // chck : do we need name here?
198+ string storageAccountName = BackupUtils . GetStorageAccountNameFromContainerName ( afsItem . ContainerName ) ;
199+
200+ targetProviderParams . Add ( ItemParams . ItemName , fileShareName ) ;
201+ targetProviderParams . Add ( ItemParams . StorageAccountName , storageAccountName ) ;
202+ targetProviderParams . Add ( ItemParams . ParameterSetName , "AzureFileShareParameterSet" ) ;
203+ }
204+
205+ PsBackupProviderManager targetProviderManager = new PsBackupProviderManager ( targetProviderParams , ServiceClientAdapter ) ;
206+
207+ WriteVerbose ( "Initialized provider manager for target vault" ) ;
208+
209+ IPsBackupProvider targetPsBackupProvider = targetProviderManager . GetProviderInstance ( Item . WorkloadType , Item . BackupManagementType ) ;
210+
211+ var enableResponse = targetPsBackupProvider . EnableProtection ( ) ;
212+
213+ WriteVerbose ( "Enabled protection successfully in target vault, tracking the job" ) ;
214+
215+ // Track Response and display job details
216+ var enableProtectionJob = HandleCreatedJob (
217+ enableResponse ,
218+ Resources . EnableProtectionOperation ,
219+ vaultName : targetVaultName ,
220+ resourceGroupName : targetResourceGroupName , returnJobObject : true ) ;
221+
222+ enableProtectionJob = CmdletHelper . EnsureJobCompletedOrThrow ( enableProtectionJob , targetVaultName , targetResourceGroupName , "enable protection" , this ) ;
223+ WriteObject ( enableProtectionJob ) ;
224+ WriteVerbose ( "Reconfigure backup protection operation completed successfully." ) ;
225+
226+ } , ShouldProcess ( Item . Name , "Reconfigure" ) ) ;
227+ }
228+ }
229+ }
0 commit comments