Skip to content

Conversation

@william051200
Copy link
Member

Related command

az vm diagnostics set

Description

Migration from mgmt.compute to aaz-based

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 February 10, 2026 04:32
@azure-client-tools-bot-prd
Copy link

azure-client-tools-bot-prd bot commented Feb 10, 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
Type Test Case Error Message Line
Failed test_diagnostics_extension_install self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f829b6fa0f0>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f829f797740>
command = 'vm diagnostics set -g cli_test_vm_vmss_diagnostics_extension000001 --vm-name testdiagvm --settings /tmp/tmpmjedg67x --protected-settings /tmp/tmp_lxd9oqr'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.12/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:135: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/patches.py:33: in handle_main_exception
    raise ex
env/lib/python3.12/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:669: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:737: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:706: in run_job
    result = cmd_copy(params)
             ^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:336: in call
    return self.handler(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/command_operation.py:120: in handler
    return op(**command_args)
           ^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/custom.py:2299: in set_diagnostics_extension
    return set_extension(cmd, resource_group_name, vm_name, vm_extension_name,
src/azure-cli/azure/cli/command_modules/vm/custom.py:2511: in set_extension
    vm = VMShow(cli_ctx=cmd.cli_ctx)(command_args={
src/azure-cli-core/azure/cli/core/aaz/command.py:155: in call
    return self.handler(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:6853: in handler
    self.execute_operations()
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:6885: in execute_operations
    self.VirtualMachinesGet(ctx=self.ctx)()
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:6905: in call
    session = self.client.send_request(request=request, stream=False, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/client.py:108: in send_request
    session = self.pipeline.run(request, stream=stream, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:242: in run
    return first_node.send(pipeline_request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/mgmt/core/policies/base.py:95: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/policies/redirect.py:205: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/policies/retry.py:545: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/http_policy.py:112: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:130: in send
    self.sender.send(request.http_request, **request.context.options),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/transport/requests_basic.py:375: in send
    response = self.session.request(  # type: ignore
env/lib/python3.12/site-packages/requests/sessions.py:589: in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/requests/sessions.py:703: in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/requests/adapters.py:667: in send
    resp = conn.urlopen(
env/lib/python3.12/site-packages/urllib3/connectionpool.py:787: in urlopen
    response = self.make_request(
env/lib/python3.12/site-packages/urllib3/connectionpool.py:534: in make_request
    response = conn.getresponse()
               ^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
        

self = <VCRRequestsHTTPSConnection/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_diagnostics_extension_install.yaml(host='management.azure.com', port=443) at 0x7f829b599d60>
 = False, kwargs = {}

    def getresponse(self, 
=False, **kwargs):
        """Retrieve the response"""
        # Check to see if the cassette has a response for this request. If so,
        # then return it
        if self.cassette.can_play_response_for(self.vcr_request):
            log.info(f"Playing response for {self.vcr_request} from cassette")
            response = self.cassette.play_response(self.vcr_request)
            return VCRHTTPResponse(response)
        else:
            if self.cassette.write_protected and self.cassette.filter_request(self.vcr_request):
>               raise CannotOverwriteExistingCassetteException(
                    cassette=self.cassette,
                    failed_request=self.vcr_request,
                )
E               vcr.errors.CannotOverwriteExistingCassetteException: Can't overwrite existing cassette ('/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_diagnostics_extension_install.yaml') in your current record mode ('once').
E               No match for the request (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>)&nbsp;was&nbsp;found.
E               Found 3 similar requests with 0 different matcher(s) :
E               
E               1 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', 'custom_request_query_matcher']
E               Matchers failed :
E               
E               2 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', 'custom_request_query_matcher']
E               Matchers failed :
E               
E               3 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', 'custom_request_query_matcher']
E               Matchers failed :

env/lib/python3.12/site-packages/vcr/stubs/init.py:277: CannotOverwriteExistingCassetteException

During handling of the above exception, another exception occurred:

self = <latest.test_vm_commands.DiagnosticsExtensionInstallTest testMethod=test_diagnostics_extension_install>
resource_group = 'cli_test_vm_vmss_diagnostics_extension000001'
storage_account = 'clitest000002'

    @AllowLargeResponse(size_kb=99999)
    @ResourceGroupPreparer(name_prefix='cli_test_vm_vmss_diagnostics_extension')
    @StorageAccountPreparer()
    def test_diagnostics_extension_install(self, resource_group, storage_account):
    
        self.kwargs.update({
            'vm': 'testdiagvm',
            'vmss': 'testdiagvmss',
            'subnet': 'subnet1',
            'vnet': 'vnet1'
        })
    
        self.cmd('vmss create -g {rg} -n {vmss} --image Canonical:UbuntuServer:18.04-LTS:latest --authentication-type password '
                 '--lb-sku Standard --admin-username user11 --admin-password TestTest12#$ --orchestration-mode Uniform')
        self.cmd('vm create -g {rg} -n {vm} --image Canonical:UbuntuServer:18.04-LTS:latest --authentication-type password '
                 '--admin-username user11 --admin-password TestTest12#$ --use-unmanaged-disk --subnet {subnet} --vnet-name {vnet} --nsg-rule NONE')
    
        # Disable default outbound access
        self.cmd('network vnet subnet update -g {rg} --vnet-name {vnet} -n {subnet} --default-outbound-access false')
    
        storage_sastoken = '123'  # use junk keys, do not retrieve real keys which will get into the recording
        
, protected_settings = tempfile.mkstemp()
        with open(protected_settings, 'w') as outfile:
            json.dump({
                "storageAccountName": storage_account,
                "storageAccountSasToken": storage_sastoken
            }, outfile)
        self.kwargs['protected_settings'] = protected_settings.replace('\', '\\')
    
        
, public_settings = tempfile.mkstemp()
        curr_dir = os.path.dirname(os.path.realpath(file))
        template_file = os.path.join(curr_dir, 'sample-public.json').replace('\', '\\')
        with open(template_file) as data_file:
            data = json.load(data_file)
        data["StorageAccount"] = storage_account
        with open(public_settings, 'w') as outfile:
            json.dump(data, outfile)
        self.kwargs['public_settings'] = public_settings.replace('\', '\\')
    
        checks = [
            self.check('virtualMachineProfile.extensionProfile.extensions[0].name', "LinuxDiagnostic"),
            self.check('virtualMachineProfile.extensionProfile.extensions[0].publisher', "Microsoft.Azure.Diagnostics"),
            self.check('virtualMachineProfile.extensionProfile.extensions[0].settings.StorageAccount', '{sa}'),
            self.check('virtualMachineProfile.extensionProfile.extensions[0].typeHandlerVersion', '3.0')
        ]
    
        self.cmd("vmss diagnostics set -g {rg} --vmss-name {vmss} --settings {public_settings} --protected-settings {protected_settings}", checks=checks)
        self.cmd("vmss show -g {rg} -n {vmss}", checks=checks)
    
        # test standalone VM, we will start with an old version
        self.cmd('vm extension set -g {rg} --vm-name {vm} -n LinuxDiagnostic --version 2.3.9025 --publisher Microsoft.OSTCExtensions --settings {public_settings} --protected-settings {protected_settings}',
                 checks=self.check('typeHandlerVersion', '2.3'))
        # see the 'diagnostics set' command upgrades to newer version
>       self.cmd("vm diagnostics set -g {rg} --vm-name {vm} --settings {public_settings} --protected-settings {protected_settings}", checks=[
            self.check('name', 'LinuxDiagnostic'),
            self.check('publisher', 'Microsoft.Azure.Diagnostics'),
            self.check('settings.StorageAccount', '{sa}'),
            self.check('typeHandlerVersion', '3.0')
        ])

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:3460: 
 
 
 
 
 
 
                                  
src/azure-cli-testsdk/azure/cli/testsdk/base.py:177: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:252: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
 
                                       

self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f829b6fa0f0>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f829f797740>
command = 'vm diagnostics set -g cli_test_vm_vmss_diagnostics_extension000001 --vm-name testdiagvm --settings /tmp/tmpmjedg67x --protected-settings /tmp/tmp_lxd9oqr'
expect_failure = False

    def _in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
            self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
            self.output = stdout_buf.getvalue()
            self.applog = logging_buf.getvalue()
    
        except CannotOverwriteExistingCassetteException as ex:
>           raise AssertionError(ex)
E           AssertionError: Can't overwrite existing cassette ('/mnt/vss/_work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_diagnostics_extension_install.yaml') in your current record mode ('once').
E           No match for the request (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>)&nbsp;was&nbsp;found.
E           Found 3 similar requests with 0 different matcher(s) :
E           
E           1 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', '_custom_request_query_matcher']
E           Matchers failed :
E           
E           2 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', '_custom_request_query_matcher']
E           Matchers failed :
E           
E           3 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', '_custom_request_query_matcher']
E           Matchers failed :

src/azure-cli-testsdk/azure/cli/testsdk/base.py:308: AssertionError
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:3406
❌3.13
Type Test Case Error Message Line
Failed test_diagnostics_extension_install self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f0d2908a580>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f0d2bb6d6d0>
command = 'vm diagnostics set -g cli_test_vm_vmss_diagnostics_extension000001 --vm-name testdiagvm --settings /tmp/tmpn59sazja --protected-settings /tmp/tmp_q_2djal'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.13/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:135: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/patches.py:33: in handle_main_exception
    raise ex
env/lib/python3.13/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:669: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:737: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:706: in run_job
    result = cmd_copy(params)
             ^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:336: in call
    return self.handler(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/command_operation.py:120: in handler
    return op(**command_args)
           ^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/custom.py:2299: in set_diagnostics_extension
    return set_extension(cmd, resource_group_name, vm_name, vm_extension_name,
src/azure-cli/azure/cli/command_modules/vm/custom.py:2511: in set_extension
    vm = VMShow(cli_ctx=cmd.cli_ctx)(command_args={
src/azure-cli-core/azure/cli/core/aaz/command.py:155: in call
    return self.handler(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:3769: in handler
    self.execute_operations()
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:3801: in execute_operations
    self.VirtualMachinesGet(ctx=self.ctx)()
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:3821: in call
    session = self.client.send_request(request=request, stream=False, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/client.py:108: in send_request
    session = self.pipeline.run(request, stream=stream, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:242: in run
    return first_node.send(pipeline_request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/mgmt/core/policies/base.py:95: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/policies/redirect.py:205: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/policies/retry.py:545: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/http_policy.py:112: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:130: in send
    self.sender.send(request.http_request, **request.context.options),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/transport/requests_basic.py:375: in send
    response = self.session.request(  # type: ignore
env/lib/python3.13/site-packages/requests/sessions.py:589: in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/requests/sessions.py:703: in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/requests/adapters.py:667: in send
    resp = conn.urlopen(
env/lib/python3.13/site-packages/urllib3/connectionpool.py:787: in urlopen
    response = self.make_request(
env/lib/python3.13/site-packages/urllib3/connectionpool.py:534: in make_request
    response = conn.getresponse()
               ^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
        

self = <VCRRequestsHTTPSConnection/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_diagnostics_extension_install.yaml(host='management.azure.com', port=443) at 0x7f0d3222fe70>
 = False, kwargs = {}

    def getresponse(self, 
=False, **kwargs):
        """Retrieve the response"""
        # Check to see if the cassette has a response for this request. If so,
        # then return it
        if self.cassette.can_play_response_for(self.vcr_request):
            log.info(f"Playing response for {self.vcr_request} from cassette")
            response = self.cassette.play_response(self.vcr_request)
            return VCRHTTPResponse(response)
        else:
            if self.cassette.write_protected and self.cassette.filter_request(self.vcr_request):
>               raise CannotOverwriteExistingCassetteException(
                    cassette=self.cassette,
                    failed_request=self.vcr_request,
                )
E               vcr.errors.CannotOverwriteExistingCassetteException: Can't overwrite existing cassette ('/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_diagnostics_extension_install.yaml') in your current record mode ('once').
E               No match for the request (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>)&nbsp;was&nbsp;found.
E               Found 3 similar requests with 0 different matcher(s) :
E               
E               1 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', 'custom_request_query_matcher']
E               Matchers failed :
E               
E               2 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', 'custom_request_query_matcher']
E               Matchers failed :
E               
E               3 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', 'custom_request_query_matcher']
E               Matchers failed :

env/lib/python3.13/site-packages/vcr/stubs/init.py:277: CannotOverwriteExistingCassetteException

During handling of the above exception, another exception occurred:

self = <latest.test_vm_commands.DiagnosticsExtensionInstallTest testMethod=test_diagnostics_extension_install>
resource_group = 'cli_test_vm_vmss_diagnostics_extension000001'
storage_account = 'clitest000002'

    @AllowLargeResponse(size_kb=99999)
    @ResourceGroupPreparer(name_prefix='cli_test_vm_vmss_diagnostics_extension')
    @StorageAccountPreparer()
    def test_diagnostics_extension_install(self, resource_group, storage_account):
    
        self.kwargs.update({
            'vm': 'testdiagvm',
            'vmss': 'testdiagvmss',
            'subnet': 'subnet1',
            'vnet': 'vnet1'
        })
    
        self.cmd('vmss create -g {rg} -n {vmss} --image Canonical:UbuntuServer:18.04-LTS:latest --authentication-type password '
                 '--lb-sku Standard --admin-username user11 --admin-password TestTest12#$ --orchestration-mode Uniform')
        self.cmd('vm create -g {rg} -n {vm} --image Canonical:UbuntuServer:18.04-LTS:latest --authentication-type password '
                 '--admin-username user11 --admin-password TestTest12#$ --use-unmanaged-disk --subnet {subnet} --vnet-name {vnet} --nsg-rule NONE')
    
        # Disable default outbound access
        self.cmd('network vnet subnet update -g {rg} --vnet-name {vnet} -n {subnet} --default-outbound-access false')
    
        storage_sastoken = '123'  # use junk keys, do not retrieve real keys which will get into the recording
        
, protected_settings = tempfile.mkstemp()
        with open(protected_settings, 'w') as outfile:
            json.dump({
                "storageAccountName": storage_account,
                "storageAccountSasToken": storage_sastoken
            }, outfile)
        self.kwargs['protected_settings'] = protected_settings.replace('\', '\\')
    
        
, public_settings = tempfile.mkstemp()
        curr_dir = os.path.dirname(os.path.realpath(file))
        template_file = os.path.join(curr_dir, 'sample-public.json').replace('\', '\\')
        with open(template_file) as data_file:
            data = json.load(data_file)
        data["StorageAccount"] = storage_account
        with open(public_settings, 'w') as outfile:
            json.dump(data, outfile)
        self.kwargs['public_settings'] = public_settings.replace('\', '\\')
    
        checks = [
            self.check('virtualMachineProfile.extensionProfile.extensions[0].name', "LinuxDiagnostic"),
            self.check('virtualMachineProfile.extensionProfile.extensions[0].publisher', "Microsoft.Azure.Diagnostics"),
            self.check('virtualMachineProfile.extensionProfile.extensions[0].settings.StorageAccount', '{sa}'),
            self.check('virtualMachineProfile.extensionProfile.extensions[0].typeHandlerVersion', '3.0')
        ]
    
        self.cmd("vmss diagnostics set -g {rg} --vmss-name {vmss} --settings {public_settings} --protected-settings {protected_settings}", checks=checks)
        self.cmd("vmss show -g {rg} -n {vmss}", checks=checks)
    
        # test standalone VM, we will start with an old version
        self.cmd('vm extension set -g {rg} --vm-name {vm} -n LinuxDiagnostic --version 2.3.9025 --publisher Microsoft.OSTCExtensions --settings {public_settings} --protected-settings {protected_settings}',
                 checks=self.check('typeHandlerVersion', '2.3'))
        # see the 'diagnostics set' command upgrades to newer version
>       self.cmd("vm diagnostics set -g {rg} --vm-name {vm} --settings {public_settings} --protected-settings {protected_settings}", checks=[
            self.check('name', 'LinuxDiagnostic'),
            self.check('publisher', 'Microsoft.Azure.Diagnostics'),
            self.check('settings.StorageAccount', '{sa}'),
            self.check('typeHandlerVersion', '3.0')
        ])

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:3460: 
 
 
 
 
 
 
                                  
src/azure-cli-testsdk/azure/cli/testsdk/base.py:177: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:252: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
 
                                       

self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f0d2908a580>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f0d2bb6d6d0>
command = 'vm diagnostics set -g cli_test_vm_vmss_diagnostics_extension000001 --vm-name testdiagvm --settings /tmp/tmpn59sazja --protected-settings /tmp/tmp_q_2djal'
expect_failure = False

    def _in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
            self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
            self.output = stdout_buf.getvalue()
            self.applog = logging_buf.getvalue()
    
        except CannotOverwriteExistingCassetteException as ex:
>           raise AssertionError(ex)
E           AssertionError: Can't overwrite existing cassette ('/mnt/vss/_work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_diagnostics_extension_install.yaml') in your current record mode ('once').
E           No match for the request (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>)&nbsp;was&nbsp;found.
E           Found 3 similar requests with 0 different matcher(s) :
E           
E           1 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', '_custom_request_query_matcher']
E           Matchers failed :
E           
E           2 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', '_custom_request_query_matcher']
E           Matchers failed :
E           
E           3 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vm_vmss_diagnostics_extension000001/providers/Microsoft.Compute/virtualMachines/testdiagvm?$expand=instanceView&api-version=2025-04-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path', '_custom_request_query_matcher']
E           Matchers failed :

src/azure-cli-testsdk/azure/cli/testsdk/base.py:308: AssertionError
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:3406

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

azure-client-tools-bot-prd bot commented Feb 10, 2026

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

@yonzhan
Copy link
Collaborator

yonzhan commented Feb 10, 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

Migrates az vm diagnostics set from the mgmt.compute SDK-based implementation to an AAZ-based implementation, aligning this command group with ongoing AAZ migration work in the vm module.

Changes:

  • Update set_diagnostics_extension to use AAZ VMShow output (get_instance_view) and AAZ vm extension delete when removing incompatible diagnostics extensions.
  • Switch extension instance-view parsing to dict/key-based access patterns.
  • Remove the compute_vm_sdk binding from the vm diagnostics command group registration.

Reviewed changes

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

File Description
src/azure-cli/azure/cli/command_modules/vm/custom.py Reworks set_diagnostics_extension to use AAZ VM show output + AAZ extension delete for incompatible versions.
src/azure-cli/azure/cli/command_modules/vm/commands.py Registers vm diagnostics command group without the mgmt.compute SDK command type.

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

Comment on lines +2292 to +2293
poller = VmExtentionDelete(cmd.cli_ctx)(command_args={
'resource_group': resource_group_name,
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

AAZ command classes in this file are instantiated with the cli_ctx= keyword (e.g., EnableBootDiagnostics(cli_ctx=cmd.cli_ctx)). Here VmExtentionDelete(cmd.cli_ctx) passes cli_ctx positionally; please align with the established pattern to avoid breakage if the constructor signature changes and to keep the style consistent.

Copilot uses AI. Check for mistakes.
no_auto_upgrade=False):
from .aaz.latest.vm.extension import Delete as VmExtentionDelete
vm = get_instance_view(cmd, resource_group_name, vm_name)
is_linux_os = _is_linux_os_by_aaz(vm)
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

get_instance_view returns an AAZ/VMShow result that uses camelCase keys (e.g., storageProfile, osProfile). _is_linux_os_by_aaz checks snake_case keys (storage_profile, os_profile), so this will mis-detect Linux VMs as Windows and select the wrong diagnostics extension. Use _is_linux_os_aaz(vm) here or convert the VM show result to snake_case before calling the helper.

Suggested change
is_linux_os = _is_linux_os_by_aaz(vm)
is_linux_os = _is_linux_os_aaz(vm)

Copilot uses AI. Check for mistakes.
Comment on lines +2281 to +2282
from .aaz.latest.vm.extension import Delete as VmExtentionDelete
vm = get_instance_view(cmd, resource_group_name, vm_name)
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

Typo in the imported alias name VmExtentionDelete ("Extention" -> "Extension"). This makes the code harder to read/search and is inconsistent with the rest of the module naming.

Copilot uses AI. Check for mistakes.
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 Compute az vm/vmss/image/disk/snapshot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants