Skip to content

Commit 93f2e7f

Browse files
aks-preview: Add managedNATGatewayV2 outbound type support
Add support for the managedNATGatewayV2 outbound type which uses Azure NAT Gateway Standard V2 SKU. New CLI parameters: - --nat-gateway-managed-outbound-ipv6-count: IPv6 managed IPs (1-16, dual-stack) - --nat-gateway-outbound-ip-ids: User-provided public IP resource IDs - --nat-gateway-outbound-ip-prefix-ids: User-provided IP prefix resource IDs These are valid only with --outbound-type managedNATGatewayV2.
1 parent 2286135 commit 93f2e7f

File tree

10 files changed

+352
-22
lines changed

10 files changed

+352
-22
lines changed

src/aks-preview/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ To release a new version, please select a new version number (usually plus 1 to
1212
Pending
1313
+++++++
1414

15+
19.0.0b25
16+
+++++++
17+
* `az aks create/update`: Add `--outbound-type managedNATGatewayV2` support using Azure NAT Gateway Standard V2 SKU with IPv6, user-provided IPs, and IP prefixes.
18+
1519
19.0.0b24
1620
+++++++
1721
* Vendor new SDK and bump API version to 2026-01-02-preview.

src/aks-preview/azext_aks_preview/_consts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@
377377

378378
CONST_OUTBOUND_TYPE_NONE = "none"
379379
CONST_OUTBOUND_TYPE_BLOCK = "block"
380+
CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY_V2 = "managedNATGatewayV2"
380381

381382
# IMDS restriction consts
382383
CONST_IMDS_RESTRICTION_ENABLED = "None"

src/aks-preview/azext_aks_preview/_help.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,15 @@
158158
- name: --nat-gateway-managed-outbound-ip-count
159159
type: int
160160
short-summary: NAT gateway managed outbound IP count.
161-
long-summary: Desired number of managed outbound IPs for NAT gateway outbound connection. Please specify a value in the range of [1, 16]. Valid for Standard SKU load balancer cluster with managedNATGateway outbound type only.
161+
long-summary: Desired number of managed outbound IPs for NAT gateway outbound connection. Please specify a value in the range of [1, 16]. Valid for Standard SKU load balancer cluster with managedNATGateway or managedNATGatewayV2 outbound type only.
162162
- name: --nat-gateway-idle-timeout
163163
type: int
164164
short-summary: NAT gateway idle timeout in minutes.
165-
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.
165+
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 or managedNATGatewayV2 outbound type only.
166166
- name: --outbound-type
167167
type: string
168168
short-summary: How outbound traffic will be configured for a cluster.
169-
long-summary: Select between loadBalancer, userDefinedRouting, managedNATGateway, userAssignedNATGateway, none and block. 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.
169+
long-summary: Select between loadBalancer, userDefinedRouting, managedNATGateway, managedNATGatewayV2, userAssignedNATGateway, none and block. If not set, defaults to type loadBalancer. managedNATGatewayV2 uses Azure NAT Gateway Standard V2 SKU and supports IPv6, user-provided public IPs, and user-provided IP prefixes.
170170
- name: --enable-addons -a
171171
type: string
172172
short-summary: Enable the Kubernetes addons in a comma-separated list.
@@ -928,15 +928,15 @@
928928
- name: --nat-gateway-managed-outbound-ip-count
929929
type: int
930930
short-summary: NAT gateway managed outbound IP count.
931-
long-summary: Desired number of managed outbound IPs for NAT gateway outbound connection. Please specify a value in the range of [1, 16]. Valid for Standard SKU load balancer cluster with managedNATGateway outbound type only.
931+
long-summary: Desired number of managed outbound IPs for NAT gateway outbound connection. Please specify a value in the range of [1, 16]. Valid for Standard SKU load balancer cluster with managedNATGateway or managedNATGatewayV2 outbound type only.
932932
- name: --nat-gateway-idle-timeout
933933
type: int
934934
short-summary: NAT gateway idle timeout in minutes.
935-
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.
935+
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 or managedNATGatewayV2 outbound type only.
936936
- name: --outbound-type
937937
type: string
938938
short-summary: How outbound traffic will be configured for a cluster.
939-
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, none and block. For custom vnet, loadbalancer, userAssignedNATGateway and userDefinedRouting are supported. For aks managed vnet, loadbalancer, managedNATGateway and userDefinedRouting are supported.
939+
long-summary: This option will change the way how the outbound connections are managed in the AKS cluster. Available options are loadbalancer, managedNATGateway, managedNATGatewayV2, userAssignedNATGateway, userDefinedRouting, none and block.
940940
- name: --nrg-lockdown-restriction-level
941941
type: string
942942
short-summary: Restriction level on the managed node resource.

src/aks-preview/azext_aks_preview/_natgateway.py

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,99 @@
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+
):
1017
"""parse and build NAT gateway profile"""
11-
if not is_nat_gateway_profile_provided(managed_outbound_ip_count, idle_timeout):
18+
if not is_nat_gateway_profile_provided(
19+
managed_outbound_ip_count, idle_timeout,
20+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
21+
):
1222
return None
1323

1424
profile = models.ManagedClusterNATGatewayProfile()
15-
return configure_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models)
25+
return configure_nat_gateway_profile(
26+
managed_outbound_ip_count, idle_timeout, profile, models,
27+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
28+
)
1629

1730

18-
def update_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models: SimpleNamespace):
31+
def update_nat_gateway_profile(
32+
managed_outbound_ip_count,
33+
idle_timeout,
34+
profile,
35+
models: SimpleNamespace,
36+
managed_outbound_ipv6_count=None,
37+
outbound_ip_ids=None,
38+
outbound_ip_prefix_ids=None,
39+
):
1940
"""parse and update an existing NAT gateway profile"""
20-
if not is_nat_gateway_profile_provided(managed_outbound_ip_count, idle_timeout):
41+
if not is_nat_gateway_profile_provided(
42+
managed_outbound_ip_count, idle_timeout,
43+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
44+
):
2145
return profile
2246
if not profile:
2347
profile = models.ManagedClusterNATGatewayProfile()
24-
return configure_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models)
48+
return configure_nat_gateway_profile(
49+
managed_outbound_ip_count, idle_timeout, profile, models,
50+
managed_outbound_ipv6_count, outbound_ip_ids, outbound_ip_prefix_ids,
51+
)
2552

2653

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])
54+
def is_nat_gateway_profile_provided(
55+
managed_outbound_ip_count,
56+
idle_timeout,
57+
managed_outbound_ipv6_count=None,
58+
outbound_ip_ids=None,
59+
outbound_ip_prefix_ids=None,
60+
):
61+
return any([
62+
managed_outbound_ip_count is not None,
63+
idle_timeout,
64+
managed_outbound_ipv6_count is not None,
65+
outbound_ip_ids,
66+
outbound_ip_prefix_ids,
67+
])
2968

3069

31-
def configure_nat_gateway_profile(managed_outbound_ip_count, idle_timeout, profile, models: SimpleNamespace):
70+
def configure_nat_gateway_profile(
71+
managed_outbound_ip_count,
72+
idle_timeout,
73+
profile,
74+
models: SimpleNamespace,
75+
managed_outbound_ipv6_count=None,
76+
outbound_ip_ids=None,
77+
outbound_ip_prefix_ids=None,
78+
):
3279
"""configure a NAT Gateway with customer supplied values"""
33-
if managed_outbound_ip_count is not None:
80+
if managed_outbound_ip_count is not None or managed_outbound_ipv6_count is not None:
3481
ManagedClusterManagedOutboundIPProfile = models.ManagedClusterManagedOutboundIPProfile
35-
profile.managed_outbound_ip_profile = ManagedClusterManagedOutboundIPProfile(
36-
count=managed_outbound_ip_count
37-
)
82+
if not profile.managed_outbound_ip_profile:
83+
profile.managed_outbound_ip_profile = ManagedClusterManagedOutboundIPProfile()
84+
if managed_outbound_ip_count is not None:
85+
profile.managed_outbound_ip_profile.count = managed_outbound_ip_count
86+
if managed_outbound_ipv6_count is not None:
87+
profile.managed_outbound_ip_profile.count_i_pv6 = managed_outbound_ipv6_count
3888

3989
if idle_timeout:
4090
profile.idle_timeout_in_minutes = idle_timeout
4191

92+
if outbound_ip_ids is not None:
93+
ManagedClusterNATGatewayProfileOutboundIPs = models.ManagedClusterNATGatewayProfileOutboundIPs
94+
profile.outbound_i_ps = ManagedClusterNATGatewayProfileOutboundIPs(
95+
public_i_ps=outbound_ip_ids
96+
)
97+
98+
if outbound_ip_prefix_ids is not None:
99+
ManagedClusterNATGatewayProfileOutboundIPPrefixes = models.ManagedClusterNATGatewayProfileOutboundIPPrefixes
100+
profile.outbound_ip_prefixes = ManagedClusterNATGatewayProfileOutboundIPPrefixes(
101+
public_ip_prefixes=outbound_ip_prefix_ids
102+
)
103+
42104
return profile

src/aks-preview/azext_aks_preview/_params.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
tags_type,
3434
zones_type,
3535
)
36+
from azext_aks_preview._validators import (
37+
validate_nat_gateway_managed_outbound_ipv6_count,
38+
)
3639
from azext_aks_preview._client_factory import CUSTOM_MGMT_AKS_PREVIEW
3740
from azext_aks_preview._completers import (
3841
get_k8s_upgrades_completion_list,
@@ -147,6 +150,7 @@
147150
CONST_ARTIFACT_SOURCE_CACHE,
148151
CONST_OUTBOUND_TYPE_NONE,
149152
CONST_OUTBOUND_TYPE_BLOCK,
153+
CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY_V2,
150154
CONST_APP_ROUTING_ANNOTATION_CONTROLLED_NGINX,
151155
CONST_APP_ROUTING_EXTERNAL_NGINX,
152156
CONST_APP_ROUTING_INTERNAL_NGINX,
@@ -371,6 +375,7 @@
371375
CONST_OUTBOUND_TYPE_LOAD_BALANCER,
372376
CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING,
373377
CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY,
378+
CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY_V2,
374379
CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY,
375380
CONST_OUTBOUND_TYPE_NONE,
376381
CONST_OUTBOUND_TYPE_BLOCK,
@@ -659,6 +664,37 @@ def load_arguments(self, _):
659664
type=int,
660665
validator=validate_nat_gateway_idle_timeout,
661666
)
667+
c.argument(
668+
"nat_gateway_managed_outbound_ipv6_count",
669+
options_list=[
670+
"--nat-gateway-managed-outbound-ipv6-count",
671+
"--nat-gw-ipv6-count",
672+
],
673+
type=int,
674+
validator=validate_nat_gateway_managed_outbound_ipv6_count,
675+
help="NAT gateway managed outbound IPv6 IP count. "
676+
"Valid only with --outbound-type managedNATGatewayV2.",
677+
)
678+
c.argument(
679+
"nat_gateway_outbound_ip_ids",
680+
options_list=[
681+
"--nat-gateway-outbound-ip-ids",
682+
"--nat-gw-ip-ids",
683+
],
684+
nargs="+",
685+
help="Space-separated public IP resource IDs for the "
686+
"cluster NAT gateway. V2 only.",
687+
)
688+
c.argument(
689+
"nat_gateway_outbound_ip_prefix_ids",
690+
options_list=[
691+
"--nat-gateway-outbound-ip-prefix-ids",
692+
"--nat-gw-prefix-ids",
693+
],
694+
nargs="+",
695+
help="Space-separated public IP prefix resource IDs "
696+
"for the cluster NAT gateway. V2 only.",
697+
)
662698
c.argument("outbound_type", arg_type=get_enum_type(outbound_types))
663699
c.argument("network_plugin", arg_type=get_enum_type(network_plugins))
664700
c.argument("network_plugin_mode", arg_type=get_enum_type(network_plugin_modes))
@@ -1247,6 +1283,37 @@ def load_arguments(self, _):
12471283
type=int,
12481284
validator=validate_nat_gateway_idle_timeout,
12491285
)
1286+
c.argument(
1287+
"nat_gateway_managed_outbound_ipv6_count",
1288+
options_list=[
1289+
"--nat-gateway-managed-outbound-ipv6-count",
1290+
"--nat-gw-ipv6-count",
1291+
],
1292+
type=int,
1293+
validator=validate_nat_gateway_managed_outbound_ipv6_count,
1294+
help="NAT gateway managed outbound IPv6 IP count. "
1295+
"Valid only with --outbound-type managedNATGatewayV2.",
1296+
)
1297+
c.argument(
1298+
"nat_gateway_outbound_ip_ids",
1299+
options_list=[
1300+
"--nat-gateway-outbound-ip-ids",
1301+
"--nat-gw-ip-ids",
1302+
],
1303+
nargs="+",
1304+
help="Space-separated public IP resource IDs for the "
1305+
"cluster NAT gateway. V2 only.",
1306+
)
1307+
c.argument(
1308+
"nat_gateway_outbound_ip_prefix_ids",
1309+
options_list=[
1310+
"--nat-gateway-outbound-ip-prefix-ids",
1311+
"--nat-gw-prefix-ids",
1312+
],
1313+
nargs="+",
1314+
help="Space-separated public IP prefix resource IDs "
1315+
"for the cluster NAT gateway. V2 only.",
1316+
)
12501317
c.argument("network_dataplane", arg_type=get_enum_type(network_dataplanes))
12511318
c.argument("network_policy")
12521319
c.argument("network_plugin", arg_type=get_enum_type(network_plugins))

src/aks-preview/azext_aks_preview/_validators.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,3 +1144,13 @@ def validate_azure_monitor_logs_enable_disable(namespace):
11441144
"Cannot specify both '--enable-azure-monitor-logs' and '--disable-azure-monitor-logs'. "
11451145
"Use either '--enable-azure-monitor-logs' or '--disable-azure-monitor-logs'."
11461146
)
1147+
1148+
1149+
def validate_nat_gateway_managed_outbound_ipv6_count(namespace):
1150+
"""validate NAT gateway profile managed outbound IPv6 count"""
1151+
if namespace.nat_gateway_managed_outbound_ipv6_count is not None:
1152+
if (namespace.nat_gateway_managed_outbound_ipv6_count < 1 or
1153+
namespace.nat_gateway_managed_outbound_ipv6_count > 16):
1154+
raise InvalidArgumentValueError(
1155+
"--nat-gateway-managed-outbound-ipv6-count must be in the range [1,16]"
1156+
)

src/aks-preview/azext_aks_preview/custom.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,9 @@ def aks_create(
955955
load_balancer_backend_pool_type=None,
956956
nat_gateway_managed_outbound_ip_count=None,
957957
nat_gateway_idle_timeout=None,
958+
nat_gateway_managed_outbound_ipv6_count=None,
959+
nat_gateway_outbound_ip_ids=None,
960+
nat_gateway_outbound_ip_prefix_ids=None,
958961
outbound_type=None,
959962
network_plugin=None,
960963
network_plugin_mode=None,
@@ -1217,6 +1220,9 @@ def aks_update(
12171220
load_balancer_backend_pool_type=None,
12181221
nat_gateway_managed_outbound_ip_count=None,
12191222
nat_gateway_idle_timeout=None,
1223+
nat_gateway_managed_outbound_ipv6_count=None,
1224+
nat_gateway_outbound_ip_ids=None,
1225+
nat_gateway_outbound_ip_prefix_ids=None,
12201226
kube_proxy_config=None,
12211227
auto_upgrade_channel=None,
12221228
node_os_upgrade_channel=None,

0 commit comments

Comments
 (0)