如何列出与我的 Azure 资源关联的策略?

How can I list the policies associated with my Azure resources?

对于我的 Azure 帐户中的每个资源,我想列出一些关于它的基本信息,然后找到与之关联的策略。使用 Azure 的 Java SDK,这是我目前所拥有的:

AzureResourceManager azureResourceManager = AzureResourceManager
        .authenticate(credential, profile)
        .withSubscription("<my-subscription-id>");

for(GenericResource resource : azureResourceManager.genericResources().list())
{
    System.out.println("Resource Name: " + resource.name());
    System.out.println("Resource ID: " + resource.id()); 
    PagedIterable<PolicyAssignment> policiesAssignmentsForThisResource = azureResourceManager.policyAssignments().listByResource(resource.id());
    for(PolicyAssignment policyAssignment : policiesAssignmentsForThisResource)
    {
        System.out.println("Policy Assignment Display Name: " + policyAssignment.displayName());
    }
}

这将列出资源名称和 ID,但在尝试遍历策略分配时,会抛出此错误:

IllegalArgumentException: Parameter parentResourcePath is required and cannot be null.

有没有办法解决这个错误?有没有更好的方法来查找资源的策略?

这是我正在使用的 listByResource() 方法:

https://docs.microsoft.com/en-us/java/api/com.azure.resourcemanager.resources.models.policyassignments.listbyresource?view=azure-java-stable

如果您想查看与某个资源关联的这些策略的状态,请参考以下代码。

注意:这是版本 1 API,不是当前版本 2 API,此代码仍处于测试阶段。

SDK

  <dependency>
      <groupId>com.microsoft.azure.policyinsights.v2019_10_01</groupId>
      <artifactId>azure-mgmt-policyinsights</artifactId>
      <version>1.0.0-beta-2</version>
    </dependency>

代码


        ApplicationTokenCredentials credentials = new ApplicationTokenCredentials(clientId,
                tenant,
                clientSecret,
                AzureEnvironment.AZURE);


       RestClient restClient=  new RestClient.Builder()
                .withBaseUrl(credentials.environment(), AzureEnvironment.Endpoint.RESOURCE_MANAGER)
                .withCredentials(credentials)
               .withSerializerAdapter( new AzureJacksonAdapter())
                .withResponseBuilderFactory(new AzureResponseBuilder.Factory())
                .build();

        PolicyInsightsClientImpl policyInsightsClient = new PolicyInsightsClientImpl(restClient);
        PagedList<PolicyStateInner> policys = policyInsightsClient.policyStates().listQueryResultsForResource(
                PolicyStatesResource.DEFAULT,
                "/subscriptions/e5b0fcfa-e859-43f3-8d84-5e5fe29f4c68/resourceGroups/andywin7"
        );
        for(PolicyStateInner policy : policys){
              System.out.println(policy.complianceState());

        }

由于我不想使用仍处于测试阶段的 v1 API,而 v2 API 还没有此功能,我选择使用 REST API 代替。我用 OkHttpClient 来处理繁重的工作。这是我的解决方案,我在其中使用资源 ID 获取资源的策略状态:

OkHttpClient policyStateHttpClient = new OkHttpClient();
String policyStateUrl = "https://management.azure.com" 
        + resource.getString("id") // This is the resource ID that I have...
        + "/providers/Microsoft.PolicyInsights/policyStates/latest/queryResults?api-version=2019-10-01";

// It's empty b/c it's a POST without a body.  Yes, it's dumb.
RequestBody policyStateRequestBody = RequestBody.create("", null); 
Request policyStateRequest = new Request.Builder()
        .url(policyStateUrl)
        .addHeader("Authorization", "Bearer " + token)
        .post(policyStateRequestBody)
        .build();

String policyStateJson = "";
try
{
    Response policyStateResponse = policyStateHttpClient.newCall(policyStateRequest).execute();
    policyStateJson = policyStateResponse.body().string();
    if (!policyStateResponse.isSuccessful())
    {
        System.out.println("ERROR: Unable to get the policy states for this resource (" + resource.getString("name") + ").");
        System.out.println(" Reason for error: ");
        System.out.println("  " + policyStateJson);
        return;
    }
}
catch (SocketTimeoutException ste)
{
    System.out.println("ERROR: Unable to get the policy states for this resource (" + resource.getString("name") + ").");
    System.out.println(" The reason is that it timed out.  Azure does this a lot.  If you re-run the app, it will likely fix itself.");
    return;
}
catch (IOException ioe)
{
    ioe.printStackTrace();   // TODO Handle this...
}
JSONObject policyStateRootObject = new JSONObject(policyStateJson);
JSONArray policyStates = policyStateRootObject.getJSONArray("value");
for (int j = 0; j < policyStates.length(); j++) 
{
    JSONObject policyState = policyStates.getJSONObject(j);
    // Do something with the JSON
    System.out.println(policyState.getString("policyDefinitionName"));
    System.out.println(policyState.getString("policyDefinitionId"));
    System.out.println(policyState.getString("complianceState"));
}