diff --git a/src/aks-preview/HISTORY.rst b/src/aks-preview/HISTORY.rst index 79b399496a8..724de53171f 100644 --- a/src/aks-preview/HISTORY.rst +++ b/src/aks-preview/HISTORY.rst @@ -29,6 +29,9 @@ Pending +++++++ * `az aks create/update`: Add `--enable-app-routing-istio` / `--disable-app-routing-istio` (short: `--enable-ari` / `--disable-ari`) flags to enable or disable Istio as a Gateway API implementation for App Routing. * `az aks approuting gateway istio enable/disable`: Add new subcommands to enable or disable the Istio Gateway API implementation for App Routing on an existing cluster. +* `az aks machine add`: Add `--spot-max-price` flag support to set the max price (in US Dollars) you are willing to pay for spot instances on a machine. +* `az aks machine add`: Add `--eviction-policy` flag support to set the eviction policy for a machine. +* `az aks machine add`: Add `--enable-ultra-ssd` flag support to enable ultra ssd on a machine. * Add 'mTLS' as a transit encryption type option for `--acns-transit-encryption-type` in `az aks create/update` 19.0.0b25 diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index cac2a156f5c..e7737810fe5 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -2725,6 +2725,15 @@ - name: --node-public-ip-tags type: string short-summary: The ipTags of the machine public IPs. + - name: --spot-max-price + type: number + short-summary: The max price (in US Dollars) you are willing to pay for spot instances. + - name: --enable-ultra-ssd + type: bool + short-summary: Whether to enable UltraSSD. + - name: --eviction-policy + type: string + short-summary: The eviction policy for machine. This cannot be specified unless the priority is 'Spot'. If not specified, the default is 'Delete'. """ helps['aks machine update'] = """ diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index b1c272c44d9..0f1a29c7e63 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -2338,6 +2338,21 @@ def load_arguments(self, _): validator=validate_k8s_version, help="Version of Kubernetes to use for the machine.", ) + c.argument( + "spot_max_price", + type=float, + validator=validate_spot_max_price, + help="The max price (in US Dollars) you are willing to pay for spot instances." + ) + c.argument( + "enable_ultra_ssd", + action="store_true" + ) + c.argument( + "eviction_policy", + arg_type=get_enum_type(node_eviction_policies), + validator=validate_eviction_policy, + ) with self.argument_context("aks machine update") as c: c.argument( diff --git a/src/aks-preview/azext_aks_preview/custom.py b/src/aks-preview/azext_aks_preview/custom.py index acc7311ccdf..fdbb48414c1 100644 --- a/src/aks-preview/azext_aks_preview/custom.py +++ b/src/aks-preview/azext_aks_preview/custom.py @@ -2744,6 +2744,9 @@ def aks_machine_add( vm_size=None, kubernetes_version=None, no_wait=False, + spot_max_price=float("nan"), + enable_ultra_ssd=False, + eviction_policy=None, ): existedMachine = None try: diff --git a/src/aks-preview/azext_aks_preview/machine.py b/src/aks-preview/azext_aks_preview/machine.py index 69d55ab39e4..3bbf75ece1e 100644 --- a/src/aks-preview/azext_aks_preview/machine.py +++ b/src/aks-preview/azext_aks_preview/machine.py @@ -84,14 +84,18 @@ def constructMachine(cmd, raw_parameters, machine_name): ) tags = raw_parameters.get("tags") priority = raw_parameters.get("priority") + eviction_policy = raw_parameters.get("eviction_policy") machineProperties = MachineProperties( tags=tags, priority=priority, + eviction_policy=eviction_policy, network=set_machine_network(cmd, raw_parameters), hardware=set_machine_hardware_profile(cmd, raw_parameters), kubernetes=set_machine_kubernetes_profile(cmd, raw_parameters), - operating_system=set_machine_os_profile(cmd, raw_parameters) + operating_system=set_machine_os_profile(cmd, raw_parameters), + billing=set_machine_billing_profile(cmd, raw_parameters) ) + Machine = cmd.get_models( "Machine", resource_type=CUSTOM_MGMT_AKS_PREVIEW, @@ -106,6 +110,7 @@ def constructMachine(cmd, raw_parameters, machine_name): def set_machine_hardware_profile(cmd, raw_parameters): + enable_ultra_ssd = raw_parameters.get("enable_ultra_ssd") vm_size = raw_parameters.get("vm_size") if vm_size is None: raise RequiredArgumentMissingError( @@ -117,7 +122,8 @@ def set_machine_hardware_profile(cmd, raw_parameters): operation_group="machines" ) machine_hardware_profile = MachineHardwareProfile( - vm_size=vm_size + vm_size=vm_size, + ultra_ssd_enabled=enable_ultra_ssd ) return machine_hardware_profile @@ -196,3 +202,16 @@ def set_machine_os_profile(cmd, raw_parameters): enable_fips=enable_fips ) return machineOSProfile + + +def set_machine_billing_profile(cmd, raw_parameters): + spot_max_price = raw_parameters.get("spot_max_price") + MachineBillingProfile = cmd.get_models( + "MachineBillingProfile", + resource_type=CUSTOM_MGMT_AKS_PREVIEW, + operation_group="machines" + ) + machineBillingProfile = MachineBillingProfile( + spot_max_price=spot_max_price + ) + return machineBillingProfile diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py b/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py index a21bbbed4aa..59fd78e03fe 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py @@ -2685,6 +2685,84 @@ def test_aks_machines_nodepool(self, resource_group, resource_group_location): checks=[self.is_empty()], ) + @AllowLargeResponse() + @AKSCustomResourceGroupPreparer( + random_name_length=17, name_prefix="clitest", location="westus2" + ) + def test_aks_machine_add_spot_and_ultra_ssd(self, resource_group, resource_group_location): + aks_name = self.create_random_name("cliakstest", 16) + nodepool_name = self.create_random_name("c", 6) + self.kwargs.update( + { + "resource_group": resource_group, + "location": resource_group_location, + "name": aks_name, + "ssh_key_value": self.generate_ssh_keys(), + "nodepool_name": nodepool_name, + "machine_name": "machinetest1", + "vm_size": "Standard_D4s_v3", + } + ) + + # create aks cluster + self.cmd( + "aks create " + "--resource-group={resource_group} " + "--name={name} " + "--ssh-key-value={ssh_key_value}", + checks=[ + self.check("provisioningState", "Succeeded"), + ], + ) + + # add machines nodepool + self.cmd( + "aks nodepool add " + "--resource-group={resource_group}" + " --cluster-name={name} " + "--name={nodepool_name} " + "--mode=Machines", + checks=[ + self.check("provisioningState", "Succeeded"), + self.check("mode", "Machines"), + ], + ) + + # add machine with spot priority, eviction policy, spot-max-price, and ultra ssd + self.cmd( + "aks machine add " + " --resource-group={resource_group} " + " --cluster-name={name} " + " --nodepool-name={nodepool_name} " + " --machine-name={machine_name} " + " --vm-size={vm_size} " + " --zones 1 " + " --priority Spot " + " --eviction-policy Delete " + " --spot-max-price 0.5 " + " --enable-ultra-ssd" + ) + + # show the machine and verify spot/eviction/ultra-ssd settings + show_cmd = ( + "aks machine show " + " --resource-group={resource_group} " + " --cluster-name={name} " + " --nodepool-name={nodepool_name} " + " --machine-name={machine_name} -o json" + ) + machine_show = self.cmd(show_cmd).get_output_in_json() + assert machine_show["properties"]["priority"] == "Spot" + assert machine_show["properties"]["evictionPolicy"] == "Delete" + assert machine_show["properties"]["billing"]["spotMaxPrice"] == 0.5 + assert machine_show["properties"]["hardware"]["ultraSsdEnabled"] is True + + # delete AKS cluster + self.cmd( + "aks delete -g {resource_group} -n {name} --yes --no-wait", + checks=[self.is_empty()], + ) + @AllowLargeResponse() @AKSCustomResourceGroupPreparer( random_name_length=17, name_prefix="clitest", location="westus2"