gsutil 和存储客户端之间对存储桶子文件夹的访问不一致
Inconsistent access to subfolder of a bucket between gsutil and storage Client
为了避免为从许多设备接收到的数据管理大量存储桶,我计划让他们将捕获的文件写入单个存储桶的文件夹中,而不是每个设备一个存储桶。
为了确保每个设备只能写入其子文件夹,我将IAM条件设置为described in this answer:
resource.name.startsWith('projects/_/buckets/dev_bucket/objects/test_folder')
我的服务帐户现在具有附加了上述条件的 Storage Object Creator
和 Storage Object viewer
角色。
这是 gcloud get-iam-policy <project>
命令
的(仅截断到此服务帐户的)输出
- condition:
expression: |-
resource.name.startsWith("projects/_/buckets/dev_bucket/objects/test_folder/")
title: only_test_subfolder
members:
- serviceAccount:myserviceaccount.iam.gserviceaccount.com
role: roles/storage.objectCreator
- condition:
expression: |-
resource.name.startsWith("projects/_/buckets/dev_bucket/objects/test_folder/")
title: only_test_subfolder
members:
- serviceAccount:myserviceaccount.iam.gserviceaccount.com
role: roles/storage.objectViewer
当使用 gsutil
命令时,一切似乎都正常
# Set the authentication via the service account json key
gcloud auth activate-service-account --key-file=/path/to/my/key.json
# all of these commands work fine
gcloud ls gs://dev_bucket/test_folder
gcloud cp gs://dev_bucket/test_folder/distant_file.txt local_file.txt
# These ones get a 403 as expected
gcloud ls gs://dev_bucket/
gcloud ls gs://another_bucket
gcloud_cp gs://dev_bucket/another_subfolder/somefile.txt local_file.txt
但是,当我尝试使用 google 存储客户端 (v 2.1.0) 时,我无法让它工作,主要是因为我应该在获取对象之前定义存储桶桶.
import os
from google.cloud import storage
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="path/to/my/key.json"
client = storage.Client()
client.get_bucket("dev_bucket")
>>> Forbidden: 403 GET https://storage.googleapis.com/storage/v1/b/dev_bucket?projection=noAcl&prettyPrint=false: <Service account> does not have storage.buckets.get access to the Google Cloud Storage bucket.
我也曾尝试使用前缀参数列出所有文件,但得到了同样的错误:
client.list_blobs("dev_bucket", prefix="test_folder")
有没有办法使用具有此类权限的 python 存储客户端?
这是预期的行为!
您正在做:
gsutil ls gs://dev_bucket/test_folder
gsutil cp gs://dev_bucket/test_folder/distant_file.txt local_file.txt
除了您的 SA 从角色 Storage Object viewer
获得的 storage.objects.get
之外,这两个命令不需要任何其他权限
但是 在你的代码中你试图访问存储桶的详细信息(存储桶本身,而不是存储桶内的对象)所以它不会工作,除非你的 SA 有权限storage.buckets.get
这一行:
client.get_bucket("dev_bucket")
将在 v1/buckets/get
上执行 GET
方法,这需要上述 IAM 权限。
因此,您需要修改代码以仅读取对象而不访问存储桶详细信息。
Here 是从存储桶下载对象的示例代码。
注意:此示例代码中使用的方法 bucket(bucket_name, user_project=None)
不会执行任何引用自 docs.
的 HTTP 请求
This will not make an HTTP request; it simply instantiates a bucket object owned by this client.
顺便说一句,您可以尝试 运行 类似的东西:
gsutil ls -L -b gs://dev_bucket
我希望此命令给您带来与您从代码中得到的相同的错误。
参考文献:
https://cloud.google.com/storage/docs/access-control/iam-gsutil
https://cloud.google.com/storage/docs/access-control/iam-json
为了避免为从许多设备接收到的数据管理大量存储桶,我计划让他们将捕获的文件写入单个存储桶的文件夹中,而不是每个设备一个存储桶。
为了确保每个设备只能写入其子文件夹,我将IAM条件设置为described in this answer:
resource.name.startsWith('projects/_/buckets/dev_bucket/objects/test_folder')
我的服务帐户现在具有附加了上述条件的 Storage Object Creator
和 Storage Object viewer
角色。
这是 gcloud get-iam-policy <project>
命令
- condition:
expression: |-
resource.name.startsWith("projects/_/buckets/dev_bucket/objects/test_folder/")
title: only_test_subfolder
members:
- serviceAccount:myserviceaccount.iam.gserviceaccount.com
role: roles/storage.objectCreator
- condition:
expression: |-
resource.name.startsWith("projects/_/buckets/dev_bucket/objects/test_folder/")
title: only_test_subfolder
members:
- serviceAccount:myserviceaccount.iam.gserviceaccount.com
role: roles/storage.objectViewer
当使用 gsutil
命令时,一切似乎都正常
# Set the authentication via the service account json key
gcloud auth activate-service-account --key-file=/path/to/my/key.json
# all of these commands work fine
gcloud ls gs://dev_bucket/test_folder
gcloud cp gs://dev_bucket/test_folder/distant_file.txt local_file.txt
# These ones get a 403 as expected
gcloud ls gs://dev_bucket/
gcloud ls gs://another_bucket
gcloud_cp gs://dev_bucket/another_subfolder/somefile.txt local_file.txt
但是,当我尝试使用 google 存储客户端 (v 2.1.0) 时,我无法让它工作,主要是因为我应该在获取对象之前定义存储桶桶.
import os
from google.cloud import storage
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="path/to/my/key.json"
client = storage.Client()
client.get_bucket("dev_bucket")
>>> Forbidden: 403 GET https://storage.googleapis.com/storage/v1/b/dev_bucket?projection=noAcl&prettyPrint=false: <Service account> does not have storage.buckets.get access to the Google Cloud Storage bucket.
我也曾尝试使用前缀参数列出所有文件,但得到了同样的错误:
client.list_blobs("dev_bucket", prefix="test_folder")
有没有办法使用具有此类权限的 python 存储客户端?
这是预期的行为!
您正在做:
gsutil ls gs://dev_bucket/test_folder
gsutil cp gs://dev_bucket/test_folder/distant_file.txt local_file.txt
除了您的 SA 从角色 Storage Object viewer
storage.objects.get
之外,这两个命令不需要任何其他权限
但是 在你的代码中你试图访问存储桶的详细信息(存储桶本身,而不是存储桶内的对象)所以它不会工作,除非你的 SA 有权限storage.buckets.get
这一行:
client.get_bucket("dev_bucket")
将在 v1/buckets/get
上执行 GET
方法,这需要上述 IAM 权限。
因此,您需要修改代码以仅读取对象而不访问存储桶详细信息。
Here 是从存储桶下载对象的示例代码。
注意:此示例代码中使用的方法 bucket(bucket_name, user_project=None)
不会执行任何引用自 docs.
This will not make an HTTP request; it simply instantiates a bucket object owned by this client.
顺便说一句,您可以尝试 运行 类似的东西:
gsutil ls -L -b gs://dev_bucket
我希望此命令给您带来与您从代码中得到的相同的错误。
参考文献:
https://cloud.google.com/storage/docs/access-control/iam-gsutil https://cloud.google.com/storage/docs/access-control/iam-json