Vendor aws-sdk-go (dep ensure) (#178)
This commit is contained in:
14
vendor/github.com/aws/aws-sdk-go/example/service/s3/concatObjects/README.md
generated
vendored
Normal file
14
vendor/github.com/aws/aws-sdk-go/example/service/s3/concatObjects/README.md
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Example
|
||||
|
||||
This is an example using the AWS SDK for Go to concatenate two objects together.
|
||||
We use `UploadPartCopy` which uses an object for a part. Here in this example we have two parts, or in other words
|
||||
two objects that we want to concatenate together.
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
The example uses the bucket name provided, two keys for each object, and lastly the output key.
|
||||
|
||||
```sh
|
||||
AWS_REGION=<region> go run -tags example concatenateObjects.go <bucket> <key for object 1> <key for object 2> <key for output>
|
||||
```
|
||||
104
vendor/github.com/aws/aws-sdk-go/example/service/s3/concatObjects/concatObjects.go
generated
vendored
Normal file
104
vendor/github.com/aws/aws-sdk-go/example/service/s3/concatObjects/concatObjects.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
type client struct {
|
||||
s3Client *s3.S3
|
||||
bucket *string
|
||||
}
|
||||
|
||||
// concatenate will contenate key1's object to key2's object under the key testKey
|
||||
func (c *client) concatenate(key1, key2, key3 string, uploadID *string) (*string, *string, error) {
|
||||
// The first part to be uploaded which is represented as part number 1
|
||||
foo, err := c.s3Client.UploadPartCopy(&s3.UploadPartCopyInput{
|
||||
Bucket: c.bucket,
|
||||
CopySource: aws.String(url.QueryEscape(*c.bucket + "/" + key1)),
|
||||
PartNumber: aws.Int64(1),
|
||||
Key: &key3,
|
||||
UploadId: uploadID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// The second part that is going to be appended to the newly created testKey
|
||||
// object.
|
||||
bar, err := c.s3Client.UploadPartCopy(&s3.UploadPartCopyInput{
|
||||
Bucket: c.bucket,
|
||||
CopySource: aws.String(url.QueryEscape(*c.bucket + "/" + key2)),
|
||||
PartNumber: aws.Int64(2),
|
||||
Key: &key3,
|
||||
UploadId: uploadID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// The ETags are needed to complete the process
|
||||
return foo.CopyPartResult.ETag, bar.CopyPartResult.ETag, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 4 {
|
||||
log.Println("USAGE ERROR: AWS_REGION=us-east-1 go run concatenateObjects.go <bucket> <key for object 1> <key for object 2> <key for output>")
|
||||
return
|
||||
}
|
||||
|
||||
bucket := os.Args[1]
|
||||
key1 := os.Args[2]
|
||||
key2 := os.Args[3]
|
||||
key3 := os.Args[4]
|
||||
sess := session.New(&aws.Config{})
|
||||
svc := s3.New(sess)
|
||||
|
||||
c := client{svc, &bucket}
|
||||
|
||||
// We let the service know that we want to do a multipart upload
|
||||
output, err := c.s3Client.CreateMultipartUpload(&s3.CreateMultipartUploadInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key3,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Println("ERROR:", err)
|
||||
return
|
||||
}
|
||||
|
||||
foo, bar, err := c.concatenate(key1, key2, key3, output.UploadId)
|
||||
if err != nil {
|
||||
log.Println("ERROR:", err)
|
||||
return
|
||||
}
|
||||
|
||||
// We finally complete the multipart upload.
|
||||
_, err = c.s3Client.CompleteMultipartUpload(&s3.CompleteMultipartUploadInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key3,
|
||||
UploadId: output.UploadId,
|
||||
MultipartUpload: &s3.CompletedMultipartUpload{
|
||||
Parts: []*s3.CompletedPart{
|
||||
{
|
||||
ETag: foo,
|
||||
PartNumber: aws.Int64(1),
|
||||
},
|
||||
{
|
||||
ETag: bar,
|
||||
PartNumber: aws.Int64(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Println("ERROR:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
27
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjects/README.md
generated
vendored
Normal file
27
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjects/README.md
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# Example
|
||||
|
||||
This is an example using the AWS SDK for Go to list objects' key in a S3 bucket.
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
The example uses the bucket name provided, and lists all object keys in a bucket.
|
||||
|
||||
```sh
|
||||
go run -tags example listObjects.go <bucket>
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
Page, 0
|
||||
Object: myKey
|
||||
Object: mykey.txt
|
||||
Object: resources/0001/item-01
|
||||
Object: resources/0001/item-02
|
||||
Object: resources/0001/item-03
|
||||
Object: resources/0002/item-01
|
||||
Object: resources/0002/item-02
|
||||
Object: resources/0002/item-03
|
||||
Object: resources/0002/item-04
|
||||
Object: resources/0002/item-05
|
||||
```
|
||||
43
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjects/listObjects.go
generated
vendored
Normal file
43
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjects/listObjects.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
// Lists all objects in a bucket using pagination
|
||||
//
|
||||
// Usage:
|
||||
// listObjects <bucket>
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("you must specify a bucket")
|
||||
return
|
||||
}
|
||||
|
||||
sess := session.Must(session.NewSession())
|
||||
|
||||
svc := s3.New(sess)
|
||||
|
||||
i := 0
|
||||
err := svc.ListObjectsPages(&s3.ListObjectsInput{
|
||||
Bucket: &os.Args[1],
|
||||
}, func(p *s3.ListObjectsOutput, last bool) (shouldContinue bool) {
|
||||
fmt.Println("Page,", i)
|
||||
i++
|
||||
|
||||
for _, obj := range p.Contents {
|
||||
fmt.Println("Object:", *obj.Key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("failed to list objects", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
13
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjectsConcurrently/README.md
generated
vendored
Normal file
13
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjectsConcurrently/README.md
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
## Example
|
||||
|
||||
This is an example using the AWS SDK for Go concurrently to list the encrypted objects in the S3 buckets owned by an account.
|
||||
|
||||
## Usage
|
||||
|
||||
The example's `accounts` string slice contains a list of the SharedCredentials profiles which will be used to look up the buckets owned by each profile. Each bucket's objects will be queried.
|
||||
|
||||
```
|
||||
AWS_REGION=us-east-1 go run -tags example listObjectsConcurrentlv.go
|
||||
```
|
||||
|
||||
|
||||
236
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjectsConcurrently/listObjectsConcurrently.go
generated
vendored
Normal file
236
vendor/github.com/aws/aws-sdk-go/example/service/s3/listObjectsConcurrently/listObjectsConcurrently.go
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
func exit(msg ...interface{}) {
|
||||
fmt.Fprintln(os.Stderr, msg...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Lists all encrypted objects owned by an account. The `accounts` string
|
||||
// contains a list of profiles to use.
|
||||
//
|
||||
// Usage:
|
||||
// listObjectsConcurrentlv
|
||||
func main() {
|
||||
accounts := []string{"default", "default2", "otherprofile"}
|
||||
|
||||
// Spin off a worker for each account to retrieve that account's
|
||||
bucketCh := make(chan *Bucket, 5)
|
||||
var wg sync.WaitGroup
|
||||
for _, acc := range accounts {
|
||||
wg.Add(1)
|
||||
go func(acc string) {
|
||||
defer wg.Done()
|
||||
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
Profile: acc,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to create session for account, %s, %v\n", acc, err)
|
||||
return
|
||||
}
|
||||
if err = getAccountBuckets(sess, bucketCh, acc); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to get account %s's bucket info, %v\n", acc, err)
|
||||
}
|
||||
}(acc)
|
||||
}
|
||||
// Spin off a goroutine which will wait until all account buckets have been collected and
|
||||
// added to the bucketCh. Close the bucketCh so the for range below will exit once all
|
||||
// bucket info is printed.
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(bucketCh)
|
||||
}()
|
||||
|
||||
// Receive from the bucket channel printing the information for each bucket to the console
|
||||
// when the bucketCh channel is drained.
|
||||
buckets := []*Bucket{}
|
||||
for b := range bucketCh {
|
||||
buckets = append(buckets, b)
|
||||
}
|
||||
|
||||
sortBuckets(buckets)
|
||||
for _, b := range buckets {
|
||||
if b.Error != nil {
|
||||
fmt.Printf("Bucket %s, owned by: %s, failed: %v\n", b.Name, b.Owner, b.Error)
|
||||
continue
|
||||
}
|
||||
|
||||
encObjs := b.encryptedObjects()
|
||||
fmt.Printf("Bucket: %s, owned by: %s, total objects: %d, failed objects: %d, encrypted objects: %d\n",
|
||||
b.Name, b.Owner, len(b.Objects), len(b.ErrObjects), len(encObjs))
|
||||
if len(encObjs) > 0 {
|
||||
for _, encObj := range encObjs {
|
||||
fmt.Printf("\t%s %s:%s/%s\n", encObj.EncryptionType, b.Region, b.Name, encObj.Key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sortBuckets(buckets []*Bucket) {
|
||||
s := sortalbeBuckets(buckets)
|
||||
sort.Sort(s)
|
||||
}
|
||||
|
||||
type sortalbeBuckets []*Bucket
|
||||
|
||||
func (s sortalbeBuckets) Len() int { return len(s) }
|
||||
func (s sortalbeBuckets) Swap(a, b int) { s[a], s[b] = s[b], s[a] }
|
||||
func (s sortalbeBuckets) Less(a, b int) bool {
|
||||
if s[a].Owner == s[b].Owner && s[a].Name < s[b].Name {
|
||||
return true
|
||||
}
|
||||
|
||||
if s[a].Owner < s[b].Owner {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func getAccountBuckets(sess *session.Session, bucketCh chan<- *Bucket, owner string) error {
|
||||
svc := s3.New(sess)
|
||||
buckets, err := listBuckets(svc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list buckets, %v", err)
|
||||
}
|
||||
for _, bucket := range buckets {
|
||||
bucket.Owner = owner
|
||||
if bucket.Error != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
bckSvc := s3.New(sess, &aws.Config{
|
||||
Region: aws.String(bucket.Region),
|
||||
Credentials: svc.Config.Credentials,
|
||||
})
|
||||
bucketDetails(bckSvc, bucket)
|
||||
bucketCh <- bucket
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func bucketDetails(svc *s3.S3, bucket *Bucket) {
|
||||
objs, errObjs, err := listBucketObjects(svc, bucket.Name)
|
||||
if err != nil {
|
||||
bucket.Error = err
|
||||
} else {
|
||||
bucket.Objects = objs
|
||||
bucket.ErrObjects = errObjs
|
||||
}
|
||||
}
|
||||
|
||||
// A Object provides details of an S3 object
|
||||
type Object struct {
|
||||
Bucket string
|
||||
Key string
|
||||
Encrypted bool
|
||||
EncryptionType string
|
||||
}
|
||||
|
||||
// An ErrObject provides details of the error occurred retrieving
|
||||
// an object's status.
|
||||
type ErrObject struct {
|
||||
Bucket string
|
||||
Key string
|
||||
Error error
|
||||
}
|
||||
|
||||
// A Bucket provides details about a bucket and its objects
|
||||
type Bucket struct {
|
||||
Owner string
|
||||
Name string
|
||||
CreationDate time.Time
|
||||
Region string
|
||||
Objects []Object
|
||||
Error error
|
||||
ErrObjects []ErrObject
|
||||
}
|
||||
|
||||
func (b *Bucket) encryptedObjects() []Object {
|
||||
encObjs := []Object{}
|
||||
for _, obj := range b.Objects {
|
||||
if obj.Encrypted {
|
||||
encObjs = append(encObjs, obj)
|
||||
}
|
||||
}
|
||||
return encObjs
|
||||
}
|
||||
|
||||
func listBuckets(svc *s3.S3) ([]*Bucket, error) {
|
||||
res, err := svc.ListBuckets(&s3.ListBucketsInput{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buckets := make([]*Bucket, len(res.Buckets))
|
||||
for i, b := range res.Buckets {
|
||||
buckets[i] = &Bucket{
|
||||
Name: *b.Name,
|
||||
CreationDate: *b.CreationDate,
|
||||
}
|
||||
|
||||
locRes, err := svc.GetBucketLocation(&s3.GetBucketLocationInput{
|
||||
Bucket: b.Name,
|
||||
})
|
||||
if err != nil {
|
||||
buckets[i].Error = err
|
||||
continue
|
||||
}
|
||||
|
||||
if locRes.LocationConstraint == nil {
|
||||
buckets[i].Region = "us-east-1"
|
||||
} else {
|
||||
buckets[i].Region = *locRes.LocationConstraint
|
||||
}
|
||||
}
|
||||
|
||||
return buckets, nil
|
||||
}
|
||||
|
||||
func listBucketObjects(svc *s3.S3, bucket string) ([]Object, []ErrObject, error) {
|
||||
listRes, err := svc.ListObjects(&s3.ListObjectsInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
objs := make([]Object, 0, len(listRes.Contents))
|
||||
errObjs := []ErrObject{}
|
||||
for _, listObj := range listRes.Contents {
|
||||
objData, err := svc.HeadObject(&s3.HeadObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: listObj.Key,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
errObjs = append(errObjs, ErrObject{Bucket: bucket, Key: *listObj.Key, Error: err})
|
||||
continue
|
||||
}
|
||||
|
||||
obj := Object{Bucket: bucket, Key: *listObj.Key}
|
||||
if objData.ServerSideEncryption != nil {
|
||||
obj.Encrypted = true
|
||||
obj.EncryptionType = *objData.ServerSideEncryption
|
||||
}
|
||||
|
||||
objs = append(objs, obj)
|
||||
}
|
||||
|
||||
return objs, errObjs, nil
|
||||
}
|
||||
124
vendor/github.com/aws/aws-sdk-go/example/service/s3/presignURL/README.md
generated
vendored
Normal file
124
vendor/github.com/aws/aws-sdk-go/example/service/s3/presignURL/README.md
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
# Presigned Amazon S3 API Operation Example
|
||||
|
||||
This example demonstrates how you can build a client application to retrieve and
|
||||
upload object data from Amazon S3 without needing to know anything about Amazon
|
||||
S3 or have access to any AWS credentials. Only the service would have knowledge
|
||||
of how and where the objects are stored in Amazon S3.
|
||||
|
||||
The example is split into two parts `server.go` and `client.go`. These two parts
|
||||
simulate the client/server architecture. In this example the client will represent
|
||||
a third part user that will request resource URLs from the service. The service
|
||||
will generate presigned S3 URLs which the client can use to download and
|
||||
upload S3 object content.
|
||||
|
||||
The service supports generating presigned URLs for two S3 APIs; `GetObject` and
|
||||
`PutObject`. The client will request a presigned URL from the service with an
|
||||
object Key. In this example the value is the S3 object's `key`. Alternatively,
|
||||
you could use your own pattern with no visible relation to the S3 object's key.
|
||||
The server would then perform a cross reference with client provided value to
|
||||
one that maps to the S3 object's key.
|
||||
|
||||
Before using the client to upload and download S3 objects you'll need to start the
|
||||
service. The service will use the SDK's default credential chain to source your
|
||||
AWS credentials. See the [`Configuring Credentials`](http://docs.aws.amazon.com/sdk-for-go/api/)
|
||||
section of the SDK's API Reference guide on how the SDK loads your AWS credentials.
|
||||
|
||||
The server requires the S3 `-b bucket` the presigned URLs will be generated for. A
|
||||
`-r region` is only needed if the bucket is in AWS China or AWS Gov Cloud. For
|
||||
buckets in AWS the server will use the [`s3manager.GetBucketRegion`](http://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#GetBucketRegion) utility to lookup the bucket's region.
|
||||
|
||||
You should run the service in the background or in a separate terminal tab before
|
||||
moving onto the client.
|
||||
|
||||
|
||||
```sh
|
||||
go run -tags example server/server.go -b mybucket
|
||||
> Starting Server On: 127.0.0.1:8080
|
||||
```
|
||||
|
||||
Use the `--help` flag to see a list of additional configuration flags, and their
|
||||
defaults.
|
||||
|
||||
## Downloading an Amazon S3 Object
|
||||
|
||||
Use the client application to request a presigned URL from the server and use
|
||||
that presigned URL to download the object from S3. Calling the client with the
|
||||
`-get key` flag will do this. An optional `-f filename` flag can be provided as
|
||||
well to write the object to. If no flag is provided the object will be written
|
||||
to `stdout`
|
||||
|
||||
```sh
|
||||
go run -tags example client/client.go -get "my-object/key" -f outputfilename
|
||||
```
|
||||
|
||||
Use the `--help` flag to see a list of additional configuration flags, and their
|
||||
defaults.
|
||||
|
||||
The following curl request demonstrates the request the client makes to the server
|
||||
for the presigned URL for the `my-object/key` S3 object. The `method` query
|
||||
parameter lets the server know that we are requesting the `GetObject`'s presigned
|
||||
URL. The `method` value can be `GET` or `PUT` for the `GetObject` or `PutObject` APIs.
|
||||
|
||||
```sh
|
||||
curl -v "http://127.0.0.1:8080/presign/my-object/key?method=GET"
|
||||
```
|
||||
|
||||
The server will respond with a JSON value. The value contains three pieces of
|
||||
information that the client will need to correctly make the request. First is
|
||||
the presigned URL. This is the URL the client will make the request to. Second
|
||||
is the HTTP method the request should be sent as. This is included to simplify
|
||||
the client's request building. Finally the response will include a list of
|
||||
additional headers that the client should include that the presigned request
|
||||
was signed with.
|
||||
|
||||
```json
|
||||
{
|
||||
"URL": "https://mybucket.s3-us-west-2.amazonaws.com/my-object/key?<signature>",
|
||||
"Method": "GET",
|
||||
"Header": {
|
||||
"x-amz-content-sha256":["UNSIGNED-PAYLOAD"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With this URL our client will build a HTTP request for the S3 object's data. The
|
||||
`client.go` will then write the object's data to the `filename` if one is provided,
|
||||
or to `stdout` of a filename is not set in the command line arguments.
|
||||
|
||||
## Uploading a File to Amazon S3
|
||||
|
||||
Just like the download, uploading a file to S3 will use a presigned URL requested
|
||||
from the server. The resigned URL will be built into an HTTP request using the
|
||||
URL, Method, and Headers. The `-put key` flag will upload the content of `-f filename`
|
||||
or stdin if no filename is provided to S3 using a presigned URL provided by the
|
||||
service
|
||||
|
||||
```sh
|
||||
go run -tags example client/client.go -put "my-object/key" -f filename
|
||||
```
|
||||
|
||||
Like the download case this will make a HTTP request to the server for the
|
||||
presigned URL. The Server will respond with a presigned URL for S3's `PutObject`
|
||||
API operation. In addition the `method` query parameter the client will also
|
||||
include a `contentLength` this value instructs the server to generate the presigned
|
||||
PutObject request with a `Content-Length` header value included in the signature.
|
||||
This is done so the content that is uploaded by the client can only be the size
|
||||
the presigned request was generated for.
|
||||
|
||||
```sh
|
||||
curl -v "http://127.0.0.1:8080/presign/my-object/key?method=PUT&contentLength=1024"
|
||||
```
|
||||
|
||||
## Expanding the Example
|
||||
|
||||
This example provides a spring board you can use to vend presigned URLs to your
|
||||
clients instead of streaming the object's content through your service. This
|
||||
client and server example can be expanded and customized. Adding new functionality
|
||||
such as additional constraints the server puts on the presigned URLs like
|
||||
`Content-Type`.
|
||||
|
||||
In addition to adding constraints to the presigned URLs the service could be
|
||||
updated to obfuscate S3 object's key. Instead of the client knowing the object's
|
||||
key, a lookup system could be used instead. This could be substitution based,
|
||||
or lookup into an external data store such as DynamoDB.
|
||||
|
||||
266
vendor/github.com/aws/aws-sdk-go/example/service/s3/presignURL/client/client.go
generated
vendored
Normal file
266
vendor/github.com/aws/aws-sdk-go/example/service/s3/presignURL/client/client.go
generated
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// client.go is an example of a client that will request URLs from a service that
|
||||
// the client will use to upload and download content with.
|
||||
//
|
||||
// The server must be started before the client is run.
|
||||
//
|
||||
// Use "--help" command line argument flag to see all options and defaults. If
|
||||
// filename is not provided the client will read from stdin for uploads and
|
||||
// write to stdout for downloads.
|
||||
//
|
||||
// Usage:
|
||||
// go run -tags example client.go -get myObjectKey -f filename
|
||||
func main() {
|
||||
method, filename, key, serverURL := loadConfig()
|
||||
|
||||
var err error
|
||||
|
||||
switch method {
|
||||
case GetMethod:
|
||||
// Requests the URL from the server that the client will use to download
|
||||
// the content from. The content will be written to the file pointed to
|
||||
// by filename. Creating it if the file does not exist. If filename is
|
||||
// not set the contents will be written to stdout.
|
||||
err = downloadFile(serverURL, key, filename)
|
||||
case PutMethod:
|
||||
// Requests the URL from the service that the client will use to upload
|
||||
// content to. The content will be read from the file pointed to by the
|
||||
// filename. If the filename is not set, content will be read from stdin.
|
||||
err = uploadFile(serverURL, key, filename)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
exitError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// loadConfig configures the client based on the command line arguments used.
|
||||
func loadConfig() (method Method, serverURL, key, filename string) {
|
||||
var getKey, putKey string
|
||||
flag.StringVar(&getKey, "get", "",
|
||||
"Downloads the object from S3 by the `key`. Writes the object to a file the filename is provided, otherwise writes to stdout.")
|
||||
flag.StringVar(&putKey, "put", "",
|
||||
"Uploads data to S3 at the `key` provided. Uploads the file if filename is provided, otherwise reads from stdin.")
|
||||
flag.StringVar(&serverURL, "s", "http://127.0.0.1:8080", "Required `URL` the client will request presigned S3 operation from.")
|
||||
flag.StringVar(&filename, "f", "", "The `filename` of the file to upload and get from S3.")
|
||||
flag.Parse()
|
||||
|
||||
var errs Errors
|
||||
|
||||
if len(serverURL) == 0 {
|
||||
errs = append(errs, fmt.Errorf("server URL required"))
|
||||
}
|
||||
|
||||
if !((len(getKey) != 0) != (len(putKey) != 0)) {
|
||||
errs = append(errs, fmt.Errorf("either `get` or `put` can be provided, and one of the two is required."))
|
||||
}
|
||||
|
||||
if len(getKey) > 0 {
|
||||
method = GetMethod
|
||||
key = getKey
|
||||
} else {
|
||||
method = PutMethod
|
||||
key = putKey
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "Failed to load configuration:%v\n", errs)
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return method, filename, key, serverURL
|
||||
}
|
||||
|
||||
// downloadFile will request a URL from the server that the client can download
|
||||
// the content pointed to by "key". The content will be written to the file
|
||||
// pointed to by filename, creating the file if it doesn't exist. If filename
|
||||
// is not set the content will be written to stdout.
|
||||
func downloadFile(serverURL, key, filename string) error {
|
||||
var w *os.File
|
||||
if len(filename) > 0 {
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create download file %s, %v", filename, err)
|
||||
}
|
||||
w = f
|
||||
} else {
|
||||
w = os.Stdout
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
// Get the presigned URL from the remote service.
|
||||
req, err := getPresignedRequest(serverURL, "GET", key, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get get presigned request, %v", err)
|
||||
}
|
||||
|
||||
// Gets the file contents with the URL provided by the service.
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to do GET request, %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("failed to get S3 object, %d:%s",
|
||||
resp.StatusCode, resp.Status)
|
||||
}
|
||||
|
||||
if _, err = io.Copy(w, resp.Body); err != nil {
|
||||
return fmt.Errorf("failed to write S3 object, %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// uploadFile will request a URL from the service that the client can use to
|
||||
// upload content to. The content will be read from the file pointed to by filename.
|
||||
// If filename is not set the content will be read from stdin.
|
||||
func uploadFile(serverURL, key, filename string) error {
|
||||
var r io.ReadCloser
|
||||
var size int64
|
||||
if len(filename) > 0 {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open upload file %s, %v", filename, err)
|
||||
}
|
||||
|
||||
// Get the size of the file so that the constraint of Content-Length
|
||||
// can be included with the presigned URL. This can be used by the
|
||||
// server or client to ensure the content uploaded is of a certain size.
|
||||
//
|
||||
// These constraints can further be expanded to include things like
|
||||
// Content-Type. Additionally constraints such as X-Amz-Content-Sha256
|
||||
// header set restricting the content of the file to only the content
|
||||
// the client initially made the request with. This prevents the object
|
||||
// from being overwritten or used to upload other unintended content.
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stat file, %s, %v", filename, err)
|
||||
}
|
||||
|
||||
size = stat.Size()
|
||||
r = f
|
||||
} else {
|
||||
buf := &bytes.Buffer{}
|
||||
io.Copy(buf, os.Stdin)
|
||||
size = int64(buf.Len())
|
||||
|
||||
r = ioutil.NopCloser(buf)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
// Get the Presigned URL from the remote service. Pass in the file's
|
||||
// size if it is known so that the presigned URL returned will be required
|
||||
// to be used with the size of content requested.
|
||||
req, err := getPresignedRequest(serverURL, "PUT", key, size)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get get presigned request, %v", err)
|
||||
}
|
||||
req.Body = r
|
||||
|
||||
// Upload the file contents to S3.
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to do GET request, %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("failed to put S3 object, %d:%s",
|
||||
resp.StatusCode, resp.Status)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getPresignRequest will request a URL from the service for the content specified
|
||||
// by the key and method. Returns a constructed Request that can be used to
|
||||
// upload or download content with based on the method used.
|
||||
//
|
||||
// If the PUT method is used the request's Body will need to be set on the returned
|
||||
// request value.
|
||||
func getPresignedRequest(serverURL, method, key string, contentLen int64) (*http.Request, error) {
|
||||
u := fmt.Sprintf("%s/presign/%s?method=%s&contentLength=%d",
|
||||
serverURL, key, method, contentLen,
|
||||
)
|
||||
|
||||
resp, err := http.Get(u)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to make request for presigned URL, %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("failed to get valid presign response, %s", resp.Status)
|
||||
}
|
||||
|
||||
p := PresignResp{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&p); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode response body, %v", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(p.Method, p.URL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build presigned request, %v", err)
|
||||
}
|
||||
|
||||
for k, vs := range p.Header {
|
||||
for _, v := range vs {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
}
|
||||
// Need to ensure that the content length member is set of the HTTP Request
|
||||
// or the request will not be transmitted correctly with a content length
|
||||
// value across the wire.
|
||||
if contLen := req.Header.Get("Content-Length"); len(contLen) > 0 {
|
||||
req.ContentLength, _ = strconv.ParseInt(contLen, 10, 64)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
type Method int
|
||||
|
||||
const (
|
||||
PutMethod Method = iota
|
||||
GetMethod
|
||||
)
|
||||
|
||||
type Errors []error
|
||||
|
||||
func (es Errors) Error() string {
|
||||
out := make([]string, len(es))
|
||||
for _, e := range es {
|
||||
out = append(out, e.Error())
|
||||
}
|
||||
return strings.Join(out, "\n")
|
||||
}
|
||||
|
||||
type PresignResp struct {
|
||||
Method, URL string
|
||||
Header http.Header
|
||||
}
|
||||
|
||||
func exitError(err error) {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
186
vendor/github.com/aws/aws-sdk-go/example/service/s3/presignURL/server/server.go
generated
vendored
Normal file
186
vendor/github.com/aws/aws-sdk-go/example/service/s3/presignURL/server/server.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3iface"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
)
|
||||
|
||||
// server.go is an example of a service that vends lists for requests for presigned
|
||||
// URLs for S3 objects. The service supports two S3 operations, "GetObject" and
|
||||
// "PutObject".
|
||||
//
|
||||
// Example GetObject request to the service for the object with the key "MyObjectKey":
|
||||
//
|
||||
// curl -v "http://127.0.0.1:8080/presign/my-object/key?method=GET"
|
||||
//
|
||||
// Example PutObject request to the service for the object with the key "MyObjectKey":
|
||||
//
|
||||
// curl -v "http://127.0.0.1:8080/presign/my-object/key?method=PUT&contentLength=1024"
|
||||
//
|
||||
// Use "--help" command line argument flag to see all options and defaults.
|
||||
//
|
||||
// Usage:
|
||||
// go run -tags example service.go -b myBucket
|
||||
func main() {
|
||||
addr, bucket, region := loadConfig()
|
||||
|
||||
// Create a AWS SDK for Go Session that will load credentials using the SDK's
|
||||
// default credential change.
|
||||
sess := session.Must(session.NewSession())
|
||||
|
||||
// Use the GetBucketRegion utility to lookup the bucket's region automatically.
|
||||
// The service.go will only do this correctly for AWS regions. For AWS China
|
||||
// and AWS Gov Cloud the region needs to be specified to let the service know
|
||||
// to look in those partitions instead of AWS.
|
||||
if len(region) == 0 {
|
||||
var err error
|
||||
region, err = s3manager.GetBucketRegion(aws.BackgroundContext(), sess, bucket, endpoints.UsWest2RegionID)
|
||||
if err != nil {
|
||||
exitError(fmt.Errorf("failed to get bucket region, %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new S3 service client that will be use by the service to generate
|
||||
// presigned URLs with. Not actual API requests will be made with this client.
|
||||
// The credentials loaded when the Session was created above will be used
|
||||
// to sign the requests with.
|
||||
s3Svc := s3.New(sess, &aws.Config{
|
||||
Region: aws.String(region),
|
||||
})
|
||||
|
||||
// Start the server listening and serve presigned URLs for GetObject and
|
||||
// PutObject requests.
|
||||
if err := listenAndServe(addr, bucket, s3Svc); err != nil {
|
||||
exitError(err)
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() (addr, bucket, region string) {
|
||||
flag.StringVar(&bucket, "b", "", "S3 `bucket` object should be uploaded to.")
|
||||
flag.StringVar(®ion, "r", "", "AWS `region` the bucket exists in, If not set region will be looked up, only valid for AWS Regions, not AWS China or Gov Cloud.")
|
||||
flag.StringVar(&addr, "a", "127.0.0.1:8080", "The TCP `address` the server will be started on.")
|
||||
flag.Parse()
|
||||
|
||||
if len(bucket) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "bucket is required")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return addr, bucket, region
|
||||
}
|
||||
|
||||
func listenAndServe(addr, bucket string, svc s3iface.S3API) error {
|
||||
l, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start service listener, %v", err)
|
||||
}
|
||||
|
||||
const presignPath = "/presign/"
|
||||
|
||||
// Create the HTTP handler for the "/presign/" path prefix. This will handle
|
||||
// all requests on this path, extracting the object's key from the path.
|
||||
http.HandleFunc(presignPath, func(w http.ResponseWriter, r *http.Request) {
|
||||
var u string
|
||||
var err error
|
||||
var signedHeaders http.Header
|
||||
|
||||
query := r.URL.Query()
|
||||
|
||||
var contentLen int64
|
||||
// Optionally the Content-Length header can be included with the signature
|
||||
// of the request. This is helpful to ensure the content uploaded is the
|
||||
// size that is expected. Constraints like these can be further expanded
|
||||
// with headers such as `Content-Type`. These can be enforced by the service
|
||||
// requiring the client to satisfying those constraints when uploading
|
||||
//
|
||||
// In addition the client could provide the service with a SHA256 of the
|
||||
// content to be uploaded. This prevents any other third party from uploading
|
||||
// anything else with the presigned URL
|
||||
if contLenStr := query.Get("contentLength"); len(contLenStr) > 0 {
|
||||
contentLen, err = strconv.ParseInt(contLenStr, 10, 64)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to parse request content length, %v", err)
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the object key from the path
|
||||
key := strings.Replace(r.URL.Path, presignPath, "", 1)
|
||||
method := query.Get("method")
|
||||
|
||||
switch method {
|
||||
case "PUT":
|
||||
// For creating PutObject presigned URLs
|
||||
fmt.Println("Received request to presign PutObject for,", key)
|
||||
sdkReq, _ := svc.PutObjectRequest(&s3.PutObjectInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String(key),
|
||||
|
||||
// If ContentLength is 0 the header will not be included in the signature.
|
||||
ContentLength: aws.Int64(contentLen),
|
||||
})
|
||||
u, signedHeaders, err = sdkReq.PresignRequest(15 * time.Minute)
|
||||
case "GET":
|
||||
// For creating GetObject presigned URLs
|
||||
fmt.Println("Received request to presign GetObject for,", key)
|
||||
sdkReq, _ := svc.GetObjectRequest(&s3.GetObjectInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String(key),
|
||||
})
|
||||
u, signedHeaders, err = sdkReq.PresignRequest(15 * time.Minute)
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "invalid method provided, %s, %v\n", method, err)
|
||||
err = fmt.Errorf("invalid request")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Create the response back to the client with the information on the
|
||||
// presigned request and additional headers to include.
|
||||
if err := json.NewEncoder(w).Encode(PresignResp{
|
||||
Method: method,
|
||||
URL: u,
|
||||
Header: signedHeaders,
|
||||
}); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to encode presign response, %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
fmt.Println("Starting Server On:", "http://"+l.Addr().String())
|
||||
|
||||
s := &http.Server{}
|
||||
return s.Serve(l)
|
||||
}
|
||||
|
||||
// PresignResp provides the Go representation of the JSON value that will be
|
||||
// sent to the client.
|
||||
type PresignResp struct {
|
||||
Method, URL string
|
||||
Header http.Header
|
||||
}
|
||||
|
||||
func exitError(err error) {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
40
vendor/github.com/aws/aws-sdk-go/example/service/s3/putObjectAcl/README.md
generated
vendored
Normal file
40
vendor/github.com/aws/aws-sdk-go/example/service/s3/putObjectAcl/README.md
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# Example
|
||||
|
||||
putObjectAcl is an example using the AWS SDK for Go to put an ACL on an S3 object.
|
||||
|
||||
# Usage
|
||||
|
||||
```sh
|
||||
putBucketAcl <params>
|
||||
-region <region> // required
|
||||
-bucket <bucket> // required
|
||||
-key <key> // required
|
||||
-owner-name <owner-name>
|
||||
-owner-id <owner-id>
|
||||
-grantee-type <some type> // required
|
||||
-uri <uri to group>
|
||||
-email <email address>
|
||||
-user-id <user-id>
|
||||
-display-name <display name>
|
||||
```
|
||||
|
||||
```sh
|
||||
go run -tags example putObjectAcl.go
|
||||
-bucket <bucket>
|
||||
-key <key>
|
||||
-owner-name <name>
|
||||
-owner-id <id>
|
||||
-grantee-type <some type>
|
||||
-user-id <user-id>
|
||||
```
|
||||
|
||||
Depending on the type is used depends on which of the three, `uri`, `email`, or `user-id`, needs to be used.
|
||||
* `s3.TypeCanonicalUser`: `user-id` or `display-name` must be used
|
||||
* `s3.TypeAmazonCustomerByEmail`: `email` must be used
|
||||
* `s3.TypeGroup`: `uri` must be used
|
||||
|
||||
Output:
|
||||
```
|
||||
success {
|
||||
} nil
|
||||
```
|
||||
91
vendor/github.com/aws/aws-sdk-go/example/service/s3/putObjectAcl/putObjectAcl.go
generated
vendored
Normal file
91
vendor/github.com/aws/aws-sdk-go/example/service/s3/putObjectAcl/putObjectAcl.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
// Put an ACL on an S3 object
|
||||
//
|
||||
// Usage:
|
||||
// putBucketAcl <params>
|
||||
// -region <region> // required
|
||||
// -bucket <bucket> // required
|
||||
// -key <key> // required
|
||||
// -owner-name <owner-name>
|
||||
// -owner-id <owner-id>
|
||||
// -grantee-type <some type> // required
|
||||
// -uri <uri to group>
|
||||
// -email <email address>
|
||||
// -user-id <user-id>
|
||||
func main() {
|
||||
regionPtr := flag.String("region", "", "region of your request")
|
||||
bucketPtr := flag.String("bucket", "", "name of your bucket")
|
||||
keyPtr := flag.String("key", "", "of your object")
|
||||
ownerNamePtr := flag.String("owner-name", "", "of your request")
|
||||
ownerIDPtr := flag.String("owner-id", "", "of your request")
|
||||
granteeTypePtr := flag.String("grantee-type", "", "of your request")
|
||||
uriPtr := flag.String("uri", "", "of your grantee type")
|
||||
emailPtr := flag.String("email", "", "of your grantee type")
|
||||
userPtr := flag.String("user-id", "", "of your grantee type")
|
||||
displayNamePtr := flag.String("display-name", "", "of your grantee type")
|
||||
flag.Parse()
|
||||
|
||||
// Based off the type, fields must be excluded.
|
||||
switch *granteeTypePtr {
|
||||
case s3.TypeCanonicalUser:
|
||||
emailPtr, uriPtr = nil, nil
|
||||
if *displayNamePtr == "" {
|
||||
displayNamePtr = nil
|
||||
}
|
||||
|
||||
if *userPtr == "" {
|
||||
userPtr = nil
|
||||
}
|
||||
case s3.TypeAmazonCustomerByEmail:
|
||||
uriPtr, userPtr = nil, nil
|
||||
case s3.TypeGroup:
|
||||
emailPtr, userPtr = nil, nil
|
||||
}
|
||||
|
||||
sess := session.Must(session.NewSession(&aws.Config{
|
||||
Region: regionPtr,
|
||||
}))
|
||||
|
||||
svc := s3.New(sess)
|
||||
|
||||
resp, err := svc.PutObjectAcl(&s3.PutObjectAclInput{
|
||||
Bucket: bucketPtr,
|
||||
Key: keyPtr,
|
||||
AccessControlPolicy: &s3.AccessControlPolicy{
|
||||
Owner: &s3.Owner{
|
||||
DisplayName: ownerNamePtr,
|
||||
ID: ownerIDPtr,
|
||||
},
|
||||
Grants: []*s3.Grant{
|
||||
{
|
||||
Grantee: &s3.Grantee{
|
||||
Type: granteeTypePtr,
|
||||
DisplayName: displayNamePtr,
|
||||
URI: uriPtr,
|
||||
EmailAddress: emailPtr,
|
||||
ID: userPtr,
|
||||
},
|
||||
Permission: aws.String(s3.BucketLogsPermissionFullControl),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("failed", err)
|
||||
} else {
|
||||
fmt.Println("success", resp)
|
||||
}
|
||||
}
|
||||
26
vendor/github.com/aws/aws-sdk-go/example/service/s3/sync/README.md
generated
vendored
Normal file
26
vendor/github.com/aws/aws-sdk-go/example/service/s3/sync/README.md
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Example
|
||||
|
||||
sync will upload a given directory to Amazon S3 using the upload iterator interface defined in the
|
||||
s3manager package. This example uses a path that is specified during runtime to walk and build keys
|
||||
to upload to Amazon S3. It will use the keys to upload the files/folders to Amazon S3.
|
||||
|
||||
# Usage
|
||||
|
||||
```sh
|
||||
sync <params>
|
||||
-region <region> // required
|
||||
-bucket <bucket> // required
|
||||
-path <path> // required
|
||||
```
|
||||
|
||||
```sh
|
||||
go run -tags example sync.go
|
||||
-region <region> // required
|
||||
-bucket <bucket> // required
|
||||
-path <path> // required
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
success
|
||||
```
|
||||
112
vendor/github.com/aws/aws-sdk-go/example/service/s3/sync/sync.go
generated
vendored
Normal file
112
vendor/github.com/aws/aws-sdk-go/example/service/s3/sync/sync.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
)
|
||||
|
||||
// SyncFolderIterator is used to upload a given folder
|
||||
// to Amazon S3.
|
||||
type SyncFolderIterator struct {
|
||||
bucket string
|
||||
fileInfos []fileInfo
|
||||
err error
|
||||
}
|
||||
|
||||
type fileInfo struct {
|
||||
key string
|
||||
fullpath string
|
||||
}
|
||||
|
||||
// NewSyncFolderIterator will walk the path, and store the key and full path
|
||||
// of the object to be uploaded. This will return a new SyncFolderIterator
|
||||
// with the data provided from walking the path.
|
||||
func NewSyncFolderIterator(path, bucket string) *SyncFolderIterator {
|
||||
metadata := []fileInfo{}
|
||||
filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
key := strings.TrimPrefix(p, path)
|
||||
metadata = append(metadata, fileInfo{key, p})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return &SyncFolderIterator{
|
||||
bucket,
|
||||
metadata,
|
||||
nil,
|
||||
}
|
||||
}
|
||||
|
||||
// Next will determine whether or not there is any remaining files to
|
||||
// be uploaded.
|
||||
func (iter *SyncFolderIterator) Next() bool {
|
||||
return len(iter.fileInfos) > 0
|
||||
}
|
||||
|
||||
// Err returns any error when os.Open is called.
|
||||
func (iter *SyncFolderIterator) Err() error {
|
||||
return iter.err
|
||||
}
|
||||
|
||||
// UploadObject will prep the new upload object by open that file and constructing a new
|
||||
// s3manager.UploadInput.
|
||||
func (iter *SyncFolderIterator) UploadObject() s3manager.BatchUploadObject {
|
||||
fi := iter.fileInfos[0]
|
||||
iter.fileInfos = iter.fileInfos[1:]
|
||||
body, err := os.Open(fi.fullpath)
|
||||
if err != nil {
|
||||
iter.err = err
|
||||
}
|
||||
|
||||
input := s3manager.UploadInput{
|
||||
Bucket: &iter.bucket,
|
||||
Key: &fi.key,
|
||||
Body: body,
|
||||
}
|
||||
|
||||
return s3manager.BatchUploadObject{
|
||||
&input,
|
||||
nil,
|
||||
}
|
||||
}
|
||||
|
||||
// Upload a directory to a given bucket
|
||||
//
|
||||
// Usage:
|
||||
// sync <params>
|
||||
// -region <region> // required
|
||||
// -bucket <bucket> // required
|
||||
// -path <path> // required
|
||||
func main() {
|
||||
bucketPtr := flag.String("bucket", "", "bucket to upload to")
|
||||
regionPtr := flag.String("region", "", "region to be used when making requests")
|
||||
pathPtr := flag.String("path", "", "path of directory to be synced")
|
||||
flag.Parse()
|
||||
|
||||
sess := session.New(&aws.Config{
|
||||
Region: regionPtr,
|
||||
})
|
||||
uploader := s3manager.NewUploader(sess)
|
||||
|
||||
iter := NewSyncFolderIterator(*pathPtr, *bucketPtr)
|
||||
if err := uploader.UploadWithIterator(aws.BackgroundContext(), iter); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unexpected error has occured: %v", err)
|
||||
}
|
||||
|
||||
if err := iter.Err(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unexpected error occured during file walking: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("Success")
|
||||
}
|
||||
Reference in New Issue
Block a user