Google API - 必需的'compute.globalOperations.get'权限

时间:2018-04-13 07:54:27

标签: google-api google-compute-engine

我正在尝试使用适用于Java的goolge计算引擎API修改实例的标记列表。我的pom.xml导入了这个依赖项:

<dependency>
  <groupId>com.google.apis</groupId>
  <artifactId>google-api-services-compute</artifactId>
  <version>v1-rev173-1.23.0</version>
</dependency>

我可以执行将成功更新与VM关联的标记的操作:

public boolean setInstanceTags(Compute computeConnection, ArrayList<String> nwTags, String projectId, String zone, String instanceName) {
    Instance instance = computeConnection.instances().get(projectId, zone, instanceName).execute();

    Tags tagsToSet = new Tags();
    tagsToSet.setFingerprint(instance.getTags().getFingerprint());
    tagsToSet.setItems(new ArrayList<String>());

    for (String tag: nwTags) {
        tagsToSet.getItems().add(tag);
    }

    Operation setTagsOperation = computeConnection.instances().setTags(projectId, zone, instanceName, tagsToSet).execute();

为了获得有关该操作是否成功的反馈,我想按如下方式提取操作状态:

String setTagsOperationId = setTagsOperation.getName();   
setTagsOperation = computeConnection.globalOperations().get(projectId, setTagsOperationId).execute();

这会抛出此错误:

  

“code”:403,     “错误”:[{       “域名”:“全球”,       “message”:“'project / myproject / global / operations / operation-1523604756600-569b5e04b94c3-a87939f4-4e293939''所需的'compute.globalOperations.get'权限,”,       “理由”:“被禁止”     }],     “message”:“'project / myproject / global / operations / operation-1523604756600-569b5e04b94c3-a87939f4-4e293939''所需的'compute.globalOperations.get'权限”

但我正在使用的服务帐户确实具有“Compute Admin”IAM角色,我的代码也设置了管理范围:

SCOPES = Arrays.asList(ComputeScopes.COMPUTE);

我使用相同的帐户/权限来创建防火墙规则并成功提取这些操作的状态。不确定为什么拉出instance.setTags操作和firewalls.insert的操作状态的权限有所不同。 我发现的唯一提示是在firewalls.insert操作上提取数据时,'selfLink'显示操作位于全局范围内:

  

https://www.googleapis.com/compute/v1/projects/myproject/全球 /操作/操作 - 1523604247193-569b5c1eea5a8-2ccf40e9-8815af38”

其中,instances.setTags操作selfLink显示此操作位于特定区域中:

  

https://www.googleapis.com/compute/v1/projects/myproject/ / US-central1-C /操作/操作 - 1523604346365-569b5c7d7e449-dc64de03-fdb77847”

2 个答案:

答案 0 :(得分:0)

我已经使用带有角色的服务帐户测试了以下API [1]调用&#34; Compute Admin&#34;:

$ curl -H&#34;授权:持票人&#34; $(gcloud auth print-access-token)https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/operations/[OPERATION_NAME]

它返回了我没有错误的预期值。

为了了解您的代码和服务帐户是否具有正确的角色,您可以尝试从官方文档[2]中提取的以下代码,其值设置为&#34; compute.globalOperations.get&#34;。

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.cloudresourcemanager.CloudResourceManager;
import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsRequest;
import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsResponse;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;

public class CloudResourceManagerExample {
  public static void main(String args[]) throws IOException, GeneralSecurityException {
    // REQUIRED: The resource for which the policy detail is being requested.
    // See the operation documentation for the appropriate value for this field.
    String resource = "my-resource"; // TODO: Update placeholder value.

    // TODO: Assign values to desired fields of `requestBody`:
    TestIamPermissionsRequest requestBody = new TestIamPermissionsRequest();

    CloudResourceManager cloudResourceManagerService = createCloudResourceManagerService();
    CloudResourceManager.Projects.TestIamPermissions request =
        cloudResourceManagerService.projects().testIamPermissions(resource, requestBody);

    TestIamPermissionsResponse response = request.execute();

    // TODO: Change code below to process the `response` object:
    System.out.println(response);
  }

  public static CloudResourceManager createCloudResourceManagerService()
      throws IOException, GeneralSecurityException {
    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

    GoogleCredential credential = GoogleCredential.getApplicationDefault();
    if (credential.createScopedRequired()) {
      credential =
          credential.createScoped(Arrays.asList("https://www.googleapis.com/auth/cloud-platform"));
    }

    return new CloudResourceManager.Builder(httpTransport, jsonFactory, credential)
        .setApplicationName("Google-CloudResourceManagerSample/0.1")
        .build();
  }
}

通过这种方式,您可以了解您的代码是否使用了正确的服务帐户,或者是否存在问题。

[1] https://cloud.google.com/compute/docs/reference/rest/beta/globalOperations/get

[2] https://cloud.google.com/resource-manager/reference/rest/v1/projects/testIamPermissions

答案 1 :(得分:0)

您可以从控制台修改实例的标记,并检查此操作是区域操作,而不是全局操作。 selfLink的下方可以从任何修改标记操作的等效REST响应中找到。

"selfLink": "https://www.googleapis.com/compute/v1/projects/[project_name]/zones/us-central1-f/operations/operation-0000000000000-0000000000000-00000000-00000000",

我相信由于这个原因,需要使用zonal method而不是global method。您可以使用以下method来解决此问题。

  

方法:zoneOperations.get

也就是说,计算管理员角色已经拥有all required permissions权限,包括compute.zoneOperations在这种情况下工作的权限。