Доступ к облачному хранилищу Google через учетную запись службы
Я неоднократно бился головой о пресловутую кирпичную стену API хранения данных GCP.
Я пытаюсь применить модуль django-storages для соединения с GCP bucket для моих статических файлов и всего остального, для чего я хочу использовать его в будущем.
Согласно документации по django-storages (https://django-storages.readthedocs.io/en/latest/backends/gcloud.html#usage), если вы работаете в виртуальной среде GCP, вы устанавливаете для своей учетной записи службы права на Storage через интерфейс IAM, и все должно работать как по маслу.
Итак, моя программа сборки облака GCP собирает образы докеров, затем запускает python manage.py migrate и python manage.py collectstatic перед развертыванием моего образа докера в CloudRun. Программа сборки использует учетную запись службы под названием XXXX@cloudbuild.gserviceaccount.com, поэтому в IAM я добавляю роль "Cloud storage - Storage admin", а чтобы быть уверенным, я также добавляю роль "Cloud storage - Storage object admin".
Теперь я запускаю повторную сборку облака и ... на этапе миграции я получаю ошибку:
...
Step #2 - "apply migrations": File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
Step #2 - "apply migrations": return _bootstrap._gcd_import(name[level:], package, level)
Step #2 - "apply migrations": File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
Step #2 - "apply migrations": File "<frozen importlib._bootstrap>", line 991, in _find_and_load
Step #2 - "apply migrations": File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
Step #2 - "apply migrations": File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
Step #2 - "apply migrations": File "<frozen importlib._bootstrap_external>", line 843, in exec_module
Step #2 - "apply migrations": File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
Step #2 - "apply migrations": File "/src/lang/urls.py", line 20, in <module>
Step #2 - "apply migrations": re_path('favicon.ico$', RedirectView.as_view(url=staticfiles_storage.url('images/apple_touch_icon.png'), permanent=False)),
Step #2 - "apply migrations": File "/usr/local/lib/python3.8/site-packages/storages/backends/gcloud.py", line 290, in url
Step #2 - "apply migrations": return blob.generate_signed_url(
Step #2 - "apply migrations": File "/usr/local/lib/python3.8/site-packages/google/cloud/storage/blob.py", line 620, in generate_signed_url
Step #2 - "apply migrations": return helper(
Step #2 - "apply migrations": File "/usr/local/lib/python3.8/site-packages/google/cloud/storage/_signing.py", line 550, in generate_signed_url_v4
Step #2 - "apply migrations": ensure_signed_credentials(credentials)
Step #2 - "apply migrations": File "/usr/local/lib/python3.8/site-packages/google/cloud/storage/_signing.py", line 52, in ensure_signed_credentials
Step #2 - "apply migrations": raise AttributeError(
Step #2 - "apply migrations": AttributeError: you need a private key to sign credentials.the credentials you are currently using <class 'google.auth.compute_engine.credentials.Credentials'> just contains a token. see https://googleapis.dev/python/google-api-core/latest/auth.html#setting-up-a-service-account for more details.
Finished Step #2 - "apply migrations"
Ха. Я не могу пройти аутентификацию через Service Worker.
Используя код из учебника google example tutorial по django, у меня есть следующая строка в моем settings.py:
credentials, project_id = google.auth.default()
Но я ничего не делаю с возвращаемой переменной credentials. Мне кажется, что документация в Интернете немного скудна в отношении того, как получить доступ к ведрам через учетные записи служб. Есть какие-нибудь соображения?
Я нашел пользователя с аналогичной проблемой: https://pnote.eu/notes/django-app-engine-user-uploaded-files/
Похоже, что проблема возникает для ведер, политика доступа к которым имеет значение Uniform, а не fine-grained. Автор вышеупомянутой статьи обратился с проблемой в django-storage, и в итоге исправление было внесено. Теперь в документации есть поле "Примечание", которое я пропустил и которое гласит:
GS_DEFAULT_ACL: При использовании этой настройки убедитесь, что в вашем ведре включен тонкий контроль доступа, а не единый контроль доступа, иначе при загрузке файлов будет выдаваться HTTP 400. Если у вас уже есть ведро с Единым контролем доступа, установленным на public read, пожалуйста, установите GS_DEFAULT_ACL на None и GS_QUERYSTRING_AUTH на False.
.
Короче говоря, решение заключается в том, чтобы добавить в файл settings.py:
GS_QUERYSTRING_AUTH = False