Skip to content

Commit 4f8e6ff

Browse files
committed
[AKS] az aks create/update: Add command to create/update a network isolated cluster
1 parent 51b8804 commit 4f8e6ff

File tree

10 files changed

+8829
-12
lines changed

10 files changed

+8829
-12
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING = "userDefinedRouting"
6868
CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY = "managedNATGateway"
6969
CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY = "userAssignedNATGateway"
70+
CONST_OUTBOUND_TYPE_NONE = "none"
7071

7172
# load balancer backend pool type
7273
CONST_LOAD_BALANCER_BACKEND_POOL_TYPE_NODE_IP = "nodeIP"
@@ -206,6 +207,10 @@
206207
CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE = "Private DNS Zone Contributor"
207208
CONST_DNS_ZONE_CONTRIBUTOR_ROLE = "DNS Zone Contributor"
208209

210+
# consts for network isolated cluster
211+
CONST_ARTIFACT_SOURCE_DIRECT = "Direct"
212+
CONST_ARTIFACT_SOURCE_CACHE = "Cache"
213+
209214

210215
# consts for decorator pattern
211216
class DecoratorMode(Enum):

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
- name: --outbound-type
183183
type: string
184184
short-summary: How outbound traffic will be configured for a cluster.
185-
long-summary: Select between loadBalancer, userDefinedRouting, managedNATGateway and userAssignedNATGateway. If not set, defaults to type loadBalancer. Requires --vnet-subnet-id to be provided with a preconfigured route table and --load-balancer-sku to be Standard.
185+
long-summary: Select between loadBalancer, userDefinedRouting, managedNATGateway, userAssignedNATGateway and none. If not set, defaults to type loadBalancer. Requires --vnet-subnet-id to be provided with a preconfigured route table and --load-balancer-sku to be Standard.
186186
- name: --auto-upgrade-channel
187187
type: string
188188
short-summary: Specify the upgrade channel for autoupgrade.
@@ -563,6 +563,14 @@
563563
- name: --if-none-match
564564
type: string
565565
short-summary: Set to '*' to allow a new cluster to be created, but to prevent updating an existing cluster. Other values will be ignored.
566+
- name: --bootstrap-artifact-source
567+
type: string
568+
short-summary: Configure artifact source when bootstraping the cluster.
569+
long-summary: |
570+
The artifacts include the addon image. Use "Direct" to download artifacts from MCR, "Cache" to downalod artifacts from Azure Container Registry.
571+
- name: --bootstrap-container-registry-resource-id
572+
type: string
573+
short-summary: Configure container registry resource ID. Must use "Cache" as bootstrap artifact source.
566574
567575
examples:
568576
- name: Create a Kubernetes cluster with an existing SSH public key.
@@ -732,7 +740,7 @@
732740
- name: --outbound-type
733741
type: string
734742
short-summary: How outbound traffic will be configured for a cluster.
735-
long-summary: This option will change the way how the outbound connections are managed in the AKS cluster. Available options are loadbalancer, managedNATGateway, userAssignedNATGateway, userDefinedRouting. For custom vnet, loadbalancer, userAssignedNATGateway and userDefinedRouting are supported. For aks managed vnet, loadbalancer, managedNATGateway and userDefinedRouting are supported.
743+
long-summary: This option will change the way how the outbound connections are managed in the AKS cluster. Available options are loadbalancer, managedNATGateway, userAssignedNATGateway, userDefinedRouting and none. For custom vnet, loadbalancer, userAssignedNATGateway and userDefinedRouting are supported. For aks managed vnet, loadbalancer, managedNATGateway and userDefinedRouting are supported.
736744
- name: --auto-upgrade-channel
737745
type: string
738746
short-summary: Specify the upgrade channel for autoupgrade.
@@ -991,6 +999,14 @@
991999
- name: --if-none-match
9921000
type: string
9931001
short-summary: Set to '*' to allow a new cluster to be created, but to prevent updating an existing cluster. Other values will be ignored.
1002+
- name: --bootstrap-artifact-source
1003+
type: string
1004+
short-summary: Configure artifact source when bootstraping the cluster.
1005+
long-summary: |
1006+
The artifacts include the addon image. Use "Direct" to download artifacts from MCR, "Cache" to downalod artifacts from Azure Container Registry.
1007+
- name: --bootstrap-container-registry-resource-id
1008+
type: string
1009+
short-summary: Configure container registry resource ID. Must use "Cache" as bootstrap artifact source.
9941010
examples:
9951011
- name: Reconcile the cluster back to its current state.
9961012
text: az aks update -g MyResourceGroup -n MyManagedCluster

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
CONST_OS_SKU_WINDOWS2019, CONST_OS_SKU_WINDOWS2022,
3434
CONST_OUTBOUND_TYPE_LOAD_BALANCER, CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY,
3535
CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY,
36-
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING, CONST_PATCH_UPGRADE_CHANNEL,
37-
CONST_RAPID_UPGRADE_CHANNEL, CONST_SCALE_DOWN_MODE_DEALLOCATE,
36+
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING, CONST_OUTBOUND_TYPE_NONE,
37+
CONST_PATCH_UPGRADE_CHANNEL, CONST_RAPID_UPGRADE_CHANNEL, CONST_SCALE_DOWN_MODE_DEALLOCATE,
3838
CONST_SCALE_DOWN_MODE_DELETE, CONST_SCALE_SET_PRIORITY_REGULAR,
3939
CONST_SCALE_SET_PRIORITY_SPOT, CONST_SPOT_EVICTION_POLICY_DEALLOCATE,
4040
CONST_SPOT_EVICTION_POLICY_DELETE, CONST_STABLE_UPGRADE_CHANNEL,
@@ -48,7 +48,9 @@
4848
CONST_AZURE_SERVICE_MESH_INGRESS_MODE_EXTERNAL,
4949
CONST_AZURE_SERVICE_MESH_INGRESS_MODE_INTERNAL,
5050
CONST_NRG_LOCKDOWN_RESTRICTION_LEVEL_READONLY,
51-
CONST_NRG_LOCKDOWN_RESTRICTION_LEVEL_UNRESTRICTED)
51+
CONST_NRG_LOCKDOWN_RESTRICTION_LEVEL_UNRESTRICTED,
52+
CONST_ARTIFACT_SOURCE_DIRECT,
53+
CONST_ARTIFACT_SOURCE_CACHE)
5254
from azure.cli.command_modules.acs.azurecontainerstorage._consts import (
5355
CONST_ACSTOR_ALL,
5456
CONST_DISK_TYPE_EPHEMERAL_VOLUME_ONLY,
@@ -100,7 +102,8 @@
100102
validate_disable_windows_outbound_nat,
101103
validate_crg_id,
102104
validate_azure_service_mesh_revision,
103-
validate_message_of_the_day)
105+
validate_message_of_the_day,
106+
validate_bootstrap_container_registry_resource_id)
104107
from azure.cli.core.commands.parameters import (
105108
edge_zone_type, file_type, get_enum_type,
106109
get_resource_name_completion_list, get_three_state_flag, name_type,
@@ -161,7 +164,7 @@
161164
network_plugin_modes = [CONST_NETWORK_PLUGIN_MODE_OVERLAY]
162165
network_dataplanes = [CONST_NETWORK_DATAPLANE_AZURE, CONST_NETWORK_DATAPLANE_CILIUM]
163166
network_policies = [CONST_NETWORK_POLICY_AZURE, CONST_NETWORK_POLICY_CALICO, CONST_NETWORK_POLICY_CILIUM, CONST_NETWORK_POLICY_NONE]
164-
outbound_types = [CONST_OUTBOUND_TYPE_LOAD_BALANCER, CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING, CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY, CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY]
167+
outbound_types = [CONST_OUTBOUND_TYPE_LOAD_BALANCER, CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING, CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY, CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY, CONST_OUTBOUND_TYPE_NONE]
165168
auto_upgrade_channels = [
166169
CONST_RAPID_UPGRADE_CHANNEL,
167170
CONST_STABLE_UPGRADE_CHANNEL,
@@ -267,6 +270,11 @@
267270
CONST_EPHEMERAL_NVME_PERF_TIER_STANDARD,
268271
]
269272

273+
bootstrap_artifact_source_types = [
274+
CONST_ARTIFACT_SOURCE_DIRECT,
275+
CONST_ARTIFACT_SOURCE_CACHE,
276+
]
277+
270278

271279
def load_arguments(self, _):
272280

@@ -372,6 +380,15 @@ def load_arguments(self, _):
372380
options_list=["--enable-azure-service-mesh", "--enable-asm"],
373381
action='store_true')
374382
c.argument("revision", validator=validate_azure_service_mesh_revision)
383+
c.argument(
384+
"bootstrap_artifact_source",
385+
arg_type=get_enum_type(bootstrap_artifact_source_types),
386+
default=CONST_ARTIFACT_SOURCE_DIRECT,
387+
)
388+
c.argument(
389+
"bootstrap_container_registry_resource_id",
390+
validator=validate_bootstrap_container_registry_resource_id,
391+
)
375392
# addons
376393
c.argument('enable_addons', options_list=['--enable-addons', '-a'])
377394
c.argument('workspace_resource_id')
@@ -563,6 +580,14 @@ def load_arguments(self, _):
563580
c.argument('enable_force_upgrade', action='store_true')
564581
c.argument('disable_force_upgrade', action='store_true', validator=validate_force_upgrade_disable_and_enable_parameters)
565582
c.argument('upgrade_override_until')
583+
c.argument(
584+
"bootstrap_artifact_source",
585+
arg_type=get_enum_type(bootstrap_artifact_source_types),
586+
)
587+
c.argument(
588+
"bootstrap_container_registry_resource_id",
589+
validator=validate_bootstrap_container_registry_resource_id,
590+
)
566591
# addons
567592
c.argument('enable_secret_rotation', action='store_true')
568593
c.argument('disable_secret_rotation', action='store_true', validator=validate_keyvault_secrets_provider_disable_and_enable_parameters)

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,3 +835,12 @@ def validate_message_of_the_day(namespace):
835835
if namespace.os_type is not None and namespace.os_type != "Linux":
836836
raise ArgumentUsageError(
837837
'--message-of-the-day can only be set for linux nodepools')
838+
839+
840+
def validate_bootstrap_container_registry_resource_id(namespace):
841+
container_registry_resource_id = namespace.bootstrap_container_registry_resource_id
842+
if container_registry_resource_id is None or container_registry_resource_id == '':
843+
return
844+
from msrestazure.tools import is_valid_resource_id
845+
if not is_valid_resource_id(container_registry_resource_id):
846+
raise InvalidArgumentValueError("--bootstrap-container-registry-resource-id is not a valid Azure resource ID.")

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_ROLLBACK,
7070
CONST_AZURE_SERVICE_MESH_MODE_ISTIO,
7171
CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM,
72+
CONST_ARTIFACT_SOURCE_DIRECT,
7273
)
7374
from azure.cli.command_modules.acs._polling import RunCommandLocationPolling
7475
from azure.cli.command_modules.acs._helpers import get_snapshot_by_snapshot_id, check_is_private_link_cluster
@@ -578,6 +579,9 @@ def aks_create(
578579
enable_acns=None,
579580
disable_acns_observability=None,
580581
disable_acns_security=None,
582+
# network isoalted cluster
583+
bootstrap_artifact_source=CONST_ARTIFACT_SOURCE_DIRECT,
584+
bootstrap_container_registry_resource_id=None,
581585
# addons
582586
enable_addons=None,
583587
workspace_resource_id=None,
@@ -782,6 +786,9 @@ def aks_update(
782786
enable_acns=None,
783787
disable_acns_observability=None,
784788
disable_acns_security=None,
789+
# network isoalted cluster
790+
bootstrap_artifact_source=None,
791+
bootstrap_container_registry_resource_id=None,
785792
# addons
786793
enable_secret_rotation=False,
787794
disable_secret_rotation=False,

src/azure-cli/azure/cli/command_modules/acs/linter_exclusions.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ aks create:
7676
nrg_lockdown_restriction_level:
7777
rule_exclusions:
7878
- option_length_too_long
79+
bootstrap_artifact_source:
80+
rule_exclusions:
81+
- option_length_too_long
82+
bootstrap_container_registry_resource_id:
83+
rule_exclusions:
84+
- option_length_too_long
7985

8086
aks enable-addons:
8187
parameters:
@@ -174,6 +180,12 @@ aks update:
174180
nrg_lockdown_restriction_level:
175181
rule_exclusions:
176182
- option_length_too_long
183+
bootstrap_artifact_source:
184+
rule_exclusions:
185+
- option_length_too_long
186+
bootstrap_container_registry_resource_id:
187+
rule_exclusions:
188+
- option_length_too_long
177189
aks nodepool add:
178190
parameters:
179191
disable_windows_outbound_nat:

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

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY,
2626
CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY,
2727
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING,
28+
CONST_OUTBOUND_TYPE_NONE,
2829
CONST_PRIVATE_DNS_ZONE_NONE,
2930
CONST_PRIVATE_DNS_ZONE_SYSTEM,
3031
CONST_AZURE_KEYVAULT_NETWORK_ACCESS_PRIVATE,
@@ -39,6 +40,7 @@
3940
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_ROLLBACK,
4041
CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE,
4142
CONST_DNS_ZONE_CONTRIBUTOR_ROLE,
43+
CONST_ARTIFACT_SOURCE_CACHE,
4244
)
4345
from azure.cli.command_modules.acs._helpers import (
4446
check_is_managed_aad_cluster,
@@ -2147,8 +2149,8 @@ def _get_outbound_type(
21472149
CONST_OUTBOUND_TYPE_LOAD_BALANCER.
21482150
21492151
This function supports the option of enable_validation. When enabled, if the value of outbound_type is
2150-
CONST_OUTBOUND_TYPE_LOAD_BALANCER,CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY, CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY or
2151-
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING, the following checks will be performed. If load_balancer_sku is set
2152+
CONST_OUTBOUND_TYPE_LOAD_BALANCER, CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY, CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY
2153+
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING or CONST_OUTBOUND_TYPE_NONE, the following checks will be performed. If load_balancer_sku is set
21522154
to basic, an InvalidArgumentValueError will be raised. If vnet_subnet_id is not assigned,
21532155
a RequiredArgumentMissingError will be raised. If any of load_balancer_managed_outbound_ip_count,
21542156
This function supports the option of read_only. When enabled, it will skip dynamic completion and validation.
@@ -2185,11 +2187,11 @@ def _get_outbound_type(
21852187
CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY,
21862188
CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY,
21872189
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING,
2188-
"none"
2190+
CONST_OUTBOUND_TYPE_NONE,
21892191
]:
21902192
raise InvalidArgumentValueError(
2191-
"Invalid outbound type, supported values are loadBalancer, managedNATGateway, userAssignedNATGateway and "
2192-
"userDefinedRouting. Please refer to "
2193+
"Invalid outbound type, supported values are loadBalancer, managedNATGateway, userAssignedNATGateway, "
2194+
"userDefinedRouting and none. Please refer to "
21932195
"https://learn.microsoft.com/en-us/azure/aks/egress-outboundtype#updating-outboundtype-after-cluster-creation " # pylint:disable=line-too-long
21942196
"for more details."
21952197
)
@@ -5248,6 +5250,16 @@ def get_if_none_match(self) -> Union[str, None]:
52485250
# this parameter does not need validation
52495251
return self.raw_param.get("if_none_match")
52505252

5253+
def get_bootstrap_artifact_source(self) -> Union[str, None]:
5254+
"""Obtain the value of bootstrap_artifact_source.
5255+
"""
5256+
return self.raw_param.get("bootstrap_artifact_source")
5257+
5258+
def get_bootstrap_container_registry_resource_id(self) -> Union[str, None]:
5259+
"""Obtain the value of bootstrap_container_registry_resource_id.
5260+
"""
5261+
return self.raw_param.get("bootstrap_container_registry_resource_id")
5262+
52515263

52525264
class AKSManagedClusterCreateDecorator(BaseAKSManagedClusterDecorator):
52535265
def __init__(
@@ -6510,6 +6522,24 @@ def set_up_node_resource_group_profile(self, mc: ManagedCluster) -> ManagedClust
65106522
mc.node_resource_group_profile = node_resource_group_profile
65116523
return mc
65126524

6525+
def set_up_bootstrap_profile(self, mc: ManagedCluster) -> ManagedCluster:
6526+
self._ensure_mc(mc)
6527+
6528+
bootstrap_artifact_source = self.context.get_bootstrap_artifact_source()
6529+
bootstrap_container_registry_resource_id = self.context.get_bootstrap_container_registry_resource_id()
6530+
if hasattr(mc, "bootstrap_profile") and bootstrap_artifact_source is not None:
6531+
if bootstrap_artifact_source != CONST_ARTIFACT_SOURCE_CACHE and bootstrap_container_registry_resource_id:
6532+
raise MutuallyExclusiveArgumentError(
6533+
"Cannot specify --bootstrap-container-registry-resource-id when "
6534+
"--bootstrap-artifact-source is not Cache."
6535+
)
6536+
if mc.bootstrap_profile is None:
6537+
mc.bootstrap_profile = self.models.ManagedClusterBootstrapProfile() # pylint: disable=no-member
6538+
mc.bootstrap_profile.artifact_source = bootstrap_artifact_source
6539+
mc.bootstrap_profile.container_registry_id = bootstrap_container_registry_resource_id
6540+
6541+
return mc
6542+
65136543
def construct_mc_profile_default(self, bypass_restore_defaults: bool = False) -> ManagedCluster:
65146544
"""The overall controller used to construct the default ManagedCluster profile.
65156545
@@ -6590,6 +6620,8 @@ def construct_mc_profile_default(self, bypass_restore_defaults: bool = False) ->
65906620
mc = self.set_up_metrics_profile(mc)
65916621
# set up node resource group profile
65926622
mc = self.set_up_node_resource_group_profile(mc)
6623+
# set up bootstrap profile
6624+
mc = self.set_up_bootstrap_profile(mc)
65936625

65946626
# DO NOT MOVE: keep this at the bottom, restore defaults
65956627
if not bypass_restore_defaults:
@@ -8351,6 +8383,24 @@ def update_metrics_profile(self, mc: ManagedCluster) -> ManagedCluster:
83518383

83528384
return mc
83538385

8386+
def update_bootstrap_profile(self, mc: ManagedCluster) -> ManagedCluster:
8387+
self._ensure_mc(mc)
8388+
8389+
bootstrap_artifact_source = self.context.get_bootstrap_artifact_source()
8390+
bootstrap_container_registry_resource_id = self.context.get_bootstrap_container_registry_resource_id()
8391+
if hasattr(mc, "bootstrap_profile") and bootstrap_artifact_source is not None:
8392+
if bootstrap_artifact_source != CONST_ARTIFACT_SOURCE_CACHE and bootstrap_container_registry_resource_id:
8393+
raise MutuallyExclusiveArgumentError(
8394+
"Cannot specify --bootstrap-container-registry-resource-id when "
8395+
"--bootstrap-artifact-source is not Cache."
8396+
)
8397+
if mc.bootstrap_profile is None:
8398+
mc.bootstrap_profile = self.models.ManagedClusterBootstrapProfile() # pylint: disable=no-member
8399+
mc.bootstrap_profile.artifact_source = bootstrap_artifact_source
8400+
mc.bootstrap_profile.container_registry_id = bootstrap_container_registry_resource_id
8401+
8402+
return mc
8403+
83548404
def update_mc_profile_default(self) -> ManagedCluster:
83558405
"""The overall controller used to update the default ManagedCluster profile.
83568406
@@ -8430,6 +8480,8 @@ def update_mc_profile_default(self) -> ManagedCluster:
84308480
mc = self.update_metrics_profile(mc)
84318481
# update node resource group profile
84328482
mc = self.update_node_resource_group_profile(mc)
8483+
# update bootstrap profile
8484+
mc = self.update_bootstrap_profile(mc)
84338485
return mc
84348486

84358487
def check_is_postprocessing_required(self, mc: ManagedCluster) -> bool:

0 commit comments

Comments
 (0)