gsutil cp завершается успешно, но метод upload_from_filename() из клиента хранилища завершается с ошибкой

#google-cloud-storage

#google-облачное хранилище

Вопрос:

Я хочу загрузить файл в GCS с помощью клиента хранилища Google на python, но его сбой из-за проблемы с разрешениями, однако gsutil cp завершается успешно. Я не могу понять, почему.

Вот что я запустил, используя gsutil :

 BUCKET=abc
$ gcloud iam service-accounts keys create --iam-account $ACCOUNT key_file.json
created key [5006838b5984f1d3b4de6523239e9bbd2c7f7047] of type [json] as [key_file.json] for [serviceaccountname@myproject.iam.gserviceaccount.com]
$ gcloud auth activate-service-account --key-file key_file.json
Activated service account credentials for: [serviceaccountname@myproject.iam.gserviceaccount.com]
$ touch test.txt
$ gsutil cp test.txt gs://${BUCKET}/test.txt     
Copying file://test.txt [Content-Type=text/plain]...
/ [1 files][    0.0 B/    0.0 B]                                                
Operation completed over 1 objects.
  

Вот что я попытался сделать из python:

 from google.cloud import storage
import os
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'key_file.json' #same file as downloaded above
storage_client = storage.Client()
bucket_name = "abc" #the bucket name
source_file_name = "test.txt"
destination_blob_name = f"{source_file_name}"
with open(source_file_name, 'w') as f:
        f.write("lorem ipsum")
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(source_file_name)
  

Эта upload_from_filename() функция завершается с ошибкой:

google.api_core.исключения.Запрещено: 403 СООБЩЕНИЯ https://storage.googleapis.com/upload/storage/v1/b/abc/o?uploadType=multipart : («Ошибка запроса с кодом состояния», 403, «Ожидаемый один из»,ОК: 200>)

Я сбит с толку. Я бы подумал, что если бы это работало из gsutil, оно работало бы с использованием клиента хранилища python. Любые предложения будут приветствоваться.

Комментарии:

1. Будет ли этот скрипт python запускаться за пределами Google Cloud в конце (на prem, в другом облаке)?

2. Он был запущен за пределами Google cloud. Он был запущен на моем ноутбуке.

3. Да, но в конце? Он также будет работать на вашем ноутбуке? Где вы планируете развернуть этот скрипт?

4. ах, я понимаю. Этот скрипт предназначен для запуска в качестве теста в конвейере CI. Тест будет запущен для проверки наличия $ACCOUNT соответствующих разрешений для выполнения действий, которые он должен иметь возможность выполнять.

5. Привет, спасибо за ваши ответы. Я решил проблему. Пожалуйста, посмотрите ответ, который я опубликовал.

Ответ №1:

Я добрался до сути этой проблемы. Это было двояко.

  1. Я обнаружил, что код будет выполнен успешно, если объект хранилища destination_blob_name еще не существует. Если объект действительно существует, то возникнет ошибка, описанная выше.
  2. Разрешение на $ACCOUNT доступ к корзине было предоставлено пользовательской ролью, которая была применена к корзине. Когда я добавил разрешение storage.objects.get amp; storage.objects.delete к этой пользовательской роли, мой код был выполнен успешно, даже если объект уже существовал.

Я обнаружил, что storage.objects.get amp; storage.objects.delete описаны как

  • Считывает данные объекта и метаданные, исключая списки управления доступом
  • Удаление объектов

https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions

Урок, который я извлек из этого, заключается в том, что при определенных обстоятельствах (например, когда целевой объект уже существует) gsutil cp требуются разные разрешения для google.cloud.storage.blob.upload_from_filename() . Если кто-нибудь может объяснить разницу между этими двумя операциями, я бы хотел понять это лучше.

Ответ №2:

Эта ошибка (403) указывает на то, что пользователь не был авторизован Google Cloud Storage для отправки запроса, в основном вам нужно иметь в виду, что: