From a296b222b4f8e3c1d828525721b60f6a344173df Mon Sep 17 00:00:00 2001 From: Qi Pan <43341456+Pan-Qi@users.noreply.github.com> Date: Wed, 22 Jul 2026 12:01:28 +1000 Subject: [PATCH] change scheduledeventsprofile --- .../azure/cli/command_modules/vm/_help.py | 11 ++ .../azure/cli/command_modules/vm/_params.py | 6 + .../command_modules/vm/_template_builder.py | 68 +++++--- .../azure/cli/command_modules/vm/custom.py | 149 +++++++++++------- .../vm/tests/latest/test_template_builder.py | 71 ++++++++- 5 files changed, 226 insertions(+), 79 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/_help.py b/src/azure-cli/azure/cli/command_modules/vm/_help.py index e85bbc86b0a..aa88cf46e7e 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_help.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_help.py @@ -994,6 +994,8 @@ examples: - name: Create an availability set. text: az vm availability-set create -n MyAvSet -g MyResourceGroup --platform-fault-domain-count 2 --platform-update-domain-count 2 + - name: Create an availability set with Scheduled Events auto-approval and API version. + text: az vm availability-set create -n MyAvSet -g MyResourceGroup --platform-fault-domain-count 2 --platform-update-domain-count 2 --enable-all-instance-down true --scheduled-events-api-version 2020-07-01 """ helps['vm boot-diagnostics'] = """ @@ -1084,6 +1086,9 @@ - name: Create a default Ubuntu2204 VM with automatic SSH authentication. text: > az vm create -n MyVm -g MyResourceGroup --image Ubuntu2204 + - name: Create a VM with Scheduled Events auto-approval and API version. + text: > + az vm create -n MyVm -g MyResourceGroup --image Ubuntu2204 --enable-all-instance-down true --scheduled-events-api-version 2020-07-01 - name: Create a default RedHat VM with automatic SSH authentication using an image URN. text: > az vm create -n MyVm -g MyResourceGroup --image RedHat:RHEL:7-RAW:7.4.2018010506 @@ -2239,6 +2244,9 @@ - name: Create a Windows VM scale set with 5 instances, a load balancer, a public IP address, a 2GB data disk and 40GB OS disk. text: > az vmss create -n MyVmss -g MyResourceGroup --instance-count 5 --image Win2016Datacenter --data-disk-sizes-gb 2 --os-disk-size-gb 40 + - name: Create a VMSS with Scheduled Events auto-approval and API version. + text: > + az vmss create -n MyVmss -g MyResourceGroup --image Ubuntu2204 --enable-all-instance-down true --scheduled-events-api-version 2020-07-01 - name: Create a Linux VM scale set with an auto-generated ssh key pair, a public IP address, a DNS entry, an existing load balancer, and an existing virtual network. text: | az vmss create -n MyVmss -g MyResourceGroup --public-ip-address-dns-name my-globally-dns-name \\ @@ -2807,6 +2815,9 @@ text: > az vmss update -n MyVmss -g MyResourceGroup --security-posture-reference-id /CommunityGalleries/{communityGalleryName}/securityPostures/{securityPostureName}/versions/{version} \\ --security-posture-reference-exclude-extensions "c:\\tmp\\exclude_extensions.json" + - name: Update a VMSS with Scheduled Events auto-approval and API version. + text: > + az vmss update -n MyVmss -g MyResourceGroup --enable-all-instance-down true --scheduled-events-api-version 2020-07-01 """ helps['vmss update-instances'] = """ diff --git a/src/azure-cli/azure/cli/command_modules/vm/_params.py b/src/azure-cli/azure/cli/command_modules/vm/_params.py index cdd3e204932..9231157c86d 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_params.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_params.py @@ -400,6 +400,8 @@ def load_arguments(self, _): c.argument('additional_scheduled_events', options_list=['--additional-scheduled-events', '--additional-events'], arg_type=get_three_state_flag(), min_api='2024-07-01', help='The configuration parameter used while creating event grid and resource graph scheduled event setting.') c.argument('enable_user_reboot_scheduled_events', options_list=['--enable-user-reboot-scheduled-events', '--enable-reboot'], arg_type=get_three_state_flag(), min_api='2024-07-01', help='The configuration parameter used while publishing scheduled events additional publishing targets.') c.argument('enable_user_redeploy_scheduled_events', options_list=['--enable-user-redeploy-scheduled-events', '--enable-redeploy'], arg_type=get_three_state_flag(), min_api='2024-07-01', help='The configuration parameter used while creating user initiated redeploy scheduled event setting creation.') + c.argument('enable_all_instance_down', options_list=['--all-instance-down', '--enable-all-instance-down'], arg_type=get_three_state_flag(), min_api='2025-04-01', help='Specify if Scheduled Events should be auto-approved when all instances are down. Its default value is true.') + c.argument('scheduled_events_api_version', options_list=['--se-api-version', '--scheduled-events-api-version'], min_api='2025-04-01', help='Specify the api-version to determine which Scheduled Events configuration schema version will be delivered.') # endregion # region VirtualMachines @@ -472,6 +474,8 @@ def load_arguments(self, _): c.argument('additional_scheduled_events', options_list=['--additional-scheduled-events', '--additional-events'], arg_type=get_three_state_flag(), min_api='2024-07-01', help='The configuration parameter used while creating event grid and resource graph scheduled event setting.') c.argument('enable_user_reboot_scheduled_events', options_list=['--enable-user-reboot-scheduled-events', '--enable-reboot'], arg_type=get_three_state_flag(), min_api='2024-07-01', help='The configuration parameter used while publishing scheduled events additional publishing targets.') c.argument('enable_user_redeploy_scheduled_events', options_list=['--enable-user-redeploy-scheduled-events', '--enable-redeploy'], arg_type=get_three_state_flag(), min_api='2024-07-01', help='The configuration parameter used while creating user initiated redeploy scheduled event setting creation.') + c.argument('enable_all_instance_down', options_list=['--all-instance-down', '--enable-all-instance-down'], arg_type=get_three_state_flag(), min_api='2025-04-01', help='Specify if Scheduled Events should be auto-approved when all instances are down. Its default value is true.') + c.argument('scheduled_events_api_version', options_list=['--se-api-version', '--scheduled-events-api-version'], min_api='2025-04-01', help='Specify the api-version to determine which Scheduled Events configuration schema version will be delivered.') c.argument('align_regional_disks_to_vm_zone', options_list=['--align-regional-disks-to-vm-zone', '--align-regional-disks'], arg_type=get_three_state_flag(), min_api='2024-11-01', help='Specify whether the regional disks should be aligned/moved to the VM zone. This is applicable only for VMs with placement property set. Please note that this change is irreversible.') c.argument('key_incarnation_id', type=int, min_api='2024-11-01', help='Increase the value of this property allows user to reset the key used for securing communication channel between guest and host.') c.argument('security_type', arg_type=get_enum_type(["TrustedLaunch", "Standard", "ConfidentialVM"], default=None), help='Specify the security type of the virtual machine. The value Standard can be used if subscription has feature flag UseStandardSecurityType registered under Microsoft.Compute namespace. Refer to https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/preview-features for steps to enable required feature.') @@ -926,6 +930,8 @@ def load_arguments(self, _): c.argument('additional_scheduled_events', options_list=['--additional-scheduled-events', '--additional-events'], arg_type=get_three_state_flag(), min_api='2024-03-01', help='The configuration parameter used while creating event grid and resource graph scheduled event setting.') c.argument('enable_user_reboot_scheduled_events', options_list=['--enable-user-reboot-scheduled-events', '--enable-reboot'], arg_type=get_three_state_flag(), min_api='2024-03-01', help='The configuration parameter used while publishing scheduled events additional publishing targets.') c.argument('enable_user_redeploy_scheduled_events', options_list=['--enable-user-redeploy-scheduled-events', '--enable-redeploy'], arg_type=get_three_state_flag(), min_api='2024-03-01', help='The configuration parameter used while creating user initiated redeploy scheduled event setting creation.') + c.argument('enable_all_instance_down', options_list=['--all-instance-down', '--enable-all-instance-down'], arg_type=get_three_state_flag(), min_api='2025-04-01', help='Specify if Scheduled Events should be auto-approved when all instances are down. Its default value is true.') + c.argument('scheduled_events_api_version', options_list=['--se-api-version', '--scheduled-events-api-version'], min_api='2025-04-01', help='Specify the api-version to determine which Scheduled Events configuration schema version will be delivered.') c.argument('enable_auto_os_upgrade', enable_auto_os_upgrade_type) c.argument('upgrade_policy_mode', help='Specify the mode of an upgrade to virtual machines in the scale set.', arg_type=get_enum_type(UpgradeMode)) c.argument('security_posture_reference_id', min_api='2023-03-01', diff --git a/src/azure-cli/azure/cli/command_modules/vm/_template_builder.py b/src/azure-cli/azure/cli/command_modules/vm/_template_builder.py index 30fe7067345..486bd77e232 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_template_builder.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_template_builder.py @@ -309,8 +309,9 @@ def build_vm_resource( # pylint: disable=too-many-locals, too-many-statements, os_disk_security_encryption_type=None, os_disk_secure_vm_disk_encryption_set=None, disk_controller_type=None, enable_proxy_agent=None, proxy_agent_mode=None, additional_scheduled_events=None, enable_user_reboot_scheduled_events=None, enable_user_redeploy_scheduled_events=None, - zone_placement_policy=None, include_zones=None, exclude_zones=None, align_regional_disks_to_vm_zone=None, - wire_server_mode=None, imds_mode=None, wire_server_access_control_profile_reference_id=None, + enable_all_instance_down=None, scheduled_events_api_version=None, zone_placement_policy=None, + include_zones=None, exclude_zones=None, align_regional_disks_to_vm_zone=None, wire_server_mode=None, + imds_mode=None, wire_server_access_control_profile_reference_id=None, imds_access_control_profile_reference_id=None, key_incarnation_id=None, add_proxy_agent_extension=None, disk_iops_read_write=None, disk_mbps_read_write=None, zone_movement=None): @@ -599,12 +600,19 @@ def _build_storage_profile(): vm_properties['resiliencyProfile'] = resiliency_profile scheduled_events_policy = {} - if additional_scheduled_events is not None: + if additional_scheduled_events is not None or scheduled_events_api_version is not None: + event_grid_and_resource_graph = {} + if additional_scheduled_events is not None: + event_grid_and_resource_graph["enable"] = additional_scheduled_events + if scheduled_events_api_version is not None: + event_grid_and_resource_graph["scheduledEventsApiVersion"] = scheduled_events_api_version + scheduled_events_policy["scheduledEventsAdditionalPublishingTargets"] = { + "eventGridAndResourceGraph": event_grid_and_resource_graph + } + if enable_all_instance_down is not None: scheduled_events_policy.update({ - "scheduledEventsAdditionalPublishingTargets": { - "eventGridAndResourceGraph": { - "enable": additional_scheduled_events - } + "allInstancesDown": { + "automaticallyApprove": enable_all_instance_down } }) if enable_user_redeploy_scheduled_events is not None: @@ -1057,10 +1065,10 @@ def build_vmss_resource(cmd, name, computer_name_prefix, location, tags, overpro security_posture_reference_id=None, security_posture_reference_exclude_extensions=None, enable_resilient_vm_creation=None, enable_resilient_vm_deletion=None, additional_scheduled_events=None, enable_user_reboot_scheduled_events=None, - enable_user_redeploy_scheduled_events=None, skuprofile_vmsizes=None, - skuprofile_allostrat=None, skuprofile_rank=None, - security_posture_reference_is_overridable=None, zone_balance=None, wire_server_mode=None, - imds_mode=None, add_proxy_agent_extension=None, + enable_user_redeploy_scheduled_events=None, enable_all_instance_down=None, + scheduled_events_api_version=None, skuprofile_vmsizes=None, skuprofile_allostrat=None, + skuprofile_rank=None, security_posture_reference_is_overridable=None, zone_balance=None, + wire_server_mode=None, imds_mode=None, add_proxy_agent_extension=None, wire_server_access_control_profile_reference_id=None, imds_access_control_profile_reference_id=None, enable_automatic_zone_balancing=None, automatic_zone_balancing_strategy=None, automatic_zone_balancing_behavior=None, @@ -1520,12 +1528,19 @@ def build_vmss_resource(cmd, name, computer_name_prefix, location, tags, overpro virtual_machine_profile['scheduledEventsProfile'] = scheduled_events_profile scheduled_events_policy = {} - if additional_scheduled_events is not None: + if additional_scheduled_events is not None or scheduled_events_api_version is not None: + event_grid_and_resource_graph = {} + if additional_scheduled_events is not None: + event_grid_and_resource_graph["enable"] = additional_scheduled_events + if scheduled_events_api_version is not None: + event_grid_and_resource_graph["scheduledEventsApiVersion"] = scheduled_events_api_version + scheduled_events_policy["scheduledEventsAdditionalPublishingTargets"] = { + "eventGridAndResourceGraph": event_grid_and_resource_graph + } + if enable_all_instance_down is not None: scheduled_events_policy.update({ - "scheduledEventsAdditionalPublishingTargets": { - "eventGridAndResourceGraph": { - "enable": additional_scheduled_events - } + "allInstancesDown": { + "automaticallyApprove": enable_all_instance_down } }) if enable_user_redeploy_scheduled_events is not None: @@ -1754,7 +1769,9 @@ def build_av_set_resource(cmd, name, location, tags, platform_update_domain_coun platform_fault_domain_count, unmanaged, proximity_placement_group=None, additional_scheduled_events=None, enable_user_reboot_scheduled_events=None, - enable_user_redeploy_scheduled_events=None): + enable_user_redeploy_scheduled_events=None, + enable_all_instance_down=None, + scheduled_events_api_version=None): av_set = { 'type': 'Microsoft.Compute/availabilitySets', 'name': name, @@ -1770,12 +1787,19 @@ def build_av_set_resource(cmd, name, location, tags, platform_update_domain_coun properties = {"platformFaultDomainCount": platform_fault_domain_count} scheduled_events_policy = {} - if additional_scheduled_events is not None: + if additional_scheduled_events is not None or scheduled_events_api_version is not None: + event_grid_and_resource_graph = {} + if additional_scheduled_events is not None: + event_grid_and_resource_graph["enable"] = additional_scheduled_events + if scheduled_events_api_version is not None: + event_grid_and_resource_graph["scheduledEventsApiVersion"] = scheduled_events_api_version + scheduled_events_policy["scheduledEventsAdditionalPublishingTargets"] = { + "eventGridAndResourceGraph": event_grid_and_resource_graph + } + if enable_all_instance_down is not None: scheduled_events_policy.update({ - "scheduledEventsAdditionalPublishingTargets": { - "eventGridAndResourceGraph": { - "enable": additional_scheduled_events - } + "allInstancesDown": { + "automaticallyApprove": enable_all_instance_down } }) if enable_user_redeploy_scheduled_events is not None: diff --git a/src/azure-cli/azure/cli/command_modules/vm/custom.py b/src/azure-cli/azure/cli/command_modules/vm/custom.py index 944f3ba348a..46381070aa1 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/custom.py +++ b/src/azure-cli/azure/cli/command_modules/vm/custom.py @@ -936,8 +936,9 @@ def create_vm(cmd, vm_name, resource_group_name, image=None, size='Standard_D2s_ proxy_agent_mode=None, source_snapshots_or_disks=None, source_snapshots_or_disks_size_gb=None, source_disk_restore_point=None, source_disk_restore_point_size_gb=None, ssh_key_type=None, additional_scheduled_events=None, enable_user_reboot_scheduled_events=None, - enable_user_redeploy_scheduled_events=None, zone_placement_policy=None, include_zones=None, - exclude_zones=None, align_regional_disks_to_vm_zone=None, wire_server_mode=None, imds_mode=None, + enable_user_redeploy_scheduled_events=None, enable_all_instance_down=None, + scheduled_events_api_version=None, zone_placement_policy=None, include_zones=None, exclude_zones=None, + align_regional_disks_to_vm_zone=None, wire_server_mode=None, imds_mode=None, wire_server_access_control_profile_reference_id=None, imds_access_control_profile_reference_id=None, key_incarnation_id=None, add_proxy_agent_extension=None, disk_iops_read_write=None, disk_mbps_read_write=None, zone_movement=None): @@ -1165,6 +1166,7 @@ def create_vm(cmd, vm_name, resource_group_name, image=None, size='Standard_D2s_ proxy_agent_mode=proxy_agent_mode, additional_scheduled_events=additional_scheduled_events, enable_user_reboot_scheduled_events=enable_user_reboot_scheduled_events, enable_user_redeploy_scheduled_events=enable_user_redeploy_scheduled_events, + enable_all_instance_down=enable_all_instance_down, scheduled_events_api_version=scheduled_events_api_version, zone_placement_policy=zone_placement_policy, include_zones=include_zones, exclude_zones=exclude_zones, align_regional_disks_to_vm_zone=align_regional_disks_to_vm_zone, wire_server_mode=wire_server_mode, imds_mode=imds_mode, @@ -1815,8 +1817,8 @@ def update_vm(cmd, resource_group_name, vm_name, os_disk=None, disk_caching=None enable_hibernation=None, v_cpus_available=None, v_cpus_per_core=None, disk_controller_type=None, security_type=None, enable_proxy_agent=None, proxy_agent_mode=None, additional_scheduled_events=None, enable_user_reboot_scheduled_events=None, enable_user_redeploy_scheduled_events=None, - align_regional_disks_to_vm_zone=None, wire_server_mode=None, imds_mode=None, - add_proxy_agent_extension=None, + enable_all_instance_down=None, scheduled_events_api_version=None, align_regional_disks_to_vm_zone=None, + wire_server_mode=None, imds_mode=None, add_proxy_agent_extension=None, wire_server_access_control_profile_reference_id=None, imds_access_control_profile_reference_id=None, key_incarnation_id=None, zone_movement=None, zone=None, **kwargs): from azure.mgmt.core.tools import parse_resource_id, resource_id, is_valid_resource_id @@ -2054,39 +2056,56 @@ def _output(self, *args, **kwargs): vm["storage_profile"] = {} vm["storage_profile"]["disk_controller_type"] = disk_controller_type - if additional_scheduled_events is not None or \ - enable_user_reboot_scheduled_events is not None or enable_user_redeploy_scheduled_events is not None: + if additional_scheduled_events is not None or enable_user_reboot_scheduled_events is not None or \ + enable_user_redeploy_scheduled_events is not None or enable_all_instance_down is not None or \ + scheduled_events_api_version is not None: if vm.get("scheduled_events_policy", None) is None: - vm["scheduled_events_policy"] = { - "scheduled_events_additional_publishing_targets": { - "event_grid_and_resource_graph": { - "enable": additional_scheduled_events if additional_scheduled_events is not None else False + if additional_scheduled_events is not None or enable_user_reboot_scheduled_events is not None or \ + enable_user_redeploy_scheduled_events is not None: + vm["scheduled_events_policy"] = { + "scheduled_events_additional_publishing_targets": { + "event_grid_and_resource_graph": { + "enable": additional_scheduled_events if additional_scheduled_events is not None else False + }, }, - }, - "user_initiated_reboot": { - "automatically_approve": - enable_user_reboot_scheduled_events if enable_user_reboot_scheduled_events is not None else False # pylint: disable=line-too-long - }, - "user_initiated_redeploy": { - "automatically_approve": - enable_user_redeploy_scheduled_events if enable_user_redeploy_scheduled_events is not None else False # pylint: disable=line-too-long - } - } - else: - if additional_scheduled_events is not None: - vm["scheduled_events_policy"]["scheduled_events_additional_publishing_targets"] = { - "event_grid_and_resource_graph": { - "enable": additional_scheduled_events + "user_initiated_reboot": { + "automatically_approve": + enable_user_reboot_scheduled_events if enable_user_reboot_scheduled_events is not None else False # pylint: disable=line-too-long + }, + "user_initiated_redeploy": { + "automatically_approve": + enable_user_redeploy_scheduled_events if enable_user_redeploy_scheduled_events is not None else False # pylint: disable=line-too-long } } - if enable_user_redeploy_scheduled_events is not None: - vm["scheduled_events_policy"]["user_initiated_redeploy"] = { - "automatically_approve": enable_user_redeploy_scheduled_events - } - if enable_user_reboot_scheduled_events is not None: - vm["scheduled_events_policy"]["user_initiated_reboot"] = { - "automatically_approve": enable_user_reboot_scheduled_events - } + else: + vm["scheduled_events_policy"] = {} + + scheduled_events_policy = vm["scheduled_events_policy"] + if additional_scheduled_events is not None or scheduled_events_api_version is not None: + if scheduled_events_policy.get("scheduled_events_additional_publishing_targets", None) is None: + scheduled_events_policy["scheduled_events_additional_publishing_targets"] = {} + scheduled_events_additional_publishing_targets = scheduled_events_policy[ + "scheduled_events_additional_publishing_targets"] + if scheduled_events_additional_publishing_targets.get("event_grid_and_resource_graph", None) is None: + scheduled_events_additional_publishing_targets["event_grid_and_resource_graph"] = {} + event_grid_and_resource_graph = scheduled_events_additional_publishing_targets[ + "event_grid_and_resource_graph"] + if additional_scheduled_events is not None: + event_grid_and_resource_graph["enable"] = additional_scheduled_events + if scheduled_events_api_version is not None: + event_grid_and_resource_graph["scheduled_events_api_version"] = scheduled_events_api_version + if enable_all_instance_down is not None: + scheduled_events_policy["all_instances_down"] = { + "automatically_approve": enable_all_instance_down + } + if enable_user_redeploy_scheduled_events is not None: + scheduled_events_policy["user_initiated_redeploy"] = { + "automatically_approve": enable_user_redeploy_scheduled_events + } + if enable_user_reboot_scheduled_events is not None: + scheduled_events_policy["user_initiated_reboot"] = { + "automatically_approve": enable_user_reboot_scheduled_events + } if vm.get("resiliency_profile") is None: vm["resiliency_profile"] = {} @@ -2159,7 +2178,8 @@ def _output(self, *args, **kwargs): def create_av_set(cmd, availability_set_name, resource_group_name, platform_fault_domain_count=2, platform_update_domain_count=None, location=None, proximity_placement_group=None, unmanaged=False, no_wait=False, tags=None, validate=False, additional_scheduled_events=None, - enable_user_reboot_scheduled_events=None, enable_user_redeploy_scheduled_events=None): + enable_user_reboot_scheduled_events=None, enable_user_redeploy_scheduled_events=None, + enable_all_instance_down=None, scheduled_events_api_version=None): from azure.cli.core.util import random_string from azure.cli.core.commands.arm import ArmTemplateBuilder from azure.cli.command_modules.vm._template_builder import build_av_set_resource @@ -2175,7 +2195,9 @@ def create_av_set(cmd, availability_set_name, resource_group_name, platform_faul proximity_placement_group=proximity_placement_group, additional_scheduled_events=additional_scheduled_events, enable_user_reboot_scheduled_events=enable_user_reboot_scheduled_events, - enable_user_redeploy_scheduled_events=enable_user_redeploy_scheduled_events) + enable_user_redeploy_scheduled_events=enable_user_redeploy_scheduled_events, + enable_all_instance_down=enable_all_instance_down, + scheduled_events_api_version=scheduled_events_api_version) master_template.add_resource(av_set_resource) template = master_template.build() @@ -3763,8 +3785,8 @@ def create_vmss(cmd, vmss_name, resource_group_name, image=None, security_posture_reference_id=None, security_posture_reference_exclude_extensions=None, enable_resilient_creation=None, enable_resilient_deletion=None, additional_scheduled_events=None, enable_user_reboot_scheduled_events=None, - enable_user_redeploy_scheduled_events=None, skuprofile_vmsizes=None, - skuprofile_allostrat=None, skuprofile_rank=None, + enable_user_redeploy_scheduled_events=None, enable_all_instance_down=None, + scheduled_events_api_version=None, skuprofile_vmsizes=None, skuprofile_allostrat=None, skuprofile_rank=None, security_posture_reference_is_overridable=None, zone_balance=None, wire_server_mode=None, imds_mode=None, add_proxy_agent_extension=None, wire_server_access_control_profile_reference_id=None, imds_access_control_profile_reference_id=None, enable_automatic_zone_balancing=None, @@ -4084,6 +4106,8 @@ def _get_public_ip_address_allocation(value, sku): additional_scheduled_events=additional_scheduled_events, enable_user_reboot_scheduled_events=enable_user_reboot_scheduled_events, enable_user_redeploy_scheduled_events=enable_user_redeploy_scheduled_events, + enable_all_instance_down=enable_all_instance_down, + scheduled_events_api_version=scheduled_events_api_version, skuprofile_vmsizes=skuprofile_vmsizes, skuprofile_allostrat=skuprofile_allostrat, skuprofile_rank=skuprofile_rank, security_posture_reference_is_overridable=security_posture_reference_is_overridable, @@ -4641,8 +4665,8 @@ def update_vmss(cmd, resource_group_name, name, license_type=None, no_wait=False max_surge=None, enable_resilient_creation=None, enable_resilient_deletion=None, ephemeral_os_disk=None, ephemeral_os_disk_option=None, zones=None, additional_scheduled_events=None, enable_user_reboot_scheduled_events=None, enable_user_redeploy_scheduled_events=None, - upgrade_policy_mode=None, enable_auto_os_upgrade=None, skuprofile_vmsizes=None, - skuprofile_allostrat=None, skuprofile_rank=None, + enable_all_instance_down=None, scheduled_events_api_version=None, upgrade_policy_mode=None, + enable_auto_os_upgrade=None, skuprofile_vmsizes=None, skuprofile_allostrat=None, skuprofile_rank=None, security_posture_reference_is_overridable=None, zone_balance=None, wire_server_mode=None, imds_mode=None, add_proxy_agent_extension=None, wire_server_access_control_profile_reference_id=None, @@ -4776,30 +4800,43 @@ def _output(self, *args, **kwargs): {"not_before_timeout": terminate_notification_time, "enable": enable_terminate_notification} - if additional_scheduled_events is not None or \ - enable_user_reboot_scheduled_events is not None or enable_user_redeploy_scheduled_events is not None: + if additional_scheduled_events is not None or enable_user_reboot_scheduled_events is not None or \ + enable_user_redeploy_scheduled_events is not None or enable_all_instance_down is not None or \ + scheduled_events_api_version is not None: if vmss.get("scheduled_events_policy", None) is None: vmss["scheduled_events_policy"] = {} - if additional_scheduled_events is not None: - if vmss["scheduled_events_policy"].get("scheduled_events_additional_publishing_targets", None) is None: - vmss["scheduled_events_policy"]["scheduled_events_additional_publishing_targets"] = {} - if vmss["scheduled_events_policy"]["scheduled_events_additional_publishing_targets"].get("event_grid_and_resource_graph", None) is None: # pylint: disable=line-too-long - vmss["scheduled_events_policy"]["scheduled_events_additional_publishing_targets"]["event_grid_and_resource_graph"] = {} # pylint: disable=line-too-long - vmss["scheduled_events_policy"]["scheduled_events_additional_publishing_targets"][ - "event_grid_and_resource_graph"]["enable"] = additional_scheduled_events + scheduled_events_policy = vmss["scheduled_events_policy"] + if additional_scheduled_events is not None or scheduled_events_api_version is not None: + if scheduled_events_policy.get("scheduled_events_additional_publishing_targets", None) is None: + scheduled_events_policy["scheduled_events_additional_publishing_targets"] = {} + scheduled_events_additional_publishing_targets = scheduled_events_policy[ + "scheduled_events_additional_publishing_targets"] + if scheduled_events_additional_publishing_targets.get("event_grid_and_resource_graph", None) is None: + scheduled_events_additional_publishing_targets["event_grid_and_resource_graph"] = {} + event_grid_and_resource_graph = scheduled_events_additional_publishing_targets[ + "event_grid_and_resource_graph"] + if additional_scheduled_events is not None: + event_grid_and_resource_graph["enable"] = additional_scheduled_events + if scheduled_events_api_version is not None: + event_grid_and_resource_graph["scheduled_events_api_version"] = scheduled_events_api_version + + if enable_all_instance_down is not None: + scheduled_events_policy["all_instances_down"] = { + "automatically_approve": enable_all_instance_down + } if enable_user_redeploy_scheduled_events is not None: - if vmss["scheduled_events_policy"].get("user_initiated_redeploy", None) is None: - vmss["scheduled_events_policy"]["user_initiated_redeploy"] = {} - vmss["scheduled_events_policy"]["user_initiated_redeploy"]["automatically_approve"] \ - = enable_user_redeploy_scheduled_events + if scheduled_events_policy.get("user_initiated_redeploy", None) is None: + scheduled_events_policy["user_initiated_redeploy"] = {} + scheduled_events_policy["user_initiated_redeploy"]["automatically_approve"] = \ + enable_user_redeploy_scheduled_events if enable_user_reboot_scheduled_events is not None: - if vmss["scheduled_events_policy"].get("user_initiated_reboot", None) is None: - vmss["scheduled_events_policy"]["user_initiated_reboot"] = {} - vmss["scheduled_events_policy"]["user_initiated_reboot"][ - "automatically_approve"] = enable_user_reboot_scheduled_events + if scheduled_events_policy.get("user_initiated_reboot", None) is None: + scheduled_events_policy["user_initiated_reboot"] = {} + scheduled_events_policy["user_initiated_reboot"]["automatically_approve"] = \ + enable_user_reboot_scheduled_events if enable_osimage_notification is not None: if vmss.get("virtual_machine_profile", None) is None: diff --git a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_template_builder.py b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_template_builder.py index 87df1e73e92..1f6972dfb31 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_template_builder.py +++ b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_template_builder.py @@ -6,11 +6,80 @@ import unittest from unittest import mock -from azure.cli.command_modules.vm._template_builder import build_load_balancer_resource +from azure.cli.command_modules.vm._template_builder import (StorageProfile, build_av_set_resource, + build_load_balancer_resource, build_vm_resource, + build_vmss_resource) class TestTemplateBuilder(unittest.TestCase): + def test_build_scheduled_events_policy(self): + disk_info = {'os': {'caching': 'ReadWrite', 'storageAccountType': 'Standard_LRS'}} + vm_resource = build_vm_resource( + name='vm1', location='westus', tags={}, size='Standard_D2s_v5', + storage_profile=StorageProfile.ManagedPirImage, nics=[], admin_username='azureuser', + custom_image_os_type='linux', os_publisher='Canonical', os_offer='UbuntuServer', os_sku='18.04-LTS', + os_version='latest', disk_info=disk_info, additional_scheduled_events=True, + enable_user_reboot_scheduled_events=True, enable_user_redeploy_scheduled_events=True, + enable_all_instance_down=True, scheduled_events_api_version='2020-07-01') + + expected_policy = { + 'scheduledEventsAdditionalPublishingTargets': { + 'eventGridAndResourceGraph': { + 'enable': True, + 'scheduledEventsApiVersion': '2020-07-01' + } + }, + 'allInstancesDown': { + 'automaticallyApprove': True + }, + 'userInitiatedRedeploy': { + 'automaticallyApprove': True + }, + 'userInitiatedReboot': { + 'automaticallyApprove': True + } + } + self.assertEqual(vm_resource['properties']['scheduledEventsPolicy'], expected_policy) + + cmd_mock = mock.MagicMock() + cmd_mock.supported_api_version.return_value = False + vmss_resource = build_vmss_resource( + cmd=cmd_mock, name='vmss1', computer_name_prefix='vmss', location='westus', tags={}, overprovision=True, + upgrade_policy_mode='Manual', vm_sku='Standard_D2s_v5', instance_count=2, ip_config_name='ipconfig', + nic_name='nic', subnet_id=None, public_ip_per_vm=False, vm_domain_name=None, dns_servers=None, nsg=None, + accelerated_networking=None, admin_username='azureuser', authentication_type='ssh', + storage_profile=StorageProfile.ManagedPirImage, os_disk_name=None, disk_info=disk_info, os_type='linux', + os_publisher='Canonical', os_offer='UbuntuServer', os_sku='18.04-LTS', os_version='latest', + additional_scheduled_events=False, enable_all_instance_down=False, + scheduled_events_api_version='2020-07-01') + self.assertEqual(vmss_resource['properties']['scheduledEventsPolicy'], { + 'scheduledEventsAdditionalPublishingTargets': { + 'eventGridAndResourceGraph': { + 'enable': False, + 'scheduledEventsApiVersion': '2020-07-01' + } + }, + 'allInstancesDown': { + 'automaticallyApprove': False + } + }) + + cmd_mock.get_api_version.return_value = '2025-04-01' + av_set_resource = build_av_set_resource( + cmd_mock, 'avset1', 'westus', {}, platform_update_domain_count=1, platform_fault_domain_count=1, + unmanaged=False, enable_all_instance_down=True, scheduled_events_api_version='2020-07-01') + self.assertEqual(av_set_resource['properties']['scheduledEventsPolicy'], { + 'scheduledEventsAdditionalPublishingTargets': { + 'eventGridAndResourceGraph': { + 'scheduledEventsApiVersion': '2020-07-01' + } + }, + 'allInstancesDown': { + 'automaticallyApprove': True + } + }) + @mock.patch('azure.cli.command_modules.vm._template_builder.get_target_network_api', autospec=True) def test_build_load_balancer_resource(self, mock_get_api): mock_get_api.returtn_value = '1970-01-01'