在我的场景中,我想在 Google Cloud Build 期间触发基于 HTTP 端点的 Google Cloud Function。 HTTP 请求是使用 python:3.7-slim 容器的步骤完成的。
基于this https://cloud.google.com/functions/docs/securing/authenticating?hl=de#functions-bearer-token-example-python and this https://cloud.google.com/run/docs/authenticating/service-to-service#console-ui文档中的示例,我想使用以下代码:
REGION = 'us-central1'
PROJECT_ID = 'name-of-project'
RECEIVING_FUNCTION = 'my-cloud-function'
function_url = f'https://{REGION}-{PROJECT_ID}.cloudfunctions.net/{RECEIVING_FUNCTION}'
metadata_server_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_full_url = metadata_server_url + function_url
token_headers = {'Metadata-Flavor': 'Google'}
token_response = requests.get(token_full_url, headers=token_headers)
jwt = token_response.text
print(jwt)
r = requests.post(url=function_url, headers=function_headers, json=payload)
令人惊讶的是,代码失败了,因为jwt
is Not Found
(根据print
陈述)。
我已经通过硬编码有效的身份令牌来测试代码和 IAM 设置,并且还在同一项目内的测试虚拟机上测试了完全相同的获取机制。
问题似乎是获取一些元数据在云构建中不起作用。
我错过了什么吗?
感谢您的任何帮助!
解决方案是使用一个用于生成 ID_TOKEN 的新 IAM api https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/generateIdToken,在具有访问令牌的服务帐户上,如果请求者(生成访问令牌的人)在服务帐户(或广泛地在项目中)上具有服务帐户令牌创建者角色。
第一个示例使用直接 API 调用
- name: gcr.io/cloud-builders/gcloud
entrypoint: "bash"
args:
- "-c"
- |
curl -X POST -H "content-type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-d '{"audience": "YOUR AUDIENCE"}' \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/YOUR SERVICE ACCOUNT:generateIdToken"
# Use Cloud Build Service Account
# service_account_email=$(gcloud config get-value account)
这里是Python代码版本
- name: python:3.7
entrypoint: "bash"
args:
- "-c"
- |
pip3 install google-auth requests
python3 extract-token.py
And extract-token.py
内容如下代码
REGION = 'us-central1'
PROJECT_ID = 'name-of-project'
RECEIVING_FUNCTION = 'my-cloud-function'
function_url = f'https://{REGION}-{PROJECT_ID}.cloudfunctions.net/{RECEIVING_FUNCTION}'
import google.auth
credentials, project_id = google.auth.default(scopes='https://www.googleapis.com/auth/cloud-platform')
# To use the Cloud Build service account email
service_account_email = credentials.service_account_email
#service_account_email = "YOUR OWN SERVICE ACCOUNT"
metadata_server_url = f'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{service_account_email}:generateIdToken'
token_headers = {'content-type': 'application/json'}
from google.auth.transport.requests import AuthorizedSession
authed_session = AuthorizedSession(credentials)
import json
body = json.dumps({'audience': function_url})
token_response = authed_session.request('POST',metadata_server_url, data=body, headers=token_headers)
jwt = token_response.json()
print(jwt['token'])
如果您需要更多详细信息,请不要犹豫。
我想我会在 Medium 上写一篇关于这个的文章,如果你想让我说出你的名字,请告诉我
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)