Skip to content

Commit ab707ce

Browse files
committed
Enhance principal type detection and fallback handling in workspace admin management
1 parent 19df38b commit ab707ce

1 file changed

Lines changed: 69 additions & 27 deletions

File tree

infra/scripts/fabric/fabric_workspace_admins.py

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ def detect_principal_type(admin_identifier, graph_client=None):
7070
return principal_type, object_id, principal_data
7171

7272
except GraphApiError as e:
73-
# Convert Graph API errors to ValueError for backward compatibility
74-
raise ValueError(f"Unable to resolve principal '{admin_identifier}': {str(e)}")
73+
# Convert Graph API errors to Unknown type for fallback handling
74+
print(f" ⚠️ WARNING: Graph API lookup failed for '{admin_identifier}': {str(e)}")
75+
print(f" Will try both ServicePrincipal and User types...")
76+
return "Unknown", admin_identifier, {"id": admin_identifier, "displayName": "Unknown"}
7577
except Exception as e:
7678
# Fallback to original logic if Graph API is not available
7779
print(f" ⚠️ WARNING: Graph API lookup failed for '{admin_identifier}': {str(e)}")
@@ -82,8 +84,8 @@ def detect_principal_type(admin_identifier, graph_client=None):
8284
elif "@" in admin_identifier and "." in admin_identifier:
8385
return "User", admin_identifier, {"userPrincipalName": admin_identifier, "displayName": "Unknown"}
8486
else:
85-
raise ValueError(
86-
f"Unable to determine if '{admin_identifier}' is a user UPN or service principal GUID")
87+
print(f" Unable to determine principal type - will try both ServicePrincipal and User...")
88+
return "Unknown", admin_identifier, {"id": admin_identifier, "displayName": "Unknown"}
8789

8890
def get_existing_admin_principals(workspace_client):
8991
"""Get set of existing admin principal IDs for duplicate checking."""
@@ -133,30 +135,70 @@ def add_workspace_admin(workspace_client, admin_identifier, existing_principals,
133135
return {'status': 'skipped', 'message': 'Already exists (by object ID)'}
134136

135137
display_name = principal_data.get('displayName', 'Unknown')
136-
print(f" 🔐 Adding {principal_type.lower()} administrator: {admin_identifier} ({display_name})")
137-
138-
# Add role assignment based on type
139-
if principal_type == "User":
140-
workspace_client.add_role_assignment(
141-
principal_id=object_id,
142-
principal_type=principal_type,
143-
role="Admin",
144-
display_name=display_name,
145-
user_principal_name=principal_data.get('userPrincipalName', admin_identifier)
146-
)
147-
else: # ServicePrincipal
148-
workspace_client.add_role_assignment(
149-
principal_id=object_id,
150-
principal_type=principal_type,
151-
role="Admin",
152-
display_name=display_name,
153-
aad_app_id=principal_data.get('appId')
154-
)
155138

156-
print(f" ✅ Successfully added '{admin_identifier}' as workspace administrator")
157-
existing_principals.add(object_id.lower())
158-
existing_principals.add(admin_identifier.lower())
159-
return {'status': 'success', 'message': 'Added successfully'}
139+
# Handle unknown principal type by trying both ServicePrincipal and User
140+
if principal_type == "Unknown":
141+
print(f" 🔐 Trying to add administrator (type unknown): {admin_identifier} ({display_name})")
142+
143+
# Try ServicePrincipal first
144+
try:
145+
print(f" 🔄 Attempting as ServicePrincipal...")
146+
workspace_client.add_role_assignment(
147+
principal_id=object_id,
148+
principal_type="ServicePrincipal",
149+
role="Admin",
150+
display_name=display_name,
151+
aad_app_id=principal_data.get('appId')
152+
)
153+
print(f" ✅ Successfully added '{admin_identifier}' as ServicePrincipal administrator")
154+
existing_principals.add(object_id.lower())
155+
existing_principals.add(admin_identifier.lower())
156+
return {'status': 'success', 'message': 'Added successfully as ServicePrincipal'}
157+
except Exception as sp_error:
158+
print(f" ❌ ServicePrincipal attempt failed: {str(sp_error)}")
159+
160+
# Try User as fallback
161+
try:
162+
print(f" 🔄 Attempting as User...")
163+
workspace_client.add_role_assignment(
164+
principal_id=object_id,
165+
principal_type="User",
166+
role="Admin",
167+
display_name=display_name,
168+
user_principal_name=principal_data.get('userPrincipalName', admin_identifier)
169+
)
170+
print(f" ✅ Successfully added '{admin_identifier}' as User administrator")
171+
existing_principals.add(object_id.lower())
172+
existing_principals.add(admin_identifier.lower())
173+
return {'status': 'success', 'message': 'Added successfully as User'}
174+
except Exception as user_error:
175+
print(f" ❌ User attempt also failed: {str(user_error)}")
176+
return {'status': 'failed', 'message': f'Failed as both ServicePrincipal and User: SP({str(sp_error)}), User({str(user_error)})'}
177+
else:
178+
print(f" 🔐 Adding {principal_type.lower()} administrator: {admin_identifier} ({display_name})")
179+
180+
# Add role assignment based on type
181+
if principal_type == "User":
182+
workspace_client.add_role_assignment(
183+
principal_id=object_id,
184+
principal_type=principal_type,
185+
role="Admin",
186+
display_name=display_name,
187+
user_principal_name=principal_data.get('userPrincipalName', admin_identifier)
188+
)
189+
else: # ServicePrincipal
190+
workspace_client.add_role_assignment(
191+
principal_id=object_id,
192+
principal_type=principal_type,
193+
role="Admin",
194+
display_name=display_name,
195+
aad_app_id=principal_data.get('appId')
196+
)
197+
198+
print(f" ✅ Successfully added '{admin_identifier}' as workspace administrator")
199+
existing_principals.add(object_id.lower())
200+
existing_principals.add(admin_identifier.lower())
201+
return {'status': 'success', 'message': 'Added successfully'}
160202

161203
except (ValueError, GraphApiError) as e:
162204
return {'status': 'failed', 'message': f'Principal type detection failed: {str(e)}'}

0 commit comments

Comments
 (0)