Skip to content

Commit

Permalink
update (Azure#6944)
Browse files Browse the repository at this point in the history
  • Loading branch information
FumingZhang authored Nov 7, 2023
1 parent f22dbad commit a09eceb
Show file tree
Hide file tree
Showing 9 changed files with 2,088 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Pending
0.5.170
+++++++
* Add `az aks approuting` and `az aks approuting zone` commands for managing App Routing.
* Add `--os-sku` to the `az aks nodepool update` command.
* Add `--node-provisioning-mode` to the `az aks update` command.
* Add `--node-provisioning-mode` to the `az aks create` command.
* Add Artifact Streaming enablement option to node pool property in `az aks nodepool add` and `az aks nodepool update`.
Expand Down
3 changes: 3 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -1795,6 +1795,9 @@
- name: --enable-artifact-streaming
type: bool
short-summary: Enable artifact streaming for VirtualMachineScaleSets managed by a node pool, to speed up the cold-start of containers on a node through on-demand image loading. To use this feature, container images must also enable artifact streaming on ACR. If not specified, the default is false.
- name: --os-sku
type: string
short-summary: The os-sku of the agent node pool.
examples:
- name: Reconcile the nodepool back to its current state.
text: az aks nodepool update -g MyResourceGroup -n nodepool1 --cluster-name MyManagedCluster
Expand Down
2 changes: 2 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
node_mode_types = [CONST_NODEPOOL_MODE_SYSTEM, CONST_NODEPOOL_MODE_USER]
node_os_skus_create = [CONST_OS_SKU_AZURELINUX, CONST_OS_SKU_UBUNTU, CONST_OS_SKU_CBLMARINER, CONST_OS_SKU_MARINER]
node_os_skus = node_os_skus_create + [CONST_OS_SKU_WINDOWS2019, CONST_OS_SKU_WINDOWS2022]
node_os_skus_update = [CONST_OS_SKU_AZURELINUX, CONST_OS_SKU_CBLMARINER, CONST_OS_SKU_MARINER]
scale_down_modes = [CONST_SCALE_DOWN_MODE_DELETE, CONST_SCALE_DOWN_MODE_DEALLOCATE]
workload_runtimes = [CONST_WORKLOAD_RUNTIME_OCI_CONTAINER, CONST_WORKLOAD_RUNTIME_WASM_WASI, CONST_WORKLOAD_RUNTIME_KATA_MSHV_VM_ISOLATION, CONST_WORKLOAD_RUNTIME_KATA_CC_ISOLATION]
gpu_instance_profiles = [
Expand Down Expand Up @@ -754,6 +755,7 @@ def load_arguments(self, _):
c.argument('allowed_host_ports', validator=validate_allowed_host_ports, is_preview=True)
c.argument('asg_ids', validator=validate_application_security_groups, is_preview=True)
c.argument('enable_artifact_streaming', action='store_true', validator=validate_artifact_streaming, is_preview=True)
c.argument('os_sku', arg_type=get_enum_type(node_os_skus_update), validator=validate_os_sku)

with self.argument_context('aks nodepool upgrade') as c:
c.argument('max_surge', validator=validate_max_surge)
Expand Down
46 changes: 45 additions & 1 deletion src/aks-preview/azext_aks_preview/agentpool_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
CONST_WORKLOAD_RUNTIME_OCI_CONTAINER,
CONST_VIRTUAL_MACHINE_SCALE_SETS,
CONST_AVAILABILITY_SET,
CONST_VIRTUAL_MACHINES
CONST_VIRTUAL_MACHINES,
CONST_OS_SKU_UBUNTU,
)
from azext_aks_preview._params import node_os_skus_update
from azext_aks_preview._helpers import get_nodepool_snapshot_by_snapshot_id

logger = get_logger(__name__)
Expand Down Expand Up @@ -384,6 +386,40 @@ def get_enable_artifact_streaming(self) -> bool:
enable_artifact_streaming = self.agentpool.artifact_streaming_profile.enabled
return enable_artifact_streaming

def _get_os_sku(self, read_only: bool = False) -> Union[str, None]:
"""Internal function to dynamically obtain the value of os_sku according to the context.
Note: Overwritten in aks-preview to support being updated.
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 or None
"""
# read the original value passed by the command
raw_value = self.raw_param.get("os_sku")
# try to read the property value corresponding to the parameter from the `agentpool` object
value_obtained_from_agentpool = None
if self.agentpool and hasattr(self.agentpool, "os_sku"): # backward compatibility
value_obtained_from_agentpool = self.agentpool.os_sku
# 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.os_sku

# set default value
if self.decorator_mode == DecoratorMode.CREATE and value_obtained_from_agentpool is not None:
os_sku = value_obtained_from_agentpool
elif raw_value is not None:
os_sku = raw_value
elif not read_only and value_obtained_from_snapshot is not None:
os_sku = value_obtained_from_snapshot
else:
os_sku = raw_value
# this parameter does not need validation
return os_sku


class AKSPreviewAgentPoolAddDecorator(AKSAgentPoolAddDecorator):
def __init__(
Expand Down Expand Up @@ -637,6 +673,14 @@ def update_artifact_streaming(self, agentpool: AgentPool) -> AgentPool:
agentpool.artifact_streaming_profile.enabled = True
return agentpool

def update_os_sku(self, agentpool: AgentPool) -> AgentPool:
self._ensure_agentpool(agentpool)

os_sku = self.context.get_os_sku()
if os_sku:
agentpool.os_sku = os_sku
return agentpool

def update_agentpool_profile_preview(self, agentpools: List[AgentPool] = None) -> AgentPool:
"""The overall controller used to update the preview AgentPool profile.
Expand Down
1 change: 1 addition & 0 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,7 @@ def aks_agentpool_update(
allowed_host_ports=None,
asg_ids=None,
enable_artifact_streaming=False,
os_sku=None,
):
# DO NOT MOVE: get all the original parameters and save them as a dictionary
raw_parameters = locals()
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,82 @@ def common_get_enable_artifact_streaming(self):
ctx_2.attach_agentpool(agentpool_2)
self.assertEqual(ctx_2.get_enable_artifact_streaming(), None)

def common_get_os_sku(self):
# default
ctx_1 = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({"os_sku": None}),
self.models,
DecoratorMode.CREATE,
self.agentpool_decorator_mode,
)
self.assertEqual(ctx_1.get_os_sku(), None)
agentpool = self.create_initialized_agentpool_instance(os_sku="test_os_sku")
ctx_1.attach_agentpool(agentpool)
self.assertEqual(ctx_1.get_os_sku(), "test_os_sku")

# custom value
ctx_2 = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({"os_sku": None, "snapshot_id": "test_snapshot_id"}),
self.models,
DecoratorMode.CREATE,
self.agentpool_decorator_mode,
)
mock_snapshot = Mock(os_sku="test_os_sku")
with patch(
"azext_aks_preview.agentpool_decorator.get_nodepool_snapshot_by_snapshot_id",
return_value=mock_snapshot,
):
self.assertEqual(ctx_2.get_os_sku(), "test_os_sku")

# custom value
ctx_3 = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict(
{
"os_sku": "custom_os_sku",
"snapshot_id": "test_snapshot_id",
}
),
self.models,
DecoratorMode.CREATE,
self.agentpool_decorator_mode,
)
mock_snapshot = Mock(os_sku="test_os_sku")
with patch(
"azext_aks_preview.agentpool_decorator.get_nodepool_snapshot_by_snapshot_id",
return_value=mock_snapshot,
):
self.assertEqual(ctx_3.get_os_sku(), "custom_os_sku")

# custom value
ctx_4 = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict(
{
"os_sku": "custom_os_sku",
}
),
self.models,
DecoratorMode.UPDATE,
self.agentpool_decorator_mode,
)
agentpool_4 = self.create_initialized_agentpool_instance(os_sku="test_os_sku")
ctx_4.attach_agentpool(agentpool_4)
self.assertEqual(ctx_4.get_os_sku(), "custom_os_sku")

# custom value
ctx_5 = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({"os_sku": None}),
self.models,
DecoratorMode.UPDATE,
self.agentpool_decorator_mode,
)
agentpool_5 = self.create_initialized_agentpool_instance(os_sku="test_os_sku")
ctx_5.attach_agentpool(agentpool_5)
self.assertEqual(ctx_5.get_os_sku(), None)

class AKSPreviewAgentPoolContextStandaloneModeTestCase(AKSPreviewAgentPoolContextCommonTestCase):
def setUp(self):
Expand Down Expand Up @@ -313,6 +389,9 @@ def test_get_disable_custom_ca_trust(self):
def test_get_enable_artifact_streaming(self):
self.common_get_enable_artifact_streaming()

def test_get_os_sku(self):
self.common_get_os_sku()

class AKSPreviewAgentPoolContextManagedClusterModeTestCase(AKSPreviewAgentPoolContextCommonTestCase):
def setUp(self):
# manually register CUSTOM_MGMT_AKS_PREVIEW
Expand Down Expand Up @@ -347,6 +426,9 @@ def test_get_disable_custom_ca_trust(self):
def test_get_enable_artifact_streaming(self):
self.common_get_enable_artifact_streaming()

def test_get_os_sku(self):
self.common_get_os_sku()

class AKSPreviewAgentPoolAddDecoratorCommonTestCase(unittest.TestCase):
def _remove_defaults_in_agentpool(self, agentpool):
self.defaults_in_agentpool = {}
Expand Down Expand Up @@ -642,7 +724,7 @@ def test_construct_agentpool_profile_preview(self):
}
raw_param_dict.update(optional_params)

# default value in `aks_create`
# default value in `aks nodepool add`
dec_1 = AKSPreviewAgentPoolAddDecorator(
self.cmd,
self.client,
Expand Down Expand Up @@ -857,7 +939,7 @@ def test_update_agentpool_profile_preview(self):
}
raw_param_dict.update(optional_params)

# default value in `aks_create`
# default value in `aks nodepool update`
dec_1 = AKSPreviewAgentPoolUpdateDecorator(
self.cmd,
self.client,
Expand Down Expand Up @@ -921,7 +1003,7 @@ def test_update_agentpool_profile_preview(self):
}
raw_param_dict.update(optional_params)

# default value in `aks_create`
# default value in `aks nodepool update`
dec_1 = AKSPreviewAgentPoolUpdateDecorator(
self.cmd,
self.client,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8696,3 +8696,32 @@ def test_aks_approuting_zone_update(self, resource_group, resource_group_locatio
# delete cluster
delete_cmd = 'aks delete --resource-group={resource_group} --name={aks_name} --yes --no-wait'
self.cmd(delete_cmd, checks=[self.is_empty()])

@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(random_name_length=17, name_prefix='clitest', location='westus2')
def test_aks_update_agentpool_os_sku(self, resource_group, resource_group_location):
aks_name = self.create_random_name('cliakstest', 16)
self.kwargs.update({
'resource_group': resource_group,
'name': aks_name,
'ssh_key_value': self.generate_ssh_keys(),
})

# create
create_cmd = 'aks create --resource-group={resource_group} --name={name} -c 1 ' \
'--ssh-key-value={ssh_key_value}'
self.cmd(create_cmd, checks=[
self.check('provisioningState', 'Succeeded'),
])

# update nodepool
update_nodepool_cmd = 'aks nodepool update --resource-group={resource_group} --cluster-name={name} ' \
'--name=nodepool1 --os-sku AzureLinux ' \
'--aks-custom-headers AKSHTTPCustomFeatures=Microsoft.ContainerService/OSSKUMigrationPreview'
self.cmd(update_nodepool_cmd, checks=[
self.check('provisioningState', 'Succeeded'),
self.check('osSku', 'AzureLinux'),
])

# delete
self.cmd('aks delete -g {resource_group} -n {name} --yes --no-wait', checks=[self.is_empty()])
2 changes: 1 addition & 1 deletion src/aks-preview/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from setuptools import setup, find_packages

VERSION = "0.5.169"
VERSION = "0.5.170"

CLASSIFIERS = [
"Development Status :: 4 - Beta",
Expand Down

0 comments on commit a09eceb

Please sign in to comment.