我正在尝试使用适用于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”
答案 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
在这种情况下工作的权限。