From d8562e207f8c864e5113ef7d2109a0a187630dfe Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 11:31:19 +1000 Subject: [PATCH 1/8] update --- .../azext_aks_preview/_roleassignments.py | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_roleassignments.py b/src/aks-preview/azext_aks_preview/_roleassignments.py index e555f501971..f00d02f44ef 100644 --- a/src/aks-preview/azext_aks_preview/_roleassignments.py +++ b/src/aks-preview/azext_aks_preview/_roleassignments.py @@ -56,21 +56,30 @@ def _add_role_assignment_executor_new(cmd, role, assignee, resource_group_name=N mod="models", operation_group="role_assignments", ) - if cmd.supported_api_version(min_api="2018-01-01-preview", resource_type=ResourceType.MGMT_AUTHORIZATION): + from azure.cli.core import __version__ as core_version + if core_version >= "2.77.0": + # since 2.77.0, role assignment client swithched to single api version from multi api versions + # ref: https://github.com/Azure/azure-cli/pull/31859 parameters = RoleAssignmentCreateParameters(role_definition_id=role_id, principal_id=object_id, - principal_type=None) + principal_type=assignee_principal_type) return assignments_client.create(scope, assignment_name, parameters, headers=custom_headers) - - # for backward compatibility - RoleAssignmentProperties = get_sdk( - cmd.cli_ctx, - ResourceType.MGMT_AUTHORIZATION, - "RoleAssignmentProperties", - mod="models", - operation_group="role_assignments", - ) - properties = RoleAssignmentProperties(role_definition_id=role_id, principal_id=object_id) - return assignments_client.create(scope, assignment_name, properties, headers=custom_headers) + else: + # before 2.77.0, role assignment client used multi api versions + if cmd.supported_api_version(min_api="2018-01-01-preview", resource_type=ResourceType.MGMT_AUTHORIZATION): + parameters = RoleAssignmentCreateParameters(role_definition_id=role_id, principal_id=object_id, + principal_type=None) + return assignments_client.create(scope, assignment_name, parameters, headers=custom_headers) + + # for backward compatibility + RoleAssignmentProperties = get_sdk( + cmd.cli_ctx, + ResourceType.MGMT_AUTHORIZATION, + "RoleAssignmentProperties", + mod="models", + operation_group="role_assignments", + ) + properties = RoleAssignmentProperties(role_definition_id=role_id, principal_id=object_id) + return assignments_client.create(scope, assignment_name, properties, headers=custom_headers) # TODO(fuming): remove and replaced by import from azure.cli.command_modules.acs once dependency bumped to 2.47.0 @@ -92,7 +101,7 @@ def _add_role_assignment_new(cmd, role, service_principal_msi_id, is_service_pri ) break except HttpResponseError as ex: - if isinstance(ex, ResourceExistsError) or "The role assignment already exists." in ex.message: + if isinstance(ex, ResourceExistsError) or ex.error.code == 'RoleAssignmentExists': break logger.info(ex.message) except Exception as ex: # pylint: disable=broad-except From 608703a82d37d47a17c83851efc3d32d994d5225 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 11:36:50 +1000 Subject: [PATCH 2/8] update history --- src/aks-preview/HISTORY.rst | 4 ++++ src/aks-preview/setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/aks-preview/HISTORY.rst b/src/aks-preview/HISTORY.rst index d46e587af80..43cbc483e7c 100644 --- a/src/aks-preview/HISTORY.rst +++ b/src/aks-preview/HISTORY.rst @@ -13,6 +13,10 @@ Pending +++++++ * Add option `Flatcar` to `--os-sku` for `az aks nodepool add` and `az aks nodepool update`. +18.0.0b42 ++++++++ +* Fix role assignment failure when using azure-cli version >= `2.77.0`. + 18.0.0b41 +++++++ * Fix `--localdns-config` parameter to handle null values in JSON configuration files gracefully, preventing crashes when DNS override sections are null. diff --git a/src/aks-preview/setup.py b/src/aks-preview/setup.py index 242af1fbaf4..8139b2cb340 100644 --- a/src/aks-preview/setup.py +++ b/src/aks-preview/setup.py @@ -9,7 +9,7 @@ from setuptools import find_packages, setup -VERSION = "18.0.0b41" +VERSION = "18.0.0b42" CLASSIFIERS = [ "Development Status :: 4 - Beta", From 3365d75aeeb8e86fc1713900b989825fa1b7ce90 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 11:44:00 +1000 Subject: [PATCH 3/8] fix --- src/aks-preview/azext_aks_preview/_roleassignments.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_roleassignments.py b/src/aks-preview/azext_aks_preview/_roleassignments.py index f00d02f44ef..7ee30525e0a 100644 --- a/src/aks-preview/azext_aks_preview/_roleassignments.py +++ b/src/aks-preview/azext_aks_preview/_roleassignments.py @@ -6,6 +6,8 @@ import time import uuid +from packaging.version import Version + from azure.cli.command_modules.acs._client_factory import ( get_auth_management_client, ) @@ -57,8 +59,8 @@ def _add_role_assignment_executor_new(cmd, role, assignee, resource_group_name=N operation_group="role_assignments", ) from azure.cli.core import __version__ as core_version - if core_version >= "2.77.0": - # since 2.77.0, role assignment client swithched to single api version from multi api versions + if Version(core_version) >= Version("2.77.0"): + # since 2.77.0, role assignment client switched to single api version from multi api versions # ref: https://github.com/Azure/azure-cli/pull/31859 parameters = RoleAssignmentCreateParameters(role_definition_id=role_id, principal_id=object_id, principal_type=assignee_principal_type) From 2a41b55efcc96a246244ce4b22c75eaf589d0f0d Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 13:19:47 +1000 Subject: [PATCH 4/8] fix --- .../azext_aks_preview/_roleassignments.py | 130 +++--------------- 1 file changed, 20 insertions(+), 110 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_roleassignments.py b/src/aks-preview/azext_aks_preview/_roleassignments.py index 7ee30525e0a..c64432afad5 100644 --- a/src/aks-preview/azext_aks_preview/_roleassignments.py +++ b/src/aks-preview/azext_aks_preview/_roleassignments.py @@ -3,114 +3,24 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -import time -import uuid - -from packaging.version import Version - -from azure.cli.command_modules.acs._client_factory import ( - get_auth_management_client, -) -from azure.cli.command_modules.acs._graph import resolve_object_id -from azure.cli.command_modules.acs._roleassignments import build_role_scope, resolve_role_id -from azure.cli.core.azclierror import AzCLIError -from azure.cli.core.profiles import ResourceType, get_sdk -from azure.core.exceptions import HttpResponseError, ResourceExistsError -from knack.log import get_logger - -logger = get_logger(__name__) - -# pylint: disable=protected-access - - -# temp workaround for the breaking change caused by default API version bump of the auth SDK -def add_role_assignment(cmd, role, service_principal_msi_id, is_service_principal=True, delay=2, scope=None): - return _add_role_assignment_new(cmd, role, service_principal_msi_id, is_service_principal, delay, scope) - - -# TODO(fuming): remove and replaced by import from azure.cli.command_modules.acs once dependency bumped to 2.47.0 -def _add_role_assignment_executor_new(cmd, role, assignee, resource_group_name=None, scope=None, resolve_assignee=True): - factory = get_auth_management_client(cmd.cli_ctx, scope) - assignments_client = factory.role_assignments - definitions_client = factory.role_definitions - - # FIXME: is this necessary? - if assignments_client._config is None: - raise AzCLIError("Assignments client config is undefined.") - - scope = build_role_scope(resource_group_name, scope, assignments_client._config.subscription_id) - - # XXX: if role is uuid, this function's output cannot be used as role assignment defintion id - # ref: https://github.com/Azure/azure-cli/issues/2458 - role_id = resolve_role_id(role, scope, definitions_client) - - # If the cluster has service principal resolve the service principal client id to get the object id, - # if not use MSI object id. - object_id = resolve_object_id(cmd.cli_ctx, assignee) if resolve_assignee else assignee - - assignment_name = uuid.uuid4() - custom_headers = None - - RoleAssignmentCreateParameters = get_sdk( - cmd.cli_ctx, - ResourceType.MGMT_AUTHORIZATION, - "RoleAssignmentCreateParameters", - mod="models", - operation_group="role_assignments", +from azure.cli.command_modules.acs._roleassignments import add_role_assignment + + +def add_role_assignment( + cmd, + role, + service_principal_msi_id, + is_service_principal=True, + delay=2, + scope=None, + assignee_principal_type=None, +): + return add_role_assignment( + cmd, + role, + service_principal_msi_id, + is_service_principal, + delay, + scope, + assignee_principal_type, ) - from azure.cli.core import __version__ as core_version - if Version(core_version) >= Version("2.77.0"): - # since 2.77.0, role assignment client switched to single api version from multi api versions - # ref: https://github.com/Azure/azure-cli/pull/31859 - parameters = RoleAssignmentCreateParameters(role_definition_id=role_id, principal_id=object_id, - principal_type=assignee_principal_type) - return assignments_client.create(scope, assignment_name, parameters, headers=custom_headers) - else: - # before 2.77.0, role assignment client used multi api versions - if cmd.supported_api_version(min_api="2018-01-01-preview", resource_type=ResourceType.MGMT_AUTHORIZATION): - parameters = RoleAssignmentCreateParameters(role_definition_id=role_id, principal_id=object_id, - principal_type=None) - return assignments_client.create(scope, assignment_name, parameters, headers=custom_headers) - - # for backward compatibility - RoleAssignmentProperties = get_sdk( - cmd.cli_ctx, - ResourceType.MGMT_AUTHORIZATION, - "RoleAssignmentProperties", - mod="models", - operation_group="role_assignments", - ) - properties = RoleAssignmentProperties(role_definition_id=role_id, principal_id=object_id) - return assignments_client.create(scope, assignment_name, properties, headers=custom_headers) - - -# TODO(fuming): remove and replaced by import from azure.cli.command_modules.acs once dependency bumped to 2.47.0 -def _add_role_assignment_new(cmd, role, service_principal_msi_id, is_service_principal=True, delay=2, scope=None): - # AAD can have delays in propagating data, so sleep and retry - hook = cmd.cli_ctx.get_progress_controller(True) - hook.add(message="Waiting for AAD role to propagate", value=0, total_val=1.0) - logger.info("Waiting for AAD role to propagate") - for x in range(0, 10): - hook.add(message="Waiting for AAD role to propagate", value=0.1 * x, total_val=1.0) - try: - # TODO: break this out into a shared utility library - _add_role_assignment_executor_new( - cmd, - role, - service_principal_msi_id, - scope=scope, - resolve_assignee=is_service_principal, - ) - break - except HttpResponseError as ex: - if isinstance(ex, ResourceExistsError) or ex.error.code == 'RoleAssignmentExists': - break - logger.info(ex.message) - except Exception as ex: # pylint: disable=broad-except - logger.error(str(ex)) - time.sleep(delay + delay * x) - else: - return False - hook.add(message="AAD role propagation done", value=1.0, total_val=1.0) - logger.info("AAD role propagation done") - return True From 14a839d778d557398e03fafa95df897950af2a2b Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 13:28:38 +1000 Subject: [PATCH 5/8] fix --- .../azext_aks_preview/_roleassignments.py | 33 ++++++++++++++++--- .../managed_cluster_decorator.py | 6 ++-- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_roleassignments.py b/src/aks-preview/azext_aks_preview/_roleassignments.py index c64432afad5..79e2f267a13 100644 --- a/src/aks-preview/azext_aks_preview/_roleassignments.py +++ b/src/aks-preview/azext_aks_preview/_roleassignments.py @@ -3,7 +3,10 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from azure.cli.command_modules.acs._roleassignments import add_role_assignment +from azure.cli.command_modules.acs._roleassignments import ( + add_role_assignment, + add_role_assignment_executor, +) def add_role_assignment( @@ -19,8 +22,28 @@ def add_role_assignment( cmd, role, service_principal_msi_id, - is_service_principal, - delay, - scope, - assignee_principal_type, + is_service_principal=is_service_principal, + delay=delay, + scope=scope, + assignee_principal_type=assignee_principal_type, + ) + + +def add_role_assignment_executor( + cmd, + role, + assignee, + resource_group_name=None, + scope=None, + resolve_assignee=True, + assignee_principal_type=None, +): + return add_role_assignment_executor( + cmd, + role, + assignee, + resource_group_name=resource_group_name, + scope=scope, + resolve_assignee=resolve_assignee, + assignee_principal_type=assignee_principal_type, ) diff --git a/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py b/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py index 6d2b9875b35..48e2672709d 100644 --- a/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py +++ b/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py @@ -73,7 +73,7 @@ ) from azext_aks_preview._roleassignments import ( add_role_assignment, - _add_role_assignment_executor_new + add_role_assignment_executor ) from azext_aks_preview.agentpool_decorator import ( AKSPreviewAgentPoolAddDecorator, @@ -212,7 +212,7 @@ def external_functions(self) -> SimpleNamespace: ] = ensure_azure_monitor_profile_prerequisites # temp workaround for the breaking change caused by default API version bump of the auth SDK external_functions["add_role_assignment"] = add_role_assignment - external_functions["_add_role_assignment_executor_new"] = _add_role_assignment_executor_new + external_functions["add_role_assignment_executor"] = add_role_assignment_executor # azure container storage functions external_functions[ "perform_enable_azure_container_storage_v1" @@ -4227,7 +4227,7 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None: except Exception as e: # pylint: disable=broad-except logger.warning("Could not get signed in user: %s", str(e)) else: - self.context.external_functions._add_role_assignment_executor_new( # type: ignore # pylint: disable=protected-access + self.context.external_functions.add_role_assignment_executor( # type: ignore # pylint: disable=protected-access self.cmd, "Azure Kubernetes Service RBAC Cluster Admin", user["id"], From 361d7956a7bf137c0e16147836c17cd674e5fb48 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 14:54:15 +1000 Subject: [PATCH 6/8] fix --- .../azext_aks_preview/_roleassignments.py | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_roleassignments.py b/src/aks-preview/azext_aks_preview/_roleassignments.py index 79e2f267a13..a321ee5bf9c 100644 --- a/src/aks-preview/azext_aks_preview/_roleassignments.py +++ b/src/aks-preview/azext_aks_preview/_roleassignments.py @@ -7,43 +7,3 @@ add_role_assignment, add_role_assignment_executor, ) - - -def add_role_assignment( - cmd, - role, - service_principal_msi_id, - is_service_principal=True, - delay=2, - scope=None, - assignee_principal_type=None, -): - return add_role_assignment( - cmd, - role, - service_principal_msi_id, - is_service_principal=is_service_principal, - delay=delay, - scope=scope, - assignee_principal_type=assignee_principal_type, - ) - - -def add_role_assignment_executor( - cmd, - role, - assignee, - resource_group_name=None, - scope=None, - resolve_assignee=True, - assignee_principal_type=None, -): - return add_role_assignment_executor( - cmd, - role, - assignee, - resource_group_name=resource_group_name, - scope=scope, - resolve_assignee=resolve_assignee, - assignee_principal_type=assignee_principal_type, - ) From 751101a21dc600b5c7bef5b7f3777889493087c4 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 15:02:45 +1000 Subject: [PATCH 7/8] fix --- src/aks-preview/azext_aks_preview/_roleassignments.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aks-preview/azext_aks_preview/_roleassignments.py b/src/aks-preview/azext_aks_preview/_roleassignments.py index a321ee5bf9c..ec9161bc457 100644 --- a/src/aks-preview/azext_aks_preview/_roleassignments.py +++ b/src/aks-preview/azext_aks_preview/_roleassignments.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- +# pylint: disable=unused-import from azure.cli.command_modules.acs._roleassignments import ( add_role_assignment, add_role_assignment_executor, From 3c39b4464655bd8486115f0c7751e16bfebf0b52 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Fri, 3 Oct 2025 16:06:40 +1000 Subject: [PATCH 8/8] fix history --- src/aks-preview/HISTORY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aks-preview/HISTORY.rst b/src/aks-preview/HISTORY.rst index 43cbc483e7c..3968dbb79b1 100644 --- a/src/aks-preview/HISTORY.rst +++ b/src/aks-preview/HISTORY.rst @@ -11,11 +11,11 @@ To release a new version, please select a new version number (usually plus 1 to Pending +++++++ -* Add option `Flatcar` to `--os-sku` for `az aks nodepool add` and `az aks nodepool update`. 18.0.0b42 +++++++ * Fix role assignment failure when using azure-cli version >= `2.77.0`. +* Add option `Flatcar` to `--os-sku` for `az aks nodepool add` and `az aks nodepool update`. 18.0.0b41 +++++++