我遇到一种情况,我试图创建两个云功能,即 CF1 和 CF2,并且我有一个云调度程序。两个云功能都启用了经过身份验证的调用。我的流程是Cloud Scheduler将触发CF1。 CF1 完成后,CF1 将触发 CF2 作为 http 调用。我已经提到过无法从 GCP Scheduler 调用 Google Cloud Function https://stackoverflow.com/questions/60055422/cannot-invoke-google-cloud-function-from-gcp-scheduler从 Cloud Scheduler 访问经过身份验证的 CF1,并且能够访问 CF1。但从 CF1 访问 CF2 时遇到问题。 CF1 不会触发 CF2,也不会给出任何错误消息。当从另一个经过身份验证的云功能访问经过身份验证的云功能时,我们是否需要遵循任何其他技术。
CF1代码:
import json
import logging
from requests_futures.sessions import FuturesSession
def main(request):
# To read parameter values from request (url arguments or Json body).
raw_request_data = request.data
string_request_data = raw_request_data.decode("utf-8")
request_json: dict = json.loads(string_request_data)
request_args = request.args
if request_json and 'cf2_endpoint' in request_json:
cf2_endpoint = request_json['cf2_endpoint']
elif request_args and 'cf2_endpoint' in request_args:
cf2_endpoint = request_args['cf2_endpoint']
else:
cf2_endpoint = 'Invalid endpoint for CF2'
logger = logging.getLogger('test')
try:
session = FuturesSession()
session.get("{}".format(cf2_endpoint))
logger.info("First cloud function executed successfully.")
except RuntimeError:
logger.error("Exception occurred {}".format(RuntimeError))
CF2代码:
import logging
def main(request):
logger = logging.getLogger('test')
logger.info("second cloud function executed successfully.")
当前输出日志:
First cloud function executed successfully.
预期输出日志:
First cloud function executed successfully.
second cloud function executed successfully.
注意:如果我对这两个云功能使用未经身份验证的访问,则相同的流程有效。
这里发生了两件事:
- 你没有使用
request-futures
完全正确。由于请求是异步发出的,因此您需要在函数隐式返回之前阻止结果,否则它可能会在 HTTP 请求完成之前返回(尽管在本例中可能是这样):
session = FuturesSession()
future = session.get("{}".format(cf2_endpoint))
resp = future.result() # Block on the request completing
- 您向第二个函数发出的请求实际上并不是经过身份验证的请求。默认情况下,不对来自云功能的出站请求进行身份验证。如果您查看上面的实际响应,您会看到:
>>> resp.status_code
403
>>> resp.content
b'\n<html><head>\n<meta http-equiv="content-type" content="text/html;charset=utf-8">\n<title>403 Forbidden</title>\n</head>\n<body text=#000000 bgcolor=#ffffff>\n<h1>Error: Forbidden</h1>\n<h2>Your client does not have permission to get URL <code>/function_two</code> from this server.</h2>\n<h2></h2>\n</body></html>\n'
您可以跳过很多环节来正确验证此请求,如文档中详述:https://cloud.google.com/functions/docs/secure/authentication#function-to-function https://cloud.google.com/functions/docs/securing/authenticating#function-to-function
但是,更好的选择是将第二个函数设为“后台”函数,并通过从第一个函数发布的 PubSub 消息来调用它:
from google.cloud import pubsub
publisher = pubsub.PublisherClient()
topic_name = 'projects/{project_id}/topics/{topic}'.format(
project_id=<your project id>,
topic='MY_TOPIC_NAME', # Set this to something appropriate.
)
def function_one(request):
message = b'My first message!'
publisher.publish(topic_name, message)
def function_two(event, context):
message = event['data'].decode('utf-8')
print(message)
只要您的函数具有发布 PubSub 消息的权限,就可以避免向 HTTP 请求添加授权,并且还可以确保至少一次传递。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)