简体   繁体   English

使用http 404,Compute Engine API调用失败

[英]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: 这是我做的:

  1. In app engine running for real (not in the local developer mode) print out the service account email. 在真实运行的应用引擎中(不是在本地开发者模式下)打印出服务帐户电子邮件。 Using the Go runtime, I used appengine.ServiceAccount(ctx) . 使用Go运行时,我使用了appengine.ServiceAccount(ctx)
  2. In Google Developers Console , go to the Permissions page for your project and add the e-mail address you obtained in the previous step as a member of your project. Google Developers Console中 ,转到项目的“权限”页面,并将您在上一步中获得的电子邮件地址添加为项目成员。

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 : 为道格的答案提供一个变体:

  1. 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的回答。

  2. At the very bottom of the application settings page, find the section called 'Cloud Integration'. 在应用程序设置页面的最底部,找到名为“云集成”的部分。 Do the integration -- this will take a minute. 进行整合 - 这将需要一分钟。

  3. 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.

相关问题 如何检查对Appengine实例的api调用是否来自Google Compute Engine实例? - How I check that an api call to an appengine instance came from a Google Compute Engine instance? Google App Engine无法连接安装在Google Compute Engine上的Aerospike - Google App Engine fails to connect Aerospike installed on Google Compute Engine 使用计算引擎默认服务帐户的从计算引擎到应用引擎标准的HTTP请求 - HTTP requests from compute engine to app-engine standard with compute engine default service account 使用PHP Yii2框架的REST API调用在Google App Engine中返回404错误 - REST API call returns 404 error in Google App Engine with PHP Yii2 framework gwt 谷歌应用引擎 HTTP 错误 404 - gwt google app engine HTTP ERROR 404 在Google Compute Engine [Debian 8]中运行Maven项目 - Running Maven Project in Google Compute Engine [Debian 8] Build fails 应用程序引擎端点API - 404具有自定义域 - App engine endpoints API - 404 with custom domain 从Google Compute Engine到Appengine标准的HTTP请求 - HTTP requests from Google Compute Engine to Appengine Standard 有没有办法使用 Compute Engine API + NodeJS 修改 Compute Engine 虚拟机中的文件 - Is there a way to modify the files in a Compute Engine virtual machine using the Compute Engine API + NodeJS Google App Engine HTTP错误500远程API调用:I / O错误 - Google App Engine HTTP Error 500 remote API call: I/O error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM