Skip to content

Commit 8a04a7d

Browse files
authored
add AKS Fleet 2026-02-01-preview API CLI changes (#9611)
1 parent 9d6509e commit 8a04a7d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+3951
-4653
lines changed

src/fleet/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,7 @@ Release History
173173
1.8.3
174174
++++++
175175
* Add automatic kubelogin conversion to Azure CLI authentication for fleet get-credentials command.
176+
177+
1.9.0
178+
++++++
179+
* Add 2026-02-01-preview API Version with UpdateRun MaxConcurrency support. Add fix for ControlPlaneOnly upgrade type requiring no node image selection.

src/fleet/azext_fleet/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def register_fleet_resource_type():
1515
register_resource_type(
1616
"latest",
1717
CUSTOM_MGMT_FLEET,
18-
SDKProfile("2025-08-01-preview"),
18+
SDKProfile("2026-02-01-preview"),
1919
)
2020

2121

src/fleet/azext_fleet/_help.py

Lines changed: 89 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -208,38 +208,99 @@
208208
A stages array is composed of one or more stages, each containing one or more groups.
209209
Each group contains the 'name' property, which represents the group to which a cluster belongs (see 'az fleet member create --help').
210210
Stages have an optional 'afterStageWaitInSeconds' integer property, acting as a delay between stage execution.
211-
{
212-
"stages": [
211+
Stages and groups have an optional 'maxConcurrency' string property that sets the maximum number of concurrent upgrades allowed. It acts as a ceiling (not a quota)—actual concurrency may be lower due to other limits or member conditions. Minimum is 1.
212+
Stage maxConcurrency: applies across all groups in the stage (total concurrent upgrades for the whole stage).
213+
Group maxConcurrency: applies within a single group, and is additionally constrained by the stage limit (effective max is min(group cluster count, stage maxConcurrency)). Minimum is 1.
214+
Value formats:
215+
Fixed count (e.g., 3)
216+
Percentage (e.g., 25%, 1–100) of the relevant cluster total (stage total for stage, group total for group). Percentages are rounded down, with a minimum of 1 enforced.
217+
Examples: 3, 25%, 100%
218+
219+
Example stages JSON, with optional properties maxConcurrency and before/after gates:
220+
{
221+
"stages": [
222+
{
223+
"name": "stage1",
224+
"maxConcurrency": "7%",
225+
"beforeGates": [
213226
{
214-
"name": "stage1",
215-
"groups": [
216-
{
217-
"name": "group-a1"
218-
},
219-
{
220-
"name": "group-a2"
221-
},
222-
{
223-
"name": "group-a3"
224-
}
225-
],
226-
"afterStageWaitInSeconds": 3600
227+
"displayName": "stage before gate",
228+
"type": "Approval"
229+
}
230+
],
231+
"afterGates": [
232+
{
233+
"displayName": "stage after gate",
234+
"type": "Approval"
235+
}
236+
],
237+
"groups": [
238+
{
239+
"name": "group-a1",
240+
"maxConcurrency": "100%",
241+
"beforeGates": [
242+
{
243+
"displayName": "group before gate",
244+
"type": "Approval"
245+
}
246+
],
247+
"afterGates": [
248+
{
249+
"displayName": "group after gate",
250+
"type": "Approval"
251+
}
252+
]
253+
},
254+
{
255+
"name": "group-a2",
256+
"maxConcurrency": "1",
257+
"beforeGates": [
258+
{
259+
"displayName": "group before gate",
260+
"type": "Approval"
261+
}
262+
],
263+
"afterGates": [
264+
{
265+
"displayName": "group after gate",
266+
"type": "Approval"
267+
}
268+
]
227269
},
228270
{
229-
"name": "stage2",
230-
"groups": [
231-
{
232-
"name": "group-b1"
233-
},
234-
{
235-
"name": "group-b2"
236-
},
237-
{
238-
"name": "group-b3"
239-
}
240-
]
271+
"name": "group-a3",
272+
"maxConcurrency": "1",
273+
"beforeGates": [
274+
{
275+
"displayName": "group before gate",
276+
"type": "Approval"
277+
}
278+
],
279+
"afterGates": [
280+
{
281+
"displayName": "group after gate",
282+
"type": "Approval"
283+
}
284+
]
285+
}
286+
],
287+
"afterStageWaitInSeconds": 3600
288+
},
289+
{
290+
"name": "stage2",
291+
"groups": [
292+
{
293+
"name": "group-b1"
294+
},
295+
{
296+
"name": "group-b2"
241297
},
242-
]
298+
{
299+
"name": "group-b3"
300+
}
301+
]
302+
}
303+
]
243304
}
244305
"""
245306

src/fleet/azext_fleet/custom.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from azext_fleet.constants import SUPPORTED_GATE_STATES_FILTERS
3131
from azext_fleet.constants import SUPPORTED_GATE_STATES_PATCH
3232
from azext_fleet.constants import FLEET_1P_APP_ID
33-
from azext_fleet.vendored_sdks.v2025_08_01_preview.models import (
33+
from azext_fleet.vendored_sdks.v2026_02_01_preview.models import (
3434
PropagationPolicy,
3535
PlacementProfile,
3636
PlacementV1ClusterResourcePlacementSpec,
@@ -441,6 +441,9 @@ def create_update_run(cmd,
441441
raise CLIError((f"The upgrade type parameter '{upgrade_type}' is not valid."
442442
f"Valid options are: '{UPGRADE_TYPE_FULL}', '{UPGRADE_TYPE_CONTROLPLANEONLY}', or '{UPGRADE_TYPE_NODEIMAGEONLY}'")) # pylint: disable=line-too-long
443443

444+
if upgrade_type == UPGRADE_TYPE_CONTROLPLANEONLY and node_image_selection is not None:
445+
raise CLIError("Node image selection must not be set when upgrade type is 'ControlPlaneOnly'.")
446+
444447
if stages is not None and update_strategy_name is not None:
445448
raise CLIError("Cannot set stages when update strategy name is set.")
446449

@@ -469,9 +472,12 @@ def create_update_run(cmd,
469472

470473
managed_cluster_upgrade_spec = managed_cluster_upgrade_spec_model(
471474
type=upgrade_type, kubernetes_version=kubernetes_version)
472-
if node_image_selection is None:
473-
node_image_selection = "Latest"
474-
node_image_selection_type = node_image_selection_model(type=node_image_selection)
475+
476+
node_image_selection_type = None
477+
if upgrade_type != UPGRADE_TYPE_CONTROLPLANEONLY:
478+
if node_image_selection is None:
479+
node_image_selection = "Latest"
480+
node_image_selection_type = node_image_selection_model(type=node_image_selection)
475481

476482
managed_cluster_update = managed_cluster_update_model(
477483
upgrade=managed_cluster_upgrade_spec,
@@ -603,6 +609,7 @@ def get_update_run_strategy(cmd, operation_group, stages):
603609
for group in stage["groups"]:
604610
update_groups.append(update_group_model(
605611
name=group["name"],
612+
max_concurrency=group.get("maxConcurrency"),
606613
before_gates=group.get("beforeGates", []),
607614
after_gates=group.get("afterGates", []),
608615
))
@@ -612,6 +619,7 @@ def get_update_run_strategy(cmd, operation_group, stages):
612619
update_stages.append(update_stage_model(
613620
name=stage["name"],
614621
groups=update_groups,
622+
max_concurrency=stage.get("maxConcurrency"),
615623
before_gates=stage.get("beforeGates", []),
616624
after_gates=stage.get("afterGates", []),
617625
after_stage_wait_in_seconds=after_wait
@@ -863,6 +871,12 @@ def create_managed_namespace(cmd,
863871
operation_group="fleet_managed_namespaces"
864872
)
865873

874+
fleet_managed_namespace_properties_model = cmd.get_models(
875+
"FleetManagedNamespaceProperties",
876+
resource_type=CUSTOM_MGMT_FLEET,
877+
operation_group="fleet_managed_namespaces"
878+
)
879+
866880
resource_quota_model = cmd.get_models(
867881
"ResourceQuota",
868882
resource_type=CUSTOM_MGMT_FLEET,
@@ -926,15 +940,19 @@ def create_managed_namespace(cmd,
926940
else:
927941
logger.warning("--member-cluster-names was empty; namespace will not be placed on any member clusters")
928942

929-
managed_namespace = managed_namespace_model(
930-
location=fleet.location,
931-
tags=tags,
943+
fleet_managed_namespace_props = fleet_managed_namespace_properties_model(
932944
managed_namespace_properties=managed_namespace_props,
933945
adoption_policy=adoption_policy,
934946
delete_policy=delete_policy,
935947
propagation_policy=propagation_policy
936948
)
937949

950+
managed_namespace = managed_namespace_model(
951+
location=fleet.location,
952+
tags=tags,
953+
properties=fleet_managed_namespace_props
954+
)
955+
938956
return sdk_no_wait(
939957
no_wait,
940958
client.begin_create_or_update,

src/fleet/azext_fleet/tests/latest/data/stages.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"stages": [
33
{
44
"name": "stage1",
5+
"maxConcurrency": "7",
56
"beforeGates": [
67
{
78
"displayName": "stage before gate",
@@ -17,6 +18,7 @@
1718
"groups": [
1819
{
1920
"name": "group1",
21+
"maxConcurrency": "100%",
2022
"beforeGates": [
2123
{
2224
"displayName": "group before gate",
@@ -32,6 +34,7 @@
3234
},
3335
{
3436
"name": "group2",
37+
"maxConcurrency": "50%",
3538
"beforeGates": [
3639
{
3740
"displayName": "group before gate",

0 commit comments

Comments
 (0)