【发布时间】:2015-10-02 04:01:34
【问题描述】:
我正在尝试通过 Python 客户端库和纯 cURL 调用来使用 Google App Engine Admin API。
这在本地机器上运行良好,但在 GCE 机器上就不行了。
我正在尝试的 cURL 命令是这样的:
$ curl -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" https://appengine.googleapis.com/v1beta4/apps/myapp
{
"name": "apps/myapp",
"id": "myapp"
}
这是在我的本地计算机上成功执行的,其中 TOKEN 是我个人帐户的 oauth2 舞蹈的结果。
GCE 机器上的相同命令:
$ curl -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" https://appengine.googleapis.com/v1beta4/apps/myapp
curl: (7) Failed to connect to appengine.googleapis.com port 443: Connection timed out
无论我使用的是我的个人基于 oauth2 的令牌,还是从运行中获得的基于服务帐户的令牌,都会出现此行为
curl http://metadata/computeMetadata/v1/instance/service-accounts/default/token -H "Metadata-Flavor: Google"
在尝试使用 Python 客户端库时也是如此。
这是我在 Python 中所做的部分 sn-p:
gae = discovery.build('appengine', 'v1beta4')
method = gae.apps().get(appsId='myapp')
method.execute(http=my_authorized_http_instance)
my_authorized_http_instance 是一个授权的httplib2.Http() 实例,使用https://www.googleapis.com/auth/cloud-platform 范围。
在本地机器上,这工作正常,我收到描述 myapp 的响应。
在 GCE 实例上,最后一行需要很长时间才能执行,并最终引发此异常:
ResponseNotReady Traceback (most recent call last)
<ipython-input-9-b5373a41f867> in <module>()
----> 1 meth.execute(http=http)
/usr/local/lib/python2.7/dist-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
135 else: # IGNORE
136 pass
--> 137 return wrapped(*args, **kwargs)
138 return positional_wrapper
139
/usr/local/lib/python2.7/dist-packages/googleapiclient/http.pyc in execute(self, http, num_retries)
720
721 resp, content = http.request(str(self.uri), method=str(self.method),
--> 722 body=self.body, headers=self.headers)
723 if resp.status < 500:
724 break
/usr/local/lib/python2.7/dist-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
135 else: # IGNORE
136 pass
--> 137 return wrapped(*args, **kwargs)
138 return positional_wrapper
139
/usr/local/lib/python2.7/dist-packages/oauth2client/client.pyc in new_request(uri, method, body, headers, redirections, connection_type)
549
550 resp, content = request_orig(uri, method, body, clean_headers(headers),
--> 551 redirections, connection_type)
552
553 if resp.status in REFRESH_STATUS_CODES:
/usr/local/lib/python2.7/dist-packages/httplib2/__init__.pyc in request(self, uri, method, body, headers, redirections, connection_type)
1606 content = ""
1607 else:
-> 1608 (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
1609 except Exception, e:
1610 if self.force_exception_to_status_code:
/usr/local/lib/python2.7/dist-packages/httplib2/__init__.pyc in _request(self, conn, host, absolute_uri, request_uri, method, body, headers, redirections, cachekey)
1348 auth.request(method, request_uri, headers, body)
1349
-> 1350 (response, content) = self._conn_request(conn, request_uri, method, body, headers)
1351
1352 if auth:
/usr/local/lib/python2.7/dist-packages/httplib2/__init__.pyc in _conn_request(self, conn, request_uri, method, body, headers)
1304 continue
1305 try:
-> 1306 response = conn.getresponse()
1307 except httplib.BadStatusLine:
1308 # If we get a BadStatusLine on the first try then that means
/usr/lib/python2.7/httplib.pyc in getresponse(self, buffering)
1037 #
1038 if self.__state != _CS_REQ_SENT or self.__response:
-> 1039 raise ResponseNotReady()
1040
1041 args = (self.sock,)
ResponseNotReady:
是的,GCE 实例有cloud-platform 服务帐户:
$ curl -s http://metadata/computeMetadata/v1/instance/service-accounts/default/scopes -H "Metadata-Flavor: Google" | grep cloud-platform
https://www.googleapis.com/auth/cloud-platform
另外,我想弄清楚这里的服务帐户问题是否有问题,所以我尝试在 GCE 实例上以我自己的身份进行授权,而不是使用服务帐户。我遇到了同样的错误。
有什么想法吗?我做错了吗?
【问题讨论】:
-
我不清楚的两件事:“在 GCE 实例中”是什么意思?当你部署你的应用程序?还是您使用从您管理的 GCE 实例运行的代码构建自己的应用程序?另外,为什么不向上发送 HTTP 请求并尝试使用发现文档?
-
@Patrice 1- 我的意思是从我管理的 GCE 实例运行的应用程序,我想通过它与 AppEngine Admin API 进行交互。 2- 不确定我是否理解“向上发送 HTTP 请求”的意思 - IIUC
gae = discovery.build('appengine', 'v1beta4')is 使用发现文档(在 Python 中)。 -
感谢您回答这些问题 :) 我只是不确定您是否真的是指调用代码的 GCE,或者您是否将“已部署的 GAE 应用程序”称为在 GCE 上运行。至于向上发送请求。我在cloud.google.com/appengine/docs/admin-api/reference/rest/… 的 API 资源管理器中使用“apps.get”方法进行了测试,看起来您最终要做的是对“GET appengine.googleapis.com/v1beta4/apps/[PROJECTNAME]”的请求。你不能自己发送那个 REST 请求吗? (我不知道我是否更清楚)
-
@Patrice 不完全确定我理解。我在 GCE 机器上的本地机器上尝试了这个“原始”cURL GET
curl -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" https://appengine.googleapis.com/v1beta4/apps/myapp。它在本地机器上成功,在 GCE 机器上失败。我将使用此测试中的更多详细信息更新我的原始问题。
标签: python google-app-engine google-cloud-platform