Come rendere pubblici 10.000 file in S3


92

Ho una cartella in un secchio con 10.000 file. Sembra che non ci sia modo di caricarli e renderli pubblici immediatamente. Quindi li ho caricati tutti, sono privati ​​e devo renderli tutti pubblici.

Ho provato la console aws, dà solo un errore (funziona bene con cartelle con meno file).

Ho provato a utilizzare l'organizzazione di S3 in Firefox, stessa cosa.

C'è qualche software o qualche script che posso eseguire per renderli pubblici?


4
Ogni strumento che ho provato si è arrestato in modo anomalo, quindi ho finito per scrivere uno script PHP che ha richiesto alcune ore e ha semplicemente eseguito il loop di ogni oggetto nel bucket e lo ha reso pubblico.
PeterV

Risposte:


119

È possibile generare una policy del bucket (vedere l'esempio di seguito) che dà accesso a tutti i file nel bucket. La policy del bucket può essere aggiunta a un bucket tramite la console AWS.

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

Guarda anche il seguente strumento di generazione di policy fornito da Amazon.

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


5
Questo non ha funzionato per me. Alcuni oggetti stanno ancora restituendo la risposta "accesso negato" anche con la policy del bucket in atto. Viene copiato e incollato da quanto sopra con solo il nome del bucket modificato. Immagino sia ora di scrivere una sceneggiatura per scorrere tutti gli 1,3 milioni di oggetti ... un po 'irritante
Blake Miller

devi cambiare "bucket" nel nome del tuo bucket
karnage

11
Mi dispiace doverlo fare in questo modo. È un brutto JSON.
superluminario

6
Solo una nota: Può sembrare ovvio, ma si può anche scegliere di limitare l'accesso a specifiche cartelle : bucket/avatars/*. (Non dimenticare la *fine. L'ho fatto e ho corso in tondo per un po '.)
bschaeffer

2
@Benjamin La configurazione "di base" per te non è appropriata per gli altri, perché i requisiti di sicurezza di ognuno sono diversi. AWS fornisce un modo uniforme per personalizzare queste policy. Pertanto, è necessario dedicare del tempo ad apprendere correttamente le politiche di sicurezza e non rifuggire da poche semplici righe di JSON.
afilina

69

Se stai caricando per la prima volta, puoi impostare i file come pubblici al caricamento sulla riga di comando:

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

Come documentato in Utilizzo dei comandi s3 di alto livello con l'interfaccia a riga di comando di AWS

Sfortunatamente applica l'ACL solo quando i file vengono caricati. Non applica (nei miei test) l'ACL ai file già caricati.

Se desideri aggiornare gli oggetti esistenti, eri in grado di sincronizzare il bucket con se stesso, ma sembra che questo abbia smesso di funzionare.

[Non funziona più] Questo può essere fatto dalla riga di comando:

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

(Quindi questo non risponde più alla domanda, ma lascia la risposta come riferimento come funzionava).


Questo comando viene effettuato sui file già caricati ma non ancora letti pubblicamente?
Alston

10
Quando l'ho testato, sembra aggiungere solo l'ACL ai file appena sincronizzati.
David Roussel

Grazie per il replay, l'ho provato anche io. Esistono modi per modificare in batch l'autorizzazione dei file caricati?
Alston

Oh, non c'è da stupirsi. Questo mi ha confuso. Ho davvero apprezzato il tuo chiarimento.
Sridhar Sarnobat

Risposta aggiornata per includere come modificare i file esistenti.
David Roussel,

34

Ho dovuto cambiare diverse centinaia di migliaia di oggetti. Ho attivato un'istanza EC2 per eseguirlo, il che rende tutto più veloce. Ti consigliamo di installare il fileaws-sdk prima gemma.

Ecco il codice:

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
Il modo più semplice è caricarli con il flag public_read impostato in primo luogo, ma in caso contrario, questa è una buona opzione.
superluminario

Questo codice ritagliato è obsoleto, fare riferimento alla mia risposta
ksarunas

26

Ho avuto lo stesso problema, la soluzione di @DanielVonFange è obsoleta, poiché è uscita la nuova versione di SDK.

Aggiunta di snippet di codice che funzioni subito con 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
Risposta fantastica - solo la sceneggiatura di cui avevo bisogno in un punto
difficile

@ksarunas Nel mio caso, ho bisogno di cambiare le autorizzazioni da pubblico a privato, quindi sostituisci public-read con private e l'accesso è stato modificato ma comunque, sono in grado di accedere all'URL?
Rahul,

19

Volevo solo aggiungere che con la nuova console S3 è possibile selezionare le cartelle e selezionare Make publicper rendere pubblici tutti i file all'interno delle cartelle. Funziona come un'attività in background, quindi dovrebbe gestire un numero qualsiasi di file.

Rendere pubblico


5
Sfortunatamente ci vuole molto tempo e non puoi chiudere il browser mentre il comando è runner. Il tuo browser sta inviando 2 richieste per ogni file, nel mio caso le due richieste hanno richiesto 500ms. Se hai molti file, ci vorrà molto tempo = (
Herlon Aguiar

2
E c'è un altro problema: questo renderà completamente pubblico. Se desideri solo l'accesso in lettura pubblica, questo è un problema.
Marcelo Agimóvel

STA MOLTO CONSAPEVOLE - Ho fatto questo Rendi pubblico e la "barra di avanzamento" che si apre è così sottile che pensavo fosse finita. Ho controllato e probabilmente ho passato un'ora a lavorarci prima di rendermi conto che hai fatto clic su Rendi pubblico e una piccola sottile "barra di avanzamento viene visualizzata" ... grrr ... dato che ho chiuso la finestra del browser circa 10 volte, presumo che l'abbia ucciso ogni volta . Lo sto eseguendo ora - è abbastanza veloce - forse 20 minuti per 120.000 immagini
Scott

11

Utilizzando il 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
non potresti semplicemente usare una pipe per grep invece di scrivere su disco con tutti i files.txt? Può essereaws 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

3

Avevo questo bisogno da solo, ma il numero di file rende MODO rallentare per farlo in serie. Così ho scritto uno script che lo fa sull'IronWorker di iron.io servizio. Le loro 500 ore di elaborazione gratuite al mese sono sufficienti per gestire bucket anche di grandi dimensioni (e se lo superi, il prezzo è ragionevole). Dato che è fatto in parallelo, si completa in meno di un minuto per i 32.000 oggetti che avevo. Inoltre credo che i loro server girino su EC2, quindi la comunicazione tra il lavoro e S3 è veloce.

Chiunque può usare il mio copione per i propri bisogni.


2

Dai un'occhiata a BucketExplorer , gestisce molto bene le operazioni di massa ed è un solido client S3.


3
Ora è anche possibile modificare in blocco le autorizzazioni in Cyberduck (gratuito) tramite la palette Info.
Taylor Edmiston

BucketExplorer è utile solo se si dispone dell'autorizzazione per elencare tutti i bucket. Molto meglio usare la CLI o un SDK per questa operazione e lasciare agli utenti autorizzazioni limitate.
perilandmishap

0

Penseresti che renderebbero pubblico leggere il comportamento predefinito, vero? :) Ho condiviso la tua frustrazione durante la creazione di un'API personalizzata per interfacciarsi con S3 da una soluzione C #. Ecco lo snippet che esegue il caricamento di un oggetto S3 e l'impostazione predefinita per l'accesso in lettura pubblica:

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));
     }
}

La funzione ToACLString (acl) restituisce public-read , BASE_SERVICE_URL è s3.amazonaws.com e la costante AWS_ACL_HEADER è x-amz-acl . Il plug e il materiale di DreamMessage probabilmente ti sembreranno strani poiché utilizziamo il framework Dream per semplificare le nostre comunicazioni http. Essenzialmente stiamo eseguendo un PUT http con le intestazioni specificate e una firma di intestazione speciale per le specifiche aws (vedere questa pagina nei documenti aws per esempi su come costruire l'intestazione di autorizzazione).

Per modificare un 1000 ACL di oggetti esistenti è possibile scrivere uno script, ma probabilmente è più semplice utilizzare uno strumento GUI per risolvere il problema immediato. Il migliore che ho usato finora proviene da una società chiamata cloudberry per S3; sembra che abbiano una prova gratuita di 15 giorni per almeno uno dei loro prodotti. Ho appena verificato che ti consentirà di selezionare più oggetti contemporaneamente e di impostare il loro ACL su pubblico tramite il menu contestuale. Goditi il ​​cloud!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.