如何使用 Java SDK 按名称查找 Azure 策略定义?

How do I find an Azure policy definition by name using the Java SDK?

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政策,你可以使用包com.azure.resourcemanager.resources中的方法PolicyClientImpl.getPolicyDefinitions().getBuiltIn()。此外,请注意内置策略的名称是guide。

例如

  1. 安装sdk
<dependency>
    <groupId>com.azure.resourcemanager</groupId>
    <artifactId>azure-resourcemanager-resources</artifactId>
    <version>2.1.0</version>
</dependency>
  1. 代码
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 性能最佳。”所以我仍然需要做一些重构以避免创建多个客户端。