问题描述
Azure 的策略服务带有许多内置策略。可以使用 Azure 的 Java SDK 和 Azure 资源管理器访问它们。可以使用 getByName()
method in the SDK 获取特定策略的定义。
代码如下:
AzureResourceManager azureResourceManager = AzureResourceManager
.authenticate(credential,profile)
.withSubscription("<my-subscription-id>");
PolicyDeFinition policyDeFinition = azureResourceManager.policyDeFinitions().getByName("<name>");
为了测试这段代码,我去控制台寻找一个预建策略的名称。我找到了两个不同的名字,一个在文中:
和定义中的不同:
但是,尝试使用这些名称中的任何一个检索策略定义会导致相同的错误:
Status code 404,The policy deFinition 'Audit VMs that do not use managed disks' Could not be found.
和
Status code 404,The policy deFinition '06a78e20-9358-41c9-923c-fb736d382a4d' Could not be found
问题:这个方法要找什么名字?或者有没有更好的方法来检索策略定义?
解决方法
如果你想在java应用中获得一个build_in policy,你可以使用包PolicyClientImpl.getPolicyDefinitions().getBuiltIn()
中的方法com.azure.resourcemanager.resources
。此外,请注意,内置策略的名称是指南。
例如
- 安装SDK
<dependency>
<groupId>com.azure.resourcemanager</groupId>
<artifactId>azure-resourcemanager-resources</artifactId>
<version>2.1.0</version>
</dependency>
- 代码
String clientId="";
String clientSecret="";
String tenant="";
String subId="";
AzureProfile profile = new AzureProfile(tenant,subId,AzureEnvironment.AZURE);
TokenCredential credential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint())
.tenantId(tenant)
.build();
PolicyClientImpl policyClient= new PolicyClientBuilder()
.pipeline(HttpPipelineProvider.buildHttpPipeline(credential,profile))
.endpoint(profile.getEnvironment().getResourceManagerEndpoint())
.subscriptionId(profile.getSubscriptionId())
.buildClient();
PolicyDefinitionInner policy = policyClient.getPolicyDefinitions().getBuiltIn("04d53d87-841c-4f23-8a5b-21564380b55e");
System.out.println(policy.policyType());
System.out.println(policy.description());
,
最后,当我知道是策略定义名称时,我最终使用 REST API 来获取策略定义。请注意,我必须使用一个调用来获取内置策略,而使用另一个调用来获取自定义策略,这很痛苦,因为我事先不知道我拥有的是哪种类型。我使用 OkHttpClient 来处理繁重的工作。这是我的解决方案:
Boolean itMightBeACustomPolicy = false;
OkHttpClient builtinPolicyDefinitionHttpClient = new OkHttpClient();
String builtinPolicyDefinitionUrl = "https://management.azure.com/providers/Microsoft.Authorization/policyDefinitions/"
+ policyState.getString("policyDefinitionName") // This is what I know
+ "?api-version=2020-09-01";
Request builtinPolicyDefinitionRequest = new Request.Builder()
.url(builtinPolicyDefinitionUrl)
.addHeader("Authorization","Bearer " + token)
.get()
.build();
String policyDefinitionJson = "";
try
{
Response builtinPolicyDefinitionResponse = builtinPolicyDefinitionHttpClient.newCall(builtinPolicyDefinitionRequest).execute();
if(builtinPolicyDefinitionResponse.isSuccessful())
{
// It's a built-in policy definition
policyDefinitionJson = builtinPolicyDefinitionResponse.body().string();
}
else
{
// Let's try for a custom definition
// I do this separately to keep the try..catch unique.
itMightBeACustomPolicy = true;
}
}
catch (IOException e)
{
e.printStackTrace(); // TODO Handle this...
}
if(itMightBeACustomPolicy)
{
OkHttpClient customPolicyDefinitionHttpClient = new OkHttpClient();
String customPolicyDefinitionUrl = "https://management.azure.com/subscriptions/"
+ subscriptionId
+ "/providers/Microsoft.Authorization/policyDefinitions/"
+ policyState.getString("policyDefinitionName") // This is what I know
+ "?api-version=2020-09-01";
Request customPolicyDefinitionRequest = new Request.Builder()
.url(customPolicyDefinitionUrl)
.addHeader("Authorization","Bearer " + token)
.get()
.build();
try
{
Response customPolicyDefinitionResponse = customPolicyDefinitionHttpClient.newCall(customPolicyDefinitionRequest).execute();
if(customPolicyDefinitionResponse.isSuccessful())
{
policyDefinitionJson = customPolicyDefinitionResponse.body().string();
}
else
{
// Not sure what it is. Let's assume there are no policy definitions available.
// So do nothing here for now.
}
}
catch (IOException e)
{
e.printStackTrace(); // TODO Handle this...
}
}
// Wherever we got the policy definition from,let's parse it and gather data.
// NOTE: This design assumes that the JSON for built-in and custom are (nearly) identical.
// That might be wrong.
if(!policyDefinitionJson.isEmpty())
{
JSONObject policyDefinitionRootObject = new JSONObject(policyDefinitionJson);
// Do something with the resulting JSON
System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("policyType"));
System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("description"));
System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("displayName"));
}
注意:“当您创建单个 OkHttpClient 实例并将其重用于所有 HTTP 调用时,OkHttp 的性能最佳。”所以我仍然需要进行一些重构以避免创建多个客户端。