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


93

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

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

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

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


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.


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 общедоступными через контекстное меню. Наслаждайтесь облаком!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.