【问题标题】:Compute Engine API call fails with http 404Compute Engine API 调用失败并出现 http 404
【发布时间】:2014-01-30 11:41:06
【问题描述】:

我需要一些关于从 App Engine 代码中调用 Google Compute Engine 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"
 }
}

有趣的是,如果我使用以下 webapp https://developers.google.com/compute/docs/reference/latest/instances/list#try-it 进行相同的 API 调用,它会成功。

因此,我查看了当这个 Web 应用发出请求并复制不记名令牌字符串并将其用于“授权”标头时发送的数据。奇怪的是,请求现在成功完成而没有更改任何其他内容。基本上,该应用程序使用用户同意 Oauth2 类型的令牌 - 所以对我来说,通过 AppIdentity 获得的令牌似乎存在一些问题。 有人能指出我正确的方向吗?谢谢!

【问题讨论】:

  • 我在 Go 运行时看到了完全相同的问题。我正在请求使用内置的应用引擎服务帐户列出来自应用引擎的计算图像,但我得到了 404。但是,使用 APIs Explorer 可以正常工作。
  • 你有没有运气解决它?我又想到了一个想法——我们的 App Engine 项目是在前一段时间创建的,当时不可能在同一个项目中拥有 api——我们稍后在它可用时激活了它们。你有类似的设置吗?
  • 是的,请参阅下面的答案。

标签: google-app-engine google-api google-compute-engine


【解决方案1】:

提供 Doug 的answer 的变体:

  1. 转到https://appengine.google.com,选择您的应用程序,然后转到管理>“应用程序设置”页面。您可以在此处找到您的服务帐户电子邮件地址。如果您想明确添加电子邮件地址,请使用此选项,即。 e.如果您的计算引擎项目与您的应用引擎项目不同。如果是这种情况,请按照 Doug 的回答。

  2. 在应用程序设置页面的最底部,找到名为“云集成”的部分。进行集成——这需要一分钟。

  3. 你瞧,如果你去https://console.developers.google.com,选择你的项目,然后进入你项目的权限页面(链接在左边很远),你会发现你的应用引擎服务帐户现在显示在服务帐户列表中,具有编辑权限。 404 应该已经解决了。

如果您希望您的 OAuth 授权代码也可以在开发服务器上工作,这个答案可能会有所帮助:https://stackoverflow.com/a/22723127

【讨论】:

    【解决方案2】:

    我遇到了同样的问题并且能够解决它,或者我应该说解决方法,以一种对我来说并不完全有意义的方式。希望对这个主题有真正了解的人可以进一步解释。此解决方案与 E. Anderson 的回答类似,但有所不同,因为 App Engine 和 Compute Engine 都在同一个项目中。

    这就是我所做的:

    1. 在真正运行的应用引擎中(不是在本地开发者模式下)打印服务帐户电子邮件。使用 Go 运行时,我使用了appengine.ServiceAccount(ctx)
    2. Google Developers Console 中,转到您的项目的权限页面,并将您在上一步中获得的电子邮件地址添加为您的项目成员。

    完成此操作后,我就可以从 App Engine 向 Compute Engine REST API 发出请求。我不知道为什么这一步是必要的。

    【讨论】:

    • 非常感谢,这就像一个魅力。我有相同的设置 - App Engine 和 Compute Engine 在同一个项目中,我没有考虑做这样的事情来让它工作。
    • 我也没有。我的一位朋友建议这样做。 Google 的文档不是很有帮助。
    • 嗯,目前AppEngine服务号好像没有默认加入项目组;您可以在 GAE 控制台的“应用程序设置”下找到 AppEngine 服务帐户 ID。它看起来像“my-app@appspot.gserviceaccount.com”
    • 是的,这是令人困惑的部分。此外,默认情况下会创建另一个服务帐户并添加到标有“Compute Engine 和 App Engine”的项目团队中。此帐户类似于“@developer.gserviceaccount.com”
    【解决方案3】:

    您是否在尝试管理的 GCE 项目所在的项目中使用 appengine 应用?如果没有,您需要将 AppEngine 应用程序中的服务帐户身份添加到 GCE 项目的项目团队;在云控制台的“权限”选项卡下查看您的 AppEngine 应用是否有权访问 GCE 项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      相关资源
      最近更新 更多