无法使用 python 脚本切换 gcloud 平台帐户
Posted
技术标签:
【中文标题】无法使用 python 脚本切换 gcloud 平台帐户【英文标题】:Unable to switch gcloud platform account using python script 【发布时间】:2019-07-16 05:19:57 【问题描述】:请问有人可以帮我查询与 Google 云平台上的权限相关的问题吗?我意识到这只是松散的编程相关,所以如果这是错误的论坛,我深表歉意!
我有一个用 Python 编写的项目(“ProjectA”),它使用 Google 的云存储和计算引擎。该项目有各种存储桶,可以使用来自计算实例和我家用计算机的 python 代码进行访问。该项目使用作为项目“所有者”的服务帐户,我相信它启用了所有 API,并且项目运行良好。服务帐号名称为“master@projectA.iam.gserviceaccount.com”。
最近我开始了一个需要类似资源(存储、计算)等的新项目,但我想将其分开。新项目名为“ProjectB”,我设置了一个名为 master@projectB.iam.gserviceaccount.com 的新主服务帐户。我在 ProjectB 中的代码会生成与访问权限相关的错误,即使我将代码剥离到这几行,也会得到演示:
ProjectA 的代码如下所示:
from google.cloud import storage
client = storage.Client(project='projectA')
mybucket = storage.bucket.Bucket(client=client, name='projectA-bucket-name')
currentblob = mybucket.get_blob('somefile.txt')
ProjectB 的代码如下所示:
from google.cloud import storage
client = storage.Client(project='projectB')
mybucket = storage.bucket.Bucket(client=client, name='projectB-bucket-name')
currentblob = mybucket.get_blob('somefile.txt')
这两个存储桶肯定存在,显然如果“somefile.text”不存在,则 currentblob 为 None,这很好,但是当我执行此代码时,我收到以下错误:
Traceback (most recent call last):
File .... .py", line 6, in <module>
currentblob = mybucket.get_blob('somefile.txt')
File "C:\Python27\lib\site-packages\google\cloud\storage\bucket.py", line 599, in get_blob
_target_object=blob,
File "C:\Python27\lib\site-packages\google\cloud\_http.py", line 319, in api_request
raise exceptions.from_http_response(response)
google.api_core.exceptions.Forbidden: 403 GET https://www.googleapis.com/storage/v1/b/<ProjectB-bucket>/o/somefile.txt: master@ProjectA.iam.gserviceaccount.com does not have storage.objects.get access to projectB/somefile.txt.
请注意错误消息如何显示“ProjectA”服务帐户没有 ProjectB 访问权限 - 好吧,我有点期待,但我希望在 ProjectB 上使用服务帐户!
在阅读文档和链接(例如 this 和 this)后,即使在删除和恢复服务帐户或为其提供有限范围之后,它也没有帮助。我尝试了一些方法:
1) 确保我的新服务帐户已在我的本地机器上“激活”(目前正在运行代码):
gcloud auth activate-service-account master@projectB.iam.gserviceaccount.com --key-file="C:\my-path-to-file\123456789.json"
这似乎是成功的。
2) 验证凭证帐户列表:
gcloud auth list
这列出了两个帐户,一个是我的电子邮件地址(用于 gmail 等),另一个是 master@projectB.iam.gserviceaccount.com,因此看来我的帐户已正确“注册”。
3) 将服务帐号设置为活动帐号:
gcloud config set account master@projectB.iam.gserviceaccount.com
当我再次查看身份验证列表时,服务帐户旁边有一个星号“*”,所以想必这很好。
4) 检查项目是否设置为 ProjectB:
gcloud config set project projectB
这似乎也没问题。
奇怪的是,当我运行 python 代码时,它正在“使用”我旧项目中的服务帐户,即使我已经更改了似乎所有内容以引用项目 B - 我已经激活了帐户,选择了它等等。
请有人指出我可能错过的方向吗?我不记得在设置我的原始项目时经历过这么多痛苦,而且我发现它非常令人沮丧,以至于我认为很简单的事情变得如此困难。
感谢任何可以为我提供帮助的人。
【问题讨论】:
向角色 Owner 授予服务帐户凭据不是好的做法。对服务帐户使用最低权限。 【参考方案1】:我不完全确定,但这个答案来自一个类似的问题: Permission to Google Cloud Storage via service account in Python
通过指向代码中的凭据明确指定帐户。如记录的here:
文档页面中的示例:
def explicit():
from google.cloud import storage
# Explicitly use service account credentials by specifying the private key
# file.
storage_client = storage.Client.from_service_account_json(
'service_account.json')
# Make an authenticated API request
buckets = list(storage_client.list_buckets())
print(buckets)
【讨论】:
这个答案提供了推荐的方法。尽可能不要使用环境变量 (GOOGLE_APPLICATION_CREDENTIALS),因为这是特定于环境的,可以由外部应用程序/用户修改。 感谢 Spiderbro(和其他所有人)的及时回复和 cmets。今天晚些时候我下班回家后,我很想尝试这个解决方案。只是一个澄清,可能是一个愚蠢的问题,但它说'service_account.json')我应该用我的.json密钥文件的绝对路径和文件名替换这个字符串?否则我看不到它是如何唯一标识我的 json 凭据文件的? 是的。由于您指向特定文件,因此您应该提供正确的路径。如果文件在当前工作目录,你可以使用上面的代码(如果文件名相同,当然)。否则,提供绝对路径。 谢谢你。我的代码现在正在处理新项目 - 非常感谢您的帮助!【参考方案2】:您是否没有配置 GOOGLE_APPLICATION_CREDENTIALS 环境变量来指向项目 A 的 SA?
【讨论】:
【参考方案3】:Google SDK 的默认行为是从环境变量 GOOGLE_APPLICATION_CREDENTIALS 中获取服务帐户。
如果您想更改帐户,可以执行以下操作:
from google.cloud import storage
credentials_json_file = os.environ.get('env_var_with_path_to_account_json')
client= storage.Client.from_service_account_json(credentials)
以上假设您已经创建了一个 json 帐户文件,例如:https://cloud.google.com/iam/docs/creating-managing-service-account-keys
并且json账户文件在环境变量env_var_with_path_to_account_json
这样您就可以拥有 2 个帐户文件并决定使用哪一个。
【讨论】:
以上是关于无法使用 python 脚本切换 gcloud 平台帐户的主要内容,如果未能解决你的问题,请参考以下文章
无法使用“gcloud spanner databases ddl update”命令执行 Spanner DDL 脚本