Repository: Azure/azure-cli-extensions

Issue:
ERROR: Could not grant Managed Identity Operator permission for cluster
### Extension name (the extension in question)
aks-preview

## Bug description
While running `az aks pod-identity --resource group $AKS_RG --cluster-name $AKS_NAME --namespace $NS --name $name --identity-resource-id /subscriptions/$SUBID/resourceGroups/$UAI_RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$IDENTITY_NAME ` on a cluster with configured with User-Assigned Managed Identity there is a check done to verify that the AKS Identity has "Managed Identity Operator" role on the Identity we want to include as pod identity. The issue is that it is not enough with having the role on the Resource group of the Identity ($UAI_RG) but you must have it specifically on the Identity resource $IDENTITY_NAME. 

This should be classified as a bug since a resource inherits from its resource group, but the script does take inheritance in account but instead requires the resource to have the role assignment.

### To reproduce:
- Existing AKS Cluster (v1.21.1) running with User-Assigned Managed Identity
- Identity (that you want to add as Pod Identity) created in separate resource group
- Run az aks pod-identity add command on AKS cluster 

### Workarounds:
1.  Assign "Managed Identity Operator" role specifically on resource $IDENTITY_NAME ($UAI_RG is not enough)
2. Assign "User Access Administrator" role for the AKS UAI on $UAI_RG, thus enabling AKS UAI to grant "Managed Identity Operator" role on the resource
-----




Discussion:
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @Azure/aks-pm.
<details>
<summary>Issue Details</summary>
<hr />

### Extension name (the extension in question)
aks-preview

## Bug description
While running `az aks pod-identity --resource group $AKS_RG --cluster-name $AKS_NAME --namespace $NS --name $name --identity-resource-id /subscriptions/$SUBID/resourceGroups/$UAI_RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$IDENTITY_NAME ` on a cluster with configured with User-Assigned Managed Identity there is a check done to verify that the AKS Identity has "Managed Identity Operator" role on the Identity we want to include as pod identity. The issue is that it is not enough with having the role on the Resource group of the Identity ($UAI_RG) but you must have it specifically on the Identity resource $IDENTITY_NAME. 

This should be classified as a bug since a resource inherits from its resource group, but the script does take inheritance in account but instead requires the resource to have the role assignment.

### To reproduce:
- Existing AKS Cluster (v1.21.1) running with User-Assigned Managed Identity
- Identity (that you want to add as Pod Identity) created in separate resource group
- Run az aks pod-identity add command on AKS cluster 

### Workarounds:
1.  Assign "Managed Identity Operator" role specifically on resource $IDENTITY_NAME ($UAI_RG is not enough)
2. Assign "User Access Administrator" role for the AKS UAI on $UAI_RG, thus enabling AKS UAI to grant "Managed Identity Operator" role on the resource
-----



<table>
  <tr>
    <th align="left">Author:</th>
    <td>felfa01</td>
  </tr>
  <tr>
    <th align="left">Assignees:</th>
    <td>-</td>
  </tr>
  <tr>
    <th align="left">Labels:</th>
    <td>

`AKS`, `Service Attention`, `extension/aks-preview`

</td>
  </tr>
  <tr>
    <th align="left">Milestone:</th>
    <td>-</td>
  </tr>
</table>
</details>
route to service team
I'm seeing a similar issue when creating an AKS cluster with a managed identity for both the control plane and the kubelet. I'm not trying to enable add-pods, but it seems it wants the control plane managed identity to have the operator role over the kubelet identity:

https://github.com/Azure/azure-cli-extensions/blob/cc860fcc385634fb8d503240f41922832d082ba8/src/aks-preview/azext_aks_preview/custom.py#L1368

```ps
az aks create `
    --resource-group ... `
    --name myManagedCluster `
    --enable-managed-identity `
    --assign-identity         /subscriptions/.../resourceGroups/.../providers/Microsoft.ManagedIdentity/userAssignedIdentities/some-managed-identity `
    --assign-kubelet-identity /subscriptions/.../resourceGroups/.../providers/Microsoft.ManagedIdentity/userAssignedIdentities/some-managed-identity

Waiting for AAD role to propagate[################################    ]  90.0000%
Could not grant Managed Identity Operator permission to cluster identity at scope /subscriptions/.../resourceGroups/.../providers/Microsoft.ManagedIdentity/userAssignedIdentities/some-managed-identity
```


But this identity is `Contributor` over the whole resource group, I thought it already should have it. Any thoughts?
@noamichael Seems to be similar to what I experienced, with the role assignment being expected to be on the specific resource rather than granted through inheritance (like it should for you given it is `Contributor`on the whole RG).

**Service team:** Any updates on this? My implemented work-around adds access requirements that I'd rather not grant at this specific level. 
Having the exact same issue, it still tries to do a role assignment even if the cluster identity has "Managed Identity Operator" on subscription level.

Is there a possibility to fix this, so `az aks pod-identity add`  can handle if we set "Managed Identity Operator" for the cluster identity on a Subscription/Resource group-level? 

Setting "Managed Identity Operator" on the specific identity to be used is not really feasible in my case
@bcho can you look into this?
Ack, this is because in the cli side, we listed only role assignments at identity level scope: https://github.com/Azure/azure-cli-extensions/blob/cc860fcc385634fb8d503240f41922832d082ba8/src/aks-preview/azext_aks_preview/custom.py#L4162 , where scope is the identity id). In this case we are unable to see the role assignments inherited from resource group / subscription.

I am working on a fix for this case, will post updates here.

cc @norshtein for the kubelet identity issue
The same issue for kubelet identity one. It is checking permission using identity resource ID as the scope, and cannot see the inherited permission. Will fix it..

Resolving patch:
diff --git a/src/aks-preview/azext_aks_preview/custom.py b/src/aks-preview/azext_aks_preview/custom.py
--- a/src/aks-preview/azext_aks_preview/custom.py
+++ b/src/aks-preview/azext_aks_preview/custom.py
@@ -4184,15 +4184,25 @@ def _ensure_managed_identity_operator_permission(cli_ctx, instance, scope):
 
     factory = get_auth_management_client(cli_ctx, scope)
     assignments_client = factory.role_assignments
+    cluster_identity_object_id = cluster_identity_object_id.lower()
+    scope = scope.lower()
 
-    for i in assignments_client.list_for_scope(scope=scope, filter='atScope()'):
-        if i.scope.lower() != scope.lower():
-            continue
+    # list all assignments of the target identity (scope) that assigned to the cluster identity
+    filter_query = "atScope() and assignedTo('{}')".format(cluster_identity_object_id)
+    for i in assignments_client.list_for_scope(scope=scope, filter=filter_query):
         if not i.role_definition_id.lower().endswith(CONST_MANAGED_IDENTITY_OPERATOR_ROLE_ID):
             continue
-        if i.principal_id.lower() != cluster_identity_object_id.lower():
+
+        # sanity checks to make sure we see the correct assignments
+        if i.principal_id.lower() != cluster_identity_object_id:
+            # assignedTo() should return the assignment to cluster identity
+            continue
+        if not scope.startswith(i.scope.lower()):
+            # atScope() should return the assignments in subscription / resource group / resource level
             continue
+
         # already assigned
+        logger.debug('Managed Identity Opereator role has been assigned to {}'.format(i.scope))
         return
 
     if not _add_role_assignment(cli_ctx, CONST_MANAGED_IDENTITY_OPERATOR_ROLE, cluster_identity_object_id,


Test patch: