@@ -147,7 +147,7 @@ def create_role_assignment(cmd, role, assignee=None, assignee_object_id=None, re
147147 raise CLIError ('usage error: --assignee STRING | --assignee-object-id GUID' )
148148
149149 if assignee_principal_type and not assignee_object_id :
150- raise CLIError ('usage error: --assignee-object-id GUID [ --assignee-principal-type] ' )
150+ raise CLIError ('usage error: --assignee-object-id GUID --assignee-principal-type TYPE ' )
151151
152152 # If condition is set and condition-version is empty, condition-version defaults to "2.0".
153153 if condition and not condition_version :
@@ -157,8 +157,18 @@ def create_role_assignment(cmd, role, assignee=None, assignee_object_id=None, re
157157 if condition_version and not condition :
158158 raise CLIError ('usage error: When --condition-version is set, --condition must be set as well.' )
159159
160- object_id , principal_type = _resolve_assignee_object (cmd .cli_ctx , assignee , assignee_object_id ,
161- assignee_principal_type )
160+ if assignee :
161+ object_id , principal_type = _resolve_object_id_and_type (cmd .cli_ctx , assignee , fallback_to_object_id = True )
162+ else :
163+ object_id = assignee_object_id
164+ if assignee_principal_type :
165+ # If principal type is provided, nothing to resolve, do not call Graph
166+ principal_type = assignee_principal_type
167+ else :
168+ # Try best to get principal type
169+ logger .warning ('RBAC service might reject creating role assignment without --assignee-principal-type '
170+ 'in the future. Better to specify --assignee-principal-type manually.' )
171+ principal_type = _get_principal_type_from_object_id (cmd .cli_ctx , assignee_object_id )
162172
163173 try :
164174 return _create_role_assignment (cmd .cli_ctx , role , object_id , resource_group_name , scope , resolve_assignee = False ,
@@ -1766,46 +1776,24 @@ def _encode_custom_key_description(key_description):
17661776 return key_description .encode ('utf-16' )
17671777
17681778
1769- def _resolve_assignee_object (cli_ctx , assignee , assignee_object_id , assignee_principal_type ):
1779+ def _get_principal_type_from_object_id (cli_ctx , assignee_object_id ):
17701780 client = _graph_client_factory (cli_ctx )
1771- result = None
1772-
1773- # resolve assignee (same as _resolve_object_id)
1774- if assignee :
1775- if assignee .find ('@' ) >= 0 : # looks like a user principal name
1776- result = list (client .users .list (filter = "userPrincipalName eq '{}'" .format (assignee )))
1777- if not result :
1778- result = list (client .service_principals .list (
1779- filter = "servicePrincipalNames/any(c:c eq '{}')" .format (assignee )))
1780- if not result and is_guid (assignee ): # assume an object id, let us verify it
1781- result = _get_object_stubs (client , [assignee ])
1782-
1783- # 2+ matches should never happen, so we only check 'no match' here
1784- if not result :
1785- raise CLIError ("Cannot find user or service principal in graph database for '{assignee}'. "
1786- "If the assignee is an appId, make sure the corresponding service principal is created "
1787- "with 'az ad sp create --id {assignee}'." .format (assignee = assignee ))
1788-
1789- return result [0 ].object_id , result [0 ].object_type
1790-
1791- # try to resolve assignee object id
17921781 try :
17931782 result = _get_object_stubs (client , [assignee_object_id ])
17941783 if result :
1795- return result [0 ].object_id , result [ 0 ]. object_type
1784+ return result [0 ].object_type
17961785 except CloudError :
1797- pass
1798-
1799- # If failed to verify assignee object id, DO NOT raise exception
1800- # since --assignee-object-id is exposed to bypass Graph API
1801- if not assignee_principal_type :
1802- logger .warning ('Failed to query --assignee-principal-type for %s by invoking Graph API.\n '
1803- 'RBAC server might reject creating role assignment without --assignee-principal-type '
1804- 'in the future. Better to specify --assignee-principal-type manually.' , assignee_object_id )
1805- return assignee_object_id , assignee_principal_type
1786+ logger .warning ('Failed to query --assignee-principal-type for --assignee-object-id %s by invoking Graph API.' ,
1787+ assignee_object_id )
1788+ return None
18061789
18071790
18081791def _resolve_object_id (cli_ctx , assignee , fallback_to_object_id = False ):
1792+ object_id , _ = _resolve_object_id_and_type (cli_ctx , assignee , fallback_to_object_id = fallback_to_object_id )
1793+ return object_id
1794+
1795+
1796+ def _resolve_object_id_and_type (cli_ctx , assignee , fallback_to_object_id = False ):
18091797 client = _graph_client_factory (cli_ctx )
18101798 result = None
18111799 try :
@@ -1823,10 +1811,14 @@ def _resolve_object_id(cli_ctx, assignee, fallback_to_object_id=False):
18231811 "If the assignee is an appId, make sure the corresponding service principal is created "
18241812 "with 'az ad sp create --id {assignee}'." .format (assignee = assignee ))
18251813
1826- return result [0 ].object_id
1814+ return result [0 ].object_id , result [ 0 ]. object_type
18271815 except (CloudError , GraphErrorException ):
1816+ logger .warning ('Failed to query %s by invoking Graph API. '
1817+ 'If you don\' t have permission to query Graph API, please '
1818+ 'specify --assignee-object-id and --assignee-principal-type.' , assignee )
18281819 if fallback_to_object_id and is_guid (assignee ):
1829- return assignee
1820+ logger .warning ('Assuming %s as an object ID.' , assignee )
1821+ return assignee , None
18301822 raise
18311823
18321824
0 commit comments