Skip to content

Commit 2665a8c

Browse files
authored
Add --migrate-vmas-to-vms option to support VMAS migration to VMS agent pool (#8711)
1 parent 290d278 commit 2665a8c

File tree

8 files changed

+215
-1
lines changed

8 files changed

+215
-1
lines changed

src/aks-preview/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ To release a new version, please select a new version number (usually plus 1 to
1212
Pending
1313
+++++++
1414

15+
17.0.0b2
16+
++++++++
17+
* Add option `--migrate-vmas-to-vms` to `az aks update`
18+
1519
17.0.0b1
1620
+++++++
1721
* [BREAKING CHANGE]: `az aks create`: Change default value of option `--node-vm-size` to ""

src/aks-preview/azext_aks_preview/_help.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,9 @@
12671267
- name: --disable-imds-restriction
12681268
type: bool
12691269
short-summary: Disable IMDS restriction in the cluster. All Pods in the cluster will be able to access IMDS.
1270+
- name: --migrate-vmas-to-vms
1271+
type: bool
1272+
short-summary: Migrate cluster with VMAS node pool to VMS node pool.
12701273
examples:
12711274
- name: Reconcile the cluster back to its current state.
12721275
text: az aks update -g MyResourceGroup -n MyManagedCluster

src/aks-preview/azext_aks_preview/_params.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,8 @@ def load_arguments(self, _):
14091409
arg_type=get_enum_type(health_probe_modes),
14101410
)
14111411

1412+
c.argument('migrate_vmas_to_vms', is_preview=True, action='store_true')
1413+
14121414
with self.argument_context("aks upgrade") as c:
14131415
c.argument("kubernetes_version", completer=get_k8s_upgrades_completion_list)
14141416
c.argument(

src/aks-preview/azext_aks_preview/custom.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ def aks_update(
761761
# IMDS restriction
762762
enable_imds_restriction=False,
763763
disable_imds_restriction=False,
764+
migrate_vmas_to_vms=False,
764765
):
765766
# DO NOT MOVE: get all the original parameters and save them as a dictionary
766767
raw_parameters = locals()

src/aks-preview/azext_aks_preview/managed_cluster_decorator.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_START,
2121
CONST_AZURE_SERVICE_MESH_DEFAULT_EGRESS_NAMESPACE,
2222
CONST_LOAD_BALANCER_SKU_BASIC,
23+
CONST_LOAD_BALANCER_SKU_STANDARD,
2324
CONST_MANAGED_CLUSTER_SKU_NAME_BASE,
2425
CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC,
2526
CONST_MANAGED_CLUSTER_SKU_TIER_FREE,
@@ -40,6 +41,8 @@
4041
CONST_OUTBOUND_TYPE_BLOCK,
4142
CONST_IMDS_RESTRICTION_ENABLED,
4243
CONST_IMDS_RESTRICTION_DISABLED,
44+
CONST_AVAILABILITY_SET,
45+
CONST_VIRTUAL_MACHINES,
4346
)
4447
from azext_aks_preview._helpers import (
4548
check_is_apiserver_vnet_integration_cluster,
@@ -2857,6 +2860,13 @@ def get_disable_imds_restriction(self) -> bool:
28572860
"""
28582861
return self.raw_param.get("disable_imds_restriction")
28592862

2863+
def get_migrate_vmas_to_vms(self) -> bool:
2864+
"""Obtain the value of migrate_vmas_to_vms.
2865+
2866+
:return: bool
2867+
"""
2868+
return self.raw_param.get("migrate_vmas_to_vms")
2869+
28602870

28612871
# pylint: disable=too-many-public-methods
28622872
class AKSPreviewManagedClusterCreateDecorator(AKSManagedClusterCreateDecorator):
@@ -5335,6 +5345,31 @@ def update_imds_restriction(self, mc: ManagedCluster) -> ManagedCluster:
53355345
raise DecoratorEarlyExitException()
53365346
return mc
53375347

5348+
def update_vmas_to_vms(self, mc: ManagedCluster) -> ManagedCluster:
5349+
"""Update the agent pool profile type from VMAS to VMS and LB sku to standard
5350+
5351+
:return: the ManagedCluster object
5352+
"""
5353+
self._ensure_mc(mc)
5354+
5355+
if self.context.get_migrate_vmas_to_vms():
5356+
msg = (
5357+
"\nWARNING: This operation will be disruptive to your workload while underway. "
5358+
"Do you wish to continue?"
5359+
)
5360+
if not self.context.get_yes() and not prompt_y_n(msg, default="n"):
5361+
raise DecoratorEarlyExitException()
5362+
# Ensure we have valid vmas AP
5363+
if len(mc.agent_pool_profiles) == 1 and mc.agent_pool_profiles[0].type == CONST_AVAILABILITY_SET:
5364+
mc.agent_pool_profiles[0].type = CONST_VIRTUAL_MACHINES
5365+
else:
5366+
raise CLIError('This is not a valid VMAS cluster, we cannot proceed with the migration.')
5367+
5368+
if mc.network_profile.load_balancer_sku == CONST_LOAD_BALANCER_SKU_BASIC:
5369+
mc.network_profile.load_balancer_sku = CONST_LOAD_BALANCER_SKU_STANDARD
5370+
5371+
return mc
5372+
53385373
def update_mc_profile_preview(self) -> ManagedCluster:
53395374
"""The overall controller used to update the preview ManagedCluster profile.
53405375
@@ -5410,6 +5445,8 @@ def update_mc_profile_preview(self) -> ManagedCluster:
54105445
mc = self.update_static_egress_gateway(mc)
54115446
# update imds restriction
54125447
mc = self.update_imds_restriction(mc)
5448+
# update VMAS to VMS
5449+
mc = self.update_vmas_to_vms(mc)
54135450

54145451
return mc
54155452

src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16079,3 +16079,59 @@ def test_aks_loadbalancer_commands(
1607916079
"aks delete -g {resource_group} -n {name} --yes --no-wait",
1608016080
checks=[self.is_empty()],
1608116081
)
16082+
16083+
16084+
# Comment out below tests as we only allow this in certain regions.
16085+
# @AllowLargeResponse()
16086+
# @AKSCustomResourceGroupPreparer(
16087+
# random_name_length=17,
16088+
# name_prefix="clitest",
16089+
# location="centraluseuap",
16090+
# )
16091+
# def test_aks_migrate_vmas_to_vms(
16092+
# self, resource_group, resource_group_location
16093+
# ):
16094+
# _, create_version = self._get_versions(resource_group_location)
16095+
# aks_name = self.create_random_name("cliakstest", 16)
16096+
# self.kwargs.update(
16097+
# {
16098+
# "resource_group": resource_group,
16099+
# "name": aks_name,
16100+
# "location": resource_group_location,
16101+
# "k8s_version": create_version,
16102+
# "ssh_key_value": self.generate_ssh_keys(),
16103+
# }
16104+
# )
16105+
16106+
# # create
16107+
# create_cmd = (
16108+
# "aks create --resource-group={resource_group} --name={name} --location={location} "
16109+
# "--ssh-key-value={ssh_key_value} "
16110+
# "--vm-set-type AvailabilitySet "
16111+
# "--load-balancer-sku Basic "
16112+
# )
16113+
# self.cmd(
16114+
# create_cmd,
16115+
# checks=[
16116+
# self.check('provisioningState', 'Succeeded'),
16117+
# self.check("agentPoolProfiles[0].type", "AvailabilitySet"),
16118+
# self.check("networkProfile.loadBalancerSku", "basic"),
16119+
# ],
16120+
# )
16121+
16122+
# # update -- migrate vmas to vma
16123+
# update_cmd = (
16124+
# "aks update --resource-group {resource_group} --name {name} "
16125+
# "--migrate-vmas-to-vms --yes "
16126+
# )
16127+
# self.cmd(update_cmd, checks=[
16128+
# self.check('provisioningState', 'Succeeded'),
16129+
# self.check("agentPoolProfiles[0].type", "VirtualMachines"),
16130+
# self.check("networkProfile.loadBalancerSku", "standard"),
16131+
# ])
16132+
16133+
# # delete
16134+
# self.cmd(
16135+
# "aks delete -g {resource_group} -n {name} --yes --no-wait",
16136+
# checks=[self.is_empty()],
16137+
# )

src/aks-preview/azext_aks_preview/tests/latest/test_managed_cluster_decorator.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
CONST_KUBE_DASHBOARD_ADDON_NAME,
3838
CONST_LOAD_BALANCER_BACKEND_POOL_TYPE_NODE_IP,
3939
CONST_LOAD_BALANCER_SKU_STANDARD,
40+
CONST_LOAD_BALANCER_SKU_BASIC,
4041
CONST_MONITORING_ADDON_NAME,
4142
CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID,
4243
CONST_MONITORING_USING_AAD_MSI_AUTH,
@@ -47,6 +48,8 @@
4748
CONST_ROTATION_POLL_INTERVAL,
4849
CONST_SECRET_ROTATION_ENABLED,
4950
CONST_VIRTUAL_MACHINE_SCALE_SETS,
51+
CONST_AVAILABILITY_SET,
52+
CONST_VIRTUAL_MACHINES,
5053
CONST_VIRTUAL_NODE_ADDON_NAME,
5154
CONST_VIRTUAL_NODE_SUBNET_NAME,
5255
CONST_WORKLOAD_RUNTIME_OCI_CONTAINER,
@@ -85,6 +88,7 @@
8588
MutuallyExclusiveArgumentError,
8689
RequiredArgumentMissingError,
8790
UnknownError,
91+
CLIError,
8892
)
8993
from azure.cli.command_modules.acs._consts import (
9094
CONST_OUTBOUND_TYPE_LOAD_BALANCER,
@@ -9078,6 +9082,113 @@ def test_update_acns_in_network_profile(self):
90789082
),
90799083
)
90809084
self.assertEqual(dec_mc_1, ground_truth_mc_1)
9085+
9086+
def test_update_vmas_to_vms(self):
9087+
# Should not update mc if unset
9088+
dec_0 = AKSPreviewManagedClusterUpdateDecorator(
9089+
self.cmd,
9090+
self.client,
9091+
{},
9092+
CUSTOM_MGMT_AKS_PREVIEW,
9093+
)
9094+
mc_0 = self.models.ManagedCluster(
9095+
location="test_location",
9096+
)
9097+
dec_0.context.attach_mc(mc_0)
9098+
dec_mc_0 = dec_0.update_vmas_to_vms(mc_0)
9099+
ground_truth_mc_0 = self.models.ManagedCluster(
9100+
location="test_location",
9101+
)
9102+
self.assertEqual(dec_mc_0, ground_truth_mc_0)
9103+
9104+
# Should raise error if trying to migrate non-vmas cluster to vms
9105+
dec_1 = AKSPreviewManagedClusterUpdateDecorator(
9106+
self.cmd,
9107+
self.client,
9108+
{
9109+
"migrate_vmas_to_vms": True,
9110+
"yes": True,
9111+
},
9112+
CUSTOM_MGMT_AKS_PREVIEW,
9113+
)
9114+
mc_1 = self.models.ManagedCluster(
9115+
location="test_location",
9116+
)
9117+
ap_1 = self.models.ManagedClusterAgentPoolProfile(
9118+
name="test_np_name",
9119+
type=CONST_VIRTUAL_MACHINE_SCALE_SETS,
9120+
)
9121+
mc_1.agent_pool_profiles = [ap_1]
9122+
dec_1.context.attach_mc(mc_1)
9123+
with self.assertRaises(CLIError):
9124+
dec_1.update_vmas_to_vms(mc_1)
9125+
9126+
# Should raise error if cluster has more than 1 AP
9127+
dec_2 = AKSPreviewManagedClusterUpdateDecorator(
9128+
self.cmd,
9129+
self.client,
9130+
{
9131+
"migrate_vmas_to_vms": True,
9132+
"yes": True,
9133+
},
9134+
CUSTOM_MGMT_AKS_PREVIEW,
9135+
)
9136+
mc_2 = self.models.ManagedCluster(
9137+
location="test_location",
9138+
)
9139+
ap_2_1 = self.models.ManagedClusterAgentPoolProfile(
9140+
name="test_np_name_1",
9141+
type=CONST_AVAILABILITY_SET,
9142+
)
9143+
ap_2_2 = self.models.ManagedClusterAgentPoolProfile(
9144+
name="test_np_name_2",
9145+
type=CONST_AVAILABILITY_SET,
9146+
)
9147+
mc_2.agent_pool_profiles = [ap_2_1, ap_2_2]
9148+
dec_2.context.attach_mc(mc_2)
9149+
with self.assertRaises(CLIError):
9150+
dec_2.update_vmas_to_vms(mc_2)
9151+
9152+
# Should migrate vmas-blb to vms-slb
9153+
dec_3 = AKSPreviewManagedClusterUpdateDecorator(
9154+
self.cmd,
9155+
self.client,
9156+
{
9157+
"migrate_vmas_to_vms": True,
9158+
"yes": True,
9159+
},
9160+
CUSTOM_MGMT_AKS_PREVIEW,
9161+
)
9162+
mc_3 = self.models.ManagedCluster(
9163+
location="test_location",
9164+
)
9165+
ap_3 = self.models.ManagedClusterAgentPoolProfile(
9166+
name="test_np_name",
9167+
type=CONST_AVAILABILITY_SET,
9168+
)
9169+
network_profile_3 = self.models.ContainerServiceNetworkProfile(
9170+
load_balancer_sku=CONST_LOAD_BALANCER_SKU_BASIC,
9171+
)
9172+
mc_3.agent_pool_profiles = [ap_3]
9173+
mc_3.network_profile = network_profile_3
9174+
dec_3.context.attach_mc(mc_3)
9175+
dec_mc_3 = dec_3.update_vmas_to_vms(mc_3)
9176+
9177+
ground_truth_mc_3 = self.models.ManagedCluster(
9178+
location="test_location",
9179+
)
9180+
ground_truth_ap_3 = self.models.ManagedClusterAgentPoolProfile(
9181+
name="test_np_name",
9182+
type=CONST_VIRTUAL_MACHINES,
9183+
)
9184+
ground_truth_network_profile_3 = self.models.ContainerServiceNetworkProfile(
9185+
load_balancer_sku=CONST_LOAD_BALANCER_SKU_STANDARD,
9186+
)
9187+
ground_truth_mc_3.agent_pool_profiles = [ground_truth_ap_3]
9188+
ground_truth_mc_3.network_profile = ground_truth_network_profile_3
9189+
self.assertEqual(dec_mc_3, ground_truth_mc_3)
9190+
9191+
90819192

90829193
def test_enable_retina_network_flow_logs(self):
90839194
# Case 1: enable_acns, enable monitoring addons_profile, enable retina_network_flow_logs

src/aks-preview/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from setuptools import setup, find_packages
1111

12-
VERSION = "17.0.0b1"
12+
VERSION = "17.0.0b2"
1313

1414
CLASSIFIERS = [
1515
"Development Status :: 4 - Beta",

0 commit comments

Comments
 (0)