Comment rendre public 10000 fichiers dans S3

92

J'ai un dossier dans un seau avec 10 000 fichiers. Il semble qu'il n'y ait aucun moyen de les télécharger et de les rendre publics immédiatement. Alors je les ai tous téléchargés, ils sont privés et je dois les rendre tous publics.

J'ai essayé la console aws, cela donne juste une erreur (fonctionne bien avec les dossiers avec moins de fichiers).

J'ai essayé d'utiliser l'organisation S3 dans Firefox, même chose.

Existe-t-il un logiciel ou un script que je peux exécuter pour rendre tout cela public?

PeterV
la source
4
Chaque outil que j'ai essayé s'est écrasé, j'ai donc fini par écrire un script PHP qui a pris quelques heures et qui a simplement parcouru chaque objet du seau et l'a rendu public.
PeterV

Réponses:

119

Vous pouvez générer une stratégie de compartiment (voir l'exemple ci-dessous) qui donne accès à tous les fichiers du compartiment. La stratégie de compartiment peut être ajoutée à un compartiment via la console AWS.

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

Regardez également l'outil de génération de politiques suivant fourni par Amazon.

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

Rajiv
la source
5
Cela n'a pas fonctionné pour moi. Certains objets renvoient toujours la réponse «Accès refusé» même avec la stratégie de compartiment en place. Il est copié à partir de ce qui précède avec seul le nom du compartiment modifié. Je suppose qu'il est temps d'écrire un script pour parcourir les 1,3 million d'objets ... un peu irritant
Blake Miller
vous devez remplacer "bucket" par le nom de votre bucket
karnage
11
Je n'aime pas devoir le faire de cette façon. C'est un JSON laid.
Superluminary
6
Juste une remarque: Cela peut sembler évident, mais vous pouvez aussi choisir de limiter l' accès aux spécifiques dossiers : bucket/avatars/*. (N'oubliez pas le *à la fin. Je l'ai fait et j'ai
tourné
2
@Benjamin Ce qui est une configuration "basique" pour vous est inapproprié pour les autres, car les exigences de sécurité de chacun sont différentes. AWS fournit un moyen uniforme de personnaliser ces stratégies. Par conséquent, il faut prendre le temps d'apprendre correctement les politiques de sécurité et ne pas se dérober à quelques lignes simples de JSON.
afilina
69

Si vous téléchargez pour la première fois, vous pouvez définir les fichiers comme publics lors du téléchargement sur la ligne de commande:

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

Comme indiqué dans Utilisation des commandes s3 de haut niveau avec l'interface de ligne de commande AWS

Malheureusement, il n'applique l'ACL que lorsque les fichiers sont téléchargés. Il n'applique pas (dans mes tests) l'ACL aux fichiers déjà téléchargés.

Si vous souhaitez mettre à jour des objets existants, vous pouviez auparavant synchroniser le compartiment avec lui-même, mais cela semble avoir cessé de fonctionner.

[Ne fonctionne plus] Cela peut être fait à partir de la ligne de commande:

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

(Donc, cela ne répond plus à la question, mais en laissant la réponse pour référence, car cela fonctionnait.)

David Roussel
la source
Cette commande est-elle appliquée aux fichiers déjà téléchargés mais pas encore lus publiquement?
Alston
10
Lorsque je l'ai testé, il semble ajouter uniquement l'ACL aux fichiers nouvellement synchronisés.
David Roussel
Merci pour la relecture, je l'ai testé aussi. Existe-t-il des moyens de modifier par lots l'autorisation des fichiers téléchargés?
Alston le
Oh, pas étonnant. J'étais confus par cela. Vraiment apprécié votre clarification.
Sridhar Sarnobat
Réponse mise à jour pour inclure comment modifier les fichiers existants.
David Roussel le
34

J'ai dû changer plusieurs centaines de milliers d'objets. J'ai lancé une instance EC2 pour l'exécuter, ce qui accélère le processus. Vous voudrez d'abord installer la aws-sdkgemme.

Voici le code:

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
Daniel Von Fange
la source
1
Le moyen simple est de les télécharger avec l'indicateur public_read défini en premier lieu, mais à défaut, c'est une bonne option.
Superluminary
Ce code extrait est obsolète, reportez-vous à ma réponse
ksarunas
26

J'ai eu le même problème, la solution de @DanielVonFange est obsolète, car la nouvelle version du SDK est sortie.

Ajout d'un extrait de code qui fonctionne pour moi en ce moment avec 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
ksarunas
la source
1
Réponse fantastique - juste le script dont j'avais besoin dans un endroit difficile
Phantomwhale
@ksarunas Dans mon cas, je dois changer les autorisations publiques en autorisations privées, alors remplacez public-read par private et l'accès a été modifié mais je peux quand même accéder à l'URL?
Rahul
19

Je voulais juste ajouter qu'avec la nouvelle console S3, vous pouvez sélectionner vos dossiers et choisir Make publicde rendre tous les fichiers à l'intérieur des dossiers publics. Il fonctionne comme une tâche d'arrière-plan et doit donc gérer n'importe quel nombre de fichiers.

Rendre publique

Selcuk
la source
5
Malheureusement, cela prend beaucoup de temps et vous ne pouvez pas fermer le navigateur tant que la commande est exécutée. Votre navigateur envoie 2 requêtes pour chaque fichier, dans mon cas, les deux requêtes ont pris 500ms. Si vous avez beaucoup de fichiers, cela prendra beaucoup de temps = (
Herlon Aguiar
2
Et, il y a un autre problème: cela rendra entièrement public. Si vous souhaitez uniquement un accès en lecture publique, c'est un problème.
Marcelo Agimóvel
SOYEZ TRÈS CONSCIENT - J'ai fait cela Rendre public et la "barre de progression" qui apparaît est si subtile, je pensais que c'était fait. J'ai vérifié et j'ai probablement passé une heure à travailler dessus avant de réaliser que vous cliquez sur Rendre public et une petite barre de progression subtile apparaît ... grrr ... puisque j'ai fermé la fenêtre du navigateur environ 10 fois, je suppose que cela l'a tué à chaque fois . Je l'exécute maintenant - c'est assez rapide - peut-être 20 minutes pour 120k images
Scott
11

Utilisation du 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)}'

Alexandre Vitanov
la source
3
ne pourriez-vous pas simplement utiliser un tube pour grep au lieu d'écrire sur le disque avec tous les fichiers.txt? Cela peut êtreaws 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

J'avais ce besoin moi-même, mais le nombre de fichiers rend le travail lent en série. J'ai donc écrit un script qu'il fait sur iron.io de ferronnier service. Leurs 500 heures de calcul gratuites par mois sont suffisantes pour gérer même de gros seaux (et si vous dépassez cela, le prix est raisonnable). Comme il se fait en parallèle, il se termine en moins d'une minute pour les 32 000 objets que j'avais. Je crois également que leurs serveurs fonctionnent sur EC2, donc la communication entre le travail et S3 est rapide.

Tout le monde est invité à utiliser mon script pour ses propres besoins.

Eric Anderson
la source
2

Jetez un œil à BucketExplorer, il gère très bien les opérations en bloc et est un client S3 solide.

willbt
la source
3
Il est également désormais possible de modifier en bloc les autorisations dans Cyberduck (gratuit) via la palette d'informations.
Taylor Edmiston
BucketExplorer n'est utile que si vous êtes autorisé à répertorier tous les buckets. Il est préférable d'utiliser la CLI ou un SDK pour cette opération et de laisser à vos utilisateurs des autorisations restreintes.
perilandmishap
0

Vous penseriez qu'ils rendraient public la lecture du comportement par défaut, n'est-ce pas? :) J'ai partagé votre frustration lors de la création d'une API personnalisée pour l'interface avec S3 à partir d'une solution C #. Voici l'extrait de code qui permet de télécharger un objet S3 et de le définir par défaut sur un accès en lecture publique:

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 fonction ToACLString (acl) renvoie une lecture publique , BASE_SERVICE_URL est s3.amazonaws.com et la constante AWS_ACL_HEADER est x-amz-acl . Le plug-in et le contenu de DreamMessage vous sembleront probablement étranges, car nous utilisons le framework Dream pour rationaliser nos communications http. Essentiellement, nous faisons un http PUT avec les en-têtes spécifiés et une signature d'en-tête spéciale par spécifications aws (voir cette page dans la documentation aws pour des exemples de construction de l'en-tête d'autorisation).

Pour modifier une liste de contrôle d'accès à 1000 objets existante, vous pouvez écrire un script, mais il est probablement plus facile d'utiliser un outil GUI pour résoudre le problème immédiat. Le meilleur que j'ai utilisé jusqu'à présent provient d'une société appelée cloudberry pour S3; il semble qu'ils bénéficient d'un essai gratuit de 15 jours pour au moins un de leurs produits. Je viens de vérifier que cela vous permettra de sélectionner plusieurs objets à la fois et de définir leur ACL sur public via le menu contextuel. Profitez du cloud!

Tahbaza
la source