Azure Python SDK: объект ‘ServicePrincipalCredentials’ не имеет атрибута ‘get_token’

#python #python-3.x #azure #azure-virtual-machine #azure-sdk-python

#python #python-3.x #azure #azure-виртуальная машина #azure-sdk-python

Вопрос:

Итак, у меня есть следующий скрипт Python3 для перечисления всех виртуальных машин.

 import os, json
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.resource import ResourceManagementClient, SubscriptionClient
from azure.common.credentials import ServicePrincipalCredentials

credentials = ServicePrincipalCredentials(
        client_id="xxx",
        secret="xxx",
        tenant="xxx"
        )

resource_client = ResourceManagementClient(credentials, "my-subscription")
compute_client = ComputeManagementClient(credentials, "my-subscription")
network_client = NetworkManagementClient(credentials, "my-subscription")

for vm in compute_client.virtual_machines.list_all():
    print("tVM: {}".format(vm.name))
  

но по какой-то причине я получаю следующую ошибку:

 Traceback (most recent call last):
  File "/Users/me/a/azure-test.py", line 17, in <module>
    for vm in compute_client.virtual_machines.list_all():
...
  File "/usr/local/lib/python3.8/site-packages/azure/core/pipeline/policies/_authentication.py", line 93, in on_request
    self._token = self._credential.get_token(*self._scopes)
AttributeError: 'ServicePrincipalCredentials' object has no attribute 'get_token'
  

Я делаю что-то не так?

Ответ №1:

Библиотеки Azure для Python в настоящее время обновляются для совместного использования общих облачных шаблонов, таких как протоколы аутентификации, ведение журнала, трассировка, транспортные протоколы, буферизованные ответы и повторные попытки.

Это также немного изменило бы механизм аутентификации. В более старой версии ServicePrincipalCredentials in azure.common использовался для аутентификации в Azure и создания клиента службы.

В более новой версии механизм аутентификации был переработан и заменен на azure-identity library, чтобы обеспечить унифицированную аутентификацию на основе Azure Identity для всех Azure SDK. Запустите pip install azure-identity , чтобы получить пакет.

С точки зрения кода, что тогда было:

 from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.compute import ComputeManagementClient

credentials = ServicePrincipalCredentials(
    client_id='xxxxx',
    secret='xxxxx',
    tenant='xxxxx'
)

compute_client = ComputeManagementClient(
    credentials=credentials,
    subscription_id=SUBSCRIPTION_ID
)
  

теперь:

 from azure.identity import ClientSecretCredential
from azure.mgmt.compute import ComputeManagementClient

credential = ClientSecretCredential(
    tenant_id='xxxxx',
    client_id='xxxxx',
    client_secret='xxxxx'
)

compute_client = ComputeManagementClient(
    credential=credential,
    subscription_id=SUBSCRIPTION_ID
)
  

Затем вы можете использовать list_all метод with compute_client для перечисления всех виртуальных машин, как обычно:

 # List all Virtual Machines in the specified subscription
def list_virtual_machines():
    for vm in compute_client.virtual_machines.list_all():
        print(vm.name)

list_virtual_machines()
  

Ссылки:

Ответ №2:

В случае Azure sovereign cloud (AZURE_PUBLIC_CLOUD, AZURE_CHINA_CLOUD, AZURE_US_GOV_CLOUD, AZURE_GERMANAN_CLOUD) принятый ответ будет распространяться на приведенный ниже фрагмент кода.

 from azure.identity import ClientSecretCredential
from azure.mgmt.compute import ComputeManagementClient
from msrestazure.azure_cloud import AZURE_US_GOV_CLOUD as cloud_env

credential = ClientSecretCredential(
    tenant_id='xxxxx',
    client_id='xxxxx',
    client_secret='xxxxx',
    authority=cloud_env.endpoints.active_directory
)

compute_client = ComputeManagementClient(
    credential=credential,
    subscription_id=SUBSCRIPTION_ID
    base_url=cloud_env.endpoints.resource_manager,
    credential_scopes=[cloud_env.endpoints.resource_manager   ".default"]
)
  

Комментарии:

1. Спасибо, что указали на это! Это спасло мой день, но credential_scopes его необходимо исправить. Он должен быть с косой чертой в конце: credential_scopes=[cloud_env.endpoints.resource_manager "/.default"] в противном случае я получил: «azure.core.exceptions. Ошибка ClientAuthenticationError: ошибка аутентификации: AADSTS70011: предоставленный запрос должен включать входной параметр ‘scope’. Указанное значение для входного параметра ‘scope’ недопустимо «.