Skip to content

{Servicefabric} az sf: Migrate commands calling Compute module to aaz-based implementation#32960

Open
william051200 wants to merge 6 commits intoAzure:devfrom
william051200:servicefabric-vm-migration
Open

{Servicefabric} az sf: Migrate commands calling Compute module to aaz-based implementation#32960
william051200 wants to merge 6 commits intoAzure:devfrom
william051200:servicefabric-vm-migration

Conversation

@william051200
Copy link
Member

@william051200 william051200 commented Mar 12, 2026

Related command

az sf cluster reliability update
az sf cluster durability update
az sf cluster node-type add
az sf cluster node add
az sf cluster node remove
az sf application certificate add

Description

Migration from mgmt.compute to aaz-based

I have upgraded vmss list aaz version from 2023-09-01 to 2024-11-01 to match sdk version

Testing Guide

History Notes


This checklist is used to make sure that common guidelines for a pull request are followed.

Copilot AI review requested due to automatic review settings March 12, 2026 06:55
@azure-client-tools-bot-prd
Copy link

azure-client-tools-bot-prd bot commented Mar 12, 2026

️✔️AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.13
️✔️acs
️✔️latest
️✔️3.12
️✔️3.13
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.13
️✔️ams
️✔️latest
️✔️3.12
️✔️3.13
️✔️apim
️✔️latest
️✔️3.12
️✔️3.13
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.13
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️aro
️✔️latest
️✔️3.12
️✔️3.13
️✔️backup
️✔️latest
️✔️3.12
️✔️3.13
️✔️batch
️✔️latest
️✔️3.12
️✔️3.13
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.13
️✔️billing
️✔️latest
️✔️3.12
️✔️3.13
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.13
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.13
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.13
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.13
️✔️config
️✔️latest
️✔️3.12
️✔️3.13
️✔️configure
️✔️latest
️✔️3.12
️✔️3.13
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.13
️✔️container
️✔️latest
️✔️3.12
️✔️3.13
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.13
️✔️core
️✔️latest
️✔️3.12
️✔️3.13
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.13
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.13
️✔️dls
️✔️latest
️✔️3.12
️✔️3.13
️✔️dms
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.13
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.13
️✔️find
️✔️latest
️✔️3.12
️✔️3.13
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.13
️✔️identity
️✔️latest
️✔️3.12
️✔️3.13
️✔️iot
️✔️latest
️✔️3.12
️✔️3.13
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.13
️✔️lab
️✔️latest
️✔️3.12
️✔️3.13
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️maps
️✔️latest
️✔️3.12
️✔️3.13
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.13
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.13
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.13
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.13
️✔️network
️✔️latest
️✔️3.12
️✔️3.13
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.13
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.13
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.13
️✔️profile
️✔️latest
️✔️3.12
️✔️3.13
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.13
️✔️redis
️✔️latest
️✔️3.12
️✔️3.13
️✔️relay
️✔️latest
️✔️3.12
️✔️3.13
️✔️resource
️✔️latest
️✔️3.12
️✔️3.13
️✔️role
️✔️latest
️✔️3.12
️✔️3.13
️✔️search
️✔️latest
️✔️3.12
️✔️3.13
️✔️security
️✔️latest
️✔️3.12
️✔️3.13
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.13
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.13
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.13
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.13
️✔️sql
️✔️latest
️✔️3.12
️✔️3.13
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.13
️✔️storage
️✔️latest
️✔️3.12
️✔️3.13
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.13
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.13
️✔️util
️✔️latest
️✔️3.12
️✔️3.13
️✔️vm
️✔️latest
️✔️3.12
️✔️3.13

@azure-client-tools-bot-prd
Copy link

azure-client-tools-bot-prd bot commented Mar 12, 2026

️✔️AzureCLI-BreakingChangeTest
️✔️Non Breaking Changes

@yonzhan
Copy link
Collaborator

yonzhan commented Mar 12, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

@github-actions
Copy link

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates several Service Fabric (az sf) commands from using the compute SDK client (compute_client_factory / mgmt.compute) to AAZ-based implementations (VMSSCreate, VMSSList from vm.operations.vmss). It also adds a new VMSSList class in the VM operations module to handle flatten conflicts for list operations.

Changes:

  • Replaced SDK-based VMSS operations (list, create_or_update) with AAZ command invocations (VMSSCreate, VMSSList) across multiple SF cluster management functions.
  • Added VMSSList class in vm/operations/vmss.py to resolve extension type flatten conflicts, mirroring the pattern used by VMSSShow and VMSSPatch.
  • Converted SDK model object access (attribute-based) to dict-based access throughout the SF custom module.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.

File Description
src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py Added VMSSList class with flatten conflict resolution for both per-RG and all-subscription list operations.
src/azure-cli/azure/cli/command_modules/servicefabric/custom.py Replaced compute SDK calls with AAZ VMSSCreate/VMSSList; converted model objects to dicts; updated property access patterns.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

fabric_ext_ref['settings']['durabilityLevel'] = durability_level
fabric_ext_ref['settings']['enableParallelJobs'] = True
vmss['resource_group'] = resource_group_name
vmss['vm_scale_set_name'] = vmss.name
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vmss.name uses attribute access on a dict, which will raise AttributeError. Should be vmss['name'].

Suggested change
vmss['vm_scale_set_name'] = vmss.name
vmss['vm_scale_set_name'] = vmss['name']

Copilot uses AI. Check for mistakes.
Comment on lines +697 to +701
format(reliability_level, instance_target, vmss.sku.capacity))
vmss.sku.capacity = instance_target
vmss_poll = compute_client.virtual_machine_scale_sets.begin_create_or_update(
resource_group_name, vmss.name, vmss)
vmss['sku']['capacity'] = instance_target
from ..vm.operations.vmss import VMSSCreate
vmss['resource_group'] = resource_group_name
vmss['vm_scale_set_name'] = vmss.name
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two issues on this line: (1) vmss.name uses attribute access on a dict and will raise AttributeError — should be vmss['name']. (2) vmss.sku.capacity in the error message on line 697 also uses attribute access on a dict — should be vmss['sku']['capacity'].

Copilot uses AI. Check for mistakes.
extension_type = ext.type_properties_type.lower()
if ext.get('type1'):
extension_type = ext['type1'].lower()
if ext.get('type'):
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second condition changed from elif to if. This means that if both type1 and type are present, type will always overwrite the value set by type1. While this may be the intended behavior, it's a subtle logic change from the original code where type_properties_type was only checked if type1 was absent. Consider whether you intended to keep the elif pattern to preserve the original precedence logic, or if you intentionally want type to take priority.

Suggested change
if ext.get('type'):
elif ext.get('type'):

Copilot uses AI. Check for mistakes.
extension.type = AAZUndefined

return self.deserialize_output(self.ctx.vars.instance, client_flatten=True)

Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing blank line before def convert_show_result_to_snake_case. PEP 8 requires two blank lines between top-level definitions. This was likely caused by the insertion of the VMSSList class above.

Suggested change

Copilot uses AI. Check for mistakes.
Comment on lines +694 to +706
if vmss.get('sku', {}).get('capacity') and vmss.get('sku', {}).get('capacity') < instance_target:
if auto_add_node is not True:
raise CLIError('Please use --auto_add_node to automatically increase the nodes,{} requires {} nodes, but currenty there are {}'.
format(reliability_level, instance_target, vmss.sku.capacity))
vmss.sku.capacity = instance_target
vmss_poll = compute_client.virtual_machine_scale_sets.begin_create_or_update(
resource_group_name, vmss.name, vmss)
vmss['sku']['capacity'] = instance_target
from ..vm.operations.vmss import VMSSCreate
vmss['resource_group'] = resource_group_name
vmss['vm_scale_set_name'] = vmss.name
vmss_poll = VMSSCreate(cli_ctx=cmd.cli_ctx)(command_args=vmss)
LongRunningOperation(cli_ctx)(vmss_poll)

node_type.vm_instance_count = vmss.sku.capacity
if vmss.get('sku', {}).get('capacity'):
node_type.vm_instance_count = vmss['sku']['capacity']
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The truthiness check vmss.get('sku', {}).get('capacity') will evaluate to False when capacity is 0, changing the behavior compared to the original code which simply did vmss.sku.capacity < instance_target. While a VMSS with 0 capacity may be uncommon, consider using an explicit is not None check instead: vmss.get('sku', {}).get('capacity') is not None and vmss['sku']['capacity'] < instance_target. The same concern applies to line 705 where node_type.vm_instance_count assignment would be skipped if capacity is 0.

Copilot uses AI. Check for mistakes.

vmss['sku']['capacity'] = vmss['sku']['capacity'] + number_of_nodes_to_add
vmss['resource_group'] = resource_group_name
vmss['vm_scale_set_name'] = vmss.name
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two issues: (1) vmss.name uses attribute access on a dict, which will raise AttributeError. (2) Even after fixing to vmss['name'], this will raise KeyError because convert_show_result_to_snake_case (called in _get_cluster_vmss_by_node_type) does not copy the name field to the new result dict. The name field needs to be preserved in convert_show_result_to_snake_case, or accessed from the original result before conversion. The same issue applies at lines 515, 567, 701, and 1248.

Suggested change
vmss['vm_scale_set_name'] = vmss.name
vmss['vm_scale_set_name'] = vmss.get('name')

Copilot uses AI. Check for mistakes.
vmss_poll = compute_client.virtual_machine_scale_sets.begin_create_or_update(
resource_group_name, vmss.name, vmss)
vmss['resource_group'] = resource_group_name
vmss['vm_scale_set_name'] = vmss.name
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vmss.name uses attribute access on a dict, which will raise AttributeError. Should be vmss['name'].

Copilot uses AI. Check for mistakes.
poller = compute_client.virtual_machine_scale_sets.begin_create_or_update(
resource_group_name, vmss.name, vmss)
vmss['resource_group'] = resource_group_name
vmss['vm_scale_set_name'] = vmss.name
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vmss.name uses attribute access on a dict, which will raise AttributeError. Should be vmss['name'].

Suggested change
vmss['vm_scale_set_name'] = vmss.name
vmss['vm_scale_set_name'] = vmss['name']

Copilot uses AI. Check for mistakes.
Comment on lines 1234 to 1245
@@ -1184,19 +1244,20 @@ def _add_cert_to_vmss(cli_ctx, vmss, resource_group_name, vault_id, secret_url):
secrets[0].vault_certificates.append(
VaultCertificate(secret_url, 'my'))
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The else branch still uses SDK-style attribute access (secrets[0].vault_certificates, c.certificate_url, VaultCertificate(...)) on objects that are now plain dicts returned by the AAZ command. These will raise AttributeError. They need to be converted to dict-style access (e.g., secrets[0]['vault_certificates'], c['certificate_url']) and dict literals instead of VaultCertificate(...) constructor calls.

Copilot uses AI. Check for mistakes.
json_data['storageAccountKey'] = list_results.keys[0].value
json_data['storageAccountEndPoint'] = "https://core.windows.net/"
diagnostics_ext.protected_settings = json_data
diagnostics_ext['protectedSettings'] = json_data
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After convert_show_result_to_snake_case is applied (via _get_cluster_vmss_by_node_type), the extension dict uses snake_case keys, so protectedSettings has been renamed to protected_settings. Using camelCase protectedSettings here adds a new key that the AAZ VMSSCreate command may not recognize. This should be diagnostics_ext['protected_settings'] = json_data to be consistent with lines 1025-1027 which correctly use protected_settings.

Suggested change
diagnostics_ext['protectedSettings'] = json_data
diagnostics_ext['protected_settings'] = json_data

Copilot uses AI. Check for mistakes.
@yonzhan yonzhan assigned yanzhudd and unassigned zhoxing-ms Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Auto-Assign Auto assign by bot Service Fabric az sf

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants