问题描述
对于我的 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()
方法:
解决方法
如果您想查看与一项资源相关联的那些策略的状态,请参考以下代码。
注意:这是第 1 版 API,不是当前第 2 版 API,并且此代码仍处于测试阶段。
开发工具包
<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"));
}