是否可以从 Azure Python SDK 获取 ASC 位置?

Is it possible to get the ASC location from the Azure Python SDK?

我正在使用 Microsoft Azure Security Center (ASC) Management Client Library 获取订阅的安全分数。库中的所有操作状态

You should not instantiate directly this class, but create a Client instance that will create it for you and attach it as attribute.

因此,我正在创建一个具有以下规范的 SecurityCenter 客户端:

SecurityCenter(credentials, subscription_id, asc_location, base_url=None)

但是,在我看来,正确获取 asc_location 信息的唯一方法是使用 SecurityCenter 客户端获取它... The spec 与上面的引用相同, You should not instantiate...。所以我无法创建客户端,因为我需要 ASC 位置才能这样做,我需要创建客户端来获取 ASC 位置。

文档提到

The location where ASC stores the data of the subscription. can be retrieved from Get locations

在 Python SDK 文档中谷歌搜索并搜索此“获取位置”没有任何结果(除了 REST API)。我错过了什么吗?我们是否应该像 SDK 存储库中的 or this GitHub issue 那样对位置进行硬编码?

作为官方 API 参考 list locations 表示:

The location of the responsible ASC of the specific subscription (home region). For each subscription there is only one responsible location.

它不会改变,所以如果您已经知道订阅的 asc_location 的值,您可以硬编码这个值。

但每个订阅可能有不同的 asc_location 值(我的 2 个 Azure 订阅有不同的 asc_location 值)。 所以如果你有很多 Azure 订阅,你可以通过 API 查询 asc_location据我所知,这是我能找到的唯一方法)然后使用SDK获取安全分数,试试下面的代码:

from azure.mgmt.security import SecurityCenter
from azure.identity import ClientSecretCredential
import requests
from requests.api import head, request 

TENANT_ID = ''
CLIENT = ''
KEY = ''
subscription_id= ''
getLocationsURL = "https://management.azure.com/subscriptions/"+subscription_id+"/providers/Microsoft.Security/locations?api-version=2015-06-01-preview"


credentials = ClientSecretCredential(
    client_id = CLIENT,
    client_secret = KEY,
    tenant_id = TENANT_ID
)

#request for asc_location for a subscription
azure_access_token = credentials.get_token('https://management.azure.com/.default')
r = requests.get(getLocationsURL,headers={"Authorization":"Bearer " +  azure_access_token.token}).json()
location = r['value'][0]['name']
print("location:" + location)

client = SecurityCenter(credentials, subscription_id, asc_location=location)
for score in client.secure_scores.list():
    print(score)

结果:

我最近遇到了这个问题。

根据我的观察,我可以使用订阅下的任何位置来启动 SecurityCenter 客户端。然后 client.locations.list() 正好给我一个 ASC 位置。

# Any of SubscriptionClient.subscriptions.list_locations will do
location = 'eastasia'

client = SecurityCenter(
            credential, my_subscription_id,
            asc_location=location
        )

data = client.locations.list().next().as_dict()
pprint(f"Asc location: {data}")

在我的例子中,无论我的输入是 eastasia.

,它总是 westcentralus

请注意,如果您使用 get 而不是 list

,则会出现异常
data = client.locations.get().as_dict()
pprint(f"Asc location: {data}")
# azure.core.exceptions.ResourceNotFoundError: (ResourceNotFound) Could not find location 'eastasia'

所以我做的有点尴尬,

  1. 使用我订阅下的位置创建一个 SecurityCenter 客户端
  2. client.locations.list() 获取 ASC 位置
  3. 使用检索到的 ASC 位置再次创建 SecurityCenter 客户端。

我最近也 运行 喜欢这个,最初做了一些基于 @stanley-gong's answer. But it felt a bit awkward, and I checked to see how the Azure CLI does it 的事情。我注意到他们硬编码了 asc_location:

的值
def _cf_security(cli_ctx, **_):
    from azure.cli.core.commands.client_factory import get_mgmt_service_client
    from azure.mgmt.security import SecurityCenter


    return get_mgmt_service_client(cli_ctx, SecurityCenter, asc_location="centralus")

以及实现 provides some more context 的 PR:

we have a task to remove the asc_location from the initialization of the clients. currently we hide the asc_location usage from the user. centralus is a just arbitrary value and is our most common region.

所以...也许 double-initializing 客户的舞蹈或拉动订阅的本地区域没有给我们买任何东西?