Skip to content
Merged
3 changes: 3 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ To release a new version, please select a new version number (usually plus 1 to

Pending
+++++++
* Implicitly enable istio when ingress or egress gateway is enabled for Azure Service Mesh.
* Add `az aks nodepool delete-machines` command.
* Update `az aks approuting zone` command to support private dns zones.
* Vendor new SDK and bump API version to 2024-01-02-preview.

1.0.0b6
Expand Down
4 changes: 4 additions & 0 deletions src/aks-preview/azext_aks_preview/_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,7 @@
# SSH Access Consts
CONST_SSH_ACCESS_DISABLED = "disabled"
CONST_SSH_ACCESS_LOCALUSER = "localuser"

# Dns zone contributor role
CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE = "Private DNS Zone Contributor"
CONST_DNS_ZONE_CONTRIBUTOR_ROLE = "DNS Zone Contributor"
74 changes: 42 additions & 32 deletions src/aks-preview/azext_aks_preview/managed_cluster_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
CONST_PRIVATE_DNS_ZONE_SYSTEM,
CONST_ROTATION_POLL_INTERVAL,
CONST_SECRET_ROTATION_ENABLED,
CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE,
CONST_DNS_ZONE_CONTRIBUTOR_ROLE,
)
from azext_aks_preview._helpers import (
check_is_apiserver_vnet_integration_cluster,
Expand Down Expand Up @@ -96,6 +98,7 @@
from knack.prompting import prompt_y_n
from knack.util import CLIError
from msrestazure.tools import is_valid_resource_id
from msrestazure.tools import parse_resource_id


logger = get_logger(__name__)
Expand Down Expand Up @@ -2567,15 +2570,16 @@ def get_dns_zone_resource_ids_from_input(self) -> Union[List[str], None]:

:return: list of str or None
"""
dns_zone_resource_ids = self.raw_param.get("dns_zone_resource_ids")
dns_zone_resource_ids = [
x.strip()
for x in (
dns_zone_resource_ids.split(",")
if dns_zone_resource_ids
else []
)
]
dns_zone_resource_ids_input = self.raw_param.get("dns_zone_resource_ids")
dns_zone_resource_ids = []

if dns_zone_resource_ids_input:
for dns_zone in dns_zone_resource_ids_input.split(","):
dns_zone = dns_zone.strip()
if dns_zone and is_valid_resource_id(dns_zone):
dns_zone_resource_ids.append(dns_zone)
else:
raise CLIError(dns_zone, " is not a valid Azure DNS Zone resource ID.")

return dns_zone_resource_ids

Expand Down Expand Up @@ -4503,24 +4507,31 @@ def _update_dns_zone_resource_ids(self, mc: ManagedCluster, dns_zone_resource_id

if mc.ingress_profile and mc.ingress_profile.web_app_routing and mc.ingress_profile.web_app_routing.enabled:
if add_dns_zone:
if mc.ingress_profile.web_app_routing.dns_zone_resource_ids is None:
mc.ingress_profile.web_app_routing.dns_zone_resource_ids = []
mc.ingress_profile.web_app_routing.dns_zone_resource_ids.extend(dns_zone_resource_ids)
if attach_zones:
try:
for dns_zone in dns_zone_resource_ids:
if not add_role_assignment(
self.cmd,
"DNS Zone Contributor",
mc.ingress_profile.web_app_routing.identity.object_id,
False,
scope=dns_zone
):
logger.warning(
'Could not create a role assignment for App Routing. '
'Are you an Owner on this subscription?')
except Exception as ex:
raise CLIError('Error in granting dns zone permisions to managed identity.\n') from ex
mc.ingress_profile.web_app_routing.dns_zone_resource_ids = (
mc.ingress_profile.web_app_routing.dns_zone_resource_ids or []
)
for dns_zone_id in dns_zone_resource_ids:
if dns_zone_id not in mc.ingress_profile.web_app_routing.dns_zone_resource_ids:
mc.ingress_profile.web_app_routing.dns_zone_resource_ids.append(dns_zone_id)
if attach_zones:
try:
is_private_dns_zone = (
parse_resource_id(dns_zone_id).get("type").lower() == "privatednszones"
)
role = CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE if is_private_dns_zone else \
CONST_DNS_ZONE_CONTRIBUTOR_ROLE
if not add_role_assignment(
self.cmd,
role,
mc.ingress_profile.web_app_routing.identity.object_id,
False,
scope=dns_zone_id
):
logger.warning(
'Could not create a role assignment for App Routing. '
'Are you an Owner on this subscription?')
except Exception as ex:
raise CLIError('Error in granting dns zone permissions to managed identity.\n') from ex
elif delete_dns_zone:
if mc.ingress_profile.web_app_routing.dns_zone_resource_ids:
dns_zone_resource_ids = [
Expand All @@ -4536,9 +4547,12 @@ def _update_dns_zone_resource_ids(self, mc: ManagedCluster, dns_zone_resource_id
if attach_zones:
try:
for dns_zone in dns_zone_resource_ids:
is_private_dns_zone = parse_resource_id(dns_zone).get("type").lower() == "privatednszones"
role = CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE if is_private_dns_zone else \
CONST_DNS_ZONE_CONTRIBUTOR_ROLE
if not add_role_assignment(
self.cmd,
"DNS Zone Contributor",
role,
mc.ingress_profile.web_app_routing.identity.object_id,
False,
scope=dns_zone,
Expand Down Expand Up @@ -4754,7 +4768,6 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None:
)

# attach keyvault to app routing addon
from msrestazure.tools import parse_resource_id
from azure.cli.command_modules.keyvault.custom import set_policy
from azext_aks_preview._client_factory import get_keyvault_client
keyvault_id = self.context.get_keyvault_id()
Expand All @@ -4779,12 +4792,10 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None:
keyvault_client = get_keyvault_client(self.cmd.cli_ctx, subscription_id=keyvault_subscription)
keyvault = keyvault_client.get(resource_group_name=keyvault_rg, vault_name=keyvault_name)
managed_identity_object_id = cluster.ingress_profile.web_app_routing.identity.object_id
print("managed_identity_object_id", managed_identity_object_id)
is_service_principal = False

try:
if keyvault.properties.enable_rbac_authorization:
print("within if block")
if not self.context.external_functions.add_role_assignment(
self.cmd,
"Key Vault Secrets User",
Expand All @@ -4797,7 +4808,6 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None:
"Are you an Owner on this subscription?"
)
else:
print("within else block")
keyvault = set_policy(
self.cmd,
keyvault_client,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7702,7 +7702,7 @@ def test_update_app_routing_profile(self):
self.cmd,
self.client,
{
"dns_zone_resource_ids": "test_dns_zone_resource_id_1,test_dns_zone_resource_id_2",
"dns_zone_resource_ids": "/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_1.com, /subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_2.com",
"add_dns_zone": True,
},
CUSTOM_MGMT_AKS_PREVIEW,
Expand All @@ -7723,8 +7723,8 @@ def test_update_app_routing_profile(self):
web_app_routing=self.models.ManagedClusterIngressProfileWebAppRouting(
enabled=True,
dns_zone_resource_ids=[
"test_dns_zone_resource_id_1",
"test_dns_zone_resource_id_2",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_1.com",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_2.com",
],
)
),
Expand All @@ -7737,7 +7737,7 @@ def test_update_app_routing_profile(self):
self.cmd,
self.client,
{
"dns_zone_resource_ids": "test_dns_zone_resource_id_1",
"dns_zone_resource_ids": "/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_1.com",
"delete_dns_zone": True,
},
CUSTOM_MGMT_AKS_PREVIEW,
Expand All @@ -7748,8 +7748,8 @@ def test_update_app_routing_profile(self):
web_app_routing=self.models.ManagedClusterIngressProfileWebAppRouting(
enabled=True,
dns_zone_resource_ids=[
"test_dns_zone_resource_id_1",
"test_dns_zone_resource_id_2",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_1.com",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_2.com",
],
)
),
Expand All @@ -7760,7 +7760,7 @@ def test_update_app_routing_profile(self):
location="test_location",
ingress_profile=self.models.ManagedClusterIngressProfile(
web_app_routing=self.models.ManagedClusterIngressProfileWebAppRouting(
enabled=True, dns_zone_resource_ids=["test_dns_zone_resource_id_2"]
enabled=True, dns_zone_resource_ids=["/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_2.com"]
)
),
)
Expand All @@ -7771,7 +7771,7 @@ def test_update_app_routing_profile(self):
self.cmd,
self.client,
{
"dns_zone_resource_ids": "test_dns_zone_resource_id_3,test_dns_zone_resource_id_4",
"dns_zone_resource_ids": "/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/privateDnsZones/testdnszone_3.com,/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/privateDnsZones/testdnszone_4.com",
"update_dns_zone": True,
},
CUSTOM_MGMT_AKS_PREVIEW,
Expand All @@ -7782,8 +7782,8 @@ def test_update_app_routing_profile(self):
web_app_routing=self.models.ManagedClusterIngressProfileWebAppRouting(
enabled=True,
dns_zone_resource_ids=[
"test_dns_zone_resource_id_1",
"test_dns_zone_resource_id_2",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_1.com",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_2.com",
],
)
),
Expand All @@ -7797,8 +7797,8 @@ def test_update_app_routing_profile(self):
web_app_routing=self.models.ManagedClusterIngressProfileWebAppRouting(
enabled=True,
dns_zone_resource_ids=[
"test_dns_zone_resource_id_3",
"test_dns_zone_resource_id_4",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/privateDnsZones/testdnszone_3.com",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/privateDnsZones/testdnszone_4.com",
],
)
),
Expand All @@ -7818,8 +7818,8 @@ def test_update_app_routing_profile(self):
web_app_routing=self.models.ManagedClusterIngressProfileWebAppRouting(
enabled=True,
dns_zone_resource_ids=[
"test_dns_zone_resource_id_1",
"test_dns_zone_resource_id_2",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_1.com",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_2.com",
],
)
),
Expand All @@ -7832,47 +7832,15 @@ def test_update_app_routing_profile(self):
web_app_routing=self.models.ManagedClusterIngressProfileWebAppRouting(
enabled=True,
dns_zone_resource_ids=[
"test_dns_zone_resource_id_1",
"test_dns_zone_resource_id_2",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_1.com",
"/subscriptions/testsub/resourceGroups/testrg/providers/Microsoft.Network/dnsZones/testdnszone_2.com",
],
)
),
)
self.assertEqual(dec_mc_7, ground_truth_mc_7)

def test_enable_disable_ai_toolchain_operator(self):
# Should not update mc if unset
dec_0 = AKSPreviewManagedClusterUpdateDecorator(
self.cmd,
self.client,
{},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_0 = self.models.ManagedCluster(
location="test_location",
)
dec_0.context.attach_mc(mc_0)
dec_mc_0 = dec_0.update_ai_toolchain_operator(mc_0)
ground_truth_mc_0 = self.models.ManagedCluster(
location="test_location",
)
self.assertEqual(dec_mc_0, ground_truth_mc_0)

# Should error if both set
dec_6 = AKSPreviewManagedClusterUpdateDecorator(
self.cmd,
self.client,
{"disable_ai_toolchain_operator": True, "enable_ai_toolchain_operator": True},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_6 = self.models.ManagedCluster(
location="test_location",
)
dec_6.context.attach_mc(mc_6)
with self.assertRaises(MutuallyExclusiveArgumentError):
dec_6.update_ai_toolchain_operator(mc_6)

# update app routing with key vault
# update app routing with key vault
from azure.cli.core.mock import DummyCli
from azure.cli.core.commands import AzCliCommand
from azure.cli.core import AzCommandsLoader
Expand Down Expand Up @@ -7931,6 +7899,38 @@ def test_enable_disable_ai_toolchain_operator(self):

self.assertEqual(dec_mc_8, ground_truth_mc_8)

def test_enable_disable_ai_toolchain_operator(self):
# Should not update mc if unset
dec_0 = AKSPreviewManagedClusterUpdateDecorator(
self.cmd,
self.client,
{},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_0 = self.models.ManagedCluster(
location="test_location",
)
dec_0.context.attach_mc(mc_0)
dec_mc_0 = dec_0.update_ai_toolchain_operator(mc_0)
ground_truth_mc_0 = self.models.ManagedCluster(
location="test_location",
)
self.assertEqual(dec_mc_0, ground_truth_mc_0)

# Should error if both set
dec_6 = AKSPreviewManagedClusterUpdateDecorator(
self.cmd,
self.client,
{"disable_ai_toolchain_operator": True, "enable_ai_toolchain_operator": True},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_6 = self.models.ManagedCluster(
location="test_location",
)
dec_6.context.attach_mc(mc_6)
with self.assertRaises(MutuallyExclusiveArgumentError):
dec_6.update_ai_toolchain_operator(mc_6)

def test_update_mc_profile_preview(self):
import inspect

Expand Down