我需要从应用程序引擎代码中获得一些关于Google计算引擎API调用的帮助。以下是我用来获得计算引擎实例列表(简化版)的部分代码
try {
final AppIdentityService appIdService = AppIdentityServiceFactory
.getAppIdentityService();
AppIdentityService.GetAccessTokenResult result = appIdService
.getAccessTokenUncached(Collections
.singletonList(ComputeScopes.COMPUTE));
String accessToken = result.getAccessToken();
String url = "https://www.googleapis.com/compute/v1/projects/MYPROJECTID/zones/us-central1-b/instances";
String payload = "";
// Create HTTPRequest and set headers
HTTPRequest httpRequest = new HTTPRequest(new URL(url.toString()),
HTTPMethod.GET, FetchOptions.Builder.doNotFollowRedirects());
httpRequest.addHeader(new HTTPHeader("Authorization", "OAuth "
+ accessToken));
httpRequest.addHeader(new HTTPHeader("Host", "www.googleapis.com"));
httpRequest.addHeader(new HTTPHeader("Content-Length", Integer
.toString(payload.length())));
httpRequest.addHeader(new HTTPHeader("Content-Type",
"application/json"));
httpRequest.addHeader(new HTTPHeader("User-Agent",
"google-api-java-client/1.0"));
httpRequest.setPayload(payload.getBytes());
URLFetchService fetcher = URLFetchServiceFactory
.getURLFetchService();
HTTPResponse httpResponse = fetcher.fetch(httpRequest);
int responseCode = httpResponse.getResponseCode();
if ((responseCode == 200) || (responseCode == 204)) {
String contentStr = new String(httpResponse.getContent());
return extractIpsAndInstanceNames(contentStr, prefix);
} else {
logger.warning("Failed. Response code " + responseCode
+ " Reason: " + new String(httpResponse.getContent()));
}
正如您所看到的,我正在使用AppIdentity来获取访问令牌。然后在API调用的请求头中使用它。
基本上每次呼叫失败时都会出现以下错误
Failed. Response code 404 Reason: {
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "The resource 'projects/MYPROJECTID' was not found"
}
],
"code": 404,
"message": "The resource 'projects/MYPROJECTID' was not found"
}
}
有趣的是,如果我使用以下网络应用程序https://developers.google.com/compute/docs/reference/latest/instances/list#try-它成功地进行了相同的API调用。
因此,我研究了当这个web应用程序发出请求并复制承载令牌字符串并在"授权"标头中使用时发送的数据。奇怪的是,请求现在成功完成了,没有更改任何其他内容。基本上,该应用程序使用用户同意Oauth2类型的令牌,所以对我来说,通过AppIdentity获得的令牌似乎存在一些问题。有人能给我指正确的方向吗?谢谢
我遇到了同样的问题,并且能够以一种对我来说没有完全意义的方式解决它,或者我应该说是变通方法。希望有真正了解这个主题的人能进一步解释。这个解决方案与E.Anderson的回答类似,但不同之处在于应用程序引擎和计算引擎都在同一个项目中。
以下是我所做的:
- 实时运行的应用内引擎(不在本地开发者模式下)打印出服务帐户电子邮件。使用Go运行时,我使用了
appengine.ServiceAccount(ctx)
- 在谷歌开发者控制台中,转到项目的"权限"页面,添加您在上一步中作为项目成员获得的电子邮件地址
一旦我做到了这一点,我就可以从应用程序引擎向计算引擎REST API发出请求。我不知道为什么这一步是必要的。
您是否在与您试图管理的GCE项目相同的项目中使用appengine应用程序?如果没有,您需要将AppEngine应用程序中的服务帐户标识添加到GCE项目的项目团队中;在云控制台的"权限"选项卡下查看您的AppEngine应用程序是否有权访问GCE项目。
提供Doug答案的变体:
-
转到https://appengine.google.com,选择您的应用程序,然后转到"管理">"应用程序设置"页面。您可以在这里找到您的服务帐户电子邮件地址。如果你想明确添加电子邮件地址,例如,如果你的计算引擎项目与应用程序引擎项目不同,请使用此选项。如果是这样的话,按照Doug的回答。
-
在应用程序设置页面的最底部,可以找到名为"云集成"的部分。进行集成--这需要一分钟的时间。
-
瞧,如果你去https://console.developers.google.com,选择您的项目,然后转到项目的"权限"页面(链接位于左侧下方),您会发现您的应用程序引擎服务帐户现在显示在服务帐户列表中,并具有编辑权限。404应该得到解决。
如果您希望OAuth授权代码也能在开发服务器上工作,这个答案可能会有所帮助:https://stackoverflow.com/a/22723127