Як зробити 10000 файлів у S3 загальнодоступними


92

У мене є папка у відрі з 10000 файлами. Здається, немає можливості завантажити їх і негайно опублікувати. Тому я завантажив їх усіх, вони приватні, і мені потрібно зробити їх загальнодоступними.

Я спробував консоль aws, вона просто видає помилку (чудово працює з папками з меншою кількістю файлів).

Я пробував використовувати організацію S3 у Firefox, те саме.

Чи існує якесь програмне забезпечення чи якийсь сценарій, який я можу запустити, щоб зробити все це загальнодоступним?


4
Кожен інструмент, який я спробував, зазнав аварії, тому в підсумку я написав PHP-скрипт, який зайняв кілька годин, і просто переглянув кожен об’єкт у відрі та зробив його загальнодоступним.
PeterV

Відповіді:


119

Ви можете створити політику сегмента (див. Приклад нижче), яка надає доступ до всіх файлів у сегменті. Політику сегмента можна додати до сегмента через консоль 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 мільйона об'єктів ... якось дратує
Блейк Міллер

вам потрібно змінити "відро" на ім'я вашого відра
karnage

11
Мені неприємно робити це таким чином. Це якийсь потворний JSON.
надсвітлий

6
Тільки примітка: Це може здатися очевидним, але ви також можете обмежити доступ до певних папок : bucket/avatars/*. (Не забувайте *в кінці. Я це зробив і деякий час бігав по колах.)
bschaeffer

2
@Benjamin Те, що для вас є "базовою" конфігурацією, не підходить для інших, оскільки вимоги до безпеки у всіх різні. AWS забезпечує єдиний спосіб налаштування цих політик. Тому потрібно витратити час, щоб правильно вивчити політику безпеки і не цуратися кількох простих рядків JSON.
afilina

69

Якщо ви завантажуєте вперше, ви можете встановити, щоб файли були загальнодоступними при завантаженні в командному рядку:

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

(Отже, це вже не відповідає на питання, а залишає відповідь для довідки, як це раніше працювало.)


Чи виконується ця команда для файлів, які вже завантажені, але ще не прочитані?
Алстон,

10
Коли я тестував його, здається, додає ACL лише до нещодавно синхронізованих файлів.
Девід Руссель

Дякую за повторне відтворення, я теж тестував. Чи є способи пакетної зміни дозволу завантажених файлів?
Алстон,

О, не дивно. Мене це розгубило. Дуже вдячний за роз'яснення.
Шрідхар Сарнобат

Відповідь оновлено, щоб включити спосіб зміни існуючих файлів.
Девід Руссель,

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

1
Найпростіший спосіб - завантажити їх із встановленим прапором public_read, але якщо це не вдасться, це хороший варіант.
надсвітлий

Цей вирізаний код застарілий, зверніться до моєї відповіді
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 У моєму випадку мені потрібно змінити загальнодоступні на приватні дозволи, тому замінити public-read на private, і доступ змінився, але все ж я можу отримати доступ до URL-адреси?
Рахул,

19

Просто хотів додати, що за допомогою нової консолі S3 ви можете вибрати свої папки та вибрати, Make publicщоб зробити всі файли в папках загальнодоступними. Він працює як фонове завдання, тому повинен обробляти будь-яку кількість файлів.

Зробити загальнодоступним


5
На жаль, це займає багато часу, і ви не можете закрити браузер, поки команда виконується. Ваш браузер надсилає 2 запити на кожен файл, у моєму випадку два запити зайняли 500 мс. Якщо у вас багато файлів, це займе багато часу = (
Herlon Aguiar

2
І є ще одна проблема: це зробить повністю публічним. Якщо ви хочете лише доступ для загального читання, це проблема.
Марсело Агімовель

БУДЬТЕ ДУЖЕ ДІАГАДЖАНИМ - я зробив це “Зробити загальнодоступним”, і спливаюча панель прогресу настільки тонка, що я думав, що це було зроблено. Я перевірив і, мабуть, цілу годину працював над цим, перш ніж зрозумів, що ти натискаєш Зробити загальнодоступним і маленький тонкий "з'являється індикатор прогресу" ... grrr ... оскільки я закрив вікно браузера приблизно 10 разів, я припускаю, що кожен раз вбивав його . Я запускаю це зараз - це досить швидко - можливо, 20 хвилин для 120 тисяч зображень
Скотт

11

Використання 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)}'
сакурашинкен

3

Якби це було мені потрібно, але кількість файлів робить це ШАЙБНО повільно робити послідовно. Тому я написав сценарій , який робить це на iron.io «s металіст служби. Їх 500 безкоштовних обчислювальних годин на місяць достатньо, щоб обробляти навіть великі відра (і якщо ви все-таки перевищуєте, ціна є розумною). Оскільки це робиться паралельно, воно завершується менш ніж за хвилину для 32 000 об’єктів, які я мав. Також я вважаю, що їх сервери працюють на EC2, тому зв’язок між роботою та S3 є швидким.

Будь-хто може використовувати мій сценарій для власних потреб.


2

Погляньте на BucketExplorer, він дуже добре управляє масовими операціями і є надійним клієнтом S3.


3
Також тепер можна масово змінювати дозволи в Cyberduck (безкоштовно) за допомогою палітри Info.
Тейлор Едмістон,

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 об’єктів ACL, ви можете написати сценарій, але, мабуть, простіше скористатися інструментом графічного інтерфейсу, щоб вирішити негайну проблему. Найкраще, що я використовував дотепер, - від компанії під назвою морошка для S3; схоже, вони мають безкоштовну 15-денну пробну версію принаймні для одного з своїх продуктів. Я щойно перевірив, що це дозволить вам вибрати декілька об’єктів одночасно та встановити їх ACL загальнодоступним через контекстне меню. Насолоджуйтесь хмарою!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.