Pretty basic question but I haven't been able to find an answer. Using Transit I can "move" files from one S3 bucket on one AWS account to another S3 bucket on another AWS account, but what it actually does is download the files from the first then upload them to the second.
Is there a way to move files directly from one S3 account to another without downloading them in between?
Yes, there is a way. And its pretty simple, though it's hard to find it. 8)
For example, suppose your first account username is acc1#gmail.com and second is acc2#gmail.com.
Open AWS Management Console as acc1. Get to the Amazon S3 bucket properties, and in the "Permissions" tab click "Add more permissions". Then add List and View Permissions for "Authenticated Users".
Next, in AWS IAM (it's accessible from among the console tabs) of acc2 create a user with full access to the S3 bucket (to be more secure, you can set up exact permissions, but I prefer to create a temporary user for the transfer and then delete it).
Then you can use s3cmd (using the credentials of the newly created user in acc2) to do something like:
s3cmd cp s3://acc1_bucket/folder/ s3://acc2_bucket/folder --recursive
All transfer will be done on Amazon's side.
Use the aws cli (I used ubuntu 14 ec2 instance) and just run the following command:
aws s3 sync s3://bucket1 s3://bucket2
You will need to specify the account details for one, and have public write access or public read access to the other.
This will sync the two buckets. You can use the same command again later to sync quickly. Best part is that it doesn't seem t require any bandwidth (e.g. files are not passing through local computer).
If you are just looking for a ready made solution there are a few solutions out there that can do this. Bucket Explorer works on Mac and Windows and can copy across accounts as can Cloudberry S3 Explorer and S3 Browser but they are Windows only so may not work for you.
I suspect the AWS console could also do it with the appropriate permissions setup but I haven't tested this.
You can also do it using the AWS API as long as you have given the AWS account you are using write permissions to the destination bucket.
boto works well. See this thread. Using boto, you copy objects straight from one bucket to another, rather than downloading them to the local machine and uploading them to another bucket.
Move S3 files from One account to another account
Let's consider there are two accounts source account and destination account. And two buckets source-bucket and destination bucket. We want to move all files from source-bucket to destination-bucket. We can do it by the following steps:
aws configure
Configure your destination account using the credential or the IAM role.
Create user policy for the destination account user.
Give destination user access to the source-bucket by modifying the source-bucket policy and adding destination account user policy into it. By this way, destination user will have the access to source-bucket.
aws s3 ls s3://source-bucket/
this will check whether the destination account is having access to source-bucket. Just for confirmation do this.
aws s3 cp s3://source-bucket s3://destination-bucket --recursive
this will copy source-bucket all files to destination-bucket. All files are copied using --recursive flag.
aws s3 mv s3://source-bucket s3://destination-bucket --recursive
this will move all the files from source-bucket to destination-bucket.
Alternative you can use the sync command
- aws s3 sync s3://source-bucket s3://detination-bucket
For Better Explanation follow the link
On Mac OS X I used the Transmit app from Panic. I opened one window for each S3 account (using the API Keys and secrets). I could then drag from one bucket in one window to another bucket in the other window. No need to download files locally first.
Andrew is correct, Transmit downloads the files locally then uploads the files.
CrossFTP can copy S3 files straight from one bucket to another without downloading them. It is a GUI S3 client that works on Windows, Mac, and Linux.
You can user Cyberduck (open source)
For newly created files (NOT existing objects), you can take advantage of new functionality from AWS. It is Cross-Region Replication (under "Versioning" for the S3 bucket). You can create a policy that will allow you to replicate new objects to a bucket in a different account.
For existing objects, you will still need to copy your objects using another method - unless AWS introduces native functionality for this in the future.
One can so it with running following :
aws s3 mv (sync for keeping buckets in sync) s3://source-bucket s3://destination-bucket --recursive
Attach a bucket policy to the source bucket in Source Account.
Attach an AWS Identity and Access Management (IAM) policy to a user or role in Destination Account.
Use the IAM user or role in Destination Account to perform the cross-account move.
Related
My aim is to be able to call the Google Storage REST APIs with an OAuth token granting an authenticated Google user the read/write permissions on a directory called "directoryName" inside my storage bucket.
So, far I have successfully managed to use the Storage APIs after adding the user to the ACL for the bucket. However, I do not want to grant the user the READ or WRITE permissions on the complete bucket but just on the user's directory inside the bucket e.g. bucket/directoryName.
e.g. I want to be able to call storage.objects.list for a directory inside the bucket without providing the user the permissions for the bucket but just for that directory (and subdirectories).
What I've tried so far: When I tried to call the GET method on https://www.googleapis.com//storage/v1/b/bucket/o?fields=kind%2Citems%28name%29&maxResults=150&prefix=directoryName with the user added to the directory's ACL (as Owner), I get the error response "code":403,"message":"myEmail#gmail.com does not have storage.objects.list access to myBucketName.appspot.com."
Is it possible to provide directory level permissions with Google Cloud Storage and list the contents of that directory only?
As explained in the documentation, there are no such thing as directories in Cloud Storage. As far as Storage is concerned, there are only buckets and inside them objects/files that may or may not have "/" in their name.
Due to this design choice, there's no option to set permissions on a "directory" in Cloud Storage. Please note however that you can create as many buckets as you want for no extra charge. You may create one bucket per user to fit your requirement.
What is the best way to upload from AngularJS to S3 without passing the access key or secret down to the client? I have a friend who is trying to accomplish this by creating a pre-signed URL on the server (NodeJS & Express) and then sending the URL to the client for upload. He's claiming it's failing due to CORS but he CAN upload using the sdk from the same AngularJS app & browser.
Update for Clarity
The tricky part is they cannot store anything in an environment variable AND each bucket has different credentials. They're storing info on 10-20 buckets / regions / IAM users and need the end user to select the bucket BY NAME on the client. This means they cannot store anything globally. The server must be able to generate something for the client to use per each request.
His original question:
Generate S3 Put URL Per Request
You can do that by using an IAM Instance Profile for your ec2 server. That way you don't have to provide your access & secret key, because any call done via the AWS SDK will be authenticated via the instance profile permissions. Either of this, in order! authenticate aws api calls:
In system environment variables: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
In the Java system properties: aws.accessKeyId and aws.secretKey.
In the default credentials file (the location of this file
varies by platform).
In the instance profile credentials, which exist within the instance metadata associated with the IAM role for the EC2 instance.
Note the instance profile creds are checked last!
More info here
I'd like to give to each of my customers access to their own bucket under my GCS enabled app.
I also need to make sure that a user's bucket is safe from other users' actions.
Last but not least, the customer will be a client application, so the whole process needs to be done transparently without asking the user to login.
If I apply an ACL on each bucket, granting access only to the user I want, can I create an API key only for that bucket and hand that API key to the client app to perform GCS API calls?
Unfortunately you only have two good options here:
Have a service which authenticates the individial app according to whatever scheme you like (some installation license, a random GUID assigned at creation time, whatever) and vends GCS signed URLs, which the end user could then use for a single operation, like uploading an object or listing a bucket's content. The downside here is that all requests must involve your service. All resources would belong entirely to your application.
Abandon the "without asking the user to login" requirement and require a single Google login at install time.
For the CQ5 environment I work on we have a farm of publisher servers. Some of the content on these servers is restricted so only users who belong to certain groups can see the content. I'd like to script the setting of permissions for the folders (nodes) that are to be secured so I don't have to manually repeat the steps of applying security using the Access Control Editor of Content Explorer (This Adobe documentation has instructions for doing it manually via Access Control Editor). The scenario is that sometimes new folders are to be created to hold secure pages, and we want to apply permissions to the folders prior to activating any content into those folders.
Since the environment has several publishers, it is repetitive, manual, and error-prone work to open Content Explorer and set the permissions on each one. I'd like to do be able to automate this so I could roll out permissions to all the servers via a script--perhaps via a curl command or some other mechanism (perhaps a package?) that can be automated.
I found the Sling jackrabbit-accessmanager bundle that seems like it will facilitate automation of this, but it seems like it opens a security hole. If I put this bundle on my publishers, it seems like I would be providing an REST interface to let anyone modify the permissions and grant access to folders/nodes that should be secured or to add security restrictions on nodes that should have none.
How can I automate the creation/modification of node permissions via a script--and do so in a way that only allows an administrator to apply the permissions changes?
This tool lets you manage permissions in a centralised way, they can also be installed automatically at deploy time:
https://github.com/Netcentric/accesscontroltool
Regarding permissions applied to new folders, the solution is setting permission properly on their parent folder. CQ/AEM will automatically apply the same permissions to all children unless another rule break the inheritance.
I found one alternative I hadn't considered before: using the Day CQ ACL Setup Service. It is mentioned at http://dev.day.com/docs/en/cq/5-5/developing/security_model_changes.html.
AclSetupService allows one to add permission to a single path or a given user/group. This will be applied on each restart of CQ to guaranteed a certain permission state within CQ. For example, "allow;inherit;everyone;/" prevent everyone from accessing CQ (i.e. it forces all users to login first). As noted in the description of AclSetupService, you will need the following pattern per entry:
( "allow" | "deny" ) ";" ( privileges | "inherit" ) ";" principal ";" path
Choose either "allow" or "deny" for the first part.
Next enter one of the privilege below or set it to inherit permission from ancestor.
Then enter a single user/group.
Finally enter a single path to apply the permission to.
Using this will replace permission set within the repository when you restart CQ. These could be scripted by using the process outlined here and here.
Privileges can be:
jcr:read
rep:write
jcr:all
crx:replicate
imp:setComplete
jcr:addChildNodes
jcr:lifecycleManagement
jcr:lockManagement
jcr:modifyAccessControl
jcr:modifyProperties
jcr:namespaceManagement
jcr:nodeTypeDefinitionManagement
jcr:nodeTypeManagement
jcr:readAccessControl
jcr:removeChildNodes
jcr:removeNode
jcr:retentionManagement
jcr:versionManagement
jcr:workspaceManagement
jcr:write
rep:privilegeManagement
If you would like to use the Sling jackrabbit-accessmanager bundle on a publish instance it is possible. You would want to make sure your dispatcher which sits in front of the publish instance does not allow the permission requests (/.modifyAce., .deleteAce., etc) and the publish instances can only be accessed directly from inside your network. It's standard practice to deny all requests in the dispatcher and specify what is allowed.
Is there are reason you are not just replicating the permissions when the folder is activated? There should be a rep:policy node underneath the secure folder which gets replicated.
I am running Django on Python SDK of GAE.
My application is an order processing app for a small business. I want to email a delivery note in the form of a spreadsheet to customers on completion of an order. Now I have been reading the docs and its no problem sending attachments, just that only certain file types are allowed in GAE.
I have created a spreadsheet document using the Google Data API, but my problem is how to get the Google Spreadsheet document emailed to the customer. My App Engine is on a hosted domain, so normal gmail accounts don't have access to it and many of the customer email accounts won't even be gmail anyway, the Google Spreadsheet attachment will just be a XML Atom object pointing to a doc hosted on my account which won't be accessible to outside users anyhow, right?
Is there any way to copy this Spreadsheet object and attach it to the email, so it can be opened locally by users with no access rights to my google doc, it can basically be opened offline. My code looks like this:
new_entry = gdata.GDataEntry()
new_entry.title = gdata.atom.Title(text='Delivery Note from ' + company.company_name)
category = gd_client._MakeKindCategory(gdata.docs.service.SPREADSHEET_LABEL)
new_entry.category.append(category)
doc_entry = gd_client.Post(new_entry, '/feeds/documents/private/full')
.....now build the spreadsheet
doc_title = 'deliverynote' + '.' + doc_entry.title.type
.....build the email body
mail.send_mail(sender_address, to_address, subject, body, attachments=[(doc_title, str(doc_entry))])
Doing it this way however when the customer receives the mail, when they try and open it they get an unexpected error (the exact words that Google uses when it tries and opens it).
The other alternative of course is to try and convert it to an Excel file. Methods are provided by google to export the file as an excel file to the local file system, but then the program is faced with the problem of uploading it again without any manual user intervention. Besides the excel file type isn't supported by GAE as a legitimate attachment type.
Has anyone got any ideas?
Interesting question.
Since you use GData to create it, your GAE app should have rights to get a copy of it and attach it. Not sure what format it would be in, and how the guy that receives it uses it though.
If you attached a Google spreadsheet to an email, how would the person open it? Since Google runs "on the web"? I know Google now has an offline option, but I haven't tried it yet. I think it requires install Google Gears and other stuff on the local machine.
Do you want people to share the spreadsheet or each get their own copy? Could you just change the rights to let more people have read-only or update access?
Do all your recipients have Excel? Do they all have Google App Accounts?
Neal Walters