【问题标题】:How can I list the policies associated with my Azure resources?如何列出与我的 Azure 资源关联的策略?
【发布时间】:2021-02-02 14:30:37
【问题描述】:

对于我的 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

【问题讨论】:

    标签: java azure azure-resource-manager azure-policy


    【解决方案1】:

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

    注意:这是版本 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());
    
            }
    

    【讨论】:

    • 感谢您的回答。我同意这段代码应该可以工作,但是当我测试它时,我发现它返回了每个资源的每个策略分配,无论它是否适用。控制台和 Azure CLI 表现出正确的行为,但 Java SDK 没有。
    • @james.garriss 您能否详细描述您的问题?
    • 我做到了。对于通过genericResources().list() 在我的帐户中找到的每个资源,listForResource() 方法会返回每个启用的策略,无论它们是否被分配给该资源。我可以在门户中看到正确的分配。我可以使用az policy state list --resource $id 通过 CLI 检索正确的分配。但是Java对我来说已经坏了。我不知道为什么。
    • @james.garriss comamnd az policy state list 不用于列出作业,您应该使用az policy assignment list 列出作业
    • 不,那个 CLI 命令正在做我想要的。或许我应该问这个问题:什么Java方法相当于az policy state list,@Jim Xu?
    【解决方案2】:

    由于我不想使用仍处于测试阶段的 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"));
    }
    

    【讨论】:

      猜你喜欢
      • 2020-05-07
      • 2022-07-01
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      相关资源
      最近更新 更多