[英]Compute Engine API call fails with http 404
I need a bit of help with Google Compute Engine API call from within App Engine code. 我需要在App Engine代码中对Google Compute Engine API调用提供一些帮助。 Following is part of code that I use to get a list of compute engine instances (simplified version)
以下是我用来获取计算引擎实例列表的代码的一部分(简化版)
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()));
}
As you can see I am using AppIdentity to obtain access token. 如您所见,我正在使用AppIdentity来获取访问令牌。 Then use it in request header in API call.
然后在API调用中的请求标头中使用它。
Basically every time the call fails with following error 基本上每次呼叫失败并出现以下错误
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"
}
}
What is interesting is that if I use following webapp https://developers.google.com/compute/docs/reference/latest/instances/list#try-it to make the same API call it succeeds. 有趣的是,如果我使用以下webapp https://developers.google.com/compute/docs/reference/latest/instances/list#try-it进行相同的API调用,则会成功。
So I looked into what data are sent when this web app makes request and copied bearer token string and used it in "Authorization" header. 因此,我查看了此Web应用程序发出请求和复制的承载令牌字符串时发送的数据,并在“授权”标题中使用它。 Strangely enough request now finished successfully without changing anything else.
奇怪的是,请求现在已经成功完成而不会改变任何其他内容 Basically that app uses user consent Oauth2 type of token - so for me it looks like there is some problem with token obtained via AppIdentity.
基本上该应用程序使用用户同意Oauth2类型的令牌 - 所以对我来说,看起来通过AppIdentity获得的令牌存在一些问题。 Could someone point me in right direction?
有人能指出我正确的方向吗? Thanks!
谢谢!
I ran into the same issue and was able to solve it, or perhaps I should say workaround it, in a way that doesn't make complete sense to me. 我遇到了同样的问题并且能够解决它,或者我应该以一种对我来说完全没有意义的方式来解决它。 Hopefully someone with real knowledge on the subject can explain further.
希望有关于这个主题的真正知识的人可以进一步解释。 This solution is similar to what E. Anderson answered, but different because both App Engine and Compute Engine were in the same project.
这个解决方案类似于E. Anderson的回答,但不同,因为App Engine和Compute Engine都在同一个项目中。
Here's what I did: 这是我做的:
appengine.ServiceAccount(ctx)
. appengine.ServiceAccount(ctx)
。 Once I did this, I was able to make requests to Compute Engine REST APIs from App Engine. 完成此操作后,我能够从App Engine向Compute Engine REST API发出请求。 I have no idea why this step was necessary.
我不知道为什么这一步是必要的。
Are you using an appengine app in the same project as the GCE project you're trying to manage? 您是否在与您尝试管理的GCE项目相同的项目中使用appengine应用程序? If not, you'll need to add the service account identity from the AppEngine app to the project team for the GCE project;
如果没有,您需要将AppEngine应用程序中的服务帐户标识添加到GCE项目的项目团队中; look under the "Permissions" tab on the cloud console to see whether your AppEngine app has access to the GCE project.
查看云控制台上的“权限”选项卡,查看您的AppEngine应用程序是否可以访问GCE项目。
To provide a variant on Doug's answer : 为道格的答案提供一个变体:
Go to https://appengine.google.com , select your application, and go to the Administration > 'Application Settings' page. 转到https://appengine.google.com ,选择您的应用程序,然后转到管理>'应用程序设置'页面。 Here you can find your service account email address.
您可以在此处找到您的服务帐户电子邮件地址 Use this in case you want to add the email address explicitly, ie if your compute engine project is different from your app engine project.
如果您想明确添加电子邮件地址,即您的计算引擎项目与您的应用引擎项目不同,请使用此选项。 If that is the case, follow Doug's answer.
如果是这种情况,请按照Doug的回答。
At the very bottom of the application settings page, find the section called 'Cloud Integration'. 在应用程序设置页面的最底部,找到名为“云集成”的部分。 Do the integration -- this will take a minute.
进行整合 - 这将需要一分钟。
Lo and behold, if you go to https://console.developers.google.com , select your project, and go to the Permissions page for your project (the link is far down on the left side), you will find that your app engine service account now shows up on the list of service accounts, with edit rights. 瞧,如果你去https://console.developers.google.com ,选择你的项目,然后转到项目的权限页面(链接在左侧很远),你会发现你的应用引擎服务帐户现在显示在具有编辑权限的服务帐户列表中。 The 404 should be resolved.
404应该得到解决。
If you want your OAuth authorization code to work from the dev server as well, this answer might help: https://stackoverflow.com/a/22723127 如果您希望OAuth授权代码也可以在开发服务器上运行,那么这个答案可能有所帮助: https : //stackoverflow.com/a/22723127
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.