Skip to content

Commit aec6795

Browse files
{AKS} az aks: add --outbound-type-sku for managed NAT Gateway V2 GA (#34017)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent a6c10e0 commit aec6795

11 files changed

Lines changed: 551 additions & 16 deletions

File tree

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@
8888
CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY = "userAssignedNATGateway"
8989
CONST_OUTBOUND_TYPE_NONE = "none"
9090

91+
# managed NAT gateway SKU
92+
CONST_NAT_GATEWAY_SKU_STANDARD = "Standard"
93+
CONST_NAT_GATEWAY_SKU_STANDARD_V2 = "StandardV2"
94+
9195
# load balancer backend pool type
9296
CONST_LOAD_BALANCER_BACKEND_POOL_TYPE_NODE_IP = "nodeIP"
9397
CONST_LOAD_BALANCER_BACKEND_POOL_TYPE_NODE_IP_CONFIGURATION = "nodeIPConfiguration"

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@
186186
type: int
187187
short-summary: NAT gateway idle timeout in minutes.
188188
long-summary: Desired idle timeout for NAT gateway outbound flows, default is 4 minutes. Please specify a value in the range of [4, 120]. Valid for Standard SKU load balancer cluster with managedNATGateway outbound type only.
189+
- name: --outbound-type-sku
190+
type: string
191+
short-summary: SKU of the managed NAT Gateway (Standard or StandardV2).
192+
long-summary: Only valid with --outbound-type managedNATGateway. Omit to default to StandardV2 where the region supports it, otherwise Standard. StandardV2 adds zone resiliency, IPv6 support, and higher bandwidth.
189193
- name: --outbound-type
190194
type: string
191195
short-summary: How outbound traffic will be configured for a cluster.
@@ -867,6 +871,10 @@
867871
type: int
868872
short-summary: NAT gateway idle timeout in minutes.
869873
long-summary: Desired idle timeout for NAT gateway outbound flows, default is 4 minutes. Please specify a value in the range of [4, 120]. Valid for Standard SKU load balancer cluster with managedNATGateway outbound type only.
874+
- name: --outbound-type-sku
875+
type: string
876+
short-summary: SKU of the managed NAT Gateway (Standard or StandardV2).
877+
long-summary: Only valid with --outbound-type managedNATGateway. Migrate an existing Standard (V1) cluster to StandardV2 by passing StandardV2. StandardV2 adds zone resiliency, IPv6 support, and higher bandwidth. Downgrade from StandardV2 to Standard is not supported.
870878
- name: --outbound-type
871879
type: string
872880
short-summary: How outbound traffic will be configured for a cluster.

‎src/azure-cli/azure/cli/command_modules/acs/_natgateway.py‎

Lines changed: 93 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,117 @@
66
from types import SimpleNamespace
77

88

9-
def create_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, models: SimpleNamespace):
9+
def create_nat_gateway_profile(
10+
managed_outbound_ip_count,
11+
idle_timeout,
12+
models: SimpleNamespace,
13+
managed_outbound_ipv6_count=None,
14+
outbound_ip_ids=None,
15+
outbound_ip_prefix_ids=None,
16+
nat_gateway_sku=None,
17+
):
1018
"""parse and build NAT gateway profile"""
11-
if not is_nat_gateway_profile_provided(managed_outbound_ip_count, idle_timeout):
19+
if not is_nat_gateway_profile_provided(
20+
managed_outbound_ip_count, idle_timeout,
21+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
22+
nat_gateway_sku,
23+
):
1224
return None
1325

1426
profile = models.ManagedClusterNATGatewayProfile()
15-
return configure_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models)
27+
return configure_nat_gateway_profile(
28+
managed_outbound_ip_count, idle_timeout, profile, models,
29+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
30+
nat_gateway_sku,
31+
)
1632

1733

18-
def update_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models: SimpleNamespace):
34+
def update_nat_gateway_profile(
35+
managed_outbound_ip_count,
36+
idle_timeout,
37+
profile,
38+
models: SimpleNamespace,
39+
managed_outbound_ipv6_count=None,
40+
outbound_ip_ids=None,
41+
outbound_ip_prefix_ids=None,
42+
nat_gateway_sku=None,
43+
):
1944
"""parse and update an existing NAT gateway profile"""
20-
if not is_nat_gateway_profile_provided(managed_outbound_ip_count, idle_timeout):
45+
if not is_nat_gateway_profile_provided(
46+
managed_outbound_ip_count, idle_timeout,
47+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
48+
nat_gateway_sku,
49+
):
2150
return profile
2251
if not profile:
2352
profile = models.ManagedClusterNATGatewayProfile()
24-
return configure_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models)
53+
return configure_nat_gateway_profile(
54+
managed_outbound_ip_count, idle_timeout, profile, models,
55+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
56+
nat_gateway_sku,
57+
)
2558

2659

27-
def is_nat_gateway_profile_provided(managed_outbound_ip_count, idle_timeout):
28-
return any([managed_outbound_ip_count is not None, idle_timeout])
60+
def is_nat_gateway_profile_provided(
61+
managed_outbound_ip_count,
62+
idle_timeout,
63+
managed_outbound_ipv6_count=None,
64+
outbound_ip_ids=None,
65+
outbound_ip_prefix_ids=None,
66+
nat_gateway_sku=None,
67+
):
68+
return any([
69+
managed_outbound_ip_count is not None,
70+
idle_timeout,
71+
managed_outbound_ipv6_count is not None,
72+
outbound_ip_ids is not None,
73+
outbound_ip_prefix_ids is not None,
74+
nat_gateway_sku is not None,
75+
])
2976

3077

31-
def configure_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models: SimpleNamespace):
78+
def configure_nat_gateway_profile(
79+
managed_outbound_ip_count,
80+
idle_timeout,
81+
profile,
82+
models: SimpleNamespace,
83+
managed_outbound_ipv6_count=None,
84+
outbound_ip_ids=None,
85+
outbound_ip_prefix_ids=None,
86+
nat_gateway_sku=None,
87+
):
3288
"""configure a NAT Gateway with customer supplied values"""
33-
if managed_outbound_ip_count is not None:
89+
if managed_outbound_ip_count is not None or managed_outbound_ipv6_count is not None:
3490
ManagedClusterManagedOutboundIPProfile = models.ManagedClusterManagedOutboundIPProfile
35-
profile.managed_outbound_ip_profile = ManagedClusterManagedOutboundIPProfile(
36-
count=managed_outbound_ip_count
37-
)
91+
if not profile.managed_outbound_ip_profile:
92+
profile.managed_outbound_ip_profile = ManagedClusterManagedOutboundIPProfile()
93+
if managed_outbound_ip_count is not None:
94+
profile.managed_outbound_ip_profile.count = managed_outbound_ip_count
95+
elif profile.managed_outbound_ip_profile.count is None:
96+
# SDK 41.6 no longer materializes the IPv4 default; keep the documented default of 1.
97+
profile.managed_outbound_ip_profile.count = 1
98+
if managed_outbound_ipv6_count is not None:
99+
profile.managed_outbound_ip_profile.count_ipv6 = managed_outbound_ipv6_count
38100

39101
if idle_timeout:
40102
profile.idle_timeout_in_minutes = idle_timeout
41103

104+
if outbound_ip_ids is not None:
105+
ManagedClusterNATGatewayProfileOutboundIPs = models.ManagedClusterNATGatewayProfileOutboundIPs
106+
if ManagedClusterNATGatewayProfileOutboundIPs is None:
107+
raise ValueError("The selected AKS API profile/SDK does not support setting NAT gateway outbound IPs.")
108+
ip_id_list = [x.strip() for x in outbound_ip_ids.split(',') if x.strip()]
109+
profile.outbound_i_ps = ManagedClusterNATGatewayProfileOutboundIPs(public_i_ps=ip_id_list)
110+
111+
if outbound_ip_prefix_ids is not None:
112+
ManagedClusterNATGatewayProfileOutboundIpPrefixes = models.ManagedClusterNATGatewayProfileOutboundIpPrefixes
113+
prefix_id_list = [x.strip() for x in outbound_ip_prefix_ids.split(',') if x.strip()]
114+
profile.outbound_ip_prefixes = ManagedClusterNATGatewayProfileOutboundIpPrefixes(
115+
public_ip_prefixes=prefix_id_list
116+
)
117+
118+
if nat_gateway_sku is not None:
119+
# GA shape: V2 is expressed as outboundType=managedNATGateway + natGatewayProfile.sku.
120+
profile.sku = nat_gateway_sku
121+
42122
return profile

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
CONST_OS_SKU_CBLMARINER, CONST_OS_SKU_MARINER,
4747
CONST_OS_SKU_UBUNTU, CONST_OS_SKU_UBUNTU2204, CONST_OS_SKU_UBUNTU2404,
4848
CONST_OS_SKU_WINDOWS2019, CONST_OS_SKU_WINDOWS2022, CONST_OS_SKU_WINDOWS2025,
49+
CONST_NAT_GATEWAY_SKU_STANDARD, CONST_NAT_GATEWAY_SKU_STANDARD_V2,
4950
CONST_OUTBOUND_TYPE_LOAD_BALANCER, CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY,
5051
CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY,
5152
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING, CONST_OUTBOUND_TYPE_NONE,
@@ -119,7 +120,11 @@
119120
validate_load_balancer_outbound_ips, validate_load_balancer_outbound_ports,
120121
validate_load_balancer_sku, validate_max_surge, validate_max_unavailable,
121122
validate_nat_gateway_idle_timeout,
122-
validate_nat_gateway_managed_outbound_ip_count, validate_network_policy,
123+
validate_nat_gateway_managed_outbound_ip_count,
124+
validate_nat_gateway_managed_outbound_ipv6_count,
125+
validate_nat_gateway_v2_params, validate_nat_gateway_v2_params_for_update,
126+
validate_network_policy,
127+
validate_outbound_type_sku, validate_outbound_type_sku_for_update,
123128
validate_nodepool_id, validate_nodepool_labels, validate_nodepool_name,
124129
validate_nodepool_tags, validate_nodes_count, validate_os_sku,
125130
validate_pod_subnet_id, validate_ppg, validate_priority,
@@ -197,6 +202,7 @@
197202

198203
# consts for ManagedCluster
199204
load_balancer_skus = [CONST_LOAD_BALANCER_SKU_BASIC, CONST_LOAD_BALANCER_SKU_STANDARD]
205+
nat_gateway_skus = [CONST_NAT_GATEWAY_SKU_STANDARD, CONST_NAT_GATEWAY_SKU_STANDARD_V2]
200206
sku_names = [CONST_MANAGED_CLUSTER_SKU_NAME_BASE, CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC]
201207
sku_tiers = [CONST_MANAGED_CLUSTER_SKU_TIER_FREE, CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD, CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM]
202208
network_plugins = [CONST_NETWORK_PLUGIN_KUBENET, CONST_NETWORK_PLUGIN_AZURE, CONST_NETWORK_PLUGIN_NONE]
@@ -428,8 +434,21 @@ def load_arguments(self, _):
428434
c.argument('load_balancer_backend_pool_type', arg_type=get_enum_type(backend_pool_types))
429435
c.argument('nrg_lockdown_restriction_level', arg_type=get_enum_type(nrg_lockdown_restriction_levels))
430436
c.argument('nat_gateway_managed_outbound_ip_count', type=int, validator=validate_nat_gateway_managed_outbound_ip_count)
437+
c.argument('nat_gateway_managed_outbound_ipv6_count',
438+
options_list=['--nat-gateway-managed-outbound-ipv6-count', '--nat-gw-ipv6-count'],
439+
type=int, validator=validate_nat_gateway_managed_outbound_ipv6_count,
440+
help='NAT gateway managed outbound IPv6 count. Only valid with --outbound-type '
441+
'managedNATGateway and --outbound-type-sku StandardV2.')
431442
c.argument('nat_gateway_idle_timeout', type=int, validator=validate_nat_gateway_idle_timeout)
432-
c.argument('outbound_type', arg_type=get_enum_type(outbound_types))
443+
c.argument('nat_gateway_sku', options_list=['--outbound-type-sku'], arg_type=get_enum_type(nat_gateway_skus), validator=validate_outbound_type_sku)
444+
c.argument('nat_gateway_outbound_ip_ids', options_list=['--nat-gateway-outbound-ips', '--nat-gw-ips'],
445+
help='Comma-separated public IP resource IDs for the cluster NAT gateway. '
446+
'Only valid with --outbound-type-sku StandardV2.')
447+
c.argument('nat_gateway_outbound_ip_prefix_ids',
448+
options_list=['--nat-gateway-outbound-ip-prefixes', '--nat-gw-prefixes'],
449+
help='Comma-separated public IP prefix resource IDs for the cluster NAT gateway. '
450+
'Only valid with --outbound-type-sku StandardV2.')
451+
c.argument('outbound_type', arg_type=get_enum_type(outbound_types), validator=validate_nat_gateway_v2_params)
433452
c.argument('network_plugin', arg_type=get_enum_type(network_plugins))
434453
c.argument('network_plugin_mode', arg_type=get_enum_type(network_plugin_modes))
435454
c.argument('network_policy', validator=validate_network_policy)
@@ -695,11 +714,24 @@ def load_arguments(self, _):
695714
c.argument("load_balancer_sku", arg_type=get_enum_type([CONST_LOAD_BALANCER_SKU_STANDARD]), validator=validate_load_balancer_sku)
696715
c.argument('nrg_lockdown_restriction_level', arg_type=get_enum_type(nrg_lockdown_restriction_levels))
697716
c.argument('nat_gateway_managed_outbound_ip_count', type=int, validator=validate_nat_gateway_managed_outbound_ip_count)
717+
c.argument('nat_gateway_managed_outbound_ipv6_count',
718+
options_list=['--nat-gateway-managed-outbound-ipv6-count', '--nat-gw-ipv6-count'],
719+
type=int, validator=validate_nat_gateway_managed_outbound_ipv6_count,
720+
help='NAT gateway managed outbound IPv6 count. Only valid with --outbound-type '
721+
'managedNATGateway and --outbound-type-sku StandardV2.')
698722
c.argument('nat_gateway_idle_timeout', type=int, validator=validate_nat_gateway_idle_timeout)
723+
c.argument('nat_gateway_sku', options_list=['--outbound-type-sku'], arg_type=get_enum_type(nat_gateway_skus), validator=validate_outbound_type_sku_for_update)
724+
c.argument('nat_gateway_outbound_ip_ids', options_list=['--nat-gateway-outbound-ips', '--nat-gw-ips'],
725+
help='Comma-separated public IP resource IDs for the cluster NAT gateway. '
726+
'Only valid with --outbound-type-sku StandardV2.')
727+
c.argument('nat_gateway_outbound_ip_prefix_ids',
728+
options_list=['--nat-gateway-outbound-ip-prefixes', '--nat-gw-prefixes'],
729+
help='Comma-separated public IP prefix resource IDs for the cluster NAT gateway. '
730+
'Only valid with --outbound-type-sku StandardV2.')
699731
c.argument('network_dataplane', arg_type=get_enum_type(network_dataplanes))
700732
c.argument('network_plugin', arg_type=get_enum_type(network_plugins))
701733
c.argument('network_policy', arg_type=get_enum_type(network_policies))
702-
c.argument('outbound_type', arg_type=get_enum_type(outbound_types))
734+
c.argument('outbound_type', arg_type=get_enum_type(outbound_types), validator=validate_nat_gateway_v2_params_for_update)
703735
c.argument('auto_upgrade_channel', arg_type=get_enum_type(auto_upgrade_channels))
704736
c.argument('cluster_autoscaler_profile', nargs='+', options_list=["--cluster-autoscaler-profile", "--ca-profile"],
705737
help="Comma-separated list of key=value pairs for configuring cluster autoscaler. Pass an empty string to clear the profile.")

0 commit comments

Comments
 (0)