Skip to content

Commit 749e7b8

Browse files
Increase delay in role assignment creation (#9279)
* update delay * add polling * remove redundant logs * update api version
1 parent 07d7123 commit 749e7b8

File tree

8 files changed

+1355
-2698
lines changed

8 files changed

+1355
-2698
lines changed

src/fleet/HISTORY.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,8 @@ Release History
160160
++++++
161161
* Upgrade SDK version to 2025-08-01-preview
162162
* Add Fleet Managed Namespace support
163+
164+
165+
1.8.1
166+
++++++
167+
* Ensure role assignment is created for private fleets before fleet creation.

src/fleet/azext_fleet/_client_factory.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from azure.cli.core.commands.client_factory import get_mgmt_service_client
77
from azure.mgmt.msi import ManagedServiceIdentityClient
8+
from azure.mgmt.authorization import AuthorizationManagementClient
89
from azure.cli.core.profiles import (
910
CustomResourceType,
1011
ResourceType
@@ -60,5 +61,9 @@ def get_provider_client(cli_ctx):
6061
cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES)
6162

6263

64+
def get_role_assignments_client(cli_ctx):
65+
return get_mgmt_service_client(cli_ctx, AuthorizationManagementClient).role_assignments
66+
67+
6368
def get_msi_client(cli_ctx, subscription_id=None):
6469
return get_mgmt_service_client(cli_ctx, ManagedServiceIdentityClient, subscription_id=subscription_id)

src/fleet/azext_fleet/_helpers.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@
99
import stat
1010
import tempfile
1111
import yaml
12+
import time
1213

1314
from knack.log import get_logger
1415
from knack.prompting import NoTTYException, prompt_y_n
1516
from knack.util import CLIError
1617
from azure.cli.command_modules.acs._roleassignments import add_role_assignment
1718
from azure.mgmt.core.tools import parse_resource_id
18-
19+
from azext_fleet.constants import NETWORK_CONTRIBUTOR_ROLE_ID
1920

2021
from azext_fleet._client_factory import get_provider_client
2122
from azext_fleet._client_factory import get_msi_client
23+
from azext_fleet._client_factory import get_role_assignments_client
2224

2325
logger = get_logger(__name__)
2426

@@ -158,12 +160,35 @@ def _load_kubernetes_configuration(filename):
158160

159161
def assign_network_contributor_role_to_subnet(cmd, object_id, subnet_id):
160162
if not add_role_assignment(cmd, 'Network Contributor', object_id, scope=subnet_id):
161-
logger.warning("Failed to create Network Contributor role assignment on the subnet %s.\n"
162-
"This role assignment is required for the managed identity to access the subnet.\n"
163-
"Please ensure you have sufficient permissions, or ask an administrator to run:\n"
164-
"az role assignment create --assignee-principal-type ServicePrincipal --assignee-object-id %s "
165-
"--role 'Network Contributor' --scope %s",
166-
subnet_id, object_id, subnet_id)
163+
logger.warning(
164+
"Failed to create Network Contributor role assignment on the subnet %s.\n"
165+
"This role assignment is required for the managed identity to access the subnet.\n"
166+
"Please ensure you have sufficient permissions, or ask an administrator to run:\n"
167+
"az role assignment create --assignee-principal-type ServicePrincipal --assignee-object-id %s "
168+
"--role 'Network Contributor' --scope %s",
169+
subnet_id, object_id, subnet_id)
170+
return
171+
172+
auth_client = get_role_assignments_client(cmd.cli_ctx)
173+
max_attempts = 3
174+
interval = 3
175+
for _ in range(max_attempts):
176+
if _is_assignment_present(auth_client, subnet_id, object_id):
177+
return
178+
time.sleep(interval)
179+
logger.warning(
180+
"Role assignment for Network Contributor on subnet %s was not detected after %s seconds. "
181+
"There may be a delay in propagation.",
182+
subnet_id, max_attempts * interval)
183+
184+
185+
def _is_assignment_present(auth_client, subnet_id, object_id):
186+
filter_query = f"assignedTo('{object_id}') and atScope()"
187+
for assignment in auth_client.list_for_scope(subnet_id, filter=filter_query):
188+
if assignment.role_definition_id.lower().endswith(NETWORK_CONTRIBUTOR_ROLE_ID) and \
189+
assignment.scope.lower() == subnet_id.lower():
190+
return True
191+
return False
167192

168193

169194
def get_msi_object_id(cmd, msi_resource_id):

src/fleet/azext_fleet/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
UPGRADE_TYPE_FULL = "Full"
88
UPGRADE_TYPE_NODEIMAGEONLY = "NodeImageOnly"
99
FLEET_1P_APP_ID = "609d2f62-527f-4451-bfd2-ac2c7850822c"
10+
NETWORK_CONTRIBUTOR_ROLE_ID = "4d97b98b-1d4f-4787-a291-c67834d212e7"
1011

1112
SUPPORTED_GATE_STATES_FILTERS = ["Pending", "Skipped", "Completed"]
1213
SUPPORTED_GATE_STATES_PATCH = ["Completed"]

src/fleet/azext_fleet/custom.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from azure.cli.core.util import sdk_no_wait, get_file_json, shell_safe_json_parse
1515
from azure.cli.core import get_default_cli
1616
from azure.mgmt.core.tools import parse_resource_id
17+
from azure.cli.command_modules.acs._graph import resolve_object_id
1718

1819
from azext_fleet._client_factory import CUSTOM_MGMT_FLEET, cf_fleet_members, cf_fleets
1920
from azext_fleet._helpers import is_rp_registered, print_or_merge_credentials
@@ -134,7 +135,8 @@ def create_fleet(cmd,
134135
if not is_rp_registered(cmd):
135136
raise CLIError("The Microsoft.ContainerService resource provider is not registered."
136137
"Run `az provider register -n Microsoft.ContainerService --wait`.")
137-
assign_network_contributor_role_to_subnet(cmd, FLEET_1P_APP_ID, agent_subnet_id)
138+
object_id = resolve_object_id(cmd.cli_ctx, FLEET_1P_APP_ID)
139+
assign_network_contributor_role_to_subnet(cmd, object_id, agent_subnet_id)
138140

139141
if enable_vnet_integration and assign_identity is not None:
140142
object_id = get_msi_object_id(cmd, assign_identity)

src/fleet/azext_fleet/tests/latest/recordings/test_fleet_hubful.yaml

Lines changed: 735 additions & 2161 deletions
Large diffs are not rendered by default.

src/fleet/azext_fleet/tests/latest/recordings/test_fleet_hubless.yaml

Lines changed: 573 additions & 528 deletions
Large diffs are not rendered by default.

src/fleet/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
# TODO: Confirm this is the right version number you want and it matches your
1818
# HISTORY.rst entry.
19-
VERSION = '1.8.0'
19+
VERSION = '1.8.1'
2020

2121
# The full list of classifiers is available at
2222
# https://pypi.python.org/pypi?%3Aaction=list_classifiers

0 commit comments

Comments
 (0)