Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/azure-cli/azure/cli/command_modules/acs/_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# mode
CONST_NODEPOOL_MODE_SYSTEM = "System"
CONST_NODEPOOL_MODE_USER = "User"
CONST_NODEPOOL_MODE_GATEWAY = "Gateway"

# os type
CONST_DEFAULT_NODE_OS_TYPE = "Linux"
Expand Down
14 changes: 12 additions & 2 deletions src/azure-cli/azure/cli/command_modules/acs/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,9 @@
- name: --bootstrap-container-registry-resource-id
type: string
short-summary: Configure container registry resource ID. Must use "Cache" as bootstrap artifact source.

- name: --enable-static-egress-gateway
type: bool
short-summary: Enable Static Egress Gateway addon to the cluster.
examples:
- name: Create a Kubernetes cluster with an existing SSH public key.
text: az aks create -g MyResourceGroup -n MyManagedCluster --ssh-key-value /path/to/publickey
Expand Down Expand Up @@ -1036,6 +1038,12 @@
- name: --bootstrap-container-registry-resource-id
type: string
short-summary: Configure container registry resource ID. Must use "Cache" as bootstrap artifact source.
- name: --enable-static-egress-gateway
type: bool
short-summary: Enable Static Egress Gateway addon to the cluster.
- name: --disable-static-egress-gateway
type: bool
short-summary: Disable Static Egress Gateway addon to the cluster.
examples:
- name: Reconcile the cluster back to its current state.
text: az aks update -g MyResourceGroup -n MyManagedCluster
Expand Down Expand Up @@ -1701,7 +1709,9 @@
- name: --gpu-driver
type: string
short-summary: Whether to install driver for GPU node pool. Possible values are "Install" or "None". Default is "Install".

- name: --gateway-prefix-size
type: int
short-summary: The size of Public IPPrefix attached to the Gateway-mode node pool. The node pool must be in Gateway mode.
examples:
- name: Create a nodepool in an existing AKS cluster with ephemeral os enabled.
text: az aks nodepool add -g MyResourceGroup -n nodepool1 --cluster-name MyManagedCluster --node-osdisk-type Ephemeral --node-osdisk-size 48
Expand Down
13 changes: 10 additions & 3 deletions src/azure-cli/azure/cli/command_modules/acs/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
CONST_NODE_OS_CHANNEL_NONE,
CONST_NODE_OS_CHANNEL_UNMANAGED,
CONST_NODE_OS_CHANNEL_SECURITY_PATCH,
CONST_NODEPOOL_MODE_SYSTEM, CONST_NODEPOOL_MODE_USER,
CONST_NODEPOOL_MODE_SYSTEM, CONST_NODEPOOL_MODE_USER, CONST_NODEPOOL_MODE_GATEWAY,
CONST_OS_DISK_TYPE_EPHEMERAL, CONST_OS_DISK_TYPE_MANAGED,
CONST_OS_SKU_AZURELINUX, CONST_OS_SKU_CBLMARINER, CONST_OS_SKU_MARINER,
CONST_OS_SKU_UBUNTU, CONST_OS_SKU_UBUNTU2204,
Expand Down Expand Up @@ -110,7 +110,9 @@
validate_azure_service_mesh_revision,
validate_message_of_the_day,
validate_custom_ca_trust_certificates,
validate_bootstrap_container_registry_resource_id)
validate_bootstrap_container_registry_resource_id,
validate_gateway_prefix_size,
)
from azure.cli.core.commands.parameters import (
edge_zone_type, file_type, get_enum_type,
get_resource_name_completion_list, get_three_state_flag, name_type,
Expand Down Expand Up @@ -158,7 +160,7 @@
node_priorities = [CONST_SCALE_SET_PRIORITY_REGULAR, CONST_SCALE_SET_PRIORITY_SPOT]
node_eviction_policies = [CONST_SPOT_EVICTION_POLICY_DELETE, CONST_SPOT_EVICTION_POLICY_DEALLOCATE]
node_os_disk_types = [CONST_OS_DISK_TYPE_MANAGED, CONST_OS_DISK_TYPE_EPHEMERAL]
node_mode_types = [CONST_NODEPOOL_MODE_SYSTEM, CONST_NODEPOOL_MODE_USER]
node_mode_types = [CONST_NODEPOOL_MODE_SYSTEM, CONST_NODEPOOL_MODE_USER, CONST_NODEPOOL_MODE_GATEWAY]
node_os_skus_create = [CONST_OS_SKU_AZURELINUX, CONST_OS_SKU_UBUNTU, CONST_OS_SKU_CBLMARINER, CONST_OS_SKU_MARINER, CONST_OS_SKU_UBUNTU2204]
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_UBUNTU, CONST_OS_SKU_UBUNTU2204]
Expand Down Expand Up @@ -434,6 +436,7 @@ def load_arguments(self, _):
arg_type=get_enum_type(app_routing_nginx_configs),
options_list=["--app-routing-default-nginx-controller", "--ardnc"]
)
c.argument("enable_static_egress_gateway", action="store_true")

# nodepool paramerters
c.argument('nodepool_name', default='nodepool1',
Expand Down Expand Up @@ -624,6 +627,9 @@ def load_arguments(self, _):
c.argument('enable_secret_rotation', action='store_true')
c.argument('disable_secret_rotation', action='store_true', validator=validate_keyvault_secrets_provider_disable_and_enable_parameters)
c.argument('rotation_poll_interval')
c.argument('enable_static_egress_gateway', action='store_true')
c.argument('disable_static_egress_gateway', action='store_true')

# nodepool paramerters
c.argument('enable_cluster_autoscaler', options_list=[
"--enable-cluster-autoscaler", "-e"], action='store_true')
Expand Down Expand Up @@ -859,6 +865,7 @@ def load_arguments(self, _):
c.argument("if_match")
c.argument("if_none_match")
c.argument('gpu_driver', arg_type=get_enum_type(gpu_driver_install_modes))
c.argument("gateway_prefix_size", type=int, validator=validate_gateway_prefix_size)

with self.argument_context('aks nodepool update', resource_type=ResourceType.MGMT_CONTAINERSERVICE, operation_group='agent_pools') as c:
c.argument('enable_cluster_autoscaler', options_list=[
Expand Down
10 changes: 10 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
CONST_OS_SKU_AZURELINUX,
CONST_OS_SKU_CBLMARINER,
CONST_OS_SKU_MARINER,
CONST_NODEPOOL_MODE_GATEWAY,
)
from azure.cli.core import keys
from azure.cli.core.azclierror import (
Expand Down Expand Up @@ -871,3 +872,12 @@ def validate_custom_ca_trust_certificates(namespace):
if hasattr(namespace, 'os_type') and namespace.os_type != "Linux":
raise ArgumentUsageError(
'--custom-ca-trust-certificates can only be set for linux nodepools')


def validate_gateway_prefix_size(namespace):
"""Validates the gateway prefix size."""
if namespace.gateway_prefix_size is not None:
if not hasattr(namespace, 'mode') or namespace.mode != CONST_NODEPOOL_MODE_GATEWAY:
raise ArgumentUsageError("--gateway-prefix-size can only be set for Gateway-mode nodepools")
if namespace.gateway_prefix_size < 28 or namespace.gateway_prefix_size > 31:
raise InvalidArgumentValueError("--gateway-prefix-size must be in the range [28, 31]")
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,13 @@ def get_gpu_driver(self) -> Union[str, None]:
"""
return self._get_gpu_driver()

def get_gateway_prefix_size(self) -> Union[int, None]:
"""Obtain the value of gateway_prefix_size.

:return: int or None
"""
return self.raw_param.get('gateway_prefix_size')


class AKSAgentPoolAddDecorator:
def __init__(
Expand Down Expand Up @@ -2007,6 +2014,22 @@ def set_up_gpu_profile(self, agentpool: AgentPool) -> AgentPool:

return agentpool

def set_up_agentpool_gateway_profile(self, agentpool: AgentPool) -> AgentPool:
"""Set up agentpool gateway profile for the AgentPool object.

:return: the AgentPool object
"""
self._ensure_agentpool(agentpool)

gateway_prefix_size = self.context.get_gateway_prefix_size()
if gateway_prefix_size is not None:
if agentpool.gateway_profile is None:
agentpool.gateway_profile = self.models.AgentPoolGatewayProfile() # pylint: disable=no-member

agentpool.gateway_profile.public_ip_prefix_size = gateway_prefix_size

return agentpool

def construct_agentpool_profile_default(self, bypass_restore_defaults: bool = False) -> AgentPool:
"""The overall controller used to construct the AgentPool profile by default.

Expand Down Expand Up @@ -2053,6 +2076,8 @@ def construct_agentpool_profile_default(self, bypass_restore_defaults: bool = Fa
agentpool = self.set_up_motd(agentpool)
# set up gpu profile
agentpool = self.set_up_gpu_profile(agentpool)
# set up agentpool gateway profile
agentpool = self.set_up_agentpool_gateway_profile(agentpool)
# restore defaults
if not bypass_restore_defaults:
agentpool = self._restore_defaults_in_agentpool(agentpool)
Expand Down
5 changes: 5 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ def aks_create(
rotation_poll_interval=None,
enable_app_routing=False,
app_routing_default_nginx_controller=None,
enable_static_egress_gateway=False,
# nodepool paramerters
nodepool_name="nodepool1",
node_vm_size=None,
Expand Down Expand Up @@ -799,6 +800,8 @@ def aks_update(
enable_secret_rotation=False,
disable_secret_rotation=False,
rotation_poll_interval=None,
enable_static_egress_gateway=False,
disable_static_egress_gateway=False,
# nodepool paramerters
enable_cluster_autoscaler=False,
disable_cluster_autoscaler=False,
Expand Down Expand Up @@ -2439,6 +2442,8 @@ def aks_agentpool_add(
if_none_match=None,
# gpu driver
gpu_driver=None,
# static egress gateway - gateway-mode pool
gateway_prefix_size=None,
):
# DO NOT MOVE: get all the original parameters and save them as a dictionary
raw_parameters = locals()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ aks create:
enable_apiserver_vnet_integration:
rule_exclusions:
- option_length_too_long

enable_static_egress_gateway:
rule_exclusions:
- option_length_too_long
aks enable-addons:
parameters:
appgw_watch_namespace:
Expand Down Expand Up @@ -195,6 +197,12 @@ aks update:
disable_private_cluster:
rule_exclusions:
- option_length_too_long
enable_static_egress_gateway:
rule_exclusions:
- option_length_too_long
disable_static_egress_gateway:
rule_exclusions:
- option_length_too_long
aks nodepool add:
parameters:
disable_windows_outbound_nat:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5454,6 +5454,37 @@ def get_bootstrap_container_registry_resource_id(self) -> Union[str, None]:
"""
return self.raw_param.get("bootstrap_container_registry_resource_id")

def _get_enable_static_egress_gateway(self, enable_validation: bool = False) -> bool:
"""Internal function to obtain the value of enable_static_egress_gateway.
When enabled, if both enable_static_egress_gateway and disable_static_egress_gateway are
specified, raise a MutuallyExclusiveArgumentError.
:return: bool
"""
enable_static_egress_gateway = self.raw_param.get("enable_static_egress_gateway")
# This parameter does not need dynamic completion.
if enable_validation:
if enable_static_egress_gateway and self.get_disable_static_egress_gateway():
raise MutuallyExclusiveArgumentError(
"Cannot specify --enable-static-egress-gateway and "
"--disable-static-egress-gateway at the same time. "
)

return enable_static_egress_gateway

def get_enable_static_egress_gateway(self) -> bool:
"""Obtain the value of enable_static_egress_gateway.
:return: bool
"""
return self._get_enable_static_egress_gateway(enable_validation=True)

def get_disable_static_egress_gateway(self) -> bool:
"""Obtain the value of disable_static_egress_gateway.
:return: bool
"""
# Note: No need to check for mutually exclusive parameter with enable-static-egress-gateway here
# because it's already checked in get_enable_static_egress_gateway
return self.raw_param.get("disable_static_egress_gateway")


class AKSManagedClusterCreateDecorator(BaseAKSManagedClusterDecorator):
def __init__(
Expand Down Expand Up @@ -6772,6 +6803,25 @@ def set_up_bootstrap_profile(self, mc: ManagedCluster) -> ManagedCluster:

return mc

def set_up_static_egress_gateway(self, mc: ManagedCluster) -> ManagedCluster:
self._ensure_mc(mc)

if self.context.get_enable_static_egress_gateway():
if not mc.network_profile:
raise UnknownError(
"Unexpectedly get an empty network profile in the process of "
"updating enable-static-egress-gateway config."
)
if mc.network_profile.static_egress_gateway_profile is None:
mc.network_profile.static_egress_gateway_profile = (
self.models.ManagedClusterStaticEgressGatewayProfile() # pylint: disable=no-member
)
# set enabled
mc.network_profile.static_egress_gateway_profile.enabled = True

# Default is disabled so no need to worry about that here
return mc

def construct_mc_profile_default(self, bypass_restore_defaults: bool = False) -> ManagedCluster:
"""The overall controller used to construct the default ManagedCluster profile.

Expand Down Expand Up @@ -6856,6 +6906,8 @@ def construct_mc_profile_default(self, bypass_restore_defaults: bool = False) ->
mc = self.set_up_node_resource_group_profile(mc)
# set up bootstrap profile
mc = self.set_up_bootstrap_profile(mc)
# set up static egress gateway profile
mc = self.set_up_static_egress_gateway(mc)

# DO NOT MOVE: keep this at the bottom, restore defaults
if not bypass_restore_defaults:
Expand Down Expand Up @@ -8682,6 +8734,35 @@ def update_bootstrap_profile(self, mc: ManagedCluster) -> ManagedCluster:

return mc

def update_static_egress_gateway(self, mc: ManagedCluster) -> ManagedCluster:
"""Update static egress gateway addon for the ManagedCluster object.
:return: the ManagedCluster object
"""
self._ensure_mc(mc)

if self.context.get_enable_static_egress_gateway():
if not mc.network_profile:
raise UnknownError(
"Unexpectedly get an empty network profile in the process of updating static-egress-gateway config."
)
if mc.network_profile.static_egress_gateway_profile is None:
mc.network_profile.static_egress_gateway_profile = (
self.models.ManagedClusterStaticEgressGatewayProfile() # pylint: disable=no-member
)
mc.network_profile.static_egress_gateway_profile.enabled = True

if self.context.get_disable_static_egress_gateway():
if not mc.network_profile:
raise UnknownError(
"Unexpectedly get an empty network profile in the process of updating static-egress-gateway config."
)
if mc.network_profile.static_egress_gateway_profile is None:
mc.network_profile.static_egress_gateway_profile = (
self.models.ManagedClusterStaticEgressGatewayProfile() # pylint: disable=no-member
)
mc.network_profile.static_egress_gateway_profile.enabled = False
return mc

def update_mc_profile_default(self) -> ManagedCluster:
"""The overall controller used to update the default ManagedCluster profile.

Expand Down Expand Up @@ -8765,6 +8846,8 @@ def update_mc_profile_default(self) -> ManagedCluster:
mc = self.update_node_resource_group_profile(mc)
# update bootstrap profile
mc = self.update_bootstrap_profile(mc)
# update static egress gateway
mc = self.update_static_egress_gateway(mc)
# update kubernetes version and orchestrator version
mc = self.update_kubernetes_version_and_orchestrator_version(mc)
return mc
Expand Down
Loading
Loading