在 Azure Devops MS 代理上的 Python SDK 中使用 Azure CLI 2.30.0 凭据时,“无法从服务主体的本地缓存检索凭据”

Kai*_*ter 7 azure-sdk-python azure-pipelines

我在自托管代理上有一个 Azure Pipeline我使用此任务

      - task: AzureCLI@2
        displayName: Azure CLI task with Python SDK
        inputs:
          azureSubscription: 'SUBSCRIPTION-SERVICE-CONNECTION'
          scriptType: bash
          scriptLocation: inlineScript
          inlineScript: |
            python ./magic-script.py

Run Code Online (Sandbox Code Playgroud)

这样我就可以使用凭据来验证Azure Python SDK

client = get_client_from_cli_profile(GraphRbacManagementClient)
Run Code Online (Sandbox Code Playgroud)

当我将此过程转移到MS 托管代理时,我收到此错误:

  File "/opt/hostedtoolcache/Python/3.7.12/x64/lib/python3.7/site-packages/azure/common/client_factory.py", line 85, in get_client_from_cli_profile
    with_tenant=True,
  File "/opt/hostedtoolcache/Python/3.7.12/x64/lib/python3.7/site-packages/azure/common/credentials.py", line 98, in get_azure_cli_credentials
    cred, subscription_id, tenant_id = profile.get_login_credentials(resource=resource)
  File "/opt/hostedtoolcache/Python/3.7.12/x64/lib/python3.7/site-packages/azure/cli/core/_profile.py", line 335, in get_login_credentials
    credential = self._create_credential(account, client_id=client_id)
  File "/opt/hostedtoolcache/Python/3.7.12/x64/lib/python3.7/site-packages/azure/cli/core/_profile.py", line 592, in _create_credential
    return identity.get_service_principal_credential(username_or_sp_id)
  File "/opt/hostedtoolcache/Python/3.7.12/x64/lib/python3.7/site-packages/azure/cli/core/auth/identity.py", line 185, in get_service_principal_credential
    entry = self._msal_secret_store.load_entry(client_id, self.tenant_id)
  File "/opt/hostedtoolcache/Python/3.7.12/x64/lib/python3.7/site-packages/azure/cli/core/auth/identity.py", line 270, in load_entry
    .format(sp_id))
knack.util.CLIError: Could not retrieve credential from local cache for service principal ***. Run `az login` for this service principal.
Run Code Online (Sandbox Code Playgroud)

基于此迁移指南,我还尝试了AzureCliCredential,例如

credential = AzureCliCredential()
client = GraphRbacManagementClient(credential, os.environ["subscriptionId"])   
Run Code Online (Sandbox Code Playgroud)

这是我登录的脚本 - 但是使用时GraphRbacManagementClient我在我的开发盒和代理上本地收到此错误:

    root_group = [g for g in graph_client.groups.list(
  File "C:\Python38\lib\site-packages\msrest\paging.py", line 143, in __next__
    self.advance_page()
  File "C:\Python38\lib\site-packages\msrest\paging.py", line 129, in advance_page
    self._response = self._get_next(self.next_link)
  File "C:\Python38\lib\site-packages\azure\graphrbac\operations\groups_operations.py", line 336, in internal_paging
    response = self._client.send(request, stream=False, **operation_config)
  File "C:\Python38\lib\site-packages\msrest\service_client.py", line 336, in send
    pipeline_response = self.config.pipeline.run(request, **kwargs)
  File "C:\Python38\lib\site-packages\msrest\pipeline\__init__.py", line 197, in run
    return first_node.send(pipeline_request, **kwargs)  # type: ignore
  File "C:\Python38\lib\site-packages\msrest\pipeline\__init__.py", line 150, in send
    response = self.next.send(request, **kwargs)
  File "C:\Python38\lib\site-packages\msrest\pipeline\requests.py", line 65, in send
    self._creds.signed_session(session)
AttributeError: 'AzureCliCredential' object has no attribute 'signed_session'
Run Code Online (Sandbox Code Playgroud)

对于StorageManagementClient这个作品。似乎取决于所使用的 SDK 客户端。

Kai*_*ter 0

问题是由Azure CLI版本2.30.0引起的,该版本似乎最近推出了MS 托管代理

因此,我将在(MS 和自)托管代理上运行的所有Python脚本调整为该模型:

def get_graph_client(subscription_id):
    if "tenantId" in os.environ:
        print('using environment variables')
        config_dict = {
            "clientId": os.environ["servicePrincipalId"],
            "clientSecret": os.environ["servicePrincipalKey"],
            "subscriptionId": subscription_id,
            "tenantId": os.environ["tenantId"],
            "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
            "resourceManagerEndpointUrl": "https://management.azure.com/",
            "activeDirectoryGraphResourceId": "https://graph.windows.net/",
            "managementEndpointUrl": "https://management.core.windows.net/"
        }
        client = get_client_from_json_dict(
            GraphRbacManagementClient, config_dict)
    else:
        print('using CLI credentials')
        credential = AzureCliCredential()
        client = GraphRbacManagementClient(credential, subscription_id)        
    return client
Run Code Online (Sandbox Code Playgroud)

AttributeError: 'AzureCliCredential' object has no attribute 'signed_session'我在问题中显示的错误是由于依赖项损坏造成的。一旦清理了虚拟环境并安装了正确的依赖项,它就适用于所有Python Azure SDK客户端。

这允许我在两种模式下操作,使用Azure CLI凭据,并通过addSpnToEnvironment: true在相应的管道任务中进行设置来使用显式凭据:

      - task: AzureCLI@2
        displayName: Azure CLI task with Python SDK
        inputs:
          azureSubscription: 'SUBSCRIPTION-SERVICE-CONNECTION'
          scriptType: bash
          scriptLocation: inlineScript
          addSpnToEnvironment: true
          inlineScript: |
            python ./magic-script.py

Run Code Online (Sandbox Code Playgroud)