python - 如何从 GoogleCredentials 获取 projectId?
问题描述
使用 Python,我想获取我在 Google Cloud 上的所有 Dataproc 集群的列表。
我将服务帐户凭据存储在 JSON 密钥文件中,其位置由 env var GOOGLE_APPLICATION_CREDENTIALS 引用。这是我到目前为止的代码:
import os
import googleapiclient.discovery
from oauth2client.client import GoogleCredentials
def build_dataproc_service(credentials):
return googleapiclient.discovery.build("dataproc", "v1", credentials=credentials)
def list_clusters():
credentials = GoogleCredentials.get_application_default()
dataproc = build_dataproc_service(credentials)
clusters = dataproc.projects().regions().clusters().list(projectId="my-project", region="REGION").execute()
return clusters
if __name__ == "__main__":
list_clusters()
如您所见,我已经对 projectId ( "my-project"
) 进行了硬编码。鉴于 projectId 存在于 JSON 密钥文件中,我希望我可以通过简单地询问credentials
对象的属性来获得它,但不存在这样的属性。projectId确实存在嵌入在credentials._service_account_email
字符串属性中,但从那里提取它很笨重并且感觉不对。
我认为必须有更好的方法。如何获取服务账号所在项目的projectId?
请注意,最初我打算将此代码在 Google Compute Engine 实例上的 docker 容器中运行,但是将来有一天我可能希望在 GKE 上运行。不确定这是否会影响答案。
解决方案
考虑这一点的正式方法是,虽然 projectId 有时是服务帐户的属性,但 projectId 通常不是长期凭证的属性。例如,想想您在gcloud
CLI 中使用的离线安装的个人凭据(如果有的话),与您的 Google 帐户/电子邮件地址相关联。该电子邮件身份不驻留在任何云项目中,但可用于派生 GoogleCredential 对象。
从技术上讲,如果您想“正确地”执行此操作,您需要一个主服务账户,该账户有权访问GET
所有项目中的服务账户描述,这些项目包含您计划使用的实际服务账户,然后调用 IAM API 的projects.serviceAccounts。获取服务帐户电子邮件地址,而不是“凭据”对象。那里的响应可以识别服务帐户所在的项目 ID。这相当于gcloud
命令:
gcloud iam service-accounts describe my-service-account@projectid.iam.gserviceaccount.com
然而,正如 Dagang 所说,从长远来看,通常会适得其反,开始假设服务帐户将仅用于其所在项目的操作。特别是,虽然service account
资源本身存在于项目中,但它们通常以跨项目的方式使用。一种常见的操作模式是使用单个 GCP 项目来管理大量服务帐户,然后授予这些服务帐户对其他 GCP 项目中资源的各种细粒度访问权限。
推荐阅读
- javascript - 如何通过ajax将两个数组发送到控制器
- android - Kotlin Android 搜索菜单项在活动开始时聚焦
- python - 绘制一个强度下降的非增长圆
- r - 获取比较多列的单列值
- excel - 从 Excel 调用 Access 函数
- lua - 为什么这个lua变量是nil,如果赋值语句后跟一个“,”
- c++ - 带有指针和 const 方法的类
- python - 如果将在 Python 中使用该类的实例,我是否必须导入该类?
- javascript - react-i18next:如何同步浏览器和 Express LanguageDetector?
- html - 即使向右浮动,元素也会向左移动