Google Cloud Composer:如何从本地开发计算机触发 DAG 运行?
背景
我有一个在 GCP 上运行的 Google Cloud Composer 1 环境。
我编写了一个Google Cloud Function,当在云中运行时,它可以在我的 Composer 环境中成功触发 DAG 运行。我的代码基于 使用 Cloud Functions 触发 DAG 指南。
这是与我的问题最相关的代码部分(来源):
from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests
def make_iap_request(url, client_id, method='GET', **kwargs):
"""Makes a request to an application protected by Identity-Aware Proxy.
Args:
url: The Identity-Aware Proxy-protected URL to fetch.
client_id: The client ID used by Identity-Aware Proxy.
method: The request method to use
('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
**kwargs: Any of the parameters defined for the request function:
https://github.com/requests/requests/blob/master/requests/api.py
If no timeout is provided, it is set to 90 by default.
Returns:
The page body, or raises an exception if the page couldn't be retrieved.
"""
# Set the default timeout, if missing
if 'timeout' not in kwargs:
kwargs['timeout'] = 90
# Obtain an OpenID Connect (OIDC) token from metadata server or using service
# account.
open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
# Fetch the Identity-Aware Proxy-protected URL, including an
# Authorization header containing "Bearer " followed by a
# Google-issued OpenID Connect token for the service account.
resp = requests.request(
method, url,
headers={'Authorization': 'Bearer {}'.format(
open_id_connect_token)}, **kwargs)
if resp.status_code == 403:
raise Exception('Service account does not have permission to '
'access the IAP-protected application.')
elif resp.status_code != 200:
raise Exception(
'Bad response from application: {!r} / {!r} / {!r}'.format(
resp.status_code, resp.headers, resp.text))
else:
return resp.text
挑战
我希望能够在我的开发计算机上本地运行相同的云功能。当我尝试这样做时,该函数崩溃并显示以下错误消息:
google.auth.exceptions.DefaultCredentialsError:找不到元数据服务器或有效的服务帐户凭据。
这是有道理的,因为引发错误的行是:
google_open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
确实,在本地运行时,元数据服务器不可用,并且我不知道如何使有效的服务帐户凭据可用于调用 fetch_id_token()
。
问题
我的问题是 - 当我在本地运行函数时,我需要更改什么才能安全地获取 OpenID Connect 令牌?
Background
I have a Google Cloud Composer 1 environment running on GCP.
I have written a Google Cloud Function that, when run in the cloud, successfully triggers a DAG Run in my Composer environment. My code is based on and almost identical to the code in the Trigger DAGs with Cloud Functions guide from GCP documentation.
Here is the section of code most relevant to my question (source):
from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests
def make_iap_request(url, client_id, method='GET', **kwargs):
"""Makes a request to an application protected by Identity-Aware Proxy.
Args:
url: The Identity-Aware Proxy-protected URL to fetch.
client_id: The client ID used by Identity-Aware Proxy.
method: The request method to use
('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
**kwargs: Any of the parameters defined for the request function:
https://github.com/requests/requests/blob/master/requests/api.py
If no timeout is provided, it is set to 90 by default.
Returns:
The page body, or raises an exception if the page couldn't be retrieved.
"""
# Set the default timeout, if missing
if 'timeout' not in kwargs:
kwargs['timeout'] = 90
# Obtain an OpenID Connect (OIDC) token from metadata server or using service
# account.
open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
# Fetch the Identity-Aware Proxy-protected URL, including an
# Authorization header containing "Bearer " followed by a
# Google-issued OpenID Connect token for the service account.
resp = requests.request(
method, url,
headers={'Authorization': 'Bearer {}'.format(
open_id_connect_token)}, **kwargs)
if resp.status_code == 403:
raise Exception('Service account does not have permission to '
'access the IAP-protected application.')
elif resp.status_code != 200:
raise Exception(
'Bad response from application: {!r} / {!r} / {!r}'.format(
resp.status_code, resp.headers, resp.text))
else:
return resp.text
Challenge
I want to be able to run the same Cloud Function locally on my dev machine. When I try to do that, the function crashes with this error message:
google.auth.exceptions.DefaultCredentialsError: Neither metadata server or valid service account credentials are found.
This makes sense because the line that throws the error is:
google_open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
Indeed when running locally the Metadata Server is not available and I don't know how to make valid service account credentials available to the call to fetch_id_token()
.
Question
My question is - What do I need to change in order to be able to securely obtain the OpenID Connect token when I run my function locally?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经能够在本地运行我的代码而无需更改它。以下是详细信息,但我不确定这是完成此操作的最安全的选择。
完成此操作后,对
id_token.fetch_id_token()
的调用从密钥文件中获取服务帐户详细信息并成功返回令牌。* - 就我而言,我在 PyCharm 调试配置中设置了环境变量。
I've been able to run my code locally without changing it. Below are the details though I'm not sure this is the most secure option to get it done.
GOOGLE_APPLICATION_CREDENTIALS
environment variable to be the path to where I placed the JSON file. More details here: https://cloud.google.com/docs/authentication/productionOnce I did this, the call to
id_token.fetch_id_token()
picked up the service account details from the key file and returned the token successfully.* - In my case I set the environment variable inside my PyCharm Debug Configuration.