Skip to content

Commit 52e0427

Browse files
committed
Add AI Toolchain Operator (Kaito) to AKS CLI
Signed-off-by: Heba <31887807+helayoty@users.noreply.github.com>
1 parent 5c3cf2f commit 52e0427

File tree

9 files changed

+1000
-0
lines changed

9 files changed

+1000
-0
lines changed

linter_exclusions.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ aks create:
285285
azure_keyvault_kms_key_vault_network_access:
286286
rule_exclusions:
287287
- option_length_too_long
288+
enable_ai_toolchain_operator:
289+
rule_exclusions:
290+
- option_length_too_long
288291
azure_keyvault_kms_key_vault_resource_id:
289292
rule_exclusions:
290293
- option_length_too_long
@@ -362,6 +365,12 @@ aks update:
362365
azure_keyvault_kms_key_vault_network_access:
363366
rule_exclusions:
364367
- option_length_too_long
368+
enable_ai_toolchain_operator:
369+
rule_exclusions:
370+
- option_length_too_long
371+
disable_ai_toolchain_operator:
372+
rule_exclusions:
373+
- option_length_too_long
365374
azure_keyvault_kms_key_vault_resource_id:
366375
rule_exclusions:
367376
- option_length_too_long

src/azure-cli/azure/cli/command_modules/acs/_help.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,9 @@
590590
short-summary: Configure artifact source when bootstraping the cluster.
591591
long-summary: |
592592
The artifacts include the addon image. Use "Direct" to download artifacts from MCR, "Cache" to downalod artifacts from Azure Container Registry.
593+
- name: --enable-ai-toolchain-operator
594+
type: bool
595+
short-summary: Enable AI toolchain operator to the cluster.
593596
- name: --bootstrap-container-registry-resource-id
594597
type: string
595598
short-summary: Configure container registry resource ID. Must use "Cache" as bootstrap artifact source.
@@ -1048,6 +1051,12 @@
10481051
short-summary: Configure artifact source when bootstraping the cluster.
10491052
long-summary: |
10501053
The artifacts include the addon image. Use "Direct" to download artifacts from MCR, "Cache" to downalod artifacts from Azure Container Registry.
1054+
- name: --enable-ai-toolchain-operator
1055+
type: bool
1056+
short-summary: Enable AI toolchain operator to the cluster
1057+
- name: --disable-ai-toolchain-operator
1058+
type: bool
1059+
short-summary: Disable AI toolchain operator.
10511060
- name: --bootstrap-container-registry-resource-id
10521061
type: string
10531062
short-summary: Configure container registry resource ID. Must use "Cache" as bootstrap artifact source.

src/azure-cli/azure/cli/command_modules/acs/_params.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ def load_arguments(self, _):
434434
c.argument('rotation_poll_interval')
435435
c.argument('enable_sgxquotehelper', action='store_true')
436436
c.argument('enable_app_routing', action="store_true")
437+
c.argument('enable_ai_toolchain_operator', is_preview=True, action='store_true')
437438
c.argument(
438439
"app_routing_default_nginx_controller",
439440
arg_type=get_enum_type(app_routing_nginx_configs),
@@ -633,6 +634,8 @@ def load_arguments(self, _):
633634
# addons
634635
c.argument('enable_secret_rotation', action='store_true')
635636
c.argument('disable_secret_rotation', action='store_true', validator=validate_keyvault_secrets_provider_disable_and_enable_parameters)
637+
c.argument('enable_ai_toolchain_operator', is_preview=True, action='store_true')
638+
c.argument('disable_ai_toolchain_operator', is_preview=True, action='store_true')
636639
c.argument('rotation_poll_interval')
637640
c.argument('enable_static_egress_gateway', action='store_true')
638641
c.argument('disable_static_egress_gateway', action='store_true')

src/azure-cli/azure/cli/command_modules/acs/custom.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ def aks_create(
602602
enable_secret_rotation=False,
603603
rotation_poll_interval=None,
604604
enable_app_routing=False,
605+
enable_ai_toolchain_operator=False,
605606
app_routing_default_nginx_controller=None,
606607
enable_static_egress_gateway=False,
607608
# nodepool paramerters
@@ -803,6 +804,8 @@ def aks_update(
803804
# addons
804805
enable_secret_rotation=False,
805806
disable_secret_rotation=False,
807+
enable_ai_toolchain_operator=False,
808+
disable_ai_toolchain_operator=False,
806809
rotation_poll_interval=None,
807810
enable_static_egress_gateway=False,
808811
disable_static_egress_gateway=False,

src/azure-cli/azure/cli/command_modules/acs/managed_cluster_decorator.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5412,6 +5412,32 @@ def get_upgrade_override_until(self) -> Union[str, None]:
54125412
# this parameter does not need validation
54135413
return self.raw_param.get("upgrade_override_until")
54145414

5415+
def get_ai_toolchain_operator(self, enable_validation: bool = False) -> bool:
5416+
"""Internal function to obtain the value of enable_ai_toolchain_operator.
5417+
When enabled, if both enable_ai_toolchain_operator and
5418+
disable_ai_toolchain_operator are specified, raise
5419+
a MutuallyExclusiveArgumentError.
5420+
:return: bool
5421+
"""
5422+
enable_ai_toolchain_operator = self.raw_param.get("enable_ai_toolchain_operator")
5423+
# This parameter does not need dynamic completion.
5424+
if enable_validation:
5425+
if enable_ai_toolchain_operator and self.get_disable_ai_toolchain_operator():
5426+
raise MutuallyExclusiveArgumentError(
5427+
"Cannot specify --enable-ai-toolchain-operator and "
5428+
"--disable-ai-toolchain-operator at the same time. "
5429+
)
5430+
5431+
return enable_ai_toolchain_operator
5432+
5433+
def get_disable_ai_toolchain_operator(self) -> bool:
5434+
"""Obtain the value of disable_ai_toolchain_operator.
5435+
:return: bool
5436+
"""
5437+
# Note: No need to check for mutually exclusive parameter with enable-ai-toolchain-operator here
5438+
# because it's already checked in get_ai_toolchain_operator
5439+
return self.raw_param.get("disable_ai_toolchain_operator")
5440+
54155441
def _get_enable_cost_analysis(self, enable_validation: bool = False) -> bool:
54165442
"""Internal function to obtain the value of enable_cost_analysis.
54175443
When enabled, if both enable_cost_analysis and disable_cost_analysis are
@@ -6764,6 +6790,18 @@ def set_up_ingress_web_app_routing(self, mc: ManagedCluster) -> ManagedCluster:
67646790

67656791
return mc
67666792

6793+
def set_up_ai_toolchain_operator(self, mc: ManagedCluster) -> ManagedCluster:
6794+
self._ensure_mc(mc)
6795+
6796+
if self.context.get_ai_toolchain_operator(enable_validation=True):
6797+
if mc.ai_toolchain_operator_profile is None:
6798+
mc.ai_toolchain_operator_profile = self.models.ManagedClusterAIToolchainOperatorProfile() # pylint: disable=no-member
6799+
# set enabled
6800+
mc.ai_toolchain_operator_profile.enabled = True
6801+
6802+
# Default is disabled so no need to worry about that here
6803+
return mc
6804+
67676805
def set_up_cost_analysis(self, mc: ManagedCluster) -> ManagedCluster:
67686806
self._ensure_mc(mc)
67696807

@@ -6919,6 +6957,8 @@ def construct_mc_profile_default(self, bypass_restore_defaults: bool = False) ->
69196957
mc = self.set_up_metrics_profile(mc)
69206958
# set up node resource group profile
69216959
mc = self.set_up_node_resource_group_profile(mc)
6960+
# set up AI toolchain operator
6961+
mc = self.set_up_ai_toolchain_operator(mc)
69226962
# set up bootstrap profile
69236963
mc = self.set_up_bootstrap_profile(mc)
69246964
# set up static egress gateway profile
@@ -8701,6 +8741,23 @@ def update_azure_container_storage(self, mc: ManagedCluster) -> ManagedCluster:
87018741

87028742
return mc
87038743

8744+
def update_ai_toolchain_operator(self, mc: ManagedCluster) -> ManagedCluster:
8745+
"""Updates the aiToolchainOperatorProfile field of the managed cluster
8746+
:return: the ManagedCluster object
8747+
"""
8748+
8749+
if self.context.get_ai_toolchain_operator(enable_validation=True):
8750+
if mc.ai_toolchain_operator_profile is None:
8751+
mc.ai_toolchain_operator_profile = self.models.ManagedClusterAIToolchainOperatorProfile() # pylint: disable=no-member
8752+
mc.ai_toolchain_operator_profile.enabled = True
8753+
8754+
if self.context.get_disable_ai_toolchain_operator():
8755+
if mc.ai_toolchain_operator_profile is None:
8756+
mc.ai_toolchain_operator_profile = self.models.ManagedClusterAIToolchainOperatorProfile() # pylint: disable=no-member
8757+
mc.ai_toolchain_operator_profile.enabled = False
8758+
8759+
return mc
8760+
87048761
def update_cost_analysis(self, mc: ManagedCluster) -> ManagedCluster:
87058762
self._ensure_mc(mc)
87068763

@@ -8862,6 +8919,8 @@ def update_mc_profile_default(self) -> ManagedCluster:
88628919
mc = self.update_metrics_profile(mc)
88638920
# update node resource group profile
88648921
mc = self.update_node_resource_group_profile(mc)
8922+
# update AI toolchain operator
8923+
mc = self.update_ai_toolchain_operator(mc)
88658924
# update bootstrap profile
88668925
mc = self.update_bootstrap_profile(mc)
88678926
# update static egress gateway
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
interactions:
2+
- request:
3+
body: null
4+
headers:
5+
Accept:
6+
- application/json
7+
Accept-Encoding:
8+
- gzip, deflate
9+
CommandName:
10+
- aks create
11+
Connection:
12+
- keep-alive
13+
ParameterSetName:
14+
- --resource-group --name --location --ssh-key-value --node-count --enable-managed-identity
15+
--enable-oidc-issuer --enable-ai-toolchain-operator --aks-custom-headers
16+
User-Agent:
17+
- AZURECLI/2.73.0 azsdk-python-core/1.31.0 Python/3.12.1 (Linux-6.8.0-1027-azure-x86_64-with-glibc2.31)
18+
method: GET
19+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000001?api-version=2025-02-01
20+
response:
21+
body:
22+
string: '{"error":{"code":"ResourceNotFound","message":"The Resource ''Microsoft.ContainerService/managedClusters/cliakstest000001''
23+
under resource group ''clitest000001'' was not found. For more details please
24+
go to https://aka.ms/ARMResourceNotFoundFix"}}'
25+
headers:
26+
cache-control:
27+
- no-cache
28+
content-length:
29+
- '244'
30+
content-type:
31+
- application/json; charset=utf-8
32+
date:
33+
- Fri, 16 May 2025 03:04:39 GMT
34+
expires:
35+
- '-1'
36+
pragma:
37+
- no-cache
38+
strict-transport-security:
39+
- max-age=31536000; includeSubDomains
40+
x-cache:
41+
- CONFIG_NOCACHE
42+
x-content-type-options:
43+
- nosniff
44+
x-ms-failure-cause:
45+
- gateway
46+
x-msedge-ref:
47+
- 'Ref A: CD7E65FD6D224333A54AF87AA670C89E Ref B: SJC211051204039 Ref C: 2025-05-16T03:04:39Z'
48+
status:
49+
code: 404
50+
message: Not Found
51+
version: 1

0 commit comments

Comments
 (0)