Skip to content

Commit d81c74f

Browse files
aks-preview-extension: Add --max-unavailablemto the az aks nodepool add/update/upgrade commands (#8478)
1 parent 72332f5 commit d81c74f

File tree

10 files changed

+1905
-2
lines changed

10 files changed

+1905
-2
lines changed

src/aks-preview/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ If there is no rush to release a new version, please just add a description of t
99

1010
To release a new version, please select a new version number (usually plus 1 to last patch version, X.Y.Z -> Major.Minor.Patch, more details in `\doc <https://semver.org/>`_), and then add a new section named as the new version number in this file, the content should include the new modifications and everything from the *Pending* section. Finally, update the `VERSION` variable in `setup.py` with this new version number.
1111

12+
13.0.0b7
13+
+++++++
14+
* Add `--max-unavailable` to the `az aks nodepool add/update/upgrade` commands.
15+
1216
13.0.0b6
1317
+++++++
1418
* `az aks create/update`: Update parameter description of `--custom-ca-certificates`.

src/aks-preview/azext_aks_preview/_help.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,9 @@
17751775
- name: --node-soak-duration
17761776
type: int
17771777
short-summary: The amount of time (in minutes) to wait after draining a node and before reimaging it and moving on to next node.
1778+
- name: --max-unavailable
1779+
type: string
1780+
short-summary: The maximum number or percentage of nodes that can be simultaneously unavailable during upgrade. When specified, it represents the number or percent used, eg. 1 or 5%
17781781
- name: --kubelet-config
17791782
type: string
17801783
short-summary: Kubelet configurations for agent nodes.
@@ -1911,6 +1914,9 @@
19111914
- name: --node-soak-duration
19121915
type: int
19131916
short-summary: The amount of time (in minutes) to wait after draining a node and before reimaging it and moving on to next node.
1917+
- name: --max-unavailable
1918+
type: string
1919+
short-summary: The maximum number or percentage of nodes that can be simultaneously unavailable during upgrade. When specified, it represents the number or percent used, eg. 1 or 5%
19141920
- name: --aks-custom-headers
19151921
type: string
19161922
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2
@@ -1960,6 +1966,9 @@
19601966
- name: --node-soak-duration
19611967
type: int
19621968
short-summary: The amount of time (in minutes) to wait after draining a node and before reimaging it and moving on to next node.
1969+
- name: --max-unavailable
1970+
type: string
1971+
short-summary: The maximum number or percentage of nodes that can be simultaneously unavailable during upgrade. When specified, it represents the number or percent used, eg. 1 or 5%
19631972
- name: --mode
19641973
type: string
19651974
short-summary: The mode for a node pool which defines a node pool's primary function. If set as "System", AKS prefers system pods scheduling to node pools with mode `System`. Learn more at https://aka.ms/aks/nodepool/mode.

src/aks-preview/azext_aks_preview/_params.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@
194194
validate_custom_endpoints,
195195
validate_bootstrap_container_registry_resource_id,
196196
validate_gateway_prefix_size,
197+
validate_max_unavailable,
197198
)
198199
from azext_aks_preview.azurecontainerstorage._consts import (
199200
CONST_ACSTOR_ALL,
@@ -1469,6 +1470,7 @@ def load_arguments(self, _):
14691470
c.argument("drain_timeout", type=int)
14701471
c.argument("node_soak_duration", type=int)
14711472
c.argument("undrainable_node_behavior")
1473+
c.argument("max_unavailable", validator=validate_max_unavailable)
14721474
c.argument("mode", arg_type=get_enum_type(node_mode_types))
14731475
c.argument("scale_down_mode", arg_type=get_enum_type(scale_down_modes))
14741476
c.argument("max_pods", type=int, options_list=["--max-pods", "-m"])
@@ -1587,6 +1589,7 @@ def load_arguments(self, _):
15871589
c.argument("drain_timeout", type=int)
15881590
c.argument("node_soak_duration", type=int)
15891591
c.argument("undrainable_node_behavior")
1592+
c.argument("max_unavailable", validator=validate_max_unavailable)
15901593
c.argument("mode", arg_type=get_enum_type(node_mode_types))
15911594
c.argument("scale_down_mode", arg_type=get_enum_type(scale_down_modes))
15921595
# extensions
@@ -1657,6 +1660,7 @@ def load_arguments(self, _):
16571660
c.argument("drain_timeout", type=int)
16581661
c.argument("node_soak_duration", type=int)
16591662
c.argument("undrainable_node_behavior")
1663+
c.argument("max_unavailable", validator=validate_max_unavailable)
16601664
c.argument("snapshot_id", validator=validate_snapshot_id)
16611665
c.argument(
16621666
"yes",

src/aks-preview/azext_aks_preview/_validators.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,22 @@ def validate_max_surge(namespace):
464464
raise CLIError("--max-surge should be an int or percentage")
465465

466466

467+
def validate_max_unavailable(namespace):
468+
"""validates parameters max unavailable are positive integers or percents."""
469+
if namespace.max_unavailable is None:
470+
return
471+
int_or_percent = namespace.max_unavailable
472+
if int_or_percent.endswith('%'):
473+
int_or_percent = int_or_percent.rstrip('%')
474+
475+
try:
476+
if int(int_or_percent) < 0:
477+
raise CLIError("--max-unavailable must be positive")
478+
except ValueError:
479+
# pylint: disable=raise-missing-from
480+
raise CLIError("--max-unavailable should be an int or percentage")
481+
482+
467483
def validate_assign_identity(namespace):
468484
if namespace.assign_identity is not None:
469485
if namespace.assign_identity == '':

src/aks-preview/azext_aks_preview/agentpool_decorator.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,26 @@ def get_undrainable_node_behavior(self) -> str:
477477
# this parameter does not need validation
478478
return undrainable_node_behavior
479479

480+
def get_max_unavailable(self) -> str:
481+
"""Obtain the value of max_unavailable.
482+
483+
:return: string
484+
"""
485+
# read the original value passed by the command
486+
max_unavailable = self.raw_param.get("max_unavailable")
487+
# In create mode, try to read the property value corresponding to the parameter from the `agentpool` object
488+
if self.decorator_mode == DecoratorMode.CREATE:
489+
if (
490+
self.agentpool and
491+
self.agentpool.upgrade_settings and
492+
self.agentpool.upgrade_settings.max_unavailable is not None
493+
):
494+
max_unavailable = self.agentpool.upgrade_settings.max_unavailable
495+
496+
# this parameter does not need dynamic completion
497+
# this parameter does not need validation
498+
return max_unavailable
499+
480500
def get_enable_artifact_streaming(self) -> bool:
481501
"""Obtain the value of enable_artifact_streaming.
482502
:return: bool
@@ -1042,6 +1062,10 @@ def set_up_upgrade_settings(self, agentpool: AgentPool) -> AgentPool:
10421062
if undrainable_node_behavior:
10431063
upgrade_settings.undrainable_node_behavior = undrainable_node_behavior
10441064

1065+
max_unavailable = self.context.get_max_unavailable()
1066+
if max_unavailable:
1067+
upgrade_settings.max_unavailable = max_unavailable
1068+
10451069
agentpool.upgrade_settings = upgrade_settings
10461070
return agentpool
10471071

@@ -1267,6 +1291,10 @@ def update_upgrade_settings(self, agentpool: AgentPool) -> AgentPool:
12671291
upgrade_settings.undrainable_node_behavior = undrainable_node_behavior
12681292
agentpool.upgrade_settings = upgrade_settings
12691293

1294+
max_unavailable = self.context.get_max_unavailable()
1295+
if max_unavailable:
1296+
upgrade_settings.max_unavailable = max_unavailable
1297+
12701298
return agentpool
12711299

12721300
def update_agentpool(self, agentpool: AgentPool) -> AgentPool:

src/aks-preview/azext_aks_preview/custom.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,7 @@ def aks_agentpool_add(
11811181
drain_timeout=None,
11821182
node_soak_duration=None,
11831183
undrainable_node_behavior=None,
1184+
max_unavailable=None,
11841185
mode=CONST_NODEPOOL_MODE_USER,
11851186
scale_down_mode=CONST_SCALE_DOWN_MODE_DELETE,
11861187
max_pods=0,
@@ -1262,6 +1263,7 @@ def aks_agentpool_update(
12621263
drain_timeout=None,
12631264
node_soak_duration=None,
12641265
undrainable_node_behavior=None,
1266+
max_unavailable=None,
12651267
mode=None,
12661268
scale_down_mode=None,
12671269
no_wait=False,
@@ -1353,6 +1355,7 @@ def aks_agentpool_upgrade(cmd,
13531355
drain_timeout=None,
13541356
node_soak_duration=None,
13551357
undrainable_node_behavior=None,
1358+
max_unavailable=None,
13561359
snapshot_id=None,
13571360
no_wait=False,
13581361
aks_custom_headers=None,
@@ -1372,7 +1375,8 @@ def aks_agentpool_upgrade(cmd,
13721375
)
13731376

13741377
# Note: we exclude this option because node image upgrade can't accept nodepool put fields like max surge
1375-
if (max_surge or drain_timeout or node_soak_duration or undrainable_node_behavior) and node_image_only:
1378+
hasUpgradeSetting = max_surge or drain_timeout or node_soak_duration or undrainable_node_behavior or max_unavailable
1379+
if hasUpgradeSetting and node_image_only:
13761380
raise MutuallyExclusiveArgumentError(
13771381
"Conflicting flags. Unable to specify max-surge/drain-timeout/node-soak-duration with node-image-only."
13781382
"If you want to use max-surge/drain-timeout/node-soak-duration with a node image upgrade, please first "
@@ -1437,6 +1441,8 @@ def aks_agentpool_upgrade(cmd,
14371441
instance.upgrade_settings.node_soak_duration_in_minutes = node_soak_duration
14381442
if undrainable_node_behavior:
14391443
instance.upgrade_settings.undrainable_node_behavior = undrainable_node_behavior
1444+
if max_unavailable:
1445+
instance.upgrade_settings.max_unavailable = max_unavailable
14401446

14411447
# custom headers
14421448
aks_custom_headers = extract_comma_separated_string(

0 commit comments

Comments
 (0)