|
16 | 16 | from knack.util import CLIError |
17 | 17 | from azure.cli.command_modules.acs._roleassignments import add_role_assignment |
18 | 18 | from azure.mgmt.core.tools import parse_resource_id |
19 | | - |
| 19 | +from azext_fleet.constants import NETWORK_CONTRIBUTOR_ROLE_ID |
20 | 20 |
|
21 | 21 | from azext_fleet._client_factory import get_provider_client |
22 | 22 | from azext_fleet._client_factory import get_msi_client |
| 23 | +from azext_fleet._client_factory import get_role_assignments_client |
23 | 24 |
|
24 | 25 | logger = get_logger(__name__) |
25 | 26 |
|
@@ -159,13 +160,38 @@ def _load_kubernetes_configuration(filename): |
159 | 160 |
|
160 | 161 | def assign_network_contributor_role_to_subnet(cmd, object_id, subnet_id): |
161 | 162 | if not add_role_assignment(cmd, 'Network Contributor', object_id, scope=subnet_id): |
162 | | - logger.warning("Failed to create Network Contributor role assignment on the subnet %s.\n" |
163 | | - "This role assignment is required for the managed identity to access the subnet.\n" |
164 | | - "Please ensure you have sufficient permissions, or ask an administrator to run:\n" |
165 | | - "az role assignment create --assignee-principal-type ServicePrincipal --assignee-object-id %s " |
166 | | - "--role 'Network Contributor' --scope %s", |
167 | | - subnet_id, object_id, subnet_id) |
168 | | - time.sleep(3) |
| 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 | + logger.warning("Role assignment for Network Contributor on subnet %s was detected.", subnet_id) |
| 178 | + return |
| 179 | + time.sleep(interval) |
| 180 | + logger.warning( |
| 181 | + "Role assignment for Network Contributor on subnet %s was not detected after %s seconds. " |
| 182 | + "There may be a delay in propagation.", |
| 183 | + subnet_id, max_attempts * interval) |
| 184 | + |
| 185 | + |
| 186 | +def _is_assignment_present(auth_client, subnet_id, object_id): |
| 187 | + filter_query = f"assignedTo('{object_id}') and atScope()" |
| 188 | + for assignment in auth_client.list_for_scope(subnet_id, filter=filter_query): |
| 189 | + if assignment.role_definition_id.lower().endswith(NETWORK_CONTRIBUTOR_ROLE_ID) and \ |
| 190 | + assignment.scope.lower() == subnet_id.lower(): |
| 191 | + return True |
| 192 | + logger.warning("No matching role assignment found for scope %s and subnet %s", |
| 193 | + assignment.scope.lower(), subnet_id.lower()) |
| 194 | + return False |
169 | 195 |
|
170 | 196 |
|
171 | 197 | def get_msi_object_id(cmd, msi_resource_id): |
|
0 commit comments