Skip to content

Commit

Permalink
{AKS} add --sku to az aks create/update command (#7478)
Browse files Browse the repository at this point in the history
  • Loading branch information
xmzhao0822 committed Apr 10, 2024
1 parent 1a1942e commit 6d1ffbc
Show file tree
Hide file tree
Showing 13 changed files with 4,344 additions and 21 deletions.
5 changes: 5 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ To release a new version, please select a new version number (usually plus 1 to

Pending
+++++++

3.0.0b2
+++++++
* Add `--sku` to the `az aks create` command.
* Add `--sku` to the `az aks update` command.
* Support cluster service health probe mode by `--cluster-service-load-balancer-health-probe-mode {Shared, Servicenodeport}`

3.0.0b1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
"trusted launch, missing feature registration & toggle": [
"test_aks_create_update_secure_boot_flow",
"test_aks_create_update_vtpm_flow"
],
"automatic, missing feature registration & toggle": [
"test_aks_automatic_sku"
]
}
}
5 changes: 5 additions & 0 deletions src/aks-preview/azext_aks_preview/_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

# vm size
CONST_DEFAULT_NODE_VM_SIZE = "Standard_DS2_v2"
CONST_DEFAULT_AUTOMATIC_SKU_NODE_VM_SIZE = "Standard_DS4_v2"
CONST_DEFAULT_WINDOWS_NODE_VM_SIZE = "Standard_D2s_v3"

# workload runtime
Expand All @@ -67,6 +68,10 @@
CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD = "standard"
CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM = "premium"

# ManagedClusterSKU Name
CONST_MANAGED_CLUSTER_SKU_NAME_BASE = "base"
CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC = "automatic"

CONST_OUTBOUND_MIGRATION_MULTIZONE_TO_NATGATEWAY_MSG = (
"Warning: this AKS cluster has multi-zonal nodepools, but NAT Gateway is not currently zone redundant. "
"Migrating outbound connectivity to NAT Gateway could lead to a reduction in zone redundancy for this cluster. "
Expand Down
6 changes: 6 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@
- name: --uptime-sla
type: bool
short-summary: --uptime-sla is deprecated. Please use '--tier standard' instead.
- name: --sku
type: string
short-summary: Specify SKU name for managed clusters. '--sku base' enables a base managed cluster. '--sku automatic' enables an automatic managed cluster.
- name: --tier
type: string
short-summary: Specify SKU tier for managed clusters. '--tier standard' enables a standard managed cluster service with a financially backed SLA. '--tier free' does not have a financially backed SLA.
Expand Down Expand Up @@ -764,6 +767,9 @@
- name: --no-uptime-sla
type: bool
short-summary: Change a standard managed cluster to a free one. --no-uptime-sla is deprecated. Please use '--tier free' instead.
- name: --sku
type: string
short-summary: Specify SKU name for managed clusters. '--sku base' enables a base managed cluster. '--sku automatic' enables an automatic managed cluster.
- name: --tier
type: string
short-summary: Specify SKU tier for managed clusters. '--tier standard' enables a standard managed cluster service with a financially backed SLA. '--tier free' changes a standard managed cluster to a free one.
Expand Down
12 changes: 12 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@
CONST_WORKLOAD_RUNTIME_WASM_WASI,
CONST_NODE_PROVISIONING_MODE_MANUAL,
CONST_NODE_PROVISIONING_MODE_AUTO,
CONST_MANAGED_CLUSTER_SKU_NAME_BASE,
CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC,
CONST_SSH_ACCESS_LOCALUSER,
CONST_SSH_ACCESS_DISABLED,
CONST_CLUSTER_SERVICE_HEALTH_PROBE_MODE_SERVICE_NODE_PORT,
Expand Down Expand Up @@ -237,6 +239,10 @@

# consts for ManagedCluster
load_balancer_skus = [CONST_LOAD_BALANCER_SKU_BASIC, CONST_LOAD_BALANCER_SKU_STANDARD]
sku_names = [
CONST_MANAGED_CLUSTER_SKU_NAME_BASE,
CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC,
]
sku_tiers = [
CONST_MANAGED_CLUSTER_SKU_TIER_FREE,
CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD,
Expand Down Expand Up @@ -505,6 +511,9 @@ def load_arguments(self, _):
target="--uptime-sla", redirect="--tier", hide=True
),
)
c.argument(
"sku", is_preview=True, arg_type=get_enum_type(sku_names)
)
c.argument(
"tier", arg_type=get_enum_type(sku_tiers), validator=validate_sku_tier
)
Expand Down Expand Up @@ -965,6 +974,9 @@ def load_arguments(self, _):
target="--no-uptime-sla", redirect="--tier", hide=True
),
)
c.argument(
"sku", is_preview=True, arg_type=get_enum_type(sku_names)
)
c.argument(
"tier", arg_type=get_enum_type(sku_tiers), validator=validate_sku_tier
)
Expand Down
53 changes: 53 additions & 0 deletions src/aks-preview/azext_aks_preview/agentpool_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
CONST_VIRTUAL_MACHINE_SCALE_SETS,
CONST_AVAILABILITY_SET,
CONST_VIRTUAL_MACHINES,
CONST_DEFAULT_NODE_VM_SIZE,
CONST_DEFAULT_AUTOMATIC_SKU_NODE_VM_SIZE,
CONST_DEFAULT_WINDOWS_NODE_VM_SIZE,
)
from azext_aks_preview._helpers import get_nodepool_snapshot_by_snapshot_id

Expand Down Expand Up @@ -104,6 +107,56 @@ def get_vm_set_type(self) -> str:
# this parameter does not need validation
return vm_set_type

def get_node_vm_size(self) -> str:
"""Obtain the value of node_vm_size.
:return: string
"""
return self._get_node_vm_size(read_only=False)

def _get_node_vm_size(self, read_only: bool = False) -> str:
"""Internal function to dynamically obtain the value of node_vm_size according to the context.
If snapshot_id is specified, dynamic completion will be triggerd, and will try to get the corresponding value
from the Snapshot. When determining the value of the parameter, obtaining from `agentpool` takes precedence over
user's explicit input over snapshot over default vaule.
:return: string
"""
# read the original value passed by the command
raw_value = self.raw_param.get("node_vm_size")
# try to read the property value corresponding to the parameter from the `agentpool` object
value_obtained_from_agentpool = None
if self.agentpool:
value_obtained_from_agentpool = self.agentpool.vm_size
# try to retrieve the value from snapshot
value_obtained_from_snapshot = None
# skip dynamic completion if read_only is specified
if not read_only:
snapshot = self.get_snapshot()
if snapshot:
value_obtained_from_snapshot = snapshot.vm_size

# set default value
if value_obtained_from_agentpool is not None:
node_vm_size = value_obtained_from_agentpool
elif raw_value is not None:
node_vm_size = raw_value
elif not read_only and value_obtained_from_snapshot is not None:
node_vm_size = value_obtained_from_snapshot
else:
if self.get_os_type().lower() == "windows":
node_vm_size = CONST_DEFAULT_WINDOWS_NODE_VM_SIZE
else:
node_vm_size = CONST_DEFAULT_NODE_VM_SIZE
sku = self.raw_param.get("sku")
# if --node-vm-size is not specified, but --sku automatic is explicitly specified
if sku is not None and sku == "automatic":
node_vm_size = CONST_DEFAULT_AUTOMATIC_SKU_NODE_VM_SIZE

# this parameter does not need validation
return node_vm_size

def get_crg_id(self) -> Union[str, None]:
"""Obtain the value of crg_id.
Expand Down
2 changes: 2 additions & 0 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ def aks_create(
node_os_upgrade_channel=None,
cluster_autoscaler_profile=None,
uptime_sla=False,
sku=None,
tier=None,
fqdn_subdomain=None,
api_server_authorized_ip_ranges=None,
Expand Down Expand Up @@ -701,6 +702,7 @@ def aks_update(
cluster_autoscaler_profile=None,
uptime_sla=False,
no_uptime_sla=False,
sku=None,
tier=None,
api_server_authorized_ip_ranges=None,
enable_public_fqdn=False,
Expand Down
74 changes: 54 additions & 20 deletions src/aks-preview/azext_aks_preview/managed_cluster_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_ROLLBACK,
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_START,
CONST_LOAD_BALANCER_SKU_BASIC,
CONST_MANAGED_CLUSTER_SKU_NAME_BASE,
CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC,
CONST_MANAGED_CLUSTER_SKU_TIER_FREE,
CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM,
CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD,
Expand Down Expand Up @@ -300,6 +302,20 @@ def get_ip_families(self) -> Union[List[str], None]:
# this parameter does not need validation
return ip_families

def get_sku_name(self) -> str:
# read the original value passed by the command
skuName = self.raw_param.get("sku")
if skuName is None:
if (
self.mc and
self.mc.sku and
getattr(self.mc.sku, 'name', None) is not None
):
skuName = vars(self.mc.sku)['name'].lower()
else:
skuName = CONST_MANAGED_CLUSTER_SKU_NAME_BASE
return skuName

def _get_outbound_type(
self,
enable_validation: bool = False,
Expand Down Expand Up @@ -354,6 +370,10 @@ def _get_outbound_type(
outbound_type != CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING
):
outbound_type = CONST_OUTBOUND_TYPE_LOAD_BALANCER
skuName = self.get_sku_name()
if skuName is not None and skuName == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC:
# outbound_type of Automatic SKU should be ManagedNATGateway if not provided.
outbound_type = CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY

# validation
# Note: The parameters involved in the validation are not verified in their own getters.
Expand Down Expand Up @@ -3171,17 +3191,23 @@ def set_up_sku(self, mc: ManagedCluster) -> ManagedCluster:
"""
self._ensure_mc(mc)

mc.sku = self.models.ManagedClusterSKU()
skuName = self.context.get_sku_name()
if skuName is not None and skuName == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC:
mc.sku.name = "Automatic"
# passive Kind should always to match sku.name
mc.kind = "Automatic"
mc.sku.tier = "Standard"
else:
mc.sku.name = "Base"
# passive Kind should always match sku.name
mc.kind = "Base"
mc.sku.tier = "Free"
if self.context.get_uptime_sla() or self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD:
mc.sku = self.models.ManagedClusterSKU( # pylint: disable=no-member
name="Base",
tier="Standard"
)
mc.sku.tier = "Standard"

if self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM:
mc.sku = self.models.ManagedClusterSKU( # pylint: disable=no-member
name="Base",
tier="Premium"
)
mc.sku.tier = "Premium"
return mc

def set_up_k8s_support_plan(self, mc: ManagedCluster) -> ManagedCluster:
Expand Down Expand Up @@ -4431,24 +4457,32 @@ def update_sku(self, mc: ManagedCluster) -> ManagedCluster:
"""
self._ensure_mc(mc)

# there are existing MCs with nil sku, that is Base/Free
if mc.sku is None:
mc.sku = self.models.ManagedClusterSKU(
sku="Base",
tier="Free",
)
skuName = self.context.get_sku_name()

if skuName is not None and skuName == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC:
mc.sku.name = "Automatic"
# passive Kind should always to match sku.name
mc.kind = "Automatic"
else:
mc.sku.name = "Base"
# passive Kind should always match sku.name
mc.kind = "Base"

# Premium without LTS is ok (not vice versa)
if self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM:
mc.sku = self.models.ManagedClusterSKU( # pylint: disable=no-member
name="Base",
tier="Premium"
)
mc.sku.tier = "Premium"

if self.context.get_uptime_sla() or self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD:
mc.sku = self.models.ManagedClusterSKU( # pylint: disable=no-member
name="Base",
tier="Standard"
)
mc.sku.tier = "Standard"

if self.context.get_no_uptime_sla() or self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_FREE:
mc.sku = self.models.ManagedClusterSKU( # pylint: disable=no-member
name="Base",
tier="Free"
)
mc.sku.tier = "Free"
return mc

def update_upgrade_settings(self, mc: ManagedCluster) -> ManagedCluster:
Expand Down
Loading

0 comments on commit 6d1ffbc

Please sign in to comment.