Как сделать 10 000 файлов в S3 общедоступными

93

У меня в ведре папка с 10 000 файлов. Кажется, нет возможности загрузить их и сразу же опубликовать. Я загрузил их все, они частные, и мне нужно сделать их общедоступными.

Пробовал консоль aws, просто выдает ошибку (отлично работает с папками с меньшим количеством файлов).

Я пробовал использовать организацию S3 в Firefox, то же самое.

Есть ли какое-нибудь программное обеспечение или какой-нибудь сценарий, который я могу запустить, чтобы сделать все это общедоступным?

ПетрV
источник
4
Каждый инструмент, который я пробовал, давал сбой, поэтому я закончил тем, что написал сценарий PHP, который занял несколько часов, и просто перебрал каждый объект в корзине и сделал его общедоступным.
PeterV 01

Ответы:

120

Вы можете создать политику корзины (см. Пример ниже), которая дает доступ ко всем файлам в корзине. Политику корзины можно добавить в корзину через консоль AWS.

{
    "Id": "...",
    "Statement": [ {
        "Sid": "...",
        "Action": [
            "s3:GetObject"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::bucket/*",
        "Principal": {
            "AWS": [ "*" ]
        }
    } ]
}

Также посмотрите следующий инструмент генератора политик, предоставленный Amazon.

http://awspolicygen.s3.amazonaws.com/policygen.html

Раджив
источник
5
У меня это не сработало. Некоторые объекты по-прежнему возвращают ответ «доступ запрещен» даже при наличии политики корзины. Он скопирован из приведенного выше с изменением только имени сегмента. Думаю, пришло время написать сценарий для перебора всех 1,3 миллиона объектов ... немного раздражает,
Блейк Миллер
вам нужно изменить "bucket" на название вашего ведра
karnage
11
Мне не нравится делать это таким образом. Какой-то уродливый JSON.
superluminary
7
Только примечание: Это может показаться очевидным, но вы также можете ограничить доступ к определенным папкам : bucket/avatars/*. (Не забывайте *в конце. Я сделал и некоторое время бегал по кругу.)
bschaeffer
2
@Benjamin Какая у вас "базовая" конфигурация не подходит для других, потому что требования безопасности у всех разные. AWS предоставляет единый способ настройки этих политик. Поэтому нужно потратить время на то, чтобы правильно изучить политики безопасности и не уклоняться от нескольких простых строк JSON.
афилина
71

Если вы загружаете в первый раз, вы можете сделать файлы общедоступными при загрузке в командной строке:

aws s3 sync . s3://my-bucket/path --acl public-read

Как описано в разделе Использование команд s3 высокого уровня с интерфейсом командной строки AWS

К сожалению, ACL применяется только тогда, когда файлы загружены. Он (в моем тестировании) не применяет ACL к уже загруженным файлам.

Если вы действительно хотите обновить существующие объекты, раньше вы могли синхронизировать ведро с самим собой, но, похоже, это перестало работать.

[Больше не работает] Это можно сделать из командной строки:

aws s3 sync s3://my-bucket/path s3://my-bucket/path --acl public-read

(Так что это больше не отвечает на вопрос, но оставляю ответ для справки, поскольку раньше он работал.)

Давид Руссель
источник
Эта команда применяется к файлам, которые уже загружены, но еще не доступны для чтения?
Alston
10
Когда я его протестировал, мне показалось, что ACL добавляется только к недавно синхронизированным файлам.
Дэвид Руссель
Спасибо за повтор, тоже тестировал. Есть ли способы пакетного изменения разрешений загружаемых файлов?
Alston
О, неудивительно. Меня это смутило. Очень признателен за разъяснения.
Шридхар Сарнобат
Обновлен ответ, в котором рассказывается, как изменить существующие файлы.
Дэвид Руссель
34

Пришлось поменять несколько сотен тысяч объектов. Я запустил инстанс EC2, чтобы запустить это, что ускоряет работу. aws-sdkСначала вы захотите установить драгоценный камень.

Вот код:

require 'rubygems'
require 'aws-sdk'


# Change this stuff.
AWS.config({
    :access_key_id => 'YOURS_HERE',
    :secret_access_key => 'YOURS_HERE',
})
bucket_name = 'YOUR_BUCKET_NAME'


s3 = AWS::S3.new()
bucket = s3.buckets[bucket_name]
bucket.objects.each do |object|
    puts object.key
    object.acl = :public_read
end
Даниэль фон Фанге
источник
2
Самый простой способ - загрузить их с установленным флагом public_read в первую очередь, но в противном случае это хороший вариант.
superluminary
Этот фрагмент кода устарел, обратитесь к моему ответу
ksarunas
26

У меня была такая же проблема, решение @DanielVonFange устарело, так как новая версия SDK отсутствует.

Добавление фрагмента кода, который сейчас работает у меня с AWS Ruby SDK:

require 'aws-sdk'

Aws.config.update({
  region: 'REGION_CODE_HERE',
  credentials: Aws::Credentials.new(
    'ACCESS_KEY_ID_HERE',
    'SECRET_ACCESS_KEY_HERE'
  )
})
bucket_name = 'BUCKET_NAME_HERE'

s3 = Aws::S3::Resource.new
s3.bucket(bucket_name).objects.each do |object|
  puts object.key
  object.acl.put({ acl: 'public-read' })
end
ксарунас
источник
1
Фантастический ответ - как раз тот сценарий, который мне нужен в трудном месте
Phantomwhale
@ksarunas В моем случае мне нужно изменить общедоступные разрешения на частные, поэтому замените общедоступное чтение на частное, и доступ изменился, но все же я могу получить доступ к URL-адресу?
Рахул
19

Просто хотел добавить, что с новой консолью S3 вы можете выбрать свои папки и Make publicсделать все файлы внутри папок общедоступными. Он работает как фоновая задача, поэтому должен обрабатывать любое количество файлов.

Опубликовать

Сельчук
источник
5
К сожалению, это занимает много времени, и вы не можете закрыть браузер, пока команда запущена. Ваш браузер отправляет 2 запроса для каждого файла, в моем случае два запроса заняли 500 мс. Если у вас много файлов, это займет много времени = (
Херлон Агияр,
2
И еще одна проблема: это станет достоянием общественности. Если вам нужен только публичный доступ для чтения, это проблема.
Марсело Агимовель
БУДЬТЕ ВНИМАТЕЛЬНЫ - я сделал это «Сделать общедоступным», и всплывающая «полоса прогресса» настолько тонкая, что я думал, что это было сделано. Я проверил и, вероятно, потратил час, работая над этим, прежде чем понял, что вы нажимаете кнопку «Сделать общедоступной» и появляется небольшая тонкая «полоса прогресса» ... гррр ... поскольку я закрыл окно браузера примерно 10 раз, я предполагаю, что убивал его каждый раз . Я запускаю его сейчас - это довольно быстро - может быть, 20 минут для 120k изображений
Скотт
12

Используя cli:

aws s3 ls s3://bucket-name --recursive > all_files.txt && grep .jpg all_files.txt > files.txt && cat files.txt | awk '{cmd="aws s3api put-object-acl --acl public-read --bucket bucket-name --key "$4;system(cmd)}'

Александр Витанов
источник
3
не могли бы вы просто использовать канал для grep вместо записи на диск со всеми файлами files.txt? Это может бытьaws s3 ls s3://bucket-name --recursive | grep .jpg | awk '{cmd="aws s3api put-object-acl --acl public-read --bucket bucket-name --key "$4;system(cmd)}'
sakurashinken 08
3

Если бы это было нужно мне, но количество файлов делает его ПУТЬ медленно делать в последовательном режиме. Поэтому я написал сценарий , который делает это на iron.io «s металлист службы. Их 500 бесплатных часов вычислений в месяц достаточно, чтобы обрабатывать даже большие сегменты (и если вы превысите это количество, то цена будет разумной). Поскольку это делается параллельно, для 32 000 объектов, которые у меня были, он завершается менее чем за минуту. Также я считаю, что их серверы работают на EC2, поэтому связь между заданием и S3 происходит быстро.

Любой желающий может использовать мой скрипт для собственных нужд.

Эрик Андерсон
источник
2

Взгляните на BucketExplorer, он очень хорошо управляет массовыми операциями и является надежным клиентом S3.

Willbt
источник
3
Также теперь можно массово изменять разрешения в Cyberduck (бесплатно) через палитру информации.
Тейлор Эдмистон
BucketExplorer полезен только в том случае, если у вас есть разрешение на перечисление всех сегментов. Намного лучше использовать CLI или SDK для этой операции и оставить вашим пользователям ограниченные права.
perilandmishap
0

Вы могли бы подумать, что они обнародуют поведение по умолчанию, не так ли? :) Я поделился вашим разочарованием при создании пользовательского API для взаимодействия с S3 из решения C #. Вот фрагмент, который выполняет загрузку объекта S3 и по умолчанию устанавливает для него общий доступ для чтения:

public void Put(string bucketName, string id, byte[] bytes, string contentType, S3ACLType acl) {
     string uri = String.Format("https://{0}/{1}", BASE_SERVICE_URL, bucketName.ToLower());
     DreamMessage msg = DreamMessage.Ok(MimeType.BINARY, bytes);
     msg.Headers[DreamHeaders.CONTENT_TYPE] = contentType;
     msg.Headers[DreamHeaders.EXPECT] = "100-continue";
     msg.Headers[AWS_ACL_HEADER] = ToACLString(acl);
     try {
        Plug s3Client = Plug.New(uri).WithPreHandler(S3AuthenticationHeader);
        s3Client.At(id).Put(msg);
     } catch (Exception ex) {
        throw new ApplicationException(String.Format("S3 upload error: {0}", ex.Message));
     }
}

Функция ToACLString (acl) возвращает общедоступное чтение , BASE_SERVICE_URL - s3.amazonaws.com, а константа AWS_ACL_HEADER - x-amz-acl . Подключаемые модули и DreamMessage могут показаться вам странными, поскольку мы используем фреймворк Dream для оптимизации наших HTTP-коммуникаций. По сути, мы выполняем HTTP PUT с указанными заголовками и специальной подписью заголовка в соответствии со спецификациями aws (см. Эту страницу в документации aws для примеров того, как создать заголовок авторизации).

Чтобы изменить существующие списки управления доступом к 1000 объектам, вы можете написать сценарий, но, вероятно, проще использовать инструмент с графическим интерфейсом, чтобы исправить немедленную проблему. Лучшее, что я использовал до сих пор, принадлежит компании под названием cloudberry for S3; похоже, что у них есть бесплатная 15-дневная пробная версия по крайней мере для одного из своих продуктов. Я только что проверил, что это позволит вам выбрать сразу несколько объектов и сделать их ACL общедоступными через контекстное меню. Наслаждайтесь облаком!

Тахбаза
источник