mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Replace minio-go with aws-sdk-go for s3-compatible log backend (#670)
* Logs should support specifying region when using S3-compatible object store * Use aws-sdk-go client for s3 backed logstore * fixes vendor with aws-sdk-go dependencies
This commit is contained in:
committed by
Reed Allman
parent
930d1e8dcc
commit
60d2e92c9a
49
vendor/github.com/aws/aws-sdk-go/example/aws/credentials/plugincreds/README.md
generated
vendored
Normal file
49
vendor/github.com/aws/aws-sdk-go/example/aws/credentials/plugincreds/README.md
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
Retrieve Credentials with Go Plugin
|
||||
===
|
||||
|
||||
This example demonstrates how you can take advantage of Go 1.8's new Plugin
|
||||
functionality to retrieve AWS credentials dynamically from a plugin compiled
|
||||
separate from your application.
|
||||
|
||||
Usage
|
||||
---
|
||||
|
||||
Example Plugin
|
||||
---
|
||||
|
||||
You can find the plugin at `plugin/plugin.go` nested within this example. The plugin
|
||||
demonstrates what symbol the SDK will use when lookup up the credential provider
|
||||
and the type signature that needs to be implemented.
|
||||
|
||||
Compile the plugin with:
|
||||
|
||||
go build -tags example -o myPlugin.so -buildmode=plugin plugin/plugin.go
|
||||
|
||||
JSON Credentials File
|
||||
---
|
||||
|
||||
This example plugin will read the credentials from a JSON file pointed to by
|
||||
the `PLUGIN_CREDS_FILE` environment variable. The contents of the file are
|
||||
the credentials, Key, Secret, and Token. The `Token` filed does not need to be
|
||||
set if your credentials do not have one.
|
||||
|
||||
```json
|
||||
{
|
||||
"Key": "MyAWSCredAccessKeyID",
|
||||
"Secret": "MyAWSCredSecretKey",
|
||||
"Token": "MyAWSCredToken"
|
||||
}
|
||||
```
|
||||
|
||||
Example Application
|
||||
---
|
||||
|
||||
The `main.go` file in this folder demonstrates how you can configure the SDK to
|
||||
use a plugin to retrieve credentials with.
|
||||
|
||||
Compile and run application:
|
||||
|
||||
go build -tags example -o myApp main.go
|
||||
|
||||
PLUGIN_CREDS_FILE=pathToCreds.json ./myApp myPlugin.so myBucket myObjectKey
|
||||
|
||||
83
vendor/github.com/aws/aws-sdk-go/example/aws/credentials/plugincreds/main.go
generated
vendored
Normal file
83
vendor/github.com/aws/aws-sdk-go/example/aws/credentials/plugincreds/main.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// +build example,go18
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"plugin"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/plugincreds"
|
||||
"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/s3manager"
|
||||
)
|
||||
|
||||
// Example application which loads a Go Plugin file, and uses the credential
|
||||
// provider defined within the plugin to get credentials for making a S3
|
||||
// request.
|
||||
//
|
||||
// The example will derive the bucket's region automatically if a AWS_REGION
|
||||
// environment variable is not defined.
|
||||
//
|
||||
// Build:
|
||||
// go build -tags example -o myApp main.go
|
||||
//
|
||||
// Usage:
|
||||
// ./myApp <compiled plugin> <bucket> <object key>
|
||||
func main() {
|
||||
if len(os.Args) < 4 {
|
||||
exitErrorf("Usage: myApp <compiled plugin>, <bucket> <object key>")
|
||||
}
|
||||
|
||||
pluginFilename := os.Args[1]
|
||||
bucket := os.Args[2]
|
||||
key := os.Args[3]
|
||||
|
||||
// Open plugin, and load it into the process.
|
||||
p, err := plugin.Open(pluginFilename)
|
||||
if err != nil {
|
||||
exitErrorf("failed to open plugin, %s, %v", pluginFilename, err)
|
||||
}
|
||||
|
||||
// Create a new Credentials value which will source the provider's Retrieve
|
||||
// and IsExpired functions from the plugin.
|
||||
creds, err := plugincreds.NewCredentials(p)
|
||||
if err != nil {
|
||||
exitErrorf("failed to load plugin provider, %v", err)
|
||||
}
|
||||
|
||||
// Example to configure a Session with the newly created credentials that
|
||||
// will be sourced using the plugin's functionality.
|
||||
sess := session.Must(session.NewSession(&aws.Config{
|
||||
Credentials: creds,
|
||||
}))
|
||||
|
||||
// If the region is not available attempt to derive the bucket's region
|
||||
// from a query to S3 for the bucket's metadata
|
||||
region := aws.StringValue(sess.Config.Region)
|
||||
if len(region) == 0 {
|
||||
region, err = s3manager.GetBucketRegion(context.Background(), sess, bucket, endpoints.UsEast1RegionID)
|
||||
if err != nil {
|
||||
exitErrorf("failed to get bucket region, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create the S3 service client for the target region
|
||||
svc := s3.New(sess, aws.NewConfig().WithRegion(region))
|
||||
|
||||
// Get the object's details
|
||||
result, err := svc.HeadObject(&s3.HeadObjectInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String(key),
|
||||
})
|
||||
fmt.Println(result, err)
|
||||
}
|
||||
|
||||
func exitErrorf(format string, args ...interface{}) {
|
||||
fmt.Fprintf(os.Stderr, format+"\n", args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
61
vendor/github.com/aws/aws-sdk-go/example/aws/credentials/plugincreds/plugin/plugin.go
generated
vendored
Normal file
61
vendor/github.com/aws/aws-sdk-go/example/aws/credentials/plugincreds/plugin/plugin.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// +build example,go18
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Example plugin that will retrieve credentials from a JSON file that the
|
||||
// "PLUGIN_CREDS_FILE" environment variable points to
|
||||
//
|
||||
// Build with:
|
||||
// go build -tags example -o plugin.so -buildmode=plugin plugin.go
|
||||
func main() {}
|
||||
|
||||
var myCredProvider provider
|
||||
|
||||
func init() {
|
||||
// Initialize a mock credential provider with stubs
|
||||
myCredProvider = provider{Filename: os.Getenv("PLUGIN_CREDS_FILE")}
|
||||
}
|
||||
|
||||
// GetAWSSDKCredentialProvider is the symbol SDK will lookup and use to
|
||||
// get the credential provider's retrieve and isExpired functions.
|
||||
func GetAWSSDKCredentialProvider() (func() (key, secret, token string, err error), func() bool) {
|
||||
return myCredProvider.Retrieve, myCredProvider.IsExpired
|
||||
}
|
||||
|
||||
// mock implementation of a type that returns retrieves credentials and
|
||||
// returns if they have expired.
|
||||
type provider struct {
|
||||
Filename string
|
||||
|
||||
loaded bool
|
||||
}
|
||||
|
||||
func (p *provider) Retrieve() (key, secret, token string, err error) {
|
||||
f, err := os.Open(p.Filename)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrapf(err, "failed to open credentials file, %q", p.Filename)
|
||||
}
|
||||
decoder := json.NewDecoder(f)
|
||||
|
||||
creds := struct {
|
||||
Key, Secret, Token string
|
||||
}{}
|
||||
|
||||
if err := decoder.Decode(&creds); err != nil {
|
||||
return "", "", "", errors.Wrap(err, "failed to decode credentials file")
|
||||
}
|
||||
|
||||
p.loaded = true
|
||||
return creds.Key, creds.Secret, creds.Token, nil
|
||||
}
|
||||
|
||||
func (p *provider) IsExpired() bool {
|
||||
return !p.loaded
|
||||
}
|
||||
14
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/customEndpoint/README.md
generated
vendored
Normal file
14
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/customEndpoint/README.md
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
Custom Endpoint Example
|
||||
===
|
||||
|
||||
This example provides examples on how you can provide custom endpoints, and logic to how endpoints are resolved by the SDK.
|
||||
|
||||
The example creates multiple clients with different endpoint configuration. From a custom endpoint resolver that wraps the default resolver so that any Amazon S3 service client created uses the custom endpoint, to how you can provide your own logic to a single service's endpoint resolving.
|
||||
|
||||
|
||||
Usage
|
||||
---
|
||||
|
||||
```sh
|
||||
go run -tags example customeEndpoint.go
|
||||
```
|
||||
77
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/customEndpoint/customEndpoint.go
generated
vendored
Normal file
77
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/customEndpoint/customEndpoint.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"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/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/aws/aws-sdk-go/service/sqs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
defaultResolver := endpoints.DefaultResolver()
|
||||
s3CustResolverFn := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
|
||||
if service == "s3" {
|
||||
return endpoints.ResolvedEndpoint{
|
||||
URL: "s3.custom.endpoint.com",
|
||||
SigningRegion: "custom-signing-region",
|
||||
}, nil
|
||||
}
|
||||
|
||||
return defaultResolver.EndpointFor(service, region, optFns...)
|
||||
}
|
||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||
Config: aws.Config{
|
||||
Region: aws.String("us-west-2"),
|
||||
EndpointResolver: endpoints.ResolverFunc(s3CustResolverFn),
|
||||
},
|
||||
}))
|
||||
|
||||
// Create the S3 service client with the shared session. This will
|
||||
// automatically use the S3 custom endpoint configured in the custom
|
||||
// endpoint resolver wrapping the default endpoint resolver.
|
||||
s3Svc := s3.New(sess)
|
||||
// Operation calls will be made to the custom endpoint.
|
||||
s3Svc.GetObject(&s3.GetObjectInput{
|
||||
Bucket: aws.String("myBucket"),
|
||||
Key: aws.String("myObjectKey"),
|
||||
})
|
||||
|
||||
// Create the SQS service client with the shared session. This will
|
||||
// fallback to the default endpoint resolver because the customization
|
||||
// passes any non S3 service endpoint resolve to the default resolver.
|
||||
sqsSvc := sqs.New(sess)
|
||||
// Operation calls will be made to the default endpoint for SQS for the
|
||||
// region configured.
|
||||
sqsSvc.ReceiveMessage(&sqs.ReceiveMessageInput{
|
||||
QueueUrl: aws.String("my-queue-url"),
|
||||
})
|
||||
|
||||
// Create a DynamoDB service client that will use a custom endpoint
|
||||
// resolver that overrides the shared session's. This is useful when
|
||||
// custom endpoints are generated, or multiple endpoints are switched on
|
||||
// by a region value.
|
||||
ddbCustResolverFn := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
|
||||
return endpoints.ResolvedEndpoint{
|
||||
URL: "dynamodb.custom.endpoint",
|
||||
SigningRegion: "custom-signing-region",
|
||||
}, nil
|
||||
}
|
||||
ddbSvc := dynamodb.New(sess, &aws.Config{
|
||||
EndpointResolver: endpoints.ResolverFunc(ddbCustResolverFn),
|
||||
})
|
||||
// Operation calls will be made to the custom endpoint set in the
|
||||
// ddCustResolverFn.
|
||||
ddbSvc.ListTables(&dynamodb.ListTablesInput{})
|
||||
|
||||
// Setting Config's Endpoint will override the EndpointResolver. Forcing
|
||||
// the service client to make all operation to the endpoint specified
|
||||
// the in the config.
|
||||
ddbSvcLocal := dynamodb.New(sess, &aws.Config{
|
||||
Endpoint: aws.String("http://localhost:8088"),
|
||||
})
|
||||
ddbSvcLocal.ListTables(&dynamodb.ListTablesInput{})
|
||||
}
|
||||
37
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/enumEndpoints/README.md
generated
vendored
Normal file
37
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/enumEndpoints/README.md
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
Enumerate Regions and Endpoints Example
|
||||
===
|
||||
|
||||
Demonstrates how the SDK's endpoints can be enumerated over to discover regions, services, and endpoints defined by the SDK's Regions and Endpoints metadata.
|
||||
|
||||
Usage
|
||||
---
|
||||
|
||||
The following parameters can be used to enumerate the SDK's partition metadata.
|
||||
|
||||
Example:
|
||||
|
||||
go run -tags example enumEndpoints.go -p aws -services -r us-west-2
|
||||
|
||||
Output:
|
||||
|
||||
Services with endpoint us-west-2 in aws:
|
||||
ec2
|
||||
dynamodb
|
||||
s3
|
||||
...
|
||||
|
||||
CLI parameters
|
||||
---
|
||||
|
||||
```
|
||||
-p=id partition id, e.g: aws
|
||||
-r=id region id, e.g: us-west-2
|
||||
-s=id service id, e.g: s3
|
||||
|
||||
-partitions Lists all partitions.
|
||||
-regions Lists all regions in a partition. Requires partition ID.
|
||||
If service ID is also provided will show endpoints for a service.
|
||||
-services Lists all services in a partition. Requires partition ID.
|
||||
If region ID is also provided, will show services available in that region.
|
||||
```
|
||||
|
||||
126
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/enumEndpoints/enumEndpoints.go
generated
vendored
Normal file
126
vendor/github.com/aws/aws-sdk-go/example/aws/endpoints/enumEndpoints/enumEndpoints.go
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||
)
|
||||
|
||||
// Demostrates how the SDK's endpoints can be enumerated over to discover
|
||||
// regions, services, and endpoints defined by the SDK's Regions and Endpoints
|
||||
// metadata.
|
||||
//
|
||||
// Usage:
|
||||
// -p=id partition id, e.g: aws
|
||||
// -r=id region id, e.g: us-west-2
|
||||
// -s=id service id, e.g: s3
|
||||
//
|
||||
// -partitions Lists all partitions.
|
||||
// -regions Lists all regions in a partition. Requires partition ID.
|
||||
// If service ID is also provided will show endpoints for a service.
|
||||
// -services Lists all services in a partition. Requires partition ID.
|
||||
// If region ID is also provided, will show services available in that region.
|
||||
//
|
||||
// Example:
|
||||
// go run enumEndpoints.go -p aws -services -r us-west-2
|
||||
//
|
||||
// Output:
|
||||
// Services with endpoint us-west-2 in aws:
|
||||
// ...
|
||||
func main() {
|
||||
var partitionID, regionID, serviceID string
|
||||
flag.StringVar(&partitionID, "p", "", "Partition ID")
|
||||
flag.StringVar(®ionID, "r", "", "Region ID")
|
||||
flag.StringVar(&serviceID, "s", "", "Service ID")
|
||||
|
||||
var cmdPartitions, cmdRegions, cmdServices bool
|
||||
flag.BoolVar(&cmdPartitions, "partitions", false, "Lists partitions.")
|
||||
flag.BoolVar(&cmdRegions, "regions", false, "Lists regions of a partition. Requires partition ID to be provided. Will filter by a service if '-s' is set.")
|
||||
flag.BoolVar(&cmdServices, "services", false, "Lists services for a partition. Requires partition ID to be provided. Will filter by a region if '-r' is set.")
|
||||
flag.Parse()
|
||||
|
||||
partitions := endpoints.DefaultResolver().(endpoints.EnumPartitions).Partitions()
|
||||
|
||||
if cmdPartitions {
|
||||
printPartitions(partitions)
|
||||
}
|
||||
|
||||
if !(cmdRegions || cmdServices) {
|
||||
return
|
||||
}
|
||||
|
||||
p, ok := findPartition(partitions, partitionID)
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr, "Partition %q not found", partitionID)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if cmdRegions {
|
||||
printRegions(p, serviceID)
|
||||
}
|
||||
|
||||
if cmdServices {
|
||||
printServices(p, regionID)
|
||||
}
|
||||
}
|
||||
|
||||
func printPartitions(ps []endpoints.Partition) {
|
||||
fmt.Println("Partitions:")
|
||||
for _, p := range ps {
|
||||
fmt.Println(p.ID())
|
||||
}
|
||||
}
|
||||
|
||||
func printRegions(p endpoints.Partition, serviceID string) {
|
||||
if len(serviceID) != 0 {
|
||||
s, ok := p.Services()[serviceID]
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr, "service %q does not exist in partition %q", serviceID, p.ID())
|
||||
os.Exit(1)
|
||||
}
|
||||
es := s.Endpoints()
|
||||
fmt.Printf("Endpoints for %s in %s:\n", serviceID, p.ID())
|
||||
for _, e := range es {
|
||||
r, _ := e.ResolveEndpoint()
|
||||
fmt.Printf("%s: %s\n", e.ID(), r.URL)
|
||||
}
|
||||
|
||||
} else {
|
||||
rs := p.Regions()
|
||||
fmt.Printf("Regions in %s:\n", p.ID())
|
||||
for _, r := range rs {
|
||||
fmt.Println(r.ID())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printServices(p endpoints.Partition, endpointID string) {
|
||||
ss := p.Services()
|
||||
|
||||
if len(endpointID) > 0 {
|
||||
fmt.Printf("Services with endpoint %s in %s:\n", endpointID, p.ID())
|
||||
} else {
|
||||
fmt.Printf("Services in %s:\n", p.ID())
|
||||
}
|
||||
|
||||
for id, s := range ss {
|
||||
if _, ok := s.Endpoints()[endpointID]; !ok && len(endpointID) > 0 {
|
||||
continue
|
||||
}
|
||||
fmt.Println(id)
|
||||
}
|
||||
}
|
||||
|
||||
func findPartition(ps []endpoints.Partition, partitionID string) (endpoints.Partition, bool) {
|
||||
for _, p := range ps {
|
||||
if p.ID() == partitionID {
|
||||
return p, true
|
||||
}
|
||||
}
|
||||
|
||||
return endpoints.Partition{}, false
|
||||
}
|
||||
17
vendor/github.com/aws/aws-sdk-go/example/aws/request/handleServiceErrorCodes/README.md
generated
vendored
Normal file
17
vendor/github.com/aws/aws-sdk-go/example/aws/request/handleServiceErrorCodes/README.md
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Handling Specific Service Error Codes
|
||||
|
||||
This examples highlights how you can use the `awserr.Error` type to perform logic based on specific error codes returned by service API operations.
|
||||
|
||||
In this example the `S3` `GetObject` API operation is used to request the contents of a object in S3. The example handles the `NoSuchBucket` and `NoSuchKey` error codes printing custom messages to stderr. If Any other error is received a generic message is printed.
|
||||
|
||||
## Usage
|
||||
|
||||
Will make a request to S3 for the contents of an object. If the request was successful, and the object was found the object's path and size will be printed to stdout.
|
||||
|
||||
If the object's bucket or key does not exist a specific error message will be printed to stderr for the error.
|
||||
|
||||
Any other error will be printed as an unknown error.
|
||||
|
||||
```sh
|
||||
go run -tags example handleServiceErrorCodes.go mybucket mykey
|
||||
```
|
||||
66
vendor/github.com/aws/aws-sdk-go/example/aws/request/handleServiceErrorCodes/handleServiceErrorCodes.go
generated
vendored
Normal file
66
vendor/github.com/aws/aws-sdk-go/example/aws/request/handleServiceErrorCodes/handleServiceErrorCodes.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
func exitErrorf(msg string, args ...interface{}) {
|
||||
fmt.Fprintf(os.Stderr, msg+"\n", args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Will make a request to S3 for the contents of an object. If the request
|
||||
// was successful, and the object was found the object's path and size will be
|
||||
// printed to stdout.
|
||||
//
|
||||
// If the object's bucket or key does not exist a specific error message will
|
||||
// be printed to stderr for the error.
|
||||
//
|
||||
// Any other error will be printed as an unknown error.
|
||||
//
|
||||
// Usage: handleServiceErrorCodes <bucket> <key>
|
||||
func main() {
|
||||
if len(os.Args) < 3 {
|
||||
exitErrorf("Usage: %s <bucket> <key>", filepath.Base(os.Args[0]))
|
||||
}
|
||||
sess := session.Must(session.NewSession())
|
||||
|
||||
svc := s3.New(sess)
|
||||
resp, err := svc.GetObject(&s3.GetObjectInput{
|
||||
Bucket: aws.String(os.Args[1]),
|
||||
Key: aws.String(os.Args[2]),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// Casting to the awserr.Error type will allow you to inspect the error
|
||||
// code returned by the service in code. The error code can be used
|
||||
// to switch on context specific functionality. In this case a context
|
||||
// specific error message is printed to the user based on the bucket
|
||||
// and key existing.
|
||||
//
|
||||
// For information on other S3 API error codes see:
|
||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case s3.ErrCodeNoSuchBucket:
|
||||
exitErrorf("bucket %s does not exist", os.Args[1])
|
||||
case s3.ErrCodeNoSuchKey:
|
||||
exitErrorf("object with key %s does not exist in bucket %s", os.Args[2], os.Args[1])
|
||||
}
|
||||
}
|
||||
exitErrorf("unknown error occurred, %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
fmt.Printf("s3://%s/%s exists. size: %d\n", os.Args[1], os.Args[2],
|
||||
aws.Int64Value(resp.ContentLength))
|
||||
}
|
||||
13
vendor/github.com/aws/aws-sdk-go/example/aws/request/withContext/README.md
generated
vendored
Normal file
13
vendor/github.com/aws/aws-sdk-go/example/aws/request/withContext/README.md
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Example
|
||||
|
||||
Uploads a file to S3 given a bucket and object key. Also takes a duration
|
||||
value to terminate the update if it doesn't complete within that time.
|
||||
|
||||
The AWS Region needs to be provided in the AWS shared config or on the
|
||||
environment variable as `AWS_REGION`. Credentials also must be provided.
|
||||
Will default to shared config file, but can load from environment if provided.
|
||||
|
||||
## Usage:
|
||||
|
||||
# Upload myfile.txt to myBucket/myKey. Must complete within 10 minutes or will fail
|
||||
go run -tags example withContext.go -b mybucket -k myKey -d 10m < myfile.txt
|
||||
71
vendor/github.com/aws/aws-sdk-go/example/aws/request/withContext/withContext.go
generated
vendored
Normal file
71
vendor/github.com/aws/aws-sdk-go/example/aws/request/withContext/withContext.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// +build example,go1.7
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
// Uploads a file to S3 given a bucket and object key. Also takes a duration
|
||||
// value to terminate the update if it doesn't complete within that time.
|
||||
//
|
||||
// The AWS Region needs to be provided in the AWS shared config or on the
|
||||
// environment variable as `AWS_REGION`. Credentials also must be provided
|
||||
// Will default to shared config file, but can load from environment if provided.
|
||||
//
|
||||
// Usage:
|
||||
// # Upload myfile.txt to myBucket/myKey. Must complete within 10 minutes or will fail
|
||||
// go run withContext.go -b mybucket -k myKey -d 10m < myfile.txt
|
||||
func main() {
|
||||
var bucket, key string
|
||||
var timeout time.Duration
|
||||
|
||||
flag.StringVar(&bucket, "b", "", "Bucket name.")
|
||||
flag.StringVar(&key, "k", "", "Object key name.")
|
||||
flag.DurationVar(&timeout, "d", 0, "Upload timeout.")
|
||||
flag.Parse()
|
||||
|
||||
sess := session.Must(session.NewSession())
|
||||
svc := s3.New(sess)
|
||||
|
||||
// Create a context with a timeout that will abort the upload if it takes
|
||||
// more than the passed in timeout.
|
||||
ctx := context.Background()
|
||||
var cancelFn func()
|
||||
if timeout > 0 {
|
||||
ctx, cancelFn = context.WithTimeout(ctx, timeout)
|
||||
}
|
||||
// Ensure the context is canceled to prevent leaking.
|
||||
// See context package for more information, https://golang.org/pkg/context/
|
||||
defer cancelFn()
|
||||
|
||||
// Uploads the object to S3. The Context will interrupt the request if the
|
||||
// timeout expires.
|
||||
_, err := svc.PutObjectWithContext(ctx, &s3.PutObjectInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String(key),
|
||||
Body: os.Stdin,
|
||||
})
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == request.CanceledErrorCode {
|
||||
// If the SDK can determine the request or retry delay was canceled
|
||||
// by a context the CanceledErrorCode error code will be returned.
|
||||
fmt.Fprintf(os.Stderr, "upload canceled due to timeout, %v\n", err)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "failed to upload object, %v\n", err)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("successfully uploaded file to %s/%s\n", bucket, key)
|
||||
}
|
||||
12
vendor/github.com/aws/aws-sdk-go/example/service/cloudfront/signCookies/README.md
generated
vendored
Normal file
12
vendor/github.com/aws/aws-sdk-go/example/service/cloudfront/signCookies/README.md
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Example
|
||||
|
||||
This example shows how the CloudFront CookieSigner can be used to generate signed cookies to provided short term access to restricted resourced fronted by CloudFront.
|
||||
|
||||
# Usage
|
||||
Makes a request for object using CloudFront cookie signing, and outputs the contents of the object to stdout.
|
||||
|
||||
```sh
|
||||
go run -tags example signCookies.go -file <privkey file> -id <keyId> -r <resource pattern> -g <object to get>
|
||||
```
|
||||
|
||||
|
||||
79
vendor/github.com/aws/aws-sdk-go/example/service/cloudfront/signCookies/signCookies.go
generated
vendored
Normal file
79
vendor/github.com/aws/aws-sdk-go/example/service/cloudfront/signCookies/signCookies.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/cloudfront/sign"
|
||||
)
|
||||
|
||||
// Makes a request for object using CloudFront cookie signing, and outputs
|
||||
// the contents of the object to stdout.
|
||||
//
|
||||
// Usage example:
|
||||
// signCookies -file <privkey file> -id <keyId> -r <resource pattern> -g <object to get>
|
||||
func main() {
|
||||
var keyFile string // Private key PEM file
|
||||
var keyID string // Key pair ID of CloudFront key pair
|
||||
var resource string // CloudFront resource pattern
|
||||
var object string // S3 object frontented by CloudFront
|
||||
|
||||
flag.StringVar(&keyFile, "file", "", "private key file")
|
||||
flag.StringVar(&keyID, "id", "", "key pair id")
|
||||
flag.StringVar(&resource, "r", "", "resource to request")
|
||||
flag.StringVar(&object, "g", "", "object to get")
|
||||
flag.Parse()
|
||||
|
||||
// Load the PEM file into memory so it can be used by the signer
|
||||
privKey, err := sign.LoadPEMPrivKeyFile(keyFile)
|
||||
if err != nil {
|
||||
fmt.Println("failed to load key,", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create the new CookieSigner to get signed cookies for CloudFront
|
||||
// resource requests
|
||||
signer := sign.NewCookieSigner(keyID, privKey)
|
||||
|
||||
// Get the cookies for the resource. These will be used
|
||||
// to make the requests with
|
||||
cookies, err := signer.Sign(resource, time.Now().Add(1*time.Hour))
|
||||
if err != nil {
|
||||
fmt.Println("failed to sign cookies", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Use the cookies in a http.Client to show how they allow the client
|
||||
// to request resources from CloudFront.
|
||||
req, err := http.NewRequest("GET", object, nil)
|
||||
fmt.Println("Cookies:")
|
||||
for _, c := range cookies {
|
||||
fmt.Printf("%s=%s;\n", c.Name, c.Value)
|
||||
req.AddCookie(c)
|
||||
}
|
||||
|
||||
// Send and handle the response. For a successful response the object's
|
||||
// content will be written to stdout. The same process could be applied
|
||||
// to a http service written cookies to the response but using
|
||||
// http.SetCookie(w, c,) on the ResponseWriter.
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
fmt.Println("failed to send request", err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Println("failed to read requested body", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Response:", resp.Status)
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
102
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/expression/readme.md
generated
vendored
Normal file
102
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/expression/readme.md
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
# Example
|
||||
|
||||
`scan` is an example how to use Amazon DynamoDB's `expression` package to fill
|
||||
the member fields of Amazon DynamoDB's Operation input types.
|
||||
|
||||
## Representing DynamoDB Expressions
|
||||
|
||||
In the example, the variable `filt` represents a `FilterExpression`. Note that
|
||||
DynamoDB item attributes are represented using the function `Name()` and
|
||||
DynamoDB item values are similarly represented using the function `Value()`. In
|
||||
this context, the string `"Artist"` represents the name of the item attribute
|
||||
that we want to evaluate and the string `"No One You Know"` represents the value
|
||||
we want to evaluate the item attribute against. The relationship between the two
|
||||
[operands](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Syntax)
|
||||
are specified using the method `Equal()`.
|
||||
|
||||
Similarly, the variable `proj` represents a `ProjectionExpression`. The list of
|
||||
item attribute names comprising the `ProjectionExpression` are specified as
|
||||
arguments to the function `NamesList()`. The `expression` package utilizes the
|
||||
type safety of Go and if an item value were to be used as an argument to the
|
||||
function `NamesList()`, a compile time error is returned. The pattern of
|
||||
representing DynamoDB Expressions by indicating relationships between `operands`
|
||||
with functions is consistent throughout the whole `expression` package.
|
||||
|
||||
```go
|
||||
filt := expression.Name("Artist").Equal(expression.Value("No One You Know"))
|
||||
// let :a be an ExpressionAttributeValue representing the string "No One You Know"
|
||||
// equivalent FilterExpression: "Artist = :a"
|
||||
|
||||
proj := expression.NamesList(expression.Name("SongTitle"), expression.Name("AlbumTitle"))
|
||||
// equivalent ProjectionExpression: "SongTitle, AlbumTitle"
|
||||
```
|
||||
|
||||
## Creating an `Expression`
|
||||
|
||||
In the example, the variable `expr` is an instance of an `Expression` type. An
|
||||
`Expression` is built using a builder pattern. First, a new `Builder` is
|
||||
initialized by the `NewBuilder()` function. Then, types representing DynamoDB
|
||||
Expressions are added to the `Builder` by methods `WithFilter()` and
|
||||
`WithProjection()`. The `Build()` method returns an instance of an `Expression`
|
||||
and an error. The error will be either an `InvalidParameterError` or an
|
||||
`UnsetParameterError`.
|
||||
|
||||
```go
|
||||
filt := expression.Name("Artist").Equal(expression.Value("No One You Know"))
|
||||
proj := expression.NamesList(expression.Name("SongTitle"), expression.Name("AlbumTitle"))
|
||||
|
||||
expr, err := expression.NewBuilder().WithFilter(filt).WithProjection(proj).Build()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
|
||||
## Filling in the fields of a DynamoDB `Scan` API
|
||||
|
||||
In the example, the getter methods of the `Expression` type is used to get the
|
||||
formatted DynamoDB Expression strings. The `ExpressionAttributeNames` and
|
||||
`ExpressionAttributeValues` member field of the DynamoDB API must always be
|
||||
assigned when using an `Expression` since all item attribute names and values
|
||||
are aliased. That means that if the `ExpressionAttributeNames` and
|
||||
`ExpressionAttributeValues` member is not assigned with the corresponding
|
||||
`Names()` and `Values()` methods, the DynamoDB operation will run into a logic
|
||||
error.
|
||||
|
||||
```go
|
||||
filt := expression.Name("Artist").Equal(expression.Value("No One You Know"))
|
||||
proj := expression.NamesList(expression.Name("SongTitle"), expression.Name("AlbumTitle"))
|
||||
expr, err := expression.NewBuilder().WithFilter(filt).WithProjection(proj).Build()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
input := &dynamodb.ScanInput{
|
||||
ExpressionAttributeNames: expr.Names(),
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
FilterExpression: expr.Filter(),
|
||||
ProjectionExpression: expr.Projection(),
|
||||
TableName: aws.String("Music"),
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`go run -tags example scan.go -table "<table_name>" -region "<optional_region>"`
|
||||
|
||||
## Output
|
||||
|
||||
```
|
||||
{
|
||||
Count: #SomeNumber,
|
||||
Items: [{
|
||||
AlbumTitle: {
|
||||
#SomeAlbumTitle
|
||||
},
|
||||
SongTitle: {
|
||||
#SomeSongTitle
|
||||
}
|
||||
}],
|
||||
...
|
||||
ScannedCount: #SomeNumber,
|
||||
}
|
||||
```
|
||||
88
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/expression/scan.go
generated
vendored
Normal file
88
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/expression/scan.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/expression"
|
||||
)
|
||||
|
||||
func exitWithError(err error) {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
cfg := Config{}
|
||||
if err := cfg.Load(); err != nil {
|
||||
exitWithError(fmt.Errorf("failed to load config, %v", err))
|
||||
}
|
||||
|
||||
// Create the config specifying the Region for the DynamoDB table.
|
||||
// If Config.Region is not set the region must come from the shared
|
||||
// config or AWS_REGION environment variable.
|
||||
awscfg := &aws.Config{}
|
||||
if len(cfg.Region) > 0 {
|
||||
awscfg.WithRegion(cfg.Region)
|
||||
}
|
||||
|
||||
// Create the session that the DynamoDB service will use.
|
||||
sess := session.Must(session.NewSession(awscfg))
|
||||
|
||||
// Create the DynamoDB service client to make the query request with.
|
||||
svc := dynamodb.New(sess)
|
||||
|
||||
// Create the Expression to fill the input struct with.
|
||||
filt := expression.Name("Artist").Equal(expression.Value("No One You Know"))
|
||||
proj := expression.NamesList(expression.Name("SongTitle"), expression.Name("AlbumTitle"))
|
||||
expr, err := expression.NewBuilder().WithFilter(filt).WithProjection(proj).Build()
|
||||
if err != nil {
|
||||
exitWithError(fmt.Errorf("failed to create the Expression, %v", err))
|
||||
}
|
||||
|
||||
// Build the query input parameters
|
||||
params := &dynamodb.ScanInput{
|
||||
ExpressionAttributeNames: expr.Names(),
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
FilterExpression: expr.Filter(),
|
||||
ProjectionExpression: expr.Projection(),
|
||||
TableName: aws.String(cfg.Table),
|
||||
}
|
||||
if cfg.Limit > 0 {
|
||||
params.Limit = aws.Int64(cfg.Limit)
|
||||
}
|
||||
|
||||
// Make the DynamoDB Query API call
|
||||
result, err := svc.Scan(params)
|
||||
if err != nil {
|
||||
exitWithError(fmt.Errorf("failed to make Query API call, %v", err))
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Table string // required
|
||||
Region string // optional
|
||||
Limit int64 // optional
|
||||
}
|
||||
|
||||
func (c *Config) Load() error {
|
||||
flag.Int64Var(&c.Limit, "limit", 0, "Limit is the max items to be returned, 0 is no limit")
|
||||
flag.StringVar(&c.Table, "table", "", "Table to Query on")
|
||||
flag.StringVar(&c.Region, "region", "", "AWS Region the table is in")
|
||||
flag.Parse()
|
||||
|
||||
if len(c.Table) == 0 {
|
||||
flag.PrintDefaults()
|
||||
return fmt.Errorf("table name is required.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
47
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/scanItems/README.md
generated
vendored
Normal file
47
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/scanItems/README.md
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# Example
|
||||
|
||||
`scanItems` is an example how to use Amazon DynamoDB's Scan API operation with the SDK's `dynamodbattributes.UnmarshalListOfMaps` to unmarshal the Scan response's `Items` `[]map[string]*dynamodb.AttributeValue` field. This unmarshaler can be used with all `[]map[string]*dynamodb.AttributeValue` type fields.
|
||||
|
||||
## Go Type
|
||||
|
||||
The `Item` time will be used by the example to unmarshal the DynamoDB table's items to.
|
||||
|
||||
```go
|
||||
type Item struct {
|
||||
Key int
|
||||
Desc string
|
||||
Data map[string]interface{}
|
||||
}
|
||||
```
|
||||
Use Go tags to define what the name is of the attribute in your DynamoDB table. See [AWS SDK for Go API Reference: Marshal](https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/#Marshal) for more information.
|
||||
|
||||
In DynamoDB the structure of the item to be returned will be:
|
||||
```json
|
||||
{
|
||||
"Data": {
|
||||
"Value 1": "abc",
|
||||
"Value 2": 1234567890
|
||||
},
|
||||
"Desc": "First ddb item",
|
||||
"Key": 1
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`go run -tags example scanItems.go -table "<table_name>" -region "<optional_region>"`
|
||||
|
||||
## Output
|
||||
|
||||
```
|
||||
0: Key: 123, Desc: An item in the DynamoDB table
|
||||
Num Data Values: 0
|
||||
1: Key: 2, Desc: Second ddb item
|
||||
Num Data Values: 2
|
||||
- "A Field": 123
|
||||
- "Another Field": abc
|
||||
2: Key: 1, Desc: First ddb item
|
||||
Num Data Values: 2
|
||||
- "Value 1": abc
|
||||
- "Value 2": 1234567890
|
||||
```
|
||||
98
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/scanItems/scanItems.go
generated
vendored
Normal file
98
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/scanItems/scanItems.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
|
||||
)
|
||||
|
||||
func exitWithError(err error) {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
cfg := Config{}
|
||||
if err := cfg.Load(); err != nil {
|
||||
exitWithError(fmt.Errorf("failed to load config, %v", err))
|
||||
}
|
||||
|
||||
// Create the config specifying the Region for the DynamoDB table.
|
||||
// If Config.Region is not set the region must come from the shared
|
||||
// config or AWS_REGION environment variable.
|
||||
awscfg := &aws.Config{}
|
||||
if len(cfg.Region) > 0 {
|
||||
awscfg.WithRegion(cfg.Region)
|
||||
}
|
||||
|
||||
// Create the session that the DynamoDB service will use.
|
||||
sess := session.Must(session.NewSession(awscfg))
|
||||
|
||||
// Create the DynamoDB service client to make the query request with.
|
||||
svc := dynamodb.New(sess)
|
||||
|
||||
// Build the query input parameters
|
||||
params := &dynamodb.ScanInput{
|
||||
TableName: aws.String(cfg.Table),
|
||||
}
|
||||
if cfg.Limit > 0 {
|
||||
params.Limit = aws.Int64(cfg.Limit)
|
||||
}
|
||||
|
||||
// Make the DynamoDB Query API call
|
||||
result, err := svc.Scan(params)
|
||||
if err != nil {
|
||||
exitWithError(fmt.Errorf("failed to make Query API call, %v", err))
|
||||
}
|
||||
|
||||
items := []Item{}
|
||||
|
||||
// Unmarshal the Items field in the result value to the Item Go type.
|
||||
err = dynamodbattribute.UnmarshalListOfMaps(result.Items, &items)
|
||||
if err != nil {
|
||||
exitWithError(fmt.Errorf("failed to unmarshal Query result items, %v", err))
|
||||
}
|
||||
|
||||
// Print out the items returned
|
||||
for i, item := range items {
|
||||
fmt.Printf("%d: Key: %d, Desc: %s\n", i, item.Key, item.Desc)
|
||||
fmt.Printf("\tNum Data Values: %d\n", len(item.Data))
|
||||
for k, v := range item.Data {
|
||||
fmt.Printf("\t- %q: %v\n", k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Key int
|
||||
Desc string
|
||||
Data map[string]interface{}
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Table string // required
|
||||
Region string // optional
|
||||
Limit int64 // optional
|
||||
|
||||
}
|
||||
|
||||
func (c *Config) Load() error {
|
||||
flag.Int64Var(&c.Limit, "limit", 0, "Limit is the max items to be returned, 0 is no limit")
|
||||
flag.StringVar(&c.Table, "table", "", "Table to Query on")
|
||||
flag.StringVar(&c.Region, "region", "", "AWS Region the table is in")
|
||||
flag.Parse()
|
||||
|
||||
if len(c.Table) == 0 {
|
||||
flag.PrintDefaults()
|
||||
return fmt.Errorf("table name is required.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
52
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/unitTest/README.md
generated
vendored
Normal file
52
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/unitTest/README.md
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# Example
|
||||
You can instantiate `*dynamodb.DynamoDB` and pass that as a parameter to all
|
||||
methods connecting to DynamoDB, or as `unitTest` demonstrates, create your own
|
||||
`type` and pass it along as a field.
|
||||
|
||||
## Test-compatible DynamoDB field
|
||||
If you use `*dynamodb.DynamoDB` as a field, you will be unable to unit test it,
|
||||
as documented in #88. Cast it instead as `dynamodbiface.DynamoDBAPI`:
|
||||
|
||||
```go
|
||||
type ItemGetter struct {
|
||||
DynamoDB dynamodbiface.DynamoDBAPI
|
||||
}
|
||||
```
|
||||
|
||||
## Querying actual DynamoDB
|
||||
You'll need an `*aws.Config` and `*session.Session` for these to work correctly:
|
||||
|
||||
```go
|
||||
// Setup
|
||||
var getter = new(ItemGetter)
|
||||
var config *aws.Config = &aws.Config{Region: aws.String("us-west-2"),}
|
||||
var sess *session.Session = session.NewSession(config)
|
||||
var svc *dynamodb.DynamoDB = dynamodb.New()
|
||||
getter.DynamoDB = dynamodbiface.DynamoDBAPI(svc)
|
||||
// Finally
|
||||
getter.DynamoDB.GetItem(/* ... */)
|
||||
```
|
||||
|
||||
## Querying in tests
|
||||
Construct a `fakeDynamoDB` and add the necessary methods for each of those
|
||||
structs (custom ones for `ItemGetter` and [whatever methods you're using for
|
||||
DynamoDB](https://github.com/aws/aws-sdk-go/blob/master/service/dynamodb/dynamodbiface/interface.go)),
|
||||
and you're good to go!
|
||||
|
||||
```go
|
||||
type fakeDynamoDB struct {
|
||||
dynamodbiface.DynamoDBAPI
|
||||
}
|
||||
var getter = new(ItemGetter)
|
||||
getter.DynamoDB = &fakeDynamoDB{}
|
||||
// And to run it (assuming you've mocked fakeDynamoDB.GetItem)
|
||||
getter.DynamoDB.GetItem(/* ... */)
|
||||
```
|
||||
|
||||
## Output
|
||||
```
|
||||
$ go test -tags example -cover
|
||||
PASS
|
||||
coverage: 100.0% of statements
|
||||
ok _/Users/shatil/workspace/aws-sdk-go/example/service/dynamodb/unitTest 0.008s
|
||||
```
|
||||
41
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/unitTest/unitTest.go
generated
vendored
Normal file
41
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/unitTest/unitTest.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// +build example
|
||||
|
||||
// Package unitTest demonstrates how to unit test, without needing to pass a
|
||||
// connector to every function, code that uses DynamoDB.
|
||||
package unitTest
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
|
||||
)
|
||||
|
||||
// ItemGetter can be assigned a DynamoDB connector like:
|
||||
// svc := dynamodb.DynamoDB(sess)
|
||||
// getter.DynamoDB = dynamodbiface.DynamoDBAPI(svc)
|
||||
type ItemGetter struct {
|
||||
DynamoDB dynamodbiface.DynamoDBAPI
|
||||
}
|
||||
|
||||
// Get a value from a DynamoDB table containing entries like:
|
||||
// {"id": "my primary key", "value": "valuable value"}
|
||||
func (ig *ItemGetter) Get(id string) (value string) {
|
||||
var input = &dynamodb.GetItemInput{
|
||||
Key: map[string]*dynamodb.AttributeValue{
|
||||
"id": {
|
||||
S: aws.String(id),
|
||||
},
|
||||
},
|
||||
TableName: aws.String("my_table"),
|
||||
AttributesToGet: []*string{
|
||||
aws.String("value"),
|
||||
},
|
||||
}
|
||||
if output, err := ig.DynamoDB.GetItem(input); err == nil {
|
||||
if _, ok := output.Item["value"]; ok {
|
||||
dynamodbattribute.Unmarshal(output.Item["value"], &value)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
59
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/unitTest/unitTest_test.go
generated
vendored
Normal file
59
vendor/github.com/aws/aws-sdk-go/example/service/dynamodb/unitTest/unitTest_test.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// +build example
|
||||
|
||||
// Unit tests for package unitTest.
|
||||
package unitTest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
|
||||
)
|
||||
|
||||
// A fakeDynamoDB instance. During testing, instatiate ItemGetter, then simply
|
||||
// assign an instance of fakeDynamoDB to it.
|
||||
type fakeDynamoDB struct {
|
||||
dynamodbiface.DynamoDBAPI
|
||||
payload map[string]string // Store expected return values
|
||||
err error
|
||||
}
|
||||
|
||||
// Mock GetItem such that the output returned carries values identical to input.
|
||||
func (fd *fakeDynamoDB) GetItem(input *dynamodb.GetItemInput) (*dynamodb.GetItemOutput, error) {
|
||||
output := new(dynamodb.GetItemOutput)
|
||||
output.Item = make(map[string]*dynamodb.AttributeValue)
|
||||
for key, value := range fd.payload {
|
||||
output.Item[key] = &dynamodb.AttributeValue{
|
||||
S: aws.String(value),
|
||||
}
|
||||
}
|
||||
return output, fd.err
|
||||
}
|
||||
|
||||
func TestItemGetterGet(t *testing.T) {
|
||||
expectedKey := "expected key"
|
||||
expectedValue := "expected value"
|
||||
getter := new(ItemGetter)
|
||||
getter.DynamoDB = &fakeDynamoDB{
|
||||
payload: map[string]string{"id": expectedKey, "value": expectedValue},
|
||||
}
|
||||
if actualValue := getter.Get(expectedKey); actualValue != expectedValue {
|
||||
t.Errorf("Expected %q but got %q", expectedValue, actualValue)
|
||||
}
|
||||
}
|
||||
|
||||
// When DynamoDB.GetItem returns a non-nil error, expect an empty string.
|
||||
func TestItemGetterGetFail(t *testing.T) {
|
||||
expectedKey := "expected key"
|
||||
expectedValue := "expected value"
|
||||
getter := new(ItemGetter)
|
||||
getter.DynamoDB = &fakeDynamoDB{
|
||||
payload: map[string]string{"id": expectedKey, "value": expectedValue},
|
||||
err: errors.New("any error"),
|
||||
}
|
||||
if actualValue := getter.Get(expectedKey); len(actualValue) > 0 {
|
||||
t.Errorf("Expected %q but got %q", expectedValue, actualValue)
|
||||
}
|
||||
}
|
||||
31
vendor/github.com/aws/aws-sdk-go/example/service/ec2/filterInstances/README.md
generated
vendored
Normal file
31
vendor/github.com/aws/aws-sdk-go/example/service/ec2/filterInstances/README.md
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Example
|
||||
|
||||
This is an example using the AWS SDK for Go to list ec2 instances that match provided tag name filter.
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
The example uses the bucket name provided, and lists all object keys in a bucket.
|
||||
|
||||
```sh
|
||||
go run -tags example filter_ec2_by_tag.go <name_filter>
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
listing instances with tag vpn in: us-east-1
|
||||
[{
|
||||
Instances: [{
|
||||
AmiLaunchIndex: 0,
|
||||
Architecture: "x86_64",
|
||||
BlockDeviceMappings: [{
|
||||
DeviceName: "/dev/xvda",
|
||||
Ebs: {
|
||||
AttachTime: 2016-07-06 18:04:53 +0000 UTC,
|
||||
DeleteOnTermination: true,
|
||||
Status: "attached",
|
||||
VolumeId: "vol-xxxx"
|
||||
}
|
||||
}],
|
||||
...
|
||||
```
|
||||
43
vendor/github.com/aws/aws-sdk-go/example/service/ec2/filterInstances/filter_ec2_by_tag.go
generated
vendored
Normal file
43
vendor/github.com/aws/aws-sdk-go/example/service/ec2/filterInstances/filter_ec2_by_tag.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
)
|
||||
|
||||
// This example will list instances with a filter
|
||||
//
|
||||
// Usage:
|
||||
// filter_ec2_by_tag <name_filter>
|
||||
func main() {
|
||||
sess := session.Must(session.NewSession())
|
||||
|
||||
nameFilter := os.Args[1]
|
||||
awsRegion := "us-east-1"
|
||||
svc := ec2.New(sess, &aws.Config{Region: aws.String(awsRegion)})
|
||||
fmt.Printf("listing instances with tag %v in: %v\n", nameFilter, awsRegion)
|
||||
params := &ec2.DescribeInstancesInput{
|
||||
Filters: []*ec2.Filter{
|
||||
{
|
||||
Name: aws.String("tag:Name"),
|
||||
Values: []*string{
|
||||
aws.String(strings.Join([]string{"*", nameFilter, "*"}, "")),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
resp, err := svc.DescribeInstances(params)
|
||||
if err != nil {
|
||||
fmt.Println("there was an error listing instances in", awsRegion, err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
fmt.Printf("%+v\n", *resp)
|
||||
}
|
||||
32
vendor/github.com/aws/aws-sdk-go/example/service/ec2/instancesbyRegion/README.md
generated
vendored
Normal file
32
vendor/github.com/aws/aws-sdk-go/example/service/ec2/instancesbyRegion/README.md
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
# Example Fetch By region
|
||||
|
||||
This is an example using the AWS SDK for Go to list ec2 instances instance state By different region . By default it fetch all running and stopped instance
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
|
||||
```sh
|
||||
# To fetch the stopped instance of all region use below:
|
||||
./filter_ec2_by_region --state running --state stopped
|
||||
|
||||
# To fetch the stopped and running instance for region us-west-1 and eu-west-1 use below:
|
||||
./filter_ec2_by_region --state running --state stopped --region us-west-1 --region=eu-west-1
|
||||
```
|
||||
|
||||
## Sample Output
|
||||
|
||||
```
|
||||
Fetching instace details for region: ap-south-1 with criteria: [running][stopped]**
|
||||
printing instance details.....
|
||||
instance id i-************
|
||||
current State stopped
|
||||
done for region ap-south-1 ****
|
||||
|
||||
|
||||
|
||||
Fetching instace details for region: eu-west-2 with criteria: [running][stopped]**
|
||||
There is no instance for the for region eu-west-2 with the matching Criteria: [running][stopped]
|
||||
done for region eu-west-2 ****
|
||||
```
|
||||
137
vendor/github.com/aws/aws-sdk-go/example/service/ec2/instancesbyRegion/instancesByRegion.go
generated
vendored
Normal file
137
vendor/github.com/aws/aws-sdk-go/example/service/ec2/instancesbyRegion/instancesByRegion.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
)
|
||||
|
||||
// Prints a list of instances for each region. If no regions are provided
|
||||
// all regions will be searched. The state is required.
|
||||
//
|
||||
// Will use the AWS SDK for Go's default credential chain and region. You can
|
||||
// specify the region with the AWS_REGION environment variable.
|
||||
//
|
||||
// Usage: instancesByRegion -state <value> [-state val...] [-region region...]
|
||||
func main() {
|
||||
states, regions := parseArguments()
|
||||
|
||||
if len(states) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", usage())
|
||||
os.Exit(1)
|
||||
}
|
||||
instanceCriteria := " "
|
||||
for _, state := range states {
|
||||
instanceCriteria += "[" + state + "]"
|
||||
}
|
||||
|
||||
if len(regions) == 0 {
|
||||
var err error
|
||||
regions, err = fetchRegion()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
for _, region := range regions {
|
||||
sess := session.Must(session.NewSession(&aws.Config{
|
||||
Region: aws.String(region),
|
||||
}))
|
||||
|
||||
ec2Svc := ec2.New(sess)
|
||||
params := &ec2.DescribeInstancesInput{
|
||||
Filters: []*ec2.Filter{
|
||||
&ec2.Filter{
|
||||
Name: aws.String("instance-state-name"),
|
||||
Values: aws.StringSlice(states),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := ec2Svc.DescribeInstances(params)
|
||||
if err != nil {
|
||||
fmt.Println("Error", err)
|
||||
} else {
|
||||
fmt.Printf("\n\n\nFetching instace details for region: %s with criteria: %s**\n ", region, instanceCriteria)
|
||||
if len(result.Reservations) == 0 {
|
||||
fmt.Printf("There is no instance for the for region %s with the matching Criteria:%s \n", region, instanceCriteria)
|
||||
}
|
||||
for _, reservation := range result.Reservations {
|
||||
|
||||
fmt.Println("printing instance details.....")
|
||||
for _, instance := range reservation.Instances {
|
||||
fmt.Println("instance id " + *instance.InstanceId)
|
||||
fmt.Println("current State " + *instance.State.Name)
|
||||
}
|
||||
}
|
||||
fmt.Printf("done for region %s **** \n", region)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fetchRegion() ([]string, error) {
|
||||
awsSession := session.Must(session.NewSession(&aws.Config{}))
|
||||
|
||||
svc := ec2.New(awsSession)
|
||||
awsRegions, err := svc.DescribeRegions(&ec2.DescribeRegionsInput{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
regions := make([]string, 0, len(awsRegions.Regions))
|
||||
for _, region := range awsRegions.Regions {
|
||||
regions = append(regions, *region.RegionName)
|
||||
}
|
||||
|
||||
return regions, nil
|
||||
}
|
||||
|
||||
type flagArgs []string
|
||||
|
||||
func (a flagArgs) String() string {
|
||||
return strings.Join(a.Args(), ",")
|
||||
}
|
||||
|
||||
func (a *flagArgs) Set(value string) error {
|
||||
*a = append(*a, value)
|
||||
return nil
|
||||
}
|
||||
func (a flagArgs) Args() []string {
|
||||
return []string(a)
|
||||
}
|
||||
|
||||
func parseArguments() (states []string, regions []string) {
|
||||
var stateArgs, regionArgs flagArgs
|
||||
|
||||
flag.Var(&stateArgs, "state", "state list")
|
||||
flag.Var(®ionArgs, "region", "region list")
|
||||
flag.Parse()
|
||||
|
||||
if flag.NFlag() != 0 {
|
||||
states = append([]string{}, stateArgs.Args()...)
|
||||
regions = append([]string{}, regionArgs.Args()...)
|
||||
}
|
||||
|
||||
return states, regions
|
||||
}
|
||||
|
||||
func usage() string {
|
||||
return `
|
||||
|
||||
Missing mandatory flag 'state'. Please use like below Example:
|
||||
|
||||
To fetch the stopped instance of all region use below:
|
||||
./filter_ec2_by_region -state running -state stopped
|
||||
|
||||
To fetch the stopped and running instance for region us-west-1 and eu-west-1 use below:
|
||||
./filter_ec2_by_region -state running -state stopped -region us-west-1 -region=eu-west-1
|
||||
`
|
||||
}
|
||||
15
vendor/github.com/aws/aws-sdk-go/example/service/rds/rdsutils/authentication/README.md
generated
vendored
Normal file
15
vendor/github.com/aws/aws-sdk-go/example/service/rds/rdsutils/authentication/README.md
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Example
|
||||
|
||||
This is an example using the AWS SDK for Go to create an Amazon RDS DB token using the
|
||||
rdsutils package.
|
||||
|
||||
# Usage
|
||||
|
||||
```sh
|
||||
go run -tags example iam_authetnication.go <region> <db user> <db name> <endpoint to database> <iam arn>
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
Successfully opened connection to database
|
||||
```
|
||||
47
vendor/github.com/aws/aws-sdk-go/example/service/rds/rdsutils/authentication/iam_authentication.go
generated
vendored
Normal file
47
vendor/github.com/aws/aws-sdk-go/example/service/rds/rdsutils/authentication/iam_authentication.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// +build example,skip
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/rds/rdsutils"
|
||||
)
|
||||
|
||||
// Usage ./iam_authentication <region> <db user> <db name> <endpoint to database> <iam arn>
|
||||
func main() {
|
||||
if len(os.Args) < 5 {
|
||||
log.Println("USAGE ERROR: go run concatenateObjects.go <region> <endpoint to database> <iam arn>")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
awsRegion := os.Args[1]
|
||||
dbUser := os.Args[2]
|
||||
dbName := os.Args[3]
|
||||
dbEndpoint := os.Args[4]
|
||||
awsCreds := stscreds.NewCredentials(session.New(&aws.Config{Region: &awsRegion}), os.Args[5])
|
||||
authToken, err := rdsutils.BuildAuthToken(dbEndpoint, awsRegion, dbUser, awsCreds)
|
||||
|
||||
// Create the MySQL DNS string for the DB connection
|
||||
// user:password@protocol(endpoint)/dbname?<params>
|
||||
dnsStr := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true",
|
||||
dbUser, authToken, dbEndpoint, dbName,
|
||||
)
|
||||
|
||||
driver := mysql.MySQLDriver{}
|
||||
_ = driver
|
||||
// Use db to perform SQL operations on database
|
||||
if _, err = sql.Open("mysql", dnsStr); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Successfully opened connection to database")
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
9
vendor/github.com/aws/aws-sdk-go/example/service/sqs/mockingClientsForTests/README.md
generated
vendored
Normal file
9
vendor/github.com/aws/aws-sdk-go/example/service/sqs/mockingClientsForTests/README.md
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Example
|
||||
|
||||
This example shows how the SDK's API interfaces can be used by your code instead of the concrete service client type directly. Using this pattern allows you to mock out your code's usage of the SDK's service client for testing.
|
||||
|
||||
# Usage
|
||||
|
||||
Use the `go test` tool to verify the `Queue` type's `GetMessages` function correctly unmarshals the SQS message responses.
|
||||
|
||||
`go test -tags example ifaceExample.go`
|
||||
79
vendor/github.com/aws/aws-sdk-go/example/service/sqs/mockingClientsForTests/ifaceExample.go
generated
vendored
Normal file
79
vendor/github.com/aws/aws-sdk-go/example/service/sqs/mockingClientsForTests/ifaceExample.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/sqs"
|
||||
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Fprintln(os.Stderr, "Queue URL required.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
sess := session.Must(session.NewSession())
|
||||
|
||||
q := Queue{
|
||||
Client: sqs.New(sess),
|
||||
URL: os.Args[1],
|
||||
}
|
||||
|
||||
msgs, err := q.GetMessages(20)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Messages:")
|
||||
for _, msg := range msgs {
|
||||
fmt.Printf("%s>%s: %s\n", msg.From, msg.To, msg.Msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Queue provides the ability to handle SQS messages.
|
||||
type Queue struct {
|
||||
Client sqsiface.SQSAPI
|
||||
URL string
|
||||
}
|
||||
|
||||
// Message is a concrete representation of the SQS message
|
||||
type Message struct {
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
// GetMessages returns the parsed messages from SQS if any. If an error
|
||||
// occurs that error will be returned.
|
||||
func (q *Queue) GetMessages(waitTimeout int64) ([]Message, error) {
|
||||
params := sqs.ReceiveMessageInput{
|
||||
QueueUrl: aws.String(q.URL),
|
||||
}
|
||||
if waitTimeout > 0 {
|
||||
params.WaitTimeSeconds = aws.Int64(waitTimeout)
|
||||
}
|
||||
resp, err := q.Client.ReceiveMessage(¶ms)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get messages, %v", err)
|
||||
}
|
||||
|
||||
msgs := make([]Message, len(resp.Messages))
|
||||
for i, msg := range resp.Messages {
|
||||
parsedMsg := Message{}
|
||||
if err := json.Unmarshal([]byte(aws.StringValue(msg.Body)), &parsedMsg); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal message, %v", err)
|
||||
}
|
||||
|
||||
msgs[i] = parsedMsg
|
||||
}
|
||||
|
||||
return msgs, nil
|
||||
}
|
||||
65
vendor/github.com/aws/aws-sdk-go/example/service/sqs/mockingClientsForTests/ifaceExample_test.go
generated
vendored
Normal file
65
vendor/github.com/aws/aws-sdk-go/example/service/sqs/mockingClientsForTests/ifaceExample_test.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// +build example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/sqs"
|
||||
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
|
||||
)
|
||||
|
||||
type mockedReceiveMsgs struct {
|
||||
sqsiface.SQSAPI
|
||||
Resp sqs.ReceiveMessageOutput
|
||||
}
|
||||
|
||||
func (m mockedReceiveMsgs) ReceiveMessage(in *sqs.ReceiveMessageInput) (*sqs.ReceiveMessageOutput, error) {
|
||||
// Only need to return mocked response output
|
||||
return &m.Resp, nil
|
||||
}
|
||||
|
||||
func TestQueueGetMessage(t *testing.T) {
|
||||
cases := []struct {
|
||||
Resp sqs.ReceiveMessageOutput
|
||||
Expected []Message
|
||||
}{
|
||||
{ // Case 1, expect parsed responses
|
||||
Resp: sqs.ReceiveMessageOutput{
|
||||
Messages: []*sqs.Message{
|
||||
{Body: aws.String(`{"from":"user_1","to":"room_1","msg":"Hello!"}`)},
|
||||
{Body: aws.String(`{"from":"user_2","to":"room_1","msg":"Hi user_1 :)"}`)},
|
||||
},
|
||||
},
|
||||
Expected: []Message{
|
||||
{From: "user_1", To: "room_1", Msg: "Hello!"},
|
||||
{From: "user_2", To: "room_1", Msg: "Hi user_1 :)"},
|
||||
},
|
||||
},
|
||||
{ // Case 2, not messages returned
|
||||
Resp: sqs.ReceiveMessageOutput{},
|
||||
Expected: []Message{},
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
q := Queue{
|
||||
Client: mockedReceiveMsgs{Resp: c.Resp},
|
||||
URL: fmt.Sprintf("mockURL_%d", i),
|
||||
}
|
||||
msgs, err := q.GetMessages(20)
|
||||
if err != nil {
|
||||
t.Fatalf("%d, unexpected error, %v", i, err)
|
||||
}
|
||||
if a, e := len(msgs), len(c.Expected); a != e {
|
||||
t.Fatalf("%d, expected %d messages, got %d", i, e, a)
|
||||
}
|
||||
for j, msg := range msgs {
|
||||
if a, e := msg, c.Expected[j]; a != e {
|
||||
t.Errorf("%d, expected %v message, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user