Skip to content

Commit 97b174d

Browse files
mettursathishsaifaldin14Saif Al-Din AliCopilot
authored
[Migrate] Start migration command, preview channel versioning & new commands for replication (#9493)
* Adding "Migrate" folder to the project * Added migrate command * Adding preview tag for commands, moving migration to a seperate folder & update help text. * Addressing style issues * addressing the styles and removing the duplicate key * addressing style issues * addesssing more style issues * addressing inline disable at the specific line * Added R1702 to the pylint disable comment on the function definition. * Addressing to disable too many nested blocks R1702 * Fixing test cases and updating version changes * Add cli fixes (#1) * Create extension * Update src/migrate/azext_migrate/__init__.py Co-authored-by: Copilot <[email protected]> * Fix import issues * Update src/migrate/setup.py Co-authored-by: Copilot <[email protected]> * Small * Small lint * Small * disable lint for this check * Add json * Fix licesnse issue * fix small * Small * Get rid of unused variables * Add service name and code owner * New version * Style * Small * Update * Follow standard * Add suggestions * Small * Not preview * Add flag to become experimental * Update history * Fix * small * Create get job and remove replication commands * Add better error handling for jobs command * Add better messages to remove protected item * Return job id in remove command * Move helpers * Rename get discovered server helper * Refactor _initialize_replication_infrastructure_helpers * Refactor new replication * Refactor jobs * Refactor delete protected item * Fix lint issues * Change release version * Fix lint issues * Add fix * Updae correct version * Put beta version before * Fix * Update * Fix bifurcation tool issue * Update amh correctly if not proper * Use current subscription id if not passed in * Fix correct location and target resource group creation * Create list protected items command * Update versions * Add __init__.py to all folders * Create unit tests for get replication * Update readme with accurate description of commands * Update readme * Create tests for jobs and remove commands * Add more tests to increase coverage to 74% * Add start migration command * Address fixes * Remove doc strings from custom.py * Add init * Remove old file locations * fix failing tests * Fix secret test * Fix test * Fix secret detection * Fix duplicates --------- Co-authored-by: Saif Al-Din Ali <[email protected]> Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Saif Al-Din Ali <[email protected]> Co-authored-by: Saif Al-Din Ali <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent f49baf0 commit 97b174d

32 files changed

+6552
-511
lines changed

azure-cli-extensions.pyproj

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,6 +2704,20 @@
27042704
<Compile Include="src\mesh\azext_mesh\_params.py" />
27052705
<Compile Include="src\mesh\azext_mesh\__init__.py" />
27062706
<Compile Include="src\mesh\setup.py" />
2707+
<Compile Include="src\migrate\azext_migrate\aaz\__init__.py" />
2708+
<Compile Include="src\migrate\azext_migrate\commands.py" />
2709+
<Compile Include="src\migrate\azext_migrate\custom.py" />
2710+
<Compile Include="src\migrate\azext_migrate\tests\latest\test_migrate_commands.py" />
2711+
<Compile Include="src\migrate\azext_migrate\tests\latest\__init__.py" />
2712+
<Compile Include="src\migrate\azext_migrate\tests\__init__.py" />
2713+
<Compile Include="src\migrate\azext_migrate\_get_discovered_server_helpers.py" />
2714+
<Compile Include="src\migrate\azext_migrate\_help.py" />
2715+
<Compile Include="src\migrate\azext_migrate\_helpers.py" />
2716+
<Compile Include="src\migrate\azext_migrate\_initialize_replication_infrastructure_helpers.py" />
2717+
<Compile Include="src\migrate\azext_migrate\_new_local_server_replication_helpers.py" />
2718+
<Compile Include="src\migrate\azext_migrate\_params.py" />
2719+
<Compile Include="src\migrate\azext_migrate\__init__.py" />
2720+
<Compile Include="src\migrate\setup.py" />
27072721
<Compile Include="src\privatedns\azext_privatedns\commands.py" />
27082722
<Compile Include="src\privatedns\azext_privatedns\custom.py" />
27092723
<Compile Include="src\privatedns\azext_privatedns\vendored_sdks\models\aaaa_record.py" />
@@ -4699,6 +4713,11 @@
46994713
<Content Include="src\mesh\azext_mesh\azext_metadata.json" />
47004714
<Content Include="src\mesh\HISTORY.rst" />
47014715
<Content Include="src\mesh\README.rst" />
4716+
<Content Include="src\migrate\azext_migrate\azext_metadata.json" />
4717+
<Content Include="src\migrate\HISTORY.rst" />
4718+
<Content Include="src\migrate\linter_exclusions.yml" />
4719+
<Content Include="src\migrate\README.md" />
4720+
<Content Include="src\migrate\setup.cfg" />
47024721
<Content Include="src\resource-graph\azext_resourcegraph\azext_metadata.json" />
47034722
<Content Include="src\resource-graph\HISTORY.rst" />
47044723
<Content Include="src\resource-graph\README.rst" />
@@ -4877,6 +4896,11 @@
48774896
<Folder Include="src\mesh\azext_mesh\servicefabricmesh\mgmt\servicefabricmesh\operations" />
48784897
<Folder Include="src\mesh\azext_mesh\tests\" />
48794898
<Folder Include="src\mesh\azext_mesh\tests\latest" />
4899+
<Folder Include="src\migrate\" />
4900+
<Folder Include="src\migrate\azext_migrate\" />
4901+
<Folder Include="src\migrate\azext_migrate\aaz\" />
4902+
<Folder Include="src\migrate\azext_migrate\tests\" />
4903+
<Folder Include="src\migrate\azext_migrate\tests\latest\" />
48804904
<Folder Include="src\privatedns\" />
48814905
<Folder Include="src\privatedns\azext_privatedns\" />
48824906
<Folder Include="src\privatedns\azext_privatedns\vendored_sdks\" />

src/migrate/HISTORY.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@
33
Release History
44
===============
55

6-
3.0.0b1
6+
3.0.0b2
77
+++++++++++++++
8-
* Refactor codebase for improved readability and maintainability.
8+
* Added replication list, get and start migration commands.
99

10-
2.0.1b1
10+
3.0.0b1
1111
+++++++++++++++
12-
* Switch to experimental version.
12+
* Refactor codebase for improved readability and maintainability.
1313

1414
2.0.0
1515
+++++++++++++++
1616
* New version.
1717

18+
2.0.1b1
19+
+++++++++++++++
20+
* Switch to experimental version.
21+
1822
1.0.0
1923
+++++++++++++++
2024
* Initial release.

src/migrate/azext_migrate/_help.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,130 @@
304304
--os-disk-id "disk-0"
305305
"""
306306

307+
helps['migrate local replication list'] = """
308+
type: command
309+
short-summary: List all protected items (replicating servers) in a project.
310+
long-summary: |
311+
Lists all servers that have replication enabled
312+
in an Azure Migrate project.
313+
This command shows the replication status, health,
314+
and configuration details for each protected server.
315+
316+
The command returns information including:
317+
- Protection state (e.g., Protected, ProtectedReplicating, EnablingFailed)
318+
- Replication health (Normal, Warning, Critical)
319+
- Source machine name and target VM name
320+
- Replication policy name
321+
- Resource IDs (used for remove command)
322+
- Health errors if any
323+
324+
Note: This command uses a preview API version
325+
and may experience breaking changes in future releases.
326+
parameters:
327+
- name: --resource-group -g
328+
short-summary: Resource group containing the Azure Migrate project.
329+
long-summary: >
330+
The name of the resource group where
331+
the Azure Migrate project is located.
332+
- name: --project-name
333+
short-summary: Name of the Azure Migrate project.
334+
long-summary: >
335+
The Azure Migrate project that contains
336+
the replicating servers.
337+
- name: --subscription-id
338+
short-summary: Azure subscription ID.
339+
long-summary: >
340+
The subscription containing the Azure Migrate project.
341+
Uses the default subscription if not specified.
342+
examples:
343+
- name: List all replicating servers in a project
344+
text: |
345+
az migrate local replication list \\
346+
--resource-group myRG \\
347+
--project-name myMigrateProject
348+
- name: List replicating servers with a specific subscription
349+
text: |
350+
az migrate local replication list \\
351+
--resource-group myRG \\
352+
--project-name myMigrateProject \\
353+
--subscription-id 00000000-0000-0000-0000-000000000000
354+
"""
355+
356+
helps['migrate local replication get'] = """
357+
type: command
358+
short-summary: Get detailed information about a specific replicating server.
359+
long-summary: |
360+
Retrieves comprehensive details about a specific protected item (replicating server)
361+
including its protection state, replication health, configuration settings,
362+
and historical information about failover operations.
363+
364+
You can retrieve the protected item either by:
365+
- Full ARM resource ID (--protected-item-id or --id)
366+
- Name with project context (--protected-item-name with --resource-group and --project-name)
367+
368+
The command returns detailed information including:
369+
- Basic information (name, resource ID, correlation ID)
370+
- Protection status (state, health, resync requirements)
371+
- Configuration (policy, replication extension)
372+
- Failover history (test, planned, unplanned)
373+
- Allowed operations
374+
- Machine details (source and target information)
375+
- Health errors with recommended actions (if any)
376+
377+
Note: This command uses a preview API version
378+
and may experience breaking changes in future releases.
379+
parameters:
380+
- name: --protected-item-id --id
381+
short-summary: Full ARM resource ID of the protected item.
382+
long-summary: >
383+
The complete ARM resource ID of the protected item.
384+
If provided, --resource-group and --project-name are not required.
385+
This ID can be obtained from the 'list' or 'new' commands.
386+
- name: --protected-item-name --name
387+
short-summary: Name of the protected item (replicating server).
388+
long-summary: >
389+
The name of the protected item to retrieve.
390+
When using this option, both --resource-group and --project-name
391+
are required to locate the item.
392+
- name: --resource-group -g
393+
short-summary: Resource group containing the Azure Migrate project.
394+
long-summary: >
395+
The name of the resource group where the Azure Migrate project is located.
396+
Required when using --protected-item-name.
397+
- name: --project-name
398+
short-summary: Name of the Azure Migrate project.
399+
long-summary: >
400+
The Azure Migrate project that contains the replicating server.
401+
Required when using --protected-item-name.
402+
- name: --subscription-id
403+
short-summary: Azure subscription ID.
404+
long-summary: >
405+
The subscription containing the Azure Migrate project.
406+
Uses the default subscription if not specified.
407+
examples:
408+
- name: Get a protected item by its full ARM resource ID
409+
text: |
410+
az migrate local replication get \\
411+
--protected-item-id "/subscriptions/xxxx/resourceGroups/myRG/providers/Microsoft.DataReplication/replicationVaults/myVault/protectedItems/myItem"
412+
- name: Get a protected item by name using project context
413+
text: |
414+
az migrate local replication get \\
415+
--protected-item-name myProtectedItem \\
416+
--resource-group myRG \\
417+
--project-name myMigrateProject
418+
- name: Get a protected item with specific subscription
419+
text: |
420+
az migrate local replication get \\
421+
--name myProtectedItem \\
422+
--resource-group myRG \\
423+
--project-name myMigrateProject \\
424+
--subscription-id 00000000-0000-0000-0000-000000000000
425+
- name: Get a protected item using short parameter names
426+
text: |
427+
az migrate local replication get \\
428+
--id "/subscriptions/xxxx/resourceGroups/myRG/providers/Microsoft.DataReplication/replicationVaults/myVault/protectedItems/myItem"
429+
"""
430+
307431
helps['migrate local replication remove'] = """
308432
type: command
309433
short-summary: Stop replication for a migrated server.
@@ -416,3 +540,61 @@
416540
--name myJobName \\
417541
--subscription-id "12345678-1234-1234-1234-123456789012"
418542
"""
543+
544+
helps['migrate local start-migration'] = """
545+
type: command
546+
short-summary: Start migration for a replicating server to Azure Local.
547+
long-summary: |
548+
Initiates the migration (failover) process for a server that
549+
has been configured for replication to Azure Local or Azure Stack HCI.
550+
This command triggers the final migration step, which creates
551+
the virtual machine on the target Azure Local/Stack HCI environment.
552+
553+
The protected item must be in a healthy replication state
554+
before migration can be initiated.
555+
You can optionally specify whether to turn off the source server
556+
after migration completes.
557+
558+
Note: This command uses a preview API version
559+
and may experience breaking changes in future releases.
560+
parameters:
561+
- name: --protected-item-id --id
562+
short-summary: Full ARM resource ID of the protected item to migrate.
563+
long-summary: >
564+
The complete ARM resource ID of the replicating server.
565+
This ID can be obtained from the 'az migrate local replication list'
566+
or 'az migrate local replication get' commands.
567+
Required parameter.
568+
- name: --turn-off-source-server
569+
short-summary: Turn off the source server after migration.
570+
long-summary: >
571+
Specifies whether the source server should be powered off
572+
after the migration completes successfully.
573+
Default is False. Use this option to automatically shut down
574+
the source server to prevent conflicts.
575+
- name: --subscription-id
576+
short-summary: Azure subscription ID.
577+
long-summary: >
578+
The subscription containing the migration resources.
579+
Uses the current subscription if not specified.
580+
examples:
581+
- name: Start migration for a protected item
582+
text: |
583+
az migrate local start-migration \\
584+
--protected-item-id "/subscriptions/xxxx/resourceGroups/myRG/providers/Microsoft.DataReplication/replicationVaults/myVault/protectedItems/myItem"
585+
- name: Start migration and turn off source server
586+
text: |
587+
az migrate local start-migration \\
588+
--protected-item-id "/subscriptions/xxxx/resourceGroups/myRG/providers/Microsoft.DataReplication/replicationVaults/myVault/protectedItems/myItem" \\
589+
--turn-off-source-server
590+
- name: Start migration using short parameter names
591+
text: |
592+
az migrate local start-migration \\
593+
--id "/subscriptions/xxxx/resourceGroups/myRG/providers/Microsoft.DataReplication/replicationVaults/myVault/protectedItems/myItem" \\
594+
--turn-off-source-server
595+
- name: Start migration with specific subscription
596+
text: |
597+
az migrate local start-migration \\
598+
--protected-item-id "/subscriptions/xxxx/resourceGroups/myRG/providers/Microsoft.DataReplication/replicationVaults/myVault/protectedItems/myItem" \\
599+
--subscription-id "12345678-1234-1234-1234-123456789012"
600+
"""

src/migrate/azext_migrate/_params.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,42 @@ def load_arguments(self, _):
184184
required=True)
185185
c.argument('subscription_id', subscription_id_type)
186186

187+
with self.argument_context('migrate local replication list') as c:
188+
c.argument(
189+
'resource_group',
190+
options_list=['--resource-group', '-g'],
191+
help='The name of the resource group where the migrate '
192+
'project is present.',
193+
required=True)
194+
c.argument(
195+
'project_name',
196+
project_name_type,
197+
help='The name of the migrate project.',
198+
required=True)
199+
c.argument('subscription_id', subscription_id_type)
200+
201+
with self.argument_context('migrate local replication get') as c:
202+
c.argument(
203+
'protected_item_name',
204+
options_list=['--protected-item-name', '--name'],
205+
help='The name of the protected item (replicating server).')
206+
c.argument(
207+
'protected_item_id',
208+
options_list=['--protected-item-id', '--id'],
209+
help='The full ARM resource ID of the protected item. '
210+
'If provided, --resource-group and --project-name are not required.')
211+
c.argument(
212+
'resource_group',
213+
options_list=['--resource-group', '-g'],
214+
help='The name of the resource group where the migrate '
215+
'project is present. Required when using --protected-item-name.')
216+
c.argument(
217+
'project_name',
218+
project_name_type,
219+
help='The name of the migrate project. Required when using '
220+
'--protected-item-name.')
221+
c.argument('subscription_id', subscription_id_type)
222+
187223
with self.argument_context('migrate local replication remove') as c:
188224
c.argument(
189225
'target_object_id',
@@ -219,3 +255,18 @@ def load_arguments(self, _):
219255
options_list=['--job-name', '--name'],
220256
help='Job identifier.')
221257
c.argument('subscription_id', subscription_id_type)
258+
259+
with self.argument_context('migrate local start-migration') as c:
260+
c.argument(
261+
'protected_item_id',
262+
options_list=['--protected-item-id', '--id'],
263+
help='The full ARM resource ID of the protected item to migrate. '
264+
'This can be obtained from the list or get replication commands.',
265+
required=True)
266+
c.argument(
267+
'turn_off_source_server',
268+
options_list=['--turn-off-source-server'],
269+
arg_type=get_three_state_flag(),
270+
help='Specifies whether the source server should be turned off '
271+
'after migration completes. Default is False.')
272+
c.argument('subscription_id', subscription_id_type)

src/migrate/azext_migrate/commands.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@
66

77
def load_command_table(self, _):
88
# Azure Local Migration Commands
9-
with self.command_group('migrate') as g:
9+
with self.command_group('migrate', is_preview=True) as g:
1010
g.custom_command('get-discovered-server', 'get_discovered_server')
1111

12-
with self.command_group('migrate local replication') as g:
12+
with self.command_group('migrate local replication', is_preview=True) as g:
1313
g.custom_command('init', 'initialize_replication_infrastructure')
1414
g.custom_command('new', 'new_local_server_replication')
15+
g.custom_command('list', 'list_local_server_replications')
16+
g.custom_command('get', 'get_local_server_replication')
1517
g.custom_command('remove', 'remove_local_server_replication')
1618
g.custom_command('get-job', 'get_local_replication_job')
19+
20+
with self.command_group('migrate local', is_preview=True) as g:
21+
g.custom_command('start-migration', 'start_local_server_migration')

0 commit comments

Comments
 (0)